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