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