xref: /sqlite-3.40.0/src/test1.c (revision 3f09beda)
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 all sorts of SQLite interfaces.  This code
13 ** is not included in the SQLite library.  It is used for automated
14 ** testing of the SQLite library.
15 */
16 #include "sqliteInt.h"
17 #if SQLITE_OS_WIN
18 #  include "os_win.h"
19 #endif
20 
21 #include "vdbeInt.h"
22 #include "tcl.h"
23 #include <stdlib.h>
24 #include <string.h>
25 
26 /*
27 ** This is a copy of the first part of the SqliteDb structure in
28 ** tclsqlite.c.  We need it here so that the get_sqlite_pointer routine
29 ** can extract the sqlite3* pointer from an existing Tcl SQLite
30 ** connection.
31 */
32 struct SqliteDb {
33   sqlite3 *db;
34 };
35 
36 /*
37 ** Convert text generated by the "%p" conversion format back into
38 ** a pointer.
39 */
40 static int testHexToInt(int h){
41   if( h>='0' && h<='9' ){
42     return h - '0';
43   }else if( h>='a' && h<='f' ){
44     return h - 'a' + 10;
45   }else{
46     assert( h>='A' && h<='F' );
47     return h - 'A' + 10;
48   }
49 }
50 void *sqlite3TestTextToPtr(const char *z){
51   void *p;
52   u64 v;
53   u32 v2;
54   if( z[0]=='0' && z[1]=='x' ){
55     z += 2;
56   }
57   v = 0;
58   while( *z ){
59     v = (v<<4) + testHexToInt(*z);
60     z++;
61   }
62   if( sizeof(p)==sizeof(v) ){
63     memcpy(&p, &v, sizeof(p));
64   }else{
65     assert( sizeof(p)==sizeof(v2) );
66     v2 = (u32)v;
67     memcpy(&p, &v2, sizeof(p));
68   }
69   return p;
70 }
71 
72 
73 /*
74 ** A TCL command that returns the address of the sqlite* pointer
75 ** for an sqlite connection instance.  Bad things happen if the
76 ** input is not an sqlite connection.
77 */
78 static int get_sqlite_pointer(
79   void * clientData,
80   Tcl_Interp *interp,
81   int objc,
82   Tcl_Obj *CONST objv[]
83 ){
84   struct SqliteDb *p;
85   Tcl_CmdInfo cmdInfo;
86   char zBuf[100];
87   if( objc!=2 ){
88     Tcl_WrongNumArgs(interp, 1, objv, "SQLITE-CONNECTION");
89     return TCL_ERROR;
90   }
91   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
92     Tcl_AppendResult(interp, "command not found: ",
93            Tcl_GetString(objv[1]), (char*)0);
94     return TCL_ERROR;
95   }
96   p = (struct SqliteDb*)cmdInfo.objClientData;
97   sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", p->db);
98   Tcl_AppendResult(interp, zBuf, 0);
99   return TCL_OK;
100 }
101 
102 /*
103 ** Decode a pointer to an sqlite3 object.
104 */
105 int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
106   struct SqliteDb *p;
107   Tcl_CmdInfo cmdInfo;
108   if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){
109     p = (struct SqliteDb*)cmdInfo.objClientData;
110     *ppDb = p->db;
111   }else{
112     *ppDb = (sqlite3*)sqlite3TestTextToPtr(zA);
113   }
114   return TCL_OK;
115 }
116 
117 #if SQLITE_OS_WIN
118 /*
119 ** Decode a Win32 HANDLE object.
120 */
121 int getWin32Handle(Tcl_Interp *interp, const char *zA, LPHANDLE phFile){
122   *phFile = (HANDLE)sqlite3TestTextToPtr(zA);
123   return TCL_OK;
124 }
125 #endif
126 
127 extern const char *sqlite3ErrName(int);
128 #define t1ErrorName sqlite3ErrName
129 
130 /*
131 ** Convert an sqlite3_stmt* into an sqlite3*.  This depends on the
132 ** fact that the sqlite3* is the first field in the Vdbe structure.
133 */
134 #define StmtToDb(X)   sqlite3_db_handle(X)
135 
136 /*
137 ** Check a return value to make sure it agrees with the results
138 ** from sqlite3_errcode.
139 */
140 int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){
141   if( sqlite3_threadsafe()==0 && rc!=SQLITE_MISUSE && rc!=SQLITE_OK
142    && sqlite3_errcode(db)!=rc ){
143     char zBuf[200];
144     int r2 = sqlite3_errcode(db);
145     sqlite3_snprintf(sizeof(zBuf), zBuf,
146        "error code %s (%d) does not match sqlite3_errcode %s (%d)",
147        t1ErrorName(rc), rc, t1ErrorName(r2), r2);
148     Tcl_ResetResult(interp);
149     Tcl_AppendResult(interp, zBuf, 0);
150     return 1;
151   }
152   return 0;
153 }
154 
155 /*
156 ** Decode a pointer to an sqlite3_stmt object.
157 */
158 static int getStmtPointer(
159   Tcl_Interp *interp,
160   const char *zArg,
161   sqlite3_stmt **ppStmt
162 ){
163   *ppStmt = (sqlite3_stmt*)sqlite3TestTextToPtr(zArg);
164   return TCL_OK;
165 }
166 
167 /*
168 ** Generate a text representation of a pointer that can be understood
169 ** by the getDbPointer and getVmPointer routines above.
170 **
171 ** The problem is, on some machines (Solaris) if you do a printf with
172 ** "%p" you cannot turn around and do a scanf with the same "%p" and
173 ** get your pointer back.  You have to prepend a "0x" before it will
174 ** work.  Or at least that is what is reported to me (drh).  But this
175 ** behavior varies from machine to machine.  The solution used her is
176 ** to test the string right after it is generated to see if it can be
177 ** understood by scanf, and if not, try prepending an "0x" to see if
178 ** that helps.  If nothing works, a fatal error is generated.
179 */
180 int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p){
181   sqlite3_snprintf(100, zPtr, "%p", p);
182   return TCL_OK;
183 }
184 
185 /*
186 ** The callback routine for sqlite3_exec_printf().
187 */
188 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
189   Tcl_DString *str = (Tcl_DString*)pArg;
190   int i;
191 
192   if( Tcl_DStringLength(str)==0 ){
193     for(i=0; i<argc; i++){
194       Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
195     }
196   }
197   for(i=0; i<argc; i++){
198     Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
199   }
200   return 0;
201 }
202 
203 /*
204 ** The I/O tracing callback.
205 */
206 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
207 static FILE *iotrace_file = 0;
208 static void io_trace_callback(const char *zFormat, ...){
209   va_list ap;
210   va_start(ap, zFormat);
211   vfprintf(iotrace_file, zFormat, ap);
212   va_end(ap);
213   fflush(iotrace_file);
214 }
215 #endif
216 
217 /*
218 ** Usage:  io_trace FILENAME
219 **
220 ** Turn I/O tracing on or off.  If FILENAME is not an empty string,
221 ** I/O tracing begins going into FILENAME. If FILENAME is an empty
222 ** string, I/O tracing is turned off.
223 */
224 static int test_io_trace(
225   void *NotUsed,
226   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
227   int argc,              /* Number of arguments */
228   char **argv            /* Text of each argument */
229 ){
230 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
231   if( argc!=2 ){
232     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
233           " FILENAME\"", 0);
234     return TCL_ERROR;
235   }
236   if( iotrace_file ){
237     if( iotrace_file!=stdout && iotrace_file!=stderr ){
238       fclose(iotrace_file);
239     }
240     iotrace_file = 0;
241     sqlite3IoTrace = 0;
242   }
243   if( argv[1][0] ){
244     if( strcmp(argv[1],"stdout")==0 ){
245       iotrace_file = stdout;
246     }else if( strcmp(argv[1],"stderr")==0 ){
247       iotrace_file = stderr;
248     }else{
249       iotrace_file = fopen(argv[1], "w");
250     }
251     sqlite3IoTrace = io_trace_callback;
252   }
253 #endif
254   return TCL_OK;
255 }
256 
257 /*
258 ** Usage:  clang_sanitize_address
259 **
260 ** Returns true if the program was compiled using clang with the
261 ** -fsanitize=address switch on the command line. False otherwise.
262 **
263 ** Also return true if the OMIT_MISUSE environment variable exists.
264 */
265 static int clang_sanitize_address(
266   void *NotUsed,
267   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
268   int argc,              /* Number of arguments */
269   char **argv            /* Text of each argument */
270 ){
271   int res = 0;
272 #if defined(__has_feature)
273 # if __has_feature(address_sanitizer)
274   res = 1;
275 # endif
276 #endif
277   if( res==0 && getenv("OMIT_MISUSE")!=0 ) res = 1;
278   Tcl_SetObjResult(interp, Tcl_NewIntObj(res));
279   return TCL_OK;
280 }
281 
282 /*
283 ** Usage:  sqlite3_exec_printf  DB  FORMAT  STRING
284 **
285 ** Invoke the sqlite3_exec_printf() interface using the open database
286 ** DB.  The SQL is the string FORMAT.  The format string should contain
287 ** one %s or %q.  STRING is the value inserted into %s or %q.
288 */
289 static int test_exec_printf(
290   void *NotUsed,
291   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
292   int argc,              /* Number of arguments */
293   char **argv            /* Text of each argument */
294 ){
295   sqlite3 *db;
296   Tcl_DString str;
297   int rc;
298   char *zErr = 0;
299   char *zSql;
300   char zBuf[30];
301   if( argc!=4 ){
302     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
303        " DB FORMAT STRING", 0);
304     return TCL_ERROR;
305   }
306   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
307   Tcl_DStringInit(&str);
308   zSql = sqlite3_mprintf(argv[2], argv[3]);
309   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
310   sqlite3_free(zSql);
311   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
312   Tcl_AppendElement(interp, zBuf);
313   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
314   Tcl_DStringFree(&str);
315   if( zErr ) sqlite3_free(zErr);
316   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
317   return TCL_OK;
318 }
319 
320 /*
321 ** Usage:  sqlite3_exec_hex  DB  HEX
322 **
323 ** Invoke the sqlite3_exec() on a string that is obtained by translating
324 ** HEX into ASCII.  Most characters are translated as is.  %HH becomes
325 ** a hex character.
326 */
327 static int test_exec_hex(
328   void *NotUsed,
329   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
330   int argc,              /* Number of arguments */
331   char **argv            /* Text of each argument */
332 ){
333   sqlite3 *db;
334   Tcl_DString str;
335   int rc, i, j;
336   char *zErr = 0;
337   char *zHex;
338   char zSql[500];
339   char zBuf[30];
340   if( argc!=3 ){
341     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
342        " DB HEX", 0);
343     return TCL_ERROR;
344   }
345   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
346   zHex = argv[2];
347   for(i=j=0; i<sizeof(zSql) && zHex[j]; i++, j++){
348     if( zHex[j]=='%' && zHex[j+2] && zHex[j+2] ){
349       zSql[i] = (testHexToInt(zHex[j+1])<<4) + testHexToInt(zHex[j+2]);
350       j += 2;
351     }else{
352       zSql[i] = zHex[j];
353     }
354   }
355   zSql[i] = 0;
356   Tcl_DStringInit(&str);
357   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
358   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
359   Tcl_AppendElement(interp, zBuf);
360   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
361   Tcl_DStringFree(&str);
362   if( zErr ) sqlite3_free(zErr);
363   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
364   return TCL_OK;
365 }
366 
367 /*
368 ** Usage:  db_enter DB
369 **         db_leave DB
370 **
371 ** Enter or leave the mutex on a database connection.
372 */
373 static int db_enter(
374   void *NotUsed,
375   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
376   int argc,              /* Number of arguments */
377   char **argv            /* Text of each argument */
378 ){
379   sqlite3 *db;
380   if( argc!=2 ){
381     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
382        " DB", 0);
383     return TCL_ERROR;
384   }
385   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
386   sqlite3_mutex_enter(db->mutex);
387   return TCL_OK;
388 }
389 static int db_leave(
390   void *NotUsed,
391   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
392   int argc,              /* Number of arguments */
393   char **argv            /* Text of each argument */
394 ){
395   sqlite3 *db;
396   if( argc!=2 ){
397     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
398        " DB", 0);
399     return TCL_ERROR;
400   }
401   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
402   sqlite3_mutex_leave(db->mutex);
403   return TCL_OK;
404 }
405 
406 /*
407 ** Usage:  sqlite3_exec  DB  SQL
408 **
409 ** Invoke the sqlite3_exec interface using the open database DB
410 */
411 static int test_exec(
412   void *NotUsed,
413   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
414   int argc,              /* Number of arguments */
415   char **argv            /* Text of each argument */
416 ){
417   sqlite3 *db;
418   Tcl_DString str;
419   int rc;
420   char *zErr = 0;
421   char *zSql;
422   int i, j;
423   char zBuf[30];
424   if( argc!=3 ){
425     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
426        " DB SQL", 0);
427     return TCL_ERROR;
428   }
429   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
430   Tcl_DStringInit(&str);
431   zSql = sqlite3_mprintf("%s", argv[2]);
432   for(i=j=0; zSql[i];){
433     if( zSql[i]=='%' ){
434       zSql[j++] = (testHexToInt(zSql[i+1])<<4) + testHexToInt(zSql[i+2]);
435       i += 3;
436     }else{
437       zSql[j++] = zSql[i++];
438     }
439   }
440   zSql[j] = 0;
441   rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr);
442   sqlite3_free(zSql);
443   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
444   Tcl_AppendElement(interp, zBuf);
445   Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
446   Tcl_DStringFree(&str);
447   if( zErr ) sqlite3_free(zErr);
448   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
449   return TCL_OK;
450 }
451 
452 /*
453 ** Usage:  sqlite3_exec_nr  DB  SQL
454 **
455 ** Invoke the sqlite3_exec interface using the open database DB.  Discard
456 ** all results
457 */
458 static int test_exec_nr(
459   void *NotUsed,
460   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
461   int argc,              /* Number of arguments */
462   char **argv            /* Text of each argument */
463 ){
464   sqlite3 *db;
465   int rc;
466   char *zErr = 0;
467   if( argc!=3 ){
468     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
469        " DB SQL", 0);
470     return TCL_ERROR;
471   }
472   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
473   rc = sqlite3_exec(db, argv[2], 0, 0, &zErr);
474   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
475   return TCL_OK;
476 }
477 
478 /*
479 ** Usage:  sqlite3_mprintf_z_test  SEPARATOR  ARG0  ARG1 ...
480 **
481 ** Test the %z format of sqlite_mprintf().  Use multiple mprintf() calls to
482 ** concatenate arg0 through argn using separator as the separator.
483 ** Return the result.
484 */
485 static int test_mprintf_z(
486   void *NotUsed,
487   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
488   int argc,              /* Number of arguments */
489   char **argv            /* Text of each argument */
490 ){
491   char *zResult = 0;
492   int i;
493 
494   for(i=2; i<argc && (i==2 || zResult); i++){
495     zResult = sqlite3_mprintf("%z%s%s", zResult, argv[1], argv[i]);
496   }
497   Tcl_AppendResult(interp, zResult, 0);
498   sqlite3_free(zResult);
499   return TCL_OK;
500 }
501 
502 /*
503 ** Usage:  sqlite3_mprintf_n_test  STRING
504 **
505 ** Test the %n format of sqlite_mprintf().  Return the length of the
506 ** input string.
507 */
508 static int test_mprintf_n(
509   void *NotUsed,
510   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
511   int argc,              /* Number of arguments */
512   char **argv            /* Text of each argument */
513 ){
514   char *zStr;
515   int n = 0;
516   zStr = sqlite3_mprintf("%s%n", argv[1], &n);
517   sqlite3_free(zStr);
518   Tcl_SetObjResult(interp, Tcl_NewIntObj(n));
519   return TCL_OK;
520 }
521 
522 /*
523 ** Usage:  sqlite3_snprintf_int  SIZE FORMAT  INT
524 **
525 ** Test the of sqlite3_snprintf() routine.  SIZE is the size of the
526 ** output buffer in bytes.  The maximum size is 100.  FORMAT is the
527 ** format string.  INT is a single integer argument.  The FORMAT
528 ** string must require no more than this one integer argument.  If
529 ** You pass in a format string that requires more than one argument,
530 ** bad things will happen.
531 */
532 static int test_snprintf_int(
533   void *NotUsed,
534   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
535   int argc,              /* Number of arguments */
536   char **argv            /* Text of each argument */
537 ){
538   char zStr[100];
539   int n = atoi(argv[1]);
540   const char *zFormat = argv[2];
541   int a1 = atoi(argv[3]);
542   if( n>sizeof(zStr) ) n = sizeof(zStr);
543   sqlite3_snprintf(sizeof(zStr), zStr, "abcdefghijklmnopqrstuvwxyz");
544   sqlite3_snprintf(n, zStr, zFormat, a1);
545   Tcl_AppendResult(interp, zStr, 0);
546   return TCL_OK;
547 }
548 
549 #ifndef SQLITE_OMIT_GET_TABLE
550 
551 /*
552 ** Usage:  sqlite3_get_table_printf  DB  FORMAT  STRING  ?--no-counts?
553 **
554 ** Invoke the sqlite3_get_table_printf() interface using the open database
555 ** DB.  The SQL is the string FORMAT.  The format string should contain
556 ** one %s or %q.  STRING is the value inserted into %s or %q.
557 */
558 static int test_get_table_printf(
559   void *NotUsed,
560   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
561   int argc,              /* Number of arguments */
562   char **argv            /* Text of each argument */
563 ){
564   sqlite3 *db;
565   Tcl_DString str;
566   int rc;
567   char *zErr = 0;
568   int nRow = 0, nCol = 0;
569   char **aResult;
570   int i;
571   char zBuf[30];
572   char *zSql;
573   int resCount = -1;
574   if( argc==5 ){
575     if( Tcl_GetInt(interp, argv[4], &resCount) ) return TCL_ERROR;
576   }
577   if( argc!=4 && argc!=5 ){
578     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
579        " DB FORMAT STRING ?COUNT?", 0);
580     return TCL_ERROR;
581   }
582   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
583   Tcl_DStringInit(&str);
584   zSql = sqlite3_mprintf(argv[2],argv[3]);
585   if( argc==5 ){
586     rc = sqlite3_get_table(db, zSql, &aResult, 0, 0, &zErr);
587   }else{
588     rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr);
589     resCount = (nRow+1)*nCol;
590   }
591   sqlite3_free(zSql);
592   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", rc);
593   Tcl_AppendElement(interp, zBuf);
594   if( rc==SQLITE_OK ){
595     if( argc==4 ){
596       sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nRow);
597       Tcl_AppendElement(interp, zBuf);
598       sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nCol);
599       Tcl_AppendElement(interp, zBuf);
600     }
601     for(i=0; i<resCount; i++){
602       Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
603     }
604   }else{
605     Tcl_AppendElement(interp, zErr);
606   }
607   sqlite3_free_table(aResult);
608   if( zErr ) sqlite3_free(zErr);
609   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
610   return TCL_OK;
611 }
612 
613 #endif /* SQLITE_OMIT_GET_TABLE */
614 
615 
616 /*
617 ** Usage:  sqlite3_last_insert_rowid DB
618 **
619 ** Returns the integer ROWID of the most recent insert.
620 */
621 static int test_last_rowid(
622   void *NotUsed,
623   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
624   int argc,              /* Number of arguments */
625   char **argv            /* Text of each argument */
626 ){
627   sqlite3 *db;
628   char zBuf[30];
629 
630   if( argc!=2 ){
631     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);
632     return TCL_ERROR;
633   }
634   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
635   sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", sqlite3_last_insert_rowid(db));
636   Tcl_AppendResult(interp, zBuf, 0);
637   return SQLITE_OK;
638 }
639 
640 /*
641 ** Usage:  sqlite3_key DB KEY
642 **
643 ** Set the codec key.
644 */
645 static int test_key(
646   void *NotUsed,
647   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
648   int argc,              /* Number of arguments */
649   char **argv            /* Text of each argument */
650 ){
651 #ifdef SQLITE_HAS_CODEC
652   sqlite3 *db;
653   const char *zKey;
654   int nKey;
655   if( argc!=3 ){
656     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
657        " FILENAME\"", 0);
658     return TCL_ERROR;
659   }
660   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
661   zKey = argv[2];
662   nKey = strlen(zKey);
663   sqlite3_key(db, zKey, nKey);
664 #endif
665   return TCL_OK;
666 }
667 
668 /*
669 ** Usage:  sqlite3_rekey DB KEY
670 **
671 ** Change the codec key.
672 */
673 static int test_rekey(
674   void *NotUsed,
675   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
676   int argc,              /* Number of arguments */
677   char **argv            /* Text of each argument */
678 ){
679 #ifdef SQLITE_HAS_CODEC
680   sqlite3 *db;
681   const char *zKey;
682   int nKey;
683   if( argc!=3 ){
684     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
685        " FILENAME\"", 0);
686     return TCL_ERROR;
687   }
688   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
689   zKey = argv[2];
690   nKey = strlen(zKey);
691   sqlite3_rekey(db, zKey, nKey);
692 #endif
693   return TCL_OK;
694 }
695 
696 /*
697 ** Usage:  sqlite3_close DB
698 **
699 ** Closes the database opened by sqlite3_open.
700 */
701 static int sqlite_test_close(
702   void *NotUsed,
703   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
704   int argc,              /* Number of arguments */
705   char **argv            /* Text of each argument */
706 ){
707   sqlite3 *db;
708   int rc;
709   if( argc!=2 ){
710     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
711        " FILENAME\"", 0);
712     return TCL_ERROR;
713   }
714   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
715   rc = sqlite3_close(db);
716   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
717   return TCL_OK;
718 }
719 
720 /*
721 ** Usage:  sqlite3_close_v2 DB
722 **
723 ** Closes the database opened by sqlite3_open.
724 */
725 static int sqlite_test_close_v2(
726   void *NotUsed,
727   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
728   int argc,              /* Number of arguments */
729   char **argv            /* Text of each argument */
730 ){
731   sqlite3 *db;
732   int rc;
733   if( argc!=2 ){
734     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
735        " FILENAME\"", 0);
736     return TCL_ERROR;
737   }
738   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
739   rc = sqlite3_close_v2(db);
740   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
741   return TCL_OK;
742 }
743 
744 /*
745 ** Implementation of the x_coalesce() function.
746 ** Return the first argument non-NULL argument.
747 */
748 static void t1_ifnullFunc(
749   sqlite3_context *context,
750   int argc,
751   sqlite3_value **argv
752 ){
753   int i;
754   for(i=0; i<argc; i++){
755     if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
756       int n = sqlite3_value_bytes(argv[i]);
757       sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]),
758           n, SQLITE_TRANSIENT);
759       break;
760     }
761   }
762 }
763 
764 /*
765 ** These are test functions.    hex8() interprets its argument as
766 ** UTF8 and returns a hex encoding.  hex16le() interprets its argument
767 ** as UTF16le and returns a hex encoding.
768 */
769 static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){
770   const unsigned char *z;
771   int i;
772   char zBuf[200];
773   z = sqlite3_value_text(argv[0]);
774   for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){
775     sqlite3_snprintf(sizeof(zBuf)-i*2, &zBuf[i*2], "%02x", z[i]);
776   }
777   zBuf[i*2] = 0;
778   sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
779 }
780 #ifndef SQLITE_OMIT_UTF16
781 static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){
782   const unsigned short int *z;
783   int i;
784   char zBuf[400];
785   z = sqlite3_value_text16(argv[0]);
786   for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){
787     sqlite3_snprintf(sizeof(zBuf)-i*4, &zBuf[i*4],"%04x", z[i]&0xff);
788   }
789   zBuf[i*4] = 0;
790   sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT);
791 }
792 #endif
793 
794 /*
795 ** A structure into which to accumulate text.
796 */
797 struct dstr {
798   int nAlloc;  /* Space allocated */
799   int nUsed;   /* Space used */
800   char *z;     /* The space */
801 };
802 
803 /*
804 ** Append text to a dstr
805 */
806 static void dstrAppend(struct dstr *p, const char *z, int divider){
807   int n = (int)strlen(z);
808   if( p->nUsed + n + 2 > p->nAlloc ){
809     char *zNew;
810     p->nAlloc = p->nAlloc*2 + n + 200;
811     zNew = sqlite3_realloc(p->z, p->nAlloc);
812     if( zNew==0 ){
813       sqlite3_free(p->z);
814       memset(p, 0, sizeof(*p));
815       return;
816     }
817     p->z = zNew;
818   }
819   if( divider && p->nUsed>0 ){
820     p->z[p->nUsed++] = divider;
821   }
822   memcpy(&p->z[p->nUsed], z, n+1);
823   p->nUsed += n;
824 }
825 
826 /*
827 ** Invoked for each callback from sqlite3ExecFunc
828 */
829 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
830   struct dstr *p = (struct dstr*)pData;
831   int i;
832   for(i=0; i<argc; i++){
833     if( argv[i]==0 ){
834       dstrAppend(p, "NULL", ' ');
835     }else{
836       dstrAppend(p, argv[i], ' ');
837     }
838   }
839   return 0;
840 }
841 
842 /*
843 ** Implementation of the x_sqlite_exec() function.  This function takes
844 ** a single argument and attempts to execute that argument as SQL code.
845 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
846 **
847 ** 2004-Jan-07:  We have changed this to make it legal to call sqlite3_exec()
848 ** from within a function call.
849 **
850 ** This routine simulates the effect of having two threads attempt to
851 ** use the same database at the same time.
852 */
853 static void sqlite3ExecFunc(
854   sqlite3_context *context,
855   int argc,
856   sqlite3_value **argv
857 ){
858   struct dstr x;
859   memset(&x, 0, sizeof(x));
860   (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context),
861       (char*)sqlite3_value_text(argv[0]),
862       execFuncCallback, &x, 0);
863   sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT);
864   sqlite3_free(x.z);
865 }
866 
867 /*
868 ** Implementation of tkt2213func(), a scalar function that takes exactly
869 ** one argument. It has two interesting features:
870 **
871 ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.
872 **   If the three pointers returned are not the same an SQL error is raised.
873 **
874 ** * Otherwise it returns a copy of the text representation of its
875 **   argument in such a way as the VDBE representation is a Mem* cell
876 **   with the MEM_Term flag clear.
877 **
878 ** Ticket #2213 can therefore be tested by evaluating the following
879 ** SQL expression:
880 **
881 **   tkt2213func(tkt2213func('a string'));
882 */
883 static void tkt2213Function(
884   sqlite3_context *context,
885   int argc,
886   sqlite3_value **argv
887 ){
888   int nText;
889   unsigned char const *zText1;
890   unsigned char const *zText2;
891   unsigned char const *zText3;
892 
893   nText = sqlite3_value_bytes(argv[0]);
894   zText1 = sqlite3_value_text(argv[0]);
895   zText2 = sqlite3_value_text(argv[0]);
896   zText3 = sqlite3_value_text(argv[0]);
897 
898   if( zText1!=zText2 || zText2!=zText3 ){
899     sqlite3_result_error(context, "tkt2213 is not fixed", -1);
900   }else{
901     char *zCopy = (char *)sqlite3_malloc(nText);
902     memcpy(zCopy, zText1, nText);
903     sqlite3_result_text(context, zCopy, nText, sqlite3_free);
904   }
905 }
906 
907 /*
908 ** The following SQL function takes 4 arguments.  The 2nd and
909 ** 4th argument must be one of these strings:  'text', 'text16',
910 ** or 'blob' corresponding to API functions
911 **
912 **      sqlite3_value_text()
913 **      sqlite3_value_text16()
914 **      sqlite3_value_blob()
915 **
916 ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
917 ** corresponding to APIs:
918 **
919 **      sqlite3_value_bytes()
920 **      sqlite3_value_bytes16()
921 **      noop
922 **
923 ** The APIs designated by the 2nd through 4th arguments are applied
924 ** to the first argument in order.  If the pointers returned by the
925 ** second and fourth are different, this routine returns 1.  Otherwise,
926 ** this routine returns 0.
927 **
928 ** This function is used to test to see when returned pointers from
929 ** the _text(), _text16() and _blob() APIs become invalidated.
930 */
931 static void ptrChngFunction(
932   sqlite3_context *context,
933   int argc,
934   sqlite3_value **argv
935 ){
936   const void *p1, *p2;
937   const char *zCmd;
938   if( argc!=4 ) return;
939   zCmd = (const char*)sqlite3_value_text(argv[1]);
940   if( zCmd==0 ) return;
941   if( strcmp(zCmd,"text")==0 ){
942     p1 = (const void*)sqlite3_value_text(argv[0]);
943 #ifndef SQLITE_OMIT_UTF16
944   }else if( strcmp(zCmd, "text16")==0 ){
945     p1 = (const void*)sqlite3_value_text16(argv[0]);
946 #endif
947   }else if( strcmp(zCmd, "blob")==0 ){
948     p1 = (const void*)sqlite3_value_blob(argv[0]);
949   }else{
950     return;
951   }
952   zCmd = (const char*)sqlite3_value_text(argv[2]);
953   if( zCmd==0 ) return;
954   if( strcmp(zCmd,"bytes")==0 ){
955     sqlite3_value_bytes(argv[0]);
956 #ifndef SQLITE_OMIT_UTF16
957   }else if( strcmp(zCmd, "bytes16")==0 ){
958     sqlite3_value_bytes16(argv[0]);
959 #endif
960   }else if( strcmp(zCmd, "noop")==0 ){
961     /* do nothing */
962   }else{
963     return;
964   }
965   zCmd = (const char*)sqlite3_value_text(argv[3]);
966   if( zCmd==0 ) return;
967   if( strcmp(zCmd,"text")==0 ){
968     p2 = (const void*)sqlite3_value_text(argv[0]);
969 #ifndef SQLITE_OMIT_UTF16
970   }else if( strcmp(zCmd, "text16")==0 ){
971     p2 = (const void*)sqlite3_value_text16(argv[0]);
972 #endif
973   }else if( strcmp(zCmd, "blob")==0 ){
974     p2 = (const void*)sqlite3_value_blob(argv[0]);
975   }else{
976     return;
977   }
978   sqlite3_result_int(context, p1!=p2);
979 }
980 
981 /*
982 ** This SQL function returns a different answer each time it is called, even if
983 ** the arguments are the same.
984 */
985 static void nondeterministicFunction(
986   sqlite3_context *context,
987   int argc,
988   sqlite3_value **argv
989 ){
990   static int cnt = 0;
991   sqlite3_result_int(context, cnt++);
992 }
993 
994 /*
995 ** Usage:  sqlite3_create_function DB
996 **
997 ** Call the sqlite3_create_function API on the given database in order
998 ** to create a function named "x_coalesce".  This function does the same thing
999 ** as the "coalesce" function.  This function also registers an SQL function
1000 ** named "x_sqlite_exec" that invokes sqlite3_exec().  Invoking sqlite3_exec()
1001 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
1002 ** The effect is similar to trying to use the same database connection from
1003 ** two threads at the same time.
1004 **
1005 ** The original motivation for this routine was to be able to call the
1006 ** sqlite3_create_function function while a query is in progress in order
1007 ** to test the SQLITE_MISUSE detection logic.
1008 */
1009 static int test_create_function(
1010   void *NotUsed,
1011   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1012   int argc,              /* Number of arguments */
1013   char **argv            /* Text of each argument */
1014 ){
1015   int rc;
1016   sqlite3 *db;
1017 
1018   if( argc!=2 ){
1019     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1020        " DB\"", 0);
1021     return TCL_ERROR;
1022   }
1023   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
1024   rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0,
1025         t1_ifnullFunc, 0, 0);
1026   if( rc==SQLITE_OK ){
1027     rc = sqlite3_create_function(db, "hex8", 1, SQLITE_UTF8 | SQLITE_DETERMINISTIC,
1028           0, hex8Func, 0, 0);
1029   }
1030 #ifndef SQLITE_OMIT_UTF16
1031   if( rc==SQLITE_OK ){
1032     rc = sqlite3_create_function(db, "hex16", 1, SQLITE_UTF16 | SQLITE_DETERMINISTIC,
1033           0, hex16Func, 0, 0);
1034   }
1035 #endif
1036   if( rc==SQLITE_OK ){
1037     rc = sqlite3_create_function(db, "tkt2213func", 1, SQLITE_ANY, 0,
1038           tkt2213Function, 0, 0);
1039   }
1040   if( rc==SQLITE_OK ){
1041     rc = sqlite3_create_function(db, "pointer_change", 4, SQLITE_ANY, 0,
1042           ptrChngFunction, 0, 0);
1043   }
1044 
1045   /* Functions counter1() and counter2() have the same implementation - they
1046   ** both return an ascending integer with each call.  But counter1() is marked
1047   ** as non-deterministic and counter2() is marked as deterministic.
1048   */
1049   if( rc==SQLITE_OK ){
1050     rc = sqlite3_create_function(db, "counter1", -1, SQLITE_UTF8,
1051           0, nondeterministicFunction, 0, 0);
1052   }
1053   if( rc==SQLITE_OK ){
1054     rc = sqlite3_create_function(db, "counter2", -1, SQLITE_UTF8|SQLITE_DETERMINISTIC,
1055           0, nondeterministicFunction, 0, 0);
1056   }
1057 
1058 #ifndef SQLITE_OMIT_UTF16
1059   /* Use the sqlite3_create_function16() API here. Mainly for fun, but also
1060   ** because it is not tested anywhere else. */
1061   if( rc==SQLITE_OK ){
1062     const void *zUtf16;
1063     sqlite3_value *pVal;
1064     sqlite3_mutex_enter(db->mutex);
1065     pVal = sqlite3ValueNew(db);
1066     sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
1067     zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
1068     if( db->mallocFailed ){
1069       rc = SQLITE_NOMEM;
1070     }else{
1071       rc = sqlite3_create_function16(db, zUtf16,
1072                 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
1073     }
1074     sqlite3ValueFree(pVal);
1075     sqlite3_mutex_leave(db->mutex);
1076   }
1077 #endif
1078 
1079   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
1080   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
1081   return TCL_OK;
1082 }
1083 
1084 /*
1085 ** Routines to implement the x_count() aggregate function.
1086 **
1087 ** x_count() counts the number of non-null arguments.  But there are
1088 ** some twists for testing purposes.
1089 **
1090 ** If the argument to x_count() is 40 then a UTF-8 error is reported
1091 ** on the step function.  If x_count(41) is seen, then a UTF-16 error
1092 ** is reported on the step function.  If the total count is 42, then
1093 ** a UTF-8 error is reported on the finalize function.
1094 */
1095 typedef struct t1CountCtx t1CountCtx;
1096 struct t1CountCtx {
1097   int n;
1098 };
1099 static void t1CountStep(
1100   sqlite3_context *context,
1101   int argc,
1102   sqlite3_value **argv
1103 ){
1104   t1CountCtx *p;
1105   p = sqlite3_aggregate_context(context, sizeof(*p));
1106   if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){
1107     p->n++;
1108   }
1109   if( argc>0 ){
1110     int v = sqlite3_value_int(argv[0]);
1111     if( v==40 ){
1112       sqlite3_result_error(context, "value of 40 handed to x_count", -1);
1113 #ifndef SQLITE_OMIT_UTF16
1114     }else if( v==41 ){
1115       const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0};
1116       sqlite3_result_error16(context, &zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1);
1117 #endif
1118     }
1119   }
1120 }
1121 static void t1CountFinalize(sqlite3_context *context){
1122   t1CountCtx *p;
1123   p = sqlite3_aggregate_context(context, sizeof(*p));
1124   if( p ){
1125     if( p->n==42 ){
1126       sqlite3_result_error(context, "x_count totals to 42", -1);
1127     }else{
1128       sqlite3_result_int(context, p ? p->n : 0);
1129     }
1130   }
1131 }
1132 
1133 #ifndef SQLITE_OMIT_DEPRECATED
1134 static void legacyCountStep(
1135   sqlite3_context *context,
1136   int argc,
1137   sqlite3_value **argv
1138 ){
1139   /* no-op */
1140 }
1141 
1142 static void legacyCountFinalize(sqlite3_context *context){
1143   sqlite3_result_int(context, sqlite3_aggregate_count(context));
1144 }
1145 #endif
1146 
1147 /*
1148 ** Usage:  sqlite3_create_aggregate DB
1149 **
1150 ** Call the sqlite3_create_function API on the given database in order
1151 ** to create a function named "x_count".  This function is similar
1152 ** to the built-in count() function, with a few special quirks
1153 ** for testing the sqlite3_result_error() APIs.
1154 **
1155 ** The original motivation for this routine was to be able to call the
1156 ** sqlite3_create_aggregate function while a query is in progress in order
1157 ** to test the SQLITE_MISUSE detection logic.  See misuse.test.
1158 **
1159 ** This routine was later extended to test the use of sqlite3_result_error()
1160 ** within aggregate functions.
1161 **
1162 ** Later: It is now also extended to register the aggregate function
1163 ** "legacy_count()" with the supplied database handle. This is used
1164 ** to test the deprecated sqlite3_aggregate_count() API.
1165 */
1166 static int test_create_aggregate(
1167   void *NotUsed,
1168   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1169   int argc,              /* Number of arguments */
1170   char **argv            /* Text of each argument */
1171 ){
1172   sqlite3 *db;
1173   int rc;
1174   if( argc!=2 ){
1175     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1176        " FILENAME\"", 0);
1177     return TCL_ERROR;
1178   }
1179   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
1180   rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0,
1181       t1CountStep,t1CountFinalize);
1182   if( rc==SQLITE_OK ){
1183     rc = sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0,
1184         t1CountStep,t1CountFinalize);
1185   }
1186 #ifndef SQLITE_OMIT_DEPRECATED
1187   if( rc==SQLITE_OK ){
1188     rc = sqlite3_create_function(db, "legacy_count", 0, SQLITE_ANY, 0, 0,
1189         legacyCountStep, legacyCountFinalize
1190     );
1191   }
1192 #endif
1193   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
1194   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
1195   return TCL_OK;
1196 }
1197 
1198 
1199 /*
1200 ** Usage:  printf TEXT
1201 **
1202 ** Send output to printf.  Use this rather than puts to merge the output
1203 ** in the correct sequence with debugging printfs inserted into C code.
1204 ** Puts uses a separate buffer and debugging statements will be out of
1205 ** sequence if it is used.
1206 */
1207 static int test_printf(
1208   void *NotUsed,
1209   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1210   int argc,              /* Number of arguments */
1211   char **argv            /* Text of each argument */
1212 ){
1213   if( argc!=2 ){
1214     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1215        " TEXT\"", 0);
1216     return TCL_ERROR;
1217   }
1218   printf("%s\n", argv[1]);
1219   return TCL_OK;
1220 }
1221 
1222 
1223 
1224 /*
1225 ** Usage:  sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
1226 **
1227 ** Call mprintf with three integer arguments
1228 */
1229 static int sqlite3_mprintf_int(
1230   void *NotUsed,
1231   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1232   int argc,              /* Number of arguments */
1233   char **argv            /* Text of each argument */
1234 ){
1235   int a[3], i;
1236   char *z;
1237   if( argc!=5 ){
1238     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1239        " FORMAT INT INT INT\"", 0);
1240     return TCL_ERROR;
1241   }
1242   for(i=2; i<5; i++){
1243     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
1244   }
1245   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
1246   Tcl_AppendResult(interp, z, 0);
1247   sqlite3_free(z);
1248   return TCL_OK;
1249 }
1250 
1251 /*
1252 ** Usage:  sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
1253 **
1254 ** Call mprintf with three 64-bit integer arguments
1255 */
1256 static int sqlite3_mprintf_int64(
1257   void *NotUsed,
1258   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1259   int argc,              /* Number of arguments */
1260   char **argv            /* Text of each argument */
1261 ){
1262   int i;
1263   sqlite_int64 a[3];
1264   char *z;
1265   if( argc!=5 ){
1266     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1267        " FORMAT INT INT INT\"", 0);
1268     return TCL_ERROR;
1269   }
1270   for(i=2; i<5; i++){
1271     if( sqlite3Atoi64(argv[i], &a[i-2], 1000000, SQLITE_UTF8) ){
1272       Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0);
1273       return TCL_ERROR;
1274     }
1275   }
1276   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
1277   Tcl_AppendResult(interp, z, 0);
1278   sqlite3_free(z);
1279   return TCL_OK;
1280 }
1281 
1282 /*
1283 ** Usage:  sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER
1284 **
1285 ** Call mprintf with three long integer arguments.   This might be the
1286 ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on
1287 ** platform.
1288 */
1289 static int sqlite3_mprintf_long(
1290   void *NotUsed,
1291   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1292   int argc,              /* Number of arguments */
1293   char **argv            /* Text of each argument */
1294 ){
1295   int i;
1296   long int a[3];
1297   int b[3];
1298   char *z;
1299   if( argc!=5 ){
1300     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1301        " FORMAT INT INT INT\"", 0);
1302     return TCL_ERROR;
1303   }
1304   for(i=2; i<5; i++){
1305     if( Tcl_GetInt(interp, argv[i], &b[i-2]) ) return TCL_ERROR;
1306     a[i-2] = (long int)b[i-2];
1307     a[i-2] &= (((u64)1)<<(sizeof(int)*8))-1;
1308   }
1309   z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]);
1310   Tcl_AppendResult(interp, z, 0);
1311   sqlite3_free(z);
1312   return TCL_OK;
1313 }
1314 
1315 /*
1316 ** Usage:  sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
1317 **
1318 ** Call mprintf with two integer arguments and one string argument
1319 */
1320 static int sqlite3_mprintf_str(
1321   void *NotUsed,
1322   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1323   int argc,              /* Number of arguments */
1324   char **argv            /* Text of each argument */
1325 ){
1326   int a[3], i;
1327   char *z;
1328   if( argc<4 || argc>5 ){
1329     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1330        " FORMAT INT INT ?STRING?\"", 0);
1331     return TCL_ERROR;
1332   }
1333   for(i=2; i<4; i++){
1334     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
1335   }
1336   z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL);
1337   Tcl_AppendResult(interp, z, 0);
1338   sqlite3_free(z);
1339   return TCL_OK;
1340 }
1341 
1342 /*
1343 ** Usage:  sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
1344 **
1345 ** Call mprintf with two integer arguments and one string argument
1346 */
1347 static int sqlite3_snprintf_str(
1348   void *NotUsed,
1349   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1350   int argc,              /* Number of arguments */
1351   char **argv            /* Text of each argument */
1352 ){
1353   int a[3], i;
1354   int n;
1355   char *z;
1356   if( argc<5 || argc>6 ){
1357     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1358        " INT FORMAT INT INT ?STRING?\"", 0);
1359     return TCL_ERROR;
1360   }
1361   if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
1362   if( n<0 ){
1363     Tcl_AppendResult(interp, "N must be non-negative", 0);
1364     return TCL_ERROR;
1365   }
1366   for(i=3; i<5; i++){
1367     if( Tcl_GetInt(interp, argv[i], &a[i-3]) ) return TCL_ERROR;
1368   }
1369   z = sqlite3_malloc( n+1 );
1370   sqlite3_snprintf(n, z, argv[2], a[0], a[1], argc>4 ? argv[5] : NULL);
1371   Tcl_AppendResult(interp, z, 0);
1372   sqlite3_free(z);
1373   return TCL_OK;
1374 }
1375 
1376 /*
1377 ** Usage:  sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
1378 **
1379 ** Call mprintf with two integer arguments and one double argument
1380 */
1381 static int sqlite3_mprintf_double(
1382   void *NotUsed,
1383   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1384   int argc,              /* Number of arguments */
1385   char **argv            /* Text of each argument */
1386 ){
1387   int a[3], i;
1388   double r;
1389   char *z;
1390   if( argc!=5 ){
1391     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1392        " FORMAT INT INT DOUBLE\"", 0);
1393     return TCL_ERROR;
1394   }
1395   for(i=2; i<4; i++){
1396     if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
1397   }
1398   if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
1399   z = sqlite3_mprintf(argv[1], a[0], a[1], r);
1400   Tcl_AppendResult(interp, z, 0);
1401   sqlite3_free(z);
1402   return TCL_OK;
1403 }
1404 
1405 /*
1406 ** Usage:  sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE
1407 **
1408 ** Call mprintf with a single double argument which is the product of the
1409 ** two arguments given above.  This is used to generate overflow and underflow
1410 ** doubles to test that they are converted properly.
1411 */
1412 static int sqlite3_mprintf_scaled(
1413   void *NotUsed,
1414   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1415   int argc,              /* Number of arguments */
1416   char **argv            /* Text of each argument */
1417 ){
1418   int i;
1419   double r[2];
1420   char *z;
1421   if( argc!=4 ){
1422     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1423        " FORMAT DOUBLE DOUBLE\"", 0);
1424     return TCL_ERROR;
1425   }
1426   for(i=2; i<4; i++){
1427     if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR;
1428   }
1429   z = sqlite3_mprintf(argv[1], r[0]*r[1]);
1430   Tcl_AppendResult(interp, z, 0);
1431   sqlite3_free(z);
1432   return TCL_OK;
1433 }
1434 
1435 /*
1436 ** Usage:  sqlite3_mprintf_stronly FORMAT STRING
1437 **
1438 ** Call mprintf with a single double argument which is the product of the
1439 ** two arguments given above.  This is used to generate overflow and underflow
1440 ** doubles to test that they are converted properly.
1441 */
1442 static int sqlite3_mprintf_stronly(
1443   void *NotUsed,
1444   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1445   int argc,              /* Number of arguments */
1446   char **argv            /* Text of each argument */
1447 ){
1448   char *z;
1449   if( argc!=3 ){
1450     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1451        " FORMAT STRING\"", 0);
1452     return TCL_ERROR;
1453   }
1454   z = sqlite3_mprintf(argv[1], argv[2]);
1455   Tcl_AppendResult(interp, z, 0);
1456   sqlite3_free(z);
1457   return TCL_OK;
1458 }
1459 
1460 /*
1461 ** Usage:  sqlite3_mprintf_hexdouble FORMAT HEX
1462 **
1463 ** Call mprintf with a single double argument which is derived from the
1464 ** hexadecimal encoding of an IEEE double.
1465 */
1466 static int sqlite3_mprintf_hexdouble(
1467   void *NotUsed,
1468   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1469   int argc,              /* Number of arguments */
1470   char **argv            /* Text of each argument */
1471 ){
1472   char *z;
1473   double r;
1474   unsigned int x1, x2;
1475   sqlite_uint64 d;
1476   if( argc!=3 ){
1477     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1478        " FORMAT STRING\"", 0);
1479     return TCL_ERROR;
1480   }
1481   if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){
1482     Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0);
1483     return TCL_ERROR;
1484   }
1485   d = x2;
1486   d = (d<<32) + x1;
1487   memcpy(&r, &d, sizeof(r));
1488   z = sqlite3_mprintf(argv[1], r);
1489   Tcl_AppendResult(interp, z, 0);
1490   sqlite3_free(z);
1491   return TCL_OK;
1492 }
1493 
1494 /*
1495 ** Usage: sqlite3_enable_shared_cache ?BOOLEAN?
1496 **
1497 */
1498 #if !defined(SQLITE_OMIT_SHARED_CACHE)
1499 static int test_enable_shared(
1500   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
1501   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1502   int objc,              /* Number of arguments */
1503   Tcl_Obj *CONST objv[]  /* Command arguments */
1504 ){
1505   int rc;
1506   int enable;
1507   int ret = 0;
1508 
1509   if( objc!=2 && objc!=1 ){
1510     Tcl_WrongNumArgs(interp, 1, objv, "?BOOLEAN?");
1511     return TCL_ERROR;
1512   }
1513   ret = sqlite3GlobalConfig.sharedCacheEnabled;
1514 
1515   if( objc==2 ){
1516     if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
1517       return TCL_ERROR;
1518     }
1519     rc = sqlite3_enable_shared_cache(enable);
1520     if( rc!=SQLITE_OK ){
1521       Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
1522       return TCL_ERROR;
1523     }
1524   }
1525   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ret));
1526   return TCL_OK;
1527 }
1528 #endif
1529 
1530 
1531 
1532 /*
1533 ** Usage: sqlite3_extended_result_codes   DB    BOOLEAN
1534 **
1535 */
1536 static int test_extended_result_codes(
1537   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
1538   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1539   int objc,              /* Number of arguments */
1540   Tcl_Obj *CONST objv[]  /* Command arguments */
1541 ){
1542   int enable;
1543   sqlite3 *db;
1544 
1545   if( objc!=3 ){
1546     Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
1547     return TCL_ERROR;
1548   }
1549   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1550   if( Tcl_GetBooleanFromObj(interp, objv[2], &enable) ) return TCL_ERROR;
1551   sqlite3_extended_result_codes(db, enable);
1552   return TCL_OK;
1553 }
1554 
1555 /*
1556 ** Usage: sqlite3_libversion_number
1557 **
1558 */
1559 static int test_libversion_number(
1560   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
1561   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1562   int objc,              /* Number of arguments */
1563   Tcl_Obj *CONST objv[]  /* Command arguments */
1564 ){
1565   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_libversion_number()));
1566   return TCL_OK;
1567 }
1568 
1569 /*
1570 ** Usage: sqlite3_table_column_metadata DB dbname tblname colname
1571 **
1572 */
1573 static int test_table_column_metadata(
1574   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
1575   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1576   int objc,              /* Number of arguments */
1577   Tcl_Obj *CONST objv[]  /* Command arguments */
1578 ){
1579   sqlite3 *db;
1580   const char *zDb;
1581   const char *zTbl;
1582   const char *zCol;
1583   int rc;
1584   Tcl_Obj *pRet;
1585 
1586   const char *zDatatype;
1587   const char *zCollseq;
1588   int notnull;
1589   int primarykey;
1590   int autoincrement;
1591 
1592   if( objc!=5 && objc!=4 ){
1593     Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname");
1594     return TCL_ERROR;
1595   }
1596   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1597   zDb = Tcl_GetString(objv[2]);
1598   zTbl = Tcl_GetString(objv[3]);
1599   zCol = objc==5 ? Tcl_GetString(objv[4]) : 0;
1600 
1601   if( strlen(zDb)==0 ) zDb = 0;
1602 
1603   rc = sqlite3_table_column_metadata(db, zDb, zTbl, zCol,
1604       &zDatatype, &zCollseq, &notnull, &primarykey, &autoincrement);
1605 
1606   if( rc!=SQLITE_OK ){
1607     Tcl_AppendResult(interp, sqlite3_errmsg(db), 0);
1608     return TCL_ERROR;
1609   }
1610 
1611   pRet = Tcl_NewObj();
1612   Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zDatatype, -1));
1613   Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zCollseq, -1));
1614   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(notnull));
1615   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey));
1616   Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement));
1617   Tcl_SetObjResult(interp, pRet);
1618 
1619   return TCL_OK;
1620 }
1621 
1622 #ifndef SQLITE_OMIT_INCRBLOB
1623 
1624 static int blobHandleFromObj(
1625   Tcl_Interp *interp,
1626   Tcl_Obj *pObj,
1627   sqlite3_blob **ppBlob
1628 ){
1629   char *z;
1630   int n;
1631 
1632   z = Tcl_GetStringFromObj(pObj, &n);
1633   if( n==0 ){
1634     *ppBlob = 0;
1635   }else{
1636     int notUsed;
1637     Tcl_Channel channel;
1638     ClientData instanceData;
1639 
1640     channel = Tcl_GetChannel(interp, z, &notUsed);
1641     if( !channel ) return TCL_ERROR;
1642 
1643     Tcl_Flush(channel);
1644     Tcl_Seek(channel, 0, SEEK_SET);
1645 
1646     instanceData = Tcl_GetChannelInstanceData(channel);
1647     *ppBlob = *((sqlite3_blob **)instanceData);
1648   }
1649 
1650   return TCL_OK;
1651 }
1652 
1653 static int test_blob_reopen(
1654   ClientData clientData, /* Not used */
1655   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1656   int objc,              /* Number of arguments */
1657   Tcl_Obj *CONST objv[]  /* Command arguments */
1658 ){
1659   Tcl_WideInt iRowid;
1660   sqlite3_blob *pBlob;
1661   int rc;
1662 
1663   if( objc!=3 ){
1664     Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL ROWID");
1665     return TCL_ERROR;
1666   }
1667 
1668   if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL_ERROR;
1669   if( Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL_ERROR;
1670 
1671   rc = sqlite3_blob_reopen(pBlob, iRowid);
1672   if( rc!=SQLITE_OK ){
1673     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE);
1674   }
1675 
1676   return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR);
1677 }
1678 
1679 #endif
1680 
1681 /*
1682 ** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC
1683 **
1684 **   This Tcl proc is used for testing the experimental
1685 **   sqlite3_create_collation_v2() interface.
1686 */
1687 struct TestCollationX {
1688   Tcl_Interp *interp;
1689   Tcl_Obj *pCmp;
1690   Tcl_Obj *pDel;
1691 };
1692 typedef struct TestCollationX TestCollationX;
1693 static void testCreateCollationDel(void *pCtx){
1694   TestCollationX *p = (TestCollationX *)pCtx;
1695 
1696   int rc = Tcl_EvalObjEx(p->interp, p->pDel, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL);
1697   if( rc!=TCL_OK ){
1698     Tcl_BackgroundError(p->interp);
1699   }
1700 
1701   Tcl_DecrRefCount(p->pCmp);
1702   Tcl_DecrRefCount(p->pDel);
1703   sqlite3_free((void *)p);
1704 }
1705 static int testCreateCollationCmp(
1706   void *pCtx,
1707   int nLeft,
1708   const void *zLeft,
1709   int nRight,
1710   const void *zRight
1711 ){
1712   TestCollationX *p = (TestCollationX *)pCtx;
1713   Tcl_Obj *pScript = Tcl_DuplicateObj(p->pCmp);
1714   int iRes = 0;
1715 
1716   Tcl_IncrRefCount(pScript);
1717   Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj((char *)zLeft, nLeft));
1718   Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj((char *)zRight,nRight));
1719 
1720   if( TCL_OK!=Tcl_EvalObjEx(p->interp, pScript, TCL_EVAL_DIRECT|TCL_EVAL_GLOBAL)
1721    || TCL_OK!=Tcl_GetIntFromObj(p->interp, Tcl_GetObjResult(p->interp), &iRes)
1722   ){
1723     Tcl_BackgroundError(p->interp);
1724   }
1725   Tcl_DecrRefCount(pScript);
1726 
1727   return iRes;
1728 }
1729 static int test_create_collation_v2(
1730   ClientData clientData, /* Not used */
1731   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1732   int objc,              /* Number of arguments */
1733   Tcl_Obj *CONST objv[]  /* Command arguments */
1734 ){
1735   TestCollationX *p;
1736   sqlite3 *db;
1737   int rc;
1738 
1739   if( objc!=5 ){
1740     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE NAME CMP-PROC DEL-PROC");
1741     return TCL_ERROR;
1742   }
1743   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1744 
1745   p = (TestCollationX *)sqlite3_malloc(sizeof(TestCollationX));
1746   p->pCmp = objv[3];
1747   p->pDel = objv[4];
1748   p->interp = interp;
1749   Tcl_IncrRefCount(p->pCmp);
1750   Tcl_IncrRefCount(p->pDel);
1751 
1752   rc = sqlite3_create_collation_v2(db, Tcl_GetString(objv[2]), 16,
1753       (void *)p, testCreateCollationCmp, testCreateCollationDel
1754   );
1755   if( rc!=SQLITE_MISUSE ){
1756     Tcl_AppendResult(interp, "sqlite3_create_collate_v2() failed to detect "
1757       "an invalid encoding", (char*)0);
1758     return TCL_ERROR;
1759   }
1760   rc = sqlite3_create_collation_v2(db, Tcl_GetString(objv[2]), SQLITE_UTF8,
1761       (void *)p, testCreateCollationCmp, testCreateCollationDel
1762   );
1763   return TCL_OK;
1764 }
1765 
1766 /*
1767 ** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES?
1768 **
1769 ** Available switches are:
1770 **
1771 **   -func    SCRIPT
1772 **   -step    SCRIPT
1773 **   -final   SCRIPT
1774 **   -destroy SCRIPT
1775 */
1776 typedef struct CreateFunctionV2 CreateFunctionV2;
1777 struct CreateFunctionV2 {
1778   Tcl_Interp *interp;
1779   Tcl_Obj *pFunc;                 /* Script for function invocation */
1780   Tcl_Obj *pStep;                 /* Script for agg. step invocation */
1781   Tcl_Obj *pFinal;                /* Script for agg. finalization invocation */
1782   Tcl_Obj *pDestroy;              /* Destructor script */
1783 };
1784 static void cf2Func(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
1785 }
1786 static void cf2Step(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
1787 }
1788 static void cf2Final(sqlite3_context *ctx){
1789 }
1790 static void cf2Destroy(void *pUser){
1791   CreateFunctionV2 *p = (CreateFunctionV2 *)pUser;
1792 
1793   if( p->interp && p->pDestroy ){
1794     int rc = Tcl_EvalObjEx(p->interp, p->pDestroy, 0);
1795     if( rc!=TCL_OK ) Tcl_BackgroundError(p->interp);
1796   }
1797 
1798   if( p->pFunc ) Tcl_DecrRefCount(p->pFunc);
1799   if( p->pStep ) Tcl_DecrRefCount(p->pStep);
1800   if( p->pFinal ) Tcl_DecrRefCount(p->pFinal);
1801   if( p->pDestroy ) Tcl_DecrRefCount(p->pDestroy);
1802   sqlite3_free(p);
1803 }
1804 static int test_create_function_v2(
1805   ClientData clientData,          /* Not used */
1806   Tcl_Interp *interp,             /* The invoking TCL interpreter */
1807   int objc,                       /* Number of arguments */
1808   Tcl_Obj *CONST objv[]           /* Command arguments */
1809 ){
1810   sqlite3 *db;
1811   const char *zFunc;
1812   int nArg;
1813   int enc;
1814   CreateFunctionV2 *p;
1815   int i;
1816   int rc;
1817 
1818   struct EncTable {
1819     const char *zEnc;
1820     int enc;
1821   } aEnc[] = {
1822     {"utf8",    SQLITE_UTF8 },
1823     {"utf16",   SQLITE_UTF16 },
1824     {"utf16le", SQLITE_UTF16LE },
1825     {"utf16be", SQLITE_UTF16BE },
1826     {"any",     SQLITE_ANY },
1827     {"0", 0 }
1828   };
1829 
1830   if( objc<5 || (objc%2)==0 ){
1831     Tcl_WrongNumArgs(interp, 1, objv, "DB NAME NARG ENC SWITCHES...");
1832     return TCL_ERROR;
1833   }
1834 
1835   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
1836   zFunc = Tcl_GetString(objv[2]);
1837   if( Tcl_GetIntFromObj(interp, objv[3], &nArg) ) return TCL_ERROR;
1838   if( Tcl_GetIndexFromObjStruct(interp, objv[4], aEnc, sizeof(aEnc[0]),
1839           "encoding", 0, &enc)
1840   ){
1841     return TCL_ERROR;
1842   }
1843   enc = aEnc[enc].enc;
1844 
1845   p = sqlite3_malloc(sizeof(CreateFunctionV2));
1846   assert( p );
1847   memset(p, 0, sizeof(CreateFunctionV2));
1848   p->interp = interp;
1849 
1850   for(i=5; i<objc; i+=2){
1851     int iSwitch;
1852     const char *azSwitch[] = {"-func", "-step", "-final", "-destroy", 0};
1853     if( Tcl_GetIndexFromObj(interp, objv[i], azSwitch, "switch", 0, &iSwitch) ){
1854       sqlite3_free(p);
1855       return TCL_ERROR;
1856     }
1857 
1858     switch( iSwitch ){
1859       case 0: p->pFunc = objv[i+1];      break;
1860       case 1: p->pStep = objv[i+1];      break;
1861       case 2: p->pFinal = objv[i+1];     break;
1862       case 3: p->pDestroy = objv[i+1];   break;
1863     }
1864   }
1865   if( p->pFunc ) p->pFunc = Tcl_DuplicateObj(p->pFunc);
1866   if( p->pStep ) p->pStep = Tcl_DuplicateObj(p->pStep);
1867   if( p->pFinal ) p->pFinal = Tcl_DuplicateObj(p->pFinal);
1868   if( p->pDestroy ) p->pDestroy = Tcl_DuplicateObj(p->pDestroy);
1869 
1870   if( p->pFunc ) Tcl_IncrRefCount(p->pFunc);
1871   if( p->pStep ) Tcl_IncrRefCount(p->pStep);
1872   if( p->pFinal ) Tcl_IncrRefCount(p->pFinal);
1873   if( p->pDestroy ) Tcl_IncrRefCount(p->pDestroy);
1874 
1875   rc = sqlite3_create_function_v2(db, zFunc, nArg, enc, (void *)p,
1876       (p->pFunc ? cf2Func : 0),
1877       (p->pStep ? cf2Step : 0),
1878       (p->pFinal ? cf2Final : 0),
1879       cf2Destroy
1880   );
1881   if( rc!=SQLITE_OK ){
1882     Tcl_ResetResult(interp);
1883     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
1884     return TCL_ERROR;
1885   }
1886   return TCL_OK;
1887 }
1888 
1889 /*
1890 ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC?
1891 */
1892 static int test_load_extension(
1893   ClientData clientData, /* Not used */
1894   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1895   int objc,              /* Number of arguments */
1896   Tcl_Obj *CONST objv[]  /* Command arguments */
1897 ){
1898   Tcl_CmdInfo cmdInfo;
1899   sqlite3 *db;
1900   int rc;
1901   char *zDb;
1902   char *zFile;
1903   char *zProc = 0;
1904   char *zErr = 0;
1905 
1906   if( objc!=4 && objc!=3 ){
1907     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?");
1908     return TCL_ERROR;
1909   }
1910   zDb = Tcl_GetString(objv[1]);
1911   zFile = Tcl_GetString(objv[2]);
1912   if( objc==4 ){
1913     zProc = Tcl_GetString(objv[3]);
1914   }
1915 
1916   /* Extract the C database handle from the Tcl command name */
1917   if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
1918     Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0);
1919     return TCL_ERROR;
1920   }
1921   db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
1922   assert(db);
1923 
1924   /* Call the underlying C function. If an error occurs, set rc to
1925   ** TCL_ERROR and load any error string into the interpreter. If no
1926   ** error occurs, set rc to TCL_OK.
1927   */
1928 #ifdef SQLITE_OMIT_LOAD_EXTENSION
1929   rc = SQLITE_ERROR;
1930   zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()");
1931 #else
1932   rc = sqlite3_load_extension(db, zFile, zProc, &zErr);
1933 #endif
1934   if( rc!=SQLITE_OK ){
1935     Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE);
1936     rc = TCL_ERROR;
1937   }else{
1938     rc = TCL_OK;
1939   }
1940   sqlite3_free(zErr);
1941 
1942   return rc;
1943 }
1944 
1945 /*
1946 ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF
1947 */
1948 static int test_enable_load(
1949   ClientData clientData, /* Not used */
1950   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1951   int objc,              /* Number of arguments */
1952   Tcl_Obj *CONST objv[]  /* Command arguments */
1953 ){
1954   Tcl_CmdInfo cmdInfo;
1955   sqlite3 *db;
1956   char *zDb;
1957   int onoff;
1958 
1959   if( objc!=3 ){
1960     Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF");
1961     return TCL_ERROR;
1962   }
1963   zDb = Tcl_GetString(objv[1]);
1964 
1965   /* Extract the C database handle from the Tcl command name */
1966   if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
1967     Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0);
1968     return TCL_ERROR;
1969   }
1970   db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
1971   assert(db);
1972 
1973   /* Get the onoff parameter */
1974   if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
1975     return TCL_ERROR;
1976   }
1977 
1978 #ifdef SQLITE_OMIT_LOAD_EXTENSION
1979   Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()");
1980   return TCL_ERROR;
1981 #else
1982   sqlite3_enable_load_extension(db, onoff);
1983   return TCL_OK;
1984 #endif
1985 }
1986 
1987 /*
1988 ** Usage:  sqlite_abort
1989 **
1990 ** Shutdown the process immediately.  This is not a clean shutdown.
1991 ** This command is used to test the recoverability of a database in
1992 ** the event of a program crash.
1993 */
1994 static int sqlite_abort(
1995   void *NotUsed,
1996   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1997   int argc,              /* Number of arguments */
1998   char **argv            /* Text of each argument */
1999 ){
2000 #if defined(_MSC_VER)
2001   /* We do this, otherwise the test will halt with a popup message
2002    * that we have to click away before the test will continue.
2003    */
2004   _set_abort_behavior( 0, _CALL_REPORTFAULT );
2005 #endif
2006   exit(255);
2007   assert( interp==0 );   /* This will always fail */
2008   return TCL_OK;
2009 }
2010 
2011 /*
2012 ** The following routine is a user-defined SQL function whose purpose
2013 ** is to test the sqlite_set_result() API.
2014 */
2015 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
2016   while( argc>=2 ){
2017     const char *zArg0 = (char*)sqlite3_value_text(argv[0]);
2018     if( zArg0 ){
2019       if( 0==sqlite3StrICmp(zArg0, "int") ){
2020         sqlite3_result_int(context, sqlite3_value_int(argv[1]));
2021       }else if( sqlite3StrICmp(zArg0,"int64")==0 ){
2022         sqlite3_result_int64(context, sqlite3_value_int64(argv[1]));
2023       }else if( sqlite3StrICmp(zArg0,"string")==0 ){
2024         sqlite3_result_text(context, (char*)sqlite3_value_text(argv[1]), -1,
2025             SQLITE_TRANSIENT);
2026       }else if( sqlite3StrICmp(zArg0,"double")==0 ){
2027         sqlite3_result_double(context, sqlite3_value_double(argv[1]));
2028       }else if( sqlite3StrICmp(zArg0,"null")==0 ){
2029         sqlite3_result_null(context);
2030       }else if( sqlite3StrICmp(zArg0,"value")==0 ){
2031         sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]);
2032       }else{
2033         goto error_out;
2034       }
2035     }else{
2036       goto error_out;
2037     }
2038     argc -= 2;
2039     argv += 2;
2040   }
2041   return;
2042 
2043 error_out:
2044   sqlite3_result_error(context,"first argument should be one of: "
2045       "int int64 string double null value", -1);
2046 }
2047 
2048 /*
2049 ** Usage:   sqlite_register_test_function  DB  NAME
2050 **
2051 ** Register the test SQL function on the database DB under the name NAME.
2052 */
2053 static int test_register_func(
2054   void *NotUsed,
2055   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2056   int argc,              /* Number of arguments */
2057   char **argv            /* Text of each argument */
2058 ){
2059   sqlite3 *db;
2060   int rc;
2061   if( argc!=3 ){
2062     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2063        " DB FUNCTION-NAME", 0);
2064     return TCL_ERROR;
2065   }
2066   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
2067   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0,
2068       testFunc, 0, 0);
2069   if( rc!=0 ){
2070     Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0);
2071     return TCL_ERROR;
2072   }
2073   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2074   return TCL_OK;
2075 }
2076 
2077 /*
2078 ** Usage:  sqlite3_finalize  STMT
2079 **
2080 ** Finalize a statement handle.
2081 */
2082 static int test_finalize(
2083   void * clientData,
2084   Tcl_Interp *interp,
2085   int objc,
2086   Tcl_Obj *CONST objv[]
2087 ){
2088   sqlite3_stmt *pStmt;
2089   int rc;
2090   sqlite3 *db = 0;
2091 
2092   if( objc!=2 ){
2093     Tcl_AppendResult(interp, "wrong # args: should be \"",
2094         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
2095     return TCL_ERROR;
2096   }
2097 
2098   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2099 
2100   if( pStmt ){
2101     db = StmtToDb(pStmt);
2102   }
2103   rc = sqlite3_finalize(pStmt);
2104   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
2105   if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2106   return TCL_OK;
2107 }
2108 
2109 /*
2110 ** Usage:  sqlite3_stmt_status  STMT  CODE  RESETFLAG
2111 **
2112 ** Get the value of a status counter from a statement.
2113 */
2114 static int test_stmt_status(
2115   void * clientData,
2116   Tcl_Interp *interp,
2117   int objc,
2118   Tcl_Obj *CONST objv[]
2119 ){
2120   int iValue;
2121   int i, op = 0, resetFlag;
2122   const char *zOpName;
2123   sqlite3_stmt *pStmt;
2124 
2125   static const struct {
2126     const char *zName;
2127     int op;
2128   } aOp[] = {
2129     { "SQLITE_STMTSTATUS_FULLSCAN_STEP",   SQLITE_STMTSTATUS_FULLSCAN_STEP   },
2130     { "SQLITE_STMTSTATUS_SORT",            SQLITE_STMTSTATUS_SORT            },
2131     { "SQLITE_STMTSTATUS_AUTOINDEX",       SQLITE_STMTSTATUS_AUTOINDEX       },
2132     { "SQLITE_STMTSTATUS_VM_STEP",         SQLITE_STMTSTATUS_VM_STEP         },
2133   };
2134   if( objc!=4 ){
2135     Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG");
2136     return TCL_ERROR;
2137   }
2138   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2139   zOpName = Tcl_GetString(objv[2]);
2140   for(i=0; i<ArraySize(aOp); i++){
2141     if( strcmp(aOp[i].zName, zOpName)==0 ){
2142       op = aOp[i].op;
2143       break;
2144     }
2145   }
2146   if( i>=ArraySize(aOp) ){
2147     if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR;
2148   }
2149   if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR;
2150   iValue = sqlite3_stmt_status(pStmt, op, resetFlag);
2151   Tcl_SetObjResult(interp, Tcl_NewIntObj(iValue));
2152   return TCL_OK;
2153 }
2154 
2155 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
2156 /*
2157 ** Usage:  sqlite3_stmt_scanstatus STMT IDX
2158 */
2159 static int test_stmt_scanstatus(
2160   void * clientData,
2161   Tcl_Interp *interp,
2162   int objc,
2163   Tcl_Obj *CONST objv[]
2164 ){
2165   sqlite3_stmt *pStmt;            /* First argument */
2166   int idx;                        /* Second argument */
2167 
2168   const char *zName;
2169   const char *zExplain;
2170   sqlite3_int64 nLoop;
2171   sqlite3_int64 nVisit;
2172   double rEst;
2173   int res;
2174 
2175   if( objc!=3 ){
2176     Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX");
2177     return TCL_ERROR;
2178   }
2179   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2180   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
2181 
2182   res = sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop);
2183   if( res==0 ){
2184     Tcl_Obj *pRet = Tcl_NewObj();
2185     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nLoop", -1));
2186     Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nLoop));
2187     sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
2188     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nVisit", -1));
2189     Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nVisit));
2190     sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EST, (void*)&rEst);
2191     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nEst", -1));
2192     Tcl_ListObjAppendElement(0, pRet, Tcl_NewDoubleObj(rEst));
2193     sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NAME, (void*)&zName);
2194     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zName", -1));
2195     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zName, -1));
2196     sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
2197     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zExplain", -1));
2198     Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zExplain, -1));
2199     Tcl_SetObjResult(interp, pRet);
2200   }else{
2201     Tcl_ResetResult(interp);
2202   }
2203   return TCL_OK;
2204 }
2205 
2206 /*
2207 ** Usage:  sqlite3_stmt_scanstatus_reset  STMT
2208 */
2209 static int test_stmt_scanstatus_reset(
2210   void * clientData,
2211   Tcl_Interp *interp,
2212   int objc,
2213   Tcl_Obj *CONST objv[]
2214 ){
2215   sqlite3_stmt *pStmt;            /* First argument */
2216   if( objc!=2 ){
2217     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
2218     return TCL_ERROR;
2219   }
2220   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2221   sqlite3_stmt_scanstatus_reset(pStmt);
2222   return TCL_OK;
2223 }
2224 #endif
2225 
2226 /*
2227 ** Usage:  sqlite3_next_stmt  DB  STMT
2228 **
2229 ** Return the next statment in sequence after STMT.
2230 */
2231 static int test_next_stmt(
2232   void * clientData,
2233   Tcl_Interp *interp,
2234   int objc,
2235   Tcl_Obj *CONST objv[]
2236 ){
2237   sqlite3_stmt *pStmt;
2238   sqlite3 *db = 0;
2239   char zBuf[50];
2240 
2241   if( objc!=3 ){
2242     Tcl_AppendResult(interp, "wrong # args: should be \"",
2243         Tcl_GetStringFromObj(objv[0], 0), " DB STMT", 0);
2244     return TCL_ERROR;
2245   }
2246 
2247   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2248   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt) ) return TCL_ERROR;
2249   pStmt = sqlite3_next_stmt(db, pStmt);
2250   if( pStmt ){
2251     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
2252     Tcl_AppendResult(interp, zBuf, 0);
2253   }
2254   return TCL_OK;
2255 }
2256 
2257 /*
2258 ** Usage:  sqlite3_stmt_readonly  STMT
2259 **
2260 ** Return true if STMT is a NULL pointer or a pointer to a statement
2261 ** that is guaranteed to leave the database unmodified.
2262 */
2263 static int test_stmt_readonly(
2264   void * clientData,
2265   Tcl_Interp *interp,
2266   int objc,
2267   Tcl_Obj *CONST objv[]
2268 ){
2269   sqlite3_stmt *pStmt;
2270   int rc;
2271 
2272   if( objc!=2 ){
2273     Tcl_AppendResult(interp, "wrong # args: should be \"",
2274         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2275     return TCL_ERROR;
2276   }
2277 
2278   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2279   rc = sqlite3_stmt_readonly(pStmt);
2280   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
2281   return TCL_OK;
2282 }
2283 
2284 /*
2285 ** Usage:  sqlite3_stmt_busy  STMT
2286 **
2287 ** Return true if STMT is a non-NULL pointer to a statement
2288 ** that has been stepped but not to completion.
2289 */
2290 static int test_stmt_busy(
2291   void * clientData,
2292   Tcl_Interp *interp,
2293   int objc,
2294   Tcl_Obj *CONST objv[]
2295 ){
2296   sqlite3_stmt *pStmt;
2297   int rc;
2298 
2299   if( objc!=2 ){
2300     Tcl_AppendResult(interp, "wrong # args: should be \"",
2301         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2302     return TCL_ERROR;
2303   }
2304 
2305   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2306   rc = sqlite3_stmt_busy(pStmt);
2307   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
2308   return TCL_OK;
2309 }
2310 
2311 /*
2312 ** Usage:  uses_stmt_journal  STMT
2313 **
2314 ** Return true if STMT uses a statement journal.
2315 */
2316 static int uses_stmt_journal(
2317   void * clientData,
2318   Tcl_Interp *interp,
2319   int objc,
2320   Tcl_Obj *CONST objv[]
2321 ){
2322   sqlite3_stmt *pStmt;
2323 
2324   if( objc!=2 ){
2325     Tcl_AppendResult(interp, "wrong # args: should be \"",
2326         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2327     return TCL_ERROR;
2328   }
2329 
2330   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2331   sqlite3_stmt_readonly(pStmt);
2332   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(((Vdbe *)pStmt)->usesStmtJournal));
2333   return TCL_OK;
2334 }
2335 
2336 
2337 /*
2338 ** Usage:  sqlite3_reset  STMT
2339 **
2340 ** Reset a statement handle.
2341 */
2342 static int test_reset(
2343   void * clientData,
2344   Tcl_Interp *interp,
2345   int objc,
2346   Tcl_Obj *CONST objv[]
2347 ){
2348   sqlite3_stmt *pStmt;
2349   int rc;
2350 
2351   if( objc!=2 ){
2352     Tcl_AppendResult(interp, "wrong # args: should be \"",
2353         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
2354     return TCL_ERROR;
2355   }
2356 
2357   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2358 
2359   rc = sqlite3_reset(pStmt);
2360   if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){
2361     return TCL_ERROR;
2362   }
2363   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
2364 /*
2365   if( rc ){
2366     return TCL_ERROR;
2367   }
2368 */
2369   return TCL_OK;
2370 }
2371 
2372 /*
2373 ** Usage:  sqlite3_expired STMT
2374 **
2375 ** Return TRUE if a recompilation of the statement is recommended.
2376 */
2377 static int test_expired(
2378   void * clientData,
2379   Tcl_Interp *interp,
2380   int objc,
2381   Tcl_Obj *CONST objv[]
2382 ){
2383 #ifndef SQLITE_OMIT_DEPRECATED
2384   sqlite3_stmt *pStmt;
2385   if( objc!=2 ){
2386     Tcl_AppendResult(interp, "wrong # args: should be \"",
2387         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
2388     return TCL_ERROR;
2389   }
2390   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2391   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt)));
2392 #endif
2393   return TCL_OK;
2394 }
2395 
2396 /*
2397 ** Usage:  sqlite3_transfer_bindings FROMSTMT TOSTMT
2398 **
2399 ** Transfer all bindings from FROMSTMT over to TOSTMT
2400 */
2401 static int test_transfer_bind(
2402   void * clientData,
2403   Tcl_Interp *interp,
2404   int objc,
2405   Tcl_Obj *CONST objv[]
2406 ){
2407 #ifndef SQLITE_OMIT_DEPRECATED
2408   sqlite3_stmt *pStmt1, *pStmt2;
2409   if( objc!=3 ){
2410     Tcl_AppendResult(interp, "wrong # args: should be \"",
2411         Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0);
2412     return TCL_ERROR;
2413   }
2414   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR;
2415   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR;
2416   Tcl_SetObjResult(interp,
2417      Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2)));
2418 #endif
2419   return TCL_OK;
2420 }
2421 
2422 /*
2423 ** Usage:  sqlite3_changes DB
2424 **
2425 ** Return the number of changes made to the database by the last SQL
2426 ** execution.
2427 */
2428 static int test_changes(
2429   void * clientData,
2430   Tcl_Interp *interp,
2431   int objc,
2432   Tcl_Obj *CONST objv[]
2433 ){
2434   sqlite3 *db;
2435   if( objc!=2 ){
2436     Tcl_AppendResult(interp, "wrong # args: should be \"",
2437        Tcl_GetString(objv[0]), " DB", 0);
2438     return TCL_ERROR;
2439   }
2440   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2441   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db)));
2442   return TCL_OK;
2443 }
2444 
2445 /*
2446 ** This is the "static_bind_value" that variables are bound to when
2447 ** the FLAG option of sqlite3_bind is "static"
2448 */
2449 static char *sqlite_static_bind_value = 0;
2450 static int sqlite_static_bind_nbyte = 0;
2451 
2452 /*
2453 ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
2454 **
2455 ** Sets the value of the IDX-th occurrence of "?" in the original SQL
2456 ** string.  VALUE is the new value.  If FLAGS=="null" then VALUE is
2457 ** ignored and the value is set to NULL.  If FLAGS=="static" then
2458 ** the value is set to the value of a static variable named
2459 ** "sqlite_static_bind_value".  If FLAGS=="normal" then a copy
2460 ** of the VALUE is made.  If FLAGS=="blob10" then a VALUE is ignored
2461 ** an a 10-byte blob "abc\000xyz\000pq" is inserted.
2462 */
2463 static int test_bind(
2464   void *NotUsed,
2465   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2466   int argc,              /* Number of arguments */
2467   char **argv            /* Text of each argument */
2468 ){
2469   sqlite3_stmt *pStmt;
2470   int rc;
2471   int idx;
2472   if( argc!=5 ){
2473     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2474        " VM IDX VALUE (null|static|normal)\"", 0);
2475     return TCL_ERROR;
2476   }
2477   if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR;
2478   if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
2479   if( strcmp(argv[4],"null")==0 ){
2480     rc = sqlite3_bind_null(pStmt, idx);
2481   }else if( strcmp(argv[4],"static")==0 ){
2482     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
2483   }else if( strcmp(argv[4],"static-nbytes")==0 ){
2484     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value,
2485                                        sqlite_static_bind_nbyte, 0);
2486   }else if( strcmp(argv[4],"normal")==0 ){
2487     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT);
2488   }else if( strcmp(argv[4],"blob10")==0 ){
2489     rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC);
2490   }else{
2491     Tcl_AppendResult(interp, "4th argument should be "
2492         "\"null\" or \"static\" or \"normal\"", 0);
2493     return TCL_ERROR;
2494   }
2495   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
2496   if( rc ){
2497     char zBuf[50];
2498     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
2499     Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
2500     return TCL_ERROR;
2501   }
2502   return TCL_OK;
2503 }
2504 
2505 #ifndef SQLITE_OMIT_UTF16
2506 /*
2507 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
2508 **
2509 ** This function is used to test that SQLite selects the correct collation
2510 ** sequence callback when multiple versions (for different text encodings)
2511 ** are available.
2512 **
2513 ** Calling this routine registers the collation sequence "test_collate"
2514 ** with database handle <db>. The second argument must be a list of three
2515 ** boolean values. If the first is true, then a version of test_collate is
2516 ** registered for UTF-8, if the second is true, a version is registered for
2517 ** UTF-16le, if the third is true, a UTF-16be version is available.
2518 ** Previous versions of test_collate are deleted.
2519 **
2520 ** The collation sequence test_collate is implemented by calling the
2521 ** following TCL script:
2522 **
2523 **   "test_collate <enc> <lhs> <rhs>"
2524 **
2525 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
2526 ** The <enc> parameter is the encoding of the collation function that
2527 ** SQLite selected to call. The TCL test script implements the
2528 ** "test_collate" proc.
2529 **
2530 ** Note that this will only work with one interpreter at a time, as the
2531 ** interp pointer to use when evaluating the TCL script is stored in
2532 ** pTestCollateInterp.
2533 */
2534 static Tcl_Interp* pTestCollateInterp;
2535 static int test_collate_func(
2536   void *pCtx,
2537   int nA, const void *zA,
2538   int nB, const void *zB
2539 ){
2540   Tcl_Interp *i = pTestCollateInterp;
2541   int encin = SQLITE_PTR_TO_INT(pCtx);
2542   int res;
2543   int n;
2544 
2545   sqlite3_value *pVal;
2546   Tcl_Obj *pX;
2547 
2548   pX = Tcl_NewStringObj("test_collate", -1);
2549   Tcl_IncrRefCount(pX);
2550 
2551   switch( encin ){
2552     case SQLITE_UTF8:
2553       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1));
2554       break;
2555     case SQLITE_UTF16LE:
2556       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1));
2557       break;
2558     case SQLITE_UTF16BE:
2559       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
2560       break;
2561     default:
2562       assert(0);
2563   }
2564 
2565   sqlite3BeginBenignMalloc();
2566   pVal = sqlite3ValueNew(0);
2567   if( pVal ){
2568     sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
2569     n = sqlite3_value_bytes(pVal);
2570     Tcl_ListObjAppendElement(i,pX,
2571         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
2572     sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
2573     n = sqlite3_value_bytes(pVal);
2574     Tcl_ListObjAppendElement(i,pX,
2575         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
2576     sqlite3ValueFree(pVal);
2577   }
2578   sqlite3EndBenignMalloc();
2579 
2580   Tcl_EvalObjEx(i, pX, 0);
2581   Tcl_DecrRefCount(pX);
2582   Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
2583   return res;
2584 }
2585 static int test_collate(
2586   void * clientData,
2587   Tcl_Interp *interp,
2588   int objc,
2589   Tcl_Obj *CONST objv[]
2590 ){
2591   sqlite3 *db;
2592   int val;
2593   sqlite3_value *pVal;
2594   int rc;
2595 
2596   if( objc!=5 ) goto bad_args;
2597   pTestCollateInterp = interp;
2598   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2599 
2600   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
2601   rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
2602           (void *)SQLITE_UTF8, val?test_collate_func:0);
2603   if( rc==SQLITE_OK ){
2604     const void *zUtf16;
2605     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
2606     rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
2607             (void *)SQLITE_UTF16LE, val?test_collate_func:0);
2608     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
2609 
2610 #if 0
2611     if( sqlite3_iMallocFail>0 ){
2612       sqlite3_iMallocFail++;
2613     }
2614 #endif
2615     sqlite3_mutex_enter(db->mutex);
2616     pVal = sqlite3ValueNew(db);
2617     sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
2618     zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
2619     if( db->mallocFailed ){
2620       rc = SQLITE_NOMEM;
2621     }else{
2622       rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE,
2623           (void *)SQLITE_UTF16BE, val?test_collate_func:0);
2624     }
2625     sqlite3ValueFree(pVal);
2626     sqlite3_mutex_leave(db->mutex);
2627   }
2628   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2629 
2630   if( rc!=SQLITE_OK ){
2631     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
2632     return TCL_ERROR;
2633   }
2634   return TCL_OK;
2635 
2636 bad_args:
2637   Tcl_AppendResult(interp, "wrong # args: should be \"",
2638       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
2639   return TCL_ERROR;
2640 }
2641 
2642 /*
2643 ** Usage: add_test_utf16bin_collate <db ptr>
2644 **
2645 ** Add a utf-16 collation sequence named "utf16bin" to the database
2646 ** handle. This collation sequence compares arguments in the same way as the
2647 ** built-in collation "binary".
2648 */
2649 static int test_utf16bin_collate_func(
2650   void *pCtx,
2651   int nA, const void *zA,
2652   int nB, const void *zB
2653 ){
2654   int nCmp = (nA>nB ? nB : nA);
2655   int res = memcmp(zA, zB, nCmp);
2656   if( res==0 ) res = nA - nB;
2657   return res;
2658 }
2659 static int test_utf16bin_collate(
2660   void * clientData,
2661   Tcl_Interp *interp,
2662   int objc,
2663   Tcl_Obj *CONST objv[]
2664 ){
2665   sqlite3 *db;
2666   int rc;
2667 
2668   if( objc!=2 ) goto bad_args;
2669   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2670 
2671   rc = sqlite3_create_collation(db, "utf16bin", SQLITE_UTF16, 0,
2672       test_utf16bin_collate_func
2673   );
2674   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2675   return TCL_OK;
2676 
2677 bad_args:
2678   Tcl_WrongNumArgs(interp, 1, objv, "DB");
2679   return TCL_ERROR;
2680 }
2681 
2682 /*
2683 ** When the collation needed callback is invoked, record the name of
2684 ** the requested collating function here.  The recorded name is linked
2685 ** to a TCL variable and used to make sure that the requested collation
2686 ** name is correct.
2687 */
2688 static char zNeededCollation[200];
2689 static char *pzNeededCollation = zNeededCollation;
2690 
2691 
2692 /*
2693 ** Called when a collating sequence is needed.  Registered using
2694 ** sqlite3_collation_needed16().
2695 */
2696 static void test_collate_needed_cb(
2697   void *pCtx,
2698   sqlite3 *db,
2699   int eTextRep,
2700   const void *pName
2701 ){
2702   int enc = ENC(db);
2703   int i;
2704   char *z;
2705   for(z = (char*)pName, i=0; *z || z[1]; z++){
2706     if( *z ) zNeededCollation[i++] = *z;
2707   }
2708   zNeededCollation[i] = 0;
2709   sqlite3_create_collation(
2710       db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func);
2711 }
2712 
2713 /*
2714 ** Usage: add_test_collate_needed DB
2715 */
2716 static int test_collate_needed(
2717   void * clientData,
2718   Tcl_Interp *interp,
2719   int objc,
2720   Tcl_Obj *CONST objv[]
2721 ){
2722   sqlite3 *db;
2723   int rc;
2724 
2725   if( objc!=2 ) goto bad_args;
2726   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2727   rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
2728   zNeededCollation[0] = 0;
2729   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2730   return TCL_OK;
2731 
2732 bad_args:
2733   Tcl_WrongNumArgs(interp, 1, objv, "DB");
2734   return TCL_ERROR;
2735 }
2736 
2737 /*
2738 ** tclcmd:   add_alignment_test_collations  DB
2739 **
2740 ** Add two new collating sequences to the database DB
2741 **
2742 **     utf16_aligned
2743 **     utf16_unaligned
2744 **
2745 ** Both collating sequences use the same sort order as BINARY.
2746 ** The only difference is that the utf16_aligned collating
2747 ** sequence is declared with the SQLITE_UTF16_ALIGNED flag.
2748 ** Both collating functions increment the unaligned utf16 counter
2749 ** whenever they see a string that begins on an odd byte boundary.
2750 */
2751 static int unaligned_string_counter = 0;
2752 static int alignmentCollFunc(
2753   void *NotUsed,
2754   int nKey1, const void *pKey1,
2755   int nKey2, const void *pKey2
2756 ){
2757   int rc, n;
2758   n = nKey1<nKey2 ? nKey1 : nKey2;
2759   if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++;
2760   if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++;
2761   rc = memcmp(pKey1, pKey2, n);
2762   if( rc==0 ){
2763     rc = nKey1 - nKey2;
2764   }
2765   return rc;
2766 }
2767 static int add_alignment_test_collations(
2768   void * clientData,
2769   Tcl_Interp *interp,
2770   int objc,
2771   Tcl_Obj *CONST objv[]
2772 ){
2773   sqlite3 *db;
2774   if( objc>=2 ){
2775     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2776     sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16,
2777         0, alignmentCollFunc);
2778     sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16_ALIGNED,
2779         0, alignmentCollFunc);
2780   }
2781   return SQLITE_OK;
2782 }
2783 #endif /* !defined(SQLITE_OMIT_UTF16) */
2784 
2785 /*
2786 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
2787 **
2788 ** This function is used to test that SQLite selects the correct user
2789 ** function callback when multiple versions (for different text encodings)
2790 ** are available.
2791 **
2792 ** Calling this routine registers up to three versions of the user function
2793 ** "test_function" with database handle <db>.  If the second argument is
2794 ** true, then a version of test_function is registered for UTF-8, if the
2795 ** third is true, a version is registered for UTF-16le, if the fourth is
2796 ** true, a UTF-16be version is available.  Previous versions of
2797 ** test_function are deleted.
2798 **
2799 ** The user function is implemented by calling the following TCL script:
2800 **
2801 **   "test_function <enc> <arg>"
2802 **
2803 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
2804 ** single argument passed to the SQL function. The value returned by
2805 ** the TCL script is used as the return value of the SQL function. It
2806 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
2807 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
2808 ** prefers UTF-16BE.
2809 */
2810 #ifndef SQLITE_OMIT_UTF16
2811 static void test_function_utf8(
2812   sqlite3_context *pCtx,
2813   int nArg,
2814   sqlite3_value **argv
2815 ){
2816   Tcl_Interp *interp;
2817   Tcl_Obj *pX;
2818   sqlite3_value *pVal;
2819   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
2820   pX = Tcl_NewStringObj("test_function", -1);
2821   Tcl_IncrRefCount(pX);
2822   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1));
2823   Tcl_ListObjAppendElement(interp, pX,
2824       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
2825   Tcl_EvalObjEx(interp, pX, 0);
2826   Tcl_DecrRefCount(pX);
2827   sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
2828   pVal = sqlite3ValueNew(0);
2829   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
2830       SQLITE_UTF8, SQLITE_STATIC);
2831   sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
2832       -1, SQLITE_TRANSIENT);
2833   sqlite3ValueFree(pVal);
2834 }
2835 static void test_function_utf16le(
2836   sqlite3_context *pCtx,
2837   int nArg,
2838   sqlite3_value **argv
2839 ){
2840   Tcl_Interp *interp;
2841   Tcl_Obj *pX;
2842   sqlite3_value *pVal;
2843   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
2844   pX = Tcl_NewStringObj("test_function", -1);
2845   Tcl_IncrRefCount(pX);
2846   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1));
2847   Tcl_ListObjAppendElement(interp, pX,
2848       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
2849   Tcl_EvalObjEx(interp, pX, 0);
2850   Tcl_DecrRefCount(pX);
2851   pVal = sqlite3ValueNew(0);
2852   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
2853       SQLITE_UTF8, SQLITE_STATIC);
2854   sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
2855   sqlite3ValueFree(pVal);
2856 }
2857 static void test_function_utf16be(
2858   sqlite3_context *pCtx,
2859   int nArg,
2860   sqlite3_value **argv
2861 ){
2862   Tcl_Interp *interp;
2863   Tcl_Obj *pX;
2864   sqlite3_value *pVal;
2865   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
2866   pX = Tcl_NewStringObj("test_function", -1);
2867   Tcl_IncrRefCount(pX);
2868   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1));
2869   Tcl_ListObjAppendElement(interp, pX,
2870       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
2871   Tcl_EvalObjEx(interp, pX, 0);
2872   Tcl_DecrRefCount(pX);
2873   pVal = sqlite3ValueNew(0);
2874   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
2875       SQLITE_UTF8, SQLITE_STATIC);
2876   sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal),
2877       -1, SQLITE_TRANSIENT);
2878   sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal),
2879       -1, SQLITE_TRANSIENT);
2880   sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
2881       -1, SQLITE_TRANSIENT);
2882   sqlite3ValueFree(pVal);
2883 }
2884 #endif /* SQLITE_OMIT_UTF16 */
2885 static int test_function(
2886   void * clientData,
2887   Tcl_Interp *interp,
2888   int objc,
2889   Tcl_Obj *CONST objv[]
2890 ){
2891 #ifndef SQLITE_OMIT_UTF16
2892   sqlite3 *db;
2893   int val;
2894 
2895   if( objc!=5 ) goto bad_args;
2896   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2897 
2898   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
2899   if( val ){
2900     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8,
2901         interp, test_function_utf8, 0, 0);
2902   }
2903   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
2904   if( val ){
2905     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE,
2906         interp, test_function_utf16le, 0, 0);
2907   }
2908   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
2909   if( val ){
2910     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE,
2911         interp, test_function_utf16be, 0, 0);
2912   }
2913 
2914   return TCL_OK;
2915 bad_args:
2916   Tcl_AppendResult(interp, "wrong # args: should be \"",
2917       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
2918 #endif /* SQLITE_OMIT_UTF16 */
2919   return TCL_ERROR;
2920 }
2921 
2922 /*
2923 ** Usage:         sqlite3_test_errstr <err code>
2924 **
2925 ** Test that the english language string equivalents for sqlite error codes
2926 ** are sane. The parameter is an integer representing an sqlite error code.
2927 ** The result is a list of two elements, the string representation of the
2928 ** error code and the english language explanation.
2929 */
2930 static int test_errstr(
2931   void * clientData,
2932   Tcl_Interp *interp,
2933   int objc,
2934   Tcl_Obj *CONST objv[]
2935 ){
2936   char *zCode;
2937   int i;
2938   if( objc!=1 ){
2939     Tcl_WrongNumArgs(interp, 1, objv, "<error code>");
2940   }
2941 
2942   zCode = Tcl_GetString(objv[1]);
2943   for(i=0; i<200; i++){
2944     if( 0==strcmp(t1ErrorName(i), zCode) ) break;
2945   }
2946   Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
2947   return TCL_OK;
2948 }
2949 
2950 /*
2951 ** Usage:    breakpoint
2952 **
2953 ** This routine exists for one purpose - to provide a place to put a
2954 ** breakpoint with GDB that can be triggered using TCL code.  The use
2955 ** for this is when a particular test fails on (say) the 1485th iteration.
2956 ** In the TCL test script, we can add code like this:
2957 **
2958 **     if {$i==1485} breakpoint
2959 **
2960 ** Then run testfixture in the debugger and wait for the breakpoint to
2961 ** fire.  Then additional breakpoints can be set to trace down the bug.
2962 */
2963 static int test_breakpoint(
2964   void *NotUsed,
2965   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2966   int argc,              /* Number of arguments */
2967   char **argv            /* Text of each argument */
2968 ){
2969   return TCL_OK;         /* Do nothing */
2970 }
2971 
2972 /*
2973 ** Usage:   sqlite3_bind_zeroblob  STMT IDX N
2974 **
2975 ** Test the sqlite3_bind_zeroblob interface.  STMT is a prepared statement.
2976 ** IDX is the index of a wildcard in the prepared statement.  This command
2977 ** binds a N-byte zero-filled BLOB to the wildcard.
2978 */
2979 static int test_bind_zeroblob(
2980   void * clientData,
2981   Tcl_Interp *interp,
2982   int objc,
2983   Tcl_Obj *CONST objv[]
2984 ){
2985   sqlite3_stmt *pStmt;
2986   int idx;
2987   int n;
2988   int rc;
2989 
2990   if( objc!=4 ){
2991     Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
2992     return TCL_ERROR;
2993   }
2994 
2995   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2996   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
2997   if( Tcl_GetIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;
2998 
2999   rc = sqlite3_bind_zeroblob(pStmt, idx, n);
3000   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3001   if( rc!=SQLITE_OK ){
3002     return TCL_ERROR;
3003   }
3004 
3005   return TCL_OK;
3006 }
3007 
3008 /*
3009 ** Usage:   sqlite3_bind_int  STMT N VALUE
3010 **
3011 ** Test the sqlite3_bind_int interface.  STMT is a prepared statement.
3012 ** N is the index of a wildcard in the prepared statement.  This command
3013 ** binds a 32-bit integer VALUE to that wildcard.
3014 */
3015 static int test_bind_int(
3016   void * clientData,
3017   Tcl_Interp *interp,
3018   int objc,
3019   Tcl_Obj *CONST objv[]
3020 ){
3021   sqlite3_stmt *pStmt;
3022   int idx;
3023   int value;
3024   int rc;
3025 
3026   if( objc!=4 ){
3027     Tcl_AppendResult(interp, "wrong # args: should be \"",
3028         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3029     return TCL_ERROR;
3030   }
3031 
3032   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3033   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3034   if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
3035 
3036   rc = sqlite3_bind_int(pStmt, idx, value);
3037   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3038   if( rc!=SQLITE_OK ){
3039     return TCL_ERROR;
3040   }
3041 
3042   return TCL_OK;
3043 }
3044 
3045 
3046 /*
3047 ** Usage:   sqlite3_bind_int64  STMT N VALUE
3048 **
3049 ** Test the sqlite3_bind_int64 interface.  STMT is a prepared statement.
3050 ** N is the index of a wildcard in the prepared statement.  This command
3051 ** binds a 64-bit integer VALUE to that wildcard.
3052 */
3053 static int test_bind_int64(
3054   void * clientData,
3055   Tcl_Interp *interp,
3056   int objc,
3057   Tcl_Obj *CONST objv[]
3058 ){
3059   sqlite3_stmt *pStmt;
3060   int idx;
3061   Tcl_WideInt value;
3062   int rc;
3063 
3064   if( objc!=4 ){
3065     Tcl_AppendResult(interp, "wrong # args: should be \"",
3066         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3067     return TCL_ERROR;
3068   }
3069 
3070   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3071   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3072   if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
3073 
3074   rc = sqlite3_bind_int64(pStmt, idx, value);
3075   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3076   if( rc!=SQLITE_OK ){
3077     return TCL_ERROR;
3078   }
3079 
3080   return TCL_OK;
3081 }
3082 
3083 
3084 /*
3085 ** Usage:   sqlite3_bind_double  STMT N VALUE
3086 **
3087 ** Test the sqlite3_bind_double interface.  STMT is a prepared statement.
3088 ** N is the index of a wildcard in the prepared statement.  This command
3089 ** binds a 64-bit integer VALUE to that wildcard.
3090 */
3091 static int test_bind_double(
3092   void * clientData,
3093   Tcl_Interp *interp,
3094   int objc,
3095   Tcl_Obj *CONST objv[]
3096 ){
3097   sqlite3_stmt *pStmt;
3098   int idx;
3099   double value = 0;
3100   int rc;
3101   const char *zVal;
3102   int i;
3103   static const struct {
3104     const char *zName;     /* Name of the special floating point value */
3105     unsigned int iUpper;   /* Upper 32 bits */
3106     unsigned int iLower;   /* Lower 32 bits */
3107   } aSpecialFp[] = {
3108     {  "NaN",      0x7fffffff, 0xffffffff },
3109     {  "SNaN",     0x7ff7ffff, 0xffffffff },
3110     {  "-NaN",     0xffffffff, 0xffffffff },
3111     {  "-SNaN",    0xfff7ffff, 0xffffffff },
3112     {  "+Inf",     0x7ff00000, 0x00000000 },
3113     {  "-Inf",     0xfff00000, 0x00000000 },
3114     {  "Epsilon",  0x00000000, 0x00000001 },
3115     {  "-Epsilon", 0x80000000, 0x00000001 },
3116     {  "NaN0",     0x7ff80000, 0x00000000 },
3117     {  "-NaN0",    0xfff80000, 0x00000000 },
3118   };
3119 
3120   if( objc!=4 ){
3121     Tcl_AppendResult(interp, "wrong # args: should be \"",
3122         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3123     return TCL_ERROR;
3124   }
3125 
3126   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3127   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3128 
3129   /* Intercept the string "NaN" and generate a NaN value for it.
3130   ** All other strings are passed through to Tcl_GetDoubleFromObj().
3131   ** Tcl_GetDoubleFromObj() should understand "NaN" but some versions
3132   ** contain a bug.
3133   */
3134   zVal = Tcl_GetString(objv[3]);
3135   for(i=0; i<sizeof(aSpecialFp)/sizeof(aSpecialFp[0]); i++){
3136     if( strcmp(aSpecialFp[i].zName, zVal)==0 ){
3137       sqlite3_uint64 x;
3138       x = aSpecialFp[i].iUpper;
3139       x <<= 32;
3140       x |= aSpecialFp[i].iLower;
3141       assert( sizeof(value)==8 );
3142       assert( sizeof(x)==8 );
3143       memcpy(&value, &x, 8);
3144       break;
3145     }
3146   }
3147   if( i>=sizeof(aSpecialFp)/sizeof(aSpecialFp[0]) &&
3148          Tcl_GetDoubleFromObj(interp, objv[3], &value) ){
3149     return TCL_ERROR;
3150   }
3151   rc = sqlite3_bind_double(pStmt, idx, value);
3152   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3153   if( rc!=SQLITE_OK ){
3154     return TCL_ERROR;
3155   }
3156 
3157   return TCL_OK;
3158 }
3159 
3160 /*
3161 ** Usage:   sqlite3_bind_null  STMT N
3162 **
3163 ** Test the sqlite3_bind_null interface.  STMT is a prepared statement.
3164 ** N is the index of a wildcard in the prepared statement.  This command
3165 ** binds a NULL to the wildcard.
3166 */
3167 static int test_bind_null(
3168   void * clientData,
3169   Tcl_Interp *interp,
3170   int objc,
3171   Tcl_Obj *CONST objv[]
3172 ){
3173   sqlite3_stmt *pStmt;
3174   int idx;
3175   int rc;
3176 
3177   if( objc!=3 ){
3178     Tcl_AppendResult(interp, "wrong # args: should be \"",
3179         Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0);
3180     return TCL_ERROR;
3181   }
3182 
3183   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3184   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3185 
3186   rc = sqlite3_bind_null(pStmt, idx);
3187   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3188   if( rc!=SQLITE_OK ){
3189     return TCL_ERROR;
3190   }
3191 
3192   return TCL_OK;
3193 }
3194 
3195 /*
3196 ** Usage:   sqlite3_bind_text  STMT N STRING BYTES
3197 **
3198 ** Test the sqlite3_bind_text interface.  STMT is a prepared statement.
3199 ** N is the index of a wildcard in the prepared statement.  This command
3200 ** binds a UTF-8 string STRING to the wildcard.  The string is BYTES bytes
3201 ** long.
3202 */
3203 static int test_bind_text(
3204   void * clientData,
3205   Tcl_Interp *interp,
3206   int objc,
3207   Tcl_Obj *CONST objv[]
3208 ){
3209   sqlite3_stmt *pStmt;
3210   int idx;
3211   int bytes;
3212   char *value;
3213   int rc;
3214 
3215   if( objc!=5 ){
3216     Tcl_AppendResult(interp, "wrong # args: should be \"",
3217         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
3218     return TCL_ERROR;
3219   }
3220 
3221   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3222   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3223   value = (char*)Tcl_GetByteArrayFromObj(objv[3], &bytes);
3224   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
3225 
3226   rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
3227   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3228   if( rc!=SQLITE_OK ){
3229     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
3230     return TCL_ERROR;
3231   }
3232 
3233   return TCL_OK;
3234 }
3235 
3236 /*
3237 ** Usage:   sqlite3_bind_text16 ?-static? STMT N STRING BYTES
3238 **
3239 ** Test the sqlite3_bind_text16 interface.  STMT is a prepared statement.
3240 ** N is the index of a wildcard in the prepared statement.  This command
3241 ** binds a UTF-16 string STRING to the wildcard.  The string is BYTES bytes
3242 ** long.
3243 */
3244 static int test_bind_text16(
3245   void * clientData,
3246   Tcl_Interp *interp,
3247   int objc,
3248   Tcl_Obj *CONST objv[]
3249 ){
3250 #ifndef SQLITE_OMIT_UTF16
3251   sqlite3_stmt *pStmt;
3252   int idx;
3253   int bytes;
3254   char *value;
3255   int rc;
3256 
3257   void (*xDel)(void*) = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT);
3258   Tcl_Obj *oStmt    = objv[objc-4];
3259   Tcl_Obj *oN       = objv[objc-3];
3260   Tcl_Obj *oString  = objv[objc-2];
3261   Tcl_Obj *oBytes   = objv[objc-1];
3262 
3263   if( objc!=5 && objc!=6){
3264     Tcl_AppendResult(interp, "wrong # args: should be \"",
3265         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
3266     return TCL_ERROR;
3267   }
3268 
3269   if( getStmtPointer(interp, Tcl_GetString(oStmt), &pStmt) ) return TCL_ERROR;
3270   if( Tcl_GetIntFromObj(interp, oN, &idx) ) return TCL_ERROR;
3271   value = (char*)Tcl_GetByteArrayFromObj(oString, 0);
3272   if( Tcl_GetIntFromObj(interp, oBytes, &bytes) ) return TCL_ERROR;
3273 
3274   rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, xDel);
3275   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3276   if( rc!=SQLITE_OK ){
3277     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
3278     return TCL_ERROR;
3279   }
3280 
3281 #endif /* SQLITE_OMIT_UTF16 */
3282   return TCL_OK;
3283 }
3284 
3285 /*
3286 ** Usage:   sqlite3_bind_blob ?-static? STMT N DATA BYTES
3287 **
3288 ** Test the sqlite3_bind_blob interface.  STMT is a prepared statement.
3289 ** N is the index of a wildcard in the prepared statement.  This command
3290 ** binds a BLOB to the wildcard.  The BLOB is BYTES bytes in size.
3291 */
3292 static int test_bind_blob(
3293   void * clientData,
3294   Tcl_Interp *interp,
3295   int objc,
3296   Tcl_Obj *CONST objv[]
3297 ){
3298   sqlite3_stmt *pStmt;
3299   int idx;
3300   int bytes;
3301   char *value;
3302   int rc;
3303   sqlite3_destructor_type xDestructor = SQLITE_TRANSIENT;
3304 
3305   if( objc!=5 && objc!=6 ){
3306     Tcl_AppendResult(interp, "wrong # args: should be \"",
3307         Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0);
3308     return TCL_ERROR;
3309   }
3310 
3311   if( objc==6 ){
3312     xDestructor = SQLITE_STATIC;
3313     objv++;
3314   }
3315 
3316   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3317   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3318   value = Tcl_GetString(objv[3]);
3319   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
3320 
3321   rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
3322   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3323   if( rc!=SQLITE_OK ){
3324     return TCL_ERROR;
3325   }
3326 
3327   return TCL_OK;
3328 }
3329 
3330 /*
3331 ** Usage:   sqlite3_bind_parameter_count  STMT
3332 **
3333 ** Return the number of wildcards in the given statement.
3334 */
3335 static int test_bind_parameter_count(
3336   void * clientData,
3337   Tcl_Interp *interp,
3338   int objc,
3339   Tcl_Obj *CONST objv[]
3340 ){
3341   sqlite3_stmt *pStmt;
3342 
3343   if( objc!=2 ){
3344     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
3345     return TCL_ERROR;
3346   }
3347   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3348   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt)));
3349   return TCL_OK;
3350 }
3351 
3352 /*
3353 ** Usage:   sqlite3_bind_parameter_name  STMT  N
3354 **
3355 ** Return the name of the Nth wildcard.  The first wildcard is 1.
3356 ** An empty string is returned if N is out of range or if the wildcard
3357 ** is nameless.
3358 */
3359 static int test_bind_parameter_name(
3360   void * clientData,
3361   Tcl_Interp *interp,
3362   int objc,
3363   Tcl_Obj *CONST objv[]
3364 ){
3365   sqlite3_stmt *pStmt;
3366   int i;
3367 
3368   if( objc!=3 ){
3369     Tcl_WrongNumArgs(interp, 1, objv, "STMT N");
3370     return TCL_ERROR;
3371   }
3372   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3373   if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR;
3374   Tcl_SetObjResult(interp,
3375      Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1)
3376   );
3377   return TCL_OK;
3378 }
3379 
3380 /*
3381 ** Usage:   sqlite3_bind_parameter_index  STMT  NAME
3382 **
3383 ** Return the index of the wildcard called NAME.  Return 0 if there is
3384 ** no such wildcard.
3385 */
3386 static int test_bind_parameter_index(
3387   void * clientData,
3388   Tcl_Interp *interp,
3389   int objc,
3390   Tcl_Obj *CONST objv[]
3391 ){
3392   sqlite3_stmt *pStmt;
3393 
3394   if( objc!=3 ){
3395     Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME");
3396     return TCL_ERROR;
3397   }
3398   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3399   Tcl_SetObjResult(interp,
3400      Tcl_NewIntObj(
3401        sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2]))
3402      )
3403   );
3404   return TCL_OK;
3405 }
3406 
3407 /*
3408 ** Usage:   sqlite3_clear_bindings STMT
3409 **
3410 */
3411 static int test_clear_bindings(
3412   void * clientData,
3413   Tcl_Interp *interp,
3414   int objc,
3415   Tcl_Obj *CONST objv[]
3416 ){
3417   sqlite3_stmt *pStmt;
3418 
3419   if( objc!=2 ){
3420     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
3421     return TCL_ERROR;
3422   }
3423   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3424   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt)));
3425   return TCL_OK;
3426 }
3427 
3428 /*
3429 ** Usage:   sqlite3_sleep MILLISECONDS
3430 */
3431 static int test_sleep(
3432   void * clientData,
3433   Tcl_Interp *interp,
3434   int objc,
3435   Tcl_Obj *CONST objv[]
3436 ){
3437   int ms;
3438 
3439   if( objc!=2 ){
3440     Tcl_WrongNumArgs(interp, 1, objv, "MILLISECONDS");
3441     return TCL_ERROR;
3442   }
3443   if( Tcl_GetIntFromObj(interp, objv[1], &ms) ){
3444     return TCL_ERROR;
3445   }
3446   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(ms)));
3447   return TCL_OK;
3448 }
3449 
3450 /*
3451 ** Usage: sqlite3_extended_errcode DB
3452 **
3453 ** Return the string representation of the most recent sqlite3_* API
3454 ** error code. e.g. "SQLITE_ERROR".
3455 */
3456 static int test_ex_errcode(
3457   void * clientData,
3458   Tcl_Interp *interp,
3459   int objc,
3460   Tcl_Obj *CONST objv[]
3461 ){
3462   sqlite3 *db;
3463   int rc;
3464 
3465   if( objc!=2 ){
3466     Tcl_AppendResult(interp, "wrong # args: should be \"",
3467        Tcl_GetString(objv[0]), " DB", 0);
3468     return TCL_ERROR;
3469   }
3470   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3471   rc = sqlite3_extended_errcode(db);
3472   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
3473   return TCL_OK;
3474 }
3475 
3476 
3477 /*
3478 ** Usage: sqlite3_errcode DB
3479 **
3480 ** Return the string representation of the most recent sqlite3_* API
3481 ** error code. e.g. "SQLITE_ERROR".
3482 */
3483 static int test_errcode(
3484   void * clientData,
3485   Tcl_Interp *interp,
3486   int objc,
3487   Tcl_Obj *CONST objv[]
3488 ){
3489   sqlite3 *db;
3490   int rc;
3491 
3492   if( objc!=2 ){
3493     Tcl_AppendResult(interp, "wrong # args: should be \"",
3494        Tcl_GetString(objv[0]), " DB", 0);
3495     return TCL_ERROR;
3496   }
3497   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3498   rc = sqlite3_errcode(db);
3499   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
3500   return TCL_OK;
3501 }
3502 
3503 /*
3504 ** Usage:   sqlite3_errmsg DB
3505 **
3506 ** Returns the UTF-8 representation of the error message string for the
3507 ** most recent sqlite3_* API call.
3508 */
3509 static int test_errmsg(
3510   void * clientData,
3511   Tcl_Interp *interp,
3512   int objc,
3513   Tcl_Obj *CONST objv[]
3514 ){
3515   sqlite3 *db;
3516   const char *zErr;
3517 
3518   if( objc!=2 ){
3519     Tcl_AppendResult(interp, "wrong # args: should be \"",
3520        Tcl_GetString(objv[0]), " DB", 0);
3521     return TCL_ERROR;
3522   }
3523   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3524 
3525   zErr = sqlite3_errmsg(db);
3526   Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
3527   return TCL_OK;
3528 }
3529 
3530 /*
3531 ** Usage:   test_errmsg16 DB
3532 **
3533 ** Returns the UTF-16 representation of the error message string for the
3534 ** most recent sqlite3_* API call. This is a byte array object at the TCL
3535 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
3536 ** UTF-16 string.
3537 */
3538 static int test_errmsg16(
3539   void * clientData,
3540   Tcl_Interp *interp,
3541   int objc,
3542   Tcl_Obj *CONST objv[]
3543 ){
3544 #ifndef SQLITE_OMIT_UTF16
3545   sqlite3 *db;
3546   const void *zErr;
3547   const char *z;
3548   int bytes = 0;
3549 
3550   if( objc!=2 ){
3551     Tcl_AppendResult(interp, "wrong # args: should be \"",
3552        Tcl_GetString(objv[0]), " DB", 0);
3553     return TCL_ERROR;
3554   }
3555   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3556 
3557   zErr = sqlite3_errmsg16(db);
3558   if( zErr ){
3559     z = zErr;
3560     for(bytes=0; z[bytes] || z[bytes+1]; bytes+=2){}
3561   }
3562   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
3563 #endif /* SQLITE_OMIT_UTF16 */
3564   return TCL_OK;
3565 }
3566 
3567 /*
3568 ** Usage: sqlite3_prepare DB sql bytes ?tailvar?
3569 **
3570 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3571 ** database handle <DB>. The parameter <tailval> is the name of a global
3572 ** variable that is set to the unused portion of <sql> (if any). A
3573 ** STMT handle is returned.
3574 */
3575 static int test_prepare(
3576   void * clientData,
3577   Tcl_Interp *interp,
3578   int objc,
3579   Tcl_Obj *CONST objv[]
3580 ){
3581   sqlite3 *db;
3582   const char *zSql;
3583   int bytes;
3584   const char *zTail = 0;
3585   sqlite3_stmt *pStmt = 0;
3586   char zBuf[50];
3587   int rc;
3588 
3589   if( objc!=5 && objc!=4 ){
3590     Tcl_AppendResult(interp, "wrong # args: should be \"",
3591        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
3592     return TCL_ERROR;
3593   }
3594   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3595   zSql = Tcl_GetString(objv[2]);
3596   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
3597 
3598   rc = sqlite3_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
3599   Tcl_ResetResult(interp);
3600   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3601   if( zTail && objc>=5 ){
3602     if( bytes>=0 ){
3603       bytes = bytes - (int)(zTail-zSql);
3604     }
3605     if( (int)strlen(zTail)<bytes ){
3606       bytes = (int)strlen(zTail);
3607     }
3608     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
3609   }
3610   if( rc!=SQLITE_OK ){
3611     assert( pStmt==0 );
3612     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
3613     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
3614     return TCL_ERROR;
3615   }
3616 
3617   if( pStmt ){
3618     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3619     Tcl_AppendResult(interp, zBuf, 0);
3620   }
3621   return TCL_OK;
3622 }
3623 
3624 /*
3625 ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar?
3626 **
3627 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3628 ** database handle <DB>. The parameter <tailval> is the name of a global
3629 ** variable that is set to the unused portion of <sql> (if any). A
3630 ** STMT handle is returned.
3631 */
3632 static int test_prepare_v2(
3633   void * clientData,
3634   Tcl_Interp *interp,
3635   int objc,
3636   Tcl_Obj *CONST objv[]
3637 ){
3638   sqlite3 *db;
3639   const char *zSql;
3640   char *zCopy = 0;                /* malloc() copy of zSql */
3641   int bytes;
3642   const char *zTail = 0;
3643   sqlite3_stmt *pStmt = 0;
3644   char zBuf[50];
3645   int rc;
3646 
3647   if( objc!=5 && objc!=4 ){
3648     Tcl_AppendResult(interp, "wrong # args: should be \"",
3649        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
3650     return TCL_ERROR;
3651   }
3652   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3653   zSql = Tcl_GetString(objv[2]);
3654   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
3655 
3656   /* Instead of using zSql directly, make a copy into a buffer obtained
3657   ** directly from malloc(). The idea is to make it easier for valgrind
3658   ** to spot buffer overreads.  */
3659   if( bytes>=0 ){
3660     zCopy = malloc(bytes);
3661     memcpy(zCopy, zSql, bytes);
3662   }else{
3663     int n = (int)strlen(zSql) + 1;
3664     zCopy = malloc(n);
3665     memcpy(zCopy, zSql, n);
3666   }
3667   rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
3668   free(zCopy);
3669   zTail = &zSql[(zTail - zCopy)];
3670 
3671   assert(rc==SQLITE_OK || pStmt==0);
3672   Tcl_ResetResult(interp);
3673   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3674   if( rc==SQLITE_OK && zTail && objc>=5 ){
3675     if( bytes>=0 ){
3676       bytes = bytes - (int)(zTail-zSql);
3677     }
3678     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
3679   }
3680   if( rc!=SQLITE_OK ){
3681     assert( pStmt==0 );
3682     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
3683     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
3684     return TCL_ERROR;
3685   }
3686 
3687   if( pStmt ){
3688     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3689     Tcl_AppendResult(interp, zBuf, 0);
3690   }
3691   return TCL_OK;
3692 }
3693 
3694 /*
3695 ** Usage: sqlite3_prepare_tkt3134 DB
3696 **
3697 ** Generate a prepared statement for a zero-byte string as a test
3698 ** for ticket #3134.  The string should be preceded by a zero byte.
3699 */
3700 static int test_prepare_tkt3134(
3701   void * clientData,
3702   Tcl_Interp *interp,
3703   int objc,
3704   Tcl_Obj *CONST objv[]
3705 ){
3706   sqlite3 *db;
3707   static const char zSql[] = "\000SELECT 1";
3708   sqlite3_stmt *pStmt = 0;
3709   char zBuf[50];
3710   int rc;
3711 
3712   if( objc!=2 ){
3713     Tcl_AppendResult(interp, "wrong # args: should be \"",
3714        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
3715     return TCL_ERROR;
3716   }
3717   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3718   rc = sqlite3_prepare_v2(db, &zSql[1], 0, &pStmt, 0);
3719   assert(rc==SQLITE_OK || pStmt==0);
3720   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3721   if( rc!=SQLITE_OK ){
3722     assert( pStmt==0 );
3723     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
3724     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
3725     return TCL_ERROR;
3726   }
3727 
3728   if( pStmt ){
3729     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3730     Tcl_AppendResult(interp, zBuf, 0);
3731   }
3732   return TCL_OK;
3733 }
3734 
3735 /*
3736 ** Usage: sqlite3_prepare16 DB sql bytes tailvar
3737 **
3738 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3739 ** database handle <DB>. The parameter <tailval> is the name of a global
3740 ** variable that is set to the unused portion of <sql> (if any). A
3741 ** STMT handle is returned.
3742 */
3743 static int test_prepare16(
3744   void * clientData,
3745   Tcl_Interp *interp,
3746   int objc,
3747   Tcl_Obj *CONST objv[]
3748 ){
3749 #ifndef SQLITE_OMIT_UTF16
3750   sqlite3 *db;
3751   const void *zSql;
3752   const void *zTail = 0;
3753   Tcl_Obj *pTail = 0;
3754   sqlite3_stmt *pStmt = 0;
3755   char zBuf[50];
3756   int rc;
3757   int bytes;                /* The integer specified as arg 3 */
3758   int objlen;               /* The byte-array length of arg 2 */
3759 
3760   if( objc!=5 && objc!=4 ){
3761     Tcl_AppendResult(interp, "wrong # args: should be \"",
3762        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
3763     return TCL_ERROR;
3764   }
3765   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3766   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
3767   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
3768 
3769   rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
3770   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3771   if( rc ){
3772     return TCL_ERROR;
3773   }
3774 
3775   if( objc>=5 ){
3776     if( zTail ){
3777       objlen = objlen - (int)((u8 *)zTail-(u8 *)zSql);
3778     }else{
3779       objlen = 0;
3780     }
3781     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
3782     Tcl_IncrRefCount(pTail);
3783     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
3784     Tcl_DecrRefCount(pTail);
3785   }
3786 
3787   if( pStmt ){
3788     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3789   }
3790   Tcl_AppendResult(interp, zBuf, 0);
3791 #endif /* SQLITE_OMIT_UTF16 */
3792   return TCL_OK;
3793 }
3794 
3795 /*
3796 ** Usage: sqlite3_prepare16_v2 DB sql bytes ?tailvar?
3797 **
3798 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3799 ** database handle <DB>. The parameter <tailval> is the name of a global
3800 ** variable that is set to the unused portion of <sql> (if any). A
3801 ** STMT handle is returned.
3802 */
3803 static int test_prepare16_v2(
3804   void * clientData,
3805   Tcl_Interp *interp,
3806   int objc,
3807   Tcl_Obj *CONST objv[]
3808 ){
3809 #ifndef SQLITE_OMIT_UTF16
3810   sqlite3 *db;
3811   const void *zSql;
3812   const void *zTail = 0;
3813   Tcl_Obj *pTail = 0;
3814   sqlite3_stmt *pStmt = 0;
3815   char zBuf[50];
3816   int rc;
3817   int bytes;                /* The integer specified as arg 3 */
3818   int objlen;               /* The byte-array length of arg 2 */
3819 
3820   if( objc!=5 && objc!=4 ){
3821     Tcl_AppendResult(interp, "wrong # args: should be \"",
3822        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
3823     return TCL_ERROR;
3824   }
3825   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3826   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
3827   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
3828 
3829   rc = sqlite3_prepare16_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
3830   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3831   if( rc ){
3832     return TCL_ERROR;
3833   }
3834 
3835   if( objc>=5 ){
3836     if( zTail ){
3837       objlen = objlen - (int)((u8 *)zTail-(u8 *)zSql);
3838     }else{
3839       objlen = 0;
3840     }
3841     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
3842     Tcl_IncrRefCount(pTail);
3843     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
3844     Tcl_DecrRefCount(pTail);
3845   }
3846 
3847   if( pStmt ){
3848     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3849   }
3850   Tcl_AppendResult(interp, zBuf, 0);
3851 #endif /* SQLITE_OMIT_UTF16 */
3852   return TCL_OK;
3853 }
3854 
3855 /*
3856 ** Usage: sqlite3_open filename ?options-list?
3857 */
3858 static int test_open(
3859   void * clientData,
3860   Tcl_Interp *interp,
3861   int objc,
3862   Tcl_Obj *CONST objv[]
3863 ){
3864   const char *zFilename;
3865   sqlite3 *db;
3866   char zBuf[100];
3867 
3868   if( objc!=3 && objc!=2 && objc!=1 ){
3869     Tcl_AppendResult(interp, "wrong # args: should be \"",
3870        Tcl_GetString(objv[0]), " filename options-list", 0);
3871     return TCL_ERROR;
3872   }
3873 
3874   zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0;
3875   sqlite3_open(zFilename, &db);
3876 
3877   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
3878   Tcl_AppendResult(interp, zBuf, 0);
3879   return TCL_OK;
3880 }
3881 
3882 /*
3883 ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
3884 */
3885 static int test_open_v2(
3886   void * clientData,
3887   Tcl_Interp *interp,
3888   int objc,
3889   Tcl_Obj *CONST objv[]
3890 ){
3891   const char *zFilename;
3892   const char *zVfs;
3893   int flags = 0;
3894   sqlite3 *db;
3895   int rc;
3896   char zBuf[100];
3897 
3898   int nFlag;
3899   Tcl_Obj **apFlag;
3900   int i;
3901 
3902   if( objc!=4 ){
3903     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS");
3904     return TCL_ERROR;
3905   }
3906   zFilename = Tcl_GetString(objv[1]);
3907   zVfs = Tcl_GetString(objv[3]);
3908   if( zVfs[0]==0x00 ) zVfs = 0;
3909 
3910   rc = Tcl_ListObjGetElements(interp, objv[2], &nFlag, &apFlag);
3911   if( rc!=TCL_OK ) return rc;
3912   for(i=0; i<nFlag; i++){
3913     int iFlag;
3914     struct OpenFlag {
3915       const char *zFlag;
3916       int flag;
3917     } aFlag[] = {
3918       { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY },
3919       { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE },
3920       { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE },
3921       { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE },
3922       { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE },
3923       { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY },
3924       { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB },
3925       { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB },
3926       { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB },
3927       { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL },
3928       { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL },
3929       { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL },
3930       { "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL },
3931       { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX },
3932       { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX },
3933       { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE },
3934       { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE },
3935       { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL },
3936       { "SQLITE_OPEN_URI", SQLITE_OPEN_URI },
3937       { 0, 0 }
3938     };
3939     rc = Tcl_GetIndexFromObjStruct(interp, apFlag[i], aFlag, sizeof(aFlag[0]),
3940         "flag", 0, &iFlag
3941     );
3942     if( rc!=TCL_OK ) return rc;
3943     flags |= aFlag[iFlag].flag;
3944   }
3945 
3946   rc = sqlite3_open_v2(zFilename, &db, flags, zVfs);
3947   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
3948   Tcl_AppendResult(interp, zBuf, 0);
3949   return TCL_OK;
3950 }
3951 
3952 /*
3953 ** Usage: sqlite3_open16 filename options
3954 */
3955 static int test_open16(
3956   void * clientData,
3957   Tcl_Interp *interp,
3958   int objc,
3959   Tcl_Obj *CONST objv[]
3960 ){
3961 #ifndef SQLITE_OMIT_UTF16
3962   const void *zFilename;
3963   sqlite3 *db;
3964   char zBuf[100];
3965 
3966   if( objc!=3 ){
3967     Tcl_AppendResult(interp, "wrong # args: should be \"",
3968        Tcl_GetString(objv[0]), " filename options-list", 0);
3969     return TCL_ERROR;
3970   }
3971 
3972   zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
3973   sqlite3_open16(zFilename, &db);
3974 
3975   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
3976   Tcl_AppendResult(interp, zBuf, 0);
3977 #endif /* SQLITE_OMIT_UTF16 */
3978   return TCL_OK;
3979 }
3980 
3981 /*
3982 ** Usage: sqlite3_complete16 <UTF-16 string>
3983 **
3984 ** Return 1 if the supplied argument is a complete SQL statement, or zero
3985 ** otherwise.
3986 */
3987 static int test_complete16(
3988   void * clientData,
3989   Tcl_Interp *interp,
3990   int objc,
3991   Tcl_Obj *CONST objv[]
3992 ){
3993 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
3994   char *zBuf;
3995 
3996   if( objc!=2 ){
3997     Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
3998     return TCL_ERROR;
3999   }
4000 
4001   zBuf = (char*)Tcl_GetByteArrayFromObj(objv[1], 0);
4002   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
4003 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
4004   return TCL_OK;
4005 }
4006 
4007 /*
4008 ** Usage: sqlite3_step STMT
4009 **
4010 ** Advance the statement to the next row.
4011 */
4012 static int test_step(
4013   void * clientData,
4014   Tcl_Interp *interp,
4015   int objc,
4016   Tcl_Obj *CONST objv[]
4017 ){
4018   sqlite3_stmt *pStmt;
4019   int rc;
4020 
4021   if( objc!=2 ){
4022     Tcl_AppendResult(interp, "wrong # args: should be \"",
4023        Tcl_GetString(objv[0]), " STMT", 0);
4024     return TCL_ERROR;
4025   }
4026 
4027   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4028   rc = sqlite3_step(pStmt);
4029 
4030   /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
4031   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
4032   return TCL_OK;
4033 }
4034 
4035 static int test_sql(
4036   void * clientData,
4037   Tcl_Interp *interp,
4038   int objc,
4039   Tcl_Obj *CONST objv[]
4040 ){
4041   sqlite3_stmt *pStmt;
4042 
4043   if( objc!=2 ){
4044     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
4045     return TCL_ERROR;
4046   }
4047 
4048   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4049   Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
4050   return TCL_OK;
4051 }
4052 
4053 /*
4054 ** Usage: sqlite3_column_count STMT
4055 **
4056 ** Return the number of columns returned by the sql statement STMT.
4057 */
4058 static int test_column_count(
4059   void * clientData,
4060   Tcl_Interp *interp,
4061   int objc,
4062   Tcl_Obj *CONST objv[]
4063 ){
4064   sqlite3_stmt *pStmt;
4065 
4066   if( objc!=2 ){
4067     Tcl_AppendResult(interp, "wrong # args: should be \"",
4068        Tcl_GetString(objv[0]), " STMT column", 0);
4069     return TCL_ERROR;
4070   }
4071 
4072   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4073 
4074   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt)));
4075   return TCL_OK;
4076 }
4077 
4078 /*
4079 ** Usage: sqlite3_column_type STMT column
4080 **
4081 ** Return the type of the data in column 'column' of the current row.
4082 */
4083 static int test_column_type(
4084   void * clientData,
4085   Tcl_Interp *interp,
4086   int objc,
4087   Tcl_Obj *CONST objv[]
4088 ){
4089   sqlite3_stmt *pStmt;
4090   int col;
4091   int tp;
4092 
4093   if( objc!=3 ){
4094     Tcl_AppendResult(interp, "wrong # args: should be \"",
4095        Tcl_GetString(objv[0]), " STMT column", 0);
4096     return TCL_ERROR;
4097   }
4098 
4099   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4100   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4101 
4102   tp = sqlite3_column_type(pStmt, col);
4103   switch( tp ){
4104     case SQLITE_INTEGER:
4105       Tcl_SetResult(interp, "INTEGER", TCL_STATIC);
4106       break;
4107     case SQLITE_NULL:
4108       Tcl_SetResult(interp, "NULL", TCL_STATIC);
4109       break;
4110     case SQLITE_FLOAT:
4111       Tcl_SetResult(interp, "FLOAT", TCL_STATIC);
4112       break;
4113     case SQLITE_TEXT:
4114       Tcl_SetResult(interp, "TEXT", TCL_STATIC);
4115       break;
4116     case SQLITE_BLOB:
4117       Tcl_SetResult(interp, "BLOB", TCL_STATIC);
4118       break;
4119     default:
4120       assert(0);
4121   }
4122 
4123   return TCL_OK;
4124 }
4125 
4126 /*
4127 ** Usage: sqlite3_column_int64 STMT column
4128 **
4129 ** Return the data in column 'column' of the current row cast as an
4130 ** wide (64-bit) integer.
4131 */
4132 static int test_column_int64(
4133   void * clientData,
4134   Tcl_Interp *interp,
4135   int objc,
4136   Tcl_Obj *CONST objv[]
4137 ){
4138   sqlite3_stmt *pStmt;
4139   int col;
4140   i64 iVal;
4141 
4142   if( objc!=3 ){
4143     Tcl_AppendResult(interp, "wrong # args: should be \"",
4144        Tcl_GetString(objv[0]), " STMT column", 0);
4145     return TCL_ERROR;
4146   }
4147 
4148   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4149   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4150 
4151   iVal = sqlite3_column_int64(pStmt, col);
4152   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal));
4153   return TCL_OK;
4154 }
4155 
4156 /*
4157 ** Usage: sqlite3_column_blob STMT column
4158 */
4159 static int test_column_blob(
4160   void * clientData,
4161   Tcl_Interp *interp,
4162   int objc,
4163   Tcl_Obj *CONST objv[]
4164 ){
4165   sqlite3_stmt *pStmt;
4166   int col;
4167 
4168   int len;
4169   const void *pBlob;
4170 
4171   if( objc!=3 ){
4172     Tcl_AppendResult(interp, "wrong # args: should be \"",
4173        Tcl_GetString(objv[0]), " STMT column", 0);
4174     return TCL_ERROR;
4175   }
4176 
4177   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4178   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4179 
4180   len = sqlite3_column_bytes(pStmt, col);
4181   pBlob = sqlite3_column_blob(pStmt, col);
4182   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
4183   return TCL_OK;
4184 }
4185 
4186 /*
4187 ** Usage: sqlite3_column_double STMT column
4188 **
4189 ** Return the data in column 'column' of the current row cast as a double.
4190 */
4191 static int test_column_double(
4192   void * clientData,
4193   Tcl_Interp *interp,
4194   int objc,
4195   Tcl_Obj *CONST objv[]
4196 ){
4197   sqlite3_stmt *pStmt;
4198   int col;
4199   double rVal;
4200 
4201   if( objc!=3 ){
4202     Tcl_AppendResult(interp, "wrong # args: should be \"",
4203        Tcl_GetString(objv[0]), " STMT column", 0);
4204     return TCL_ERROR;
4205   }
4206 
4207   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4208   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4209 
4210   rVal = sqlite3_column_double(pStmt, col);
4211   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
4212   return TCL_OK;
4213 }
4214 
4215 /*
4216 ** Usage: sqlite3_data_count STMT
4217 **
4218 ** Return the number of columns returned by the sql statement STMT.
4219 */
4220 static int test_data_count(
4221   void * clientData,
4222   Tcl_Interp *interp,
4223   int objc,
4224   Tcl_Obj *CONST objv[]
4225 ){
4226   sqlite3_stmt *pStmt;
4227 
4228   if( objc!=2 ){
4229     Tcl_AppendResult(interp, "wrong # args: should be \"",
4230        Tcl_GetString(objv[0]), " STMT column", 0);
4231     return TCL_ERROR;
4232   }
4233 
4234   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4235 
4236   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt)));
4237   return TCL_OK;
4238 }
4239 
4240 /*
4241 ** Usage: sqlite3_column_text STMT column
4242 **
4243 ** Usage: sqlite3_column_decltype STMT column
4244 **
4245 ** Usage: sqlite3_column_name STMT column
4246 */
4247 static int test_stmt_utf8(
4248   void * clientData,        /* Pointer to SQLite API function to be invoke */
4249   Tcl_Interp *interp,
4250   int objc,
4251   Tcl_Obj *CONST objv[]
4252 ){
4253   sqlite3_stmt *pStmt;
4254   int col;
4255   const char *(*xFunc)(sqlite3_stmt*, int);
4256   const char *zRet;
4257 
4258   xFunc = (const char *(*)(sqlite3_stmt*, int))clientData;
4259   if( objc!=3 ){
4260     Tcl_AppendResult(interp, "wrong # args: should be \"",
4261        Tcl_GetString(objv[0]), " STMT column", 0);
4262     return TCL_ERROR;
4263   }
4264 
4265   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4266   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4267   zRet = xFunc(pStmt, col);
4268   if( zRet ){
4269     Tcl_SetResult(interp, (char *)zRet, 0);
4270   }
4271   return TCL_OK;
4272 }
4273 
4274 static int test_global_recover(
4275   void * clientData,
4276   Tcl_Interp *interp,
4277   int objc,
4278   Tcl_Obj *CONST objv[]
4279 ){
4280 #ifndef SQLITE_OMIT_DEPRECATED
4281   int rc;
4282   if( objc!=1 ){
4283     Tcl_WrongNumArgs(interp, 1, objv, "");
4284     return TCL_ERROR;
4285   }
4286   rc = sqlite3_global_recover();
4287   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4288 #endif
4289   return TCL_OK;
4290 }
4291 
4292 /*
4293 ** Usage: sqlite3_column_text STMT column
4294 **
4295 ** Usage: sqlite3_column_decltype STMT column
4296 **
4297 ** Usage: sqlite3_column_name STMT column
4298 */
4299 static int test_stmt_utf16(
4300   void * clientData,     /* Pointer to SQLite API function to be invoked */
4301   Tcl_Interp *interp,
4302   int objc,
4303   Tcl_Obj *CONST objv[]
4304 ){
4305 #ifndef SQLITE_OMIT_UTF16
4306   sqlite3_stmt *pStmt;
4307   int col;
4308   Tcl_Obj *pRet;
4309   const void *zName16;
4310   const void *(*xFunc)(sqlite3_stmt*, int);
4311 
4312   xFunc = (const void *(*)(sqlite3_stmt*, int))clientData;
4313   if( objc!=3 ){
4314     Tcl_AppendResult(interp, "wrong # args: should be \"",
4315        Tcl_GetString(objv[0]), " STMT column", 0);
4316     return TCL_ERROR;
4317   }
4318 
4319   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4320   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4321 
4322   zName16 = xFunc(pStmt, col);
4323   if( zName16 ){
4324     int n;
4325     const char *z = zName16;
4326     for(n=0; z[n] || z[n+1]; n+=2){}
4327     pRet = Tcl_NewByteArrayObj(zName16, n+2);
4328     Tcl_SetObjResult(interp, pRet);
4329   }
4330 #endif /* SQLITE_OMIT_UTF16 */
4331 
4332   return TCL_OK;
4333 }
4334 
4335 /*
4336 ** Usage: sqlite3_column_int STMT column
4337 **
4338 ** Usage: sqlite3_column_bytes STMT column
4339 **
4340 ** Usage: sqlite3_column_bytes16 STMT column
4341 **
4342 */
4343 static int test_stmt_int(
4344   void * clientData,    /* Pointer to SQLite API function to be invoked */
4345   Tcl_Interp *interp,
4346   int objc,
4347   Tcl_Obj *CONST objv[]
4348 ){
4349   sqlite3_stmt *pStmt;
4350   int col;
4351   int (*xFunc)(sqlite3_stmt*, int);
4352 
4353   xFunc = (int (*)(sqlite3_stmt*, int))clientData;
4354   if( objc!=3 ){
4355     Tcl_AppendResult(interp, "wrong # args: should be \"",
4356        Tcl_GetString(objv[0]), " STMT column", 0);
4357     return TCL_ERROR;
4358   }
4359 
4360   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4361   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4362 
4363   Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col)));
4364   return TCL_OK;
4365 }
4366 
4367 /*
4368 ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
4369 **
4370 ** Set the db->magic value.  This is used to test error recovery logic.
4371 */
4372 static int sqlite_set_magic(
4373   void * clientData,
4374   Tcl_Interp *interp,
4375   int argc,
4376   char **argv
4377 ){
4378   sqlite3 *db;
4379   if( argc!=3 ){
4380     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4381          " DB MAGIC", 0);
4382     return TCL_ERROR;
4383   }
4384   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4385   if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){
4386     db->magic = SQLITE_MAGIC_OPEN;
4387   }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){
4388     db->magic = SQLITE_MAGIC_CLOSED;
4389   }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){
4390     db->magic = SQLITE_MAGIC_BUSY;
4391   }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){
4392     db->magic = SQLITE_MAGIC_ERROR;
4393   }else if( Tcl_GetInt(interp, argv[2], (int*)&db->magic) ){
4394     return TCL_ERROR;
4395   }
4396   return TCL_OK;
4397 }
4398 
4399 /*
4400 ** Usage:  sqlite3_interrupt  DB
4401 **
4402 ** Trigger an interrupt on DB
4403 */
4404 static int test_interrupt(
4405   void * clientData,
4406   Tcl_Interp *interp,
4407   int argc,
4408   char **argv
4409 ){
4410   sqlite3 *db;
4411   if( argc!=2 ){
4412     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0);
4413     return TCL_ERROR;
4414   }
4415   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4416   sqlite3_interrupt(db);
4417   return TCL_OK;
4418 }
4419 
4420 static u8 *sqlite3_stack_baseline = 0;
4421 
4422 /*
4423 ** Fill the stack with a known bitpattern.
4424 */
4425 static void prepStack(void){
4426   int i;
4427   u32 bigBuf[65536];
4428   for(i=0; i<sizeof(bigBuf)/sizeof(bigBuf[0]); i++) bigBuf[i] = 0xdeadbeef;
4429   sqlite3_stack_baseline = (u8*)&bigBuf[65536];
4430 }
4431 
4432 /*
4433 ** Get the current stack depth.  Used for debugging only.
4434 */
4435 u64 sqlite3StackDepth(void){
4436   u8 x;
4437   return (u64)(sqlite3_stack_baseline - &x);
4438 }
4439 
4440 /*
4441 ** Usage:  sqlite3_stack_used DB SQL
4442 **
4443 ** Try to measure the amount of stack space used by a call to sqlite3_exec
4444 */
4445 static int test_stack_used(
4446   void * clientData,
4447   Tcl_Interp *interp,
4448   int argc,
4449   char **argv
4450 ){
4451   sqlite3 *db;
4452   int i;
4453   if( argc!=3 ){
4454     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4455         " DB SQL", 0);
4456     return TCL_ERROR;
4457   }
4458   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4459   prepStack();
4460   (void)sqlite3_exec(db, argv[2], 0, 0, 0);
4461   for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
4462   Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
4463   return TCL_OK;
4464 }
4465 
4466 /*
4467 ** Usage: sqlite_delete_function DB function-name
4468 **
4469 ** Delete the user function 'function-name' from database handle DB. It
4470 ** is assumed that the user function was created as UTF8, any number of
4471 ** arguments (the way the TCL interface does it).
4472 */
4473 static int delete_function(
4474   void * clientData,
4475   Tcl_Interp *interp,
4476   int argc,
4477   char **argv
4478 ){
4479   int rc;
4480   sqlite3 *db;
4481   if( argc!=3 ){
4482     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4483         " DB function-name", 0);
4484     return TCL_ERROR;
4485   }
4486   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4487   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
4488   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4489   return TCL_OK;
4490 }
4491 
4492 /*
4493 ** Usage: sqlite_delete_collation DB collation-name
4494 **
4495 ** Delete the collation sequence 'collation-name' from database handle
4496 ** DB. It is assumed that the collation sequence was created as UTF8 (the
4497 ** way the TCL interface does it).
4498 */
4499 static int delete_collation(
4500   void * clientData,
4501   Tcl_Interp *interp,
4502   int argc,
4503   char **argv
4504 ){
4505   int rc;
4506   sqlite3 *db;
4507   if( argc!=3 ){
4508     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4509         " DB function-name", 0);
4510     return TCL_ERROR;
4511   }
4512   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4513   rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
4514   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4515   return TCL_OK;
4516 }
4517 
4518 /*
4519 ** Usage: sqlite3_get_autocommit DB
4520 **
4521 ** Return true if the database DB is currently in auto-commit mode.
4522 ** Return false if not.
4523 */
4524 static int get_autocommit(
4525   void * clientData,
4526   Tcl_Interp *interp,
4527   int argc,
4528   char **argv
4529 ){
4530   char zBuf[30];
4531   sqlite3 *db;
4532   if( argc!=2 ){
4533     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4534         " DB", 0);
4535     return TCL_ERROR;
4536   }
4537   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4538   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3_get_autocommit(db));
4539   Tcl_AppendResult(interp, zBuf, 0);
4540   return TCL_OK;
4541 }
4542 
4543 /*
4544 ** Usage: sqlite3_busy_timeout DB MS
4545 **
4546 ** Set the busy timeout.  This is more easily done using the timeout
4547 ** method of the TCL interface.  But we need a way to test the case
4548 ** where it returns SQLITE_MISUSE.
4549 */
4550 static int test_busy_timeout(
4551   void * clientData,
4552   Tcl_Interp *interp,
4553   int argc,
4554   char **argv
4555 ){
4556   int rc, ms;
4557   sqlite3 *db;
4558   if( argc!=3 ){
4559     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4560         " DB", 0);
4561     return TCL_ERROR;
4562   }
4563   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4564   if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR;
4565   rc = sqlite3_busy_timeout(db, ms);
4566   Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
4567   return TCL_OK;
4568 }
4569 
4570 /*
4571 ** Usage:  tcl_variable_type VARIABLENAME
4572 **
4573 ** Return the name of the internal representation for the
4574 ** value of the given variable.
4575 */
4576 static int tcl_variable_type(
4577   void * clientData,
4578   Tcl_Interp *interp,
4579   int objc,
4580   Tcl_Obj *CONST objv[]
4581 ){
4582   Tcl_Obj *pVar;
4583   if( objc!=2 ){
4584     Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE");
4585     return TCL_ERROR;
4586   }
4587   pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG);
4588   if( pVar==0 ) return TCL_ERROR;
4589   if( pVar->typePtr ){
4590     Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1));
4591   }
4592   return TCL_OK;
4593 }
4594 
4595 /*
4596 ** Usage:  sqlite3_release_memory ?N?
4597 **
4598 ** Attempt to release memory currently held but not actually required.
4599 ** The integer N is the number of bytes we are trying to release.  The
4600 ** return value is the amount of memory actually released.
4601 */
4602 static int test_release_memory(
4603   void * clientData,
4604   Tcl_Interp *interp,
4605   int objc,
4606   Tcl_Obj *CONST objv[]
4607 ){
4608 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
4609   int N;
4610   int amt;
4611   if( objc!=1 && objc!=2 ){
4612     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
4613     return TCL_ERROR;
4614   }
4615   if( objc==2 ){
4616     if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
4617   }else{
4618     N = -1;
4619   }
4620   amt = sqlite3_release_memory(N);
4621   Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
4622 #endif
4623   return TCL_OK;
4624 }
4625 
4626 
4627 /*
4628 ** Usage:  sqlite3_db_release_memory DB
4629 **
4630 ** Attempt to release memory currently held by database DB.  Return the
4631 ** result code (which in the current implementation is always zero).
4632 */
4633 static int test_db_release_memory(
4634   void * clientData,
4635   Tcl_Interp *interp,
4636   int objc,
4637   Tcl_Obj *CONST objv[]
4638 ){
4639   sqlite3 *db;
4640   int rc;
4641   if( objc!=2 ){
4642     Tcl_WrongNumArgs(interp, 1, objv, "DB");
4643     return TCL_ERROR;
4644   }
4645   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4646   rc = sqlite3_db_release_memory(db);
4647   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
4648   return TCL_OK;
4649 }
4650 
4651 /*
4652 ** Usage:  sqlite3_db_filename DB DBNAME
4653 **
4654 ** Return the name of a file associated with a database.
4655 */
4656 static int test_db_filename(
4657   void * clientData,
4658   Tcl_Interp *interp,
4659   int objc,
4660   Tcl_Obj *CONST objv[]
4661 ){
4662   sqlite3 *db;
4663   const char *zDbName;
4664   if( objc!=3 ){
4665     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
4666     return TCL_ERROR;
4667   }
4668   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4669   zDbName = Tcl_GetString(objv[2]);
4670   Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0);
4671   return TCL_OK;
4672 }
4673 
4674 /*
4675 ** Usage:  sqlite3_db_readonly DB DBNAME
4676 **
4677 ** Return 1 or 0 if DBNAME is readonly or not.  Return -1 if DBNAME does
4678 ** not exist.
4679 */
4680 static int test_db_readonly(
4681   void * clientData,
4682   Tcl_Interp *interp,
4683   int objc,
4684   Tcl_Obj *CONST objv[]
4685 ){
4686   sqlite3 *db;
4687   const char *zDbName;
4688   if( objc!=3 ){
4689     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
4690     return TCL_ERROR;
4691   }
4692   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4693   zDbName = Tcl_GetString(objv[2]);
4694   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_db_readonly(db, zDbName)));
4695   return TCL_OK;
4696 }
4697 
4698 /*
4699 ** Usage:  sqlite3_soft_heap_limit ?N?
4700 **
4701 ** Query or set the soft heap limit for the current thread.  The
4702 ** limit is only changed if the N is present.  The previous limit
4703 ** is returned.
4704 */
4705 static int test_soft_heap_limit(
4706   void * clientData,
4707   Tcl_Interp *interp,
4708   int objc,
4709   Tcl_Obj *CONST objv[]
4710 ){
4711   sqlite3_int64 amt;
4712   Tcl_WideInt N = -1;
4713   if( objc!=1 && objc!=2 ){
4714     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
4715     return TCL_ERROR;
4716   }
4717   if( objc==2 ){
4718     if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
4719   }
4720   amt = sqlite3_soft_heap_limit64(N);
4721   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
4722   return TCL_OK;
4723 }
4724 
4725 /*
4726 ** Usage:   sqlite3_thread_cleanup
4727 **
4728 ** Call the sqlite3_thread_cleanup API.
4729 */
4730 static int test_thread_cleanup(
4731   void * clientData,
4732   Tcl_Interp *interp,
4733   int objc,
4734   Tcl_Obj *CONST objv[]
4735 ){
4736 #ifndef SQLITE_OMIT_DEPRECATED
4737   sqlite3_thread_cleanup();
4738 #endif
4739   return TCL_OK;
4740 }
4741 
4742 /*
4743 ** Usage:   sqlite3_pager_refcounts  DB
4744 **
4745 ** Return a list of numbers which are the PagerRefcount for all
4746 ** pagers on each database connection.
4747 */
4748 static int test_pager_refcounts(
4749   void * clientData,
4750   Tcl_Interp *interp,
4751   int objc,
4752   Tcl_Obj *CONST objv[]
4753 ){
4754   sqlite3 *db;
4755   int i;
4756   int v, *a;
4757   Tcl_Obj *pResult;
4758 
4759   if( objc!=2 ){
4760     Tcl_AppendResult(interp, "wrong # args: should be \"",
4761         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
4762     return TCL_ERROR;
4763   }
4764   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4765   pResult = Tcl_NewObj();
4766   for(i=0; i<db->nDb; i++){
4767     if( db->aDb[i].pBt==0 ){
4768       v = -1;
4769     }else{
4770       sqlite3_mutex_enter(db->mutex);
4771       a = sqlite3PagerStats(sqlite3BtreePager(db->aDb[i].pBt));
4772       v = a[0];
4773       sqlite3_mutex_leave(db->mutex);
4774     }
4775     Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(v));
4776   }
4777   Tcl_SetObjResult(interp, pResult);
4778   return TCL_OK;
4779 }
4780 
4781 
4782 /*
4783 ** tclcmd:   working_64bit_int
4784 **
4785 ** Some TCL builds (ex: cygwin) do not support 64-bit integers.  This
4786 ** leads to a number of test failures.  The present command checks the
4787 ** TCL build to see whether or not it supports 64-bit integers.  It
4788 ** returns TRUE if it does and FALSE if not.
4789 **
4790 ** This command is used to warn users that their TCL build is defective
4791 ** and that the errors they are seeing in the test scripts might be
4792 ** a result of their defective TCL rather than problems in SQLite.
4793 */
4794 static int working_64bit_int(
4795   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4796   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4797   int objc,              /* Number of arguments */
4798   Tcl_Obj *CONST objv[]  /* Command arguments */
4799 ){
4800   Tcl_Obj *pTestObj;
4801   int working = 0;
4802 
4803   pTestObj = Tcl_NewWideIntObj(1000000*(i64)1234567890);
4804   working = strcmp(Tcl_GetString(pTestObj), "1234567890000000")==0;
4805   Tcl_DecrRefCount(pTestObj);
4806   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(working));
4807   return TCL_OK;
4808 }
4809 
4810 
4811 /*
4812 ** tclcmd:   vfs_unlink_test
4813 **
4814 ** This TCL command unregisters the primary VFS and then registers
4815 ** it back again.  This is used to test the ability to register a
4816 ** VFS when none are previously registered, and the ability to
4817 ** unregister the only available VFS.  Ticket #2738
4818 */
4819 static int vfs_unlink_test(
4820   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4821   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4822   int objc,              /* Number of arguments */
4823   Tcl_Obj *CONST objv[]  /* Command arguments */
4824 ){
4825   int i;
4826   sqlite3_vfs *pMain;
4827   sqlite3_vfs *apVfs[20];
4828   sqlite3_vfs one, two;
4829 
4830   sqlite3_vfs_unregister(0);   /* Unregister of NULL is harmless */
4831   one.zName = "__one";
4832   two.zName = "__two";
4833 
4834   /* Calling sqlite3_vfs_register with 2nd argument of 0 does not
4835   ** change the default VFS
4836   */
4837   pMain = sqlite3_vfs_find(0);
4838   sqlite3_vfs_register(&one, 0);
4839   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
4840   sqlite3_vfs_register(&two, 0);
4841   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
4842 
4843   /* We can find a VFS by its name */
4844   assert( sqlite3_vfs_find("__one")==&one );
4845   assert( sqlite3_vfs_find("__two")==&two );
4846 
4847   /* Calling sqlite_vfs_register with non-zero second parameter changes the
4848   ** default VFS, even if the 1st parameter is an existig VFS that is
4849   ** previously registered as the non-default.
4850   */
4851   sqlite3_vfs_register(&one, 1);
4852   assert( sqlite3_vfs_find("__one")==&one );
4853   assert( sqlite3_vfs_find("__two")==&two );
4854   assert( sqlite3_vfs_find(0)==&one );
4855   sqlite3_vfs_register(&two, 1);
4856   assert( sqlite3_vfs_find("__one")==&one );
4857   assert( sqlite3_vfs_find("__two")==&two );
4858   assert( sqlite3_vfs_find(0)==&two );
4859   if( pMain ){
4860     sqlite3_vfs_register(pMain, 1);
4861     assert( sqlite3_vfs_find("__one")==&one );
4862     assert( sqlite3_vfs_find("__two")==&two );
4863     assert( sqlite3_vfs_find(0)==pMain );
4864   }
4865 
4866   /* Unlink the default VFS.  Repeat until there are no more VFSes
4867   ** registered.
4868   */
4869   for(i=0; i<sizeof(apVfs)/sizeof(apVfs[0]); i++){
4870     apVfs[i] = sqlite3_vfs_find(0);
4871     if( apVfs[i] ){
4872       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
4873       sqlite3_vfs_unregister(apVfs[i]);
4874       assert( 0==sqlite3_vfs_find(apVfs[i]->zName) );
4875     }
4876   }
4877   assert( 0==sqlite3_vfs_find(0) );
4878 
4879   /* Register the main VFS as non-default (will be made default, since
4880   ** it'll be the only one in existence).
4881   */
4882   sqlite3_vfs_register(pMain, 0);
4883   assert( sqlite3_vfs_find(0)==pMain );
4884 
4885   /* Un-register the main VFS again to restore an empty VFS list */
4886   sqlite3_vfs_unregister(pMain);
4887   assert( 0==sqlite3_vfs_find(0) );
4888 
4889   /* Relink all VFSes in reverse order. */
4890   for(i=sizeof(apVfs)/sizeof(apVfs[0])-1; i>=0; i--){
4891     if( apVfs[i] ){
4892       sqlite3_vfs_register(apVfs[i], 1);
4893       assert( apVfs[i]==sqlite3_vfs_find(0) );
4894       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
4895     }
4896   }
4897 
4898   /* Unregister out sample VFSes. */
4899   sqlite3_vfs_unregister(&one);
4900   sqlite3_vfs_unregister(&two);
4901 
4902   /* Unregistering a VFS that is not currently registered is harmless */
4903   sqlite3_vfs_unregister(&one);
4904   sqlite3_vfs_unregister(&two);
4905   assert( sqlite3_vfs_find("__one")==0 );
4906   assert( sqlite3_vfs_find("__two")==0 );
4907 
4908   /* We should be left with the original default VFS back as the
4909   ** original */
4910   assert( sqlite3_vfs_find(0)==pMain );
4911 
4912   return TCL_OK;
4913 }
4914 
4915 /*
4916 ** tclcmd:   vfs_initfail_test
4917 **
4918 ** This TCL command attempts to vfs_find and vfs_register when the
4919 ** sqlite3_initialize() interface is failing.  All calls should fail.
4920 */
4921 static int vfs_initfail_test(
4922   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4923   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4924   int objc,              /* Number of arguments */
4925   Tcl_Obj *CONST objv[]  /* Command arguments */
4926 ){
4927   sqlite3_vfs one;
4928   one.zName = "__one";
4929 
4930   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
4931   sqlite3_vfs_register(&one, 0);
4932   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
4933   sqlite3_vfs_register(&one, 1);
4934   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
4935   return TCL_OK;
4936 }
4937 
4938 /*
4939 ** Saved VFSes
4940 */
4941 static sqlite3_vfs *apVfs[20];
4942 static int nVfs = 0;
4943 
4944 /*
4945 ** tclcmd:   vfs_unregister_all
4946 **
4947 ** Unregister all VFSes.
4948 */
4949 static int vfs_unregister_all(
4950   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4951   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4952   int objc,              /* Number of arguments */
4953   Tcl_Obj *CONST objv[]  /* Command arguments */
4954 ){
4955   int i;
4956   for(i=0; i<ArraySize(apVfs); i++){
4957     apVfs[i] = sqlite3_vfs_find(0);
4958     if( apVfs[i]==0 ) break;
4959     sqlite3_vfs_unregister(apVfs[i]);
4960   }
4961   nVfs = i;
4962   return TCL_OK;
4963 }
4964 /*
4965 ** tclcmd:   vfs_reregister_all
4966 **
4967 ** Restore all VFSes that were removed using vfs_unregister_all
4968 */
4969 static int vfs_reregister_all(
4970   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4971   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4972   int objc,              /* Number of arguments */
4973   Tcl_Obj *CONST objv[]  /* Command arguments */
4974 ){
4975   int i;
4976   for(i=0; i<nVfs; i++){
4977     sqlite3_vfs_register(apVfs[i], i==0);
4978   }
4979   return TCL_OK;
4980 }
4981 
4982 
4983 /*
4984 ** tclcmd:   file_control_test DB
4985 **
4986 ** This TCL command runs the sqlite3_file_control interface and
4987 ** verifies correct operation of the same.
4988 */
4989 static int file_control_test(
4990   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
4991   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4992   int objc,              /* Number of arguments */
4993   Tcl_Obj *CONST objv[]  /* Command arguments */
4994 ){
4995   int iArg = 0;
4996   sqlite3 *db;
4997   int rc;
4998 
4999   if( objc!=2 ){
5000     Tcl_AppendResult(interp, "wrong # args: should be \"",
5001         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5002     return TCL_ERROR;
5003   }
5004   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5005   rc = sqlite3_file_control(db, 0, 0, &iArg);
5006   assert( rc==SQLITE_NOTFOUND );
5007   rc = sqlite3_file_control(db, "notadatabase", SQLITE_FCNTL_LOCKSTATE, &iArg);
5008   assert( rc==SQLITE_ERROR );
5009   rc = sqlite3_file_control(db, "main", -1, &iArg);
5010   assert( rc==SQLITE_NOTFOUND );
5011   rc = sqlite3_file_control(db, "temp", -1, &iArg);
5012   assert( rc==SQLITE_NOTFOUND || rc==SQLITE_ERROR );
5013 
5014   return TCL_OK;
5015 }
5016 
5017 
5018 /*
5019 ** tclcmd:   file_control_lasterrno_test DB
5020 **
5021 ** This TCL command runs the sqlite3_file_control interface and
5022 ** verifies correct operation of the SQLITE_LAST_ERRNO verb.
5023 */
5024 static int file_control_lasterrno_test(
5025   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5026   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5027   int objc,              /* Number of arguments */
5028   Tcl_Obj *CONST objv[]  /* Command arguments */
5029 ){
5030   int iArg = 0;
5031   sqlite3 *db;
5032   int rc;
5033 
5034   if( objc!=2 ){
5035     Tcl_AppendResult(interp, "wrong # args: should be \"",
5036         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5037     return TCL_ERROR;
5038   }
5039   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5040     return TCL_ERROR;
5041   }
5042   rc = sqlite3_file_control(db, NULL, SQLITE_LAST_ERRNO, &iArg);
5043   if( rc ){
5044     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5045     return TCL_ERROR;
5046   }
5047   if( iArg!=0 ) {
5048     Tcl_AppendResult(interp, "Unexpected non-zero errno: ",
5049                      Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0);
5050     return TCL_ERROR;
5051   }
5052   return TCL_OK;
5053 }
5054 
5055 /*
5056 ** tclcmd:   file_control_chunksize_test DB DBNAME SIZE
5057 **
5058 ** This TCL command runs the sqlite3_file_control interface and
5059 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
5060 ** SQLITE_SET_LOCKPROXYFILE verbs.
5061 */
5062 static int file_control_chunksize_test(
5063   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5064   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5065   int objc,              /* Number of arguments */
5066   Tcl_Obj *CONST objv[]  /* Command arguments */
5067 ){
5068   int nSize;                      /* New chunk size */
5069   char *zDb;                      /* Db name ("main", "temp" etc.) */
5070   sqlite3 *db;                    /* Database handle */
5071   int rc;                         /* file_control() return code */
5072 
5073   if( objc!=4 ){
5074     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
5075     return TCL_ERROR;
5076   }
5077   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
5078    || Tcl_GetIntFromObj(interp, objv[3], &nSize)
5079   ){
5080    return TCL_ERROR;
5081   }
5082   zDb = Tcl_GetString(objv[2]);
5083   if( zDb[0]=='\0' ) zDb = NULL;
5084 
5085   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
5086   if( rc ){
5087     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
5088     return TCL_ERROR;
5089   }
5090   return TCL_OK;
5091 }
5092 
5093 /*
5094 ** tclcmd:   file_control_sizehint_test DB DBNAME SIZE
5095 **
5096 ** This TCL command runs the sqlite3_file_control interface
5097 ** with SQLITE_FCNTL_SIZE_HINT
5098 */
5099 static int file_control_sizehint_test(
5100   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5101   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5102   int objc,              /* Number of arguments */
5103   Tcl_Obj *CONST objv[]  /* Command arguments */
5104 ){
5105   Tcl_WideInt nSize;              /* Hinted size */
5106   char *zDb;                      /* Db name ("main", "temp" etc.) */
5107   sqlite3 *db;                    /* Database handle */
5108   int rc;                         /* file_control() return code */
5109 
5110   if( objc!=4 ){
5111     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
5112     return TCL_ERROR;
5113   }
5114   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
5115    || Tcl_GetWideIntFromObj(interp, objv[3], &nSize)
5116   ){
5117    return TCL_ERROR;
5118   }
5119   zDb = Tcl_GetString(objv[2]);
5120   if( zDb[0]=='\0' ) zDb = NULL;
5121 
5122   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_SIZE_HINT, (void *)&nSize);
5123   if( rc ){
5124     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
5125     return TCL_ERROR;
5126   }
5127   return TCL_OK;
5128 }
5129 
5130 /*
5131 ** tclcmd:   file_control_lockproxy_test DB PWD
5132 **
5133 ** This TCL command runs the sqlite3_file_control interface and
5134 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
5135 ** SQLITE_SET_LOCKPROXYFILE verbs.
5136 */
5137 static int file_control_lockproxy_test(
5138   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5139   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5140   int objc,              /* Number of arguments */
5141   Tcl_Obj *CONST objv[]  /* Command arguments */
5142 ){
5143   sqlite3 *db;
5144 
5145   if( objc!=3 ){
5146     Tcl_AppendResult(interp, "wrong # args: should be \"",
5147                      Tcl_GetStringFromObj(objv[0], 0), " DB PWD", 0);
5148     return TCL_ERROR;
5149   }
5150   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5151    return TCL_ERROR;
5152   }
5153 
5154 #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
5155 #  if defined(__APPLE__)
5156 #    define SQLITE_ENABLE_LOCKING_STYLE 1
5157 #  else
5158 #    define SQLITE_ENABLE_LOCKING_STYLE 0
5159 #  endif
5160 #endif
5161 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
5162   {
5163     char *testPath;
5164     int rc;
5165     int nPwd;
5166     const char *zPwd;
5167     char proxyPath[400];
5168 
5169     zPwd = Tcl_GetStringFromObj(objv[2], &nPwd);
5170     if( sizeof(proxyPath)<nPwd+20 ){
5171       Tcl_AppendResult(interp, "PWD too big", (void*)0);
5172       return TCL_ERROR;
5173     }
5174     sqlite3_snprintf(sizeof(proxyPath), proxyPath, "%s/test.proxy", zPwd);
5175     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
5176     if( rc ){
5177       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5178       return TCL_ERROR;
5179     }
5180     rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
5181     if( strncmp(proxyPath,testPath,11) ){
5182       Tcl_AppendResult(interp, "Lock proxy file did not match the "
5183                                "previously assigned value", 0);
5184       return TCL_ERROR;
5185     }
5186     if( rc ){
5187       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5188       return TCL_ERROR;
5189     }
5190     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
5191     if( rc ){
5192       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5193       return TCL_ERROR;
5194     }
5195   }
5196 #endif
5197   return TCL_OK;
5198 }
5199 
5200 #if SQLITE_OS_WIN
5201 /*
5202 ** tclcmd:   file_control_win32_av_retry DB  NRETRY  DELAY
5203 **
5204 ** This TCL command runs the sqlite3_file_control interface with
5205 ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
5206 */
5207 static int file_control_win32_av_retry(
5208   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5209   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5210   int objc,              /* Number of arguments */
5211   Tcl_Obj *CONST objv[]  /* Command arguments */
5212 ){
5213   sqlite3 *db;
5214   int rc;
5215   int a[2];
5216   char z[100];
5217 
5218   if( objc!=4 ){
5219     Tcl_AppendResult(interp, "wrong # args: should be \"",
5220         Tcl_GetStringFromObj(objv[0], 0), " DB NRETRY DELAY", 0);
5221     return TCL_ERROR;
5222   }
5223   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5224     return TCL_ERROR;
5225   }
5226   if( Tcl_GetIntFromObj(interp, objv[2], &a[0]) ) return TCL_ERROR;
5227   if( Tcl_GetIntFromObj(interp, objv[3], &a[1]) ) return TCL_ERROR;
5228   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_AV_RETRY, (void*)a);
5229   sqlite3_snprintf(sizeof(z), z, "%d %d %d", rc, a[0], a[1]);
5230   Tcl_AppendResult(interp, z, (char*)0);
5231   return TCL_OK;
5232 }
5233 
5234 /*
5235 ** tclcmd:   file_control_win32_set_handle DB HANDLE
5236 **
5237 ** This TCL command runs the sqlite3_file_control interface with
5238 ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
5239 */
5240 static int file_control_win32_set_handle(
5241   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5242   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5243   int objc,              /* Number of arguments */
5244   Tcl_Obj *CONST objv[]  /* Command arguments */
5245 ){
5246   sqlite3 *db;
5247   int rc;
5248   HANDLE hFile = NULL;
5249   char z[100];
5250 
5251   if( objc!=3 ){
5252     Tcl_AppendResult(interp, "wrong # args: should be \"",
5253         Tcl_GetStringFromObj(objv[0], 0), " DB HANDLE", 0);
5254     return TCL_ERROR;
5255   }
5256   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5257     return TCL_ERROR;
5258   }
5259   if( getWin32Handle(interp, Tcl_GetString(objv[2]), &hFile) ){
5260     return TCL_ERROR;
5261   }
5262   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_SET_HANDLE,
5263                             (void*)&hFile);
5264   sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile);
5265   Tcl_AppendResult(interp, z, (char*)0);
5266   return TCL_OK;
5267 }
5268 #endif
5269 
5270 /*
5271 ** tclcmd:   file_control_persist_wal DB PERSIST-FLAG
5272 **
5273 ** This TCL command runs the sqlite3_file_control interface with
5274 ** the SQLITE_FCNTL_PERSIST_WAL opcode.
5275 */
5276 static int file_control_persist_wal(
5277   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5278   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5279   int objc,              /* Number of arguments */
5280   Tcl_Obj *CONST objv[]  /* Command arguments */
5281 ){
5282   sqlite3 *db;
5283   int rc;
5284   int bPersist;
5285   char z[100];
5286 
5287   if( objc!=3 ){
5288     Tcl_AppendResult(interp, "wrong # args: should be \"",
5289         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
5290     return TCL_ERROR;
5291   }
5292   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5293     return TCL_ERROR;
5294   }
5295   if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR;
5296   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
5297   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
5298   Tcl_AppendResult(interp, z, (char*)0);
5299   return TCL_OK;
5300 }
5301 
5302 /*
5303 ** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
5304 **
5305 ** This TCL command runs the sqlite3_file_control interface with
5306 ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
5307 */
5308 static int file_control_powersafe_overwrite(
5309   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5310   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5311   int objc,              /* Number of arguments */
5312   Tcl_Obj *CONST objv[]  /* Command arguments */
5313 ){
5314   sqlite3 *db;
5315   int rc;
5316   int b;
5317   char z[100];
5318 
5319   if( objc!=3 ){
5320     Tcl_AppendResult(interp, "wrong # args: should be \"",
5321         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
5322     return TCL_ERROR;
5323   }
5324   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5325     return TCL_ERROR;
5326   }
5327   if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
5328   rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b);
5329   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b);
5330   Tcl_AppendResult(interp, z, (char*)0);
5331   return TCL_OK;
5332 }
5333 
5334 
5335 /*
5336 ** tclcmd:   file_control_vfsname DB ?AUXDB?
5337 **
5338 ** Return a string that describes the stack of VFSes.
5339 */
5340 static int file_control_vfsname(
5341   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5342   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5343   int objc,              /* Number of arguments */
5344   Tcl_Obj *CONST objv[]  /* Command arguments */
5345 ){
5346   sqlite3 *db;
5347   const char *zDbName = "main";
5348   char *zVfsName = 0;
5349 
5350   if( objc!=2 && objc!=3 ){
5351     Tcl_AppendResult(interp, "wrong # args: should be \"",
5352         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
5353     return TCL_ERROR;
5354   }
5355   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5356     return TCL_ERROR;
5357   }
5358   if( objc==3 ){
5359     zDbName = Tcl_GetString(objv[2]);
5360   }
5361   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
5362   Tcl_AppendResult(interp, zVfsName, (char*)0);
5363   sqlite3_free(zVfsName);
5364   return TCL_OK;
5365 }
5366 
5367 /*
5368 ** tclcmd:   file_control_tempfilename DB ?AUXDB?
5369 **
5370 ** Return a string that is a temporary filename
5371 */
5372 static int file_control_tempfilename(
5373   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5374   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5375   int objc,              /* Number of arguments */
5376   Tcl_Obj *CONST objv[]  /* Command arguments */
5377 ){
5378   sqlite3 *db;
5379   const char *zDbName = "main";
5380   char *zTName = 0;
5381 
5382   if( objc!=2 && objc!=3 ){
5383     Tcl_AppendResult(interp, "wrong # args: should be \"",
5384         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
5385     return TCL_ERROR;
5386   }
5387   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5388     return TCL_ERROR;
5389   }
5390   if( objc==3 ){
5391     zDbName = Tcl_GetString(objv[2]);
5392   }
5393   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
5394   Tcl_AppendResult(interp, zTName, (char*)0);
5395   sqlite3_free(zTName);
5396   return TCL_OK;
5397 }
5398 
5399 
5400 /*
5401 ** tclcmd:   sqlite3_vfs_list
5402 **
5403 **   Return a tcl list containing the names of all registered vfs's.
5404 */
5405 static int vfs_list(
5406   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5407   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5408   int objc,              /* Number of arguments */
5409   Tcl_Obj *CONST objv[]  /* Command arguments */
5410 ){
5411   sqlite3_vfs *pVfs;
5412   Tcl_Obj *pRet = Tcl_NewObj();
5413   if( objc!=1 ){
5414     Tcl_WrongNumArgs(interp, 1, objv, "");
5415     return TCL_ERROR;
5416   }
5417   for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5418     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(pVfs->zName, -1));
5419   }
5420   Tcl_SetObjResult(interp, pRet);
5421   return TCL_OK;
5422 }
5423 
5424 /*
5425 ** tclcmd:   sqlite3_limit DB ID VALUE
5426 **
5427 ** This TCL command runs the sqlite3_limit interface and
5428 ** verifies correct operation of the same.
5429 */
5430 static int test_limit(
5431   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5432   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5433   int objc,              /* Number of arguments */
5434   Tcl_Obj *CONST objv[]  /* Command arguments */
5435 ){
5436   sqlite3 *db;
5437   int rc;
5438   static const struct {
5439      char *zName;
5440      int id;
5441   } aId[] = {
5442     { "SQLITE_LIMIT_LENGTH",              SQLITE_LIMIT_LENGTH               },
5443     { "SQLITE_LIMIT_SQL_LENGTH",          SQLITE_LIMIT_SQL_LENGTH           },
5444     { "SQLITE_LIMIT_COLUMN",              SQLITE_LIMIT_COLUMN               },
5445     { "SQLITE_LIMIT_EXPR_DEPTH",          SQLITE_LIMIT_EXPR_DEPTH           },
5446     { "SQLITE_LIMIT_COMPOUND_SELECT",     SQLITE_LIMIT_COMPOUND_SELECT      },
5447     { "SQLITE_LIMIT_VDBE_OP",             SQLITE_LIMIT_VDBE_OP              },
5448     { "SQLITE_LIMIT_FUNCTION_ARG",        SQLITE_LIMIT_FUNCTION_ARG         },
5449     { "SQLITE_LIMIT_ATTACHED",            SQLITE_LIMIT_ATTACHED             },
5450     { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH  },
5451     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
5452     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
5453     { "SQLITE_LIMIT_WORKER_THREADS",      SQLITE_LIMIT_WORKER_THREADS       },
5454 
5455     /* Out of range test cases */
5456     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
5457     { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_WORKER_THREADS+1     },
5458   };
5459   int i, id = 0;
5460   int val;
5461   const char *zId;
5462 
5463   if( objc!=4 ){
5464     Tcl_AppendResult(interp, "wrong # args: should be \"",
5465         Tcl_GetStringFromObj(objv[0], 0), " DB ID VALUE", 0);
5466     return TCL_ERROR;
5467   }
5468   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5469   zId = Tcl_GetString(objv[2]);
5470   for(i=0; i<sizeof(aId)/sizeof(aId[0]); i++){
5471     if( strcmp(zId, aId[i].zName)==0 ){
5472       id = aId[i].id;
5473       break;
5474     }
5475   }
5476   if( i>=sizeof(aId)/sizeof(aId[0]) ){
5477     Tcl_AppendResult(interp, "unknown limit type: ", zId, (char*)0);
5478     return TCL_ERROR;
5479   }
5480   if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
5481   rc = sqlite3_limit(db, id, val);
5482   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5483   return TCL_OK;
5484 }
5485 
5486 /*
5487 ** tclcmd:  save_prng_state
5488 **
5489 ** Save the state of the pseudo-random number generator.
5490 ** At the same time, verify that sqlite3_test_control works even when
5491 ** called with an out-of-range opcode.
5492 */
5493 static int save_prng_state(
5494   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5495   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5496   int objc,              /* Number of arguments */
5497   Tcl_Obj *CONST objv[]  /* Command arguments */
5498 ){
5499   int rc = sqlite3_test_control(9999);
5500   assert( rc==0 );
5501   rc = sqlite3_test_control(-1);
5502   assert( rc==0 );
5503   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE);
5504   return TCL_OK;
5505 }
5506 /*
5507 ** tclcmd:  restore_prng_state
5508 */
5509 static int restore_prng_state(
5510   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5511   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5512   int objc,              /* Number of arguments */
5513   Tcl_Obj *CONST objv[]  /* Command arguments */
5514 ){
5515   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE);
5516   return TCL_OK;
5517 }
5518 /*
5519 ** tclcmd:  reset_prng_state
5520 */
5521 static int reset_prng_state(
5522   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5523   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5524   int objc,              /* Number of arguments */
5525   Tcl_Obj *CONST objv[]  /* Command arguments */
5526 ){
5527   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
5528   return TCL_OK;
5529 }
5530 
5531 /*
5532 ** tclcmd:  database_may_be_corrupt
5533 **
5534 ** Indicate that database files might be corrupt.  In other words, set the normal
5535 ** state of operation.
5536 */
5537 static int database_may_be_corrupt(
5538   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5539   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5540   int objc,              /* Number of arguments */
5541   Tcl_Obj *CONST objv[]  /* Command arguments */
5542 ){
5543   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0);
5544   return TCL_OK;
5545 }
5546 /*
5547 ** tclcmd:  database_never_corrupt
5548 **
5549 ** Indicate that database files are always well-formed.  This enables extra assert()
5550 ** statements that test conditions that are always true for well-formed databases.
5551 */
5552 static int database_never_corrupt(
5553   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5554   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5555   int objc,              /* Number of arguments */
5556   Tcl_Obj *CONST objv[]  /* Command arguments */
5557 ){
5558   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1);
5559   return TCL_OK;
5560 }
5561 
5562 /*
5563 ** tclcmd:  pcache_stats
5564 */
5565 static int test_pcache_stats(
5566   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5567   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5568   int objc,              /* Number of arguments */
5569   Tcl_Obj *CONST objv[]  /* Command arguments */
5570 ){
5571   int nMin;
5572   int nMax;
5573   int nCurrent;
5574   int nRecyclable;
5575   Tcl_Obj *pRet;
5576 
5577   sqlite3PcacheStats(&nCurrent, &nMax, &nMin, &nRecyclable);
5578 
5579   pRet = Tcl_NewObj();
5580   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("current", -1));
5581   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCurrent));
5582   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("max", -1));
5583   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMax));
5584   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("min", -1));
5585   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMin));
5586   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("recyclable", -1));
5587   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nRecyclable));
5588 
5589   Tcl_SetObjResult(interp, pRet);
5590 
5591   return TCL_OK;
5592 }
5593 
5594 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
5595 static void test_unlock_notify_cb(void **aArg, int nArg){
5596   int ii;
5597   for(ii=0; ii<nArg; ii++){
5598     Tcl_EvalEx((Tcl_Interp *)aArg[ii], "unlock_notify", -1, TCL_EVAL_GLOBAL);
5599   }
5600 }
5601 #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
5602 
5603 /*
5604 ** tclcmd:  sqlite3_unlock_notify db
5605 */
5606 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
5607 static int test_unlock_notify(
5608   ClientData clientData, /* Unused */
5609   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5610   int objc,              /* Number of arguments */
5611   Tcl_Obj *CONST objv[]  /* Command arguments */
5612 ){
5613   sqlite3 *db;
5614   int rc;
5615 
5616   if( objc!=2 ){
5617     Tcl_WrongNumArgs(interp, 1, objv, "DB");
5618     return TCL_ERROR;
5619   }
5620 
5621   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5622     return TCL_ERROR;
5623   }
5624   rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void *)interp);
5625   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
5626   return TCL_OK;
5627 }
5628 #endif
5629 
5630 /*
5631 ** tclcmd:  sqlite3_wal_checkpoint db ?NAME?
5632 */
5633 static int test_wal_checkpoint(
5634   ClientData clientData, /* Unused */
5635   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5636   int objc,              /* Number of arguments */
5637   Tcl_Obj *CONST objv[]  /* Command arguments */
5638 ){
5639   char *zDb = 0;
5640   sqlite3 *db;
5641   int rc;
5642 
5643   if( objc!=3 && objc!=2 ){
5644     Tcl_WrongNumArgs(interp, 1, objv, "DB ?NAME?");
5645     return TCL_ERROR;
5646   }
5647 
5648   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5649     return TCL_ERROR;
5650   }
5651   if( objc==3 ){
5652     zDb = Tcl_GetString(objv[2]);
5653   }
5654   rc = sqlite3_wal_checkpoint(db, zDb);
5655   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
5656   return TCL_OK;
5657 }
5658 
5659 /*
5660 ** tclcmd:  sqlite3_wal_checkpoint_v2 db MODE ?NAME?
5661 **
5662 ** This command calls the wal_checkpoint_v2() function with the specified
5663 ** mode argument (passive, full or restart). If present, the database name
5664 ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
5665 ** NAME argument is not present, a NULL pointer is passed instead.
5666 **
5667 ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
5668 ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
5669 ** to the error message obtained from sqlite3_errmsg().
5670 **
5671 ** Otherwise, this command returns a list of three integers. The first integer
5672 ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
5673 ** are the values returned via the output parameters by wal_checkpoint_v2() -
5674 ** the number of frames in the log and the number of frames in the log
5675 ** that have been checkpointed.
5676 */
5677 static int test_wal_checkpoint_v2(
5678   ClientData clientData, /* Unused */
5679   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5680   int objc,              /* Number of arguments */
5681   Tcl_Obj *CONST objv[]  /* Command arguments */
5682 ){
5683   char *zDb = 0;
5684   sqlite3 *db;
5685   int rc;
5686 
5687   int eMode;
5688   int nLog = -555;
5689   int nCkpt = -555;
5690   Tcl_Obj *pRet;
5691 
5692   const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
5693   assert( SQLITE_CHECKPOINT_PASSIVE==0 );
5694   assert( SQLITE_CHECKPOINT_FULL==1 );
5695   assert( SQLITE_CHECKPOINT_RESTART==2 );
5696   assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
5697 
5698   if( objc!=3 && objc!=4 ){
5699     Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
5700     return TCL_ERROR;
5701   }
5702 
5703   if( objc==4 ){
5704     zDb = Tcl_GetString(objv[3]);
5705   }
5706   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) || (
5707       TCL_OK!=Tcl_GetIntFromObj(0, objv[2], &eMode)
5708    && TCL_OK!=Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode)
5709   )){
5710     return TCL_ERROR;
5711   }
5712 
5713   rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt);
5714   if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
5715     const char *zErrCode = sqlite3ErrName(rc);
5716     Tcl_ResetResult(interp);
5717     Tcl_AppendResult(interp, zErrCode, " - ", (char *)sqlite3_errmsg(db), 0);
5718     return TCL_ERROR;
5719   }
5720 
5721   pRet = Tcl_NewObj();
5722   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
5723   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
5724   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
5725   Tcl_SetObjResult(interp, pRet);
5726 
5727   return TCL_OK;
5728 }
5729 
5730 /*
5731 ** tclcmd:  sqlite3_wal_autocheckpoint db VALUE
5732 */
5733 static int test_wal_autocheckpoint(
5734   ClientData clientData, /* Unused */
5735   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5736   int objc,              /* Number of arguments */
5737   Tcl_Obj *CONST objv[]  /* Command arguments */
5738 ){
5739   sqlite3 *db;
5740   int rc;
5741   int iVal;
5742 
5743 
5744   if( objc!=3 ){
5745     Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE");
5746     return TCL_ERROR;
5747   }
5748 
5749   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
5750    || Tcl_GetIntFromObj(0, objv[2], &iVal)
5751   ){
5752     return TCL_ERROR;
5753   }
5754 
5755   rc = sqlite3_wal_autocheckpoint(db, iVal);
5756   Tcl_ResetResult(interp);
5757   if( rc!=SQLITE_OK ){
5758     const char *zErrCode = sqlite3ErrName(rc);
5759     Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1));
5760     return TCL_ERROR;
5761   }
5762 
5763   return TCL_OK;
5764 }
5765 
5766 
5767 /*
5768 ** tclcmd:  test_sqlite3_log ?SCRIPT?
5769 */
5770 static struct LogCallback {
5771   Tcl_Interp *pInterp;
5772   Tcl_Obj *pObj;
5773 } logcallback = {0, 0};
5774 static void xLogcallback(void *unused, int err, char *zMsg){
5775   Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj);
5776   Tcl_IncrRefCount(pNew);
5777   Tcl_ListObjAppendElement(
5778       0, pNew, Tcl_NewStringObj(sqlite3ErrName(err), -1)
5779   );
5780   Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zMsg, -1));
5781   Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
5782   Tcl_DecrRefCount(pNew);
5783 }
5784 static int test_sqlite3_log(
5785   ClientData clientData,
5786   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5787   int objc,              /* Number of arguments */
5788   Tcl_Obj *CONST objv[]  /* Command arguments */
5789 ){
5790   if( objc>2 ){
5791     Tcl_WrongNumArgs(interp, 1, objv, "SCRIPT");
5792     return TCL_ERROR;
5793   }
5794   if( logcallback.pObj ){
5795     Tcl_DecrRefCount(logcallback.pObj);
5796     logcallback.pObj = 0;
5797     logcallback.pInterp = 0;
5798     sqlite3_config(SQLITE_CONFIG_LOG, 0, 0);
5799   }
5800   if( objc>1 ){
5801     logcallback.pObj = objv[1];
5802     Tcl_IncrRefCount(logcallback.pObj);
5803     logcallback.pInterp = interp;
5804     sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, 0);
5805   }
5806   return TCL_OK;
5807 }
5808 
5809 /*
5810 **     tcl_objproc COMMANDNAME ARGS...
5811 **
5812 ** Run a TCL command using its objProc interface.  Throw an error if
5813 ** the command has no objProc interface.
5814 */
5815 static int runAsObjProc(
5816   void * clientData,
5817   Tcl_Interp *interp,
5818   int objc,
5819   Tcl_Obj *CONST objv[]
5820 ){
5821   Tcl_CmdInfo cmdInfo;
5822   if( objc<2 ){
5823     Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ...");
5824     return TCL_ERROR;
5825   }
5826   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
5827     Tcl_AppendResult(interp, "command not found: ",
5828            Tcl_GetString(objv[1]), (char*)0);
5829     return TCL_ERROR;
5830   }
5831   if( cmdInfo.objProc==0 ){
5832     Tcl_AppendResult(interp, "command has no objProc: ",
5833            Tcl_GetString(objv[1]), (char*)0);
5834     return TCL_ERROR;
5835   }
5836   return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1);
5837 }
5838 
5839 #ifndef SQLITE_OMIT_EXPLAIN
5840 /*
5841 ** WARNING: The following function, printExplainQueryPlan() is an exact
5842 ** copy of example code from eqp.in (eqp.html). If this code is modified,
5843 ** then the documentation copy needs to be modified as well.
5844 */
5845 /*
5846 ** Argument pStmt is a prepared SQL statement. This function compiles
5847 ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
5848 ** and prints the report to stdout using printf().
5849 */
5850 int printExplainQueryPlan(sqlite3_stmt *pStmt){
5851   const char *zSql;               /* Input SQL */
5852   char *zExplain;                 /* SQL with EXPLAIN QUERY PLAN prepended */
5853   sqlite3_stmt *pExplain;         /* Compiled EXPLAIN QUERY PLAN command */
5854   int rc;                         /* Return code from sqlite3_prepare_v2() */
5855 
5856   zSql = sqlite3_sql(pStmt);
5857   if( zSql==0 ) return SQLITE_ERROR;
5858 
5859   zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
5860   if( zExplain==0 ) return SQLITE_NOMEM;
5861 
5862   rc = sqlite3_prepare_v2(sqlite3_db_handle(pStmt), zExplain, -1, &pExplain, 0);
5863   sqlite3_free(zExplain);
5864   if( rc!=SQLITE_OK ) return rc;
5865 
5866   while( SQLITE_ROW==sqlite3_step(pExplain) ){
5867     int iSelectid = sqlite3_column_int(pExplain, 0);
5868     int iOrder = sqlite3_column_int(pExplain, 1);
5869     int iFrom = sqlite3_column_int(pExplain, 2);
5870     const char *zDetail = (const char *)sqlite3_column_text(pExplain, 3);
5871 
5872     printf("%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail);
5873   }
5874 
5875   return sqlite3_finalize(pExplain);
5876 }
5877 
5878 static int test_print_eqp(
5879   void * clientData,
5880   Tcl_Interp *interp,
5881   int objc,
5882   Tcl_Obj *CONST objv[]
5883 ){
5884   int rc;
5885   sqlite3_stmt *pStmt;
5886 
5887   if( objc!=2 ){
5888     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
5889     return TCL_ERROR;
5890   }
5891   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
5892   rc = printExplainQueryPlan(pStmt);
5893   /* This is needed on Windows so that a test case using this
5894   ** function can open a read pipe and get the output of
5895   ** printExplainQueryPlan() immediately.
5896   */
5897   fflush(stdout);
5898   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
5899   return TCL_OK;
5900 }
5901 #endif /* SQLITE_OMIT_EXPLAIN */
5902 
5903 /*
5904 ** sqlite3_test_control VERB ARGS...
5905 */
5906 static int test_test_control(
5907   void * clientData,
5908   Tcl_Interp *interp,
5909   int objc,
5910   Tcl_Obj *CONST objv[]
5911 ){
5912   struct Verb {
5913     const char *zName;
5914     int i;
5915   } aVerb[] = {
5916     { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
5917     { "SQLITE_TESTCTRL_SORTER_MMAP",     SQLITE_TESTCTRL_SORTER_MMAP     },
5918     { "SQLITE_TESTCTRL_IMPOSTER",        SQLITE_TESTCTRL_IMPOSTER        },
5919   };
5920   int iVerb;
5921   int iFlag;
5922   int rc;
5923 
5924   if( objc<2 ){
5925     Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS...");
5926     return TCL_ERROR;
5927   }
5928 
5929   rc = Tcl_GetIndexFromObjStruct(
5930       interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
5931   );
5932   if( rc!=TCL_OK ) return rc;
5933 
5934   iFlag = aVerb[iVerb].i;
5935   switch( iFlag ){
5936     case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
5937       int val;
5938       if( objc!=3 ){
5939         Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
5940         return TCL_ERROR;
5941       }
5942       if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
5943       sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
5944       break;
5945     }
5946 
5947     case SQLITE_TESTCTRL_SORTER_MMAP: {
5948       int val;
5949       sqlite3 *db;
5950       if( objc!=4 ){
5951         Tcl_WrongNumArgs(interp, 2, objv, "DB LIMIT");
5952         return TCL_ERROR;
5953       }
5954       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
5955       if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
5956       sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
5957       break;
5958     }
5959 
5960     case SQLITE_TESTCTRL_IMPOSTER: {
5961       int onOff, tnum;
5962       const char *zDbName;
5963       sqlite3 *db;
5964       if( objc!=6 ){
5965         Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
5966         return TCL_ERROR;
5967       }
5968       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
5969       zDbName = Tcl_GetString(objv[3]);
5970       if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
5971       if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
5972       sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
5973       break;
5974     }
5975   }
5976 
5977   Tcl_ResetResult(interp);
5978   return TCL_OK;
5979 }
5980 
5981 #if SQLITE_OS_UNIX
5982 #include <sys/time.h>
5983 #include <sys/resource.h>
5984 
5985 static int test_getrusage(
5986   void * clientData,
5987   Tcl_Interp *interp,
5988   int objc,
5989   Tcl_Obj *CONST objv[]
5990 ){
5991   char buf[1024];
5992   struct rusage r;
5993   memset(&r, 0, sizeof(r));
5994   getrusage(RUSAGE_SELF, &r);
5995 
5996   sqlite3_snprintf(sizeof(buf), buf,
5997     "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
5998     (int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec,
5999     (int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec,
6000     (int)r.ru_minflt, (int)r.ru_majflt
6001   );
6002   Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
6003   return TCL_OK;
6004 }
6005 #endif
6006 
6007 #if SQLITE_OS_WIN
6008 /*
6009 ** Information passed from the main thread into the windows file locker
6010 ** background thread.
6011 */
6012 struct win32FileLocker {
6013   char *evName;       /* Name of event to signal thread startup */
6014   HANDLE h;           /* Handle of the file to be locked */
6015   int delay1;         /* Delay before locking */
6016   int delay2;         /* Delay before unlocking */
6017   int ok;             /* Finished ok */
6018   int err;            /* True if an error occurs */
6019 };
6020 #endif
6021 
6022 
6023 #if SQLITE_OS_WIN
6024 #include <process.h>
6025 /*
6026 ** The background thread that does file locking.
6027 */
6028 static void win32_file_locker(void *pAppData){
6029   struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
6030   if( p->evName ){
6031     HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
6032     if ( ev ){
6033       SetEvent(ev);
6034       CloseHandle(ev);
6035     }
6036   }
6037   if( p->delay1 ) Sleep(p->delay1);
6038   if( LockFile(p->h, 0, 0, 100000000, 0) ){
6039     Sleep(p->delay2);
6040     UnlockFile(p->h, 0, 0, 100000000, 0);
6041     p->ok = 1;
6042   }else{
6043     p->err = 1;
6044   }
6045   CloseHandle(p->h);
6046   p->h = 0;
6047   p->delay1 = 0;
6048   p->delay2 = 0;
6049 }
6050 #endif
6051 
6052 #if SQLITE_OS_WIN
6053 /*
6054 **      lock_win32_file FILENAME DELAY1 DELAY2
6055 **
6056 ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
6057 ** Wait DELAY1 milliseconds before acquiring the lock.
6058 */
6059 static int win32_file_lock(
6060   void * clientData,
6061   Tcl_Interp *interp,
6062   int objc,
6063   Tcl_Obj *CONST objv[]
6064 ){
6065   static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
6066   const char *zFilename;
6067   char zBuf[200];
6068   int retry = 0;
6069   HANDLE ev;
6070   DWORD wResult;
6071 
6072   if( objc!=4 && objc!=1 ){
6073     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
6074     return TCL_ERROR;
6075   }
6076   if( objc==1 ){
6077     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
6078                      x.ok, x.err, x.delay1, x.delay2, x.h);
6079     Tcl_AppendResult(interp, zBuf, (char*)0);
6080     return TCL_OK;
6081   }
6082   while( x.h && retry<30 ){
6083     retry++;
6084     Sleep(100);
6085   }
6086   if( x.h ){
6087     Tcl_AppendResult(interp, "busy", (char*)0);
6088     return TCL_ERROR;
6089   }
6090   if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
6091   if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
6092   zFilename = Tcl_GetString(objv[1]);
6093   x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
6094               FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
6095               FILE_ATTRIBUTE_NORMAL, 0);
6096   if( !x.h ){
6097     Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
6098     return TCL_ERROR;
6099   }
6100   ev = CreateEvent(NULL, TRUE, FALSE, x.evName);
6101   if ( !ev ){
6102     Tcl_AppendResult(interp, "cannot create event: ", x.evName, (char*)0);
6103     return TCL_ERROR;
6104   }
6105   _beginthread(win32_file_locker, 0, (void*)&x);
6106   Sleep(0);
6107   if ( (wResult = WaitForSingleObject(ev, 10000))!=WAIT_OBJECT_0 ){
6108     sqlite3_snprintf(sizeof(zBuf), zBuf, "0x%x", wResult);
6109     Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0);
6110     CloseHandle(ev);
6111     return TCL_ERROR;
6112   }
6113   CloseHandle(ev);
6114   return TCL_OK;
6115 }
6116 
6117 /*
6118 **      exists_win32_path PATH
6119 **
6120 ** Returns non-zero if the specified path exists, whose fully qualified name
6121 ** may exceed 260 characters if it is prefixed with "\\?\".
6122 */
6123 static int win32_exists_path(
6124   void *clientData,
6125   Tcl_Interp *interp,
6126   int objc,
6127   Tcl_Obj *CONST objv[]
6128 ){
6129   if( objc!=2 ){
6130     Tcl_WrongNumArgs(interp, 1, objv, "PATH");
6131     return TCL_ERROR;
6132   }
6133   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
6134       GetFileAttributesW( Tcl_GetUnicode(objv[1]))!=INVALID_FILE_ATTRIBUTES ));
6135   return TCL_OK;
6136 }
6137 
6138 /*
6139 **      find_win32_file PATTERN
6140 **
6141 ** Returns a list of entries in a directory that match the specified pattern,
6142 ** whose fully qualified name may exceed 248 characters if it is prefixed with
6143 ** "\\?\".
6144 */
6145 static int win32_find_file(
6146   void *clientData,
6147   Tcl_Interp *interp,
6148   int objc,
6149   Tcl_Obj *CONST objv[]
6150 ){
6151   HANDLE hFindFile = INVALID_HANDLE_VALUE;
6152   WIN32_FIND_DATAW findData;
6153   Tcl_Obj *listObj;
6154   DWORD lastErrno;
6155   if( objc!=2 ){
6156     Tcl_WrongNumArgs(interp, 1, objv, "PATTERN");
6157     return TCL_ERROR;
6158   }
6159   hFindFile = FindFirstFileW(Tcl_GetUnicode(objv[1]), &findData);
6160   if( hFindFile==INVALID_HANDLE_VALUE ){
6161     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6162     return TCL_ERROR;
6163   }
6164   listObj = Tcl_NewObj();
6165   Tcl_IncrRefCount(listObj);
6166   do {
6167     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewUnicodeObj(
6168         findData.cFileName, -1));
6169     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(
6170         findData.dwFileAttributes));
6171   } while( FindNextFileW(hFindFile, &findData) );
6172   lastErrno = GetLastError();
6173   if( lastErrno!=NO_ERROR && lastErrno!=ERROR_NO_MORE_FILES ){
6174     FindClose(hFindFile);
6175     Tcl_DecrRefCount(listObj);
6176     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6177     return TCL_ERROR;
6178   }
6179   FindClose(hFindFile);
6180   Tcl_SetObjResult(interp, listObj);
6181   return TCL_OK;
6182 }
6183 
6184 /*
6185 **      delete_win32_file FILENAME
6186 **
6187 ** Deletes the specified file, whose fully qualified name may exceed 260
6188 ** characters if it is prefixed with "\\?\".
6189 */
6190 static int win32_delete_file(
6191   void *clientData,
6192   Tcl_Interp *interp,
6193   int objc,
6194   Tcl_Obj *CONST objv[]
6195 ){
6196   if( objc!=2 ){
6197     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
6198     return TCL_ERROR;
6199   }
6200   if( !DeleteFileW(Tcl_GetUnicode(objv[1])) ){
6201     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6202     return TCL_ERROR;
6203   }
6204   Tcl_ResetResult(interp);
6205   return TCL_OK;
6206 }
6207 
6208 /*
6209 **      make_win32_dir DIRECTORY
6210 **
6211 ** Creates the specified directory, whose fully qualified name may exceed 248
6212 ** characters if it is prefixed with "\\?\".
6213 */
6214 static int win32_mkdir(
6215   void *clientData,
6216   Tcl_Interp *interp,
6217   int objc,
6218   Tcl_Obj *CONST objv[]
6219 ){
6220   if( objc!=2 ){
6221     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6222     return TCL_ERROR;
6223   }
6224   if( !CreateDirectoryW(Tcl_GetUnicode(objv[1]), NULL) ){
6225     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6226     return TCL_ERROR;
6227   }
6228   Tcl_ResetResult(interp);
6229   return TCL_OK;
6230 }
6231 
6232 /*
6233 **      remove_win32_dir DIRECTORY
6234 **
6235 ** Removes the specified directory, whose fully qualified name may exceed 248
6236 ** characters if it is prefixed with "\\?\".
6237 */
6238 static int win32_rmdir(
6239   void *clientData,
6240   Tcl_Interp *interp,
6241   int objc,
6242   Tcl_Obj *CONST objv[]
6243 ){
6244   if( objc!=2 ){
6245     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6246     return TCL_ERROR;
6247   }
6248   if( !RemoveDirectoryW(Tcl_GetUnicode(objv[1])) ){
6249     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6250     return TCL_ERROR;
6251   }
6252   Tcl_ResetResult(interp);
6253   return TCL_OK;
6254 }
6255 #endif
6256 
6257 
6258 /*
6259 **      optimization_control DB OPT BOOLEAN
6260 **
6261 ** Enable or disable query optimizations using the sqlite3_test_control()
6262 ** interface.  Disable if BOOLEAN is false and enable if BOOLEAN is true.
6263 ** OPT is the name of the optimization to be disabled.
6264 */
6265 static int optimization_control(
6266   void * clientData,
6267   Tcl_Interp *interp,
6268   int objc,
6269   Tcl_Obj *CONST objv[]
6270 ){
6271   int i;
6272   sqlite3 *db;
6273   const char *zOpt;
6274   int onoff;
6275   int mask = 0;
6276   static const struct {
6277     const char *zOptName;
6278     int mask;
6279   } aOpt[] = {
6280     { "all",                 SQLITE_AllOpts        },
6281     { "none",                0                     },
6282     { "query-flattener",     SQLITE_QueryFlattener },
6283     { "column-cache",        SQLITE_ColumnCache    },
6284     { "groupby-order",       SQLITE_GroupByOrder   },
6285     { "factor-constants",    SQLITE_FactorOutConst },
6286     { "distinct-opt",        SQLITE_DistinctOpt    },
6287     { "cover-idx-scan",      SQLITE_CoverIdxScan   },
6288     { "order-by-idx-join",   SQLITE_OrderByIdxJoin },
6289     { "transitive",          SQLITE_Transitive     },
6290     { "subquery-coroutine",  SQLITE_SubqCoroutine  },
6291     { "omit-noop-join",      SQLITE_OmitNoopJoin   },
6292     { "stat3",               SQLITE_Stat34         },
6293     { "stat4",               SQLITE_Stat34         },
6294   };
6295 
6296   if( objc!=4 ){
6297     Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
6298     return TCL_ERROR;
6299   }
6300   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6301   if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ) return TCL_ERROR;
6302   zOpt = Tcl_GetString(objv[2]);
6303   for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6304     if( strcmp(zOpt, aOpt[i].zOptName)==0 ){
6305       mask = aOpt[i].mask;
6306       break;
6307     }
6308   }
6309   if( onoff ) mask = ~mask;
6310   if( i>=sizeof(aOpt)/sizeof(aOpt[0]) ){
6311     Tcl_AppendResult(interp, "unknown optimization - should be one of:",
6312                      (char*)0);
6313     for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6314       Tcl_AppendResult(interp, " ", aOpt[i].zOptName, (char*)0);
6315     }
6316     return TCL_ERROR;
6317   }
6318   sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
6319   return TCL_OK;
6320 }
6321 
6322 typedef struct sqlite3_api_routines sqlite3_api_routines;
6323 /*
6324 **     load_static_extension DB NAME ...
6325 **
6326 ** Load one or more statically linked extensions.
6327 */
6328 static int tclLoadStaticExtensionCmd(
6329   void * clientData,
6330   Tcl_Interp *interp,
6331   int objc,
6332   Tcl_Obj *CONST objv[]
6333 ){
6334   extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
6335   extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
6336   extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
6337   extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
6338   extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
6339   extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
6340   extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
6341   extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
6342   extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
6343   extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
6344   extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
6345   extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
6346   extern int sqlite3_fts5_init(sqlite3*,char**,const sqlite3_api_routines*);
6347   static const struct {
6348     const char *zExtName;
6349     int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
6350   } aExtension[] = {
6351     { "amatch",                sqlite3_amatch_init               },
6352     { "closure",               sqlite3_closure_init              },
6353     { "eval",                  sqlite3_eval_init                 },
6354 #ifdef SQLITE_ENABLE_FTS5
6355     { "fts5",                  sqlite3_fts5_init                 },
6356 #endif
6357     { "fileio",                sqlite3_fileio_init               },
6358     { "fuzzer",                sqlite3_fuzzer_init               },
6359     { "ieee754",               sqlite3_ieee_init                 },
6360     { "nextchar",              sqlite3_nextchar_init             },
6361     { "percentile",            sqlite3_percentile_init           },
6362     { "regexp",                sqlite3_regexp_init               },
6363     { "spellfix",              sqlite3_spellfix_init             },
6364     { "totype",                sqlite3_totype_init               },
6365     { "wholenumber",           sqlite3_wholenumber_init          },
6366   };
6367   sqlite3 *db;
6368   const char *zName;
6369   int i, j, rc;
6370   char *zErrMsg = 0;
6371   if( objc<3 ){
6372     Tcl_WrongNumArgs(interp, 1, objv, "DB NAME ...");
6373     return TCL_ERROR;
6374   }
6375   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6376   for(j=2; j<objc; j++){
6377     zName = Tcl_GetString(objv[j]);
6378     for(i=0; i<ArraySize(aExtension); i++){
6379       if( strcmp(zName, aExtension[i].zExtName)==0 ) break;
6380     }
6381     if( i>=ArraySize(aExtension) ){
6382       Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0);
6383       return TCL_ERROR;
6384     }
6385     rc = aExtension[i].pInit(db, &zErrMsg, 0);
6386     if( rc!=SQLITE_OK || zErrMsg ){
6387       Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
6388                        (char*)0);
6389       sqlite3_free(zErrMsg);
6390       return TCL_ERROR;
6391     }
6392   }
6393   return TCL_OK;
6394 }
6395 
6396 /*
6397 **     sorter_test_fakeheap BOOL
6398 **
6399 */
6400 static int sorter_test_fakeheap(
6401   void * clientData,
6402   Tcl_Interp *interp,
6403   int objc,
6404   Tcl_Obj *CONST objv[]
6405 ){
6406   int bArg;
6407   if( objc!=2 ){
6408     Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
6409     return TCL_ERROR;
6410   }
6411 
6412   if( Tcl_GetBooleanFromObj(interp, objv[1], &bArg) ){
6413     return TCL_ERROR;
6414   }
6415 
6416   if( bArg ){
6417     if( sqlite3GlobalConfig.pHeap==0 ){
6418       sqlite3GlobalConfig.pHeap = SQLITE_INT_TO_PTR(-1);
6419     }
6420   }else{
6421     if( sqlite3GlobalConfig.pHeap==SQLITE_INT_TO_PTR(-1) ){
6422       sqlite3GlobalConfig.pHeap = 0;
6423     }
6424   }
6425 
6426   Tcl_ResetResult(interp);
6427   return TCL_OK;
6428 }
6429 
6430 /*
6431 **     sorter_test_sort4_helper DB SQL1 NSTEP SQL2
6432 **
6433 ** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
6434 ** check that the leftmost and rightmost columns returned are both integers,
6435 ** and that both contain the same value.
6436 **
6437 ** Then execute statement $SQL2. Check that the statement returns the same
6438 ** set of integers in the same order as in the previous step (using $SQL1).
6439 */
6440 static int sorter_test_sort4_helper(
6441   void * clientData,
6442   Tcl_Interp *interp,
6443   int objc,
6444   Tcl_Obj *CONST objv[]
6445 ){
6446   const char *zSql1;
6447   const char *zSql2;
6448   int nStep;
6449   int iStep;
6450   int iCksum1 = 0;
6451   int iCksum2 = 0;
6452   int rc;
6453   int iB;
6454   sqlite3 *db;
6455   sqlite3_stmt *pStmt;
6456 
6457   if( objc!=5 ){
6458     Tcl_WrongNumArgs(interp, 1, objv, "DB SQL1 NSTEP SQL2");
6459     return TCL_ERROR;
6460   }
6461 
6462   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6463   zSql1 = Tcl_GetString(objv[2]);
6464   if( Tcl_GetIntFromObj(interp, objv[3], &nStep) ) return TCL_ERROR;
6465   zSql2 = Tcl_GetString(objv[4]);
6466 
6467   rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0);
6468   if( rc!=SQLITE_OK ) goto sql_error;
6469 
6470   iB = sqlite3_column_count(pStmt)-1;
6471   for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6472     int a = sqlite3_column_int(pStmt, 0);
6473     if( a!=sqlite3_column_int(pStmt, iB) ){
6474       Tcl_AppendResult(interp, "data error: (a!=b)", 0);
6475       return TCL_ERROR;
6476     }
6477 
6478     iCksum1 += (iCksum1 << 3) + a;
6479   }
6480   rc = sqlite3_finalize(pStmt);
6481   if( rc!=SQLITE_OK ) goto sql_error;
6482 
6483   rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0);
6484   if( rc!=SQLITE_OK ) goto sql_error;
6485   for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6486     int a = sqlite3_column_int(pStmt, 0);
6487     iCksum2 += (iCksum2 << 3) + a;
6488   }
6489   rc = sqlite3_finalize(pStmt);
6490   if( rc!=SQLITE_OK ) goto sql_error;
6491 
6492   if( iCksum1!=iCksum2 ){
6493     Tcl_AppendResult(interp, "checksum mismatch", 0);
6494     return TCL_ERROR;
6495   }
6496 
6497   return TCL_OK;
6498  sql_error:
6499   Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
6500   return TCL_ERROR;
6501 }
6502 
6503 
6504 #ifdef SQLITE_USER_AUTHENTICATION
6505 #include "sqlite3userauth.h"
6506 /*
6507 ** tclcmd:  sqlite3_user_authenticate DB USERNAME PASSWORD
6508 */
6509 static int test_user_authenticate(
6510   ClientData clientData, /* Unused */
6511   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6512   int objc,              /* Number of arguments */
6513   Tcl_Obj *CONST objv[]  /* Command arguments */
6514 ){
6515   char *zUser = 0;
6516   char *zPasswd = 0;
6517   int nPasswd = 0;
6518   sqlite3 *db;
6519   int rc;
6520 
6521   if( objc!=4 ){
6522     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD");
6523     return TCL_ERROR;
6524   }
6525   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6526     return TCL_ERROR;
6527   }
6528   zUser = Tcl_GetString(objv[2]);
6529   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
6530   rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd);
6531   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6532   return TCL_OK;
6533 }
6534 #endif /* SQLITE_USER_AUTHENTICATION */
6535 
6536 #ifdef SQLITE_USER_AUTHENTICATION
6537 /*
6538 ** tclcmd:  sqlite3_user_add DB USERNAME PASSWORD ISADMIN
6539 */
6540 static int test_user_add(
6541   ClientData clientData, /* Unused */
6542   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6543   int objc,              /* Number of arguments */
6544   Tcl_Obj *CONST objv[]  /* Command arguments */
6545 ){
6546   char *zUser = 0;
6547   char *zPasswd = 0;
6548   int nPasswd = 0;
6549   int isAdmin = 0;
6550   sqlite3 *db;
6551   int rc;
6552 
6553   if( objc!=5 ){
6554     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
6555     return TCL_ERROR;
6556   }
6557   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6558     return TCL_ERROR;
6559   }
6560   zUser = Tcl_GetString(objv[2]);
6561   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
6562   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
6563   rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin);
6564   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6565   return TCL_OK;
6566 }
6567 #endif /* SQLITE_USER_AUTHENTICATION */
6568 
6569 #ifdef SQLITE_USER_AUTHENTICATION
6570 /*
6571 ** tclcmd:  sqlite3_user_change DB USERNAME PASSWORD ISADMIN
6572 */
6573 static int test_user_change(
6574   ClientData clientData, /* Unused */
6575   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6576   int objc,              /* Number of arguments */
6577   Tcl_Obj *CONST objv[]  /* Command arguments */
6578 ){
6579   char *zUser = 0;
6580   char *zPasswd = 0;
6581   int nPasswd = 0;
6582   int isAdmin = 0;
6583   sqlite3 *db;
6584   int rc;
6585 
6586   if( objc!=5 ){
6587     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
6588     return TCL_ERROR;
6589   }
6590   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6591     return TCL_ERROR;
6592   }
6593   zUser = Tcl_GetString(objv[2]);
6594   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
6595   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
6596   rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin);
6597   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6598   return TCL_OK;
6599 }
6600 #endif /* SQLITE_USER_AUTHENTICATION */
6601 
6602 #ifdef SQLITE_USER_AUTHENTICATION
6603 /*
6604 ** tclcmd:  sqlite3_user_delete DB USERNAME
6605 */
6606 static int test_user_delete(
6607   ClientData clientData, /* Unused */
6608   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6609   int objc,              /* Number of arguments */
6610   Tcl_Obj *CONST objv[]  /* Command arguments */
6611 ){
6612   char *zUser = 0;
6613   sqlite3 *db;
6614   int rc;
6615 
6616   if( objc!=3 ){
6617     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME");
6618     return TCL_ERROR;
6619   }
6620   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6621     return TCL_ERROR;
6622   }
6623   zUser = Tcl_GetString(objv[2]);
6624   rc = sqlite3_user_delete(db, zUser);
6625   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6626   return TCL_OK;
6627 }
6628 #endif /* SQLITE_USER_AUTHENTICATION */
6629 
6630 /*
6631 ** tclcmd: bad_behavior TYPE
6632 **
6633 ** Do some things that should trigger a valgrind or -fsanitize=undefined
6634 ** warning.  This is used to verify that errors and warnings output by those
6635 ** tools are detected by the test scripts.
6636 **
6637 **       TYPE       BEHAVIOR
6638 **       1          Overflow a signed integer
6639 **       2          Jump based on an uninitialized variable
6640 **       3          Read after free
6641 **       4          Panic
6642 */
6643 static int test_bad_behavior(
6644   ClientData clientData, /* Pointer to an integer containing zero */
6645   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6646   int objc,              /* Number of arguments */
6647   Tcl_Obj *CONST objv[]  /* Command arguments */
6648 ){
6649   int iType;
6650   int xyz;
6651   int i = *(int*)clientData;
6652   int j;
6653   int w[10];
6654   int *a;
6655   if( objc!=2 ){
6656     Tcl_WrongNumArgs(interp, 1, objv, "TYPE");
6657     return TCL_ERROR;
6658   }
6659   if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR;
6660   switch( iType ){
6661     case 1: {
6662       xyz = 0x7fffff00 - i;
6663       xyz += 0x100;
6664       Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz));
6665       break;
6666     }
6667     case 2: {
6668       w[1] = 5;
6669       if( w[i]>0 ) w[1]++;
6670       Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1]));
6671       break;
6672     }
6673     case 3: {
6674       a = malloc( sizeof(int)*10 );
6675       for(j=0; j<10; j++) a[j] = j;
6676       free(a);
6677       Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i]));
6678       break;
6679     }
6680     case 4: {
6681       Tcl_Panic("Deliberate panic");
6682       break;
6683     }
6684   }
6685   return TCL_OK;
6686 }
6687 
6688 /*
6689 ** tclcmd:   register_dbstat_vtab DB
6690 **
6691 ** Cause the dbstat virtual table to be available on the connection DB
6692 */
6693 static int test_register_dbstat_vtab(
6694   void *clientData,
6695   Tcl_Interp *interp,
6696   int objc,
6697   Tcl_Obj *CONST objv[]
6698 ){
6699 #ifdef SQLITE_OMIT_VIRTUALTABLE
6700   Tcl_AppendResult(interp, "dbstat not available because of "
6701                            "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
6702   return TCL_ERROR;
6703 #else
6704   struct SqliteDb { sqlite3 *db; };
6705   char *zDb;
6706   Tcl_CmdInfo cmdInfo;
6707 
6708   if( objc!=2 ){
6709     Tcl_WrongNumArgs(interp, 1, objv, "DB");
6710     return TCL_ERROR;
6711   }
6712 
6713   zDb = Tcl_GetString(objv[1]);
6714   if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
6715     sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
6716     sqlite3DbstatRegister(db);
6717   }
6718   return TCL_OK;
6719 #endif /* SQLITE_OMIT_VIRTUALTABLE */
6720 }
6721 
6722 /*
6723 ** Register commands with the TCL interpreter.
6724 */
6725 int Sqlitetest1_Init(Tcl_Interp *interp){
6726   extern int sqlite3_search_count;
6727   extern int sqlite3_found_count;
6728   extern int sqlite3_interrupt_count;
6729   extern int sqlite3_open_file_count;
6730   extern int sqlite3_sort_count;
6731   extern int sqlite3_current_time;
6732 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
6733   extern int sqlite3_hostid_num;
6734 #endif
6735   extern int sqlite3_max_blobsize;
6736   extern int sqlite3BtreeSharedCacheReport(void*,
6737                                           Tcl_Interp*,int,Tcl_Obj*CONST*);
6738   static int iZero = 0;
6739   static struct {
6740      char *zName;
6741      Tcl_CmdProc *xProc;
6742   } aCmd[] = {
6743      { "db_enter",                      (Tcl_CmdProc*)db_enter               },
6744      { "db_leave",                      (Tcl_CmdProc*)db_leave               },
6745      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
6746      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
6747      { "sqlite3_mprintf_long",          (Tcl_CmdProc*)sqlite3_mprintf_long   },
6748      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
6749      { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
6750      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
6751      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
6752      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
6753      { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
6754      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
6755      { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
6756      { "sqlite3_snprintf_int",          (Tcl_CmdProc*)test_snprintf_int     },
6757      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
6758      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
6759      { "sqlite3_exec_hex",              (Tcl_CmdProc*)test_exec_hex         },
6760      { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
6761      { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
6762 #ifndef SQLITE_OMIT_GET_TABLE
6763      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
6764 #endif
6765      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
6766      { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
6767      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
6768      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
6769      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
6770      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
6771      { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
6772      { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
6773      { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
6774      { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
6775      { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
6776      { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
6777      { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
6778      { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
6779      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
6780      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
6781      { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
6782      { "printf",                        (Tcl_CmdProc*)test_printf           },
6783      { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
6784      { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
6785   };
6786   static struct {
6787      char *zName;
6788      Tcl_ObjCmdProc *xProc;
6789      void *clientData;
6790   } aObjCmd[] = {
6791      { "bad_behavior",                  test_bad_behavior,  (void*)&iZero },
6792      { "register_dbstat_vtab",          test_register_dbstat_vtab  },
6793      { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
6794      { "sqlite3_bind_int",              test_bind_int,      0 },
6795      { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
6796      { "sqlite3_bind_int64",            test_bind_int64,    0 },
6797      { "sqlite3_bind_double",           test_bind_double,   0 },
6798      { "sqlite3_bind_null",             test_bind_null     ,0 },
6799      { "sqlite3_bind_text",             test_bind_text     ,0 },
6800      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
6801      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
6802      { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
6803      { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
6804      { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
6805      { "sqlite3_clear_bindings",        test_clear_bindings, 0},
6806      { "sqlite3_sleep",                 test_sleep,          0},
6807      { "sqlite3_errcode",               test_errcode       ,0 },
6808      { "sqlite3_extended_errcode",      test_ex_errcode    ,0 },
6809      { "sqlite3_errmsg",                test_errmsg        ,0 },
6810      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
6811      { "sqlite3_open",                  test_open          ,0 },
6812      { "sqlite3_open16",                test_open16        ,0 },
6813      { "sqlite3_open_v2",               test_open_v2       ,0 },
6814      { "sqlite3_complete16",            test_complete16    ,0 },
6815 
6816      { "sqlite3_prepare",               test_prepare       ,0 },
6817      { "sqlite3_prepare16",             test_prepare16     ,0 },
6818      { "sqlite3_prepare_v2",            test_prepare_v2    ,0 },
6819      { "sqlite3_prepare_tkt3134",       test_prepare_tkt3134, 0},
6820      { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
6821      { "sqlite3_finalize",              test_finalize      ,0 },
6822      { "sqlite3_stmt_status",           test_stmt_status   ,0 },
6823      { "sqlite3_reset",                 test_reset         ,0 },
6824      { "sqlite3_expired",               test_expired       ,0 },
6825      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
6826      { "sqlite3_changes",               test_changes       ,0 },
6827      { "sqlite3_step",                  test_step          ,0 },
6828      { "sqlite3_sql",                   test_sql           ,0 },
6829      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
6830      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
6831      { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
6832      { "uses_stmt_journal",             uses_stmt_journal ,0 },
6833 
6834      { "sqlite3_release_memory",        test_release_memory,     0},
6835      { "sqlite3_db_release_memory",     test_db_release_memory,  0},
6836      { "sqlite3_db_filename",           test_db_filename,        0},
6837      { "sqlite3_db_readonly",           test_db_readonly,        0},
6838      { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
6839      { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
6840      { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
6841 
6842      { "sqlite3_load_extension",        test_load_extension,     0},
6843      { "sqlite3_enable_load_extension", test_enable_load,        0},
6844      { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
6845      { "sqlite3_limit",                 test_limit,                 0},
6846 
6847      { "save_prng_state",               save_prng_state,    0 },
6848      { "restore_prng_state",            restore_prng_state, 0 },
6849      { "reset_prng_state",              reset_prng_state,   0 },
6850      { "database_never_corrupt",        database_never_corrupt, 0},
6851      { "database_may_be_corrupt",       database_may_be_corrupt, 0},
6852      { "optimization_control",          optimization_control,0},
6853 #if SQLITE_OS_WIN
6854      { "lock_win32_file",               win32_file_lock,    0 },
6855      { "exists_win32_path",             win32_exists_path,  0 },
6856      { "find_win32_file",               win32_find_file,    0 },
6857      { "delete_win32_file",             win32_delete_file,  0 },
6858      { "make_win32_dir",                win32_mkdir,        0 },
6859      { "remove_win32_dir",              win32_rmdir,        0 },
6860 #endif
6861      { "tcl_objproc",                   runAsObjProc,       0 },
6862 
6863      /* sqlite3_column_*() API */
6864      { "sqlite3_column_count",          test_column_count  ,0 },
6865      { "sqlite3_data_count",            test_data_count    ,0 },
6866      { "sqlite3_column_type",           test_column_type   ,0 },
6867      { "sqlite3_column_blob",           test_column_blob   ,0 },
6868      { "sqlite3_column_double",         test_column_double ,0 },
6869      { "sqlite3_column_int64",          test_column_int64  ,0 },
6870      { "sqlite3_column_text",   test_stmt_utf8,  (void*)sqlite3_column_text },
6871      { "sqlite3_column_name",   test_stmt_utf8,  (void*)sqlite3_column_name },
6872      { "sqlite3_column_int",    test_stmt_int,   (void*)sqlite3_column_int  },
6873      { "sqlite3_column_bytes",  test_stmt_int,   (void*)sqlite3_column_bytes},
6874 #ifndef SQLITE_OMIT_DECLTYPE
6875      { "sqlite3_column_decltype",test_stmt_utf8,(void*)sqlite3_column_decltype},
6876 #endif
6877 #ifdef SQLITE_ENABLE_COLUMN_METADATA
6878 { "sqlite3_column_database_name",test_stmt_utf8,(void*)sqlite3_column_database_name},
6879 { "sqlite3_column_table_name",test_stmt_utf8,(void*)sqlite3_column_table_name},
6880 { "sqlite3_column_origin_name",test_stmt_utf8,(void*)sqlite3_column_origin_name},
6881 #endif
6882 
6883 #ifndef SQLITE_OMIT_UTF16
6884      { "sqlite3_column_bytes16", test_stmt_int, (void*)sqlite3_column_bytes16 },
6885      { "sqlite3_column_text16",  test_stmt_utf16, (void*)sqlite3_column_text16},
6886      { "sqlite3_column_name16",  test_stmt_utf16, (void*)sqlite3_column_name16},
6887      { "add_alignment_test_collations", add_alignment_test_collations, 0      },
6888 #ifndef SQLITE_OMIT_DECLTYPE
6889      { "sqlite3_column_decltype16",test_stmt_utf16,(void*)sqlite3_column_decltype16},
6890 #endif
6891 #ifdef SQLITE_ENABLE_COLUMN_METADATA
6892 {"sqlite3_column_database_name16",
6893   test_stmt_utf16, (void*)sqlite3_column_database_name16},
6894 {"sqlite3_column_table_name16", test_stmt_utf16, (void*)sqlite3_column_table_name16},
6895 {"sqlite3_column_origin_name16", test_stmt_utf16, (void*)sqlite3_column_origin_name16},
6896 #endif
6897 #endif
6898      { "sqlite3_create_collation_v2", test_create_collation_v2, 0 },
6899      { "sqlite3_global_recover",     test_global_recover, 0   },
6900      { "working_64bit_int",          working_64bit_int,   0   },
6901      { "vfs_unlink_test",            vfs_unlink_test,     0   },
6902      { "vfs_initfail_test",          vfs_initfail_test,   0   },
6903      { "vfs_unregister_all",         vfs_unregister_all,  0   },
6904      { "vfs_reregister_all",         vfs_reregister_all,  0   },
6905      { "file_control_test",          file_control_test,   0   },
6906      { "file_control_lasterrno_test", file_control_lasterrno_test,  0   },
6907      { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
6908      { "file_control_chunksize_test", file_control_chunksize_test,  0   },
6909      { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
6910 #if SQLITE_OS_WIN
6911      { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
6912      { "file_control_win32_set_handle", file_control_win32_set_handle, 0  },
6913 #endif
6914      { "file_control_persist_wal",    file_control_persist_wal,     0   },
6915      { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
6916      { "file_control_vfsname",        file_control_vfsname,         0   },
6917      { "file_control_tempfilename",   file_control_tempfilename,    0   },
6918      { "sqlite3_vfs_list",           vfs_list,     0   },
6919      { "sqlite3_create_function_v2", test_create_function_v2, 0 },
6920 
6921      /* Functions from os.h */
6922 #ifndef SQLITE_OMIT_UTF16
6923      { "add_test_collate",        test_collate, 0            },
6924      { "add_test_collate_needed", test_collate_needed, 0     },
6925      { "add_test_function",       test_function, 0           },
6926      { "add_test_utf16bin_collate",    test_utf16bin_collate, 0        },
6927 #endif
6928      { "sqlite3_test_errstr",     test_errstr, 0             },
6929      { "tcl_variable_type",       tcl_variable_type, 0       },
6930 #ifndef SQLITE_OMIT_SHARED_CACHE
6931      { "sqlite3_enable_shared_cache", test_enable_shared, 0  },
6932      { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
6933 #endif
6934      { "sqlite3_libversion_number", test_libversion_number, 0  },
6935      { "sqlite3_table_column_metadata", test_table_column_metadata, 0  },
6936 #ifndef SQLITE_OMIT_INCRBLOB
6937      { "sqlite3_blob_reopen", test_blob_reopen, 0  },
6938 #endif
6939      { "pcache_stats",       test_pcache_stats, 0  },
6940 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6941      { "sqlite3_unlock_notify", test_unlock_notify, 0  },
6942 #endif
6943      { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
6944      { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
6945      { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0  },
6946      { "test_sqlite3_log",         test_sqlite3_log, 0  },
6947 #ifndef SQLITE_OMIT_EXPLAIN
6948      { "print_explain_query_plan", test_print_eqp, 0  },
6949 #endif
6950      { "sqlite3_test_control", test_test_control },
6951 #if SQLITE_OS_UNIX
6952      { "getrusage", test_getrusage },
6953 #endif
6954      { "load_static_extension", tclLoadStaticExtensionCmd },
6955      { "sorter_test_fakeheap", sorter_test_fakeheap },
6956      { "sorter_test_sort4_helper", sorter_test_sort4_helper },
6957 #ifdef SQLITE_USER_AUTHENTICATION
6958      { "sqlite3_user_authenticate", test_user_authenticate, 0 },
6959      { "sqlite3_user_add",          test_user_add,          0 },
6960      { "sqlite3_user_change",       test_user_change,       0 },
6961      { "sqlite3_user_delete",       test_user_delete,       0 },
6962 #endif
6963 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
6964      { "sqlite3_stmt_scanstatus",       test_stmt_scanstatus,   0 },
6965      { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset,   0 },
6966 #endif
6967 
6968   };
6969   static int bitmask_size = sizeof(Bitmask)*8;
6970   int i;
6971   extern int sqlite3_sync_count, sqlite3_fullsync_count;
6972   extern int sqlite3_opentemp_count;
6973   extern int sqlite3_like_count;
6974   extern int sqlite3_xferopt_count;
6975   extern int sqlite3_pager_readdb_count;
6976   extern int sqlite3_pager_writedb_count;
6977   extern int sqlite3_pager_writej_count;
6978 #if SQLITE_OS_WIN
6979   extern LONG volatile sqlite3_os_type;
6980 #endif
6981 #ifdef SQLITE_DEBUG
6982   extern int sqlite3WhereTrace;
6983   extern int sqlite3OSTrace;
6984   extern int sqlite3WalTrace;
6985 #endif
6986 #ifdef SQLITE_TEST
6987 #ifdef SQLITE_ENABLE_FTS3
6988   extern int sqlite3_fts3_enable_parentheses;
6989 #endif
6990 #endif
6991 
6992   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
6993     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
6994   }
6995   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
6996     Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
6997         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
6998   }
6999   Tcl_LinkVar(interp, "sqlite_search_count",
7000       (char*)&sqlite3_search_count, TCL_LINK_INT);
7001   Tcl_LinkVar(interp, "sqlite_found_count",
7002       (char*)&sqlite3_found_count, TCL_LINK_INT);
7003   Tcl_LinkVar(interp, "sqlite_sort_count",
7004       (char*)&sqlite3_sort_count, TCL_LINK_INT);
7005   Tcl_LinkVar(interp, "sqlite3_max_blobsize",
7006       (char*)&sqlite3_max_blobsize, TCL_LINK_INT);
7007   Tcl_LinkVar(interp, "sqlite_like_count",
7008       (char*)&sqlite3_like_count, TCL_LINK_INT);
7009   Tcl_LinkVar(interp, "sqlite_interrupt_count",
7010       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
7011   Tcl_LinkVar(interp, "sqlite_open_file_count",
7012       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
7013   Tcl_LinkVar(interp, "sqlite_current_time",
7014       (char*)&sqlite3_current_time, TCL_LINK_INT);
7015 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
7016   Tcl_LinkVar(interp, "sqlite_hostid_num",
7017       (char*)&sqlite3_hostid_num, TCL_LINK_INT);
7018 #endif
7019   Tcl_LinkVar(interp, "sqlite3_xferopt_count",
7020       (char*)&sqlite3_xferopt_count, TCL_LINK_INT);
7021   Tcl_LinkVar(interp, "sqlite3_pager_readdb_count",
7022       (char*)&sqlite3_pager_readdb_count, TCL_LINK_INT);
7023   Tcl_LinkVar(interp, "sqlite3_pager_writedb_count",
7024       (char*)&sqlite3_pager_writedb_count, TCL_LINK_INT);
7025   Tcl_LinkVar(interp, "sqlite3_pager_writej_count",
7026       (char*)&sqlite3_pager_writej_count, TCL_LINK_INT);
7027 #ifndef SQLITE_OMIT_UTF16
7028   Tcl_LinkVar(interp, "unaligned_string_counter",
7029       (char*)&unaligned_string_counter, TCL_LINK_INT);
7030 #endif
7031 #ifndef SQLITE_OMIT_UTF16
7032   Tcl_LinkVar(interp, "sqlite_last_needed_collation",
7033       (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7034 #endif
7035 #if SQLITE_OS_WIN
7036   Tcl_LinkVar(interp, "sqlite_os_type",
7037       (char*)&sqlite3_os_type, TCL_LINK_LONG);
7038 #endif
7039 #ifdef SQLITE_TEST
7040   {
7041     static const char *query_plan = "*** OBSOLETE VARIABLE ***";
7042     Tcl_LinkVar(interp, "sqlite_query_plan",
7043        (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7044   }
7045 #endif
7046 #ifdef SQLITE_DEBUG
7047   Tcl_LinkVar(interp, "sqlite_where_trace",
7048       (char*)&sqlite3WhereTrace, TCL_LINK_INT);
7049   Tcl_LinkVar(interp, "sqlite_os_trace",
7050       (char*)&sqlite3OSTrace, TCL_LINK_INT);
7051 #ifndef SQLITE_OMIT_WAL
7052   Tcl_LinkVar(interp, "sqlite_wal_trace",
7053       (char*)&sqlite3WalTrace, TCL_LINK_INT);
7054 #endif
7055 #endif
7056 #ifndef SQLITE_OMIT_DISKIO
7057   Tcl_LinkVar(interp, "sqlite_opentemp_count",
7058       (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
7059 #endif
7060   Tcl_LinkVar(interp, "sqlite_static_bind_value",
7061       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
7062   Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
7063       (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
7064   Tcl_LinkVar(interp, "sqlite_temp_directory",
7065       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
7066   Tcl_LinkVar(interp, "sqlite_data_directory",
7067       (char*)&sqlite3_data_directory, TCL_LINK_STRING);
7068   Tcl_LinkVar(interp, "bitmask_size",
7069       (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
7070   Tcl_LinkVar(interp, "sqlite_sync_count",
7071       (char*)&sqlite3_sync_count, TCL_LINK_INT);
7072   Tcl_LinkVar(interp, "sqlite_fullsync_count",
7073       (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
7074 #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
7075   Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
7076       (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
7077 #endif
7078   return TCL_OK;
7079 }
7080