xref: /sqlite-3.40.0/src/test1.c (revision 47d00872)
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_get_handle DB
5682 **
5683 ** This TCL command runs the sqlite3_file_control interface with
5684 ** the SQLITE_FCNTL_WIN32_GET_HANDLE opcode.
5685 */
5686 static int file_control_win32_get_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!=2 ){
5698     Tcl_AppendResult(interp, "wrong # args: should be \"",
5699         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5700     return TCL_ERROR;
5701   }
5702   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5703     return TCL_ERROR;
5704   }
5705   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_GET_HANDLE,
5706                             (void*)&hFile);
5707   sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile);
5708   Tcl_AppendResult(interp, z, (char*)0);
5709   return TCL_OK;
5710 }
5711 
5712 /*
5713 ** tclcmd:   file_control_win32_set_handle DB HANDLE
5714 **
5715 ** This TCL command runs the sqlite3_file_control interface with
5716 ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
5717 */
5718 static int SQLITE_TCLAPI file_control_win32_set_handle(
5719   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5720   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5721   int objc,              /* Number of arguments */
5722   Tcl_Obj *CONST objv[]  /* Command arguments */
5723 ){
5724   sqlite3 *db;
5725   int rc;
5726   HANDLE hFile = NULL;
5727   char z[100];
5728 
5729   if( objc!=3 ){
5730     Tcl_AppendResult(interp, "wrong # args: should be \"",
5731         Tcl_GetStringFromObj(objv[0], 0), " DB HANDLE", 0);
5732     return TCL_ERROR;
5733   }
5734   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5735     return TCL_ERROR;
5736   }
5737   if( getWin32Handle(interp, Tcl_GetString(objv[2]), &hFile) ){
5738     return TCL_ERROR;
5739   }
5740   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_SET_HANDLE,
5741                             (void*)&hFile);
5742   sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile);
5743   Tcl_AppendResult(interp, z, (char*)0);
5744   return TCL_OK;
5745 }
5746 #endif
5747 
5748 /*
5749 ** tclcmd:   file_control_persist_wal DB PERSIST-FLAG
5750 **
5751 ** This TCL command runs the sqlite3_file_control interface with
5752 ** the SQLITE_FCNTL_PERSIST_WAL opcode.
5753 */
5754 static int SQLITE_TCLAPI file_control_persist_wal(
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 bPersist;
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], &bPersist) ) return TCL_ERROR;
5774   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
5775   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
5776   Tcl_AppendResult(interp, z, (char*)0);
5777   return TCL_OK;
5778 }
5779 
5780 /*
5781 ** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
5782 **
5783 ** This TCL command runs the sqlite3_file_control interface with
5784 ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
5785 */
5786 static int SQLITE_TCLAPI file_control_powersafe_overwrite(
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   int rc;
5794   int b;
5795   char z[100];
5796 
5797   if( objc!=3 ){
5798     Tcl_AppendResult(interp, "wrong # args: should be \"",
5799         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
5800     return TCL_ERROR;
5801   }
5802   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5803     return TCL_ERROR;
5804   }
5805   if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
5806   rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b);
5807   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b);
5808   Tcl_AppendResult(interp, z, (char*)0);
5809   return TCL_OK;
5810 }
5811 
5812 
5813 /*
5814 ** tclcmd:   file_control_vfsname DB ?AUXDB?
5815 **
5816 ** Return a string that describes the stack of VFSes.
5817 */
5818 static int SQLITE_TCLAPI file_control_vfsname(
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 *zVfsName = 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_VFSNAME,(void*)&zVfsName);
5840   Tcl_AppendResult(interp, zVfsName, (char*)0);
5841   sqlite3_free(zVfsName);
5842   return TCL_OK;
5843 }
5844 
5845 /*
5846 ** tclcmd:   file_control_tempfilename DB ?AUXDB?
5847 **
5848 ** Return a string that is a temporary filename
5849 */
5850 static int SQLITE_TCLAPI file_control_tempfilename(
5851   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5852   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5853   int objc,              /* Number of arguments */
5854   Tcl_Obj *CONST objv[]  /* Command arguments */
5855 ){
5856   sqlite3 *db;
5857   const char *zDbName = "main";
5858   char *zTName = 0;
5859 
5860   if( objc!=2 && objc!=3 ){
5861     Tcl_AppendResult(interp, "wrong # args: should be \"",
5862         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
5863     return TCL_ERROR;
5864   }
5865   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5866     return TCL_ERROR;
5867   }
5868   if( objc==3 ){
5869     zDbName = Tcl_GetString(objv[2]);
5870   }
5871   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
5872   Tcl_AppendResult(interp, zTName, (char*)0);
5873   sqlite3_free(zTName);
5874   return TCL_OK;
5875 }
5876 
5877 
5878 /*
5879 ** tclcmd:   sqlite3_vfs_list
5880 **
5881 **   Return a tcl list containing the names of all registered vfs's.
5882 */
5883 static int SQLITE_TCLAPI vfs_list(
5884   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5885   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5886   int objc,              /* Number of arguments */
5887   Tcl_Obj *CONST objv[]  /* Command arguments */
5888 ){
5889   sqlite3_vfs *pVfs;
5890   Tcl_Obj *pRet = Tcl_NewObj();
5891   if( objc!=1 ){
5892     Tcl_WrongNumArgs(interp, 1, objv, "");
5893     return TCL_ERROR;
5894   }
5895   for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5896     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(pVfs->zName, -1));
5897   }
5898   Tcl_SetObjResult(interp, pRet);
5899   return TCL_OK;
5900 }
5901 
5902 /*
5903 ** tclcmd:   sqlite3_limit DB ID VALUE
5904 **
5905 ** This TCL command runs the sqlite3_limit interface and
5906 ** verifies correct operation of the same.
5907 */
5908 static int SQLITE_TCLAPI test_limit(
5909   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5910   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5911   int objc,              /* Number of arguments */
5912   Tcl_Obj *CONST objv[]  /* Command arguments */
5913 ){
5914   sqlite3 *db;
5915   int rc;
5916   static const struct {
5917      char *zName;
5918      int id;
5919   } aId[] = {
5920     { "SQLITE_LIMIT_LENGTH",              SQLITE_LIMIT_LENGTH               },
5921     { "SQLITE_LIMIT_SQL_LENGTH",          SQLITE_LIMIT_SQL_LENGTH           },
5922     { "SQLITE_LIMIT_COLUMN",              SQLITE_LIMIT_COLUMN               },
5923     { "SQLITE_LIMIT_EXPR_DEPTH",          SQLITE_LIMIT_EXPR_DEPTH           },
5924     { "SQLITE_LIMIT_COMPOUND_SELECT",     SQLITE_LIMIT_COMPOUND_SELECT      },
5925     { "SQLITE_LIMIT_VDBE_OP",             SQLITE_LIMIT_VDBE_OP              },
5926     { "SQLITE_LIMIT_FUNCTION_ARG",        SQLITE_LIMIT_FUNCTION_ARG         },
5927     { "SQLITE_LIMIT_ATTACHED",            SQLITE_LIMIT_ATTACHED             },
5928     { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH  },
5929     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
5930     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
5931     { "SQLITE_LIMIT_WORKER_THREADS",      SQLITE_LIMIT_WORKER_THREADS       },
5932 
5933     /* Out of range test cases */
5934     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
5935     { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_WORKER_THREADS+1     },
5936   };
5937   int i, id = 0;
5938   int val;
5939   const char *zId;
5940 
5941   if( objc!=4 ){
5942     Tcl_AppendResult(interp, "wrong # args: should be \"",
5943         Tcl_GetStringFromObj(objv[0], 0), " DB ID VALUE", 0);
5944     return TCL_ERROR;
5945   }
5946   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5947   zId = Tcl_GetString(objv[2]);
5948   for(i=0; i<sizeof(aId)/sizeof(aId[0]); i++){
5949     if( strcmp(zId, aId[i].zName)==0 ){
5950       id = aId[i].id;
5951       break;
5952     }
5953   }
5954   if( i>=sizeof(aId)/sizeof(aId[0]) ){
5955     Tcl_AppendResult(interp, "unknown limit type: ", zId, (char*)0);
5956     return TCL_ERROR;
5957   }
5958   if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
5959   rc = sqlite3_limit(db, id, val);
5960   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5961   return TCL_OK;
5962 }
5963 
5964 /*
5965 ** tclcmd:  save_prng_state
5966 **
5967 ** Save the state of the pseudo-random number generator.
5968 ** At the same time, verify that sqlite3_test_control works even when
5969 ** called with an out-of-range opcode.
5970 */
5971 static int SQLITE_TCLAPI save_prng_state(
5972   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5973   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5974   int objc,              /* Number of arguments */
5975   Tcl_Obj *CONST objv[]  /* Command arguments */
5976 ){
5977   int rc = sqlite3_test_control(9999);
5978   assert( rc==0 );
5979   rc = sqlite3_test_control(-1);
5980   assert( rc==0 );
5981   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE);
5982   return TCL_OK;
5983 }
5984 /*
5985 ** tclcmd:  restore_prng_state
5986 */
5987 static int SQLITE_TCLAPI restore_prng_state(
5988   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5989   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5990   int objc,              /* Number of arguments */
5991   Tcl_Obj *CONST objv[]  /* Command arguments */
5992 ){
5993   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE);
5994   return TCL_OK;
5995 }
5996 /*
5997 ** tclcmd:  reset_prng_state
5998 */
5999 static int SQLITE_TCLAPI reset_prng_state(
6000   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
6001   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6002   int objc,              /* Number of arguments */
6003   Tcl_Obj *CONST objv[]  /* Command arguments */
6004 ){
6005   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
6006   return TCL_OK;
6007 }
6008 
6009 /*
6010 ** tclcmd:  database_may_be_corrupt
6011 **
6012 ** Indicate that database files might be corrupt.  In other words, set the normal
6013 ** state of operation.
6014 */
6015 static int SQLITE_TCLAPI database_may_be_corrupt(
6016   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
6017   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6018   int objc,              /* Number of arguments */
6019   Tcl_Obj *CONST objv[]  /* Command arguments */
6020 ){
6021   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0);
6022   return TCL_OK;
6023 }
6024 /*
6025 ** tclcmd:  database_never_corrupt
6026 **
6027 ** Indicate that database files are always well-formed.  This enables extra assert()
6028 ** statements that test conditions that are always true for well-formed databases.
6029 */
6030 static int SQLITE_TCLAPI database_never_corrupt(
6031   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
6032   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6033   int objc,              /* Number of arguments */
6034   Tcl_Obj *CONST objv[]  /* Command arguments */
6035 ){
6036   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1);
6037   return TCL_OK;
6038 }
6039 
6040 /*
6041 ** tclcmd:  pcache_stats
6042 */
6043 static int SQLITE_TCLAPI test_pcache_stats(
6044   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
6045   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6046   int objc,              /* Number of arguments */
6047   Tcl_Obj *CONST objv[]  /* Command arguments */
6048 ){
6049   int nMin;
6050   int nMax;
6051   int nCurrent;
6052   int nRecyclable;
6053   Tcl_Obj *pRet;
6054 
6055   sqlite3PcacheStats(&nCurrent, &nMax, &nMin, &nRecyclable);
6056 
6057   pRet = Tcl_NewObj();
6058   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("current", -1));
6059   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCurrent));
6060   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("max", -1));
6061   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMax));
6062   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("min", -1));
6063   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMin));
6064   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("recyclable", -1));
6065   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nRecyclable));
6066 
6067   Tcl_SetObjResult(interp, pRet);
6068 
6069   return TCL_OK;
6070 }
6071 
6072 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6073 static void test_unlock_notify_cb(void **aArg, int nArg){
6074   int ii;
6075   for(ii=0; ii<nArg; ii++){
6076     Tcl_EvalEx((Tcl_Interp *)aArg[ii], "unlock_notify", -1, TCL_EVAL_GLOBAL);
6077   }
6078 }
6079 #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
6080 
6081 /*
6082 ** tclcmd:  sqlite3_unlock_notify db
6083 */
6084 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6085 static int SQLITE_TCLAPI test_unlock_notify(
6086   ClientData clientData, /* Unused */
6087   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6088   int objc,              /* Number of arguments */
6089   Tcl_Obj *CONST objv[]  /* Command arguments */
6090 ){
6091   sqlite3 *db;
6092   int rc;
6093 
6094   if( objc!=2 ){
6095     Tcl_WrongNumArgs(interp, 1, objv, "DB");
6096     return TCL_ERROR;
6097   }
6098 
6099   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6100     return TCL_ERROR;
6101   }
6102   rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void *)interp);
6103   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6104   return TCL_OK;
6105 }
6106 #endif
6107 
6108 /*
6109 ** tclcmd:  sqlite3_wal_checkpoint db ?NAME?
6110 */
6111 static int SQLITE_TCLAPI test_wal_checkpoint(
6112   ClientData clientData, /* Unused */
6113   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6114   int objc,              /* Number of arguments */
6115   Tcl_Obj *CONST objv[]  /* Command arguments */
6116 ){
6117   char *zDb = 0;
6118   sqlite3 *db;
6119   int rc;
6120 
6121   if( objc!=3 && objc!=2 ){
6122     Tcl_WrongNumArgs(interp, 1, objv, "DB ?NAME?");
6123     return TCL_ERROR;
6124   }
6125 
6126   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6127     return TCL_ERROR;
6128   }
6129   if( objc==3 ){
6130     zDb = Tcl_GetString(objv[2]);
6131   }
6132   rc = sqlite3_wal_checkpoint(db, zDb);
6133   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6134   return TCL_OK;
6135 }
6136 
6137 /*
6138 ** tclcmd:  sqlite3_wal_checkpoint_v2 db MODE ?NAME?
6139 **
6140 ** This command calls the wal_checkpoint_v2() function with the specified
6141 ** mode argument (passive, full or restart). If present, the database name
6142 ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
6143 ** NAME argument is not present, a NULL pointer is passed instead.
6144 **
6145 ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
6146 ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
6147 ** to the error message obtained from sqlite3_errmsg().
6148 **
6149 ** Otherwise, this command returns a list of three integers. The first integer
6150 ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
6151 ** are the values returned via the output parameters by wal_checkpoint_v2() -
6152 ** the number of frames in the log and the number of frames in the log
6153 ** that have been checkpointed.
6154 */
6155 static int SQLITE_TCLAPI test_wal_checkpoint_v2(
6156   ClientData clientData, /* Unused */
6157   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6158   int objc,              /* Number of arguments */
6159   Tcl_Obj *CONST objv[]  /* Command arguments */
6160 ){
6161   char *zDb = 0;
6162   sqlite3 *db;
6163   int rc;
6164 
6165   int eMode;
6166   int nLog = -555;
6167   int nCkpt = -555;
6168   Tcl_Obj *pRet;
6169 
6170   const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
6171   assert( SQLITE_CHECKPOINT_PASSIVE==0 );
6172   assert( SQLITE_CHECKPOINT_FULL==1 );
6173   assert( SQLITE_CHECKPOINT_RESTART==2 );
6174   assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
6175 
6176   if( objc!=3 && objc!=4 ){
6177     Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
6178     return TCL_ERROR;
6179   }
6180 
6181   if( objc==4 ){
6182     zDb = Tcl_GetString(objv[3]);
6183   }
6184   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) || (
6185       TCL_OK!=Tcl_GetIntFromObj(0, objv[2], &eMode)
6186    && TCL_OK!=Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode)
6187   )){
6188     return TCL_ERROR;
6189   }
6190 
6191   rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt);
6192   if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
6193     const char *zErrCode = sqlite3ErrName(rc);
6194     Tcl_ResetResult(interp);
6195     Tcl_AppendResult(interp, zErrCode, " - ", (char *)sqlite3_errmsg(db), 0);
6196     return TCL_ERROR;
6197   }
6198 
6199   pRet = Tcl_NewObj();
6200   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
6201   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
6202   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
6203   Tcl_SetObjResult(interp, pRet);
6204 
6205   return TCL_OK;
6206 }
6207 
6208 /*
6209 ** tclcmd:  sqlite3_wal_autocheckpoint db VALUE
6210 */
6211 static int SQLITE_TCLAPI test_wal_autocheckpoint(
6212   ClientData clientData, /* Unused */
6213   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6214   int objc,              /* Number of arguments */
6215   Tcl_Obj *CONST objv[]  /* Command arguments */
6216 ){
6217   sqlite3 *db;
6218   int rc;
6219   int iVal;
6220 
6221 
6222   if( objc!=3 ){
6223     Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE");
6224     return TCL_ERROR;
6225   }
6226 
6227   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
6228    || Tcl_GetIntFromObj(0, objv[2], &iVal)
6229   ){
6230     return TCL_ERROR;
6231   }
6232 
6233   rc = sqlite3_wal_autocheckpoint(db, iVal);
6234   Tcl_ResetResult(interp);
6235   if( rc!=SQLITE_OK ){
6236     const char *zErrCode = sqlite3ErrName(rc);
6237     Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1));
6238     return TCL_ERROR;
6239   }
6240 
6241   return TCL_OK;
6242 }
6243 
6244 
6245 /*
6246 ** tclcmd:  test_sqlite3_log ?SCRIPT?
6247 */
6248 static struct LogCallback {
6249   Tcl_Interp *pInterp;
6250   Tcl_Obj *pObj;
6251 } logcallback = {0, 0};
6252 static void xLogcallback(void *unused, int err, char *zMsg){
6253   Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj);
6254   Tcl_IncrRefCount(pNew);
6255   Tcl_ListObjAppendElement(
6256       0, pNew, Tcl_NewStringObj(sqlite3ErrName(err), -1)
6257   );
6258   Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zMsg, -1));
6259   Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
6260   Tcl_DecrRefCount(pNew);
6261 }
6262 static int SQLITE_TCLAPI test_sqlite3_log(
6263   ClientData clientData,
6264   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6265   int objc,              /* Number of arguments */
6266   Tcl_Obj *CONST objv[]  /* Command arguments */
6267 ){
6268   if( objc>2 ){
6269     Tcl_WrongNumArgs(interp, 1, objv, "SCRIPT");
6270     return TCL_ERROR;
6271   }
6272   if( logcallback.pObj ){
6273     Tcl_DecrRefCount(logcallback.pObj);
6274     logcallback.pObj = 0;
6275     logcallback.pInterp = 0;
6276     sqlite3_config(SQLITE_CONFIG_LOG, (void*)0, (void*)0);
6277   }
6278   if( objc>1 ){
6279     logcallback.pObj = objv[1];
6280     Tcl_IncrRefCount(logcallback.pObj);
6281     logcallback.pInterp = interp;
6282     sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, (void*)0);
6283   }
6284   return TCL_OK;
6285 }
6286 
6287 /*
6288 **     tcl_objproc COMMANDNAME ARGS...
6289 **
6290 ** Run a TCL command using its objProc interface.  Throw an error if
6291 ** the command has no objProc interface.
6292 */
6293 static int SQLITE_TCLAPI runAsObjProc(
6294   void * clientData,
6295   Tcl_Interp *interp,
6296   int objc,
6297   Tcl_Obj *CONST objv[]
6298 ){
6299   Tcl_CmdInfo cmdInfo;
6300   if( objc<2 ){
6301     Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ...");
6302     return TCL_ERROR;
6303   }
6304   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
6305     Tcl_AppendResult(interp, "command not found: ",
6306            Tcl_GetString(objv[1]), (char*)0);
6307     return TCL_ERROR;
6308   }
6309   if( cmdInfo.objProc==0 ){
6310     Tcl_AppendResult(interp, "command has no objProc: ",
6311            Tcl_GetString(objv[1]), (char*)0);
6312     return TCL_ERROR;
6313   }
6314   return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1);
6315 }
6316 
6317 #ifndef SQLITE_OMIT_EXPLAIN
6318 /*
6319 ** WARNING: The following function, printExplainQueryPlan() is an exact
6320 ** copy of example code from eqp.in (eqp.html). If this code is modified,
6321 ** then the documentation copy needs to be modified as well.
6322 */
6323 /*
6324 ** Argument pStmt is a prepared SQL statement. This function compiles
6325 ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
6326 ** and prints the report to stdout using printf().
6327 */
6328 int printExplainQueryPlan(sqlite3_stmt *pStmt){
6329   const char *zSql;               /* Input SQL */
6330   char *zExplain;                 /* SQL with EXPLAIN QUERY PLAN prepended */
6331   sqlite3_stmt *pExplain;         /* Compiled EXPLAIN QUERY PLAN command */
6332   int rc;                         /* Return code from sqlite3_prepare_v2() */
6333 
6334   zSql = sqlite3_sql(pStmt);
6335   if( zSql==0 ) return SQLITE_ERROR;
6336 
6337   zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
6338   if( zExplain==0 ) return SQLITE_NOMEM;
6339 
6340   rc = sqlite3_prepare_v2(sqlite3_db_handle(pStmt), zExplain, -1, &pExplain, 0);
6341   sqlite3_free(zExplain);
6342   if( rc!=SQLITE_OK ) return rc;
6343 
6344   while( SQLITE_ROW==sqlite3_step(pExplain) ){
6345     int iSelectid = sqlite3_column_int(pExplain, 0);
6346     int iOrder = sqlite3_column_int(pExplain, 1);
6347     int iFrom = sqlite3_column_int(pExplain, 2);
6348     const char *zDetail = (const char *)sqlite3_column_text(pExplain, 3);
6349 
6350     printf("%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail);
6351   }
6352 
6353   return sqlite3_finalize(pExplain);
6354 }
6355 
6356 static int SQLITE_TCLAPI test_print_eqp(
6357   void * clientData,
6358   Tcl_Interp *interp,
6359   int objc,
6360   Tcl_Obj *CONST objv[]
6361 ){
6362   int rc;
6363   sqlite3_stmt *pStmt;
6364 
6365   if( objc!=2 ){
6366     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
6367     return TCL_ERROR;
6368   }
6369   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
6370   rc = printExplainQueryPlan(pStmt);
6371   /* This is needed on Windows so that a test case using this
6372   ** function can open a read pipe and get the output of
6373   ** printExplainQueryPlan() immediately.
6374   */
6375   fflush(stdout);
6376   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
6377   return TCL_OK;
6378 }
6379 #endif /* SQLITE_OMIT_EXPLAIN */
6380 
6381 /*
6382 ** sqlite3_test_control VERB ARGS...
6383 */
6384 static int SQLITE_TCLAPI test_test_control(
6385   void * clientData,
6386   Tcl_Interp *interp,
6387   int objc,
6388   Tcl_Obj *CONST objv[]
6389 ){
6390   struct Verb {
6391     const char *zName;
6392     int i;
6393   } aVerb[] = {
6394     { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
6395     { "SQLITE_TESTCTRL_SORTER_MMAP",     SQLITE_TESTCTRL_SORTER_MMAP     },
6396     { "SQLITE_TESTCTRL_IMPOSTER",        SQLITE_TESTCTRL_IMPOSTER        },
6397   };
6398   int iVerb;
6399   int iFlag;
6400   int rc;
6401 
6402   if( objc<2 ){
6403     Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS...");
6404     return TCL_ERROR;
6405   }
6406 
6407   rc = Tcl_GetIndexFromObjStruct(
6408       interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
6409   );
6410   if( rc!=TCL_OK ) return rc;
6411 
6412   iFlag = aVerb[iVerb].i;
6413   switch( iFlag ){
6414     case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
6415       int val;
6416       if( objc!=3 ){
6417         Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
6418         return TCL_ERROR;
6419       }
6420       if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
6421       sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
6422       break;
6423     }
6424 
6425     case SQLITE_TESTCTRL_SORTER_MMAP: {
6426       int val;
6427       sqlite3 *db;
6428       if( objc!=4 ){
6429         Tcl_WrongNumArgs(interp, 2, objv, "DB LIMIT");
6430         return TCL_ERROR;
6431       }
6432       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
6433       if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
6434       sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
6435       break;
6436     }
6437 
6438     case SQLITE_TESTCTRL_IMPOSTER: {
6439       int onOff, tnum;
6440       const char *zDbName;
6441       sqlite3 *db;
6442       if( objc!=6 ){
6443         Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
6444         return TCL_ERROR;
6445       }
6446       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
6447       zDbName = Tcl_GetString(objv[3]);
6448       if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
6449       if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
6450       sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
6451       break;
6452     }
6453   }
6454 
6455   Tcl_ResetResult(interp);
6456   return TCL_OK;
6457 }
6458 
6459 #if SQLITE_OS_UNIX
6460 #include <sys/time.h>
6461 #include <sys/resource.h>
6462 
6463 static int SQLITE_TCLAPI test_getrusage(
6464   void * clientData,
6465   Tcl_Interp *interp,
6466   int objc,
6467   Tcl_Obj *CONST objv[]
6468 ){
6469   char buf[1024];
6470   struct rusage r;
6471   memset(&r, 0, sizeof(r));
6472   getrusage(RUSAGE_SELF, &r);
6473 
6474   sqlite3_snprintf(sizeof(buf), buf,
6475     "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
6476     (int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec,
6477     (int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec,
6478     (int)r.ru_minflt, (int)r.ru_majflt
6479   );
6480   Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
6481   return TCL_OK;
6482 }
6483 #endif
6484 
6485 #if SQLITE_OS_WIN
6486 /*
6487 ** Information passed from the main thread into the windows file locker
6488 ** background thread.
6489 */
6490 struct win32FileLocker {
6491   char *evName;       /* Name of event to signal thread startup */
6492   HANDLE h;           /* Handle of the file to be locked */
6493   int delay1;         /* Delay before locking */
6494   int delay2;         /* Delay before unlocking */
6495   int ok;             /* Finished ok */
6496   int err;            /* True if an error occurs */
6497 };
6498 #endif
6499 
6500 
6501 #if SQLITE_OS_WIN
6502 #include <process.h>
6503 /*
6504 ** The background thread that does file locking.
6505 */
6506 static void SQLITE_CDECL win32_file_locker(void *pAppData){
6507   struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
6508   if( p->evName ){
6509     HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
6510     if ( ev ){
6511       SetEvent(ev);
6512       CloseHandle(ev);
6513     }
6514   }
6515   if( p->delay1 ) Sleep(p->delay1);
6516   if( LockFile(p->h, 0, 0, 100000000, 0) ){
6517     Sleep(p->delay2);
6518     UnlockFile(p->h, 0, 0, 100000000, 0);
6519     p->ok = 1;
6520   }else{
6521     p->err = 1;
6522   }
6523   CloseHandle(p->h);
6524   p->h = 0;
6525   p->delay1 = 0;
6526   p->delay2 = 0;
6527 }
6528 #endif
6529 
6530 #if SQLITE_OS_WIN
6531 /*
6532 **      lock_win32_file FILENAME DELAY1 DELAY2
6533 **
6534 ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
6535 ** Wait DELAY1 milliseconds before acquiring the lock.
6536 */
6537 static int SQLITE_TCLAPI win32_file_lock(
6538   void * clientData,
6539   Tcl_Interp *interp,
6540   int objc,
6541   Tcl_Obj *CONST objv[]
6542 ){
6543   static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
6544   const char *zFilename;
6545   char zBuf[200];
6546   int retry = 0;
6547   HANDLE ev;
6548   DWORD wResult;
6549 
6550   if( objc!=4 && objc!=1 ){
6551     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
6552     return TCL_ERROR;
6553   }
6554   if( objc==1 ){
6555     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
6556                      x.ok, x.err, x.delay1, x.delay2, x.h);
6557     Tcl_AppendResult(interp, zBuf, (char*)0);
6558     return TCL_OK;
6559   }
6560   while( x.h && retry<30 ){
6561     retry++;
6562     Sleep(100);
6563   }
6564   if( x.h ){
6565     Tcl_AppendResult(interp, "busy", (char*)0);
6566     return TCL_ERROR;
6567   }
6568   if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
6569   if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
6570   zFilename = Tcl_GetString(objv[1]);
6571   x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
6572               FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
6573               FILE_ATTRIBUTE_NORMAL, 0);
6574   if( !x.h ){
6575     Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
6576     return TCL_ERROR;
6577   }
6578   ev = CreateEvent(NULL, TRUE, FALSE, x.evName);
6579   if ( !ev ){
6580     Tcl_AppendResult(interp, "cannot create event: ", x.evName, (char*)0);
6581     return TCL_ERROR;
6582   }
6583   _beginthread(win32_file_locker, 0, (void*)&x);
6584   Sleep(0);
6585   if ( (wResult = WaitForSingleObject(ev, 10000))!=WAIT_OBJECT_0 ){
6586     sqlite3_snprintf(sizeof(zBuf), zBuf, "0x%x", wResult);
6587     Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0);
6588     CloseHandle(ev);
6589     return TCL_ERROR;
6590   }
6591   CloseHandle(ev);
6592   return TCL_OK;
6593 }
6594 
6595 /*
6596 **      exists_win32_path PATH
6597 **
6598 ** Returns non-zero if the specified path exists, whose fully qualified name
6599 ** may exceed 260 characters if it is prefixed with "\\?\".
6600 */
6601 static int SQLITE_TCLAPI win32_exists_path(
6602   void *clientData,
6603   Tcl_Interp *interp,
6604   int objc,
6605   Tcl_Obj *CONST objv[]
6606 ){
6607   if( objc!=2 ){
6608     Tcl_WrongNumArgs(interp, 1, objv, "PATH");
6609     return TCL_ERROR;
6610   }
6611   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
6612       GetFileAttributesW( Tcl_GetUnicode(objv[1]))!=INVALID_FILE_ATTRIBUTES ));
6613   return TCL_OK;
6614 }
6615 
6616 /*
6617 **      find_win32_file PATTERN
6618 **
6619 ** Returns a list of entries in a directory that match the specified pattern,
6620 ** whose fully qualified name may exceed 248 characters if it is prefixed with
6621 ** "\\?\".
6622 */
6623 static int SQLITE_TCLAPI win32_find_file(
6624   void *clientData,
6625   Tcl_Interp *interp,
6626   int objc,
6627   Tcl_Obj *CONST objv[]
6628 ){
6629   HANDLE hFindFile = INVALID_HANDLE_VALUE;
6630   WIN32_FIND_DATAW findData;
6631   Tcl_Obj *listObj;
6632   DWORD lastErrno;
6633   if( objc!=2 ){
6634     Tcl_WrongNumArgs(interp, 1, objv, "PATTERN");
6635     return TCL_ERROR;
6636   }
6637   hFindFile = FindFirstFileW(Tcl_GetUnicode(objv[1]), &findData);
6638   if( hFindFile==INVALID_HANDLE_VALUE ){
6639     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6640     return TCL_ERROR;
6641   }
6642   listObj = Tcl_NewObj();
6643   Tcl_IncrRefCount(listObj);
6644   do {
6645     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewUnicodeObj(
6646         findData.cFileName, -1));
6647     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(
6648         findData.dwFileAttributes));
6649   } while( FindNextFileW(hFindFile, &findData) );
6650   lastErrno = GetLastError();
6651   if( lastErrno!=NO_ERROR && lastErrno!=ERROR_NO_MORE_FILES ){
6652     FindClose(hFindFile);
6653     Tcl_DecrRefCount(listObj);
6654     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6655     return TCL_ERROR;
6656   }
6657   FindClose(hFindFile);
6658   Tcl_SetObjResult(interp, listObj);
6659   return TCL_OK;
6660 }
6661 
6662 /*
6663 **      delete_win32_file FILENAME
6664 **
6665 ** Deletes the specified file, whose fully qualified name may exceed 260
6666 ** characters if it is prefixed with "\\?\".
6667 */
6668 static int SQLITE_TCLAPI win32_delete_file(
6669   void *clientData,
6670   Tcl_Interp *interp,
6671   int objc,
6672   Tcl_Obj *CONST objv[]
6673 ){
6674   if( objc!=2 ){
6675     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
6676     return TCL_ERROR;
6677   }
6678   if( !DeleteFileW(Tcl_GetUnicode(objv[1])) ){
6679     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6680     return TCL_ERROR;
6681   }
6682   Tcl_ResetResult(interp);
6683   return TCL_OK;
6684 }
6685 
6686 /*
6687 **      make_win32_dir DIRECTORY
6688 **
6689 ** Creates the specified directory, whose fully qualified name may exceed 248
6690 ** characters if it is prefixed with "\\?\".
6691 */
6692 static int SQLITE_TCLAPI win32_mkdir(
6693   void *clientData,
6694   Tcl_Interp *interp,
6695   int objc,
6696   Tcl_Obj *CONST objv[]
6697 ){
6698   if( objc!=2 ){
6699     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6700     return TCL_ERROR;
6701   }
6702   if( !CreateDirectoryW(Tcl_GetUnicode(objv[1]), NULL) ){
6703     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6704     return TCL_ERROR;
6705   }
6706   Tcl_ResetResult(interp);
6707   return TCL_OK;
6708 }
6709 
6710 /*
6711 **      remove_win32_dir DIRECTORY
6712 **
6713 ** Removes the specified directory, whose fully qualified name may exceed 248
6714 ** characters if it is prefixed with "\\?\".
6715 */
6716 static int SQLITE_TCLAPI win32_rmdir(
6717   void *clientData,
6718   Tcl_Interp *interp,
6719   int objc,
6720   Tcl_Obj *CONST objv[]
6721 ){
6722   if( objc!=2 ){
6723     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6724     return TCL_ERROR;
6725   }
6726   if( !RemoveDirectoryW(Tcl_GetUnicode(objv[1])) ){
6727     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6728     return TCL_ERROR;
6729   }
6730   Tcl_ResetResult(interp);
6731   return TCL_OK;
6732 }
6733 #endif
6734 
6735 
6736 /*
6737 **      optimization_control DB OPT BOOLEAN
6738 **
6739 ** Enable or disable query optimizations using the sqlite3_test_control()
6740 ** interface.  Disable if BOOLEAN is false and enable if BOOLEAN is true.
6741 ** OPT is the name of the optimization to be disabled.
6742 */
6743 static int SQLITE_TCLAPI optimization_control(
6744   void * clientData,
6745   Tcl_Interp *interp,
6746   int objc,
6747   Tcl_Obj *CONST objv[]
6748 ){
6749   int i;
6750   sqlite3 *db;
6751   const char *zOpt;
6752   int onoff;
6753   int mask = 0;
6754   static const struct {
6755     const char *zOptName;
6756     int mask;
6757   } aOpt[] = {
6758     { "all",                 SQLITE_AllOpts        },
6759     { "none",                0                     },
6760     { "query-flattener",     SQLITE_QueryFlattener },
6761     { "column-cache",        SQLITE_ColumnCache    },
6762     { "groupby-order",       SQLITE_GroupByOrder   },
6763     { "factor-constants",    SQLITE_FactorOutConst },
6764     { "distinct-opt",        SQLITE_DistinctOpt    },
6765     { "cover-idx-scan",      SQLITE_CoverIdxScan   },
6766     { "order-by-idx-join",   SQLITE_OrderByIdxJoin },
6767     { "transitive",          SQLITE_Transitive     },
6768     { "subquery-coroutine",  SQLITE_SubqCoroutine  },
6769     { "omit-noop-join",      SQLITE_OmitNoopJoin   },
6770     { "stat3",               SQLITE_Stat34         },
6771     { "stat4",               SQLITE_Stat34         },
6772   };
6773 
6774   if( objc!=4 ){
6775     Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
6776     return TCL_ERROR;
6777   }
6778   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6779   if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ) return TCL_ERROR;
6780   zOpt = Tcl_GetString(objv[2]);
6781   for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6782     if( strcmp(zOpt, aOpt[i].zOptName)==0 ){
6783       mask = aOpt[i].mask;
6784       break;
6785     }
6786   }
6787   if( onoff ) mask = ~mask;
6788   if( i>=sizeof(aOpt)/sizeof(aOpt[0]) ){
6789     Tcl_AppendResult(interp, "unknown optimization - should be one of:",
6790                      (char*)0);
6791     for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6792       Tcl_AppendResult(interp, " ", aOpt[i].zOptName, (char*)0);
6793     }
6794     return TCL_ERROR;
6795   }
6796   sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
6797   return TCL_OK;
6798 }
6799 
6800 /*
6801 **     load_static_extension DB NAME ...
6802 **
6803 ** Load one or more statically linked extensions.
6804 */
6805 static int SQLITE_TCLAPI tclLoadStaticExtensionCmd(
6806   void * clientData,
6807   Tcl_Interp *interp,
6808   int objc,
6809   Tcl_Obj *CONST objv[]
6810 ){
6811   extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
6812   extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*);
6813   extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
6814   extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
6815   extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
6816   extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
6817   extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
6818   extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
6819   extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
6820   extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
6821   extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
6822   extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*);
6823   extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
6824   extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
6825   extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
6826   static const struct {
6827     const char *zExtName;
6828     int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
6829   } aExtension[] = {
6830     { "amatch",                sqlite3_amatch_init               },
6831     { "carray",                sqlite3_carray_init               },
6832     { "closure",               sqlite3_closure_init              },
6833     { "csv",                   sqlite3_csv_init                  },
6834     { "eval",                  sqlite3_eval_init                 },
6835     { "fileio",                sqlite3_fileio_init               },
6836     { "fuzzer",                sqlite3_fuzzer_init               },
6837     { "ieee754",               sqlite3_ieee_init                 },
6838     { "nextchar",              sqlite3_nextchar_init             },
6839     { "percentile",            sqlite3_percentile_init           },
6840     { "regexp",                sqlite3_regexp_init               },
6841     { "series",                sqlite3_series_init               },
6842     { "spellfix",              sqlite3_spellfix_init             },
6843     { "totype",                sqlite3_totype_init               },
6844     { "wholenumber",           sqlite3_wholenumber_init          },
6845   };
6846   sqlite3 *db;
6847   const char *zName;
6848   int i, j, rc;
6849   char *zErrMsg = 0;
6850   if( objc<3 ){
6851     Tcl_WrongNumArgs(interp, 1, objv, "DB NAME ...");
6852     return TCL_ERROR;
6853   }
6854   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6855   for(j=2; j<objc; j++){
6856     zName = Tcl_GetString(objv[j]);
6857     for(i=0; i<ArraySize(aExtension); i++){
6858       if( strcmp(zName, aExtension[i].zExtName)==0 ) break;
6859     }
6860     if( i>=ArraySize(aExtension) ){
6861       Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0);
6862       return TCL_ERROR;
6863     }
6864     if( aExtension[i].pInit ){
6865       rc = aExtension[i].pInit(db, &zErrMsg, 0);
6866     }else{
6867       rc = SQLITE_OK;
6868     }
6869     if( rc!=SQLITE_OK || zErrMsg ){
6870       Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
6871                        (char*)0);
6872       sqlite3_free(zErrMsg);
6873       return TCL_ERROR;
6874     }
6875   }
6876   return TCL_OK;
6877 }
6878 
6879 /*
6880 **     sorter_test_fakeheap BOOL
6881 **
6882 */
6883 static int SQLITE_TCLAPI sorter_test_fakeheap(
6884   void * clientData,
6885   Tcl_Interp *interp,
6886   int objc,
6887   Tcl_Obj *CONST objv[]
6888 ){
6889   int bArg;
6890   if( objc!=2 ){
6891     Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
6892     return TCL_ERROR;
6893   }
6894 
6895   if( Tcl_GetBooleanFromObj(interp, objv[1], &bArg) ){
6896     return TCL_ERROR;
6897   }
6898 
6899   if( bArg ){
6900     if( sqlite3GlobalConfig.pHeap==0 ){
6901       sqlite3GlobalConfig.pHeap = SQLITE_INT_TO_PTR(-1);
6902     }
6903   }else{
6904     if( sqlite3GlobalConfig.pHeap==SQLITE_INT_TO_PTR(-1) ){
6905       sqlite3GlobalConfig.pHeap = 0;
6906     }
6907   }
6908 
6909   Tcl_ResetResult(interp);
6910   return TCL_OK;
6911 }
6912 
6913 /*
6914 **     sorter_test_sort4_helper DB SQL1 NSTEP SQL2
6915 **
6916 ** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
6917 ** check that the leftmost and rightmost columns returned are both integers,
6918 ** and that both contain the same value.
6919 **
6920 ** Then execute statement $SQL2. Check that the statement returns the same
6921 ** set of integers in the same order as in the previous step (using $SQL1).
6922 */
6923 static int SQLITE_TCLAPI sorter_test_sort4_helper(
6924   void * clientData,
6925   Tcl_Interp *interp,
6926   int objc,
6927   Tcl_Obj *CONST objv[]
6928 ){
6929   const char *zSql1;
6930   const char *zSql2;
6931   int nStep;
6932   int iStep;
6933   unsigned int iCksum1 = 0;
6934   unsigned int iCksum2 = 0;
6935   int rc;
6936   int iB;
6937   sqlite3 *db;
6938   sqlite3_stmt *pStmt;
6939 
6940   if( objc!=5 ){
6941     Tcl_WrongNumArgs(interp, 1, objv, "DB SQL1 NSTEP SQL2");
6942     return TCL_ERROR;
6943   }
6944 
6945   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6946   zSql1 = Tcl_GetString(objv[2]);
6947   if( Tcl_GetIntFromObj(interp, objv[3], &nStep) ) return TCL_ERROR;
6948   zSql2 = Tcl_GetString(objv[4]);
6949 
6950   rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0);
6951   if( rc!=SQLITE_OK ) goto sql_error;
6952 
6953   iB = sqlite3_column_count(pStmt)-1;
6954   for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6955     int a = sqlite3_column_int(pStmt, 0);
6956     if( a!=sqlite3_column_int(pStmt, iB) ){
6957       Tcl_AppendResult(interp, "data error: (a!=b)", 0);
6958       return TCL_ERROR;
6959     }
6960 
6961     iCksum1 += (iCksum1 << 3) + (unsigned int)a;
6962   }
6963   rc = sqlite3_finalize(pStmt);
6964   if( rc!=SQLITE_OK ) goto sql_error;
6965 
6966   rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0);
6967   if( rc!=SQLITE_OK ) goto sql_error;
6968   for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6969     int a = sqlite3_column_int(pStmt, 0);
6970     iCksum2 += (iCksum2 << 3) + (unsigned int)a;
6971   }
6972   rc = sqlite3_finalize(pStmt);
6973   if( rc!=SQLITE_OK ) goto sql_error;
6974 
6975   if( iCksum1!=iCksum2 ){
6976     Tcl_AppendResult(interp, "checksum mismatch", 0);
6977     return TCL_ERROR;
6978   }
6979 
6980   return TCL_OK;
6981  sql_error:
6982   Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
6983   return TCL_ERROR;
6984 }
6985 
6986 
6987 #ifdef SQLITE_USER_AUTHENTICATION
6988 #include "sqlite3userauth.h"
6989 /*
6990 ** tclcmd:  sqlite3_user_authenticate DB USERNAME PASSWORD
6991 */
6992 static int SQLITE_TCLAPI test_user_authenticate(
6993   ClientData clientData, /* Unused */
6994   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6995   int objc,              /* Number of arguments */
6996   Tcl_Obj *CONST objv[]  /* Command arguments */
6997 ){
6998   char *zUser = 0;
6999   char *zPasswd = 0;
7000   int nPasswd = 0;
7001   sqlite3 *db;
7002   int rc;
7003 
7004   if( objc!=4 ){
7005     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD");
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   rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd);
7014   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7015   return TCL_OK;
7016 }
7017 #endif /* SQLITE_USER_AUTHENTICATION */
7018 
7019 #ifdef SQLITE_USER_AUTHENTICATION
7020 /*
7021 ** tclcmd:  sqlite3_user_add DB USERNAME PASSWORD ISADMIN
7022 */
7023 static int SQLITE_TCLAPI test_user_add(
7024   ClientData clientData, /* Unused */
7025   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7026   int objc,              /* Number of arguments */
7027   Tcl_Obj *CONST objv[]  /* Command arguments */
7028 ){
7029   char *zUser = 0;
7030   char *zPasswd = 0;
7031   int nPasswd = 0;
7032   int isAdmin = 0;
7033   sqlite3 *db;
7034   int rc;
7035 
7036   if( objc!=5 ){
7037     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
7038     return TCL_ERROR;
7039   }
7040   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
7041     return TCL_ERROR;
7042   }
7043   zUser = Tcl_GetString(objv[2]);
7044   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
7045   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
7046   rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin);
7047   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7048   return TCL_OK;
7049 }
7050 #endif /* SQLITE_USER_AUTHENTICATION */
7051 
7052 #ifdef SQLITE_USER_AUTHENTICATION
7053 /*
7054 ** tclcmd:  sqlite3_user_change DB USERNAME PASSWORD ISADMIN
7055 */
7056 static int SQLITE_TCLAPI test_user_change(
7057   ClientData clientData, /* Unused */
7058   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7059   int objc,              /* Number of arguments */
7060   Tcl_Obj *CONST objv[]  /* Command arguments */
7061 ){
7062   char *zUser = 0;
7063   char *zPasswd = 0;
7064   int nPasswd = 0;
7065   int isAdmin = 0;
7066   sqlite3 *db;
7067   int rc;
7068 
7069   if( objc!=5 ){
7070     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
7071     return TCL_ERROR;
7072   }
7073   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
7074     return TCL_ERROR;
7075   }
7076   zUser = Tcl_GetString(objv[2]);
7077   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
7078   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
7079   rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin);
7080   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7081   return TCL_OK;
7082 }
7083 #endif /* SQLITE_USER_AUTHENTICATION */
7084 
7085 #ifdef SQLITE_USER_AUTHENTICATION
7086 /*
7087 ** tclcmd:  sqlite3_user_delete DB USERNAME
7088 */
7089 static int SQLITE_TCLAPI test_user_delete(
7090   ClientData clientData, /* Unused */
7091   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7092   int objc,              /* Number of arguments */
7093   Tcl_Obj *CONST objv[]  /* Command arguments */
7094 ){
7095   char *zUser = 0;
7096   sqlite3 *db;
7097   int rc;
7098 
7099   if( objc!=3 ){
7100     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME");
7101     return TCL_ERROR;
7102   }
7103   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
7104     return TCL_ERROR;
7105   }
7106   zUser = Tcl_GetString(objv[2]);
7107   rc = sqlite3_user_delete(db, zUser);
7108   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7109   return TCL_OK;
7110 }
7111 #endif /* SQLITE_USER_AUTHENTICATION */
7112 
7113 /*
7114 ** tclcmd: bad_behavior TYPE
7115 **
7116 ** Do some things that should trigger a valgrind or -fsanitize=undefined
7117 ** warning.  This is used to verify that errors and warnings output by those
7118 ** tools are detected by the test scripts.
7119 **
7120 **       TYPE       BEHAVIOR
7121 **       1          Overflow a signed integer
7122 **       2          Jump based on an uninitialized variable
7123 **       3          Read after free
7124 **       4          Panic
7125 */
7126 static int SQLITE_TCLAPI test_bad_behavior(
7127   ClientData clientData, /* Pointer to an integer containing zero */
7128   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7129   int objc,              /* Number of arguments */
7130   Tcl_Obj *CONST objv[]  /* Command arguments */
7131 ){
7132   int iType;
7133   int xyz;
7134   int i = *(int*)clientData;
7135   int j;
7136   int w[10];
7137   int *a;
7138   if( objc!=2 ){
7139     Tcl_WrongNumArgs(interp, 1, objv, "TYPE");
7140     return TCL_ERROR;
7141   }
7142   if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR;
7143   switch( iType ){
7144     case 1: {
7145       xyz = 0x7fffff00 - i;
7146       xyz += 0x100;
7147       Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz));
7148       break;
7149     }
7150     case 2: {
7151       w[1] = 5;
7152       if( w[i]>0 ) w[1]++;
7153       Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1]));
7154       break;
7155     }
7156     case 3: {
7157       a = malloc( sizeof(int)*10 );
7158       for(j=0; j<10; j++) a[j] = j;
7159       free(a);
7160       Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i]));
7161       break;
7162     }
7163     case 4: {
7164       Tcl_Panic("Deliberate panic");
7165       break;
7166     }
7167   }
7168   return TCL_OK;
7169 }
7170 
7171 /*
7172 ** tclcmd:   register_dbstat_vtab DB
7173 **
7174 ** Cause the dbstat virtual table to be available on the connection DB
7175 */
7176 static int SQLITE_TCLAPI test_register_dbstat_vtab(
7177   void *clientData,
7178   Tcl_Interp *interp,
7179   int objc,
7180   Tcl_Obj *CONST objv[]
7181 ){
7182 #ifdef SQLITE_OMIT_VIRTUALTABLE
7183   Tcl_AppendResult(interp, "dbstat not available because of "
7184                            "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
7185   return TCL_ERROR;
7186 #else
7187   struct SqliteDb { sqlite3 *db; };
7188   char *zDb;
7189   Tcl_CmdInfo cmdInfo;
7190 
7191   if( objc!=2 ){
7192     Tcl_WrongNumArgs(interp, 1, objv, "DB");
7193     return TCL_ERROR;
7194   }
7195 
7196   zDb = Tcl_GetString(objv[1]);
7197   if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
7198     sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
7199     sqlite3DbstatRegister(db);
7200   }
7201   return TCL_OK;
7202 #endif /* SQLITE_OMIT_VIRTUALTABLE */
7203 }
7204 
7205 /*
7206 ** tclcmd:   sqlite3_db_config DB SETTING VALUE
7207 **
7208 ** Invoke sqlite3_db_config() for one of the setting values.
7209 */
7210 static int SQLITE_TCLAPI test_sqlite3_db_config(
7211   void *clientData,
7212   Tcl_Interp *interp,
7213   int objc,
7214   Tcl_Obj *CONST objv[]
7215 ){
7216   static const struct {
7217     const char *zName;
7218     int eVal;
7219   } aSetting[] = {
7220     { "FKEY",            SQLITE_DBCONFIG_ENABLE_FKEY },
7221     { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
7222     { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
7223     { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
7224   };
7225   int i;
7226   int v;
7227   const char *zSetting;
7228   sqlite3 *db;
7229 
7230   if( objc!=4 ){
7231     Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING VALUE");
7232     return TCL_ERROR;
7233   }
7234   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
7235   zSetting = Tcl_GetString(objv[2]);
7236   if( sqlite3_strglob("SQLITE_*", zSetting)==0 ) zSetting += 7;
7237   if( sqlite3_strglob("DBCONFIG_*", zSetting)==0 ) zSetting += 9;
7238   if( sqlite3_strglob("ENABLE_*", zSetting)==0 ) zSetting += 7;
7239   for(i=0; i<ArraySize(aSetting); i++){
7240     if( strcmp(zSetting, aSetting[i].zName)==0 ) break;
7241   }
7242   if( i>=ArraySize(aSetting) ){
7243     Tcl_SetObjResult(interp,
7244       Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
7245     return TCL_ERROR;
7246   }
7247   if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
7248   sqlite3_db_config(db, aSetting[i].eVal, v, &v);
7249   Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
7250   return TCL_OK;
7251 }
7252 
7253 /*
7254 ** Change the name of the main database schema from "main" to "icecube".
7255 */
7256 static int SQLITE_TCLAPI test_dbconfig_maindbname_icecube(
7257   void * clientData,
7258   Tcl_Interp *interp,
7259   int objc,
7260   Tcl_Obj *CONST objv[]
7261 ){
7262   int rc;
7263   sqlite3 *db;
7264   extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
7265   if( objc!=2 ){
7266     Tcl_WrongNumArgs(interp, 1, objv, "DB");
7267     return TCL_ERROR;
7268   }else{
7269     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
7270     rc = sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "icecube");
7271     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
7272     return TCL_OK;
7273   }
7274 }
7275 
7276 /*
7277 ** Register commands with the TCL interpreter.
7278 */
7279 int Sqlitetest1_Init(Tcl_Interp *interp){
7280   extern int sqlite3_search_count;
7281   extern int sqlite3_found_count;
7282   extern int sqlite3_interrupt_count;
7283   extern int sqlite3_open_file_count;
7284   extern int sqlite3_sort_count;
7285   extern int sqlite3_current_time;
7286 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
7287   extern int sqlite3_hostid_num;
7288 #endif
7289   extern int sqlite3_max_blobsize;
7290   extern int SQLITE_TCLAPI sqlite3BtreeSharedCacheReport(void*,
7291                                           Tcl_Interp*,int,Tcl_Obj*CONST*);
7292   static int iZero = 0;
7293   static struct {
7294      char *zName;
7295      Tcl_CmdProc *xProc;
7296   } aCmd[] = {
7297      { "db_enter",                      (Tcl_CmdProc*)db_enter               },
7298      { "db_leave",                      (Tcl_CmdProc*)db_leave               },
7299      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
7300      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
7301      { "sqlite3_mprintf_long",          (Tcl_CmdProc*)sqlite3_mprintf_long   },
7302      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
7303      { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
7304      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
7305      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
7306      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
7307      { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
7308      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
7309      { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
7310      { "sqlite3_snprintf_int",          (Tcl_CmdProc*)test_snprintf_int     },
7311      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
7312      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
7313      { "sqlite3_exec_hex",              (Tcl_CmdProc*)test_exec_hex         },
7314      { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
7315      { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
7316 #ifndef SQLITE_OMIT_GET_TABLE
7317      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
7318 #endif
7319      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
7320      { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
7321      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
7322      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
7323      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
7324      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
7325      { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
7326      { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
7327      { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
7328      { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
7329      { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
7330      { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
7331      { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
7332      { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
7333      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
7334      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
7335      { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
7336      { "printf",                        (Tcl_CmdProc*)test_printf           },
7337      { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
7338      { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
7339   };
7340   static struct {
7341      char *zName;
7342      Tcl_ObjCmdProc *xProc;
7343      void *clientData;
7344   } aObjCmd[] = {
7345      { "sqlite3_db_config",             test_sqlite3_db_config, 0 },
7346      { "bad_behavior",                  test_bad_behavior,  (void*)&iZero },
7347      { "register_dbstat_vtab",          test_register_dbstat_vtab  },
7348      { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
7349      { "intarray_addr",                 test_intarray_addr, 0 },
7350      { "int64array_addr",               test_int64array_addr, 0 },
7351      { "doublearray_addr",              test_doublearray_addr, 0 },
7352      { "textarray_addr",                test_textarray_addr, 0 },
7353      { "sqlite3_bind_int",              test_bind_int,      0 },
7354      { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
7355      { "sqlite3_bind_zeroblob64",       test_bind_zeroblob64, 0 },
7356      { "sqlite3_bind_int64",            test_bind_int64,    0 },
7357      { "sqlite3_bind_double",           test_bind_double,   0 },
7358      { "sqlite3_bind_null",             test_bind_null     ,0 },
7359      { "sqlite3_bind_text",             test_bind_text     ,0 },
7360      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
7361      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
7362      { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
7363      { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
7364      { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
7365      { "sqlite3_clear_bindings",        test_clear_bindings, 0},
7366      { "sqlite3_sleep",                 test_sleep,          0},
7367      { "sqlite3_errcode",               test_errcode       ,0 },
7368      { "sqlite3_extended_errcode",      test_ex_errcode    ,0 },
7369      { "sqlite3_errmsg",                test_errmsg        ,0 },
7370      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
7371      { "sqlite3_open",                  test_open          ,0 },
7372      { "sqlite3_open16",                test_open16        ,0 },
7373      { "sqlite3_open_v2",               test_open_v2       ,0 },
7374      { "sqlite3_complete16",            test_complete16    ,0 },
7375 
7376      { "sqlite3_prepare",               test_prepare       ,0 },
7377      { "sqlite3_prepare16",             test_prepare16     ,0 },
7378      { "sqlite3_prepare_v2",            test_prepare_v2    ,0 },
7379      { "sqlite3_prepare_tkt3134",       test_prepare_tkt3134, 0},
7380      { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
7381      { "sqlite3_finalize",              test_finalize      ,0 },
7382      { "sqlite3_stmt_status",           test_stmt_status   ,0 },
7383      { "sqlite3_reset",                 test_reset         ,0 },
7384      { "sqlite3_expired",               test_expired       ,0 },
7385      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
7386      { "sqlite3_changes",               test_changes       ,0 },
7387      { "sqlite3_step",                  test_step          ,0 },
7388      { "sqlite3_sql",                   test_sql           ,0 },
7389      { "sqlite3_expanded_sql",          test_ex_sql        ,0 },
7390      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
7391      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
7392      { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
7393      { "uses_stmt_journal",             uses_stmt_journal ,0 },
7394 
7395      { "sqlite3_release_memory",        test_release_memory,     0},
7396      { "sqlite3_db_release_memory",     test_db_release_memory,  0},
7397      { "sqlite3_db_cacheflush",         test_db_cacheflush,      0},
7398      { "sqlite3_system_errno",          test_system_errno,       0},
7399      { "sqlite3_db_filename",           test_db_filename,        0},
7400      { "sqlite3_db_readonly",           test_db_readonly,        0},
7401      { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
7402      { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
7403      { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
7404 
7405      { "sqlite3_load_extension",        test_load_extension,     0},
7406      { "sqlite3_enable_load_extension", test_enable_load,        0},
7407      { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
7408      { "sqlite3_limit",                 test_limit,                 0},
7409      { "dbconfig_maindbname_icecube",   test_dbconfig_maindbname_icecube },
7410 
7411      { "save_prng_state",               save_prng_state,    0 },
7412      { "restore_prng_state",            restore_prng_state, 0 },
7413      { "reset_prng_state",              reset_prng_state,   0 },
7414      { "database_never_corrupt",        database_never_corrupt, 0},
7415      { "database_may_be_corrupt",       database_may_be_corrupt, 0},
7416      { "optimization_control",          optimization_control,0},
7417 #if SQLITE_OS_WIN
7418      { "lock_win32_file",               win32_file_lock,    0 },
7419      { "exists_win32_path",             win32_exists_path,  0 },
7420      { "find_win32_file",               win32_find_file,    0 },
7421      { "delete_win32_file",             win32_delete_file,  0 },
7422      { "make_win32_dir",                win32_mkdir,        0 },
7423      { "remove_win32_dir",              win32_rmdir,        0 },
7424 #endif
7425      { "tcl_objproc",                   runAsObjProc,       0 },
7426 
7427      /* sqlite3_column_*() API */
7428      { "sqlite3_column_count",          test_column_count  ,0 },
7429      { "sqlite3_data_count",            test_data_count    ,0 },
7430      { "sqlite3_column_type",           test_column_type   ,0 },
7431      { "sqlite3_column_blob",           test_column_blob   ,0 },
7432      { "sqlite3_column_double",         test_column_double ,0 },
7433      { "sqlite3_column_int64",          test_column_int64  ,0 },
7434      { "sqlite3_column_text",   test_stmt_utf8,  (void*)sqlite3_column_text },
7435      { "sqlite3_column_name",   test_stmt_utf8,  (void*)sqlite3_column_name },
7436      { "sqlite3_column_int",    test_stmt_int,   (void*)sqlite3_column_int  },
7437      { "sqlite3_column_bytes",  test_stmt_int,   (void*)sqlite3_column_bytes},
7438 #ifndef SQLITE_OMIT_DECLTYPE
7439      { "sqlite3_column_decltype",test_stmt_utf8,(void*)sqlite3_column_decltype},
7440 #endif
7441 #ifdef SQLITE_ENABLE_COLUMN_METADATA
7442 { "sqlite3_column_database_name",test_stmt_utf8,(void*)sqlite3_column_database_name},
7443 { "sqlite3_column_table_name",test_stmt_utf8,(void*)sqlite3_column_table_name},
7444 { "sqlite3_column_origin_name",test_stmt_utf8,(void*)sqlite3_column_origin_name},
7445 #endif
7446 
7447 #ifndef SQLITE_OMIT_UTF16
7448      { "sqlite3_column_bytes16", test_stmt_int, (void*)sqlite3_column_bytes16 },
7449      { "sqlite3_column_text16",  test_stmt_utf16, (void*)sqlite3_column_text16},
7450      { "sqlite3_column_name16",  test_stmt_utf16, (void*)sqlite3_column_name16},
7451      { "add_alignment_test_collations", add_alignment_test_collations, 0      },
7452 #ifndef SQLITE_OMIT_DECLTYPE
7453      { "sqlite3_column_decltype16",test_stmt_utf16,(void*)sqlite3_column_decltype16},
7454 #endif
7455 #ifdef SQLITE_ENABLE_COLUMN_METADATA
7456 {"sqlite3_column_database_name16",
7457   test_stmt_utf16, (void*)sqlite3_column_database_name16},
7458 {"sqlite3_column_table_name16", test_stmt_utf16, (void*)sqlite3_column_table_name16},
7459 {"sqlite3_column_origin_name16", test_stmt_utf16, (void*)sqlite3_column_origin_name16},
7460 #endif
7461 #endif
7462      { "sqlite3_create_collation_v2", test_create_collation_v2, 0 },
7463      { "sqlite3_global_recover",     test_global_recover, 0   },
7464      { "working_64bit_int",          working_64bit_int,   0   },
7465      { "vfs_unlink_test",            vfs_unlink_test,     0   },
7466      { "vfs_initfail_test",          vfs_initfail_test,   0   },
7467      { "vfs_unregister_all",         vfs_unregister_all,  0   },
7468      { "vfs_reregister_all",         vfs_reregister_all,  0   },
7469      { "file_control_test",          file_control_test,   0   },
7470      { "file_control_lasterrno_test", file_control_lasterrno_test,  0   },
7471      { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
7472      { "file_control_chunksize_test", file_control_chunksize_test,  0   },
7473      { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
7474 #if SQLITE_OS_WIN
7475      { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
7476      { "file_control_win32_get_handle", file_control_win32_get_handle, 0  },
7477      { "file_control_win32_set_handle", file_control_win32_set_handle, 0  },
7478 #endif
7479      { "file_control_persist_wal",    file_control_persist_wal,     0   },
7480      { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
7481      { "file_control_vfsname",        file_control_vfsname,         0   },
7482      { "file_control_tempfilename",   file_control_tempfilename,    0   },
7483      { "sqlite3_vfs_list",           vfs_list,     0   },
7484      { "sqlite3_create_function_v2", test_create_function_v2, 0 },
7485 
7486      /* Functions from os.h */
7487 #ifndef SQLITE_OMIT_UTF16
7488      { "add_test_collate",        test_collate, 0            },
7489      { "add_test_collate_needed", test_collate_needed, 0     },
7490      { "add_test_function",       test_function, 0           },
7491      { "add_test_utf16bin_collate",    test_utf16bin_collate, 0        },
7492 #endif
7493      { "sqlite3_test_errstr",     test_errstr, 0             },
7494      { "tcl_variable_type",       tcl_variable_type, 0       },
7495 #ifndef SQLITE_OMIT_SHARED_CACHE
7496      { "sqlite3_enable_shared_cache", test_enable_shared, 0  },
7497      { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
7498 #endif
7499      { "sqlite3_libversion_number", test_libversion_number, 0  },
7500      { "sqlite3_table_column_metadata", test_table_column_metadata, 0  },
7501 #ifndef SQLITE_OMIT_INCRBLOB
7502      { "sqlite3_blob_reopen", test_blob_reopen, 0  },
7503 #endif
7504      { "pcache_stats",       test_pcache_stats, 0  },
7505 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
7506      { "sqlite3_unlock_notify", test_unlock_notify, 0  },
7507 #endif
7508      { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
7509      { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
7510      { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0  },
7511      { "test_sqlite3_log",         test_sqlite3_log, 0  },
7512 #ifndef SQLITE_OMIT_EXPLAIN
7513      { "print_explain_query_plan", test_print_eqp, 0  },
7514 #endif
7515      { "sqlite3_test_control", test_test_control },
7516 #if SQLITE_OS_UNIX
7517      { "getrusage", test_getrusage },
7518 #endif
7519      { "load_static_extension", tclLoadStaticExtensionCmd },
7520      { "sorter_test_fakeheap", sorter_test_fakeheap },
7521      { "sorter_test_sort4_helper", sorter_test_sort4_helper },
7522 #ifdef SQLITE_USER_AUTHENTICATION
7523      { "sqlite3_user_authenticate", test_user_authenticate, 0 },
7524      { "sqlite3_user_add",          test_user_add,          0 },
7525      { "sqlite3_user_change",       test_user_change,       0 },
7526      { "sqlite3_user_delete",       test_user_delete,       0 },
7527 #endif
7528 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
7529      { "sqlite3_stmt_scanstatus",       test_stmt_scanstatus,   0 },
7530      { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset,   0 },
7531 #endif
7532 #ifdef SQLITE_ENABLE_SQLLOG
7533      { "sqlite3_config_sqllog",         test_config_sqllog,   0 },
7534 #endif
7535      { "vfs_current_time_int64",           vfsCurrentTimeInt64,   0 },
7536 #ifdef SQLITE_ENABLE_SNAPSHOT
7537      { "sqlite3_snapshot_get", test_snapshot_get, 0 },
7538      { "sqlite3_snapshot_open", test_snapshot_open, 0 },
7539      { "sqlite3_snapshot_free", test_snapshot_free, 0 },
7540      { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
7541 #endif
7542      { "sqlite3_delete_database", test_delete_database, 0 },
7543   };
7544   static int bitmask_size = sizeof(Bitmask)*8;
7545   static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
7546   int i;
7547   extern int sqlite3_sync_count, sqlite3_fullsync_count;
7548   extern int sqlite3_opentemp_count;
7549   extern int sqlite3_like_count;
7550   extern int sqlite3_xferopt_count;
7551   extern int sqlite3_pager_readdb_count;
7552   extern int sqlite3_pager_writedb_count;
7553   extern int sqlite3_pager_writej_count;
7554 #if SQLITE_OS_WIN
7555   extern LONG volatile sqlite3_os_type;
7556 #endif
7557 #ifdef SQLITE_DEBUG
7558   extern int sqlite3WhereTrace;
7559   extern int sqlite3OSTrace;
7560   extern int sqlite3WalTrace;
7561 #endif
7562 #ifdef SQLITE_TEST
7563 #ifdef SQLITE_ENABLE_FTS3
7564   extern int sqlite3_fts3_enable_parentheses;
7565 #endif
7566 #endif
7567 
7568   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
7569     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
7570   }
7571   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
7572     Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
7573         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
7574   }
7575   Tcl_LinkVar(interp, "sqlite_search_count",
7576       (char*)&sqlite3_search_count, TCL_LINK_INT);
7577   Tcl_LinkVar(interp, "sqlite_found_count",
7578       (char*)&sqlite3_found_count, TCL_LINK_INT);
7579   Tcl_LinkVar(interp, "sqlite_sort_count",
7580       (char*)&sqlite3_sort_count, TCL_LINK_INT);
7581   Tcl_LinkVar(interp, "sqlite3_max_blobsize",
7582       (char*)&sqlite3_max_blobsize, TCL_LINK_INT);
7583   Tcl_LinkVar(interp, "sqlite_like_count",
7584       (char*)&sqlite3_like_count, TCL_LINK_INT);
7585   Tcl_LinkVar(interp, "sqlite_interrupt_count",
7586       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
7587   Tcl_LinkVar(interp, "sqlite_open_file_count",
7588       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
7589   Tcl_LinkVar(interp, "sqlite_current_time",
7590       (char*)&sqlite3_current_time, TCL_LINK_INT);
7591 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
7592   Tcl_LinkVar(interp, "sqlite_hostid_num",
7593       (char*)&sqlite3_hostid_num, TCL_LINK_INT);
7594 #endif
7595   Tcl_LinkVar(interp, "sqlite3_xferopt_count",
7596       (char*)&sqlite3_xferopt_count, TCL_LINK_INT);
7597   Tcl_LinkVar(interp, "sqlite3_pager_readdb_count",
7598       (char*)&sqlite3_pager_readdb_count, TCL_LINK_INT);
7599   Tcl_LinkVar(interp, "sqlite3_pager_writedb_count",
7600       (char*)&sqlite3_pager_writedb_count, TCL_LINK_INT);
7601   Tcl_LinkVar(interp, "sqlite3_pager_writej_count",
7602       (char*)&sqlite3_pager_writej_count, TCL_LINK_INT);
7603 #ifndef SQLITE_OMIT_UTF16
7604   Tcl_LinkVar(interp, "unaligned_string_counter",
7605       (char*)&unaligned_string_counter, TCL_LINK_INT);
7606 #endif
7607 #ifndef SQLITE_OMIT_UTF16
7608   Tcl_LinkVar(interp, "sqlite_last_needed_collation",
7609       (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7610 #endif
7611 #if SQLITE_OS_WIN
7612   Tcl_LinkVar(interp, "sqlite_os_type",
7613       (char*)&sqlite3_os_type, TCL_LINK_LONG);
7614 #endif
7615 #ifdef SQLITE_TEST
7616   {
7617     static const char *query_plan = "*** OBSOLETE VARIABLE ***";
7618     Tcl_LinkVar(interp, "sqlite_query_plan",
7619        (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7620   }
7621 #endif
7622 #ifdef SQLITE_DEBUG
7623   Tcl_LinkVar(interp, "sqlite_where_trace",
7624       (char*)&sqlite3WhereTrace, TCL_LINK_INT);
7625   Tcl_LinkVar(interp, "sqlite_os_trace",
7626       (char*)&sqlite3OSTrace, TCL_LINK_INT);
7627 #ifndef SQLITE_OMIT_WAL
7628   Tcl_LinkVar(interp, "sqlite_wal_trace",
7629       (char*)&sqlite3WalTrace, TCL_LINK_INT);
7630 #endif
7631 #endif
7632 #ifndef SQLITE_OMIT_DISKIO
7633   Tcl_LinkVar(interp, "sqlite_opentemp_count",
7634       (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
7635 #endif
7636   Tcl_LinkVar(interp, "sqlite_static_bind_value",
7637       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
7638   Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
7639       (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
7640   Tcl_LinkVar(interp, "sqlite_temp_directory",
7641       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
7642   Tcl_LinkVar(interp, "sqlite_data_directory",
7643       (char*)&sqlite3_data_directory, TCL_LINK_STRING);
7644   Tcl_LinkVar(interp, "bitmask_size",
7645       (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
7646   Tcl_LinkVar(interp, "longdouble_size",
7647       (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
7648   Tcl_LinkVar(interp, "sqlite_sync_count",
7649       (char*)&sqlite3_sync_count, TCL_LINK_INT);
7650   Tcl_LinkVar(interp, "sqlite_fullsync_count",
7651       (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
7652 #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
7653   Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
7654       (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
7655 #endif
7656   return TCL_OK;
7657 }
7658