xref: /sqlite-3.40.0/src/test1.c (revision 52b1dbb5)
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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_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_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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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_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 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 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 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 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 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 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 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 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 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 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 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_next_stmt  DB  STMT
2393 **
2394 ** Return the next statment in sequence after STMT.
2395 */
2396 static int test_next_stmt(
2397   void * clientData,
2398   Tcl_Interp *interp,
2399   int objc,
2400   Tcl_Obj *CONST objv[]
2401 ){
2402   sqlite3_stmt *pStmt;
2403   sqlite3 *db = 0;
2404   char zBuf[50];
2405 
2406   if( objc!=3 ){
2407     Tcl_AppendResult(interp, "wrong # args: should be \"",
2408         Tcl_GetStringFromObj(objv[0], 0), " DB STMT", 0);
2409     return TCL_ERROR;
2410   }
2411 
2412   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2413   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt) ) return TCL_ERROR;
2414   pStmt = sqlite3_next_stmt(db, pStmt);
2415   if( pStmt ){
2416     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
2417     Tcl_AppendResult(interp, zBuf, 0);
2418   }
2419   return TCL_OK;
2420 }
2421 
2422 /*
2423 ** Usage:  sqlite3_stmt_readonly  STMT
2424 **
2425 ** Return true if STMT is a NULL pointer or a pointer to a statement
2426 ** that is guaranteed to leave the database unmodified.
2427 */
2428 static int test_stmt_readonly(
2429   void * clientData,
2430   Tcl_Interp *interp,
2431   int objc,
2432   Tcl_Obj *CONST objv[]
2433 ){
2434   sqlite3_stmt *pStmt;
2435   int rc;
2436 
2437   if( objc!=2 ){
2438     Tcl_AppendResult(interp, "wrong # args: should be \"",
2439         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2440     return TCL_ERROR;
2441   }
2442 
2443   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2444   rc = sqlite3_stmt_readonly(pStmt);
2445   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
2446   return TCL_OK;
2447 }
2448 
2449 /*
2450 ** Usage:  sqlite3_stmt_busy  STMT
2451 **
2452 ** Return true if STMT is a non-NULL pointer to a statement
2453 ** that has been stepped but not to completion.
2454 */
2455 static int test_stmt_busy(
2456   void * clientData,
2457   Tcl_Interp *interp,
2458   int objc,
2459   Tcl_Obj *CONST objv[]
2460 ){
2461   sqlite3_stmt *pStmt;
2462   int rc;
2463 
2464   if( objc!=2 ){
2465     Tcl_AppendResult(interp, "wrong # args: should be \"",
2466         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2467     return TCL_ERROR;
2468   }
2469 
2470   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2471   rc = sqlite3_stmt_busy(pStmt);
2472   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
2473   return TCL_OK;
2474 }
2475 
2476 /*
2477 ** Usage:  uses_stmt_journal  STMT
2478 **
2479 ** Return true if STMT uses a statement journal.
2480 */
2481 static int uses_stmt_journal(
2482   void * clientData,
2483   Tcl_Interp *interp,
2484   int objc,
2485   Tcl_Obj *CONST objv[]
2486 ){
2487   sqlite3_stmt *pStmt;
2488 
2489   if( objc!=2 ){
2490     Tcl_AppendResult(interp, "wrong # args: should be \"",
2491         Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
2492     return TCL_ERROR;
2493   }
2494 
2495   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2496   sqlite3_stmt_readonly(pStmt);
2497   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(((Vdbe *)pStmt)->usesStmtJournal));
2498   return TCL_OK;
2499 }
2500 
2501 
2502 /*
2503 ** Usage:  sqlite3_reset  STMT
2504 **
2505 ** Reset a statement handle.
2506 */
2507 static int test_reset(
2508   void * clientData,
2509   Tcl_Interp *interp,
2510   int objc,
2511   Tcl_Obj *CONST objv[]
2512 ){
2513   sqlite3_stmt *pStmt;
2514   int rc;
2515 
2516   if( objc!=2 ){
2517     Tcl_AppendResult(interp, "wrong # args: should be \"",
2518         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
2519     return TCL_ERROR;
2520   }
2521 
2522   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2523 
2524   rc = sqlite3_reset(pStmt);
2525   if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){
2526     return TCL_ERROR;
2527   }
2528   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
2529 /*
2530   if( rc ){
2531     return TCL_ERROR;
2532   }
2533 */
2534   return TCL_OK;
2535 }
2536 
2537 /*
2538 ** Usage:  sqlite3_expired STMT
2539 **
2540 ** Return TRUE if a recompilation of the statement is recommended.
2541 */
2542 static int test_expired(
2543   void * clientData,
2544   Tcl_Interp *interp,
2545   int objc,
2546   Tcl_Obj *CONST objv[]
2547 ){
2548 #ifndef SQLITE_OMIT_DEPRECATED
2549   sqlite3_stmt *pStmt;
2550   if( objc!=2 ){
2551     Tcl_AppendResult(interp, "wrong # args: should be \"",
2552         Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0);
2553     return TCL_ERROR;
2554   }
2555   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
2556   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt)));
2557 #endif
2558   return TCL_OK;
2559 }
2560 
2561 /*
2562 ** Usage:  sqlite3_transfer_bindings FROMSTMT TOSTMT
2563 **
2564 ** Transfer all bindings from FROMSTMT over to TOSTMT
2565 */
2566 static int test_transfer_bind(
2567   void * clientData,
2568   Tcl_Interp *interp,
2569   int objc,
2570   Tcl_Obj *CONST objv[]
2571 ){
2572 #ifndef SQLITE_OMIT_DEPRECATED
2573   sqlite3_stmt *pStmt1, *pStmt2;
2574   if( objc!=3 ){
2575     Tcl_AppendResult(interp, "wrong # args: should be \"",
2576         Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0);
2577     return TCL_ERROR;
2578   }
2579   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR;
2580   if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR;
2581   Tcl_SetObjResult(interp,
2582      Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2)));
2583 #endif
2584   return TCL_OK;
2585 }
2586 
2587 /*
2588 ** Usage:  sqlite3_changes DB
2589 **
2590 ** Return the number of changes made to the database by the last SQL
2591 ** execution.
2592 */
2593 static int test_changes(
2594   void * clientData,
2595   Tcl_Interp *interp,
2596   int objc,
2597   Tcl_Obj *CONST objv[]
2598 ){
2599   sqlite3 *db;
2600   if( objc!=2 ){
2601     Tcl_AppendResult(interp, "wrong # args: should be \"",
2602        Tcl_GetString(objv[0]), " DB", 0);
2603     return TCL_ERROR;
2604   }
2605   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2606   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db)));
2607   return TCL_OK;
2608 }
2609 
2610 /*
2611 ** This is the "static_bind_value" that variables are bound to when
2612 ** the FLAG option of sqlite3_bind is "static"
2613 */
2614 static char *sqlite_static_bind_value = 0;
2615 static int sqlite_static_bind_nbyte = 0;
2616 
2617 /*
2618 ** Usage:  sqlite3_bind  VM  IDX  VALUE  FLAGS
2619 **
2620 ** Sets the value of the IDX-th occurrence of "?" in the original SQL
2621 ** string.  VALUE is the new value.  If FLAGS=="null" then VALUE is
2622 ** ignored and the value is set to NULL.  If FLAGS=="static" then
2623 ** the value is set to the value of a static variable named
2624 ** "sqlite_static_bind_value".  If FLAGS=="normal" then a copy
2625 ** of the VALUE is made.  If FLAGS=="blob10" then a VALUE is ignored
2626 ** an a 10-byte blob "abc\000xyz\000pq" is inserted.
2627 */
2628 static int test_bind(
2629   void *NotUsed,
2630   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2631   int argc,              /* Number of arguments */
2632   char **argv            /* Text of each argument */
2633 ){
2634   sqlite3_stmt *pStmt;
2635   int rc;
2636   int idx;
2637   if( argc!=5 ){
2638     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2639        " VM IDX VALUE (null|static|normal)\"", 0);
2640     return TCL_ERROR;
2641   }
2642   if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR;
2643   if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
2644   if( strcmp(argv[4],"null")==0 ){
2645     rc = sqlite3_bind_null(pStmt, idx);
2646   }else if( strcmp(argv[4],"static")==0 ){
2647     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0);
2648   }else if( strcmp(argv[4],"static-nbytes")==0 ){
2649     rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value,
2650                                        sqlite_static_bind_nbyte, 0);
2651   }else if( strcmp(argv[4],"normal")==0 ){
2652     rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT);
2653   }else if( strcmp(argv[4],"blob10")==0 ){
2654     rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC);
2655   }else{
2656     Tcl_AppendResult(interp, "4th argument should be "
2657         "\"null\" or \"static\" or \"normal\"", 0);
2658     return TCL_ERROR;
2659   }
2660   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
2661   if( rc ){
2662     char zBuf[50];
2663     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
2664     Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0);
2665     return TCL_ERROR;
2666   }
2667   return TCL_OK;
2668 }
2669 
2670 #ifndef SQLITE_OMIT_UTF16
2671 /*
2672 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
2673 **
2674 ** This function is used to test that SQLite selects the correct collation
2675 ** sequence callback when multiple versions (for different text encodings)
2676 ** are available.
2677 **
2678 ** Calling this routine registers the collation sequence "test_collate"
2679 ** with database handle <db>. The second argument must be a list of three
2680 ** boolean values. If the first is true, then a version of test_collate is
2681 ** registered for UTF-8, if the second is true, a version is registered for
2682 ** UTF-16le, if the third is true, a UTF-16be version is available.
2683 ** Previous versions of test_collate are deleted.
2684 **
2685 ** The collation sequence test_collate is implemented by calling the
2686 ** following TCL script:
2687 **
2688 **   "test_collate <enc> <lhs> <rhs>"
2689 **
2690 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
2691 ** The <enc> parameter is the encoding of the collation function that
2692 ** SQLite selected to call. The TCL test script implements the
2693 ** "test_collate" proc.
2694 **
2695 ** Note that this will only work with one interpreter at a time, as the
2696 ** interp pointer to use when evaluating the TCL script is stored in
2697 ** pTestCollateInterp.
2698 */
2699 static Tcl_Interp* pTestCollateInterp;
2700 static int test_collate_func(
2701   void *pCtx,
2702   int nA, const void *zA,
2703   int nB, const void *zB
2704 ){
2705   Tcl_Interp *i = pTestCollateInterp;
2706   int encin = SQLITE_PTR_TO_INT(pCtx);
2707   int res;
2708   int n;
2709 
2710   sqlite3_value *pVal;
2711   Tcl_Obj *pX;
2712 
2713   pX = Tcl_NewStringObj("test_collate", -1);
2714   Tcl_IncrRefCount(pX);
2715 
2716   switch( encin ){
2717     case SQLITE_UTF8:
2718       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1));
2719       break;
2720     case SQLITE_UTF16LE:
2721       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1));
2722       break;
2723     case SQLITE_UTF16BE:
2724       Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1));
2725       break;
2726     default:
2727       assert(0);
2728   }
2729 
2730   sqlite3BeginBenignMalloc();
2731   pVal = sqlite3ValueNew(0);
2732   if( pVal ){
2733     sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC);
2734     n = sqlite3_value_bytes(pVal);
2735     Tcl_ListObjAppendElement(i,pX,
2736         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
2737     sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC);
2738     n = sqlite3_value_bytes(pVal);
2739     Tcl_ListObjAppendElement(i,pX,
2740         Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n));
2741     sqlite3ValueFree(pVal);
2742   }
2743   sqlite3EndBenignMalloc();
2744 
2745   Tcl_EvalObjEx(i, pX, 0);
2746   Tcl_DecrRefCount(pX);
2747   Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res);
2748   return res;
2749 }
2750 static int test_collate(
2751   void * clientData,
2752   Tcl_Interp *interp,
2753   int objc,
2754   Tcl_Obj *CONST objv[]
2755 ){
2756   sqlite3 *db;
2757   int val;
2758   sqlite3_value *pVal;
2759   int rc;
2760 
2761   if( objc!=5 ) goto bad_args;
2762   pTestCollateInterp = interp;
2763   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2764 
2765   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
2766   rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8,
2767           (void *)SQLITE_UTF8, val?test_collate_func:0);
2768   if( rc==SQLITE_OK ){
2769     const void *zUtf16;
2770     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
2771     rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE,
2772             (void *)SQLITE_UTF16LE, val?test_collate_func:0);
2773     if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
2774 
2775 #if 0
2776     if( sqlite3_iMallocFail>0 ){
2777       sqlite3_iMallocFail++;
2778     }
2779 #endif
2780     sqlite3_mutex_enter(db->mutex);
2781     pVal = sqlite3ValueNew(db);
2782     sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
2783     zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
2784     if( db->mallocFailed ){
2785       rc = SQLITE_NOMEM;
2786     }else{
2787       rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE,
2788           (void *)SQLITE_UTF16BE, val?test_collate_func:0);
2789     }
2790     sqlite3ValueFree(pVal);
2791     sqlite3_mutex_leave(db->mutex);
2792   }
2793   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2794 
2795   if( rc!=SQLITE_OK ){
2796     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
2797     return TCL_ERROR;
2798   }
2799   return TCL_OK;
2800 
2801 bad_args:
2802   Tcl_AppendResult(interp, "wrong # args: should be \"",
2803       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
2804   return TCL_ERROR;
2805 }
2806 
2807 /*
2808 ** Usage: add_test_utf16bin_collate <db ptr>
2809 **
2810 ** Add a utf-16 collation sequence named "utf16bin" to the database
2811 ** handle. This collation sequence compares arguments in the same way as the
2812 ** built-in collation "binary".
2813 */
2814 static int test_utf16bin_collate_func(
2815   void *pCtx,
2816   int nA, const void *zA,
2817   int nB, const void *zB
2818 ){
2819   int nCmp = (nA>nB ? nB : nA);
2820   int res = memcmp(zA, zB, nCmp);
2821   if( res==0 ) res = nA - nB;
2822   return res;
2823 }
2824 static int test_utf16bin_collate(
2825   void * clientData,
2826   Tcl_Interp *interp,
2827   int objc,
2828   Tcl_Obj *CONST objv[]
2829 ){
2830   sqlite3 *db;
2831   int rc;
2832 
2833   if( objc!=2 ) goto bad_args;
2834   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2835 
2836   rc = sqlite3_create_collation(db, "utf16bin", SQLITE_UTF16, 0,
2837       test_utf16bin_collate_func
2838   );
2839   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2840   return TCL_OK;
2841 
2842 bad_args:
2843   Tcl_WrongNumArgs(interp, 1, objv, "DB");
2844   return TCL_ERROR;
2845 }
2846 
2847 /*
2848 ** When the collation needed callback is invoked, record the name of
2849 ** the requested collating function here.  The recorded name is linked
2850 ** to a TCL variable and used to make sure that the requested collation
2851 ** name is correct.
2852 */
2853 static char zNeededCollation[200];
2854 static char *pzNeededCollation = zNeededCollation;
2855 
2856 
2857 /*
2858 ** Called when a collating sequence is needed.  Registered using
2859 ** sqlite3_collation_needed16().
2860 */
2861 static void test_collate_needed_cb(
2862   void *pCtx,
2863   sqlite3 *db,
2864   int eTextRep,
2865   const void *pName
2866 ){
2867   int enc = ENC(db);
2868   int i;
2869   char *z;
2870   for(z = (char*)pName, i=0; *z || z[1]; z++){
2871     if( *z ) zNeededCollation[i++] = *z;
2872   }
2873   zNeededCollation[i] = 0;
2874   sqlite3_create_collation(
2875       db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func);
2876 }
2877 
2878 /*
2879 ** Usage: add_test_collate_needed DB
2880 */
2881 static int test_collate_needed(
2882   void * clientData,
2883   Tcl_Interp *interp,
2884   int objc,
2885   Tcl_Obj *CONST objv[]
2886 ){
2887   sqlite3 *db;
2888   int rc;
2889 
2890   if( objc!=2 ) goto bad_args;
2891   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2892   rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
2893   zNeededCollation[0] = 0;
2894   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
2895   return TCL_OK;
2896 
2897 bad_args:
2898   Tcl_WrongNumArgs(interp, 1, objv, "DB");
2899   return TCL_ERROR;
2900 }
2901 
2902 /*
2903 ** tclcmd:   add_alignment_test_collations  DB
2904 **
2905 ** Add two new collating sequences to the database DB
2906 **
2907 **     utf16_aligned
2908 **     utf16_unaligned
2909 **
2910 ** Both collating sequences use the same sort order as BINARY.
2911 ** The only difference is that the utf16_aligned collating
2912 ** sequence is declared with the SQLITE_UTF16_ALIGNED flag.
2913 ** Both collating functions increment the unaligned utf16 counter
2914 ** whenever they see a string that begins on an odd byte boundary.
2915 */
2916 static int unaligned_string_counter = 0;
2917 static int alignmentCollFunc(
2918   void *NotUsed,
2919   int nKey1, const void *pKey1,
2920   int nKey2, const void *pKey2
2921 ){
2922   int rc, n;
2923   n = nKey1<nKey2 ? nKey1 : nKey2;
2924   if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++;
2925   if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++;
2926   rc = memcmp(pKey1, pKey2, n);
2927   if( rc==0 ){
2928     rc = nKey1 - nKey2;
2929   }
2930   return rc;
2931 }
2932 static int add_alignment_test_collations(
2933   void * clientData,
2934   Tcl_Interp *interp,
2935   int objc,
2936   Tcl_Obj *CONST objv[]
2937 ){
2938   sqlite3 *db;
2939   if( objc>=2 ){
2940     if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
2941     sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16,
2942         0, alignmentCollFunc);
2943     sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16_ALIGNED,
2944         0, alignmentCollFunc);
2945   }
2946   return SQLITE_OK;
2947 }
2948 #endif /* !defined(SQLITE_OMIT_UTF16) */
2949 
2950 /*
2951 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
2952 **
2953 ** This function is used to test that SQLite selects the correct user
2954 ** function callback when multiple versions (for different text encodings)
2955 ** are available.
2956 **
2957 ** Calling this routine registers up to three versions of the user function
2958 ** "test_function" with database handle <db>.  If the second argument is
2959 ** true, then a version of test_function is registered for UTF-8, if the
2960 ** third is true, a version is registered for UTF-16le, if the fourth is
2961 ** true, a UTF-16be version is available.  Previous versions of
2962 ** test_function are deleted.
2963 **
2964 ** The user function is implemented by calling the following TCL script:
2965 **
2966 **   "test_function <enc> <arg>"
2967 **
2968 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
2969 ** single argument passed to the SQL function. The value returned by
2970 ** the TCL script is used as the return value of the SQL function. It
2971 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
2972 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
2973 ** prefers UTF-16BE.
2974 */
2975 #ifndef SQLITE_OMIT_UTF16
2976 static void test_function_utf8(
2977   sqlite3_context *pCtx,
2978   int nArg,
2979   sqlite3_value **argv
2980 ){
2981   Tcl_Interp *interp;
2982   Tcl_Obj *pX;
2983   sqlite3_value *pVal;
2984   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
2985   pX = Tcl_NewStringObj("test_function", -1);
2986   Tcl_IncrRefCount(pX);
2987   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1));
2988   Tcl_ListObjAppendElement(interp, pX,
2989       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
2990   Tcl_EvalObjEx(interp, pX, 0);
2991   Tcl_DecrRefCount(pX);
2992   sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT);
2993   pVal = sqlite3ValueNew(0);
2994   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
2995       SQLITE_UTF8, SQLITE_STATIC);
2996   sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal),
2997       -1, SQLITE_TRANSIENT);
2998   sqlite3ValueFree(pVal);
2999 }
3000 static void test_function_utf16le(
3001   sqlite3_context *pCtx,
3002   int nArg,
3003   sqlite3_value **argv
3004 ){
3005   Tcl_Interp *interp;
3006   Tcl_Obj *pX;
3007   sqlite3_value *pVal;
3008   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
3009   pX = Tcl_NewStringObj("test_function", -1);
3010   Tcl_IncrRefCount(pX);
3011   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1));
3012   Tcl_ListObjAppendElement(interp, pX,
3013       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
3014   Tcl_EvalObjEx(interp, pX, 0);
3015   Tcl_DecrRefCount(pX);
3016   pVal = sqlite3ValueNew(0);
3017   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
3018       SQLITE_UTF8, SQLITE_STATIC);
3019   sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT);
3020   sqlite3ValueFree(pVal);
3021 }
3022 static void test_function_utf16be(
3023   sqlite3_context *pCtx,
3024   int nArg,
3025   sqlite3_value **argv
3026 ){
3027   Tcl_Interp *interp;
3028   Tcl_Obj *pX;
3029   sqlite3_value *pVal;
3030   interp = (Tcl_Interp *)sqlite3_user_data(pCtx);
3031   pX = Tcl_NewStringObj("test_function", -1);
3032   Tcl_IncrRefCount(pX);
3033   Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1));
3034   Tcl_ListObjAppendElement(interp, pX,
3035       Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1));
3036   Tcl_EvalObjEx(interp, pX, 0);
3037   Tcl_DecrRefCount(pX);
3038   pVal = sqlite3ValueNew(0);
3039   sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp),
3040       SQLITE_UTF8, SQLITE_STATIC);
3041   sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal),
3042       -1, SQLITE_TRANSIENT);
3043   sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal),
3044       -1, SQLITE_TRANSIENT);
3045   sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal),
3046       -1, SQLITE_TRANSIENT);
3047   sqlite3ValueFree(pVal);
3048 }
3049 #endif /* SQLITE_OMIT_UTF16 */
3050 static int test_function(
3051   void * clientData,
3052   Tcl_Interp *interp,
3053   int objc,
3054   Tcl_Obj *CONST objv[]
3055 ){
3056 #ifndef SQLITE_OMIT_UTF16
3057   sqlite3 *db;
3058   int val;
3059 
3060   if( objc!=5 ) goto bad_args;
3061   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3062 
3063   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
3064   if( val ){
3065     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8,
3066         interp, test_function_utf8, 0, 0);
3067   }
3068   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
3069   if( val ){
3070     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE,
3071         interp, test_function_utf16le, 0, 0);
3072   }
3073   if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;
3074   if( val ){
3075     sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE,
3076         interp, test_function_utf16be, 0, 0);
3077   }
3078 
3079   return TCL_OK;
3080 bad_args:
3081   Tcl_AppendResult(interp, "wrong # args: should be \"",
3082       Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
3083 #endif /* SQLITE_OMIT_UTF16 */
3084   return TCL_ERROR;
3085 }
3086 
3087 /*
3088 ** Usage:         sqlite3_test_errstr <err code>
3089 **
3090 ** Test that the english language string equivalents for sqlite error codes
3091 ** are sane. The parameter is an integer representing an sqlite error code.
3092 ** The result is a list of two elements, the string representation of the
3093 ** error code and the english language explanation.
3094 */
3095 static int test_errstr(
3096   void * clientData,
3097   Tcl_Interp *interp,
3098   int objc,
3099   Tcl_Obj *CONST objv[]
3100 ){
3101   char *zCode;
3102   int i;
3103   if( objc!=1 ){
3104     Tcl_WrongNumArgs(interp, 1, objv, "<error code>");
3105   }
3106 
3107   zCode = Tcl_GetString(objv[1]);
3108   for(i=0; i<200; i++){
3109     if( 0==strcmp(t1ErrorName(i), zCode) ) break;
3110   }
3111   Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
3112   return TCL_OK;
3113 }
3114 
3115 /*
3116 ** Usage:    breakpoint
3117 **
3118 ** This routine exists for one purpose - to provide a place to put a
3119 ** breakpoint with GDB that can be triggered using TCL code.  The use
3120 ** for this is when a particular test fails on (say) the 1485th iteration.
3121 ** In the TCL test script, we can add code like this:
3122 **
3123 **     if {$i==1485} breakpoint
3124 **
3125 ** Then run testfixture in the debugger and wait for the breakpoint to
3126 ** fire.  Then additional breakpoints can be set to trace down the bug.
3127 */
3128 static int test_breakpoint(
3129   void *NotUsed,
3130   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
3131   int argc,              /* Number of arguments */
3132   char **argv            /* Text of each argument */
3133 ){
3134   return TCL_OK;         /* Do nothing */
3135 }
3136 
3137 /*
3138 ** Usage:   sqlite3_bind_zeroblob  STMT IDX N
3139 **
3140 ** Test the sqlite3_bind_zeroblob interface.  STMT is a prepared statement.
3141 ** IDX is the index of a wildcard in the prepared statement.  This command
3142 ** binds a N-byte zero-filled BLOB to the wildcard.
3143 */
3144 static int test_bind_zeroblob(
3145   void * clientData,
3146   Tcl_Interp *interp,
3147   int objc,
3148   Tcl_Obj *CONST objv[]
3149 ){
3150   sqlite3_stmt *pStmt;
3151   int idx;
3152   int n;
3153   int rc;
3154 
3155   if( objc!=4 ){
3156     Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
3157     return TCL_ERROR;
3158   }
3159 
3160   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3161   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3162   if( Tcl_GetIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;
3163 
3164   rc = sqlite3_bind_zeroblob(pStmt, idx, n);
3165   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3166   if( rc!=SQLITE_OK ){
3167     return TCL_ERROR;
3168   }
3169 
3170   return TCL_OK;
3171 }
3172 
3173 /*
3174 ** Usage:   sqlite3_bind_zeroblob64  STMT IDX N
3175 **
3176 ** Test the sqlite3_bind_zeroblob64 interface.  STMT is a prepared statement.
3177 ** IDX is the index of a wildcard in the prepared statement.  This command
3178 ** binds a N-byte zero-filled BLOB to the wildcard.
3179 */
3180 static int test_bind_zeroblob64(
3181   void * clientData,
3182   Tcl_Interp *interp,
3183   int objc,
3184   Tcl_Obj *CONST objv[]
3185 ){
3186   sqlite3_stmt *pStmt;
3187   int idx;
3188   Tcl_WideInt n;
3189   int rc;
3190 
3191   if( objc!=4 ){
3192     Tcl_WrongNumArgs(interp, 1, objv, "STMT IDX N");
3193     return TCL_ERROR;
3194   }
3195 
3196   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3197   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3198   if( Tcl_GetWideIntFromObj(interp, objv[3], &n) ) return TCL_ERROR;
3199 
3200   rc = sqlite3_bind_zeroblob64(pStmt, idx, n);
3201   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3202   if( rc!=SQLITE_OK ){
3203     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
3204     return TCL_ERROR;
3205   }
3206 
3207   return TCL_OK;
3208 }
3209 
3210 /*
3211 ** Usage:   sqlite3_bind_int  STMT N VALUE
3212 **
3213 ** Test the sqlite3_bind_int interface.  STMT is a prepared statement.
3214 ** N is the index of a wildcard in the prepared statement.  This command
3215 ** binds a 32-bit integer VALUE to that wildcard.
3216 */
3217 static int test_bind_int(
3218   void * clientData,
3219   Tcl_Interp *interp,
3220   int objc,
3221   Tcl_Obj *CONST objv[]
3222 ){
3223   sqlite3_stmt *pStmt;
3224   int idx;
3225   int value;
3226   int rc;
3227 
3228   if( objc!=4 ){
3229     Tcl_AppendResult(interp, "wrong # args: should be \"",
3230         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3231     return TCL_ERROR;
3232   }
3233 
3234   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3235   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3236   if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
3237 
3238   rc = sqlite3_bind_int(pStmt, idx, value);
3239   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3240   if( rc!=SQLITE_OK ){
3241     return TCL_ERROR;
3242   }
3243 
3244   return TCL_OK;
3245 }
3246 
3247 
3248 /*
3249 ** Usage:   intarray_addr  INT  ...
3250 **
3251 ** Return the address of a C-language array of 32-bit integers.
3252 **
3253 ** Space to hold the array is obtained from malloc().  Call this procedure once
3254 ** with no arguments in order to release memory.  Each call to this procedure
3255 ** overwrites the previous array.
3256 */
3257 static int test_intarray_addr(
3258   void * clientData,
3259   Tcl_Interp *interp,
3260   int objc,
3261   Tcl_Obj *CONST objv[]
3262 ){
3263   int i;
3264   static int *p = 0;
3265 
3266   sqlite3_free(p);
3267   p = 0;
3268   if( objc>1 ){
3269     p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
3270     if( p==0 ) return TCL_ERROR;
3271     for(i=0; i<objc-1; i++){
3272       if( Tcl_GetIntFromObj(interp, objv[1+i], &p[i]) ){
3273         sqlite3_free(p);
3274         p = 0;
3275         return TCL_ERROR;
3276       }
3277     }
3278   }
3279   Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
3280   return TCL_OK;
3281 }
3282 /*
3283 ** Usage:   intarray_addr  INT  ...
3284 **
3285 ** Return the address of a C-language array of 32-bit integers.
3286 **
3287 ** Space to hold the array is obtained from malloc().  Call this procedure once
3288 ** with no arguments in order to release memory.  Each call to this procedure
3289 ** overwrites the previous array.
3290 */
3291 static int test_int64array_addr(
3292   void * clientData,
3293   Tcl_Interp *interp,
3294   int objc,
3295   Tcl_Obj *CONST objv[]
3296 ){
3297   int i;
3298   static sqlite3_int64 *p = 0;
3299 
3300   sqlite3_free(p);
3301   p = 0;
3302   if( objc>1 ){
3303     p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
3304     if( p==0 ) return TCL_ERROR;
3305     for(i=0; i<objc-1; i++){
3306       Tcl_WideInt v;
3307       if( Tcl_GetWideIntFromObj(interp, objv[1+i], &v) ){
3308         sqlite3_free(p);
3309         p = 0;
3310         return TCL_ERROR;
3311       }
3312       p[i] = v;
3313     }
3314   }
3315   Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
3316   return TCL_OK;
3317 }
3318 /*
3319 ** Usage:   doublearray_addr  INT  ...
3320 **
3321 ** Return the address of a C-language array of doubles.
3322 **
3323 ** Space to hold the array is obtained from malloc().  Call this procedure once
3324 ** with no arguments in order to release memory.  Each call to this procedure
3325 ** overwrites the previous array.
3326 */
3327 static int test_doublearray_addr(
3328   void * clientData,
3329   Tcl_Interp *interp,
3330   int objc,
3331   Tcl_Obj *CONST objv[]
3332 ){
3333   int i;
3334   static double *p = 0;
3335 
3336   sqlite3_free(p);
3337   p = 0;
3338   if( objc>1 ){
3339     p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
3340     if( p==0 ) return TCL_ERROR;
3341     for(i=0; i<objc-1; i++){
3342       if( Tcl_GetDoubleFromObj(interp, objv[1+i], &p[i]) ){
3343         sqlite3_free(p);
3344         p = 0;
3345         return TCL_ERROR;
3346       }
3347     }
3348   }
3349   Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
3350   return TCL_OK;
3351 }
3352 /*
3353 ** Usage:   textarray_addr  TEXT ...
3354 **
3355 ** Return the address of a C-language array of strings.
3356 **
3357 ** Space to hold the array is obtained from malloc().  Call this procedure once
3358 ** with no arguments in order to release memory.  Each call to this procedure
3359 ** overwrites the previous array.
3360 */
3361 static int test_textarray_addr(
3362   void * clientData,
3363   Tcl_Interp *interp,
3364   int objc,
3365   Tcl_Obj *CONST objv[]
3366 ){
3367   int i;
3368   static int n = 0;
3369   static char **p = 0;
3370 
3371   for(i=0; i<n; i++) sqlite3_free(p[i]);
3372   sqlite3_free(p);
3373   p = 0;
3374   if( objc>1 ){
3375     p = sqlite3_malloc( sizeof(p[0])*(objc-1) );
3376     if( p==0 ) return TCL_ERROR;
3377     for(i=0; i<objc-1; i++){
3378       p[i] = sqlite3_mprintf("%s", Tcl_GetString(objv[1+i]));
3379     }
3380   }
3381   n = objc-1;
3382   Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p));
3383   return TCL_OK;
3384 }
3385 
3386 
3387 /*
3388 ** Usage:   sqlite3_bind_int64  STMT N VALUE
3389 **
3390 ** Test the sqlite3_bind_int64 interface.  STMT is a prepared statement.
3391 ** N is the index of a wildcard in the prepared statement.  This command
3392 ** binds a 64-bit integer VALUE to that wildcard.
3393 */
3394 static int test_bind_int64(
3395   void * clientData,
3396   Tcl_Interp *interp,
3397   int objc,
3398   Tcl_Obj *CONST objv[]
3399 ){
3400   sqlite3_stmt *pStmt;
3401   int idx;
3402   Tcl_WideInt value;
3403   int rc;
3404 
3405   if( objc!=4 ){
3406     Tcl_AppendResult(interp, "wrong # args: should be \"",
3407         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3408     return TCL_ERROR;
3409   }
3410 
3411   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3412   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3413   if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR;
3414 
3415   rc = sqlite3_bind_int64(pStmt, idx, value);
3416   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3417   if( rc!=SQLITE_OK ){
3418     return TCL_ERROR;
3419   }
3420 
3421   return TCL_OK;
3422 }
3423 
3424 
3425 /*
3426 ** Usage:   sqlite3_bind_double  STMT N VALUE
3427 **
3428 ** Test the sqlite3_bind_double interface.  STMT is a prepared statement.
3429 ** N is the index of a wildcard in the prepared statement.  This command
3430 ** binds a 64-bit integer VALUE to that wildcard.
3431 */
3432 static int test_bind_double(
3433   void * clientData,
3434   Tcl_Interp *interp,
3435   int objc,
3436   Tcl_Obj *CONST objv[]
3437 ){
3438   sqlite3_stmt *pStmt;
3439   int idx;
3440   double value = 0;
3441   int rc;
3442   const char *zVal;
3443   int i;
3444   static const struct {
3445     const char *zName;     /* Name of the special floating point value */
3446     unsigned int iUpper;   /* Upper 32 bits */
3447     unsigned int iLower;   /* Lower 32 bits */
3448   } aSpecialFp[] = {
3449     {  "NaN",      0x7fffffff, 0xffffffff },
3450     {  "SNaN",     0x7ff7ffff, 0xffffffff },
3451     {  "-NaN",     0xffffffff, 0xffffffff },
3452     {  "-SNaN",    0xfff7ffff, 0xffffffff },
3453     {  "+Inf",     0x7ff00000, 0x00000000 },
3454     {  "-Inf",     0xfff00000, 0x00000000 },
3455     {  "Epsilon",  0x00000000, 0x00000001 },
3456     {  "-Epsilon", 0x80000000, 0x00000001 },
3457     {  "NaN0",     0x7ff80000, 0x00000000 },
3458     {  "-NaN0",    0xfff80000, 0x00000000 },
3459   };
3460 
3461   if( objc!=4 ){
3462     Tcl_AppendResult(interp, "wrong # args: should be \"",
3463         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0);
3464     return TCL_ERROR;
3465   }
3466 
3467   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3468   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3469 
3470   /* Intercept the string "NaN" and generate a NaN value for it.
3471   ** All other strings are passed through to Tcl_GetDoubleFromObj().
3472   ** Tcl_GetDoubleFromObj() should understand "NaN" but some versions
3473   ** contain a bug.
3474   */
3475   zVal = Tcl_GetString(objv[3]);
3476   for(i=0; i<sizeof(aSpecialFp)/sizeof(aSpecialFp[0]); i++){
3477     if( strcmp(aSpecialFp[i].zName, zVal)==0 ){
3478       sqlite3_uint64 x;
3479       x = aSpecialFp[i].iUpper;
3480       x <<= 32;
3481       x |= aSpecialFp[i].iLower;
3482       assert( sizeof(value)==8 );
3483       assert( sizeof(x)==8 );
3484       memcpy(&value, &x, 8);
3485       break;
3486     }
3487   }
3488   if( i>=sizeof(aSpecialFp)/sizeof(aSpecialFp[0]) &&
3489          Tcl_GetDoubleFromObj(interp, objv[3], &value) ){
3490     return TCL_ERROR;
3491   }
3492   rc = sqlite3_bind_double(pStmt, idx, value);
3493   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3494   if( rc!=SQLITE_OK ){
3495     return TCL_ERROR;
3496   }
3497 
3498   return TCL_OK;
3499 }
3500 
3501 /*
3502 ** Usage:   sqlite3_bind_null  STMT N
3503 **
3504 ** Test the sqlite3_bind_null interface.  STMT is a prepared statement.
3505 ** N is the index of a wildcard in the prepared statement.  This command
3506 ** binds a NULL to the wildcard.
3507 */
3508 static int test_bind_null(
3509   void * clientData,
3510   Tcl_Interp *interp,
3511   int objc,
3512   Tcl_Obj *CONST objv[]
3513 ){
3514   sqlite3_stmt *pStmt;
3515   int idx;
3516   int rc;
3517 
3518   if( objc!=3 ){
3519     Tcl_AppendResult(interp, "wrong # args: should be \"",
3520         Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0);
3521     return TCL_ERROR;
3522   }
3523 
3524   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3525   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3526 
3527   rc = sqlite3_bind_null(pStmt, idx);
3528   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3529   if( rc!=SQLITE_OK ){
3530     return TCL_ERROR;
3531   }
3532 
3533   return TCL_OK;
3534 }
3535 
3536 /*
3537 ** Usage:   sqlite3_bind_text  STMT N STRING BYTES
3538 **
3539 ** Test the sqlite3_bind_text interface.  STMT is a prepared statement.
3540 ** N is the index of a wildcard in the prepared statement.  This command
3541 ** binds a UTF-8 string STRING to the wildcard.  The string is BYTES bytes
3542 ** long.
3543 */
3544 static int test_bind_text(
3545   void * clientData,
3546   Tcl_Interp *interp,
3547   int objc,
3548   Tcl_Obj *CONST objv[]
3549 ){
3550   sqlite3_stmt *pStmt;
3551   int idx;
3552   int bytes;
3553   char *value;
3554   int rc;
3555 
3556   if( objc!=5 ){
3557     Tcl_AppendResult(interp, "wrong # args: should be \"",
3558         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
3559     return TCL_ERROR;
3560   }
3561 
3562   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3563   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3564   value = (char*)Tcl_GetByteArrayFromObj(objv[3], &bytes);
3565   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
3566 
3567   rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT);
3568   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3569   if( rc!=SQLITE_OK ){
3570     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
3571     return TCL_ERROR;
3572   }
3573 
3574   return TCL_OK;
3575 }
3576 
3577 /*
3578 ** Usage:   sqlite3_bind_text16 ?-static? STMT N STRING BYTES
3579 **
3580 ** Test the sqlite3_bind_text16 interface.  STMT is a prepared statement.
3581 ** N is the index of a wildcard in the prepared statement.  This command
3582 ** binds a UTF-16 string STRING to the wildcard.  The string is BYTES bytes
3583 ** long.
3584 */
3585 static int test_bind_text16(
3586   void * clientData,
3587   Tcl_Interp *interp,
3588   int objc,
3589   Tcl_Obj *CONST objv[]
3590 ){
3591 #ifndef SQLITE_OMIT_UTF16
3592   sqlite3_stmt *pStmt;
3593   int idx;
3594   int bytes;
3595   char *value;
3596   int rc;
3597 
3598   void (*xDel)(void*) = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT);
3599   Tcl_Obj *oStmt    = objv[objc-4];
3600   Tcl_Obj *oN       = objv[objc-3];
3601   Tcl_Obj *oString  = objv[objc-2];
3602   Tcl_Obj *oBytes   = objv[objc-1];
3603 
3604   if( objc!=5 && objc!=6){
3605     Tcl_AppendResult(interp, "wrong # args: should be \"",
3606         Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0);
3607     return TCL_ERROR;
3608   }
3609 
3610   if( getStmtPointer(interp, Tcl_GetString(oStmt), &pStmt) ) return TCL_ERROR;
3611   if( Tcl_GetIntFromObj(interp, oN, &idx) ) return TCL_ERROR;
3612   value = (char*)Tcl_GetByteArrayFromObj(oString, 0);
3613   if( Tcl_GetIntFromObj(interp, oBytes, &bytes) ) return TCL_ERROR;
3614 
3615   rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, xDel);
3616   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3617   if( rc!=SQLITE_OK ){
3618     Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
3619     return TCL_ERROR;
3620   }
3621 
3622 #endif /* SQLITE_OMIT_UTF16 */
3623   return TCL_OK;
3624 }
3625 
3626 /*
3627 ** Usage:   sqlite3_bind_blob ?-static? STMT N DATA BYTES
3628 **
3629 ** Test the sqlite3_bind_blob interface.  STMT is a prepared statement.
3630 ** N is the index of a wildcard in the prepared statement.  This command
3631 ** binds a BLOB to the wildcard.  The BLOB is BYTES bytes in size.
3632 */
3633 static int test_bind_blob(
3634   void * clientData,
3635   Tcl_Interp *interp,
3636   int objc,
3637   Tcl_Obj *CONST objv[]
3638 ){
3639   sqlite3_stmt *pStmt;
3640   int len, idx;
3641   int bytes;
3642   char *value;
3643   int rc;
3644   sqlite3_destructor_type xDestructor = SQLITE_TRANSIENT;
3645 
3646   if( objc!=5 && objc!=6 ){
3647     Tcl_AppendResult(interp, "wrong # args: should be \"",
3648         Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0);
3649     return TCL_ERROR;
3650   }
3651 
3652   if( objc==6 ){
3653     xDestructor = SQLITE_STATIC;
3654     objv++;
3655   }
3656 
3657   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3658   if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
3659 
3660   value = (char*)Tcl_GetByteArrayFromObj(objv[3], &len);
3661   if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR;
3662 
3663   if( bytes>len ){
3664     char zBuf[200];
3665     sqlite3_snprintf(sizeof(zBuf), zBuf,
3666                      "cannot use %d blob bytes, have %d", bytes, len);
3667     Tcl_AppendResult(interp, zBuf, -1);
3668     return TCL_ERROR;
3669   }
3670 
3671   rc = sqlite3_bind_blob(pStmt, idx, value, bytes, xDestructor);
3672   if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR;
3673   if( rc!=SQLITE_OK ){
3674     return TCL_ERROR;
3675   }
3676 
3677   return TCL_OK;
3678 }
3679 
3680 /*
3681 ** Usage:   sqlite3_bind_parameter_count  STMT
3682 **
3683 ** Return the number of wildcards in the given statement.
3684 */
3685 static int test_bind_parameter_count(
3686   void * clientData,
3687   Tcl_Interp *interp,
3688   int objc,
3689   Tcl_Obj *CONST objv[]
3690 ){
3691   sqlite3_stmt *pStmt;
3692 
3693   if( objc!=2 ){
3694     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
3695     return TCL_ERROR;
3696   }
3697   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3698   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt)));
3699   return TCL_OK;
3700 }
3701 
3702 /*
3703 ** Usage:   sqlite3_bind_parameter_name  STMT  N
3704 **
3705 ** Return the name of the Nth wildcard.  The first wildcard is 1.
3706 ** An empty string is returned if N is out of range or if the wildcard
3707 ** is nameless.
3708 */
3709 static int test_bind_parameter_name(
3710   void * clientData,
3711   Tcl_Interp *interp,
3712   int objc,
3713   Tcl_Obj *CONST objv[]
3714 ){
3715   sqlite3_stmt *pStmt;
3716   int i;
3717 
3718   if( objc!=3 ){
3719     Tcl_WrongNumArgs(interp, 1, objv, "STMT N");
3720     return TCL_ERROR;
3721   }
3722   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3723   if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR;
3724   Tcl_SetObjResult(interp,
3725      Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1)
3726   );
3727   return TCL_OK;
3728 }
3729 
3730 /*
3731 ** Usage:   sqlite3_bind_parameter_index  STMT  NAME
3732 **
3733 ** Return the index of the wildcard called NAME.  Return 0 if there is
3734 ** no such wildcard.
3735 */
3736 static int test_bind_parameter_index(
3737   void * clientData,
3738   Tcl_Interp *interp,
3739   int objc,
3740   Tcl_Obj *CONST objv[]
3741 ){
3742   sqlite3_stmt *pStmt;
3743 
3744   if( objc!=3 ){
3745     Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME");
3746     return TCL_ERROR;
3747   }
3748   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3749   Tcl_SetObjResult(interp,
3750      Tcl_NewIntObj(
3751        sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2]))
3752      )
3753   );
3754   return TCL_OK;
3755 }
3756 
3757 /*
3758 ** Usage:   sqlite3_clear_bindings STMT
3759 **
3760 */
3761 static int test_clear_bindings(
3762   void * clientData,
3763   Tcl_Interp *interp,
3764   int objc,
3765   Tcl_Obj *CONST objv[]
3766 ){
3767   sqlite3_stmt *pStmt;
3768 
3769   if( objc!=2 ){
3770     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
3771     return TCL_ERROR;
3772   }
3773   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
3774   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt)));
3775   return TCL_OK;
3776 }
3777 
3778 /*
3779 ** Usage:   sqlite3_sleep MILLISECONDS
3780 */
3781 static int test_sleep(
3782   void * clientData,
3783   Tcl_Interp *interp,
3784   int objc,
3785   Tcl_Obj *CONST objv[]
3786 ){
3787   int ms;
3788 
3789   if( objc!=2 ){
3790     Tcl_WrongNumArgs(interp, 1, objv, "MILLISECONDS");
3791     return TCL_ERROR;
3792   }
3793   if( Tcl_GetIntFromObj(interp, objv[1], &ms) ){
3794     return TCL_ERROR;
3795   }
3796   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(ms)));
3797   return TCL_OK;
3798 }
3799 
3800 /*
3801 ** Usage: sqlite3_extended_errcode DB
3802 **
3803 ** Return the string representation of the most recent sqlite3_* API
3804 ** error code. e.g. "SQLITE_ERROR".
3805 */
3806 static int test_ex_errcode(
3807   void * clientData,
3808   Tcl_Interp *interp,
3809   int objc,
3810   Tcl_Obj *CONST objv[]
3811 ){
3812   sqlite3 *db;
3813   int rc;
3814 
3815   if( objc!=2 ){
3816     Tcl_AppendResult(interp, "wrong # args: should be \"",
3817        Tcl_GetString(objv[0]), " DB", 0);
3818     return TCL_ERROR;
3819   }
3820   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3821   rc = sqlite3_extended_errcode(db);
3822   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
3823   return TCL_OK;
3824 }
3825 
3826 
3827 /*
3828 ** Usage: sqlite3_errcode DB
3829 **
3830 ** Return the string representation of the most recent sqlite3_* API
3831 ** error code. e.g. "SQLITE_ERROR".
3832 */
3833 static int test_errcode(
3834   void * clientData,
3835   Tcl_Interp *interp,
3836   int objc,
3837   Tcl_Obj *CONST objv[]
3838 ){
3839   sqlite3 *db;
3840   int rc;
3841 
3842   if( objc!=2 ){
3843     Tcl_AppendResult(interp, "wrong # args: should be \"",
3844        Tcl_GetString(objv[0]), " DB", 0);
3845     return TCL_ERROR;
3846   }
3847   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3848   rc = sqlite3_errcode(db);
3849   Tcl_AppendResult(interp, (char *)t1ErrorName(rc), 0);
3850   return TCL_OK;
3851 }
3852 
3853 /*
3854 ** Usage:   sqlite3_errmsg DB
3855 **
3856 ** Returns the UTF-8 representation of the error message string for the
3857 ** most recent sqlite3_* API call.
3858 */
3859 static int test_errmsg(
3860   void * clientData,
3861   Tcl_Interp *interp,
3862   int objc,
3863   Tcl_Obj *CONST objv[]
3864 ){
3865   sqlite3 *db;
3866   const char *zErr;
3867 
3868   if( objc!=2 ){
3869     Tcl_AppendResult(interp, "wrong # args: should be \"",
3870        Tcl_GetString(objv[0]), " DB", 0);
3871     return TCL_ERROR;
3872   }
3873   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3874 
3875   zErr = sqlite3_errmsg(db);
3876   Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
3877   return TCL_OK;
3878 }
3879 
3880 /*
3881 ** Usage:   test_errmsg16 DB
3882 **
3883 ** Returns the UTF-16 representation of the error message string for the
3884 ** most recent sqlite3_* API call. This is a byte array object at the TCL
3885 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
3886 ** UTF-16 string.
3887 */
3888 static int test_errmsg16(
3889   void * clientData,
3890   Tcl_Interp *interp,
3891   int objc,
3892   Tcl_Obj *CONST objv[]
3893 ){
3894 #ifndef SQLITE_OMIT_UTF16
3895   sqlite3 *db;
3896   const void *zErr;
3897   const char *z;
3898   int bytes = 0;
3899 
3900   if( objc!=2 ){
3901     Tcl_AppendResult(interp, "wrong # args: should be \"",
3902        Tcl_GetString(objv[0]), " DB", 0);
3903     return TCL_ERROR;
3904   }
3905   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3906 
3907   zErr = sqlite3_errmsg16(db);
3908   if( zErr ){
3909     z = zErr;
3910     for(bytes=0; z[bytes] || z[bytes+1]; bytes+=2){}
3911   }
3912   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
3913 #endif /* SQLITE_OMIT_UTF16 */
3914   return TCL_OK;
3915 }
3916 
3917 /*
3918 ** Usage: sqlite3_prepare DB sql bytes ?tailvar?
3919 **
3920 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3921 ** database handle <DB>. The parameter <tailval> is the name of a global
3922 ** variable that is set to the unused portion of <sql> (if any). A
3923 ** STMT handle is returned.
3924 */
3925 static int test_prepare(
3926   void * clientData,
3927   Tcl_Interp *interp,
3928   int objc,
3929   Tcl_Obj *CONST objv[]
3930 ){
3931   sqlite3 *db;
3932   const char *zSql;
3933   int bytes;
3934   const char *zTail = 0;
3935   sqlite3_stmt *pStmt = 0;
3936   char zBuf[50];
3937   int rc;
3938 
3939   if( objc!=5 && objc!=4 ){
3940     Tcl_AppendResult(interp, "wrong # args: should be \"",
3941        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
3942     return TCL_ERROR;
3943   }
3944   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
3945   zSql = Tcl_GetString(objv[2]);
3946   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
3947 
3948   rc = sqlite3_prepare(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
3949   Tcl_ResetResult(interp);
3950   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
3951   if( zTail && objc>=5 ){
3952     if( bytes>=0 ){
3953       bytes = bytes - (int)(zTail-zSql);
3954     }
3955     if( (int)strlen(zTail)<bytes ){
3956       bytes = (int)strlen(zTail);
3957     }
3958     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
3959   }
3960   if( rc!=SQLITE_OK ){
3961     assert( pStmt==0 );
3962     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
3963     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
3964     return TCL_ERROR;
3965   }
3966 
3967   if( pStmt ){
3968     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
3969     Tcl_AppendResult(interp, zBuf, 0);
3970   }
3971   return TCL_OK;
3972 }
3973 
3974 /*
3975 ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar?
3976 **
3977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
3978 ** database handle <DB>. The parameter <tailval> is the name of a global
3979 ** variable that is set to the unused portion of <sql> (if any). A
3980 ** STMT handle is returned.
3981 */
3982 static int test_prepare_v2(
3983   void * clientData,
3984   Tcl_Interp *interp,
3985   int objc,
3986   Tcl_Obj *CONST objv[]
3987 ){
3988   sqlite3 *db;
3989   const char *zSql;
3990   char *zCopy = 0;                /* malloc() copy of zSql */
3991   int bytes;
3992   const char *zTail = 0;
3993   sqlite3_stmt *pStmt = 0;
3994   char zBuf[50];
3995   int rc;
3996 
3997   if( objc!=5 && objc!=4 ){
3998     Tcl_AppendResult(interp, "wrong # args: should be \"",
3999        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
4000     return TCL_ERROR;
4001   }
4002   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4003   zSql = Tcl_GetString(objv[2]);
4004   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
4005 
4006   /* Instead of using zSql directly, make a copy into a buffer obtained
4007   ** directly from malloc(). The idea is to make it easier for valgrind
4008   ** to spot buffer overreads.  */
4009   if( bytes>=0 ){
4010     zCopy = malloc(bytes);
4011     memcpy(zCopy, zSql, bytes);
4012   }else{
4013     int n = (int)strlen(zSql) + 1;
4014     zCopy = malloc(n);
4015     memcpy(zCopy, zSql, n);
4016   }
4017   rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, objc>=5 ? &zTail : 0);
4018   free(zCopy);
4019   zTail = &zSql[(zTail - zCopy)];
4020 
4021   assert(rc==SQLITE_OK || pStmt==0);
4022   Tcl_ResetResult(interp);
4023   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
4024   if( rc==SQLITE_OK && zTail && objc>=5 ){
4025     if( bytes>=0 ){
4026       bytes = bytes - (int)(zTail-zSql);
4027     }
4028     Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
4029   }
4030   if( rc!=SQLITE_OK ){
4031     assert( pStmt==0 );
4032     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
4033     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
4034     return TCL_ERROR;
4035   }
4036 
4037   if( pStmt ){
4038     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
4039     Tcl_AppendResult(interp, zBuf, 0);
4040   }
4041   return TCL_OK;
4042 }
4043 
4044 /*
4045 ** Usage: sqlite3_prepare_tkt3134 DB
4046 **
4047 ** Generate a prepared statement for a zero-byte string as a test
4048 ** for ticket #3134.  The string should be preceded by a zero byte.
4049 */
4050 static int test_prepare_tkt3134(
4051   void * clientData,
4052   Tcl_Interp *interp,
4053   int objc,
4054   Tcl_Obj *CONST objv[]
4055 ){
4056   sqlite3 *db;
4057   static const char zSql[] = "\000SELECT 1";
4058   sqlite3_stmt *pStmt = 0;
4059   char zBuf[50];
4060   int rc;
4061 
4062   if( objc!=2 ){
4063     Tcl_AppendResult(interp, "wrong # args: should be \"",
4064        Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
4065     return TCL_ERROR;
4066   }
4067   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4068   rc = sqlite3_prepare_v2(db, &zSql[1], 0, &pStmt, 0);
4069   assert(rc==SQLITE_OK || pStmt==0);
4070   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
4071   if( rc!=SQLITE_OK ){
4072     assert( pStmt==0 );
4073     sqlite3_snprintf(sizeof(zBuf), zBuf, "(%d) ", rc);
4074     Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
4075     return TCL_ERROR;
4076   }
4077 
4078   if( pStmt ){
4079     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
4080     Tcl_AppendResult(interp, zBuf, 0);
4081   }
4082   return TCL_OK;
4083 }
4084 
4085 /*
4086 ** Usage: sqlite3_prepare16 DB sql bytes tailvar
4087 **
4088 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4089 ** database handle <DB>. The parameter <tailval> is the name of a global
4090 ** variable that is set to the unused portion of <sql> (if any). A
4091 ** STMT handle is returned.
4092 */
4093 static int test_prepare16(
4094   void * clientData,
4095   Tcl_Interp *interp,
4096   int objc,
4097   Tcl_Obj *CONST objv[]
4098 ){
4099 #ifndef SQLITE_OMIT_UTF16
4100   sqlite3 *db;
4101   const void *zSql;
4102   const void *zTail = 0;
4103   Tcl_Obj *pTail = 0;
4104   sqlite3_stmt *pStmt = 0;
4105   char zBuf[50];
4106   int rc;
4107   int bytes;                /* The integer specified as arg 3 */
4108   int objlen;               /* The byte-array length of arg 2 */
4109 
4110   if( objc!=5 && objc!=4 ){
4111     Tcl_AppendResult(interp, "wrong # args: should be \"",
4112        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
4113     return TCL_ERROR;
4114   }
4115   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4116   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
4117   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
4118 
4119   rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
4120   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
4121   if( rc ){
4122     return TCL_ERROR;
4123   }
4124 
4125   if( objc>=5 ){
4126     if( zTail ){
4127       objlen = objlen - (int)((u8 *)zTail-(u8 *)zSql);
4128     }else{
4129       objlen = 0;
4130     }
4131     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
4132     Tcl_IncrRefCount(pTail);
4133     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
4134     Tcl_DecrRefCount(pTail);
4135   }
4136 
4137   if( pStmt ){
4138     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
4139   }
4140   Tcl_AppendResult(interp, zBuf, 0);
4141 #endif /* SQLITE_OMIT_UTF16 */
4142   return TCL_OK;
4143 }
4144 
4145 /*
4146 ** Usage: sqlite3_prepare16_v2 DB sql bytes ?tailvar?
4147 **
4148 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4149 ** database handle <DB>. The parameter <tailval> is the name of a global
4150 ** variable that is set to the unused portion of <sql> (if any). A
4151 ** STMT handle is returned.
4152 */
4153 static int test_prepare16_v2(
4154   void * clientData,
4155   Tcl_Interp *interp,
4156   int objc,
4157   Tcl_Obj *CONST objv[]
4158 ){
4159 #ifndef SQLITE_OMIT_UTF16
4160   sqlite3 *db;
4161   const void *zSql;
4162   const void *zTail = 0;
4163   Tcl_Obj *pTail = 0;
4164   sqlite3_stmt *pStmt = 0;
4165   char zBuf[50];
4166   int rc;
4167   int bytes;                /* The integer specified as arg 3 */
4168   int objlen;               /* The byte-array length of arg 2 */
4169 
4170   if( objc!=5 && objc!=4 ){
4171     Tcl_AppendResult(interp, "wrong # args: should be \"",
4172        Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0);
4173     return TCL_ERROR;
4174   }
4175   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
4176   zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
4177   if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;
4178 
4179   rc = sqlite3_prepare16_v2(db, zSql, bytes, &pStmt, objc>=5 ? &zTail : 0);
4180   if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR;
4181   if( rc ){
4182     return TCL_ERROR;
4183   }
4184 
4185   if( objc>=5 ){
4186     if( zTail ){
4187       objlen = objlen - (int)((u8 *)zTail-(u8 *)zSql);
4188     }else{
4189       objlen = 0;
4190     }
4191     pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
4192     Tcl_IncrRefCount(pTail);
4193     Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
4194     Tcl_DecrRefCount(pTail);
4195   }
4196 
4197   if( pStmt ){
4198     if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
4199   }
4200   Tcl_AppendResult(interp, zBuf, 0);
4201 #endif /* SQLITE_OMIT_UTF16 */
4202   return TCL_OK;
4203 }
4204 
4205 /*
4206 ** Usage: sqlite3_open filename ?options-list?
4207 */
4208 static int test_open(
4209   void * clientData,
4210   Tcl_Interp *interp,
4211   int objc,
4212   Tcl_Obj *CONST objv[]
4213 ){
4214   const char *zFilename;
4215   sqlite3 *db;
4216   char zBuf[100];
4217 
4218   if( objc!=3 && objc!=2 && objc!=1 ){
4219     Tcl_AppendResult(interp, "wrong # args: should be \"",
4220        Tcl_GetString(objv[0]), " filename options-list", 0);
4221     return TCL_ERROR;
4222   }
4223 
4224   zFilename = objc>1 ? Tcl_GetString(objv[1]) : 0;
4225   sqlite3_open(zFilename, &db);
4226 
4227   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
4228   Tcl_AppendResult(interp, zBuf, 0);
4229   return TCL_OK;
4230 }
4231 
4232 /*
4233 ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
4234 */
4235 static int test_open_v2(
4236   void * clientData,
4237   Tcl_Interp *interp,
4238   int objc,
4239   Tcl_Obj *CONST objv[]
4240 ){
4241   const char *zFilename;
4242   const char *zVfs;
4243   int flags = 0;
4244   sqlite3 *db;
4245   int rc;
4246   char zBuf[100];
4247 
4248   int nFlag;
4249   Tcl_Obj **apFlag;
4250   int i;
4251 
4252   if( objc!=4 ){
4253     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS");
4254     return TCL_ERROR;
4255   }
4256   zFilename = Tcl_GetString(objv[1]);
4257   zVfs = Tcl_GetString(objv[3]);
4258   if( zVfs[0]==0x00 ) zVfs = 0;
4259 
4260   rc = Tcl_ListObjGetElements(interp, objv[2], &nFlag, &apFlag);
4261   if( rc!=TCL_OK ) return rc;
4262   for(i=0; i<nFlag; i++){
4263     int iFlag;
4264     struct OpenFlag {
4265       const char *zFlag;
4266       int flag;
4267     } aFlag[] = {
4268       { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY },
4269       { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE },
4270       { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE },
4271       { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE },
4272       { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE },
4273       { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY },
4274       { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB },
4275       { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB },
4276       { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB },
4277       { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL },
4278       { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL },
4279       { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL },
4280       { "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL },
4281       { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX },
4282       { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX },
4283       { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE },
4284       { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE },
4285       { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL },
4286       { "SQLITE_OPEN_URI", SQLITE_OPEN_URI },
4287       { 0, 0 }
4288     };
4289     rc = Tcl_GetIndexFromObjStruct(interp, apFlag[i], aFlag, sizeof(aFlag[0]),
4290         "flag", 0, &iFlag
4291     );
4292     if( rc!=TCL_OK ) return rc;
4293     flags |= aFlag[iFlag].flag;
4294   }
4295 
4296   rc = sqlite3_open_v2(zFilename, &db, flags, zVfs);
4297   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
4298   Tcl_AppendResult(interp, zBuf, 0);
4299   return TCL_OK;
4300 }
4301 
4302 /*
4303 ** Usage: sqlite3_open16 filename options
4304 */
4305 static int test_open16(
4306   void * clientData,
4307   Tcl_Interp *interp,
4308   int objc,
4309   Tcl_Obj *CONST objv[]
4310 ){
4311 #ifndef SQLITE_OMIT_UTF16
4312   const void *zFilename;
4313   sqlite3 *db;
4314   char zBuf[100];
4315 
4316   if( objc!=3 ){
4317     Tcl_AppendResult(interp, "wrong # args: should be \"",
4318        Tcl_GetString(objv[0]), " filename options-list", 0);
4319     return TCL_ERROR;
4320   }
4321 
4322   zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
4323   sqlite3_open16(zFilename, &db);
4324 
4325   if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR;
4326   Tcl_AppendResult(interp, zBuf, 0);
4327 #endif /* SQLITE_OMIT_UTF16 */
4328   return TCL_OK;
4329 }
4330 
4331 /*
4332 ** Usage: sqlite3_complete16 <UTF-16 string>
4333 **
4334 ** Return 1 if the supplied argument is a complete SQL statement, or zero
4335 ** otherwise.
4336 */
4337 static int test_complete16(
4338   void * clientData,
4339   Tcl_Interp *interp,
4340   int objc,
4341   Tcl_Obj *CONST objv[]
4342 ){
4343 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
4344   char *zBuf;
4345 
4346   if( objc!=2 ){
4347     Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
4348     return TCL_ERROR;
4349   }
4350 
4351   zBuf = (char*)Tcl_GetByteArrayFromObj(objv[1], 0);
4352   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
4353 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
4354   return TCL_OK;
4355 }
4356 
4357 /*
4358 ** Usage: sqlite3_step STMT
4359 **
4360 ** Advance the statement to the next row.
4361 */
4362 static int test_step(
4363   void * clientData,
4364   Tcl_Interp *interp,
4365   int objc,
4366   Tcl_Obj *CONST objv[]
4367 ){
4368   sqlite3_stmt *pStmt;
4369   int rc;
4370 
4371   if( objc!=2 ){
4372     Tcl_AppendResult(interp, "wrong # args: should be \"",
4373        Tcl_GetString(objv[0]), " STMT", 0);
4374     return TCL_ERROR;
4375   }
4376 
4377   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4378   rc = sqlite3_step(pStmt);
4379 
4380   /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
4381   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
4382   return TCL_OK;
4383 }
4384 
4385 static int test_sql(
4386   void * clientData,
4387   Tcl_Interp *interp,
4388   int objc,
4389   Tcl_Obj *CONST objv[]
4390 ){
4391   sqlite3_stmt *pStmt;
4392 
4393   if( objc!=2 ){
4394     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
4395     return TCL_ERROR;
4396   }
4397 
4398   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4399   Tcl_SetResult(interp, (char *)sqlite3_sql(pStmt), TCL_VOLATILE);
4400   return TCL_OK;
4401 }
4402 static int test_ex_sql(
4403   void * clientData,
4404   Tcl_Interp *interp,
4405   int objc,
4406   Tcl_Obj *CONST objv[]
4407 ){
4408   sqlite3_stmt *pStmt;
4409   char *z;
4410 
4411   if( objc!=2 ){
4412     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
4413     return TCL_ERROR;
4414   }
4415 
4416   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4417   z = sqlite3_expanded_sql(pStmt);
4418   Tcl_SetResult(interp, z, TCL_VOLATILE);
4419   sqlite3_free(z);
4420   return TCL_OK;
4421 }
4422 
4423 /*
4424 ** Usage: sqlite3_column_count STMT
4425 **
4426 ** Return the number of columns returned by the sql statement STMT.
4427 */
4428 static int test_column_count(
4429   void * clientData,
4430   Tcl_Interp *interp,
4431   int objc,
4432   Tcl_Obj *CONST objv[]
4433 ){
4434   sqlite3_stmt *pStmt;
4435 
4436   if( objc!=2 ){
4437     Tcl_AppendResult(interp, "wrong # args: should be \"",
4438        Tcl_GetString(objv[0]), " STMT column", 0);
4439     return TCL_ERROR;
4440   }
4441 
4442   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4443 
4444   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt)));
4445   return TCL_OK;
4446 }
4447 
4448 /*
4449 ** Usage: sqlite3_column_type STMT column
4450 **
4451 ** Return the type of the data in column 'column' of the current row.
4452 */
4453 static int test_column_type(
4454   void * clientData,
4455   Tcl_Interp *interp,
4456   int objc,
4457   Tcl_Obj *CONST objv[]
4458 ){
4459   sqlite3_stmt *pStmt;
4460   int col;
4461   int tp;
4462 
4463   if( objc!=3 ){
4464     Tcl_AppendResult(interp, "wrong # args: should be \"",
4465        Tcl_GetString(objv[0]), " STMT column", 0);
4466     return TCL_ERROR;
4467   }
4468 
4469   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4470   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4471 
4472   tp = sqlite3_column_type(pStmt, col);
4473   switch( tp ){
4474     case SQLITE_INTEGER:
4475       Tcl_SetResult(interp, "INTEGER", TCL_STATIC);
4476       break;
4477     case SQLITE_NULL:
4478       Tcl_SetResult(interp, "NULL", TCL_STATIC);
4479       break;
4480     case SQLITE_FLOAT:
4481       Tcl_SetResult(interp, "FLOAT", TCL_STATIC);
4482       break;
4483     case SQLITE_TEXT:
4484       Tcl_SetResult(interp, "TEXT", TCL_STATIC);
4485       break;
4486     case SQLITE_BLOB:
4487       Tcl_SetResult(interp, "BLOB", TCL_STATIC);
4488       break;
4489     default:
4490       assert(0);
4491   }
4492 
4493   return TCL_OK;
4494 }
4495 
4496 /*
4497 ** Usage: sqlite3_column_int64 STMT column
4498 **
4499 ** Return the data in column 'column' of the current row cast as an
4500 ** wide (64-bit) integer.
4501 */
4502 static int test_column_int64(
4503   void * clientData,
4504   Tcl_Interp *interp,
4505   int objc,
4506   Tcl_Obj *CONST objv[]
4507 ){
4508   sqlite3_stmt *pStmt;
4509   int col;
4510   i64 iVal;
4511 
4512   if( objc!=3 ){
4513     Tcl_AppendResult(interp, "wrong # args: should be \"",
4514        Tcl_GetString(objv[0]), " STMT column", 0);
4515     return TCL_ERROR;
4516   }
4517 
4518   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4519   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4520 
4521   iVal = sqlite3_column_int64(pStmt, col);
4522   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal));
4523   return TCL_OK;
4524 }
4525 
4526 /*
4527 ** Usage: sqlite3_column_blob STMT column
4528 */
4529 static int test_column_blob(
4530   void * clientData,
4531   Tcl_Interp *interp,
4532   int objc,
4533   Tcl_Obj *CONST objv[]
4534 ){
4535   sqlite3_stmt *pStmt;
4536   int col;
4537 
4538   int len;
4539   const void *pBlob;
4540 
4541   if( objc!=3 ){
4542     Tcl_AppendResult(interp, "wrong # args: should be \"",
4543        Tcl_GetString(objv[0]), " STMT column", 0);
4544     return TCL_ERROR;
4545   }
4546 
4547   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4548   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4549 
4550   len = sqlite3_column_bytes(pStmt, col);
4551   pBlob = sqlite3_column_blob(pStmt, col);
4552   Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len));
4553   return TCL_OK;
4554 }
4555 
4556 /*
4557 ** Usage: sqlite3_column_double STMT column
4558 **
4559 ** Return the data in column 'column' of the current row cast as a double.
4560 */
4561 static int test_column_double(
4562   void * clientData,
4563   Tcl_Interp *interp,
4564   int objc,
4565   Tcl_Obj *CONST objv[]
4566 ){
4567   sqlite3_stmt *pStmt;
4568   int col;
4569   double rVal;
4570 
4571   if( objc!=3 ){
4572     Tcl_AppendResult(interp, "wrong # args: should be \"",
4573        Tcl_GetString(objv[0]), " STMT column", 0);
4574     return TCL_ERROR;
4575   }
4576 
4577   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4578   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4579 
4580   rVal = sqlite3_column_double(pStmt, col);
4581   Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal));
4582   return TCL_OK;
4583 }
4584 
4585 /*
4586 ** Usage: sqlite3_data_count STMT
4587 **
4588 ** Return the number of columns returned by the sql statement STMT.
4589 */
4590 static int test_data_count(
4591   void * clientData,
4592   Tcl_Interp *interp,
4593   int objc,
4594   Tcl_Obj *CONST objv[]
4595 ){
4596   sqlite3_stmt *pStmt;
4597 
4598   if( objc!=2 ){
4599     Tcl_AppendResult(interp, "wrong # args: should be \"",
4600        Tcl_GetString(objv[0]), " STMT column", 0);
4601     return TCL_ERROR;
4602   }
4603 
4604   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4605 
4606   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt)));
4607   return TCL_OK;
4608 }
4609 
4610 /*
4611 ** Usage: sqlite3_column_text STMT column
4612 **
4613 ** Usage: sqlite3_column_decltype STMT column
4614 **
4615 ** Usage: sqlite3_column_name STMT column
4616 */
4617 static int test_stmt_utf8(
4618   void * clientData,        /* Pointer to SQLite API function to be invoke */
4619   Tcl_Interp *interp,
4620   int objc,
4621   Tcl_Obj *CONST objv[]
4622 ){
4623   sqlite3_stmt *pStmt;
4624   int col;
4625   const char *(*xFunc)(sqlite3_stmt*, int);
4626   const char *zRet;
4627 
4628   xFunc = (const char *(*)(sqlite3_stmt*, int))clientData;
4629   if( objc!=3 ){
4630     Tcl_AppendResult(interp, "wrong # args: should be \"",
4631        Tcl_GetString(objv[0]), " STMT column", 0);
4632     return TCL_ERROR;
4633   }
4634 
4635   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4636   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4637   zRet = xFunc(pStmt, col);
4638   if( zRet ){
4639     Tcl_SetResult(interp, (char *)zRet, 0);
4640   }
4641   return TCL_OK;
4642 }
4643 
4644 static int test_global_recover(
4645   void * clientData,
4646   Tcl_Interp *interp,
4647   int objc,
4648   Tcl_Obj *CONST objv[]
4649 ){
4650 #ifndef SQLITE_OMIT_DEPRECATED
4651   int rc;
4652   if( objc!=1 ){
4653     Tcl_WrongNumArgs(interp, 1, objv, "");
4654     return TCL_ERROR;
4655   }
4656   rc = sqlite3_global_recover();
4657   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4658 #endif
4659   return TCL_OK;
4660 }
4661 
4662 /*
4663 ** Usage: sqlite3_column_text STMT column
4664 **
4665 ** Usage: sqlite3_column_decltype STMT column
4666 **
4667 ** Usage: sqlite3_column_name STMT column
4668 */
4669 static int test_stmt_utf16(
4670   void * clientData,     /* Pointer to SQLite API function to be invoked */
4671   Tcl_Interp *interp,
4672   int objc,
4673   Tcl_Obj *CONST objv[]
4674 ){
4675 #ifndef SQLITE_OMIT_UTF16
4676   sqlite3_stmt *pStmt;
4677   int col;
4678   Tcl_Obj *pRet;
4679   const void *zName16;
4680   const void *(*xFunc)(sqlite3_stmt*, int);
4681 
4682   xFunc = (const void *(*)(sqlite3_stmt*, int))clientData;
4683   if( objc!=3 ){
4684     Tcl_AppendResult(interp, "wrong # args: should be \"",
4685        Tcl_GetString(objv[0]), " STMT column", 0);
4686     return TCL_ERROR;
4687   }
4688 
4689   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4690   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4691 
4692   zName16 = xFunc(pStmt, col);
4693   if( zName16 ){
4694     int n;
4695     const char *z = zName16;
4696     for(n=0; z[n] || z[n+1]; n+=2){}
4697     pRet = Tcl_NewByteArrayObj(zName16, n+2);
4698     Tcl_SetObjResult(interp, pRet);
4699   }
4700 #endif /* SQLITE_OMIT_UTF16 */
4701 
4702   return TCL_OK;
4703 }
4704 
4705 /*
4706 ** Usage: sqlite3_column_int STMT column
4707 **
4708 ** Usage: sqlite3_column_bytes STMT column
4709 **
4710 ** Usage: sqlite3_column_bytes16 STMT column
4711 **
4712 */
4713 static int test_stmt_int(
4714   void * clientData,    /* Pointer to SQLite API function to be invoked */
4715   Tcl_Interp *interp,
4716   int objc,
4717   Tcl_Obj *CONST objv[]
4718 ){
4719   sqlite3_stmt *pStmt;
4720   int col;
4721   int (*xFunc)(sqlite3_stmt*, int);
4722 
4723   xFunc = (int (*)(sqlite3_stmt*, int))clientData;
4724   if( objc!=3 ){
4725     Tcl_AppendResult(interp, "wrong # args: should be \"",
4726        Tcl_GetString(objv[0]), " STMT column", 0);
4727     return TCL_ERROR;
4728   }
4729 
4730   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
4731   if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR;
4732 
4733   Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col)));
4734   return TCL_OK;
4735 }
4736 
4737 /*
4738 ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
4739 **
4740 ** Set the db->magic value.  This is used to test error recovery logic.
4741 */
4742 static int sqlite_set_magic(
4743   void * clientData,
4744   Tcl_Interp *interp,
4745   int argc,
4746   char **argv
4747 ){
4748   sqlite3 *db;
4749   if( argc!=3 ){
4750     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4751          " DB MAGIC", 0);
4752     return TCL_ERROR;
4753   }
4754   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4755   if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){
4756     db->magic = SQLITE_MAGIC_OPEN;
4757   }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){
4758     db->magic = SQLITE_MAGIC_CLOSED;
4759   }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){
4760     db->magic = SQLITE_MAGIC_BUSY;
4761   }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){
4762     db->magic = SQLITE_MAGIC_ERROR;
4763   }else if( Tcl_GetInt(interp, argv[2], (int*)&db->magic) ){
4764     return TCL_ERROR;
4765   }
4766   return TCL_OK;
4767 }
4768 
4769 /*
4770 ** Usage:  sqlite3_interrupt  DB
4771 **
4772 ** Trigger an interrupt on DB
4773 */
4774 static int test_interrupt(
4775   void * clientData,
4776   Tcl_Interp *interp,
4777   int argc,
4778   char **argv
4779 ){
4780   sqlite3 *db;
4781   if( argc!=2 ){
4782     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0);
4783     return TCL_ERROR;
4784   }
4785   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4786   sqlite3_interrupt(db);
4787   return TCL_OK;
4788 }
4789 
4790 static u8 *sqlite3_stack_baseline = 0;
4791 
4792 /*
4793 ** Fill the stack with a known bitpattern.
4794 */
4795 static void prepStack(void){
4796   int i;
4797   u32 bigBuf[65536];
4798   for(i=0; i<sizeof(bigBuf)/sizeof(bigBuf[0]); i++) bigBuf[i] = 0xdeadbeef;
4799   sqlite3_stack_baseline = (u8*)&bigBuf[65536];
4800 }
4801 
4802 /*
4803 ** Get the current stack depth.  Used for debugging only.
4804 */
4805 u64 sqlite3StackDepth(void){
4806   u8 x;
4807   return (u64)(sqlite3_stack_baseline - &x);
4808 }
4809 
4810 /*
4811 ** Usage:  sqlite3_stack_used DB SQL
4812 **
4813 ** Try to measure the amount of stack space used by a call to sqlite3_exec
4814 */
4815 static int test_stack_used(
4816   void * clientData,
4817   Tcl_Interp *interp,
4818   int argc,
4819   char **argv
4820 ){
4821   sqlite3 *db;
4822   int i;
4823   if( argc!=3 ){
4824     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4825         " DB SQL", 0);
4826     return TCL_ERROR;
4827   }
4828   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4829   prepStack();
4830   (void)sqlite3_exec(db, argv[2], 0, 0, 0);
4831   for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){}
4832   Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4));
4833   return TCL_OK;
4834 }
4835 
4836 /*
4837 ** Usage: sqlite_delete_function DB function-name
4838 **
4839 ** Delete the user function 'function-name' from database handle DB. It
4840 ** is assumed that the user function was created as UTF8, any number of
4841 ** arguments (the way the TCL interface does it).
4842 */
4843 static int delete_function(
4844   void * clientData,
4845   Tcl_Interp *interp,
4846   int argc,
4847   char **argv
4848 ){
4849   int rc;
4850   sqlite3 *db;
4851   if( argc!=3 ){
4852     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4853         " DB function-name", 0);
4854     return TCL_ERROR;
4855   }
4856   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4857   rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0);
4858   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4859   return TCL_OK;
4860 }
4861 
4862 /*
4863 ** Usage: sqlite_delete_collation DB collation-name
4864 **
4865 ** Delete the collation sequence 'collation-name' from database handle
4866 ** DB. It is assumed that the collation sequence was created as UTF8 (the
4867 ** way the TCL interface does it).
4868 */
4869 static int delete_collation(
4870   void * clientData,
4871   Tcl_Interp *interp,
4872   int argc,
4873   char **argv
4874 ){
4875   int rc;
4876   sqlite3 *db;
4877   if( argc!=3 ){
4878     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4879         " DB function-name", 0);
4880     return TCL_ERROR;
4881   }
4882   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4883   rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0);
4884   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
4885   return TCL_OK;
4886 }
4887 
4888 /*
4889 ** Usage: sqlite3_get_autocommit DB
4890 **
4891 ** Return true if the database DB is currently in auto-commit mode.
4892 ** Return false if not.
4893 */
4894 static int get_autocommit(
4895   void * clientData,
4896   Tcl_Interp *interp,
4897   int argc,
4898   char **argv
4899 ){
4900   char zBuf[30];
4901   sqlite3 *db;
4902   if( argc!=2 ){
4903     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4904         " DB", 0);
4905     return TCL_ERROR;
4906   }
4907   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4908   sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3_get_autocommit(db));
4909   Tcl_AppendResult(interp, zBuf, 0);
4910   return TCL_OK;
4911 }
4912 
4913 /*
4914 ** Usage: sqlite3_busy_timeout DB MS
4915 **
4916 ** Set the busy timeout.  This is more easily done using the timeout
4917 ** method of the TCL interface.  But we need a way to test the case
4918 ** where it returns SQLITE_MISUSE.
4919 */
4920 static int test_busy_timeout(
4921   void * clientData,
4922   Tcl_Interp *interp,
4923   int argc,
4924   char **argv
4925 ){
4926   int rc, ms;
4927   sqlite3 *db;
4928   if( argc!=3 ){
4929     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4930         " DB", 0);
4931     return TCL_ERROR;
4932   }
4933   if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
4934   if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR;
4935   rc = sqlite3_busy_timeout(db, ms);
4936   Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
4937   return TCL_OK;
4938 }
4939 
4940 /*
4941 ** Usage:  tcl_variable_type VARIABLENAME
4942 **
4943 ** Return the name of the internal representation for the
4944 ** value of the given variable.
4945 */
4946 static int tcl_variable_type(
4947   void * clientData,
4948   Tcl_Interp *interp,
4949   int objc,
4950   Tcl_Obj *CONST objv[]
4951 ){
4952   Tcl_Obj *pVar;
4953   if( objc!=2 ){
4954     Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE");
4955     return TCL_ERROR;
4956   }
4957   pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG);
4958   if( pVar==0 ) return TCL_ERROR;
4959   if( pVar->typePtr ){
4960     Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1));
4961   }
4962   return TCL_OK;
4963 }
4964 
4965 /*
4966 ** Usage:  sqlite3_release_memory ?N?
4967 **
4968 ** Attempt to release memory currently held but not actually required.
4969 ** The integer N is the number of bytes we are trying to release.  The
4970 ** return value is the amount of memory actually released.
4971 */
4972 static int test_release_memory(
4973   void * clientData,
4974   Tcl_Interp *interp,
4975   int objc,
4976   Tcl_Obj *CONST objv[]
4977 ){
4978 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
4979   int N;
4980   int amt;
4981   if( objc!=1 && objc!=2 ){
4982     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
4983     return TCL_ERROR;
4984   }
4985   if( objc==2 ){
4986     if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
4987   }else{
4988     N = -1;
4989   }
4990   amt = sqlite3_release_memory(N);
4991   Tcl_SetObjResult(interp, Tcl_NewIntObj(amt));
4992 #endif
4993   return TCL_OK;
4994 }
4995 
4996 
4997 /*
4998 ** Usage:  sqlite3_db_release_memory DB
4999 **
5000 ** Attempt to release memory currently held by database DB.  Return the
5001 ** result code (which in the current implementation is always zero).
5002 */
5003 static int test_db_release_memory(
5004   void * clientData,
5005   Tcl_Interp *interp,
5006   int objc,
5007   Tcl_Obj *CONST objv[]
5008 ){
5009   sqlite3 *db;
5010   int rc;
5011   if( objc!=2 ){
5012     Tcl_WrongNumArgs(interp, 1, objv, "DB");
5013     return TCL_ERROR;
5014   }
5015   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5016   rc = sqlite3_db_release_memory(db);
5017   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5018   return TCL_OK;
5019 }
5020 
5021 /*
5022 ** Usage:  sqlite3_db_cacheflush DB
5023 **
5024 ** Attempt to flush any dirty pages to disk.
5025 */
5026 static int test_db_cacheflush(
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_cacheflush(db);
5040   if( rc ){
5041     Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
5042     return TCL_ERROR;
5043   }
5044 
5045   Tcl_ResetResult(interp);
5046   return TCL_OK;
5047 }
5048 
5049 /*
5050 ** Usage:  sqlite3_system_errno DB
5051 **
5052 ** Return the low-level system errno value.
5053 */
5054 static int test_system_errno(
5055   void * clientData,
5056   Tcl_Interp *interp,
5057   int objc,
5058   Tcl_Obj *CONST objv[]
5059 ){
5060   sqlite3 *db;
5061   int iErrno;
5062   if( objc!=2 ){
5063     Tcl_WrongNumArgs(interp, 1, objv, "DB");
5064     return TCL_ERROR;
5065   }
5066   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5067   iErrno = sqlite3_system_errno(db);
5068   Tcl_SetObjResult(interp, Tcl_NewIntObj(iErrno));
5069   return TCL_OK;
5070 }
5071 
5072 /*
5073 ** Usage:  sqlite3_db_filename DB DBNAME
5074 **
5075 ** Return the name of a file associated with a database.
5076 */
5077 static int test_db_filename(
5078   void * clientData,
5079   Tcl_Interp *interp,
5080   int objc,
5081   Tcl_Obj *CONST objv[]
5082 ){
5083   sqlite3 *db;
5084   const char *zDbName;
5085   if( objc!=3 ){
5086     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
5087     return TCL_ERROR;
5088   }
5089   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5090   zDbName = Tcl_GetString(objv[2]);
5091   Tcl_AppendResult(interp, sqlite3_db_filename(db, zDbName), (void*)0);
5092   return TCL_OK;
5093 }
5094 
5095 /*
5096 ** Usage:  sqlite3_db_readonly DB DBNAME
5097 **
5098 ** Return 1 or 0 if DBNAME is readonly or not.  Return -1 if DBNAME does
5099 ** not exist.
5100 */
5101 static int test_db_readonly(
5102   void * clientData,
5103   Tcl_Interp *interp,
5104   int objc,
5105   Tcl_Obj *CONST objv[]
5106 ){
5107   sqlite3 *db;
5108   const char *zDbName;
5109   if( objc!=3 ){
5110     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME");
5111     return TCL_ERROR;
5112   }
5113   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5114   zDbName = Tcl_GetString(objv[2]);
5115   Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_db_readonly(db, zDbName)));
5116   return TCL_OK;
5117 }
5118 
5119 /*
5120 ** Usage:  sqlite3_soft_heap_limit ?N?
5121 **
5122 ** Query or set the soft heap limit for the current thread.  The
5123 ** limit is only changed if the N is present.  The previous limit
5124 ** is returned.
5125 */
5126 static int test_soft_heap_limit(
5127   void * clientData,
5128   Tcl_Interp *interp,
5129   int objc,
5130   Tcl_Obj *CONST objv[]
5131 ){
5132   sqlite3_int64 amt;
5133   Tcl_WideInt N = -1;
5134   if( objc!=1 && objc!=2 ){
5135     Tcl_WrongNumArgs(interp, 1, objv, "?N?");
5136     return TCL_ERROR;
5137   }
5138   if( objc==2 ){
5139     if( Tcl_GetWideIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
5140   }
5141   amt = sqlite3_soft_heap_limit64(N);
5142   Tcl_SetObjResult(interp, Tcl_NewWideIntObj(amt));
5143   return TCL_OK;
5144 }
5145 
5146 /*
5147 ** Usage:   sqlite3_thread_cleanup
5148 **
5149 ** Call the sqlite3_thread_cleanup API.
5150 */
5151 static int test_thread_cleanup(
5152   void * clientData,
5153   Tcl_Interp *interp,
5154   int objc,
5155   Tcl_Obj *CONST objv[]
5156 ){
5157 #ifndef SQLITE_OMIT_DEPRECATED
5158   sqlite3_thread_cleanup();
5159 #endif
5160   return TCL_OK;
5161 }
5162 
5163 /*
5164 ** Usage:   sqlite3_pager_refcounts  DB
5165 **
5166 ** Return a list of numbers which are the PagerRefcount for all
5167 ** pagers on each database connection.
5168 */
5169 static int test_pager_refcounts(
5170   void * clientData,
5171   Tcl_Interp *interp,
5172   int objc,
5173   Tcl_Obj *CONST objv[]
5174 ){
5175   sqlite3 *db;
5176   int i;
5177   int v, *a;
5178   Tcl_Obj *pResult;
5179 
5180   if( objc!=2 ){
5181     Tcl_AppendResult(interp, "wrong # args: should be \"",
5182         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5183     return TCL_ERROR;
5184   }
5185   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5186   pResult = Tcl_NewObj();
5187   for(i=0; i<db->nDb; i++){
5188     if( db->aDb[i].pBt==0 ){
5189       v = -1;
5190     }else{
5191       sqlite3_mutex_enter(db->mutex);
5192       a = sqlite3PagerStats(sqlite3BtreePager(db->aDb[i].pBt));
5193       v = a[0];
5194       sqlite3_mutex_leave(db->mutex);
5195     }
5196     Tcl_ListObjAppendElement(0, pResult, Tcl_NewIntObj(v));
5197   }
5198   Tcl_SetObjResult(interp, pResult);
5199   return TCL_OK;
5200 }
5201 
5202 
5203 /*
5204 ** tclcmd:   working_64bit_int
5205 **
5206 ** Some TCL builds (ex: cygwin) do not support 64-bit integers.  This
5207 ** leads to a number of test failures.  The present command checks the
5208 ** TCL build to see whether or not it supports 64-bit integers.  It
5209 ** returns TRUE if it does and FALSE if not.
5210 **
5211 ** This command is used to warn users that their TCL build is defective
5212 ** and that the errors they are seeing in the test scripts might be
5213 ** a result of their defective TCL rather than problems in SQLite.
5214 */
5215 static int working_64bit_int(
5216   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5217   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5218   int objc,              /* Number of arguments */
5219   Tcl_Obj *CONST objv[]  /* Command arguments */
5220 ){
5221   Tcl_Obj *pTestObj;
5222   int working = 0;
5223 
5224   pTestObj = Tcl_NewWideIntObj(1000000*(i64)1234567890);
5225   working = strcmp(Tcl_GetString(pTestObj), "1234567890000000")==0;
5226   Tcl_DecrRefCount(pTestObj);
5227   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(working));
5228   return TCL_OK;
5229 }
5230 
5231 
5232 /*
5233 ** tclcmd:   vfs_unlink_test
5234 **
5235 ** This TCL command unregisters the primary VFS and then registers
5236 ** it back again.  This is used to test the ability to register a
5237 ** VFS when none are previously registered, and the ability to
5238 ** unregister the only available VFS.  Ticket #2738
5239 */
5240 static int vfs_unlink_test(
5241   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5242   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5243   int objc,              /* Number of arguments */
5244   Tcl_Obj *CONST objv[]  /* Command arguments */
5245 ){
5246   int i;
5247   sqlite3_vfs *pMain;
5248   sqlite3_vfs *apVfs[20];
5249   sqlite3_vfs one, two;
5250 
5251   sqlite3_vfs_unregister(0);   /* Unregister of NULL is harmless */
5252   one.zName = "__one";
5253   two.zName = "__two";
5254 
5255   /* Calling sqlite3_vfs_register with 2nd argument of 0 does not
5256   ** change the default VFS
5257   */
5258   pMain = sqlite3_vfs_find(0);
5259   sqlite3_vfs_register(&one, 0);
5260   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
5261   sqlite3_vfs_register(&two, 0);
5262   assert( pMain==0 || pMain==sqlite3_vfs_find(0) );
5263 
5264   /* We can find a VFS by its name */
5265   assert( sqlite3_vfs_find("__one")==&one );
5266   assert( sqlite3_vfs_find("__two")==&two );
5267 
5268   /* Calling sqlite_vfs_register with non-zero second parameter changes the
5269   ** default VFS, even if the 1st parameter is an existig VFS that is
5270   ** previously registered as the non-default.
5271   */
5272   sqlite3_vfs_register(&one, 1);
5273   assert( sqlite3_vfs_find("__one")==&one );
5274   assert( sqlite3_vfs_find("__two")==&two );
5275   assert( sqlite3_vfs_find(0)==&one );
5276   sqlite3_vfs_register(&two, 1);
5277   assert( sqlite3_vfs_find("__one")==&one );
5278   assert( sqlite3_vfs_find("__two")==&two );
5279   assert( sqlite3_vfs_find(0)==&two );
5280   if( pMain ){
5281     sqlite3_vfs_register(pMain, 1);
5282     assert( sqlite3_vfs_find("__one")==&one );
5283     assert( sqlite3_vfs_find("__two")==&two );
5284     assert( sqlite3_vfs_find(0)==pMain );
5285   }
5286 
5287   /* Unlink the default VFS.  Repeat until there are no more VFSes
5288   ** registered.
5289   */
5290   for(i=0; i<sizeof(apVfs)/sizeof(apVfs[0]); i++){
5291     apVfs[i] = sqlite3_vfs_find(0);
5292     if( apVfs[i] ){
5293       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
5294       sqlite3_vfs_unregister(apVfs[i]);
5295       assert( 0==sqlite3_vfs_find(apVfs[i]->zName) );
5296     }
5297   }
5298   assert( 0==sqlite3_vfs_find(0) );
5299 
5300   /* Register the main VFS as non-default (will be made default, since
5301   ** it'll be the only one in existence).
5302   */
5303   sqlite3_vfs_register(pMain, 0);
5304   assert( sqlite3_vfs_find(0)==pMain );
5305 
5306   /* Un-register the main VFS again to restore an empty VFS list */
5307   sqlite3_vfs_unregister(pMain);
5308   assert( 0==sqlite3_vfs_find(0) );
5309 
5310   /* Relink all VFSes in reverse order. */
5311   for(i=sizeof(apVfs)/sizeof(apVfs[0])-1; i>=0; i--){
5312     if( apVfs[i] ){
5313       sqlite3_vfs_register(apVfs[i], 1);
5314       assert( apVfs[i]==sqlite3_vfs_find(0) );
5315       assert( apVfs[i]==sqlite3_vfs_find(apVfs[i]->zName) );
5316     }
5317   }
5318 
5319   /* Unregister out sample VFSes. */
5320   sqlite3_vfs_unregister(&one);
5321   sqlite3_vfs_unregister(&two);
5322 
5323   /* Unregistering a VFS that is not currently registered is harmless */
5324   sqlite3_vfs_unregister(&one);
5325   sqlite3_vfs_unregister(&two);
5326   assert( sqlite3_vfs_find("__one")==0 );
5327   assert( sqlite3_vfs_find("__two")==0 );
5328 
5329   /* We should be left with the original default VFS back as the
5330   ** original */
5331   assert( sqlite3_vfs_find(0)==pMain );
5332 
5333   return TCL_OK;
5334 }
5335 
5336 /*
5337 ** tclcmd:   vfs_initfail_test
5338 **
5339 ** This TCL command attempts to vfs_find and vfs_register when the
5340 ** sqlite3_initialize() interface is failing.  All calls should fail.
5341 */
5342 static int vfs_initfail_test(
5343   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5344   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5345   int objc,              /* Number of arguments */
5346   Tcl_Obj *CONST objv[]  /* Command arguments */
5347 ){
5348   sqlite3_vfs one;
5349   one.zName = "__one";
5350 
5351   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
5352   sqlite3_vfs_register(&one, 0);
5353   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
5354   sqlite3_vfs_register(&one, 1);
5355   if( sqlite3_vfs_find(0) ) return TCL_ERROR;
5356   return TCL_OK;
5357 }
5358 
5359 /*
5360 ** Saved VFSes
5361 */
5362 static sqlite3_vfs *apVfs[20];
5363 static int nVfs = 0;
5364 
5365 /*
5366 ** tclcmd:   vfs_unregister_all
5367 **
5368 ** Unregister all VFSes.
5369 */
5370 static int vfs_unregister_all(
5371   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5372   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5373   int objc,              /* Number of arguments */
5374   Tcl_Obj *CONST objv[]  /* Command arguments */
5375 ){
5376   int i;
5377   for(i=0; i<ArraySize(apVfs); i++){
5378     apVfs[i] = sqlite3_vfs_find(0);
5379     if( apVfs[i]==0 ) break;
5380     sqlite3_vfs_unregister(apVfs[i]);
5381   }
5382   nVfs = i;
5383   return TCL_OK;
5384 }
5385 /*
5386 ** tclcmd:   vfs_reregister_all
5387 **
5388 ** Restore all VFSes that were removed using vfs_unregister_all. Taking
5389 ** care to put the linked list back together in the same order as it was
5390 ** in before vfs_unregister_all was invoked.
5391 */
5392 static int vfs_reregister_all(
5393   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5394   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5395   int objc,              /* Number of arguments */
5396   Tcl_Obj *CONST objv[]  /* Command arguments */
5397 ){
5398   int i;
5399   for(i=nVfs-1; i>=0; i--){
5400     sqlite3_vfs_register(apVfs[i], 1);
5401   }
5402   return TCL_OK;
5403 }
5404 
5405 
5406 /*
5407 ** tclcmd:   file_control_test DB
5408 **
5409 ** This TCL command runs the sqlite3_file_control interface and
5410 ** verifies correct operation of the same.
5411 */
5412 static int file_control_test(
5413   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5414   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5415   int objc,              /* Number of arguments */
5416   Tcl_Obj *CONST objv[]  /* Command arguments */
5417 ){
5418   int iArg = 0;
5419   sqlite3 *db;
5420   int rc;
5421 
5422   if( objc!=2 ){
5423     Tcl_AppendResult(interp, "wrong # args: should be \"",
5424         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5425     return TCL_ERROR;
5426   }
5427   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5428   rc = sqlite3_file_control(db, 0, 0, &iArg);
5429   assert( rc==SQLITE_NOTFOUND );
5430   rc = sqlite3_file_control(db, "notadatabase", SQLITE_FCNTL_LOCKSTATE, &iArg);
5431   assert( rc==SQLITE_ERROR );
5432   rc = sqlite3_file_control(db, "main", -1, &iArg);
5433   assert( rc==SQLITE_NOTFOUND );
5434   rc = sqlite3_file_control(db, "temp", -1, &iArg);
5435   assert( rc==SQLITE_NOTFOUND || rc==SQLITE_ERROR );
5436 
5437   return TCL_OK;
5438 }
5439 
5440 
5441 /*
5442 ** tclcmd:   file_control_lasterrno_test DB
5443 **
5444 ** This TCL command runs the sqlite3_file_control interface and
5445 ** verifies correct operation of the SQLITE_LAST_ERRNO verb.
5446 */
5447 static int file_control_lasterrno_test(
5448   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5449   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5450   int objc,              /* Number of arguments */
5451   Tcl_Obj *CONST objv[]  /* Command arguments */
5452 ){
5453   int iArg = 0;
5454   sqlite3 *db;
5455   int rc;
5456 
5457   if( objc!=2 ){
5458     Tcl_AppendResult(interp, "wrong # args: should be \"",
5459         Tcl_GetStringFromObj(objv[0], 0), " DB", 0);
5460     return TCL_ERROR;
5461   }
5462   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5463     return TCL_ERROR;
5464   }
5465   rc = sqlite3_file_control(db, NULL, SQLITE_LAST_ERRNO, &iArg);
5466   if( rc ){
5467     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5468     return TCL_ERROR;
5469   }
5470   if( iArg!=0 ) {
5471     Tcl_AppendResult(interp, "Unexpected non-zero errno: ",
5472                      Tcl_GetStringFromObj(Tcl_NewIntObj(iArg), 0), " ", 0);
5473     return TCL_ERROR;
5474   }
5475   return TCL_OK;
5476 }
5477 
5478 /*
5479 ** tclcmd:   file_control_chunksize_test DB DBNAME SIZE
5480 **
5481 ** This TCL command runs the sqlite3_file_control interface and
5482 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
5483 ** SQLITE_SET_LOCKPROXYFILE verbs.
5484 */
5485 static int file_control_chunksize_test(
5486   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5487   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5488   int objc,              /* Number of arguments */
5489   Tcl_Obj *CONST objv[]  /* Command arguments */
5490 ){
5491   int nSize;                      /* New chunk size */
5492   char *zDb;                      /* Db name ("main", "temp" etc.) */
5493   sqlite3 *db;                    /* Database handle */
5494   int rc;                         /* file_control() return code */
5495 
5496   if( objc!=4 ){
5497     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
5498     return TCL_ERROR;
5499   }
5500   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
5501    || Tcl_GetIntFromObj(interp, objv[3], &nSize)
5502   ){
5503    return TCL_ERROR;
5504   }
5505   zDb = Tcl_GetString(objv[2]);
5506   if( zDb[0]=='\0' ) zDb = NULL;
5507 
5508   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_CHUNK_SIZE, (void *)&nSize);
5509   if( rc ){
5510     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
5511     return TCL_ERROR;
5512   }
5513   return TCL_OK;
5514 }
5515 
5516 /*
5517 ** tclcmd:   file_control_sizehint_test DB DBNAME SIZE
5518 **
5519 ** This TCL command runs the sqlite3_file_control interface
5520 ** with SQLITE_FCNTL_SIZE_HINT
5521 */
5522 static int file_control_sizehint_test(
5523   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5524   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5525   int objc,              /* Number of arguments */
5526   Tcl_Obj *CONST objv[]  /* Command arguments */
5527 ){
5528   Tcl_WideInt nSize;              /* Hinted size */
5529   char *zDb;                      /* Db name ("main", "temp" etc.) */
5530   sqlite3 *db;                    /* Database handle */
5531   int rc;                         /* file_control() return code */
5532 
5533   if( objc!=4 ){
5534     Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SIZE");
5535     return TCL_ERROR;
5536   }
5537   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
5538    || Tcl_GetWideIntFromObj(interp, objv[3], &nSize)
5539   ){
5540    return TCL_ERROR;
5541   }
5542   zDb = Tcl_GetString(objv[2]);
5543   if( zDb[0]=='\0' ) zDb = NULL;
5544 
5545   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_SIZE_HINT, (void *)&nSize);
5546   if( rc ){
5547     Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
5548     return TCL_ERROR;
5549   }
5550   return TCL_OK;
5551 }
5552 
5553 /*
5554 ** tclcmd:   file_control_lockproxy_test DB PWD
5555 **
5556 ** This TCL command runs the sqlite3_file_control interface and
5557 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
5558 ** SQLITE_SET_LOCKPROXYFILE verbs.
5559 */
5560 static int file_control_lockproxy_test(
5561   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5562   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5563   int objc,              /* Number of arguments */
5564   Tcl_Obj *CONST objv[]  /* Command arguments */
5565 ){
5566   sqlite3 *db;
5567 
5568   if( objc!=3 ){
5569     Tcl_AppendResult(interp, "wrong # args: should be \"",
5570                      Tcl_GetStringFromObj(objv[0], 0), " DB PWD", 0);
5571     return TCL_ERROR;
5572   }
5573   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5574    return TCL_ERROR;
5575   }
5576 
5577 #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
5578 #  if defined(__APPLE__)
5579 #    define SQLITE_ENABLE_LOCKING_STYLE 1
5580 #  else
5581 #    define SQLITE_ENABLE_LOCKING_STYLE 0
5582 #  endif
5583 #endif
5584 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
5585   {
5586     char *testPath;
5587     int rc;
5588     int nPwd;
5589     const char *zPwd;
5590     char proxyPath[400];
5591 
5592     zPwd = Tcl_GetStringFromObj(objv[2], &nPwd);
5593     if( sizeof(proxyPath)<nPwd+20 ){
5594       Tcl_AppendResult(interp, "PWD too big", (void*)0);
5595       return TCL_ERROR;
5596     }
5597     sqlite3_snprintf(sizeof(proxyPath), proxyPath, "%s/test.proxy", zPwd);
5598     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
5599     if( rc ){
5600       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5601       return TCL_ERROR;
5602     }
5603     rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath);
5604     if( strncmp(proxyPath,testPath,11) ){
5605       Tcl_AppendResult(interp, "Lock proxy file did not match the "
5606                                "previously assigned value", 0);
5607       return TCL_ERROR;
5608     }
5609     if( rc ){
5610       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5611       return TCL_ERROR;
5612     }
5613     rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath);
5614     if( rc ){
5615       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5616       return TCL_ERROR;
5617     }
5618   }
5619 #endif
5620   return TCL_OK;
5621 }
5622 
5623 #if SQLITE_OS_WIN
5624 /*
5625 ** tclcmd:   file_control_win32_av_retry DB  NRETRY  DELAY
5626 **
5627 ** This TCL command runs the sqlite3_file_control interface with
5628 ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
5629 */
5630 static int file_control_win32_av_retry(
5631   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5632   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5633   int objc,              /* Number of arguments */
5634   Tcl_Obj *CONST objv[]  /* Command arguments */
5635 ){
5636   sqlite3 *db;
5637   int rc;
5638   int a[2];
5639   char z[100];
5640 
5641   if( objc!=4 ){
5642     Tcl_AppendResult(interp, "wrong # args: should be \"",
5643         Tcl_GetStringFromObj(objv[0], 0), " DB NRETRY DELAY", 0);
5644     return TCL_ERROR;
5645   }
5646   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5647     return TCL_ERROR;
5648   }
5649   if( Tcl_GetIntFromObj(interp, objv[2], &a[0]) ) return TCL_ERROR;
5650   if( Tcl_GetIntFromObj(interp, objv[3], &a[1]) ) return TCL_ERROR;
5651   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_AV_RETRY, (void*)a);
5652   sqlite3_snprintf(sizeof(z), z, "%d %d %d", rc, a[0], a[1]);
5653   Tcl_AppendResult(interp, z, (char*)0);
5654   return TCL_OK;
5655 }
5656 
5657 /*
5658 ** tclcmd:   file_control_win32_set_handle DB HANDLE
5659 **
5660 ** This TCL command runs the sqlite3_file_control interface with
5661 ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
5662 */
5663 static int file_control_win32_set_handle(
5664   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5665   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5666   int objc,              /* Number of arguments */
5667   Tcl_Obj *CONST objv[]  /* Command arguments */
5668 ){
5669   sqlite3 *db;
5670   int rc;
5671   HANDLE hFile = NULL;
5672   char z[100];
5673 
5674   if( objc!=3 ){
5675     Tcl_AppendResult(interp, "wrong # args: should be \"",
5676         Tcl_GetStringFromObj(objv[0], 0), " DB HANDLE", 0);
5677     return TCL_ERROR;
5678   }
5679   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5680     return TCL_ERROR;
5681   }
5682   if( getWin32Handle(interp, Tcl_GetString(objv[2]), &hFile) ){
5683     return TCL_ERROR;
5684   }
5685   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_WIN32_SET_HANDLE,
5686                             (void*)&hFile);
5687   sqlite3_snprintf(sizeof(z), z, "%d %p", rc, (void*)hFile);
5688   Tcl_AppendResult(interp, z, (char*)0);
5689   return TCL_OK;
5690 }
5691 #endif
5692 
5693 /*
5694 ** tclcmd:   file_control_persist_wal DB PERSIST-FLAG
5695 **
5696 ** This TCL command runs the sqlite3_file_control interface with
5697 ** the SQLITE_FCNTL_PERSIST_WAL opcode.
5698 */
5699 static int file_control_persist_wal(
5700   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5701   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5702   int objc,              /* Number of arguments */
5703   Tcl_Obj *CONST objv[]  /* Command arguments */
5704 ){
5705   sqlite3 *db;
5706   int rc;
5707   int bPersist;
5708   char z[100];
5709 
5710   if( objc!=3 ){
5711     Tcl_AppendResult(interp, "wrong # args: should be \"",
5712         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
5713     return TCL_ERROR;
5714   }
5715   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5716     return TCL_ERROR;
5717   }
5718   if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR;
5719   rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
5720   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
5721   Tcl_AppendResult(interp, z, (char*)0);
5722   return TCL_OK;
5723 }
5724 
5725 /*
5726 ** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
5727 **
5728 ** This TCL command runs the sqlite3_file_control interface with
5729 ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
5730 */
5731 static int file_control_powersafe_overwrite(
5732   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5733   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5734   int objc,              /* Number of arguments */
5735   Tcl_Obj *CONST objv[]  /* Command arguments */
5736 ){
5737   sqlite3 *db;
5738   int rc;
5739   int b;
5740   char z[100];
5741 
5742   if( objc!=3 ){
5743     Tcl_AppendResult(interp, "wrong # args: should be \"",
5744         Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
5745     return TCL_ERROR;
5746   }
5747   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5748     return TCL_ERROR;
5749   }
5750   if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
5751   rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b);
5752   sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b);
5753   Tcl_AppendResult(interp, z, (char*)0);
5754   return TCL_OK;
5755 }
5756 
5757 
5758 /*
5759 ** tclcmd:   file_control_vfsname DB ?AUXDB?
5760 **
5761 ** Return a string that describes the stack of VFSes.
5762 */
5763 static int file_control_vfsname(
5764   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5765   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5766   int objc,              /* Number of arguments */
5767   Tcl_Obj *CONST objv[]  /* Command arguments */
5768 ){
5769   sqlite3 *db;
5770   const char *zDbName = "main";
5771   char *zVfsName = 0;
5772 
5773   if( objc!=2 && objc!=3 ){
5774     Tcl_AppendResult(interp, "wrong # args: should be \"",
5775         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
5776     return TCL_ERROR;
5777   }
5778   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5779     return TCL_ERROR;
5780   }
5781   if( objc==3 ){
5782     zDbName = Tcl_GetString(objv[2]);
5783   }
5784   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
5785   Tcl_AppendResult(interp, zVfsName, (char*)0);
5786   sqlite3_free(zVfsName);
5787   return TCL_OK;
5788 }
5789 
5790 /*
5791 ** tclcmd:   file_control_tempfilename DB ?AUXDB?
5792 **
5793 ** Return a string that is a temporary filename
5794 */
5795 static int file_control_tempfilename(
5796   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5797   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5798   int objc,              /* Number of arguments */
5799   Tcl_Obj *CONST objv[]  /* Command arguments */
5800 ){
5801   sqlite3 *db;
5802   const char *zDbName = "main";
5803   char *zTName = 0;
5804 
5805   if( objc!=2 && objc!=3 ){
5806     Tcl_AppendResult(interp, "wrong # args: should be \"",
5807         Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
5808     return TCL_ERROR;
5809   }
5810   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
5811     return TCL_ERROR;
5812   }
5813   if( objc==3 ){
5814     zDbName = Tcl_GetString(objv[2]);
5815   }
5816   sqlite3_file_control(db, zDbName, SQLITE_FCNTL_TEMPFILENAME, (void*)&zTName);
5817   Tcl_AppendResult(interp, zTName, (char*)0);
5818   sqlite3_free(zTName);
5819   return TCL_OK;
5820 }
5821 
5822 
5823 /*
5824 ** tclcmd:   sqlite3_vfs_list
5825 **
5826 **   Return a tcl list containing the names of all registered vfs's.
5827 */
5828 static int vfs_list(
5829   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5830   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5831   int objc,              /* Number of arguments */
5832   Tcl_Obj *CONST objv[]  /* Command arguments */
5833 ){
5834   sqlite3_vfs *pVfs;
5835   Tcl_Obj *pRet = Tcl_NewObj();
5836   if( objc!=1 ){
5837     Tcl_WrongNumArgs(interp, 1, objv, "");
5838     return TCL_ERROR;
5839   }
5840   for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
5841     Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(pVfs->zName, -1));
5842   }
5843   Tcl_SetObjResult(interp, pRet);
5844   return TCL_OK;
5845 }
5846 
5847 /*
5848 ** tclcmd:   sqlite3_limit DB ID VALUE
5849 **
5850 ** This TCL command runs the sqlite3_limit interface and
5851 ** verifies correct operation of the same.
5852 */
5853 static int test_limit(
5854   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5855   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5856   int objc,              /* Number of arguments */
5857   Tcl_Obj *CONST objv[]  /* Command arguments */
5858 ){
5859   sqlite3 *db;
5860   int rc;
5861   static const struct {
5862      char *zName;
5863      int id;
5864   } aId[] = {
5865     { "SQLITE_LIMIT_LENGTH",              SQLITE_LIMIT_LENGTH               },
5866     { "SQLITE_LIMIT_SQL_LENGTH",          SQLITE_LIMIT_SQL_LENGTH           },
5867     { "SQLITE_LIMIT_COLUMN",              SQLITE_LIMIT_COLUMN               },
5868     { "SQLITE_LIMIT_EXPR_DEPTH",          SQLITE_LIMIT_EXPR_DEPTH           },
5869     { "SQLITE_LIMIT_COMPOUND_SELECT",     SQLITE_LIMIT_COMPOUND_SELECT      },
5870     { "SQLITE_LIMIT_VDBE_OP",             SQLITE_LIMIT_VDBE_OP              },
5871     { "SQLITE_LIMIT_FUNCTION_ARG",        SQLITE_LIMIT_FUNCTION_ARG         },
5872     { "SQLITE_LIMIT_ATTACHED",            SQLITE_LIMIT_ATTACHED             },
5873     { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH  },
5874     { "SQLITE_LIMIT_VARIABLE_NUMBER",     SQLITE_LIMIT_VARIABLE_NUMBER      },
5875     { "SQLITE_LIMIT_TRIGGER_DEPTH",       SQLITE_LIMIT_TRIGGER_DEPTH        },
5876     { "SQLITE_LIMIT_WORKER_THREADS",      SQLITE_LIMIT_WORKER_THREADS       },
5877 
5878     /* Out of range test cases */
5879     { "SQLITE_LIMIT_TOOSMALL",            -1,                               },
5880     { "SQLITE_LIMIT_TOOBIG",              SQLITE_LIMIT_WORKER_THREADS+1     },
5881   };
5882   int i, id = 0;
5883   int val;
5884   const char *zId;
5885 
5886   if( objc!=4 ){
5887     Tcl_AppendResult(interp, "wrong # args: should be \"",
5888         Tcl_GetStringFromObj(objv[0], 0), " DB ID VALUE", 0);
5889     return TCL_ERROR;
5890   }
5891   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
5892   zId = Tcl_GetString(objv[2]);
5893   for(i=0; i<sizeof(aId)/sizeof(aId[0]); i++){
5894     if( strcmp(zId, aId[i].zName)==0 ){
5895       id = aId[i].id;
5896       break;
5897     }
5898   }
5899   if( i>=sizeof(aId)/sizeof(aId[0]) ){
5900     Tcl_AppendResult(interp, "unknown limit type: ", zId, (char*)0);
5901     return TCL_ERROR;
5902   }
5903   if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
5904   rc = sqlite3_limit(db, id, val);
5905   Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5906   return TCL_OK;
5907 }
5908 
5909 /*
5910 ** tclcmd:  save_prng_state
5911 **
5912 ** Save the state of the pseudo-random number generator.
5913 ** At the same time, verify that sqlite3_test_control works even when
5914 ** called with an out-of-range opcode.
5915 */
5916 static int save_prng_state(
5917   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5918   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5919   int objc,              /* Number of arguments */
5920   Tcl_Obj *CONST objv[]  /* Command arguments */
5921 ){
5922   int rc = sqlite3_test_control(9999);
5923   assert( rc==0 );
5924   rc = sqlite3_test_control(-1);
5925   assert( rc==0 );
5926   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE);
5927   return TCL_OK;
5928 }
5929 /*
5930 ** tclcmd:  restore_prng_state
5931 */
5932 static int restore_prng_state(
5933   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5934   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5935   int objc,              /* Number of arguments */
5936   Tcl_Obj *CONST objv[]  /* Command arguments */
5937 ){
5938   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE);
5939   return TCL_OK;
5940 }
5941 /*
5942 ** tclcmd:  reset_prng_state
5943 */
5944 static int reset_prng_state(
5945   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5946   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5947   int objc,              /* Number of arguments */
5948   Tcl_Obj *CONST objv[]  /* Command arguments */
5949 ){
5950   sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
5951   return TCL_OK;
5952 }
5953 
5954 /*
5955 ** tclcmd:  database_may_be_corrupt
5956 **
5957 ** Indicate that database files might be corrupt.  In other words, set the normal
5958 ** state of operation.
5959 */
5960 static int database_may_be_corrupt(
5961   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5962   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5963   int objc,              /* Number of arguments */
5964   Tcl_Obj *CONST objv[]  /* Command arguments */
5965 ){
5966   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 0);
5967   return TCL_OK;
5968 }
5969 /*
5970 ** tclcmd:  database_never_corrupt
5971 **
5972 ** Indicate that database files are always well-formed.  This enables extra assert()
5973 ** statements that test conditions that are always true for well-formed databases.
5974 */
5975 static int database_never_corrupt(
5976   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5977   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5978   int objc,              /* Number of arguments */
5979   Tcl_Obj *CONST objv[]  /* Command arguments */
5980 ){
5981   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, 1);
5982   return TCL_OK;
5983 }
5984 
5985 /*
5986 ** tclcmd:  pcache_stats
5987 */
5988 static int test_pcache_stats(
5989   ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
5990   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5991   int objc,              /* Number of arguments */
5992   Tcl_Obj *CONST objv[]  /* Command arguments */
5993 ){
5994   int nMin;
5995   int nMax;
5996   int nCurrent;
5997   int nRecyclable;
5998   Tcl_Obj *pRet;
5999 
6000   sqlite3PcacheStats(&nCurrent, &nMax, &nMin, &nRecyclable);
6001 
6002   pRet = Tcl_NewObj();
6003   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("current", -1));
6004   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCurrent));
6005   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("max", -1));
6006   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMax));
6007   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("min", -1));
6008   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nMin));
6009   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj("recyclable", -1));
6010   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nRecyclable));
6011 
6012   Tcl_SetObjResult(interp, pRet);
6013 
6014   return TCL_OK;
6015 }
6016 
6017 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6018 static void test_unlock_notify_cb(void **aArg, int nArg){
6019   int ii;
6020   for(ii=0; ii<nArg; ii++){
6021     Tcl_EvalEx((Tcl_Interp *)aArg[ii], "unlock_notify", -1, TCL_EVAL_GLOBAL);
6022   }
6023 }
6024 #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
6025 
6026 /*
6027 ** tclcmd:  sqlite3_unlock_notify db
6028 */
6029 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
6030 static int test_unlock_notify(
6031   ClientData clientData, /* Unused */
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 *db;
6037   int rc;
6038 
6039   if( objc!=2 ){
6040     Tcl_WrongNumArgs(interp, 1, objv, "DB");
6041     return TCL_ERROR;
6042   }
6043 
6044   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6045     return TCL_ERROR;
6046   }
6047   rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void *)interp);
6048   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6049   return TCL_OK;
6050 }
6051 #endif
6052 
6053 /*
6054 ** tclcmd:  sqlite3_wal_checkpoint db ?NAME?
6055 */
6056 static int test_wal_checkpoint(
6057   ClientData clientData, /* Unused */
6058   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6059   int objc,              /* Number of arguments */
6060   Tcl_Obj *CONST objv[]  /* Command arguments */
6061 ){
6062   char *zDb = 0;
6063   sqlite3 *db;
6064   int rc;
6065 
6066   if( objc!=3 && objc!=2 ){
6067     Tcl_WrongNumArgs(interp, 1, objv, "DB ?NAME?");
6068     return TCL_ERROR;
6069   }
6070 
6071   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6072     return TCL_ERROR;
6073   }
6074   if( objc==3 ){
6075     zDb = Tcl_GetString(objv[2]);
6076   }
6077   rc = sqlite3_wal_checkpoint(db, zDb);
6078   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6079   return TCL_OK;
6080 }
6081 
6082 /*
6083 ** tclcmd:  sqlite3_wal_checkpoint_v2 db MODE ?NAME?
6084 **
6085 ** This command calls the wal_checkpoint_v2() function with the specified
6086 ** mode argument (passive, full or restart). If present, the database name
6087 ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
6088 ** NAME argument is not present, a NULL pointer is passed instead.
6089 **
6090 ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
6091 ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
6092 ** to the error message obtained from sqlite3_errmsg().
6093 **
6094 ** Otherwise, this command returns a list of three integers. The first integer
6095 ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
6096 ** are the values returned via the output parameters by wal_checkpoint_v2() -
6097 ** the number of frames in the log and the number of frames in the log
6098 ** that have been checkpointed.
6099 */
6100 static int test_wal_checkpoint_v2(
6101   ClientData clientData, /* Unused */
6102   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6103   int objc,              /* Number of arguments */
6104   Tcl_Obj *CONST objv[]  /* Command arguments */
6105 ){
6106   char *zDb = 0;
6107   sqlite3 *db;
6108   int rc;
6109 
6110   int eMode;
6111   int nLog = -555;
6112   int nCkpt = -555;
6113   Tcl_Obj *pRet;
6114 
6115   const char * aMode[] = { "passive", "full", "restart", "truncate", 0 };
6116   assert( SQLITE_CHECKPOINT_PASSIVE==0 );
6117   assert( SQLITE_CHECKPOINT_FULL==1 );
6118   assert( SQLITE_CHECKPOINT_RESTART==2 );
6119   assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
6120 
6121   if( objc!=3 && objc!=4 ){
6122     Tcl_WrongNumArgs(interp, 1, objv, "DB MODE ?NAME?");
6123     return TCL_ERROR;
6124   }
6125 
6126   if( objc==4 ){
6127     zDb = Tcl_GetString(objv[3]);
6128   }
6129   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) || (
6130       TCL_OK!=Tcl_GetIntFromObj(0, objv[2], &eMode)
6131    && TCL_OK!=Tcl_GetIndexFromObj(interp, objv[2], aMode, "mode", 0, &eMode)
6132   )){
6133     return TCL_ERROR;
6134   }
6135 
6136   rc = sqlite3_wal_checkpoint_v2(db, zDb, eMode, &nLog, &nCkpt);
6137   if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
6138     const char *zErrCode = sqlite3ErrName(rc);
6139     Tcl_ResetResult(interp);
6140     Tcl_AppendResult(interp, zErrCode, " - ", (char *)sqlite3_errmsg(db), 0);
6141     return TCL_ERROR;
6142   }
6143 
6144   pRet = Tcl_NewObj();
6145   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(rc==SQLITE_BUSY?1:0));
6146   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nLog));
6147   Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(nCkpt));
6148   Tcl_SetObjResult(interp, pRet);
6149 
6150   return TCL_OK;
6151 }
6152 
6153 /*
6154 ** tclcmd:  sqlite3_wal_autocheckpoint db VALUE
6155 */
6156 static int test_wal_autocheckpoint(
6157   ClientData clientData, /* Unused */
6158   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6159   int objc,              /* Number of arguments */
6160   Tcl_Obj *CONST objv[]  /* Command arguments */
6161 ){
6162   sqlite3 *db;
6163   int rc;
6164   int iVal;
6165 
6166 
6167   if( objc!=3 ){
6168     Tcl_WrongNumArgs(interp, 1, objv, "DB VALUE");
6169     return TCL_ERROR;
6170   }
6171 
6172   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db)
6173    || Tcl_GetIntFromObj(0, objv[2], &iVal)
6174   ){
6175     return TCL_ERROR;
6176   }
6177 
6178   rc = sqlite3_wal_autocheckpoint(db, iVal);
6179   Tcl_ResetResult(interp);
6180   if( rc!=SQLITE_OK ){
6181     const char *zErrCode = sqlite3ErrName(rc);
6182     Tcl_SetObjResult(interp, Tcl_NewStringObj(zErrCode, -1));
6183     return TCL_ERROR;
6184   }
6185 
6186   return TCL_OK;
6187 }
6188 
6189 
6190 /*
6191 ** tclcmd:  test_sqlite3_log ?SCRIPT?
6192 */
6193 static struct LogCallback {
6194   Tcl_Interp *pInterp;
6195   Tcl_Obj *pObj;
6196 } logcallback = {0, 0};
6197 static void xLogcallback(void *unused, int err, char *zMsg){
6198   Tcl_Obj *pNew = Tcl_DuplicateObj(logcallback.pObj);
6199   Tcl_IncrRefCount(pNew);
6200   Tcl_ListObjAppendElement(
6201       0, pNew, Tcl_NewStringObj(sqlite3ErrName(err), -1)
6202   );
6203   Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zMsg, -1));
6204   Tcl_EvalObjEx(logcallback.pInterp, pNew, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
6205   Tcl_DecrRefCount(pNew);
6206 }
6207 static int test_sqlite3_log(
6208   ClientData clientData,
6209   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6210   int objc,              /* Number of arguments */
6211   Tcl_Obj *CONST objv[]  /* Command arguments */
6212 ){
6213   if( objc>2 ){
6214     Tcl_WrongNumArgs(interp, 1, objv, "SCRIPT");
6215     return TCL_ERROR;
6216   }
6217   if( logcallback.pObj ){
6218     Tcl_DecrRefCount(logcallback.pObj);
6219     logcallback.pObj = 0;
6220     logcallback.pInterp = 0;
6221     sqlite3_config(SQLITE_CONFIG_LOG, (void*)0, (void*)0);
6222   }
6223   if( objc>1 ){
6224     logcallback.pObj = objv[1];
6225     Tcl_IncrRefCount(logcallback.pObj);
6226     logcallback.pInterp = interp;
6227     sqlite3_config(SQLITE_CONFIG_LOG, xLogcallback, (void*)0);
6228   }
6229   return TCL_OK;
6230 }
6231 
6232 /*
6233 **     tcl_objproc COMMANDNAME ARGS...
6234 **
6235 ** Run a TCL command using its objProc interface.  Throw an error if
6236 ** the command has no objProc interface.
6237 */
6238 static int runAsObjProc(
6239   void * clientData,
6240   Tcl_Interp *interp,
6241   int objc,
6242   Tcl_Obj *CONST objv[]
6243 ){
6244   Tcl_CmdInfo cmdInfo;
6245   if( objc<2 ){
6246     Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ...");
6247     return TCL_ERROR;
6248   }
6249   if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
6250     Tcl_AppendResult(interp, "command not found: ",
6251            Tcl_GetString(objv[1]), (char*)0);
6252     return TCL_ERROR;
6253   }
6254   if( cmdInfo.objProc==0 ){
6255     Tcl_AppendResult(interp, "command has no objProc: ",
6256            Tcl_GetString(objv[1]), (char*)0);
6257     return TCL_ERROR;
6258   }
6259   return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1);
6260 }
6261 
6262 #ifndef SQLITE_OMIT_EXPLAIN
6263 /*
6264 ** WARNING: The following function, printExplainQueryPlan() is an exact
6265 ** copy of example code from eqp.in (eqp.html). If this code is modified,
6266 ** then the documentation copy needs to be modified as well.
6267 */
6268 /*
6269 ** Argument pStmt is a prepared SQL statement. This function compiles
6270 ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
6271 ** and prints the report to stdout using printf().
6272 */
6273 int printExplainQueryPlan(sqlite3_stmt *pStmt){
6274   const char *zSql;               /* Input SQL */
6275   char *zExplain;                 /* SQL with EXPLAIN QUERY PLAN prepended */
6276   sqlite3_stmt *pExplain;         /* Compiled EXPLAIN QUERY PLAN command */
6277   int rc;                         /* Return code from sqlite3_prepare_v2() */
6278 
6279   zSql = sqlite3_sql(pStmt);
6280   if( zSql==0 ) return SQLITE_ERROR;
6281 
6282   zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
6283   if( zExplain==0 ) return SQLITE_NOMEM;
6284 
6285   rc = sqlite3_prepare_v2(sqlite3_db_handle(pStmt), zExplain, -1, &pExplain, 0);
6286   sqlite3_free(zExplain);
6287   if( rc!=SQLITE_OK ) return rc;
6288 
6289   while( SQLITE_ROW==sqlite3_step(pExplain) ){
6290     int iSelectid = sqlite3_column_int(pExplain, 0);
6291     int iOrder = sqlite3_column_int(pExplain, 1);
6292     int iFrom = sqlite3_column_int(pExplain, 2);
6293     const char *zDetail = (const char *)sqlite3_column_text(pExplain, 3);
6294 
6295     printf("%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail);
6296   }
6297 
6298   return sqlite3_finalize(pExplain);
6299 }
6300 
6301 static int test_print_eqp(
6302   void * clientData,
6303   Tcl_Interp *interp,
6304   int objc,
6305   Tcl_Obj *CONST objv[]
6306 ){
6307   int rc;
6308   sqlite3_stmt *pStmt;
6309 
6310   if( objc!=2 ){
6311     Tcl_WrongNumArgs(interp, 1, objv, "STMT");
6312     return TCL_ERROR;
6313   }
6314   if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
6315   rc = printExplainQueryPlan(pStmt);
6316   /* This is needed on Windows so that a test case using this
6317   ** function can open a read pipe and get the output of
6318   ** printExplainQueryPlan() immediately.
6319   */
6320   fflush(stdout);
6321   Tcl_SetResult(interp, (char *)t1ErrorName(rc), 0);
6322   return TCL_OK;
6323 }
6324 #endif /* SQLITE_OMIT_EXPLAIN */
6325 
6326 /*
6327 ** sqlite3_test_control VERB ARGS...
6328 */
6329 static int test_test_control(
6330   void * clientData,
6331   Tcl_Interp *interp,
6332   int objc,
6333   Tcl_Obj *CONST objv[]
6334 ){
6335   struct Verb {
6336     const char *zName;
6337     int i;
6338   } aVerb[] = {
6339     { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT },
6340     { "SQLITE_TESTCTRL_SORTER_MMAP",     SQLITE_TESTCTRL_SORTER_MMAP     },
6341     { "SQLITE_TESTCTRL_IMPOSTER",        SQLITE_TESTCTRL_IMPOSTER        },
6342   };
6343   int iVerb;
6344   int iFlag;
6345   int rc;
6346 
6347   if( objc<2 ){
6348     Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS...");
6349     return TCL_ERROR;
6350   }
6351 
6352   rc = Tcl_GetIndexFromObjStruct(
6353       interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb
6354   );
6355   if( rc!=TCL_OK ) return rc;
6356 
6357   iFlag = aVerb[iVerb].i;
6358   switch( iFlag ){
6359     case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
6360       int val;
6361       if( objc!=3 ){
6362         Tcl_WrongNumArgs(interp, 2, objv, "ONOFF");
6363         return TCL_ERROR;
6364       }
6365       if( Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
6366       sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, val);
6367       break;
6368     }
6369 
6370     case SQLITE_TESTCTRL_SORTER_MMAP: {
6371       int val;
6372       sqlite3 *db;
6373       if( objc!=4 ){
6374         Tcl_WrongNumArgs(interp, 2, objv, "DB LIMIT");
6375         return TCL_ERROR;
6376       }
6377       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
6378       if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR;
6379       sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val);
6380       break;
6381     }
6382 
6383     case SQLITE_TESTCTRL_IMPOSTER: {
6384       int onOff, tnum;
6385       const char *zDbName;
6386       sqlite3 *db;
6387       if( objc!=6 ){
6388         Tcl_WrongNumArgs(interp, 2, objv, "DB dbName onOff tnum");
6389         return TCL_ERROR;
6390       }
6391       if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR;
6392       zDbName = Tcl_GetString(objv[3]);
6393       if( Tcl_GetIntFromObj(interp, objv[4], &onOff) ) return TCL_ERROR;
6394       if( Tcl_GetIntFromObj(interp, objv[5], &tnum) ) return TCL_ERROR;
6395       sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zDbName, onOff, tnum);
6396       break;
6397     }
6398   }
6399 
6400   Tcl_ResetResult(interp);
6401   return TCL_OK;
6402 }
6403 
6404 #if SQLITE_OS_UNIX
6405 #include <sys/time.h>
6406 #include <sys/resource.h>
6407 
6408 static int test_getrusage(
6409   void * clientData,
6410   Tcl_Interp *interp,
6411   int objc,
6412   Tcl_Obj *CONST objv[]
6413 ){
6414   char buf[1024];
6415   struct rusage r;
6416   memset(&r, 0, sizeof(r));
6417   getrusage(RUSAGE_SELF, &r);
6418 
6419   sqlite3_snprintf(sizeof(buf), buf,
6420     "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
6421     (int)r.ru_utime.tv_sec, (int)r.ru_utime.tv_usec,
6422     (int)r.ru_stime.tv_sec, (int)r.ru_stime.tv_usec,
6423     (int)r.ru_minflt, (int)r.ru_majflt
6424   );
6425   Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
6426   return TCL_OK;
6427 }
6428 #endif
6429 
6430 #if SQLITE_OS_WIN
6431 /*
6432 ** Information passed from the main thread into the windows file locker
6433 ** background thread.
6434 */
6435 struct win32FileLocker {
6436   char *evName;       /* Name of event to signal thread startup */
6437   HANDLE h;           /* Handle of the file to be locked */
6438   int delay1;         /* Delay before locking */
6439   int delay2;         /* Delay before unlocking */
6440   int ok;             /* Finished ok */
6441   int err;            /* True if an error occurs */
6442 };
6443 #endif
6444 
6445 
6446 #if SQLITE_OS_WIN
6447 #include <process.h>
6448 /*
6449 ** The background thread that does file locking.
6450 */
6451 static void SQLITE_CDECL win32_file_locker(void *pAppData){
6452   struct win32FileLocker *p = (struct win32FileLocker*)pAppData;
6453   if( p->evName ){
6454     HANDLE ev = OpenEvent(EVENT_MODIFY_STATE, FALSE, p->evName);
6455     if ( ev ){
6456       SetEvent(ev);
6457       CloseHandle(ev);
6458     }
6459   }
6460   if( p->delay1 ) Sleep(p->delay1);
6461   if( LockFile(p->h, 0, 0, 100000000, 0) ){
6462     Sleep(p->delay2);
6463     UnlockFile(p->h, 0, 0, 100000000, 0);
6464     p->ok = 1;
6465   }else{
6466     p->err = 1;
6467   }
6468   CloseHandle(p->h);
6469   p->h = 0;
6470   p->delay1 = 0;
6471   p->delay2 = 0;
6472 }
6473 #endif
6474 
6475 #if SQLITE_OS_WIN
6476 /*
6477 **      lock_win32_file FILENAME DELAY1 DELAY2
6478 **
6479 ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
6480 ** Wait DELAY1 milliseconds before acquiring the lock.
6481 */
6482 static int win32_file_lock(
6483   void * clientData,
6484   Tcl_Interp *interp,
6485   int objc,
6486   Tcl_Obj *CONST objv[]
6487 ){
6488   static struct win32FileLocker x = { "win32_file_lock", 0, 0, 0, 0, 0 };
6489   const char *zFilename;
6490   char zBuf[200];
6491   int retry = 0;
6492   HANDLE ev;
6493   DWORD wResult;
6494 
6495   if( objc!=4 && objc!=1 ){
6496     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME DELAY1 DELAY2");
6497     return TCL_ERROR;
6498   }
6499   if( objc==1 ){
6500     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d %d %d %d %d",
6501                      x.ok, x.err, x.delay1, x.delay2, x.h);
6502     Tcl_AppendResult(interp, zBuf, (char*)0);
6503     return TCL_OK;
6504   }
6505   while( x.h && retry<30 ){
6506     retry++;
6507     Sleep(100);
6508   }
6509   if( x.h ){
6510     Tcl_AppendResult(interp, "busy", (char*)0);
6511     return TCL_ERROR;
6512   }
6513   if( Tcl_GetIntFromObj(interp, objv[2], &x.delay1) ) return TCL_ERROR;
6514   if( Tcl_GetIntFromObj(interp, objv[3], &x.delay2) ) return TCL_ERROR;
6515   zFilename = Tcl_GetString(objv[1]);
6516   x.h = CreateFile(zFilename, GENERIC_READ|GENERIC_WRITE,
6517               FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_ALWAYS,
6518               FILE_ATTRIBUTE_NORMAL, 0);
6519   if( !x.h ){
6520     Tcl_AppendResult(interp, "cannot open file: ", zFilename, (char*)0);
6521     return TCL_ERROR;
6522   }
6523   ev = CreateEvent(NULL, TRUE, FALSE, x.evName);
6524   if ( !ev ){
6525     Tcl_AppendResult(interp, "cannot create event: ", x.evName, (char*)0);
6526     return TCL_ERROR;
6527   }
6528   _beginthread(win32_file_locker, 0, (void*)&x);
6529   Sleep(0);
6530   if ( (wResult = WaitForSingleObject(ev, 10000))!=WAIT_OBJECT_0 ){
6531     sqlite3_snprintf(sizeof(zBuf), zBuf, "0x%x", wResult);
6532     Tcl_AppendResult(interp, "wait failed: ", zBuf, (char*)0);
6533     CloseHandle(ev);
6534     return TCL_ERROR;
6535   }
6536   CloseHandle(ev);
6537   return TCL_OK;
6538 }
6539 
6540 /*
6541 **      exists_win32_path PATH
6542 **
6543 ** Returns non-zero if the specified path exists, whose fully qualified name
6544 ** may exceed 260 characters if it is prefixed with "\\?\".
6545 */
6546 static int win32_exists_path(
6547   void *clientData,
6548   Tcl_Interp *interp,
6549   int objc,
6550   Tcl_Obj *CONST objv[]
6551 ){
6552   if( objc!=2 ){
6553     Tcl_WrongNumArgs(interp, 1, objv, "PATH");
6554     return TCL_ERROR;
6555   }
6556   Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
6557       GetFileAttributesW( Tcl_GetUnicode(objv[1]))!=INVALID_FILE_ATTRIBUTES ));
6558   return TCL_OK;
6559 }
6560 
6561 /*
6562 **      find_win32_file PATTERN
6563 **
6564 ** Returns a list of entries in a directory that match the specified pattern,
6565 ** whose fully qualified name may exceed 248 characters if it is prefixed with
6566 ** "\\?\".
6567 */
6568 static int win32_find_file(
6569   void *clientData,
6570   Tcl_Interp *interp,
6571   int objc,
6572   Tcl_Obj *CONST objv[]
6573 ){
6574   HANDLE hFindFile = INVALID_HANDLE_VALUE;
6575   WIN32_FIND_DATAW findData;
6576   Tcl_Obj *listObj;
6577   DWORD lastErrno;
6578   if( objc!=2 ){
6579     Tcl_WrongNumArgs(interp, 1, objv, "PATTERN");
6580     return TCL_ERROR;
6581   }
6582   hFindFile = FindFirstFileW(Tcl_GetUnicode(objv[1]), &findData);
6583   if( hFindFile==INVALID_HANDLE_VALUE ){
6584     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6585     return TCL_ERROR;
6586   }
6587   listObj = Tcl_NewObj();
6588   Tcl_IncrRefCount(listObj);
6589   do {
6590     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewUnicodeObj(
6591         findData.cFileName, -1));
6592     Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj(
6593         findData.dwFileAttributes));
6594   } while( FindNextFileW(hFindFile, &findData) );
6595   lastErrno = GetLastError();
6596   if( lastErrno!=NO_ERROR && lastErrno!=ERROR_NO_MORE_FILES ){
6597     FindClose(hFindFile);
6598     Tcl_DecrRefCount(listObj);
6599     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6600     return TCL_ERROR;
6601   }
6602   FindClose(hFindFile);
6603   Tcl_SetObjResult(interp, listObj);
6604   return TCL_OK;
6605 }
6606 
6607 /*
6608 **      delete_win32_file FILENAME
6609 **
6610 ** Deletes the specified file, whose fully qualified name may exceed 260
6611 ** characters if it is prefixed with "\\?\".
6612 */
6613 static int win32_delete_file(
6614   void *clientData,
6615   Tcl_Interp *interp,
6616   int objc,
6617   Tcl_Obj *CONST objv[]
6618 ){
6619   if( objc!=2 ){
6620     Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
6621     return TCL_ERROR;
6622   }
6623   if( !DeleteFileW(Tcl_GetUnicode(objv[1])) ){
6624     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6625     return TCL_ERROR;
6626   }
6627   Tcl_ResetResult(interp);
6628   return TCL_OK;
6629 }
6630 
6631 /*
6632 **      make_win32_dir DIRECTORY
6633 **
6634 ** Creates the specified directory, whose fully qualified name may exceed 248
6635 ** characters if it is prefixed with "\\?\".
6636 */
6637 static int win32_mkdir(
6638   void *clientData,
6639   Tcl_Interp *interp,
6640   int objc,
6641   Tcl_Obj *CONST objv[]
6642 ){
6643   if( objc!=2 ){
6644     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6645     return TCL_ERROR;
6646   }
6647   if( !CreateDirectoryW(Tcl_GetUnicode(objv[1]), NULL) ){
6648     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6649     return TCL_ERROR;
6650   }
6651   Tcl_ResetResult(interp);
6652   return TCL_OK;
6653 }
6654 
6655 /*
6656 **      remove_win32_dir DIRECTORY
6657 **
6658 ** Removes the specified directory, whose fully qualified name may exceed 248
6659 ** characters if it is prefixed with "\\?\".
6660 */
6661 static int win32_rmdir(
6662   void *clientData,
6663   Tcl_Interp *interp,
6664   int objc,
6665   Tcl_Obj *CONST objv[]
6666 ){
6667   if( objc!=2 ){
6668     Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY");
6669     return TCL_ERROR;
6670   }
6671   if( !RemoveDirectoryW(Tcl_GetUnicode(objv[1])) ){
6672     Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError()));
6673     return TCL_ERROR;
6674   }
6675   Tcl_ResetResult(interp);
6676   return TCL_OK;
6677 }
6678 #endif
6679 
6680 
6681 /*
6682 **      optimization_control DB OPT BOOLEAN
6683 **
6684 ** Enable or disable query optimizations using the sqlite3_test_control()
6685 ** interface.  Disable if BOOLEAN is false and enable if BOOLEAN is true.
6686 ** OPT is the name of the optimization to be disabled.
6687 */
6688 static int optimization_control(
6689   void * clientData,
6690   Tcl_Interp *interp,
6691   int objc,
6692   Tcl_Obj *CONST objv[]
6693 ){
6694   int i;
6695   sqlite3 *db;
6696   const char *zOpt;
6697   int onoff;
6698   int mask = 0;
6699   static const struct {
6700     const char *zOptName;
6701     int mask;
6702   } aOpt[] = {
6703     { "all",                 SQLITE_AllOpts        },
6704     { "none",                0                     },
6705     { "query-flattener",     SQLITE_QueryFlattener },
6706     { "column-cache",        SQLITE_ColumnCache    },
6707     { "groupby-order",       SQLITE_GroupByOrder   },
6708     { "factor-constants",    SQLITE_FactorOutConst },
6709     { "distinct-opt",        SQLITE_DistinctOpt    },
6710     { "cover-idx-scan",      SQLITE_CoverIdxScan   },
6711     { "order-by-idx-join",   SQLITE_OrderByIdxJoin },
6712     { "transitive",          SQLITE_Transitive     },
6713     { "subquery-coroutine",  SQLITE_SubqCoroutine  },
6714     { "omit-noop-join",      SQLITE_OmitNoopJoin   },
6715     { "stat3",               SQLITE_Stat34         },
6716     { "stat4",               SQLITE_Stat34         },
6717   };
6718 
6719   if( objc!=4 ){
6720     Tcl_WrongNumArgs(interp, 1, objv, "DB OPT BOOLEAN");
6721     return TCL_ERROR;
6722   }
6723   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6724   if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ) return TCL_ERROR;
6725   zOpt = Tcl_GetString(objv[2]);
6726   for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6727     if( strcmp(zOpt, aOpt[i].zOptName)==0 ){
6728       mask = aOpt[i].mask;
6729       break;
6730     }
6731   }
6732   if( onoff ) mask = ~mask;
6733   if( i>=sizeof(aOpt)/sizeof(aOpt[0]) ){
6734     Tcl_AppendResult(interp, "unknown optimization - should be one of:",
6735                      (char*)0);
6736     for(i=0; i<sizeof(aOpt)/sizeof(aOpt[0]); i++){
6737       Tcl_AppendResult(interp, " ", aOpt[i].zOptName, (char*)0);
6738     }
6739     return TCL_ERROR;
6740   }
6741   sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask);
6742   return TCL_OK;
6743 }
6744 
6745 typedef struct sqlite3_api_routines sqlite3_api_routines;
6746 /*
6747 **     load_static_extension DB NAME ...
6748 **
6749 ** Load one or more statically linked extensions.
6750 */
6751 static int tclLoadStaticExtensionCmd(
6752   void * clientData,
6753   Tcl_Interp *interp,
6754   int objc,
6755   Tcl_Obj *CONST objv[]
6756 ){
6757   extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
6758   extern int sqlite3_carray_init(sqlite3*,char**,const sqlite3_api_routines*);
6759   extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
6760   extern int sqlite3_csv_init(sqlite3*,char**,const sqlite3_api_routines*);
6761   extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
6762   extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
6763   extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
6764   extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
6765   extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
6766   extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
6767   extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
6768   extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*);
6769   extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
6770   extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
6771   extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
6772   static const struct {
6773     const char *zExtName;
6774     int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
6775   } aExtension[] = {
6776     { "amatch",                sqlite3_amatch_init               },
6777     { "carray",                sqlite3_carray_init               },
6778     { "closure",               sqlite3_closure_init              },
6779     { "csv",                   sqlite3_csv_init                  },
6780     { "eval",                  sqlite3_eval_init                 },
6781     { "fileio",                sqlite3_fileio_init               },
6782     { "fuzzer",                sqlite3_fuzzer_init               },
6783     { "ieee754",               sqlite3_ieee_init                 },
6784     { "nextchar",              sqlite3_nextchar_init             },
6785     { "percentile",            sqlite3_percentile_init           },
6786     { "regexp",                sqlite3_regexp_init               },
6787     { "series",                sqlite3_series_init               },
6788     { "spellfix",              sqlite3_spellfix_init             },
6789     { "totype",                sqlite3_totype_init               },
6790     { "wholenumber",           sqlite3_wholenumber_init          },
6791   };
6792   sqlite3 *db;
6793   const char *zName;
6794   int i, j, rc;
6795   char *zErrMsg = 0;
6796   if( objc<3 ){
6797     Tcl_WrongNumArgs(interp, 1, objv, "DB NAME ...");
6798     return TCL_ERROR;
6799   }
6800   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6801   for(j=2; j<objc; j++){
6802     zName = Tcl_GetString(objv[j]);
6803     for(i=0; i<ArraySize(aExtension); i++){
6804       if( strcmp(zName, aExtension[i].zExtName)==0 ) break;
6805     }
6806     if( i>=ArraySize(aExtension) ){
6807       Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0);
6808       return TCL_ERROR;
6809     }
6810     if( aExtension[i].pInit ){
6811       rc = aExtension[i].pInit(db, &zErrMsg, 0);
6812     }else{
6813       rc = SQLITE_OK;
6814     }
6815     if( rc!=SQLITE_OK || zErrMsg ){
6816       Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
6817                        (char*)0);
6818       sqlite3_free(zErrMsg);
6819       return TCL_ERROR;
6820     }
6821   }
6822   return TCL_OK;
6823 }
6824 
6825 /*
6826 **     sorter_test_fakeheap BOOL
6827 **
6828 */
6829 static int sorter_test_fakeheap(
6830   void * clientData,
6831   Tcl_Interp *interp,
6832   int objc,
6833   Tcl_Obj *CONST objv[]
6834 ){
6835   int bArg;
6836   if( objc!=2 ){
6837     Tcl_WrongNumArgs(interp, 1, objv, "BOOL");
6838     return TCL_ERROR;
6839   }
6840 
6841   if( Tcl_GetBooleanFromObj(interp, objv[1], &bArg) ){
6842     return TCL_ERROR;
6843   }
6844 
6845   if( bArg ){
6846     if( sqlite3GlobalConfig.pHeap==0 ){
6847       sqlite3GlobalConfig.pHeap = SQLITE_INT_TO_PTR(-1);
6848     }
6849   }else{
6850     if( sqlite3GlobalConfig.pHeap==SQLITE_INT_TO_PTR(-1) ){
6851       sqlite3GlobalConfig.pHeap = 0;
6852     }
6853   }
6854 
6855   Tcl_ResetResult(interp);
6856   return TCL_OK;
6857 }
6858 
6859 /*
6860 **     sorter_test_sort4_helper DB SQL1 NSTEP SQL2
6861 **
6862 ** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
6863 ** check that the leftmost and rightmost columns returned are both integers,
6864 ** and that both contain the same value.
6865 **
6866 ** Then execute statement $SQL2. Check that the statement returns the same
6867 ** set of integers in the same order as in the previous step (using $SQL1).
6868 */
6869 static int sorter_test_sort4_helper(
6870   void * clientData,
6871   Tcl_Interp *interp,
6872   int objc,
6873   Tcl_Obj *CONST objv[]
6874 ){
6875   const char *zSql1;
6876   const char *zSql2;
6877   int nStep;
6878   int iStep;
6879   unsigned int iCksum1 = 0;
6880   unsigned int iCksum2 = 0;
6881   int rc;
6882   int iB;
6883   sqlite3 *db;
6884   sqlite3_stmt *pStmt;
6885 
6886   if( objc!=5 ){
6887     Tcl_WrongNumArgs(interp, 1, objv, "DB SQL1 NSTEP SQL2");
6888     return TCL_ERROR;
6889   }
6890 
6891   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
6892   zSql1 = Tcl_GetString(objv[2]);
6893   if( Tcl_GetIntFromObj(interp, objv[3], &nStep) ) return TCL_ERROR;
6894   zSql2 = Tcl_GetString(objv[4]);
6895 
6896   rc = sqlite3_prepare_v2(db, zSql1, -1, &pStmt, 0);
6897   if( rc!=SQLITE_OK ) goto sql_error;
6898 
6899   iB = sqlite3_column_count(pStmt)-1;
6900   for(iStep=0; iStep<nStep && SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6901     int a = sqlite3_column_int(pStmt, 0);
6902     if( a!=sqlite3_column_int(pStmt, iB) ){
6903       Tcl_AppendResult(interp, "data error: (a!=b)", 0);
6904       return TCL_ERROR;
6905     }
6906 
6907     iCksum1 += (iCksum1 << 3) + (unsigned int)a;
6908   }
6909   rc = sqlite3_finalize(pStmt);
6910   if( rc!=SQLITE_OK ) goto sql_error;
6911 
6912   rc = sqlite3_prepare_v2(db, zSql2, -1, &pStmt, 0);
6913   if( rc!=SQLITE_OK ) goto sql_error;
6914   for(iStep=0; SQLITE_ROW==sqlite3_step(pStmt); iStep++){
6915     int a = sqlite3_column_int(pStmt, 0);
6916     iCksum2 += (iCksum2 << 3) + (unsigned int)a;
6917   }
6918   rc = sqlite3_finalize(pStmt);
6919   if( rc!=SQLITE_OK ) goto sql_error;
6920 
6921   if( iCksum1!=iCksum2 ){
6922     Tcl_AppendResult(interp, "checksum mismatch", 0);
6923     return TCL_ERROR;
6924   }
6925 
6926   return TCL_OK;
6927  sql_error:
6928   Tcl_AppendResult(interp, "sql error: ", sqlite3_errmsg(db), 0);
6929   return TCL_ERROR;
6930 }
6931 
6932 
6933 #ifdef SQLITE_USER_AUTHENTICATION
6934 #include "sqlite3userauth.h"
6935 /*
6936 ** tclcmd:  sqlite3_user_authenticate DB USERNAME PASSWORD
6937 */
6938 static int test_user_authenticate(
6939   ClientData clientData, /* Unused */
6940   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6941   int objc,              /* Number of arguments */
6942   Tcl_Obj *CONST objv[]  /* Command arguments */
6943 ){
6944   char *zUser = 0;
6945   char *zPasswd = 0;
6946   int nPasswd = 0;
6947   sqlite3 *db;
6948   int rc;
6949 
6950   if( objc!=4 ){
6951     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD");
6952     return TCL_ERROR;
6953   }
6954   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6955     return TCL_ERROR;
6956   }
6957   zUser = Tcl_GetString(objv[2]);
6958   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
6959   rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd);
6960   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6961   return TCL_OK;
6962 }
6963 #endif /* SQLITE_USER_AUTHENTICATION */
6964 
6965 #ifdef SQLITE_USER_AUTHENTICATION
6966 /*
6967 ** tclcmd:  sqlite3_user_add DB USERNAME PASSWORD ISADMIN
6968 */
6969 static int test_user_add(
6970   ClientData clientData, /* Unused */
6971   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6972   int objc,              /* Number of arguments */
6973   Tcl_Obj *CONST objv[]  /* Command arguments */
6974 ){
6975   char *zUser = 0;
6976   char *zPasswd = 0;
6977   int nPasswd = 0;
6978   int isAdmin = 0;
6979   sqlite3 *db;
6980   int rc;
6981 
6982   if( objc!=5 ){
6983     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
6984     return TCL_ERROR;
6985   }
6986   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
6987     return TCL_ERROR;
6988   }
6989   zUser = Tcl_GetString(objv[2]);
6990   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
6991   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
6992   rc = sqlite3_user_add(db, zUser, zPasswd, nPasswd, isAdmin);
6993   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
6994   return TCL_OK;
6995 }
6996 #endif /* SQLITE_USER_AUTHENTICATION */
6997 
6998 #ifdef SQLITE_USER_AUTHENTICATION
6999 /*
7000 ** tclcmd:  sqlite3_user_change DB USERNAME PASSWORD ISADMIN
7001 */
7002 static int test_user_change(
7003   ClientData clientData, /* Unused */
7004   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7005   int objc,              /* Number of arguments */
7006   Tcl_Obj *CONST objv[]  /* Command arguments */
7007 ){
7008   char *zUser = 0;
7009   char *zPasswd = 0;
7010   int nPasswd = 0;
7011   int isAdmin = 0;
7012   sqlite3 *db;
7013   int rc;
7014 
7015   if( objc!=5 ){
7016     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME PASSWORD ISADMIN");
7017     return TCL_ERROR;
7018   }
7019   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
7020     return TCL_ERROR;
7021   }
7022   zUser = Tcl_GetString(objv[2]);
7023   zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd);
7024   Tcl_GetBooleanFromObj(interp, objv[4], &isAdmin);
7025   rc = sqlite3_user_change(db, zUser, zPasswd, nPasswd, isAdmin);
7026   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7027   return TCL_OK;
7028 }
7029 #endif /* SQLITE_USER_AUTHENTICATION */
7030 
7031 #ifdef SQLITE_USER_AUTHENTICATION
7032 /*
7033 ** tclcmd:  sqlite3_user_delete DB USERNAME
7034 */
7035 static int test_user_delete(
7036   ClientData clientData, /* Unused */
7037   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7038   int objc,              /* Number of arguments */
7039   Tcl_Obj *CONST objv[]  /* Command arguments */
7040 ){
7041   char *zUser = 0;
7042   sqlite3 *db;
7043   int rc;
7044 
7045   if( objc!=3 ){
7046     Tcl_WrongNumArgs(interp, 1, objv, "DB USERNAME");
7047     return TCL_ERROR;
7048   }
7049   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
7050     return TCL_ERROR;
7051   }
7052   zUser = Tcl_GetString(objv[2]);
7053   rc = sqlite3_user_delete(db, zUser);
7054   Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
7055   return TCL_OK;
7056 }
7057 #endif /* SQLITE_USER_AUTHENTICATION */
7058 
7059 /*
7060 ** tclcmd: bad_behavior TYPE
7061 **
7062 ** Do some things that should trigger a valgrind or -fsanitize=undefined
7063 ** warning.  This is used to verify that errors and warnings output by those
7064 ** tools are detected by the test scripts.
7065 **
7066 **       TYPE       BEHAVIOR
7067 **       1          Overflow a signed integer
7068 **       2          Jump based on an uninitialized variable
7069 **       3          Read after free
7070 **       4          Panic
7071 */
7072 static int test_bad_behavior(
7073   ClientData clientData, /* Pointer to an integer containing zero */
7074   Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
7075   int objc,              /* Number of arguments */
7076   Tcl_Obj *CONST objv[]  /* Command arguments */
7077 ){
7078   int iType;
7079   int xyz;
7080   int i = *(int*)clientData;
7081   int j;
7082   int w[10];
7083   int *a;
7084   if( objc!=2 ){
7085     Tcl_WrongNumArgs(interp, 1, objv, "TYPE");
7086     return TCL_ERROR;
7087   }
7088   if( Tcl_GetIntFromObj(interp, objv[1], &iType) ) return TCL_ERROR;
7089   switch( iType ){
7090     case 1: {
7091       xyz = 0x7fffff00 - i;
7092       xyz += 0x100;
7093       Tcl_SetObjResult(interp, Tcl_NewIntObj(xyz));
7094       break;
7095     }
7096     case 2: {
7097       w[1] = 5;
7098       if( w[i]>0 ) w[1]++;
7099       Tcl_SetObjResult(interp, Tcl_NewIntObj(w[1]));
7100       break;
7101     }
7102     case 3: {
7103       a = malloc( sizeof(int)*10 );
7104       for(j=0; j<10; j++) a[j] = j;
7105       free(a);
7106       Tcl_SetObjResult(interp, Tcl_NewIntObj(a[i]));
7107       break;
7108     }
7109     case 4: {
7110       Tcl_Panic("Deliberate panic");
7111       break;
7112     }
7113   }
7114   return TCL_OK;
7115 }
7116 
7117 /*
7118 ** tclcmd:   register_dbstat_vtab DB
7119 **
7120 ** Cause the dbstat virtual table to be available on the connection DB
7121 */
7122 static int test_register_dbstat_vtab(
7123   void *clientData,
7124   Tcl_Interp *interp,
7125   int objc,
7126   Tcl_Obj *CONST objv[]
7127 ){
7128 #ifdef SQLITE_OMIT_VIRTUALTABLE
7129   Tcl_AppendResult(interp, "dbstat not available because of "
7130                            "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
7131   return TCL_ERROR;
7132 #else
7133   struct SqliteDb { sqlite3 *db; };
7134   char *zDb;
7135   Tcl_CmdInfo cmdInfo;
7136 
7137   if( objc!=2 ){
7138     Tcl_WrongNumArgs(interp, 1, objv, "DB");
7139     return TCL_ERROR;
7140   }
7141 
7142   zDb = Tcl_GetString(objv[1]);
7143   if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
7144     sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
7145     sqlite3DbstatRegister(db);
7146   }
7147   return TCL_OK;
7148 #endif /* SQLITE_OMIT_VIRTUALTABLE */
7149 }
7150 
7151 /*
7152 ** tclcmd:   sqlite3_db_config DB SETTING VALUE
7153 **
7154 ** Invoke sqlite3_db_config() for one of the setting values.
7155 */
7156 static int test_sqlite3_db_config(
7157   void *clientData,
7158   Tcl_Interp *interp,
7159   int objc,
7160   Tcl_Obj *CONST objv[]
7161 ){
7162   static const struct {
7163     const char *zName;
7164     int eVal;
7165   } aSetting[] = {
7166     { "FKEY",            SQLITE_DBCONFIG_ENABLE_FKEY },
7167     { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
7168     { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
7169     { "LOAD_EXTENSION",  SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION },
7170   };
7171   int i;
7172   int v;
7173   const char *zSetting;
7174   sqlite3 *db;
7175 
7176   if( objc!=4 ){
7177     Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING VALUE");
7178     return TCL_ERROR;
7179   }
7180   if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
7181   zSetting = Tcl_GetString(objv[2]);
7182   if( sqlite3_strglob("SQLITE_*", zSetting)==0 ) zSetting += 7;
7183   if( sqlite3_strglob("DBCONFIG_*", zSetting)==0 ) zSetting += 9;
7184   if( sqlite3_strglob("ENABLE_*", zSetting)==0 ) zSetting += 7;
7185   for(i=0; i<ArraySize(aSetting); i++){
7186     if( strcmp(zSetting, aSetting[i].zName)==0 ) break;
7187   }
7188   if( i>=ArraySize(aSetting) ){
7189     Tcl_SetObjResult(interp,
7190       Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
7191     return TCL_ERROR;
7192   }
7193   if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
7194   sqlite3_db_config(db, aSetting[i].eVal, v, &v);
7195   Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
7196   return TCL_OK;
7197 }
7198 
7199 /*
7200 ** Register commands with the TCL interpreter.
7201 */
7202 int Sqlitetest1_Init(Tcl_Interp *interp){
7203   extern int sqlite3_search_count;
7204   extern int sqlite3_found_count;
7205   extern int sqlite3_interrupt_count;
7206   extern int sqlite3_open_file_count;
7207   extern int sqlite3_sort_count;
7208   extern int sqlite3_current_time;
7209 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
7210   extern int sqlite3_hostid_num;
7211 #endif
7212   extern int sqlite3_max_blobsize;
7213   extern int sqlite3BtreeSharedCacheReport(void*,
7214                                           Tcl_Interp*,int,Tcl_Obj*CONST*);
7215   static int iZero = 0;
7216   static struct {
7217      char *zName;
7218      Tcl_CmdProc *xProc;
7219   } aCmd[] = {
7220      { "db_enter",                      (Tcl_CmdProc*)db_enter               },
7221      { "db_leave",                      (Tcl_CmdProc*)db_leave               },
7222      { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
7223      { "sqlite3_mprintf_int64",         (Tcl_CmdProc*)sqlite3_mprintf_int64  },
7224      { "sqlite3_mprintf_long",          (Tcl_CmdProc*)sqlite3_mprintf_long   },
7225      { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
7226      { "sqlite3_snprintf_str",          (Tcl_CmdProc*)sqlite3_snprintf_str   },
7227      { "sqlite3_mprintf_stronly",       (Tcl_CmdProc*)sqlite3_mprintf_stronly},
7228      { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
7229      { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
7230      { "sqlite3_mprintf_hexdouble",   (Tcl_CmdProc*)sqlite3_mprintf_hexdouble},
7231      { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
7232      { "sqlite3_mprintf_n_test",        (Tcl_CmdProc*)test_mprintf_n        },
7233      { "sqlite3_snprintf_int",          (Tcl_CmdProc*)test_snprintf_int     },
7234      { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
7235      { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
7236      { "sqlite3_exec_hex",              (Tcl_CmdProc*)test_exec_hex         },
7237      { "sqlite3_exec",                  (Tcl_CmdProc*)test_exec             },
7238      { "sqlite3_exec_nr",               (Tcl_CmdProc*)test_exec_nr          },
7239 #ifndef SQLITE_OMIT_GET_TABLE
7240      { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
7241 #endif
7242      { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
7243      { "sqlite3_close_v2",              (Tcl_CmdProc*)sqlite_test_close_v2  },
7244      { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
7245      { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
7246      { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
7247      { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
7248      { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
7249      { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
7250      { "sqlite3_key",                   (Tcl_CmdProc*)test_key              },
7251      { "sqlite3_rekey",                 (Tcl_CmdProc*)test_rekey            },
7252      { "sqlite_set_magic",              (Tcl_CmdProc*)sqlite_set_magic      },
7253      { "sqlite3_interrupt",             (Tcl_CmdProc*)test_interrupt        },
7254      { "sqlite_delete_function",        (Tcl_CmdProc*)delete_function       },
7255      { "sqlite_delete_collation",       (Tcl_CmdProc*)delete_collation      },
7256      { "sqlite3_get_autocommit",        (Tcl_CmdProc*)get_autocommit        },
7257      { "sqlite3_stack_used",            (Tcl_CmdProc*)test_stack_used       },
7258      { "sqlite3_busy_timeout",          (Tcl_CmdProc*)test_busy_timeout     },
7259      { "printf",                        (Tcl_CmdProc*)test_printf           },
7260      { "sqlite3IoTrace",              (Tcl_CmdProc*)test_io_trace         },
7261      { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
7262   };
7263   static struct {
7264      char *zName;
7265      Tcl_ObjCmdProc *xProc;
7266      void *clientData;
7267   } aObjCmd[] = {
7268      { "sqlite3_db_config",             test_sqlite3_db_config, 0 },
7269      { "bad_behavior",                  test_bad_behavior,  (void*)&iZero },
7270      { "register_dbstat_vtab",          test_register_dbstat_vtab  },
7271      { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
7272      { "intarray_addr",                 test_intarray_addr, 0 },
7273      { "int64array_addr",               test_int64array_addr, 0 },
7274      { "doublearray_addr",              test_doublearray_addr, 0 },
7275      { "textarray_addr",                test_textarray_addr, 0 },
7276      { "sqlite3_bind_int",              test_bind_int,      0 },
7277      { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
7278      { "sqlite3_bind_zeroblob64",       test_bind_zeroblob64, 0 },
7279      { "sqlite3_bind_int64",            test_bind_int64,    0 },
7280      { "sqlite3_bind_double",           test_bind_double,   0 },
7281      { "sqlite3_bind_null",             test_bind_null     ,0 },
7282      { "sqlite3_bind_text",             test_bind_text     ,0 },
7283      { "sqlite3_bind_text16",           test_bind_text16   ,0 },
7284      { "sqlite3_bind_blob",             test_bind_blob     ,0 },
7285      { "sqlite3_bind_parameter_count",  test_bind_parameter_count, 0},
7286      { "sqlite3_bind_parameter_name",   test_bind_parameter_name,  0},
7287      { "sqlite3_bind_parameter_index",  test_bind_parameter_index, 0},
7288      { "sqlite3_clear_bindings",        test_clear_bindings, 0},
7289      { "sqlite3_sleep",                 test_sleep,          0},
7290      { "sqlite3_errcode",               test_errcode       ,0 },
7291      { "sqlite3_extended_errcode",      test_ex_errcode    ,0 },
7292      { "sqlite3_errmsg",                test_errmsg        ,0 },
7293      { "sqlite3_errmsg16",              test_errmsg16      ,0 },
7294      { "sqlite3_open",                  test_open          ,0 },
7295      { "sqlite3_open16",                test_open16        ,0 },
7296      { "sqlite3_open_v2",               test_open_v2       ,0 },
7297      { "sqlite3_complete16",            test_complete16    ,0 },
7298 
7299      { "sqlite3_prepare",               test_prepare       ,0 },
7300      { "sqlite3_prepare16",             test_prepare16     ,0 },
7301      { "sqlite3_prepare_v2",            test_prepare_v2    ,0 },
7302      { "sqlite3_prepare_tkt3134",       test_prepare_tkt3134, 0},
7303      { "sqlite3_prepare16_v2",          test_prepare16_v2  ,0 },
7304      { "sqlite3_finalize",              test_finalize      ,0 },
7305      { "sqlite3_stmt_status",           test_stmt_status   ,0 },
7306      { "sqlite3_reset",                 test_reset         ,0 },
7307      { "sqlite3_expired",               test_expired       ,0 },
7308      { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
7309      { "sqlite3_changes",               test_changes       ,0 },
7310      { "sqlite3_step",                  test_step          ,0 },
7311      { "sqlite3_sql",                   test_sql           ,0 },
7312      { "sqlite3_expanded_sql",          test_ex_sql        ,0 },
7313      { "sqlite3_next_stmt",             test_next_stmt     ,0 },
7314      { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },
7315      { "sqlite3_stmt_busy",             test_stmt_busy     ,0 },
7316      { "uses_stmt_journal",             uses_stmt_journal ,0 },
7317 
7318      { "sqlite3_release_memory",        test_release_memory,     0},
7319      { "sqlite3_db_release_memory",     test_db_release_memory,  0},
7320      { "sqlite3_db_cacheflush",         test_db_cacheflush,      0},
7321      { "sqlite3_system_errno",          test_system_errno,       0},
7322      { "sqlite3_db_filename",           test_db_filename,        0},
7323      { "sqlite3_db_readonly",           test_db_readonly,        0},
7324      { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
7325      { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
7326      { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},
7327 
7328      { "sqlite3_load_extension",        test_load_extension,     0},
7329      { "sqlite3_enable_load_extension", test_enable_load,        0},
7330      { "sqlite3_extended_result_codes", test_extended_result_codes, 0},
7331      { "sqlite3_limit",                 test_limit,                 0},
7332 
7333      { "save_prng_state",               save_prng_state,    0 },
7334      { "restore_prng_state",            restore_prng_state, 0 },
7335      { "reset_prng_state",              reset_prng_state,   0 },
7336      { "database_never_corrupt",        database_never_corrupt, 0},
7337      { "database_may_be_corrupt",       database_may_be_corrupt, 0},
7338      { "optimization_control",          optimization_control,0},
7339 #if SQLITE_OS_WIN
7340      { "lock_win32_file",               win32_file_lock,    0 },
7341      { "exists_win32_path",             win32_exists_path,  0 },
7342      { "find_win32_file",               win32_find_file,    0 },
7343      { "delete_win32_file",             win32_delete_file,  0 },
7344      { "make_win32_dir",                win32_mkdir,        0 },
7345      { "remove_win32_dir",              win32_rmdir,        0 },
7346 #endif
7347      { "tcl_objproc",                   runAsObjProc,       0 },
7348 
7349      /* sqlite3_column_*() API */
7350      { "sqlite3_column_count",          test_column_count  ,0 },
7351      { "sqlite3_data_count",            test_data_count    ,0 },
7352      { "sqlite3_column_type",           test_column_type   ,0 },
7353      { "sqlite3_column_blob",           test_column_blob   ,0 },
7354      { "sqlite3_column_double",         test_column_double ,0 },
7355      { "sqlite3_column_int64",          test_column_int64  ,0 },
7356      { "sqlite3_column_text",   test_stmt_utf8,  (void*)sqlite3_column_text },
7357      { "sqlite3_column_name",   test_stmt_utf8,  (void*)sqlite3_column_name },
7358      { "sqlite3_column_int",    test_stmt_int,   (void*)sqlite3_column_int  },
7359      { "sqlite3_column_bytes",  test_stmt_int,   (void*)sqlite3_column_bytes},
7360 #ifndef SQLITE_OMIT_DECLTYPE
7361      { "sqlite3_column_decltype",test_stmt_utf8,(void*)sqlite3_column_decltype},
7362 #endif
7363 #ifdef SQLITE_ENABLE_COLUMN_METADATA
7364 { "sqlite3_column_database_name",test_stmt_utf8,(void*)sqlite3_column_database_name},
7365 { "sqlite3_column_table_name",test_stmt_utf8,(void*)sqlite3_column_table_name},
7366 { "sqlite3_column_origin_name",test_stmt_utf8,(void*)sqlite3_column_origin_name},
7367 #endif
7368 
7369 #ifndef SQLITE_OMIT_UTF16
7370      { "sqlite3_column_bytes16", test_stmt_int, (void*)sqlite3_column_bytes16 },
7371      { "sqlite3_column_text16",  test_stmt_utf16, (void*)sqlite3_column_text16},
7372      { "sqlite3_column_name16",  test_stmt_utf16, (void*)sqlite3_column_name16},
7373      { "add_alignment_test_collations", add_alignment_test_collations, 0      },
7374 #ifndef SQLITE_OMIT_DECLTYPE
7375      { "sqlite3_column_decltype16",test_stmt_utf16,(void*)sqlite3_column_decltype16},
7376 #endif
7377 #ifdef SQLITE_ENABLE_COLUMN_METADATA
7378 {"sqlite3_column_database_name16",
7379   test_stmt_utf16, (void*)sqlite3_column_database_name16},
7380 {"sqlite3_column_table_name16", test_stmt_utf16, (void*)sqlite3_column_table_name16},
7381 {"sqlite3_column_origin_name16", test_stmt_utf16, (void*)sqlite3_column_origin_name16},
7382 #endif
7383 #endif
7384      { "sqlite3_create_collation_v2", test_create_collation_v2, 0 },
7385      { "sqlite3_global_recover",     test_global_recover, 0   },
7386      { "working_64bit_int",          working_64bit_int,   0   },
7387      { "vfs_unlink_test",            vfs_unlink_test,     0   },
7388      { "vfs_initfail_test",          vfs_initfail_test,   0   },
7389      { "vfs_unregister_all",         vfs_unregister_all,  0   },
7390      { "vfs_reregister_all",         vfs_reregister_all,  0   },
7391      { "file_control_test",          file_control_test,   0   },
7392      { "file_control_lasterrno_test", file_control_lasterrno_test,  0   },
7393      { "file_control_lockproxy_test", file_control_lockproxy_test,  0   },
7394      { "file_control_chunksize_test", file_control_chunksize_test,  0   },
7395      { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
7396 #if SQLITE_OS_WIN
7397      { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
7398      { "file_control_win32_set_handle", file_control_win32_set_handle, 0  },
7399 #endif
7400      { "file_control_persist_wal",    file_control_persist_wal,     0   },
7401      { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
7402      { "file_control_vfsname",        file_control_vfsname,         0   },
7403      { "file_control_tempfilename",   file_control_tempfilename,    0   },
7404      { "sqlite3_vfs_list",           vfs_list,     0   },
7405      { "sqlite3_create_function_v2", test_create_function_v2, 0 },
7406 
7407      /* Functions from os.h */
7408 #ifndef SQLITE_OMIT_UTF16
7409      { "add_test_collate",        test_collate, 0            },
7410      { "add_test_collate_needed", test_collate_needed, 0     },
7411      { "add_test_function",       test_function, 0           },
7412      { "add_test_utf16bin_collate",    test_utf16bin_collate, 0        },
7413 #endif
7414      { "sqlite3_test_errstr",     test_errstr, 0             },
7415      { "tcl_variable_type",       tcl_variable_type, 0       },
7416 #ifndef SQLITE_OMIT_SHARED_CACHE
7417      { "sqlite3_enable_shared_cache", test_enable_shared, 0  },
7418      { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0},
7419 #endif
7420      { "sqlite3_libversion_number", test_libversion_number, 0  },
7421      { "sqlite3_table_column_metadata", test_table_column_metadata, 0  },
7422 #ifndef SQLITE_OMIT_INCRBLOB
7423      { "sqlite3_blob_reopen", test_blob_reopen, 0  },
7424 #endif
7425      { "pcache_stats",       test_pcache_stats, 0  },
7426 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
7427      { "sqlite3_unlock_notify", test_unlock_notify, 0  },
7428 #endif
7429      { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
7430      { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
7431      { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint, 0  },
7432      { "test_sqlite3_log",         test_sqlite3_log, 0  },
7433 #ifndef SQLITE_OMIT_EXPLAIN
7434      { "print_explain_query_plan", test_print_eqp, 0  },
7435 #endif
7436      { "sqlite3_test_control", test_test_control },
7437 #if SQLITE_OS_UNIX
7438      { "getrusage", test_getrusage },
7439 #endif
7440      { "load_static_extension", tclLoadStaticExtensionCmd },
7441      { "sorter_test_fakeheap", sorter_test_fakeheap },
7442      { "sorter_test_sort4_helper", sorter_test_sort4_helper },
7443 #ifdef SQLITE_USER_AUTHENTICATION
7444      { "sqlite3_user_authenticate", test_user_authenticate, 0 },
7445      { "sqlite3_user_add",          test_user_add,          0 },
7446      { "sqlite3_user_change",       test_user_change,       0 },
7447      { "sqlite3_user_delete",       test_user_delete,       0 },
7448 #endif
7449 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
7450      { "sqlite3_stmt_scanstatus",       test_stmt_scanstatus,   0 },
7451      { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset,   0 },
7452 #endif
7453 #ifdef SQLITE_ENABLE_SQLLOG
7454      { "sqlite3_config_sqllog",         test_config_sqllog,   0 },
7455 #endif
7456      { "vfs_current_time_int64",           vfsCurrentTimeInt64,   0 },
7457 #ifdef SQLITE_ENABLE_SNAPSHOT
7458      { "sqlite3_snapshot_get", test_snapshot_get, 0 },
7459      { "sqlite3_snapshot_open", test_snapshot_open, 0 },
7460      { "sqlite3_snapshot_free", test_snapshot_free, 0 },
7461      { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
7462 #endif
7463   };
7464   static int bitmask_size = sizeof(Bitmask)*8;
7465   static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
7466   int i;
7467   extern int sqlite3_sync_count, sqlite3_fullsync_count;
7468   extern int sqlite3_opentemp_count;
7469   extern int sqlite3_like_count;
7470   extern int sqlite3_xferopt_count;
7471   extern int sqlite3_pager_readdb_count;
7472   extern int sqlite3_pager_writedb_count;
7473   extern int sqlite3_pager_writej_count;
7474 #if SQLITE_OS_WIN
7475   extern LONG volatile sqlite3_os_type;
7476 #endif
7477 #ifdef SQLITE_DEBUG
7478   extern int sqlite3WhereTrace;
7479   extern int sqlite3OSTrace;
7480   extern int sqlite3WalTrace;
7481 #endif
7482 #ifdef SQLITE_TEST
7483 #ifdef SQLITE_ENABLE_FTS3
7484   extern int sqlite3_fts3_enable_parentheses;
7485 #endif
7486 #endif
7487 
7488   for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
7489     Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
7490   }
7491   for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
7492     Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
7493         aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
7494   }
7495   Tcl_LinkVar(interp, "sqlite_search_count",
7496       (char*)&sqlite3_search_count, TCL_LINK_INT);
7497   Tcl_LinkVar(interp, "sqlite_found_count",
7498       (char*)&sqlite3_found_count, TCL_LINK_INT);
7499   Tcl_LinkVar(interp, "sqlite_sort_count",
7500       (char*)&sqlite3_sort_count, TCL_LINK_INT);
7501   Tcl_LinkVar(interp, "sqlite3_max_blobsize",
7502       (char*)&sqlite3_max_blobsize, TCL_LINK_INT);
7503   Tcl_LinkVar(interp, "sqlite_like_count",
7504       (char*)&sqlite3_like_count, TCL_LINK_INT);
7505   Tcl_LinkVar(interp, "sqlite_interrupt_count",
7506       (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
7507   Tcl_LinkVar(interp, "sqlite_open_file_count",
7508       (char*)&sqlite3_open_file_count, TCL_LINK_INT);
7509   Tcl_LinkVar(interp, "sqlite_current_time",
7510       (char*)&sqlite3_current_time, TCL_LINK_INT);
7511 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
7512   Tcl_LinkVar(interp, "sqlite_hostid_num",
7513       (char*)&sqlite3_hostid_num, TCL_LINK_INT);
7514 #endif
7515   Tcl_LinkVar(interp, "sqlite3_xferopt_count",
7516       (char*)&sqlite3_xferopt_count, TCL_LINK_INT);
7517   Tcl_LinkVar(interp, "sqlite3_pager_readdb_count",
7518       (char*)&sqlite3_pager_readdb_count, TCL_LINK_INT);
7519   Tcl_LinkVar(interp, "sqlite3_pager_writedb_count",
7520       (char*)&sqlite3_pager_writedb_count, TCL_LINK_INT);
7521   Tcl_LinkVar(interp, "sqlite3_pager_writej_count",
7522       (char*)&sqlite3_pager_writej_count, TCL_LINK_INT);
7523 #ifndef SQLITE_OMIT_UTF16
7524   Tcl_LinkVar(interp, "unaligned_string_counter",
7525       (char*)&unaligned_string_counter, TCL_LINK_INT);
7526 #endif
7527 #ifndef SQLITE_OMIT_UTF16
7528   Tcl_LinkVar(interp, "sqlite_last_needed_collation",
7529       (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7530 #endif
7531 #if SQLITE_OS_WIN
7532   Tcl_LinkVar(interp, "sqlite_os_type",
7533       (char*)&sqlite3_os_type, TCL_LINK_LONG);
7534 #endif
7535 #ifdef SQLITE_TEST
7536   {
7537     static const char *query_plan = "*** OBSOLETE VARIABLE ***";
7538     Tcl_LinkVar(interp, "sqlite_query_plan",
7539        (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY);
7540   }
7541 #endif
7542 #ifdef SQLITE_DEBUG
7543   Tcl_LinkVar(interp, "sqlite_where_trace",
7544       (char*)&sqlite3WhereTrace, TCL_LINK_INT);
7545   Tcl_LinkVar(interp, "sqlite_os_trace",
7546       (char*)&sqlite3OSTrace, TCL_LINK_INT);
7547 #ifndef SQLITE_OMIT_WAL
7548   Tcl_LinkVar(interp, "sqlite_wal_trace",
7549       (char*)&sqlite3WalTrace, TCL_LINK_INT);
7550 #endif
7551 #endif
7552 #ifndef SQLITE_OMIT_DISKIO
7553   Tcl_LinkVar(interp, "sqlite_opentemp_count",
7554       (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
7555 #endif
7556   Tcl_LinkVar(interp, "sqlite_static_bind_value",
7557       (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
7558   Tcl_LinkVar(interp, "sqlite_static_bind_nbyte",
7559       (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT);
7560   Tcl_LinkVar(interp, "sqlite_temp_directory",
7561       (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
7562   Tcl_LinkVar(interp, "sqlite_data_directory",
7563       (char*)&sqlite3_data_directory, TCL_LINK_STRING);
7564   Tcl_LinkVar(interp, "bitmask_size",
7565       (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
7566   Tcl_LinkVar(interp, "longdouble_size",
7567       (char*)&longdouble_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
7568   Tcl_LinkVar(interp, "sqlite_sync_count",
7569       (char*)&sqlite3_sync_count, TCL_LINK_INT);
7570   Tcl_LinkVar(interp, "sqlite_fullsync_count",
7571       (char*)&sqlite3_fullsync_count, TCL_LINK_INT);
7572 #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
7573   Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses",
7574       (char*)&sqlite3_fts3_enable_parentheses, TCL_LINK_INT);
7575 #endif
7576   return TCL_OK;
7577 }
7578