4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
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.
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.
16 #include "sqliteInt.h"
22 # if defined(__APPLE__)
23 # include <sys/param.h>
24 # include <sys/sysctl.h>
29 #if defined(INCLUDE_SQLITE_TCL_H)
30 # include "sqlite_tcl.h"
38 ** This is a copy of the first part of the SqliteDb structure in
39 ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine
40 ** can extract the sqlite3* pointer from an existing Tcl SQLite
48 ** Convert text generated by the "%p" conversion format back into
51 static int testHexToInt(int h
){
52 if( h
>='0' && h
<='9' ){
54 }else if( h
>='a' && h
<='f' ){
57 assert( h
>='A' && h
<='F' );
61 void *sqlite3TestTextToPtr(const char *z
){
65 if( z
[0]=='0' && z
[1]=='x' ){
70 v
= (v
<<4) + testHexToInt(*z
);
73 if( sizeof(p
)==sizeof(v
) ){
74 memcpy(&p
, &v
, sizeof(p
));
76 assert( sizeof(p
)==sizeof(v2
) );
78 memcpy(&p
, &v2
, sizeof(p
));
85 ** A TCL command that returns the address of the sqlite* pointer
86 ** for an sqlite connection instance. Bad things happen if the
87 ** input is not an sqlite connection.
89 static int SQLITE_TCLAPI
get_sqlite_pointer(
99 Tcl_WrongNumArgs(interp
, 1, objv
, "SQLITE-CONNECTION");
102 if( !Tcl_GetCommandInfo(interp
, Tcl_GetString(objv
[1]), &cmdInfo
) ){
103 Tcl_AppendResult(interp
, "command not found: ",
104 Tcl_GetString(objv
[1]), (char*)0);
107 p
= (struct SqliteDb
*)cmdInfo
.objClientData
;
108 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%p", p
->db
);
109 Tcl_AppendResult(interp
, zBuf
, 0);
114 ** Decode a pointer to an sqlite3 object.
116 int getDbPointer(Tcl_Interp
*interp
, const char *zA
, sqlite3
**ppDb
){
119 if( Tcl_GetCommandInfo(interp
, zA
, &cmdInfo
) ){
120 p
= (struct SqliteDb
*)cmdInfo
.objClientData
;
123 *ppDb
= (sqlite3
*)sqlite3TestTextToPtr(zA
);
130 ** Decode a Win32 HANDLE object.
132 int getWin32Handle(Tcl_Interp
*interp
, const char *zA
, LPHANDLE phFile
){
133 *phFile
= (HANDLE
)sqlite3TestTextToPtr(zA
);
138 extern const char *sqlite3ErrName(int);
139 #define t1ErrorName sqlite3ErrName
142 ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the
143 ** fact that the sqlite3* is the first field in the Vdbe structure.
145 #define StmtToDb(X) sqlite3_db_handle(X)
148 ** Check a return value to make sure it agrees with the results
149 ** from sqlite3_errcode.
151 int sqlite3TestErrCode(Tcl_Interp
*interp
, sqlite3
*db
, int rc
){
152 if( sqlite3_threadsafe()==0 && rc
!=SQLITE_MISUSE
&& rc
!=SQLITE_OK
153 && sqlite3_errcode(db
)!=rc
){
155 int r2
= sqlite3_errcode(db
);
156 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
157 "error code %s (%d) does not match sqlite3_errcode %s (%d)",
158 t1ErrorName(rc
), rc
, t1ErrorName(r2
), r2
);
159 Tcl_ResetResult(interp
);
160 Tcl_AppendResult(interp
, zBuf
, 0);
167 ** Decode a pointer to an sqlite3_stmt object.
169 static int getStmtPointer(
172 sqlite3_stmt
**ppStmt
174 *ppStmt
= (sqlite3_stmt
*)sqlite3TestTextToPtr(zArg
);
179 ** Generate a text representation of a pointer that can be understood
180 ** by the getDbPointer and getVmPointer routines above.
182 ** The problem is, on some machines (Solaris) if you do a printf with
183 ** "%p" you cannot turn around and do a scanf with the same "%p" and
184 ** get your pointer back. You have to prepend a "0x" before it will
185 ** work. Or at least that is what is reported to me (drh). But this
186 ** behavior varies from machine to machine. The solution used her is
187 ** to test the string right after it is generated to see if it can be
188 ** understood by scanf, and if not, try prepending an "0x" to see if
189 ** that helps. If nothing works, a fatal error is generated.
191 int sqlite3TestMakePointerStr(Tcl_Interp
*interp
, char *zPtr
, void *p
){
192 sqlite3_snprintf(100, zPtr
, "%p", p
);
197 ** The callback routine for sqlite3_exec_printf().
199 static int exec_printf_cb(void *pArg
, int argc
, char **argv
, char **name
){
200 Tcl_DString
*str
= (Tcl_DString
*)pArg
;
203 if( Tcl_DStringLength(str
)==0 ){
204 for(i
=0; i
<argc
; i
++){
205 Tcl_DStringAppendElement(str
, name
[i
] ? name
[i
] : "NULL");
208 for(i
=0; i
<argc
; i
++){
209 Tcl_DStringAppendElement(str
, argv
[i
] ? argv
[i
] : "NULL");
215 ** The I/O tracing callback.
217 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
218 static FILE *iotrace_file
= 0;
219 static void io_trace_callback(const char *zFormat
, ...){
221 va_start(ap
, zFormat
);
222 vfprintf(iotrace_file
, zFormat
, ap
);
224 fflush(iotrace_file
);
229 ** Usage: io_trace FILENAME
231 ** Turn I/O tracing on or off. If FILENAME is not an empty string,
232 ** I/O tracing begins going into FILENAME. If FILENAME is an empty
233 ** string, I/O tracing is turned off.
235 static int SQLITE_TCLAPI
test_io_trace(
237 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
238 int argc
, /* Number of arguments */
239 char **argv
/* Text of each argument */
241 #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
243 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
248 if( iotrace_file
!=stdout
&& iotrace_file
!=stderr
){
249 fclose(iotrace_file
);
255 if( strcmp(argv
[1],"stdout")==0 ){
256 iotrace_file
= stdout
;
257 }else if( strcmp(argv
[1],"stderr")==0 ){
258 iotrace_file
= stderr
;
260 iotrace_file
= fopen(argv
[1], "w");
262 sqlite3IoTrace
= io_trace_callback
;
269 ** Usage: clang_sanitize_address
271 ** Returns true if the program was compiled using clang with the
272 ** -fsanitize=address switch on the command line. False otherwise.
274 ** Also return true if the OMIT_MISUSE environment variable exists.
276 static int SQLITE_TCLAPI
clang_sanitize_address(
278 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
279 int argc
, /* Number of arguments */
280 char **argv
/* Text of each argument */
283 #if defined(__has_feature)
284 # if __has_feature(address_sanitizer)
288 #ifdef __SANITIZE_ADDRESS__
291 if( res
==0 && getenv("OMIT_MISUSE")!=0 ) res
= 1;
292 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
297 ** Usage: sqlite3_exec_printf DB FORMAT STRING
299 ** Invoke the sqlite3_exec_printf() interface using the open database
300 ** DB. The SQL is the string FORMAT. The format string should contain
301 ** one %s or %q. STRING is the value inserted into %s or %q.
303 static int SQLITE_TCLAPI
test_exec_printf(
305 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
306 int argc
, /* Number of arguments */
307 char **argv
/* Text of each argument */
316 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
317 " DB FORMAT STRING", 0);
320 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
321 Tcl_DStringInit(&str
);
322 zSql
= sqlite3_mprintf(argv
[2], argv
[3]);
323 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
325 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
326 Tcl_AppendElement(interp
, zBuf
);
327 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
328 Tcl_DStringFree(&str
);
329 if( zErr
) sqlite3_free(zErr
);
330 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
335 ** Usage: sqlite3_exec_hex DB HEX
337 ** Invoke the sqlite3_exec() on a string that is obtained by translating
338 ** HEX into ASCII. Most characters are translated as is. %HH becomes
341 static int SQLITE_TCLAPI
test_exec_hex(
343 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
344 int argc
, /* Number of arguments */
345 char **argv
/* Text of each argument */
355 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
359 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
361 for(i
=j
=0; i
<(sizeof(zSql
)-1) && zHex
[j
]; i
++, j
++){
362 if( zHex
[j
]=='%' && zHex
[j
+2] && zHex
[j
+2] ){
363 zSql
[i
] = (testHexToInt(zHex
[j
+1])<<4) + testHexToInt(zHex
[j
+2]);
370 Tcl_DStringInit(&str
);
371 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
372 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
373 Tcl_AppendElement(interp
, zBuf
);
374 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
375 Tcl_DStringFree(&str
);
376 if( zErr
) sqlite3_free(zErr
);
377 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
382 ** Usage: db_enter DB
385 ** Enter or leave the mutex on a database connection.
387 static int SQLITE_TCLAPI
db_enter(
389 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
390 int argc
, /* Number of arguments */
391 char **argv
/* Text of each argument */
395 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
399 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
400 sqlite3_mutex_enter(db
->mutex
);
403 static int SQLITE_TCLAPI
db_leave(
405 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
406 int argc
, /* Number of arguments */
407 char **argv
/* Text of each argument */
411 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
415 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
416 sqlite3_mutex_leave(db
->mutex
);
421 ** Usage: sqlite3_exec DB SQL
423 ** Invoke the sqlite3_exec interface using the open database DB
425 static int SQLITE_TCLAPI
test_exec(
427 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
428 int argc
, /* Number of arguments */
429 char **argv
/* Text of each argument */
439 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
443 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
444 Tcl_DStringInit(&str
);
445 zSql
= sqlite3_mprintf("%s", argv
[2]);
446 for(i
=j
=0; zSql
[i
];){
448 zSql
[j
++] = (testHexToInt(zSql
[i
+1])<<4) + testHexToInt(zSql
[i
+2]);
451 zSql
[j
++] = zSql
[i
++];
455 rc
= sqlite3_exec(db
, zSql
, exec_printf_cb
, &str
, &zErr
);
457 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
458 Tcl_AppendElement(interp
, zBuf
);
459 Tcl_AppendElement(interp
, rc
==SQLITE_OK
? Tcl_DStringValue(&str
) : zErr
);
460 Tcl_DStringFree(&str
);
461 if( zErr
) sqlite3_free(zErr
);
462 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
467 ** Usage: sqlite3_exec_nr DB SQL
469 ** Invoke the sqlite3_exec interface using the open database DB. Discard
472 static int SQLITE_TCLAPI
test_exec_nr(
474 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
475 int argc
, /* Number of arguments */
476 char **argv
/* Text of each argument */
482 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
486 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
487 rc
= sqlite3_exec(db
, argv
[2], 0, 0, &zErr
);
488 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
493 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ...
495 ** Test the %z format of sqlite_mprintf(). Use multiple mprintf() calls to
496 ** concatenate arg0 through argn using separator as the separator.
497 ** Return the result.
499 static int SQLITE_TCLAPI
test_mprintf_z(
501 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
502 int argc
, /* Number of arguments */
503 char **argv
/* Text of each argument */
508 for(i
=2; i
<argc
&& (i
==2 || zResult
); i
++){
509 zResult
= sqlite3_mprintf("%z%s%s", zResult
, argv
[1], argv
[i
]);
511 Tcl_AppendResult(interp
, zResult
, 0);
512 sqlite3_free(zResult
);
517 ** Usage: sqlite3_mprintf_n_test STRING
519 ** Test the %n format of sqlite_mprintf(). Return the length of the
522 static int SQLITE_TCLAPI
test_mprintf_n(
524 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
525 int argc
, /* Number of arguments */
526 char **argv
/* Text of each argument */
530 zStr
= sqlite3_mprintf("%s%n", argv
[1], &n
);
532 Tcl_SetObjResult(interp
, Tcl_NewIntObj(n
));
537 ** Usage: sqlite3_snprintf_int SIZE FORMAT INT
539 ** Test the of sqlite3_snprintf() routine. SIZE is the size of the
540 ** output buffer in bytes. The maximum size is 100. FORMAT is the
541 ** format string. INT is a single integer argument. The FORMAT
542 ** string must require no more than this one integer argument. If
543 ** You pass in a format string that requires more than one argument,
544 ** bad things will happen.
546 static int SQLITE_TCLAPI
test_snprintf_int(
548 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
549 int argc
, /* Number of arguments */
550 char **argv
/* Text of each argument */
553 int n
= atoi(argv
[1]);
554 const char *zFormat
= argv
[2];
555 int a1
= atoi(argv
[3]);
556 if( n
>sizeof(zStr
) ) n
= sizeof(zStr
);
557 sqlite3_snprintf(sizeof(zStr
), zStr
, "abcdefghijklmnopqrstuvwxyz");
558 sqlite3_snprintf(n
, zStr
, zFormat
, a1
);
559 Tcl_AppendResult(interp
, zStr
, 0);
563 #ifndef SQLITE_OMIT_GET_TABLE
566 ** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts?
568 ** Invoke the sqlite3_get_table_printf() interface using the open database
569 ** DB. The SQL is the string FORMAT. The format string should contain
570 ** one %s or %q. STRING is the value inserted into %s or %q.
572 static int SQLITE_TCLAPI
test_get_table_printf(
574 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
575 int argc
, /* Number of arguments */
576 char **argv
/* Text of each argument */
582 int nRow
= 0, nCol
= 0;
589 if( Tcl_GetInt(interp
, argv
[4], &resCount
) ) return TCL_ERROR
;
591 if( argc
!=4 && argc
!=5 ){
592 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
593 " DB FORMAT STRING ?COUNT?", 0);
596 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
597 Tcl_DStringInit(&str
);
598 zSql
= sqlite3_mprintf(argv
[2],argv
[3]);
600 rc
= sqlite3_get_table(db
, zSql
, &aResult
, 0, 0, &zErr
);
602 rc
= sqlite3_get_table(db
, zSql
, &aResult
, &nRow
, &nCol
, &zErr
);
603 resCount
= (nRow
+1)*nCol
;
606 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", rc
);
607 Tcl_AppendElement(interp
, zBuf
);
610 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", nRow
);
611 Tcl_AppendElement(interp
, zBuf
);
612 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", nCol
);
613 Tcl_AppendElement(interp
, zBuf
);
615 for(i
=0; i
<resCount
; i
++){
616 Tcl_AppendElement(interp
, aResult
[i
] ? aResult
[i
] : "NULL");
619 Tcl_AppendElement(interp
, zErr
);
621 sqlite3_free_table(aResult
);
622 if( zErr
) sqlite3_free(zErr
);
623 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
627 #endif /* SQLITE_OMIT_GET_TABLE */
631 ** Usage: sqlite3_last_insert_rowid DB
633 ** Returns the integer ROWID of the most recent insert.
635 static int SQLITE_TCLAPI
test_last_rowid(
637 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
638 int argc
, /* Number of arguments */
639 char **argv
/* Text of each argument */
645 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0], " DB\"", 0);
648 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
649 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%lld", sqlite3_last_insert_rowid(db
));
650 Tcl_AppendResult(interp
, zBuf
, 0);
655 ** Usage: sqlite3_key DB KEY
657 ** Set the codec key.
659 static int SQLITE_TCLAPI
test_key(
661 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
662 int argc
, /* Number of arguments */
663 char **argv
/* Text of each argument */
665 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
670 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
674 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
677 sqlite3_key(db
, zKey
, nKey
);
683 ** Usage: sqlite3_rekey DB KEY
685 ** Change the codec key.
687 static int SQLITE_TCLAPI
test_rekey(
689 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
690 int argc
, /* Number of arguments */
691 char **argv
/* Text of each argument */
693 #ifdef SQLITE_HAS_CODEC
698 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
702 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
705 sqlite3_rekey(db
, zKey
, nKey
);
711 ** Usage: sqlite3_close DB
713 ** Closes the database opened by sqlite3_open.
715 static int SQLITE_TCLAPI
sqlite_test_close(
717 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
718 int argc
, /* Number of arguments */
719 char **argv
/* Text of each argument */
724 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
728 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
729 rc
= sqlite3_close(db
);
730 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
735 ** Usage: sqlite3_close_v2 DB
737 ** Closes the database opened by sqlite3_open.
739 static int SQLITE_TCLAPI
sqlite_test_close_v2(
741 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
742 int argc
, /* Number of arguments */
743 char **argv
/* Text of each argument */
748 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
752 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
753 rc
= sqlite3_close_v2(db
);
754 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
759 ** Implementation of the x_coalesce() function.
760 ** Return the first argument non-NULL argument.
762 static void t1_ifnullFunc(
763 sqlite3_context
*context
,
768 for(i
=0; i
<argc
; i
++){
769 if( SQLITE_NULL
!=sqlite3_value_type(argv
[i
]) ){
770 int n
= sqlite3_value_bytes(argv
[i
]);
771 sqlite3_result_text(context
, (char*)sqlite3_value_text(argv
[i
]),
772 n
, SQLITE_TRANSIENT
);
779 ** These are test functions. hex8() interprets its argument as
780 ** UTF8 and returns a hex encoding. hex16le() interprets its argument
781 ** as UTF16le and returns a hex encoding.
783 static void hex8Func(sqlite3_context
*p
, int argc
, sqlite3_value
**argv
){
784 const unsigned char *z
;
787 z
= sqlite3_value_text(argv
[0]);
788 for(i
=0; i
<sizeof(zBuf
)/2 - 2 && z
[i
]; i
++){
789 sqlite3_snprintf(sizeof(zBuf
)-i
*2, &zBuf
[i
*2], "%02x", z
[i
]);
792 sqlite3_result_text(p
, (char*)zBuf
, -1, SQLITE_TRANSIENT
);
794 #ifndef SQLITE_OMIT_UTF16
795 static void hex16Func(sqlite3_context
*p
, int argc
, sqlite3_value
**argv
){
796 const unsigned short int *z
;
799 z
= sqlite3_value_text16(argv
[0]);
800 for(i
=0; i
<sizeof(zBuf
)/4 - 4 && z
[i
]; i
++){
801 sqlite3_snprintf(sizeof(zBuf
)-i
*4, &zBuf
[i
*4],"%04x", z
[i
]&0xff);
804 sqlite3_result_text(p
, (char*)zBuf
, -1, SQLITE_TRANSIENT
);
809 ** A structure into which to accumulate text.
812 int nAlloc
; /* Space allocated */
813 int nUsed
; /* Space used */
814 char *z
; /* The space */
818 ** Append text to a dstr
820 static void dstrAppend(struct dstr
*p
, const char *z
, int divider
){
821 int n
= (int)strlen(z
);
822 if( p
->nUsed
+ n
+ 2 > p
->nAlloc
){
824 p
->nAlloc
= p
->nAlloc
*2 + n
+ 200;
825 zNew
= sqlite3_realloc(p
->z
, p
->nAlloc
);
828 memset(p
, 0, sizeof(*p
));
833 if( divider
&& p
->nUsed
>0 ){
834 p
->z
[p
->nUsed
++] = divider
;
836 memcpy(&p
->z
[p
->nUsed
], z
, n
+1);
841 ** Invoked for each callback from sqlite3ExecFunc
843 static int execFuncCallback(void *pData
, int argc
, char **argv
, char **NotUsed
){
844 struct dstr
*p
= (struct dstr
*)pData
;
846 for(i
=0; i
<argc
; i
++){
848 dstrAppend(p
, "NULL", ' ');
850 dstrAppend(p
, argv
[i
], ' ');
857 ** Implementation of the x_sqlite_exec() function. This function takes
858 ** a single argument and attempts to execute that argument as SQL code.
859 ** This is illegal and should set the SQLITE_MISUSE flag on the database.
861 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec()
862 ** from within a function call.
864 ** This routine simulates the effect of having two threads attempt to
865 ** use the same database at the same time.
867 static void sqlite3ExecFunc(
868 sqlite3_context
*context
,
873 memset(&x
, 0, sizeof(x
));
874 (void)sqlite3_exec((sqlite3
*)sqlite3_user_data(context
),
875 (char*)sqlite3_value_text(argv
[0]),
876 execFuncCallback
, &x
, 0);
877 sqlite3_result_text(context
, x
.z
, x
.nUsed
, SQLITE_TRANSIENT
);
882 ** Implementation of tkt2213func(), a scalar function that takes exactly
883 ** one argument. It has two interesting features:
885 ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.
886 ** If the three pointers returned are not the same an SQL error is raised.
888 ** * Otherwise it returns a copy of the text representation of its
889 ** argument in such a way as the VDBE representation is a Mem* cell
890 ** with the MEM_Term flag clear.
892 ** Ticket #2213 can therefore be tested by evaluating the following
895 ** tkt2213func(tkt2213func('a string'));
897 static void tkt2213Function(
898 sqlite3_context
*context
,
903 unsigned char const *zText1
;
904 unsigned char const *zText2
;
905 unsigned char const *zText3
;
907 nText
= sqlite3_value_bytes(argv
[0]);
908 zText1
= sqlite3_value_text(argv
[0]);
909 zText2
= sqlite3_value_text(argv
[0]);
910 zText3
= sqlite3_value_text(argv
[0]);
912 if( zText1
!=zText2
|| zText2
!=zText3
){
913 sqlite3_result_error(context
, "tkt2213 is not fixed", -1);
915 char *zCopy
= (char *)sqlite3_malloc(nText
);
916 memcpy(zCopy
, zText1
, nText
);
917 sqlite3_result_text(context
, zCopy
, nText
, sqlite3_free
);
922 ** The following SQL function takes 4 arguments. The 2nd and
923 ** 4th argument must be one of these strings: 'text', 'text16',
924 ** or 'blob' corresponding to API functions
926 ** sqlite3_value_text()
927 ** sqlite3_value_text16()
928 ** sqlite3_value_blob()
930 ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
931 ** corresponding to APIs:
933 ** sqlite3_value_bytes()
934 ** sqlite3_value_bytes16()
937 ** The APIs designated by the 2nd through 4th arguments are applied
938 ** to the first argument in order. If the pointers returned by the
939 ** second and fourth are different, this routine returns 1. Otherwise,
940 ** this routine returns 0.
942 ** This function is used to test to see when returned pointers from
943 ** the _text(), _text16() and _blob() APIs become invalidated.
945 static void ptrChngFunction(
946 sqlite3_context
*context
,
952 if( argc
!=4 ) return;
953 zCmd
= (const char*)sqlite3_value_text(argv
[1]);
954 if( zCmd
==0 ) return;
955 if( strcmp(zCmd
,"text")==0 ){
956 p1
= (const void*)sqlite3_value_text(argv
[0]);
957 #ifndef SQLITE_OMIT_UTF16
958 }else if( strcmp(zCmd
, "text16")==0 ){
959 p1
= (const void*)sqlite3_value_text16(argv
[0]);
961 }else if( strcmp(zCmd
, "blob")==0 ){
962 p1
= (const void*)sqlite3_value_blob(argv
[0]);
966 zCmd
= (const char*)sqlite3_value_text(argv
[2]);
967 if( zCmd
==0 ) return;
968 if( strcmp(zCmd
,"bytes")==0 ){
969 sqlite3_value_bytes(argv
[0]);
970 #ifndef SQLITE_OMIT_UTF16
971 }else if( strcmp(zCmd
, "bytes16")==0 ){
972 sqlite3_value_bytes16(argv
[0]);
974 }else if( strcmp(zCmd
, "noop")==0 ){
979 zCmd
= (const char*)sqlite3_value_text(argv
[3]);
980 if( zCmd
==0 ) return;
981 if( strcmp(zCmd
,"text")==0 ){
982 p2
= (const void*)sqlite3_value_text(argv
[0]);
983 #ifndef SQLITE_OMIT_UTF16
984 }else if( strcmp(zCmd
, "text16")==0 ){
985 p2
= (const void*)sqlite3_value_text16(argv
[0]);
987 }else if( strcmp(zCmd
, "blob")==0 ){
988 p2
= (const void*)sqlite3_value_blob(argv
[0]);
992 sqlite3_result_int(context
, p1
!=p2
);
996 ** This SQL function returns a different answer each time it is called, even if
997 ** the arguments are the same.
999 static void nondeterministicFunction(
1000 sqlite3_context
*context
,
1002 sqlite3_value
**argv
1005 sqlite3_result_int(context
, cnt
++);
1009 ** This SQL function returns the integer value of its argument as a MEM_IntReal
1012 static void intrealFunction(
1013 sqlite3_context
*context
,
1015 sqlite3_value
**argv
1017 sqlite3_int64 v
= sqlite3_value_int64(argv
[0]);
1018 sqlite3_result_int64(context
, v
);
1019 sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL
, context
);
1023 ** SQL function: strtod(X)
1025 ** Use the C-library strtod() function to convert string X into a double.
1026 ** Used for comparing the accuracy of SQLite's internal text-to-float conversion
1027 ** routines against the C-library.
1029 static void shellStrtod(
1030 sqlite3_context
*pCtx
,
1032 sqlite3_value
**apVal
1034 char *z
= (char*)sqlite3_value_text(apVal
[0]);
1035 UNUSED_PARAMETER(nVal
);
1037 sqlite3_result_double(pCtx
, strtod(z
,0));
1041 ** SQL function: dtostr(X)
1043 ** Use the C-library printf() function to convert real value X into a string.
1044 ** Used for comparing the accuracy of SQLite's internal float-to-text conversion
1045 ** routines against the C-library.
1047 static void shellDtostr(
1048 sqlite3_context
*pCtx
,
1050 sqlite3_value
**apVal
1052 double r
= sqlite3_value_double(apVal
[0]);
1053 int n
= nVal
>=2 ? sqlite3_value_int(apVal
[1]) : 26;
1056 if( n
>350 ) n
= 350;
1057 sprintf(z
, "%#+.*e", n
, r
);
1058 sqlite3_result_text(pCtx
, z
, -1, SQLITE_TRANSIENT
);
1063 ** Usage: sqlite3_create_function DB
1065 ** Call the sqlite3_create_function API on the given database in order
1066 ** to create a function named "x_coalesce". This function does the same thing
1067 ** as the "coalesce" function. This function also registers an SQL function
1068 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec()
1069 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
1070 ** The effect is similar to trying to use the same database connection from
1071 ** two threads at the same time.
1073 ** The original motivation for this routine was to be able to call the
1074 ** sqlite3_create_function function while a query is in progress in order
1075 ** to test the SQLITE_MISUSE detection logic.
1077 static int SQLITE_TCLAPI
test_create_function(
1079 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1080 int argc
, /* Number of arguments */
1081 char **argv
/* Text of each argument */
1087 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1091 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1092 rc
= sqlite3_create_function(db
, "x_coalesce", -1, SQLITE_UTF8
, 0,
1093 t1_ifnullFunc
, 0, 0);
1094 if( rc
==SQLITE_OK
){
1095 rc
= sqlite3_create_function(db
, "hex8", 1, SQLITE_UTF8
| SQLITE_DETERMINISTIC
,
1098 #ifndef SQLITE_OMIT_UTF16
1099 if( rc
==SQLITE_OK
){
1100 rc
= sqlite3_create_function(db
, "hex16", 1, SQLITE_UTF16
| SQLITE_DETERMINISTIC
,
1101 0, hex16Func
, 0, 0);
1104 if( rc
==SQLITE_OK
){
1105 rc
= sqlite3_create_function(db
, "tkt2213func", 1, SQLITE_ANY
, 0,
1106 tkt2213Function
, 0, 0);
1108 if( rc
==SQLITE_OK
){
1109 rc
= sqlite3_create_function(db
, "pointer_change", 4, SQLITE_ANY
, 0,
1110 ptrChngFunction
, 0, 0);
1113 /* Functions counter1() and counter2() have the same implementation - they
1114 ** both return an ascending integer with each call. But counter1() is marked
1115 ** as non-deterministic and counter2() is marked as deterministic.
1117 if( rc
==SQLITE_OK
){
1118 rc
= sqlite3_create_function(db
, "counter1", -1, SQLITE_UTF8
,
1119 0, nondeterministicFunction
, 0, 0);
1121 if( rc
==SQLITE_OK
){
1122 rc
= sqlite3_create_function(db
, "counter2", -1, SQLITE_UTF8
|SQLITE_DETERMINISTIC
,
1123 0, nondeterministicFunction
, 0, 0);
1126 /* The intreal() function converts its argument to an integer and returns
1127 ** it as a MEM_IntReal.
1129 if( rc
==SQLITE_OK
){
1130 rc
= sqlite3_create_function(db
, "intreal", 1, SQLITE_UTF8
,
1131 0, intrealFunction
, 0, 0);
1134 /* Functions strtod() and dtostr() work as in the shell. These routines
1135 ** use the standard C library to convert between floating point and
1136 ** text. This is used to compare SQLite's internal conversion routines
1137 ** against the standard library conversion routines.
1139 ** Both routines copy/pasted from the shell.c.in implementation
1142 if( rc
==SQLITE_OK
){
1143 rc
= sqlite3_create_function(db
, "strtod", 1, SQLITE_UTF8
, 0,
1146 if( rc
==SQLITE_OK
){
1147 rc
= sqlite3_create_function(db
, "dtostr", 1, SQLITE_UTF8
, 0,
1150 if( rc
==SQLITE_OK
){
1151 rc
= sqlite3_create_function(db
, "dtostr", 2, SQLITE_UTF8
, 0,
1155 #ifndef SQLITE_OMIT_UTF16
1156 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also
1157 ** because it is not tested anywhere else. */
1158 if( rc
==SQLITE_OK
){
1160 sqlite3_value
*pVal
;
1161 sqlite3_mutex_enter(db
->mutex
);
1162 pVal
= sqlite3ValueNew(db
);
1163 sqlite3ValueSetStr(pVal
, -1, "x_sqlite_exec", SQLITE_UTF8
, SQLITE_STATIC
);
1164 zUtf16
= sqlite3ValueText(pVal
, SQLITE_UTF16NATIVE
);
1165 if( db
->mallocFailed
){
1168 rc
= sqlite3_create_function16(db
, zUtf16
,
1169 1, SQLITE_UTF16
, db
, sqlite3ExecFunc
, 0, 0);
1171 sqlite3ValueFree(pVal
);
1172 sqlite3_mutex_leave(db
->mutex
);
1176 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
1177 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
1182 ** Usage: sqlite3_drop_modules DB ?NAME ...?
1184 ** Invoke the sqlite3_drop_modules(D,L) interface on database
1185 ** connection DB, in order to drop all modules except those named in
1188 static int SQLITE_TCLAPI
test_drop_modules(
1190 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1191 int argc
, /* Number of arguments */
1192 char **argv
/* Text of each argument */
1197 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1201 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1202 #ifndef SQLITE_OMIT_VIRTUALTABLE
1203 sqlite3_drop_modules(db
, argc
>2 ? (const char**)(argv
+2) : 0);
1209 ** Routines to implement the x_count() aggregate function.
1211 ** x_count() counts the number of non-null arguments. But there are
1212 ** some twists for testing purposes.
1214 ** If the argument to x_count() is 40 then a UTF-8 error is reported
1215 ** on the step function. If x_count(41) is seen, then a UTF-16 error
1216 ** is reported on the step function. If the total count is 42, then
1217 ** a UTF-8 error is reported on the finalize function.
1219 typedef struct t1CountCtx t1CountCtx
;
1223 static void t1CountStep(
1224 sqlite3_context
*context
,
1226 sqlite3_value
**argv
1229 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
1230 if( (argc
==0 || SQLITE_NULL
!=sqlite3_value_type(argv
[0]) ) && p
){
1234 int v
= sqlite3_value_int(argv
[0]);
1236 sqlite3_result_error(context
, "value of 40 handed to x_count", -1);
1237 #ifndef SQLITE_OMIT_UTF16
1239 const char zUtf16ErrMsg
[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0};
1240 sqlite3_result_error16(context
, &zUtf16ErrMsg
[1-SQLITE_BIGENDIAN
], -1);
1245 static void t1CountFinalize(sqlite3_context
*context
){
1247 p
= sqlite3_aggregate_context(context
, sizeof(*p
));
1250 sqlite3_result_error(context
, "x_count totals to 42", -1);
1252 sqlite3_result_int(context
, p
? p
->n
: 0);
1257 #ifndef SQLITE_OMIT_DEPRECATED
1258 static void legacyCountStep(
1259 sqlite3_context
*context
,
1261 sqlite3_value
**argv
1266 static void legacyCountFinalize(sqlite3_context
*context
){
1267 sqlite3_result_int(context
, sqlite3_aggregate_count(context
));
1272 ** Usage: sqlite3_create_aggregate DB
1274 ** Call the sqlite3_create_function API on the given database in order
1275 ** to create a function named "x_count". This function is similar
1276 ** to the built-in count() function, with a few special quirks
1277 ** for testing the sqlite3_result_error() APIs.
1279 ** The original motivation for this routine was to be able to call the
1280 ** sqlite3_create_aggregate function while a query is in progress in order
1281 ** to test the SQLITE_MISUSE detection logic. See misuse.test.
1283 ** This routine was later extended to test the use of sqlite3_result_error()
1284 ** within aggregate functions.
1286 ** Later: It is now also extended to register the aggregate function
1287 ** "legacy_count()" with the supplied database handle. This is used
1288 ** to test the deprecated sqlite3_aggregate_count() API.
1290 static int SQLITE_TCLAPI
test_create_aggregate(
1292 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1293 int argc
, /* Number of arguments */
1294 char **argv
/* Text of each argument */
1299 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1303 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
1304 rc
= sqlite3_create_function(db
, "x_count", 0, SQLITE_UTF8
, 0, 0,
1305 t1CountStep
,t1CountFinalize
);
1306 if( rc
==SQLITE_OK
){
1307 rc
= sqlite3_create_function(db
, "x_count", 1, SQLITE_UTF8
, 0, 0,
1308 t1CountStep
,t1CountFinalize
);
1310 #ifndef SQLITE_OMIT_DEPRECATED
1311 if( rc
==SQLITE_OK
){
1312 rc
= sqlite3_create_function(db
, "legacy_count", 0, SQLITE_ANY
, 0, 0,
1313 legacyCountStep
, legacyCountFinalize
1317 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
1318 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
1324 ** Usage: printf TEXT
1326 ** Send output to printf. Use this rather than puts to merge the output
1327 ** in the correct sequence with debugging printfs inserted into C code.
1328 ** Puts uses a separate buffer and debugging statements will be out of
1329 ** sequence if it is used.
1331 static int SQLITE_TCLAPI
test_printf(
1333 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1334 int argc
, /* Number of arguments */
1335 char **argv
/* Text of each argument */
1338 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1342 printf("%s\n", argv
[1]);
1349 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
1351 ** Call mprintf with three integer arguments
1353 static int SQLITE_TCLAPI
sqlite3_mprintf_int(
1355 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1356 int argc
, /* Number of arguments */
1357 char **argv
/* Text of each argument */
1362 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1363 " FORMAT INT INT INT\"", 0);
1367 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1369 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1370 Tcl_AppendResult(interp
, z
, 0);
1376 ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
1378 ** Call mprintf with three 64-bit integer arguments
1380 static int SQLITE_TCLAPI
sqlite3_mprintf_int64(
1382 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1383 int argc
, /* Number of arguments */
1384 char **argv
/* Text of each argument */
1390 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1391 " FORMAT INT INT INT\"", 0);
1395 if( sqlite3Atoi64(argv
[i
], &a
[i
-2], sqlite3Strlen30(argv
[i
]), SQLITE_UTF8
) ){
1396 Tcl_AppendResult(interp
, "argument is not a valid 64-bit integer", 0);
1400 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1401 Tcl_AppendResult(interp
, z
, 0);
1407 ** Usage: sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER
1409 ** Call mprintf with three long integer arguments. This might be the
1410 ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on
1413 static int SQLITE_TCLAPI
sqlite3_mprintf_long(
1415 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1416 int argc
, /* Number of arguments */
1417 char **argv
/* Text of each argument */
1424 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1425 " FORMAT INT INT INT\"", 0);
1429 if( Tcl_GetInt(interp
, argv
[i
], &b
[i
-2]) ) return TCL_ERROR
;
1430 a
[i
-2] = (long int)b
[i
-2];
1431 a
[i
-2] &= (((u64
)1)<<(sizeof(int)*8))-1;
1433 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], a
[2]);
1434 Tcl_AppendResult(interp
, z
, 0);
1440 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
1442 ** Call mprintf with two integer arguments and one string argument
1444 static int SQLITE_TCLAPI
sqlite3_mprintf_str(
1446 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1447 int argc
, /* Number of arguments */
1448 char **argv
/* Text of each argument */
1452 if( argc
<4 || argc
>5 ){
1453 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1454 " FORMAT INT INT ?STRING?\"", 0);
1458 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1460 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], argc
>4 ? argv
[4] : NULL
);
1461 Tcl_AppendResult(interp
, z
, 0);
1467 ** Usage: sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
1469 ** Call mprintf with two integer arguments and one string argument
1471 static int SQLITE_TCLAPI
sqlite3_snprintf_str(
1473 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1474 int argc
, /* Number of arguments */
1475 char **argv
/* Text of each argument */
1480 if( argc
<5 || argc
>6 ){
1481 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1482 " INT FORMAT INT INT ?STRING?\"", 0);
1485 if( Tcl_GetInt(interp
, argv
[1], &n
) ) return TCL_ERROR
;
1487 Tcl_AppendResult(interp
, "N must be non-negative", 0);
1491 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-3]) ) return TCL_ERROR
;
1493 z
= sqlite3_malloc( n
+1 );
1494 sqlite3_snprintf(n
, z
, argv
[2], a
[0], a
[1], argc
>4 ? argv
[5] : NULL
);
1495 Tcl_AppendResult(interp
, z
, 0);
1501 ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE
1503 ** Call mprintf with two integer arguments and one double argument
1505 static int SQLITE_TCLAPI
sqlite3_mprintf_double(
1507 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1508 int argc
, /* Number of arguments */
1509 char **argv
/* Text of each argument */
1515 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1516 " FORMAT INT INT DOUBLE\"", 0);
1520 if( Tcl_GetInt(interp
, argv
[i
], &a
[i
-2]) ) return TCL_ERROR
;
1522 if( Tcl_GetDouble(interp
, argv
[4], &r
) ) return TCL_ERROR
;
1523 z
= sqlite3_mprintf(argv
[1], a
[0], a
[1], r
);
1524 Tcl_AppendResult(interp
, z
, 0);
1530 ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE
1532 ** Call mprintf with a single double argument which is the product of the
1533 ** two arguments given above. This is used to generate overflow and underflow
1534 ** doubles to test that they are converted properly.
1536 static int SQLITE_TCLAPI
sqlite3_mprintf_scaled(
1538 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1539 int argc
, /* Number of arguments */
1540 char **argv
/* Text of each argument */
1546 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1547 " FORMAT DOUBLE DOUBLE\"", 0);
1551 if( Tcl_GetDouble(interp
, argv
[i
], &r
[i
-2]) ) return TCL_ERROR
;
1553 z
= sqlite3_mprintf(argv
[1], r
[0]*r
[1]);
1554 Tcl_AppendResult(interp
, z
, 0);
1560 ** Usage: sqlite3_mprintf_stronly FORMAT STRING
1562 ** Call mprintf with a single double argument which is the product of the
1563 ** two arguments given above. This is used to generate overflow and underflow
1564 ** doubles to test that they are converted properly.
1566 static int SQLITE_TCLAPI
sqlite3_mprintf_stronly(
1568 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1569 int argc
, /* Number of arguments */
1570 char **argv
/* Text of each argument */
1574 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1575 " FORMAT STRING\"", 0);
1578 z
= sqlite3_mprintf(argv
[1], argv
[2]);
1579 Tcl_AppendResult(interp
, z
, 0);
1585 ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX
1587 ** Call mprintf with a single double argument which is derived from the
1588 ** hexadecimal encoding of an IEEE double.
1590 static int SQLITE_TCLAPI
sqlite3_mprintf_hexdouble(
1592 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1593 int argc
, /* Number of arguments */
1594 char **argv
/* Text of each argument */
1598 unsigned int x1
, x2
;
1601 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
1602 " FORMAT STRING\"", 0);
1605 if( sscanf(argv
[2], "%08x%08x", &x2
, &x1
)!=2 ){
1606 Tcl_AppendResult(interp
, "2nd argument should be 16-characters of hex", 0);
1611 memcpy(&r
, &d
, sizeof(r
));
1612 z
= sqlite3_mprintf(argv
[1], r
);
1613 Tcl_AppendResult(interp
, z
, 0);
1619 ** Usage: sqlite3_enable_shared_cache ?BOOLEAN?
1622 #if !defined(SQLITE_OMIT_SHARED_CACHE)
1623 static int SQLITE_TCLAPI
test_enable_shared(
1624 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1625 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1626 int objc
, /* Number of arguments */
1627 Tcl_Obj
*CONST objv
[] /* Command arguments */
1633 if( objc
!=2 && objc
!=1 ){
1634 Tcl_WrongNumArgs(interp
, 1, objv
, "?BOOLEAN?");
1637 ret
= sqlite3GlobalConfig
.sharedCacheEnabled
;
1640 if( Tcl_GetBooleanFromObj(interp
, objv
[1], &enable
) ){
1643 rc
= sqlite3_enable_shared_cache(enable
);
1644 if( rc
!=SQLITE_OK
){
1645 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(rc
), TCL_STATIC
);
1649 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(ret
));
1657 ** Usage: sqlite3_extended_result_codes DB BOOLEAN
1660 static int SQLITE_TCLAPI
test_extended_result_codes(
1661 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1662 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1663 int objc
, /* Number of arguments */
1664 Tcl_Obj
*CONST objv
[] /* Command arguments */
1670 Tcl_WrongNumArgs(interp
, 1, objv
, "DB BOOLEAN");
1673 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1674 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &enable
) ) return TCL_ERROR
;
1675 sqlite3_extended_result_codes(db
, enable
);
1680 ** Usage: sqlite3_libversion_number
1683 static int SQLITE_TCLAPI
test_libversion_number(
1684 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1685 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1686 int objc
, /* Number of arguments */
1687 Tcl_Obj
*CONST objv
[] /* Command arguments */
1689 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_libversion_number()));
1694 ** Usage: sqlite3_table_column_metadata DB dbname tblname colname
1697 static int SQLITE_TCLAPI
test_table_column_metadata(
1698 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
1699 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1700 int objc
, /* Number of arguments */
1701 Tcl_Obj
*CONST objv
[] /* Command arguments */
1710 const char *zDatatype
;
1711 const char *zCollseq
;
1716 if( objc
!=5 && objc
!=4 ){
1717 Tcl_WrongNumArgs(interp
, 1, objv
, "DB dbname tblname colname");
1720 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1721 zDb
= Tcl_GetString(objv
[2]);
1722 zTbl
= Tcl_GetString(objv
[3]);
1723 zCol
= objc
==5 ? Tcl_GetString(objv
[4]) : 0;
1725 if( strlen(zDb
)==0 ) zDb
= 0;
1727 rc
= sqlite3_table_column_metadata(db
, zDb
, zTbl
, zCol
,
1728 &zDatatype
, &zCollseq
, ¬null
, &primarykey
, &autoincrement
);
1730 if( rc
!=SQLITE_OK
){
1731 Tcl_AppendResult(interp
, sqlite3_errmsg(db
), 0);
1735 pRet
= Tcl_NewObj();
1736 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zDatatype
, -1));
1737 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zCollseq
, -1));
1738 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(notnull
));
1739 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(primarykey
));
1740 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(autoincrement
));
1741 Tcl_SetObjResult(interp
, pRet
);
1746 #ifndef SQLITE_OMIT_INCRBLOB
1748 static int SQLITE_TCLAPI
blobHandleFromObj(
1751 sqlite3_blob
**ppBlob
1756 z
= Tcl_GetStringFromObj(pObj
, &n
);
1761 Tcl_Channel channel
;
1762 ClientData instanceData
;
1764 channel
= Tcl_GetChannel(interp
, z
, ¬Used
);
1765 if( !channel
) return TCL_ERROR
;
1768 Tcl_Seek(channel
, 0, SEEK_SET
);
1770 instanceData
= Tcl_GetChannelInstanceData(channel
);
1771 *ppBlob
= *((sqlite3_blob
**)instanceData
);
1777 static int SQLITE_TCLAPI
test_blob_reopen(
1778 ClientData clientData
, /* Not used */
1779 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1780 int objc
, /* Number of arguments */
1781 Tcl_Obj
*CONST objv
[] /* Command arguments */
1784 sqlite3_blob
*pBlob
;
1788 Tcl_WrongNumArgs(interp
, 1, objv
, "CHANNEL ROWID");
1792 if( blobHandleFromObj(interp
, objv
[1], &pBlob
) ) return TCL_ERROR
;
1793 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &iRowid
) ) return TCL_ERROR
;
1795 rc
= sqlite3_blob_reopen(pBlob
, iRowid
);
1796 if( rc
!=SQLITE_OK
){
1797 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
1800 return (rc
==SQLITE_OK
? TCL_OK
: TCL_ERROR
);
1806 ** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC
1808 ** This Tcl proc is used for testing the experimental
1809 ** sqlite3_create_collation_v2() interface.
1811 struct TestCollationX
{
1816 typedef struct TestCollationX TestCollationX
;
1817 static void testCreateCollationDel(void *pCtx
){
1818 TestCollationX
*p
= (TestCollationX
*)pCtx
;
1820 int rc
= Tcl_EvalObjEx(p
->interp
, p
->pDel
, TCL_EVAL_DIRECT
|TCL_EVAL_GLOBAL
);
1822 Tcl_BackgroundError(p
->interp
);
1825 Tcl_DecrRefCount(p
->pCmp
);
1826 Tcl_DecrRefCount(p
->pDel
);
1827 sqlite3_free((void *)p
);
1829 static int testCreateCollationCmp(
1836 TestCollationX
*p
= (TestCollationX
*)pCtx
;
1837 Tcl_Obj
*pScript
= Tcl_DuplicateObj(p
->pCmp
);
1840 Tcl_IncrRefCount(pScript
);
1841 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj((char *)zLeft
, nLeft
));
1842 Tcl_ListObjAppendElement(0, pScript
, Tcl_NewStringObj((char *)zRight
,nRight
));
1844 if( TCL_OK
!=Tcl_EvalObjEx(p
->interp
, pScript
, TCL_EVAL_DIRECT
|TCL_EVAL_GLOBAL
)
1845 || TCL_OK
!=Tcl_GetIntFromObj(p
->interp
, Tcl_GetObjResult(p
->interp
), &iRes
)
1847 Tcl_BackgroundError(p
->interp
);
1849 Tcl_DecrRefCount(pScript
);
1853 static int SQLITE_TCLAPI
test_create_collation_v2(
1854 ClientData clientData
, /* Not used */
1855 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
1856 int objc
, /* Number of arguments */
1857 Tcl_Obj
*CONST objv
[] /* Command arguments */
1864 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE NAME CMP-PROC DEL-PROC");
1867 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1869 p
= (TestCollationX
*)sqlite3_malloc(sizeof(TestCollationX
));
1873 Tcl_IncrRefCount(p
->pCmp
);
1874 Tcl_IncrRefCount(p
->pDel
);
1876 rc
= sqlite3_create_collation_v2(db
, Tcl_GetString(objv
[2]), 16,
1877 (void *)p
, testCreateCollationCmp
, testCreateCollationDel
1879 if( rc
!=SQLITE_MISUSE
){
1880 Tcl_AppendResult(interp
, "sqlite3_create_collate_v2() failed to detect "
1881 "an invalid encoding", (char*)0);
1884 rc
= sqlite3_create_collation_v2(db
, Tcl_GetString(objv
[2]), SQLITE_UTF8
,
1885 (void *)p
, testCreateCollationCmp
, testCreateCollationDel
1891 ** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES?
1893 ** Available switches are:
1900 typedef struct CreateFunctionV2 CreateFunctionV2
;
1901 struct CreateFunctionV2
{
1903 Tcl_Obj
*pFunc
; /* Script for function invocation */
1904 Tcl_Obj
*pStep
; /* Script for agg. step invocation */
1905 Tcl_Obj
*pFinal
; /* Script for agg. finalization invocation */
1906 Tcl_Obj
*pDestroy
; /* Destructor script */
1908 static void cf2Func(sqlite3_context
*ctx
, int nArg
, sqlite3_value
**aArg
){
1910 static void cf2Step(sqlite3_context
*ctx
, int nArg
, sqlite3_value
**aArg
){
1912 static void cf2Final(sqlite3_context
*ctx
){
1914 static void cf2Destroy(void *pUser
){
1915 CreateFunctionV2
*p
= (CreateFunctionV2
*)pUser
;
1917 if( p
->interp
&& p
->pDestroy
){
1918 int rc
= Tcl_EvalObjEx(p
->interp
, p
->pDestroy
, 0);
1919 if( rc
!=TCL_OK
) Tcl_BackgroundError(p
->interp
);
1922 if( p
->pFunc
) Tcl_DecrRefCount(p
->pFunc
);
1923 if( p
->pStep
) Tcl_DecrRefCount(p
->pStep
);
1924 if( p
->pFinal
) Tcl_DecrRefCount(p
->pFinal
);
1925 if( p
->pDestroy
) Tcl_DecrRefCount(p
->pDestroy
);
1928 static int SQLITE_TCLAPI
test_create_function_v2(
1929 ClientData clientData
, /* Not used */
1930 Tcl_Interp
*interp
, /* The invoking TCL interpreter */
1931 int objc
, /* Number of arguments */
1932 Tcl_Obj
*CONST objv
[] /* Command arguments */
1938 CreateFunctionV2
*p
;
1946 {"utf8", SQLITE_UTF8
},
1947 {"utf16", SQLITE_UTF16
},
1948 {"utf16le", SQLITE_UTF16LE
},
1949 {"utf16be", SQLITE_UTF16BE
},
1950 {"any", SQLITE_ANY
},
1955 if( objc
<5 || (objc
%2)==0 ){
1956 Tcl_WrongNumArgs(interp
, 1, objv
, "DB NAME NARG ENC SWITCHES...");
1960 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
1961 zFunc
= Tcl_GetString(objv
[2]);
1962 if( Tcl_GetIntFromObj(interp
, objv
[3], &nArg
) ) return TCL_ERROR
;
1963 if( Tcl_GetIndexFromObjStruct(interp
, objv
[4], aEnc
, sizeof(aEnc
[0]),
1964 "encoding", 0, &enc
)
1968 enc
= aEnc
[enc
].enc
;
1970 p
= sqlite3_malloc(sizeof(CreateFunctionV2
));
1972 memset(p
, 0, sizeof(CreateFunctionV2
));
1975 for(i
=5; i
<objc
; i
+=2){
1977 const char *azSwitch
[] = {"-func", "-step", "-final", "-destroy", 0};
1978 if( Tcl_GetIndexFromObj(interp
, objv
[i
], azSwitch
, "switch", 0, &iSwitch
) ){
1984 case 0: p
->pFunc
= objv
[i
+1]; break;
1985 case 1: p
->pStep
= objv
[i
+1]; break;
1986 case 2: p
->pFinal
= objv
[i
+1]; break;
1987 case 3: p
->pDestroy
= objv
[i
+1]; break;
1990 if( p
->pFunc
) p
->pFunc
= Tcl_DuplicateObj(p
->pFunc
);
1991 if( p
->pStep
) p
->pStep
= Tcl_DuplicateObj(p
->pStep
);
1992 if( p
->pFinal
) p
->pFinal
= Tcl_DuplicateObj(p
->pFinal
);
1993 if( p
->pDestroy
) p
->pDestroy
= Tcl_DuplicateObj(p
->pDestroy
);
1995 if( p
->pFunc
) Tcl_IncrRefCount(p
->pFunc
);
1996 if( p
->pStep
) Tcl_IncrRefCount(p
->pStep
);
1997 if( p
->pFinal
) Tcl_IncrRefCount(p
->pFinal
);
1998 if( p
->pDestroy
) Tcl_IncrRefCount(p
->pDestroy
);
2000 rc
= sqlite3_create_function_v2(db
, zFunc
, nArg
, enc
, (void *)p
,
2001 (p
->pFunc
? cf2Func
: 0),
2002 (p
->pStep
? cf2Step
: 0),
2003 (p
->pFinal
? cf2Final
: 0),
2006 if( rc
!=SQLITE_OK
){
2007 Tcl_ResetResult(interp
);
2008 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
2015 ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC?
2017 static int SQLITE_TCLAPI
test_load_extension(
2018 ClientData clientData
, /* Not used */
2019 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2020 int objc
, /* Number of arguments */
2021 Tcl_Obj
*CONST objv
[] /* Command arguments */
2023 Tcl_CmdInfo cmdInfo
;
2031 if( objc
!=4 && objc
!=3 ){
2032 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE FILE ?PROC?");
2035 zDb
= Tcl_GetString(objv
[1]);
2036 zFile
= Tcl_GetString(objv
[2]);
2038 zProc
= Tcl_GetString(objv
[3]);
2041 /* Extract the C database handle from the Tcl command name */
2042 if( !Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
2043 Tcl_AppendResult(interp
, "command not found: ", zDb
, (char*)0);
2046 db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
2049 /* Call the underlying C function. If an error occurs, set rc to
2050 ** TCL_ERROR and load any error string into the interpreter. If no
2051 ** error occurs, set rc to TCL_OK.
2053 #ifdef SQLITE_OMIT_LOAD_EXTENSION
2055 zErr
= sqlite3_mprintf("this build omits sqlite3_load_extension()");
2059 rc
= sqlite3_load_extension(db
, zFile
, zProc
, &zErr
);
2061 if( rc
!=SQLITE_OK
){
2062 Tcl_SetResult(interp
, zErr
? zErr
: "", TCL_VOLATILE
);
2073 ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF
2075 static int SQLITE_TCLAPI
test_enable_load(
2076 ClientData clientData
, /* Not used */
2077 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2078 int objc
, /* Number of arguments */
2079 Tcl_Obj
*CONST objv
[] /* Command arguments */
2081 Tcl_CmdInfo cmdInfo
;
2087 Tcl_WrongNumArgs(interp
, 1, objv
, "DB-HANDLE ONOFF");
2090 zDb
= Tcl_GetString(objv
[1]);
2092 /* Extract the C database handle from the Tcl command name */
2093 if( !Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
2094 Tcl_AppendResult(interp
, "command not found: ", zDb
, (char*)0);
2097 db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
2100 /* Get the onoff parameter */
2101 if( Tcl_GetBooleanFromObj(interp
, objv
[2], &onoff
) ){
2105 #ifdef SQLITE_OMIT_LOAD_EXTENSION
2106 Tcl_AppendResult(interp
, "this build omits sqlite3_load_extension()");
2109 sqlite3_enable_load_extension(db
, onoff
);
2115 ** Usage: sqlite_abort
2117 ** Shutdown the process immediately. This is not a clean shutdown.
2118 ** This command is used to test the recoverability of a database in
2119 ** the event of a program crash.
2121 static int SQLITE_TCLAPI
sqlite_abort(
2123 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2124 int argc
, /* Number of arguments */
2125 char **argv
/* Text of each argument */
2127 #if defined(_MSC_VER)
2128 /* We do this, otherwise the test will halt with a popup message
2129 * that we have to click away before the test will continue.
2131 _set_abort_behavior( 0, _CALL_REPORTFAULT
);
2134 assert( interp
==0 ); /* This will always fail */
2139 ** The following routine is a user-defined SQL function whose purpose
2140 ** is to test the sqlite_set_result() API.
2142 static void testFunc(sqlite3_context
*context
, int argc
, sqlite3_value
**argv
){
2144 const char *zArg0
= (char*)sqlite3_value_text(argv
[0]);
2146 if( 0==sqlite3StrICmp(zArg0
, "int") ){
2147 sqlite3_result_int(context
, sqlite3_value_int(argv
[1]));
2148 }else if( sqlite3StrICmp(zArg0
,"int64")==0 ){
2149 sqlite3_result_int64(context
, sqlite3_value_int64(argv
[1]));
2150 }else if( sqlite3StrICmp(zArg0
,"string")==0 ){
2151 sqlite3_result_text(context
, (char*)sqlite3_value_text(argv
[1]), -1,
2153 }else if( sqlite3StrICmp(zArg0
,"double")==0 ){
2154 sqlite3_result_double(context
, sqlite3_value_double(argv
[1]));
2155 }else if( sqlite3StrICmp(zArg0
,"null")==0 ){
2156 sqlite3_result_null(context
);
2157 }else if( sqlite3StrICmp(zArg0
,"value")==0 ){
2158 sqlite3_result_value(context
, argv
[sqlite3_value_int(argv
[1])]);
2171 sqlite3_result_error(context
,"first argument should be one of: "
2172 "int int64 string double null value", -1);
2176 ** Usage: sqlite_register_test_function DB NAME
2178 ** Register the test SQL function on the database DB under the name NAME.
2180 static int SQLITE_TCLAPI
test_register_func(
2182 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
2183 int argc
, /* Number of arguments */
2184 char **argv
/* Text of each argument */
2189 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
2190 " DB FUNCTION-NAME", 0);
2193 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
2194 rc
= sqlite3_create_function(db
, argv
[2], -1, SQLITE_UTF8
, 0,
2197 Tcl_AppendResult(interp
, sqlite3ErrStr(rc
), 0);
2200 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
2205 ** Usage: sqlite3_finalize STMT
2207 ** Finalize a statement handle.
2209 static int SQLITE_TCLAPI
test_finalize(
2213 Tcl_Obj
*CONST objv
[]
2215 sqlite3_stmt
*pStmt
;
2220 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2221 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
2225 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2228 db
= StmtToDb(pStmt
);
2230 rc
= sqlite3_finalize(pStmt
);
2231 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
2232 if( db
&& sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
2237 ** Usage: sqlite3_stmt_status STMT CODE RESETFLAG
2239 ** Get the value of a status counter from a statement.
2241 static int SQLITE_TCLAPI
test_stmt_status(
2245 Tcl_Obj
*CONST objv
[]
2248 int i
, op
= 0, resetFlag
;
2249 const char *zOpName
;
2250 sqlite3_stmt
*pStmt
;
2252 static const struct {
2256 { "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP
},
2257 { "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT
},
2258 { "SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX
},
2259 { "SQLITE_STMTSTATUS_VM_STEP", SQLITE_STMTSTATUS_VM_STEP
},
2260 { "SQLITE_STMTSTATUS_REPREPARE", SQLITE_STMTSTATUS_REPREPARE
},
2261 { "SQLITE_STMTSTATUS_RUN", SQLITE_STMTSTATUS_RUN
},
2262 { "SQLITE_STMTSTATUS_MEMUSED", SQLITE_STMTSTATUS_MEMUSED
},
2265 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT PARAMETER RESETFLAG");
2268 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2269 zOpName
= Tcl_GetString(objv
[2]);
2270 for(i
=0; i
<ArraySize(aOp
); i
++){
2271 if( strcmp(aOp
[i
].zName
, zOpName
)==0 ){
2276 if( i
>=ArraySize(aOp
) ){
2277 if( Tcl_GetIntFromObj(interp
, objv
[2], &op
) ) return TCL_ERROR
;
2279 if( Tcl_GetBooleanFromObj(interp
, objv
[3], &resetFlag
) ) return TCL_ERROR
;
2280 iValue
= sqlite3_stmt_status(pStmt
, op
, resetFlag
);
2281 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iValue
));
2285 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
2287 ** Usage: sqlite3_stmt_scanstatus ?-flags FLAGS? STMT IDX
2289 static int SQLITE_TCLAPI
test_stmt_scanstatus(
2293 Tcl_Obj
*CONST objv
[]
2295 sqlite3_stmt
*pStmt
; /* First argument */
2296 int idx
; /* Second argument */
2299 const char *zExplain
;
2300 sqlite3_int64 nLoop
;
2301 sqlite3_int64 nVisit
;
2302 sqlite3_int64 nCycle
;
2315 {"complex", SQLITE_SCANSTAT_COMPLEX
},
2320 Tcl_Obj
**aFlag
= 0;
2324 if( Tcl_ListObjGetElements(interp
, objv
[2], &nFlag
, &aFlag
) ){
2327 for(ii
=0; ii
<nFlag
; ii
++){
2329 int res
= Tcl_GetIndexFromObjStruct(
2330 interp
, aFlag
[ii
], aTbl
, sizeof(aTbl
[0]), "flag", 0, &iVal
2332 if( res
) return TCL_ERROR
;
2333 if( aTbl
[iVal
].flag
==-1 ){
2336 flags
|= aTbl
[iVal
].flag
;
2341 if( objc
!=3 && objc
!=5 ){
2342 Tcl_WrongNumArgs(interp
, 1, objv
, "-flags FLAGS STMT IDX");
2345 if( getStmtPointer(interp
, Tcl_GetString(objv
[objc
-2]), &pStmt
)
2346 || Tcl_GetIntFromObj(interp
, objv
[objc
-1], &idx
)
2351 if( bDebug
&& 0==(flags
& SQLITE_SCANSTAT_COMPLEX
) ){
2352 Tcl_SetObjResult(interp
,
2353 Tcl_NewStringObj("may not specify debug without complex", -1)
2359 Tcl_Obj
*pRet
= Tcl_NewObj();
2360 res
= sqlite3_stmt_scanstatus_v2(
2361 pStmt
, -1, SQLITE_SCANSTAT_NCYCLE
, flags
, (void*)&nCycle
2363 sqlite3_stmt_scanstatus_v2(
2364 pStmt
, idx
, SQLITE_SCANSTAT_NCYCLE
, flags
, (void*)&nCycle
);
2365 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nCycle", -1));
2366 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nCycle
));
2367 Tcl_SetObjResult(interp
, pRet
);
2369 res
= sqlite3_stmt_scanstatus_v2(
2370 pStmt
, idx
, SQLITE_SCANSTAT_NLOOP
, flags
, (void*)&nLoop
2373 Tcl_Obj
*pRet
= Tcl_NewObj();
2374 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nLoop", -1));
2375 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nLoop
));
2376 sqlite3_stmt_scanstatus_v2(
2377 pStmt
, idx
, SQLITE_SCANSTAT_NVISIT
, flags
, (void*)&nVisit
);
2378 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nVisit", -1));
2379 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nVisit
));
2380 sqlite3_stmt_scanstatus_v2(
2381 pStmt
, idx
, SQLITE_SCANSTAT_EST
, flags
, (void*)&rEst
);
2382 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nEst", -1));
2383 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewDoubleObj(rEst
));
2384 sqlite3_stmt_scanstatus_v2(
2385 pStmt
, idx
, SQLITE_SCANSTAT_NAME
, flags
, (void*)&zName
);
2386 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("zName", -1));
2387 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zName
, -1));
2388 sqlite3_stmt_scanstatus_v2(
2389 pStmt
, idx
, SQLITE_SCANSTAT_EXPLAIN
, flags
, (void*)&zExplain
);
2390 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("zExplain", -1));
2391 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj(zExplain
, -1));
2392 sqlite3_stmt_scanstatus_v2(
2393 pStmt
, idx
, SQLITE_SCANSTAT_SELECTID
, flags
, (void*)&iSelectId
);
2394 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("iSelectId", -1));
2395 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(iSelectId
));
2396 sqlite3_stmt_scanstatus_v2(
2397 pStmt
, idx
, SQLITE_SCANSTAT_PARENTID
, flags
, (void*)&iParentId
);
2398 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("iParentId", -1));
2399 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(iParentId
));
2400 sqlite3_stmt_scanstatus_v2(
2401 pStmt
, idx
, SQLITE_SCANSTAT_NCYCLE
, flags
, (void*)&nCycle
);
2402 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("nCycle", -1));
2403 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewWideIntObj(nCycle
));
2407 ScanStatus
*pScan
= &((Vdbe
*)pStmt
)->aScan
[idx
];
2408 Tcl_Obj
*pRange
= Tcl_NewObj();
2409 Tcl_Obj
*pCsr
= Tcl_NewObj();
2411 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("debug_loop", -1));
2412 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(pScan
->addrLoop
));
2413 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("debug_visit", -1));
2414 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(pScan
->addrVisit
));
2415 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("debug_explain",-1));
2416 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewIntObj(pScan
->addrExplain
));
2417 for(ii
=0; ii
<ArraySize(pScan
->aAddrRange
)/2; ii
++){
2418 int iStart
= pScan
->aAddrRange
[ii
*2];
2419 int iEnd
= pScan
->aAddrRange
[ii
*2+1];
2421 Tcl_ListObjAppendElement(0, pRange
, Tcl_NewIntObj(iStart
));
2422 Tcl_ListObjAppendElement(0, pRange
, Tcl_NewIntObj(iEnd
));
2423 }else if( iStart
<0 ){
2424 Tcl_ListObjAppendElement(0, pCsr
, Tcl_NewIntObj(iEnd
));
2428 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("debug_range", -1));
2429 Tcl_ListObjAppendElement(0, pRet
, pRange
);
2430 Tcl_ListObjAppendElement(0, pRet
, Tcl_NewStringObj("debug_csr", -1));
2431 Tcl_ListObjAppendElement(0, pRet
, pCsr
);
2434 Tcl_SetObjResult(interp
, pRet
);
2436 Tcl_ResetResult(interp
);
2443 ** Usage: sqlite3_stmt_scanstatus_reset STMT
2445 static int SQLITE_TCLAPI
test_stmt_scanstatus_reset(
2449 Tcl_Obj
*CONST objv
[]
2451 sqlite3_stmt
*pStmt
; /* First argument */
2453 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
2456 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2457 sqlite3_stmt_scanstatus_reset(pStmt
);
2462 #ifdef SQLITE_ENABLE_SQLLOG
2464 ** Usage: sqlite3_config_sqllog
2466 ** Zero the SQLITE_CONFIG_SQLLOG configuration
2468 static int SQLITE_TCLAPI
test_config_sqllog(
2472 Tcl_Obj
*CONST objv
[]
2475 Tcl_WrongNumArgs(interp
, 1, objv
, "");
2478 sqlite3_config(SQLITE_CONFIG_SQLLOG
, 0, 0);
2484 ** Usage: sqlite3_config_sorterref
2486 ** Set the SQLITE_CONFIG_SORTERREF_SIZE configuration option
2488 static int SQLITE_TCLAPI
test_config_sorterref(
2492 Tcl_Obj
*CONST objv
[]
2496 Tcl_WrongNumArgs(interp
, 1, objv
, "NBYTE");
2499 if( Tcl_GetIntFromObj(interp
, objv
[1], &iVal
) ) return TCL_ERROR
;
2500 sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE
, iVal
);
2505 ** Usage: vfs_current_time_int64
2507 ** Return the value returned by the default VFS's xCurrentTimeInt64 method.
2509 static int SQLITE_TCLAPI
vfsCurrentTimeInt64(
2513 Tcl_Obj
*CONST objv
[]
2516 sqlite3_vfs
*pVfs
= sqlite3_vfs_find(0);
2518 Tcl_WrongNumArgs(interp
, 1, objv
, "");
2521 pVfs
->xCurrentTimeInt64(pVfs
, &t
);
2522 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(t
));
2526 #ifndef SQLITE_OMIT_VIRTUALTABLE
2528 ** Usage: create_null_module DB NAME
2530 static int SQLITE_TCLAPI
test_create_null_module(
2534 Tcl_Obj
*CONST objv
[]
2540 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2543 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2544 zName
= Tcl_GetString(objv
[2]);
2546 sqlite3_create_module(db
, zName
, 0, 0);
2549 #endif /* SQLITE_OMIT_VIRTUALTABLE */
2551 #ifdef SQLITE_ENABLE_SNAPSHOT
2553 ** Usage: sqlite3_snapshot_get DB DBNAME
2555 static int SQLITE_TCLAPI
test_snapshot_get(
2559 Tcl_Obj
*CONST objv
[]
2564 sqlite3_snapshot
*pSnapshot
= 0;
2567 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2570 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2571 zName
= Tcl_GetString(objv
[2]);
2573 rc
= sqlite3_snapshot_get(db
, zName
, &pSnapshot
);
2574 if( rc
!=SQLITE_OK
){
2575 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2579 if( sqlite3TestMakePointerStr(interp
, zBuf
, pSnapshot
) ) return TCL_ERROR
;
2580 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zBuf
, -1));
2584 #endif /* SQLITE_ENABLE_SNAPSHOT */
2586 #ifdef SQLITE_ENABLE_SNAPSHOT
2588 ** Usage: sqlite3_snapshot_recover DB DBNAME
2590 static int SQLITE_TCLAPI
test_snapshot_recover(
2594 Tcl_Obj
*CONST objv
[]
2601 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2604 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2605 zName
= Tcl_GetString(objv
[2]);
2607 rc
= sqlite3_snapshot_recover(db
, zName
);
2608 if( rc
!=SQLITE_OK
){
2609 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2612 Tcl_ResetResult(interp
);
2616 #endif /* SQLITE_ENABLE_SNAPSHOT */
2618 #ifdef SQLITE_ENABLE_SNAPSHOT
2620 ** Usage: sqlite3_snapshot_open DB DBNAME SNAPSHOT
2622 static int SQLITE_TCLAPI
test_snapshot_open(
2626 Tcl_Obj
*CONST objv
[]
2631 sqlite3_snapshot
*pSnapshot
;
2634 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SNAPSHOT");
2637 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2638 zName
= Tcl_GetString(objv
[2]);
2639 pSnapshot
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[3]));
2641 rc
= sqlite3_snapshot_open(db
, zName
, pSnapshot
);
2642 if( rc
!=SQLITE_OK
){
2643 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2646 Tcl_ResetResult(interp
);
2650 #endif /* SQLITE_ENABLE_SNAPSHOT */
2652 #ifdef SQLITE_ENABLE_SNAPSHOT
2654 ** Usage: sqlite3_snapshot_free SNAPSHOT
2656 static int SQLITE_TCLAPI
test_snapshot_free(
2660 Tcl_Obj
*CONST objv
[]
2662 sqlite3_snapshot
*pSnapshot
;
2664 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT");
2667 pSnapshot
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[1]));
2668 sqlite3_snapshot_free(pSnapshot
);
2671 #endif /* SQLITE_ENABLE_SNAPSHOT */
2673 #ifdef SQLITE_ENABLE_SNAPSHOT
2675 ** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2
2677 static int SQLITE_TCLAPI
test_snapshot_cmp(
2681 Tcl_Obj
*CONST objv
[]
2684 sqlite3_snapshot
*p1
;
2685 sqlite3_snapshot
*p2
;
2687 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT1 SNAPSHOT2");
2690 p1
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[1]));
2691 p2
= (sqlite3_snapshot
*)sqlite3TestTextToPtr(Tcl_GetString(objv
[2]));
2692 res
= sqlite3_snapshot_cmp(p1
, p2
);
2693 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
2696 #endif /* SQLITE_ENABLE_SNAPSHOT */
2698 #ifdef SQLITE_ENABLE_SNAPSHOT
2700 ** Usage: sqlite3_snapshot_get_blob DB DBNAME
2702 static int SQLITE_TCLAPI
test_snapshot_get_blob(
2706 Tcl_Obj
*CONST objv
[]
2711 sqlite3_snapshot
*pSnapshot
= 0;
2714 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
2717 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2718 zName
= Tcl_GetString(objv
[2]);
2720 rc
= sqlite3_snapshot_get(db
, zName
, &pSnapshot
);
2721 if( rc
!=SQLITE_OK
){
2722 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2725 Tcl_SetObjResult(interp
,
2726 Tcl_NewByteArrayObj((unsigned char*)pSnapshot
, sizeof(sqlite3_snapshot
))
2728 sqlite3_snapshot_free(pSnapshot
);
2732 #endif /* SQLITE_ENABLE_SNAPSHOT */
2734 #ifdef SQLITE_ENABLE_SNAPSHOT
2736 ** Usage: sqlite3_snapshot_open_blob DB DBNAME SNAPSHOT
2738 static int SQLITE_TCLAPI
test_snapshot_open_blob(
2742 Tcl_Obj
*CONST objv
[]
2747 unsigned char *pBlob
;
2751 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SNAPSHOT");
2754 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2755 zName
= Tcl_GetString(objv
[2]);
2756 pBlob
= Tcl_GetByteArrayFromObj(objv
[3], &nBlob
);
2757 if( nBlob
!=sizeof(sqlite3_snapshot
) ){
2758 Tcl_AppendResult(interp
, "bad SNAPSHOT", 0);
2761 rc
= sqlite3_snapshot_open(db
, zName
, (sqlite3_snapshot
*)pBlob
);
2762 if( rc
!=SQLITE_OK
){
2763 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2768 #endif /* SQLITE_ENABLE_SNAPSHOT */
2770 #ifdef SQLITE_ENABLE_SNAPSHOT
2772 ** Usage: sqlite3_snapshot_cmp_blob SNAPSHOT1 SNAPSHOT2
2774 static int SQLITE_TCLAPI
test_snapshot_cmp_blob(
2778 Tcl_Obj
*CONST objv
[]
2787 Tcl_WrongNumArgs(interp
, 1, objv
, "SNAPSHOT1 SNAPSHOT2");
2791 p1
= Tcl_GetByteArrayFromObj(objv
[1], &n1
);
2792 p2
= Tcl_GetByteArrayFromObj(objv
[2], &n2
);
2794 if( n1
!=sizeof(sqlite3_snapshot
) || n1
!=n2
){
2795 Tcl_AppendResult(interp
, "bad SNAPSHOT", 0);
2799 res
= sqlite3_snapshot_cmp((sqlite3_snapshot
*)p1
, (sqlite3_snapshot
*)p2
);
2800 Tcl_SetObjResult(interp
, Tcl_NewIntObj(res
));
2803 #endif /* SQLITE_ENABLE_SNAPSHOT */
2806 ** Usage: sqlite3_delete_database FILENAME
2808 int sqlite3_delete_database(const char*); /* in test_delete.c */
2809 static int SQLITE_TCLAPI
test_delete_database(
2813 Tcl_Obj
*CONST objv
[]
2818 Tcl_WrongNumArgs(interp
, 1, objv
, "FILE");
2821 zFile
= (const char*)Tcl_GetString(objv
[1]);
2822 rc
= sqlite3_delete_database(zFile
);
2824 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
2829 ** Usage: atomic_batch_write PATH
2831 static int SQLITE_TCLAPI
test_atomic_batch_write(
2835 Tcl_Obj
*CONST objv
[]
2837 char *zFile
= 0; /* Path to file to test */
2838 sqlite3
*db
= 0; /* Database handle */
2839 sqlite3_file
*pFd
= 0; /* SQLite fd open on zFile */
2840 int bRes
= 0; /* Integer result of this command */
2841 int dc
= 0; /* Device-characteristics mask */
2842 int rc
; /* sqlite3_open() return code */
2845 Tcl_WrongNumArgs(interp
, 1, objv
, "PATH");
2848 zFile
= Tcl_GetString(objv
[1]);
2850 rc
= sqlite3_open(zFile
, &db
);
2851 if( rc
!=SQLITE_OK
){
2852 Tcl_AppendResult(interp
, sqlite3_errmsg(db
), 0);
2857 rc
= sqlite3_file_control(db
, "main", SQLITE_FCNTL_FILE_POINTER
, (void*)&pFd
);
2858 dc
= pFd
->pMethods
->xDeviceCharacteristics(pFd
);
2859 if( dc
& SQLITE_IOCAP_BATCH_ATOMIC
){
2863 Tcl_SetObjResult(interp
, Tcl_NewIntObj(bRes
));
2869 ** Usage: sqlite3_next_stmt DB STMT
2871 ** Return the next statement in sequence after STMT.
2873 static int SQLITE_TCLAPI
test_next_stmt(
2877 Tcl_Obj
*CONST objv
[]
2879 sqlite3_stmt
*pStmt
;
2884 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2885 Tcl_GetStringFromObj(objv
[0], 0), " DB STMT", 0);
2889 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
2890 if( getStmtPointer(interp
, Tcl_GetString(objv
[2]), &pStmt
) ) return TCL_ERROR
;
2891 pStmt
= sqlite3_next_stmt(db
, pStmt
);
2893 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
2894 Tcl_AppendResult(interp
, zBuf
, 0);
2900 ** Usage: sqlite3_stmt_readonly STMT
2902 ** Return true if STMT is a NULL pointer or a pointer to a statement
2903 ** that is guaranteed to leave the database unmodified.
2905 static int SQLITE_TCLAPI
test_stmt_readonly(
2909 Tcl_Obj
*CONST objv
[]
2911 sqlite3_stmt
*pStmt
;
2915 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2916 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2920 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2921 rc
= sqlite3_stmt_readonly(pStmt
);
2922 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(rc
));
2927 ** Usage: sqlite3_stmt_isexplain STMT
2929 ** Return 1, 2, or 0 respectively if STMT is an EXPLAIN statement, an
2930 ** EXPLAIN QUERY PLAN statement or an ordinary statement or NULL pointer.
2932 static int SQLITE_TCLAPI
test_stmt_isexplain(
2936 Tcl_Obj
*CONST objv
[]
2938 sqlite3_stmt
*pStmt
;
2942 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2943 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
2947 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2948 rc
= sqlite3_stmt_isexplain(pStmt
);
2949 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
2954 ** Usage: sqlite3_stmt_explain STMT INT
2956 ** Set the explain to normal (0), EXPLAIN (1) or EXPLAIN QUERY PLAN (2).
2958 static int SQLITE_TCLAPI
test_stmt_explain(
2962 Tcl_Obj
*CONST objv
[]
2964 sqlite3_stmt
*pStmt
;
2969 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2970 Tcl_GetStringFromObj(objv
[0], 0), " STMT INT", 0);
2974 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
2975 if( Tcl_GetIntFromObj(interp
, objv
[2], &eMode
) ) return TCL_ERROR
;
2976 rc
= sqlite3_stmt_explain(pStmt
, eMode
);
2977 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
2982 ** Usage: sqlite3_stmt_busy STMT
2984 ** Return true if STMT is a non-NULL pointer to a statement
2985 ** that has been stepped but not to completion.
2987 static int SQLITE_TCLAPI
test_stmt_busy(
2991 Tcl_Obj
*CONST objv
[]
2993 sqlite3_stmt
*pStmt
;
2997 Tcl_AppendResult(interp
, "wrong # args: should be \"",
2998 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
3002 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3003 rc
= sqlite3_stmt_busy(pStmt
);
3004 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(rc
));
3009 ** Usage: uses_stmt_journal STMT
3011 ** Return true if STMT uses a statement journal.
3013 static int SQLITE_TCLAPI
uses_stmt_journal(
3017 Tcl_Obj
*CONST objv
[]
3019 sqlite3_stmt
*pStmt
;
3022 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3023 Tcl_GetStringFromObj(objv
[0], 0), " STMT", 0);
3027 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3028 sqlite3_stmt_readonly(pStmt
);
3029 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(((Vdbe
*)pStmt
)->usesStmtJournal
));
3035 ** Usage: sqlite3_reset STMT
3037 ** Reset a statement handle.
3039 static int SQLITE_TCLAPI
test_reset(
3043 Tcl_Obj
*CONST objv
[]
3045 sqlite3_stmt
*pStmt
;
3049 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3050 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
3054 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3056 rc
= sqlite3_reset(pStmt
);
3057 if( pStmt
&& sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ){
3060 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
3070 ** Usage: sqlite3_expired STMT
3072 ** Return TRUE if a recompilation of the statement is recommended.
3074 static int SQLITE_TCLAPI
test_expired(
3078 Tcl_Obj
*CONST objv
[]
3080 #ifndef SQLITE_OMIT_DEPRECATED
3081 sqlite3_stmt
*pStmt
;
3083 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3084 Tcl_GetStringFromObj(objv
[0], 0), " <STMT>", 0);
3087 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3088 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(sqlite3_expired(pStmt
)));
3094 ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT
3096 ** Transfer all bindings from FROMSTMT over to TOSTMT
3098 static int SQLITE_TCLAPI
test_transfer_bind(
3102 Tcl_Obj
*CONST objv
[]
3104 #ifndef SQLITE_OMIT_DEPRECATED
3105 sqlite3_stmt
*pStmt1
, *pStmt2
;
3107 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3108 Tcl_GetStringFromObj(objv
[0], 0), " FROM-STMT TO-STMT", 0);
3111 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt1
)) return TCL_ERROR
;
3112 if( getStmtPointer(interp
, Tcl_GetString(objv
[2]), &pStmt2
)) return TCL_ERROR
;
3113 Tcl_SetObjResult(interp
,
3114 Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1
,pStmt2
)));
3120 ** Usage: sqlite3_changes DB
3122 ** Return the number of changes made to the database by the last SQL
3125 static int SQLITE_TCLAPI
test_changes(
3129 Tcl_Obj
*CONST objv
[]
3133 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3134 Tcl_GetString(objv
[0]), " DB", 0);
3137 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3138 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_changes(db
)));
3143 ** This is the "static_bind_value" that variables are bound to when
3144 ** the FLAG option of sqlite3_bind is "static"
3146 static char *sqlite_static_bind_value
= 0;
3147 static int sqlite_static_bind_nbyte
= 0;
3150 ** Usage: sqlite3_bind VM IDX VALUE FLAGS
3152 ** Sets the value of the IDX-th occurrence of "?" in the original SQL
3153 ** string. VALUE is the new value. If FLAGS=="null" then VALUE is
3154 ** ignored and the value is set to NULL. If FLAGS=="static" then
3155 ** the value is set to the value of a static variable named
3156 ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy
3157 ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored
3158 ** an a 10-byte blob "abc\000xyz\000pq" is inserted.
3160 static int SQLITE_TCLAPI
test_bind(
3162 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
3163 int argc
, /* Number of arguments */
3164 char **argv
/* Text of each argument */
3166 sqlite3_stmt
*pStmt
;
3170 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
3171 " VM IDX VALUE (null|static|normal)\"", 0);
3174 if( getStmtPointer(interp
, argv
[1], &pStmt
) ) return TCL_ERROR
;
3175 if( Tcl_GetInt(interp
, argv
[2], &idx
) ) return TCL_ERROR
;
3176 if( strcmp(argv
[4],"null")==0 ){
3177 rc
= sqlite3_bind_null(pStmt
, idx
);
3178 }else if( strcmp(argv
[4],"static")==0 ){
3179 rc
= sqlite3_bind_text(pStmt
, idx
, sqlite_static_bind_value
, -1, 0);
3180 }else if( strcmp(argv
[4],"static-nbytes")==0 ){
3181 rc
= sqlite3_bind_text(pStmt
, idx
, sqlite_static_bind_value
,
3182 sqlite_static_bind_nbyte
, 0);
3183 }else if( strcmp(argv
[4],"normal")==0 ){
3184 rc
= sqlite3_bind_text(pStmt
, idx
, argv
[3], -1, SQLITE_TRANSIENT
);
3185 }else if( strcmp(argv
[4],"blob10")==0 ){
3186 rc
= sqlite3_bind_text(pStmt
, idx
, "abc\000xyz\000pq", 10, SQLITE_STATIC
);
3188 Tcl_AppendResult(interp
, "4th argument should be "
3189 "\"null\" or \"static\" or \"normal\"", 0);
3192 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3195 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
3196 Tcl_AppendResult(interp
, zBuf
, sqlite3ErrStr(rc
), 0);
3202 #ifndef SQLITE_OMIT_UTF16
3204 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be>
3206 ** This function is used to test that SQLite selects the correct collation
3207 ** sequence callback when multiple versions (for different text encodings)
3210 ** Calling this routine registers the collation sequence "test_collate"
3211 ** with database handle <db>. The second argument must be a list of three
3212 ** boolean values. If the first is true, then a version of test_collate is
3213 ** registered for UTF-8, if the second is true, a version is registered for
3214 ** UTF-16le, if the third is true, a UTF-16be version is available.
3215 ** Previous versions of test_collate are deleted.
3217 ** The collation sequence test_collate is implemented by calling the
3218 ** following TCL script:
3220 ** "test_collate <enc> <lhs> <rhs>"
3222 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8.
3223 ** The <enc> parameter is the encoding of the collation function that
3224 ** SQLite selected to call. The TCL test script implements the
3225 ** "test_collate" proc.
3227 ** Note that this will only work with one interpreter at a time, as the
3228 ** interp pointer to use when evaluating the TCL script is stored in
3229 ** pTestCollateInterp.
3231 static Tcl_Interp
* pTestCollateInterp
;
3232 static int test_collate_func(
3234 int nA
, const void *zA
,
3235 int nB
, const void *zB
3237 Tcl_Interp
*i
= pTestCollateInterp
;
3238 int encin
= SQLITE_PTR_TO_INT(pCtx
);
3242 sqlite3_value
*pVal
;
3245 pX
= Tcl_NewStringObj("test_collate", -1);
3246 Tcl_IncrRefCount(pX
);
3250 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-8",-1));
3252 case SQLITE_UTF16LE
:
3253 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-16LE",-1));
3255 case SQLITE_UTF16BE
:
3256 Tcl_ListObjAppendElement(i
,pX
,Tcl_NewStringObj("UTF-16BE",-1));
3262 sqlite3BeginBenignMalloc();
3263 pVal
= sqlite3ValueNew(0);
3265 sqlite3ValueSetStr(pVal
, nA
, zA
, encin
, SQLITE_STATIC
);
3266 n
= sqlite3_value_bytes(pVal
);
3267 Tcl_ListObjAppendElement(i
,pX
,
3268 Tcl_NewStringObj((char*)sqlite3_value_text(pVal
),n
));
3269 sqlite3ValueSetStr(pVal
, nB
, zB
, encin
, SQLITE_STATIC
);
3270 n
= sqlite3_value_bytes(pVal
);
3271 Tcl_ListObjAppendElement(i
,pX
,
3272 Tcl_NewStringObj((char*)sqlite3_value_text(pVal
),n
));
3273 sqlite3ValueFree(pVal
);
3275 sqlite3EndBenignMalloc();
3277 Tcl_EvalObjEx(i
, pX
, 0);
3278 Tcl_DecrRefCount(pX
);
3279 Tcl_GetIntFromObj(i
, Tcl_GetObjResult(i
), &res
);
3282 static int SQLITE_TCLAPI
test_collate(
3286 Tcl_Obj
*CONST objv
[]
3290 sqlite3_value
*pVal
;
3293 if( objc
!=5 ) goto bad_args
;
3294 pTestCollateInterp
= interp
;
3295 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3297 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
3298 rc
= sqlite3_create_collation(db
, "test_collate", SQLITE_UTF8
,
3299 (void *)SQLITE_UTF8
, val
?test_collate_func
:0);
3300 if( rc
==SQLITE_OK
){
3302 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
3303 rc
= sqlite3_create_collation(db
, "test_collate", SQLITE_UTF16LE
,
3304 (void *)SQLITE_UTF16LE
, val
?test_collate_func
:0);
3305 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[4], &val
) ) return TCL_ERROR
;
3308 if( sqlite3_iMallocFail
>0 ){
3309 sqlite3_iMallocFail
++;
3312 sqlite3_mutex_enter(db
->mutex
);
3313 pVal
= sqlite3ValueNew(db
);
3314 sqlite3ValueSetStr(pVal
, -1, "test_collate", SQLITE_UTF8
, SQLITE_STATIC
);
3315 zUtf16
= sqlite3ValueText(pVal
, SQLITE_UTF16NATIVE
);
3316 if( db
->mallocFailed
){
3319 rc
= sqlite3_create_collation16(db
, zUtf16
, SQLITE_UTF16BE
,
3320 (void *)SQLITE_UTF16BE
, val
?test_collate_func
:0);
3322 sqlite3ValueFree(pVal
);
3323 sqlite3_mutex_leave(db
->mutex
);
3325 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3327 if( rc
!=SQLITE_OK
){
3328 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
3334 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3335 Tcl_GetStringFromObj(objv
[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
3340 ** Usage: add_test_utf16bin_collate <db ptr>
3342 ** Add a utf-16 collation sequence named "utf16bin" to the database
3343 ** handle. This collation sequence compares arguments in the same way as the
3344 ** built-in collation "binary".
3346 static int test_utf16bin_collate_func(
3348 int nA
, const void *zA
,
3349 int nB
, const void *zB
3351 int nCmp
= (nA
>nB
? nB
: nA
);
3352 int res
= memcmp(zA
, zB
, nCmp
);
3353 if( res
==0 ) res
= nA
- nB
;
3356 static int SQLITE_TCLAPI
test_utf16bin_collate(
3360 Tcl_Obj
*CONST objv
[]
3365 if( objc
!=2 ) goto bad_args
;
3366 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3368 rc
= sqlite3_create_collation(db
, "utf16bin", SQLITE_UTF16
, 0,
3369 test_utf16bin_collate_func
3371 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3375 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
3380 ** When the collation needed callback is invoked, record the name of
3381 ** the requested collating function here. The recorded name is linked
3382 ** to a TCL variable and used to make sure that the requested collation
3385 static char zNeededCollation
[200];
3386 static char *pzNeededCollation
= zNeededCollation
;
3390 ** Called when a collating sequence is needed. Registered using
3391 ** sqlite3_collation_needed16().
3393 static void test_collate_needed_cb(
3402 for(z
= (char*)pName
, i
=0; *z
|| z
[1]; z
++){
3403 if( *z
) zNeededCollation
[i
++] = *z
;
3405 zNeededCollation
[i
] = 0;
3406 sqlite3_create_collation(
3407 db
, "test_collate", ENC(db
), SQLITE_INT_TO_PTR(enc
), test_collate_func
);
3411 ** Usage: add_test_collate_needed DB
3413 static int SQLITE_TCLAPI
test_collate_needed(
3417 Tcl_Obj
*CONST objv
[]
3422 if( objc
!=2 ) goto bad_args
;
3423 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3424 rc
= sqlite3_collation_needed16(db
, 0, test_collate_needed_cb
);
3425 zNeededCollation
[0] = 0;
3426 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
3430 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
3435 ** tclcmd: add_alignment_test_collations DB
3437 ** Add two new collating sequences to the database DB
3442 ** Both collating sequences use the same sort order as BINARY.
3443 ** The only difference is that the utf16_aligned collating
3444 ** sequence is declared with the SQLITE_UTF16_ALIGNED flag.
3445 ** Both collating functions increment the unaligned utf16 counter
3446 ** whenever they see a string that begins on an odd byte boundary.
3448 static int unaligned_string_counter
= 0;
3449 static int alignmentCollFunc(
3451 int nKey1
, const void *pKey1
,
3452 int nKey2
, const void *pKey2
3455 n
= nKey1
<nKey2
? nKey1
: nKey2
;
3456 if( nKey1
>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1
))) ) unaligned_string_counter
++;
3457 if( nKey2
>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2
))) ) unaligned_string_counter
++;
3458 rc
= memcmp(pKey1
, pKey2
, n
);
3464 static int SQLITE_TCLAPI
add_alignment_test_collations(
3468 Tcl_Obj
*CONST objv
[]
3472 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3473 sqlite3_create_collation(db
, "utf16_unaligned", SQLITE_UTF16
,
3474 0, alignmentCollFunc
);
3475 sqlite3_create_collation(db
, "utf16_aligned", SQLITE_UTF16_ALIGNED
,
3476 0, alignmentCollFunc
);
3480 #endif /* !defined(SQLITE_OMIT_UTF16) */
3483 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
3485 ** This function is used to test that SQLite selects the correct user
3486 ** function callback when multiple versions (for different text encodings)
3489 ** Calling this routine registers up to three versions of the user function
3490 ** "test_function" with database handle <db>. If the second argument is
3491 ** true, then a version of test_function is registered for UTF-8, if the
3492 ** third is true, a version is registered for UTF-16le, if the fourth is
3493 ** true, a UTF-16be version is available. Previous versions of
3494 ** test_function are deleted.
3496 ** The user function is implemented by calling the following TCL script:
3498 ** "test_function <enc> <arg>"
3500 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the
3501 ** single argument passed to the SQL function. The value returned by
3502 ** the TCL script is used as the return value of the SQL function. It
3503 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8
3504 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that
3505 ** prefers UTF-16BE.
3507 #ifndef SQLITE_OMIT_UTF16
3508 static void test_function_utf8(
3509 sqlite3_context
*pCtx
,
3511 sqlite3_value
**argv
3515 sqlite3_value
*pVal
;
3516 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3517 pX
= Tcl_NewStringObj("test_function", -1);
3518 Tcl_IncrRefCount(pX
);
3519 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-8", -1));
3520 Tcl_ListObjAppendElement(interp
, pX
,
3521 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3522 Tcl_EvalObjEx(interp
, pX
, 0);
3523 Tcl_DecrRefCount(pX
);
3524 sqlite3_result_text(pCtx
, Tcl_GetStringResult(interp
), -1, SQLITE_TRANSIENT
);
3525 pVal
= sqlite3ValueNew(0);
3526 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3527 SQLITE_UTF8
, SQLITE_STATIC
);
3528 sqlite3_result_text16be(pCtx
, sqlite3_value_text16be(pVal
),
3529 -1, SQLITE_TRANSIENT
);
3530 sqlite3ValueFree(pVal
);
3532 static void test_function_utf16le(
3533 sqlite3_context
*pCtx
,
3535 sqlite3_value
**argv
3539 sqlite3_value
*pVal
;
3540 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3541 pX
= Tcl_NewStringObj("test_function", -1);
3542 Tcl_IncrRefCount(pX
);
3543 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-16LE", -1));
3544 Tcl_ListObjAppendElement(interp
, pX
,
3545 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3546 Tcl_EvalObjEx(interp
, pX
, 0);
3547 Tcl_DecrRefCount(pX
);
3548 pVal
= sqlite3ValueNew(0);
3549 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3550 SQLITE_UTF8
, SQLITE_STATIC
);
3551 sqlite3_result_text(pCtx
,(char*)sqlite3_value_text(pVal
),-1,SQLITE_TRANSIENT
);
3552 sqlite3ValueFree(pVal
);
3554 static void test_function_utf16be(
3555 sqlite3_context
*pCtx
,
3557 sqlite3_value
**argv
3561 sqlite3_value
*pVal
;
3562 interp
= (Tcl_Interp
*)sqlite3_user_data(pCtx
);
3563 pX
= Tcl_NewStringObj("test_function", -1);
3564 Tcl_IncrRefCount(pX
);
3565 Tcl_ListObjAppendElement(interp
, pX
, Tcl_NewStringObj("UTF-16BE", -1));
3566 Tcl_ListObjAppendElement(interp
, pX
,
3567 Tcl_NewStringObj((char*)sqlite3_value_text(argv
[0]), -1));
3568 Tcl_EvalObjEx(interp
, pX
, 0);
3569 Tcl_DecrRefCount(pX
);
3570 pVal
= sqlite3ValueNew(0);
3571 sqlite3ValueSetStr(pVal
, -1, Tcl_GetStringResult(interp
),
3572 SQLITE_UTF8
, SQLITE_STATIC
);
3573 sqlite3_result_text16(pCtx
, sqlite3_value_text16le(pVal
),
3574 -1, SQLITE_TRANSIENT
);
3575 sqlite3_result_text16be(pCtx
, sqlite3_value_text16le(pVal
),
3576 -1, SQLITE_TRANSIENT
);
3577 sqlite3_result_text16le(pCtx
, sqlite3_value_text16le(pVal
),
3578 -1, SQLITE_TRANSIENT
);
3579 sqlite3ValueFree(pVal
);
3581 #endif /* SQLITE_OMIT_UTF16 */
3582 static int SQLITE_TCLAPI
test_function(
3586 Tcl_Obj
*CONST objv
[]
3588 #ifndef SQLITE_OMIT_UTF16
3592 if( objc
!=5 ) goto bad_args
;
3593 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
3595 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
3597 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF8
,
3598 interp
, test_function_utf8
, 0, 0);
3600 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
3602 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF16LE
,
3603 interp
, test_function_utf16le
, 0, 0);
3605 if( TCL_OK
!=Tcl_GetBooleanFromObj(interp
, objv
[4], &val
) ) return TCL_ERROR
;
3607 sqlite3_create_function(db
, "test_function", 1, SQLITE_UTF16BE
,
3608 interp
, test_function_utf16be
, 0, 0);
3613 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3614 Tcl_GetStringFromObj(objv
[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
3615 #endif /* SQLITE_OMIT_UTF16 */
3620 ** Usage: sqlite3_test_errstr <err code>
3622 ** Test that the English language string equivalents for sqlite error codes
3623 ** are sane. The parameter is an integer representing an sqlite error code.
3624 ** The result is a list of two elements, the string representation of the
3625 ** error code and the English language explanation.
3627 static int SQLITE_TCLAPI
test_errstr(
3631 Tcl_Obj
*CONST objv
[]
3636 Tcl_WrongNumArgs(interp
, 1, objv
, "<error code>");
3639 zCode
= Tcl_GetString(objv
[1]);
3640 for(i
=0; i
<200; i
++){
3641 if( 0==strcmp(t1ErrorName(i
), zCode
) ) break;
3643 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(i
), 0);
3648 ** Usage: breakpoint
3650 ** This routine exists for one purpose - to provide a place to put a
3651 ** breakpoint with GDB that can be triggered using TCL code. The use
3652 ** for this is when a particular test fails on (say) the 1485th iteration.
3653 ** In the TCL test script, we can add code like this:
3655 ** if {$i==1485} breakpoint
3657 ** Then run testfixture in the debugger and wait for the breakpoint to
3658 ** fire. Then additional breakpoints can be set to trace down the bug.
3660 static int SQLITE_TCLAPI
test_breakpoint(
3662 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
3663 int argc
, /* Number of arguments */
3664 char **argv
/* Text of each argument */
3666 return TCL_OK
; /* Do nothing */
3670 ** Usage: sqlite3_bind_zeroblob STMT IDX N
3672 ** Test the sqlite3_bind_zeroblob interface. STMT is a prepared statement.
3673 ** IDX is the index of a wildcard in the prepared statement. This command
3674 ** binds a N-byte zero-filled BLOB to the wildcard.
3676 static int SQLITE_TCLAPI
test_bind_zeroblob(
3680 Tcl_Obj
*CONST objv
[]
3682 sqlite3_stmt
*pStmt
;
3688 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT IDX N");
3692 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3693 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3694 if( Tcl_GetIntFromObj(interp
, objv
[3], &n
) ) return TCL_ERROR
;
3696 rc
= sqlite3_bind_zeroblob(pStmt
, idx
, n
);
3697 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3698 if( rc
!=SQLITE_OK
){
3706 ** Usage: sqlite3_bind_zeroblob64 STMT IDX N
3708 ** Test the sqlite3_bind_zeroblob64 interface. STMT is a prepared statement.
3709 ** IDX is the index of a wildcard in the prepared statement. This command
3710 ** binds a N-byte zero-filled BLOB to the wildcard.
3712 static int SQLITE_TCLAPI
test_bind_zeroblob64(
3716 Tcl_Obj
*CONST objv
[]
3718 sqlite3_stmt
*pStmt
;
3724 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT IDX N");
3728 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3729 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3730 if( Tcl_GetWideIntFromObj(interp
, objv
[3], &n
) ) return TCL_ERROR
;
3732 rc
= sqlite3_bind_zeroblob64(pStmt
, idx
, n
);
3733 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3734 if( rc
!=SQLITE_OK
){
3735 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
3743 ** Usage: sqlite3_bind_int STMT N VALUE
3745 ** Test the sqlite3_bind_int interface. STMT is a prepared statement.
3746 ** N is the index of a wildcard in the prepared statement. This command
3747 ** binds a 32-bit integer VALUE to that wildcard.
3749 static int SQLITE_TCLAPI
test_bind_int(
3753 Tcl_Obj
*CONST objv
[]
3755 sqlite3_stmt
*pStmt
;
3761 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3762 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3766 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3767 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3768 if( Tcl_GetIntFromObj(interp
, objv
[3], &value
) ) return TCL_ERROR
;
3770 rc
= sqlite3_bind_int(pStmt
, idx
, value
);
3771 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3772 if( rc
!=SQLITE_OK
){
3781 ** Usage: intarray_addr INT ...
3783 ** Return the address of a C-language array of 32-bit integers.
3785 ** Space to hold the array is obtained from malloc(). Call this procedure once
3786 ** with no arguments in order to release memory. Each call to this procedure
3787 ** overwrites the previous array.
3789 static int SQLITE_TCLAPI
test_intarray_addr(
3793 Tcl_Obj
*CONST objv
[]
3801 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3802 if( p
==0 ) return TCL_ERROR
;
3803 for(i
=0; i
<objc
-1; i
++){
3804 if( Tcl_GetIntFromObj(interp
, objv
[1+i
], &p
[i
]) ){
3811 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((uptr
)p
));
3815 ** Usage: intarray_addr INT ...
3817 ** Return the address of a C-language array of 32-bit integers.
3819 ** Space to hold the array is obtained from malloc(). Call this procedure once
3820 ** with no arguments in order to release memory. Each call to this procedure
3821 ** overwrites the previous array.
3823 static int SQLITE_TCLAPI
test_int64array_addr(
3827 Tcl_Obj
*CONST objv
[]
3830 static sqlite3_int64
*p
= 0;
3835 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3836 if( p
==0 ) return TCL_ERROR
;
3837 for(i
=0; i
<objc
-1; i
++){
3839 if( Tcl_GetWideIntFromObj(interp
, objv
[1+i
], &v
) ){
3847 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((uptr
)p
));
3851 ** Usage: doublearray_addr INT ...
3853 ** Return the address of a C-language array of doubles.
3855 ** Space to hold the array is obtained from malloc(). Call this procedure once
3856 ** with no arguments in order to release memory. Each call to this procedure
3857 ** overwrites the previous array.
3859 static int SQLITE_TCLAPI
test_doublearray_addr(
3863 Tcl_Obj
*CONST objv
[]
3866 static double *p
= 0;
3871 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3872 if( p
==0 ) return TCL_ERROR
;
3873 for(i
=0; i
<objc
-1; i
++){
3874 if( Tcl_GetDoubleFromObj(interp
, objv
[1+i
], &p
[i
]) ){
3881 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((uptr
)p
));
3885 ** Usage: textarray_addr TEXT ...
3887 ** Return the address of a C-language array of strings.
3889 ** Space to hold the array is obtained from malloc(). Call this procedure once
3890 ** with no arguments in order to release memory. Each call to this procedure
3891 ** overwrites the previous array.
3893 static int SQLITE_TCLAPI
test_textarray_addr(
3897 Tcl_Obj
*CONST objv
[]
3901 static char **p
= 0;
3903 for(i
=0; i
<n
; i
++) sqlite3_free(p
[i
]);
3907 p
= sqlite3_malloc( sizeof(p
[0])*(objc
-1) );
3908 if( p
==0 ) return TCL_ERROR
;
3909 for(i
=0; i
<objc
-1; i
++){
3910 p
[i
] = sqlite3_mprintf("%s", Tcl_GetString(objv
[1+i
]));
3914 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj((uptr
)p
));
3920 ** Usage: sqlite3_bind_int64 STMT N VALUE
3922 ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement.
3923 ** N is the index of a wildcard in the prepared statement. This command
3924 ** binds a 64-bit integer VALUE to that wildcard.
3926 static int SQLITE_TCLAPI
test_bind_int64(
3930 Tcl_Obj
*CONST objv
[]
3932 sqlite3_stmt
*pStmt
;
3938 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3939 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3943 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
3944 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
3945 if( Tcl_GetWideIntFromObj(interp
, objv
[3], &value
) ) return TCL_ERROR
;
3947 rc
= sqlite3_bind_int64(pStmt
, idx
, value
);
3948 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
3949 if( rc
!=SQLITE_OK
){
3958 ** Usage: sqlite3_bind_double STMT N VALUE
3960 ** Test the sqlite3_bind_double interface. STMT is a prepared statement.
3961 ** N is the index of a wildcard in the prepared statement. This command
3962 ** binds a 64-bit integer VALUE to that wildcard.
3964 static int SQLITE_TCLAPI
test_bind_double(
3968 Tcl_Obj
*CONST objv
[]
3970 sqlite3_stmt
*pStmt
;
3976 static const struct {
3977 const char *zName
; /* Name of the special floating point value */
3978 unsigned int iUpper
; /* Upper 32 bits */
3979 unsigned int iLower
; /* Lower 32 bits */
3981 { "NaN", 0x7fffffff, 0xffffffff },
3982 { "SNaN", 0x7ff7ffff, 0xffffffff },
3983 { "-NaN", 0xffffffff, 0xffffffff },
3984 { "-SNaN", 0xfff7ffff, 0xffffffff },
3985 { "+Inf", 0x7ff00000, 0x00000000 },
3986 { "-Inf", 0xfff00000, 0x00000000 },
3987 { "Epsilon", 0x00000000, 0x00000001 },
3988 { "-Epsilon", 0x80000000, 0x00000001 },
3989 { "NaN0", 0x7ff80000, 0x00000000 },
3990 { "-NaN0", 0xfff80000, 0x00000000 },
3994 Tcl_AppendResult(interp
, "wrong # args: should be \"",
3995 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE", 0);
3999 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4000 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4002 /* Intercept the string "NaN" and generate a NaN value for it.
4003 ** All other strings are passed through to Tcl_GetDoubleFromObj().
4004 ** Tcl_GetDoubleFromObj() should understand "NaN" but some versions
4007 zVal
= Tcl_GetString(objv
[3]);
4008 for(i
=0; i
<sizeof(aSpecialFp
)/sizeof(aSpecialFp
[0]); i
++){
4009 if( strcmp(aSpecialFp
[i
].zName
, zVal
)==0 ){
4011 x
= aSpecialFp
[i
].iUpper
;
4013 x
|= aSpecialFp
[i
].iLower
;
4014 assert( sizeof(value
)==8 );
4015 assert( sizeof(x
)==8 );
4016 memcpy(&value
, &x
, 8);
4020 if( i
>=sizeof(aSpecialFp
)/sizeof(aSpecialFp
[0]) &&
4021 Tcl_GetDoubleFromObj(interp
, objv
[3], &value
) ){
4024 rc
= sqlite3_bind_double(pStmt
, idx
, value
);
4025 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4026 if( rc
!=SQLITE_OK
){
4034 ** Usage: sqlite3_bind_null STMT N
4036 ** Test the sqlite3_bind_null interface. STMT is a prepared statement.
4037 ** N is the index of a wildcard in the prepared statement. This command
4038 ** binds a NULL to the wildcard.
4040 static int SQLITE_TCLAPI
test_bind_null(
4044 Tcl_Obj
*CONST objv
[]
4046 sqlite3_stmt
*pStmt
;
4051 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4052 Tcl_GetStringFromObj(objv
[0], 0), " STMT N", 0);
4056 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4057 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4059 rc
= sqlite3_bind_null(pStmt
, idx
);
4060 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4061 if( rc
!=SQLITE_OK
){
4069 ** Usage: sqlite3_bind_text STMT N STRING BYTES
4071 ** Test the sqlite3_bind_text interface. STMT is a prepared statement.
4072 ** N is the index of a wildcard in the prepared statement. This command
4073 ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes
4076 static int SQLITE_TCLAPI
test_bind_text(
4080 Tcl_Obj
*CONST objv
[]
4082 sqlite3_stmt
*pStmt
;
4091 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4092 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE BYTES", 0);
4096 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4097 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4098 value
= (char*)Tcl_GetByteArrayFromObj(objv
[3], &trueLength
);
4099 if( Tcl_GetIntFromObj(interp
, objv
[4], &bytes
) ) return TCL_ERROR
;
4101 toFree
= malloc( trueLength
+ 1 );
4103 Tcl_AppendResult(interp
, "out of memory", (void*)0);
4106 memcpy(toFree
, value
, trueLength
);
4107 toFree
[trueLength
] = 0;
4110 rc
= sqlite3_bind_text(pStmt
, idx
, value
, bytes
, SQLITE_TRANSIENT
);
4112 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4113 if( rc
!=SQLITE_OK
){
4114 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), (void*)0);
4122 ** Usage: sqlite3_bind_text16 ?-static? STMT N STRING BYTES
4124 ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement.
4125 ** N is the index of a wildcard in the prepared statement. This command
4126 ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes
4129 static int SQLITE_TCLAPI
test_bind_text16(
4133 Tcl_Obj
*CONST objv
[]
4135 #ifndef SQLITE_OMIT_UTF16
4136 sqlite3_stmt
*pStmt
;
4144 void (*xDel
)(void*) = (objc
==6?SQLITE_STATIC
:SQLITE_TRANSIENT
);
4145 Tcl_Obj
*oStmt
= objv
[objc
-4];
4146 Tcl_Obj
*oN
= objv
[objc
-3];
4147 Tcl_Obj
*oString
= objv
[objc
-2];
4148 Tcl_Obj
*oBytes
= objv
[objc
-1];
4150 if( objc
!=5 && objc
!=6){
4151 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4152 Tcl_GetStringFromObj(objv
[0], 0), " STMT N VALUE BYTES", 0);
4156 if( getStmtPointer(interp
, Tcl_GetString(oStmt
), &pStmt
) ) return TCL_ERROR
;
4157 if( Tcl_GetIntFromObj(interp
, oN
, &idx
) ) return TCL_ERROR
;
4158 value
= (char*)Tcl_GetByteArrayFromObj(oString
, &trueLength
);
4159 if( Tcl_GetIntFromObj(interp
, oBytes
, &bytes
) ) return TCL_ERROR
;
4160 if( bytes
<0 && xDel
==SQLITE_TRANSIENT
){
4161 toFree
= malloc( trueLength
+ 3 );
4163 Tcl_AppendResult(interp
, "out of memory", (void*)0);
4166 memcpy(toFree
, value
, trueLength
);
4167 memset(toFree
+trueLength
, 0, 3);
4170 rc
= sqlite3_bind_text16(pStmt
, idx
, (void *)value
, bytes
, xDel
);
4172 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4173 if( rc
!=SQLITE_OK
){
4174 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
4178 #endif /* SQLITE_OMIT_UTF16 */
4183 ** Usage: sqlite3_bind_blob ?-static? STMT N DATA BYTES
4185 ** Test the sqlite3_bind_blob interface. STMT is a prepared statement.
4186 ** N is the index of a wildcard in the prepared statement. This command
4187 ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size.
4189 static int SQLITE_TCLAPI
test_bind_blob(
4193 Tcl_Obj
*CONST objv
[]
4195 sqlite3_stmt
*pStmt
;
4200 sqlite3_destructor_type xDestructor
= SQLITE_TRANSIENT
;
4202 if( objc
!=5 && objc
!=6 ){
4203 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4204 Tcl_GetStringFromObj(objv
[0], 0), " STMT N DATA BYTES", 0);
4209 xDestructor
= SQLITE_STATIC
;
4213 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4214 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4216 value
= (char*)Tcl_GetByteArrayFromObj(objv
[3], &len
);
4217 if( Tcl_GetIntFromObj(interp
, objv
[4], &bytes
) ) return TCL_ERROR
;
4221 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
4222 "cannot use %d blob bytes, have %d", bytes
, len
);
4223 Tcl_AppendResult(interp
, zBuf
, (char*)0);
4227 rc
= sqlite3_bind_blob(pStmt
, idx
, value
, bytes
, xDestructor
);
4228 if( sqlite3TestErrCode(interp
, StmtToDb(pStmt
), rc
) ) return TCL_ERROR
;
4229 if( rc
!=SQLITE_OK
){
4237 ** Usage: sqlite3_bind_value_from_preupdate STMT N NEW|OLD IDX
4239 ** Test the sqlite3_bind_value interface using sqlite3_value objects
4240 ** obtained from either sqlite3_preupdate_new() (if arg[3]=="new") or
4241 ** sqlite3_preupdate_old() if (arg[3]=="old"). IDX is the index to
4242 ** pass to the sqlite3_preupdate_xxx() function.
4244 static int SQLITE_TCLAPI
test_bind_value_from_preupdate(
4248 Tcl_Obj
*CONST objv
[]
4250 sqlite3_stmt
*pStmt
;
4253 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
4256 sqlite3_value
*pVal
= 0;
4260 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT N NEW|OLD IDX");
4264 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4265 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4266 if( Tcl_GetIntFromObj(interp
, objv
[4], &bidx
) ) return TCL_ERROR
;
4268 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
4269 z3
= Tcl_GetString(objv
[3]);
4270 db
= sqlite3_db_handle(pStmt
);
4272 sqlite3_preupdate_new(db
, bidx
, &pVal
);
4273 }else if( z3
[0]=='o' ){
4274 sqlite3_preupdate_old(db
, bidx
, &pVal
);
4276 Tcl_AppendResult(interp
, "expected new or old, got: ", z3
, (char*)0);
4279 sqlite3_bind_value(pStmt
, idx
, pVal
);
4286 ** Usage: sqlite3_bind_value_from_select STMT N SELECT
4288 ** Test the sqlite3_bind_value interface. STMT is a prepared statement.
4289 ** N is the index of a wildcard in the prepared statement.
4291 static int SQLITE_TCLAPI
test_bind_value_from_select(
4295 Tcl_Obj
*CONST objv
[]
4297 sqlite3_stmt
*pStmt
;
4298 sqlite3_stmt
*pStmt2
;
4300 const char *zSql
= 0;
4305 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT N SELECT");
4309 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4310 if( Tcl_GetIntFromObj(interp
, objv
[2], &idx
) ) return TCL_ERROR
;
4311 zSql
= Tcl_GetString(objv
[3]);
4312 db
= sqlite3_db_handle(pStmt
);
4314 rc
= sqlite3_prepare_v2(db
, zSql
, -1, &pStmt2
, 0);
4315 if( rc
!=SQLITE_OK
){
4316 Tcl_AppendResult(interp
, "error in SQL: ", sqlite3_errmsg(db
), (char*)0);
4319 if( sqlite3_step(pStmt2
)==SQLITE_ROW
){
4320 sqlite3_value
*pVal
= sqlite3_column_value(pStmt2
, 0);
4321 sqlite3_bind_value(pStmt
, idx
, pVal
);
4323 rc
= sqlite3_finalize(pStmt2
);
4324 if( rc
!=SQLITE_OK
){
4325 Tcl_AppendResult(interp
,
4326 "error runnning SQL: ", sqlite3_errmsg(db
), (char*)0
4340 # include <sys/uio.h>
4343 #ifndef SQLITE_OMIT_VIRTUALTABLE
4345 ** sqlite3_carray_bind [options...] STMT NAME VALUE ...
4356 ** Each call clears static data. Called with no options does nothing
4357 ** but clear static data.
4359 static int SQLITE_TCLAPI
test_carray_bind(
4363 Tcl_Obj
*CONST objv
[]
4365 sqlite3_stmt
*pStmt
;
4366 int eType
= 0; /* CARRAY_INT32 */
4369 int isTransient
= 0;
4374 void (*xDel
)(void*) = sqlite3_free
;
4375 static void *aStaticData
= 0;
4376 static int nStaticData
= 0;
4377 static int eStaticType
= 0;
4378 extern int sqlite3_carray_bind(
4379 sqlite3_stmt
*pStmt
,
4384 void (*xDestroy
)(void*)
4388 /* Always clear preexisting static data on every call */
4389 if( eStaticType
==3 ){
4390 for(i
=0; i
<nStaticData
; i
++){
4391 sqlite3_free(((char**)aStaticData
)[i
]);
4394 if( eStaticType
==4 ){
4395 for(i
=0; i
<nStaticData
; i
++){
4396 sqlite3_free(((struct iovec
*)aStaticData
)[i
].iov_base
);
4399 sqlite3_free(aStaticData
);
4404 if( objc
==1 ) return TCL_OK
;
4406 for(i
=1; i
<objc
&& Tcl_GetString(objv
[i
])[0]=='-'; i
++){
4407 const char *z
= Tcl_GetString(objv
[i
]);
4408 if( strcmp(z
, "-transient")==0 ){
4410 xDel
= SQLITE_TRANSIENT
;
4412 if( strcmp(z
, "-static")==0 ){
4414 xDel
= SQLITE_STATIC
;
4416 if( strcmp(z
, "-int32")==0 ){
4417 eType
= 0; /* CARRAY_INT32 */
4419 if( strcmp(z
, "-int64")==0 ){
4420 eType
= 1; /* CARRAY_INT64 */
4422 if( strcmp(z
, "-double")==0 ){
4423 eType
= 2; /* CARRAY_DOUBLE */
4425 if( strcmp(z
, "-text")==0 ){
4426 eType
= 3; /* CARRAY_TEXT */
4428 if( strcmp(z
, "-blob")==0 ){
4429 eType
= 4; /* CARRAY_BLOB */
4431 if( strcmp(z
, "--")==0 ){
4435 Tcl_AppendResult(interp
, "unknown option: ", z
, (char*)0);
4439 if( eType
==3 && !isStatic
&& !isTransient
){
4440 Tcl_AppendResult(interp
, "text data must be either -static or -transient",
4444 if( eType
==4 && !isStatic
&& !isTransient
){
4445 Tcl_AppendResult(interp
, "blob data must be either -static or -transient",
4449 if( isStatic
&& isTransient
){
4450 Tcl_AppendResult(interp
, "cannot be both -static and -transient",
4455 Tcl_WrongNumArgs(interp
, 1, objv
, "[OPTIONS] STMT IDX VALUE ...");
4458 if( getStmtPointer(interp
, Tcl_GetString(objv
[i
]), &pStmt
) ) return TCL_ERROR
;
4460 if( Tcl_GetIntFromObj(interp
, objv
[i
], &idx
) ) return TCL_ERROR
;
4463 switch( eType
+ 5*(nData
<=0) ){
4464 case 0: { /* INT32 */
4465 int *a
= sqlite3_malloc( sizeof(int)*nData
);
4466 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4467 for(j
=0; j
<nData
; j
++){
4469 if( Tcl_GetIntFromObj(interp
, objv
[i
+j
], &v
) ){
4478 case 1: { /* INT64 */
4479 sqlite3_int64
*a
= sqlite3_malloc( sizeof(sqlite3_int64
)*nData
);
4480 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4481 for(j
=0; j
<nData
; j
++){
4483 if( Tcl_GetWideIntFromObj(interp
, objv
[i
+j
], &v
) ){
4492 case 2: { /* DOUBLE */
4493 double *a
= sqlite3_malloc( sizeof(double)*nData
);
4494 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4495 for(j
=0; j
<nData
; j
++){
4497 if( Tcl_GetDoubleFromObj(interp
, objv
[i
+j
], &v
) ){
4506 case 3: { /* TEXT */
4507 char **a
= sqlite3_malloc( sizeof(char*)*nData
);
4508 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4509 for(j
=0; j
<nData
; j
++){
4510 const char *v
= Tcl_GetString(objv
[i
+j
]);
4511 a
[j
] = sqlite3_mprintf("%s", v
);
4516 case 4: { /* BLOB */
4517 struct iovec
*a
= sqlite3_malloc( sizeof(struct iovec
)*nData
);
4518 if( a
==0 ){ rc
= SQLITE_NOMEM
; goto carray_bind_done
; }
4519 for(j
=0; j
<nData
; j
++){
4521 unsigned char *v
= Tcl_GetByteArrayFromObj(objv
[i
+i
], &n
);
4523 a
[j
].iov_base
= sqlite3_malloc64( n
);
4524 if( a
[j
].iov_base
==0 ){
4527 memcpy(a
[j
].iov_base
, v
, n
);
4533 case 5: { /* nData==0 */
4535 xDel
= SQLITE_STATIC
;
4542 aStaticData
= aData
;
4543 nStaticData
= nData
;
4544 eStaticType
= eType
;
4546 rc
= sqlite3_carray_bind(pStmt
, idx
, aData
, nData
, eType
, xDel
);
4549 for(i
=0; i
<nData
; i
++) sqlite3_free(((char**)aData
)[i
]);
4552 for(i
=0; i
<nData
; i
++) sqlite3_free(((struct iovec
*)aData
)[i
].iov_base
);
4554 sqlite3_free(aData
);
4558 Tcl_AppendResult(interp
, sqlite3_errstr(rc
), (char*)0);
4563 #endif /* SQLITE_OMIT_VIRTUALTABLE */
4566 ** Usage: sqlite3_bind_parameter_count STMT
4568 ** Return the number of wildcards in the given statement.
4570 static int SQLITE_TCLAPI
test_bind_parameter_count(
4574 Tcl_Obj
*CONST objv
[]
4576 sqlite3_stmt
*pStmt
;
4579 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
4582 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4583 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt
)));
4588 ** Usage: sqlite3_bind_parameter_name STMT N
4590 ** Return the name of the Nth wildcard. The first wildcard is 1.
4591 ** An empty string is returned if N is out of range or if the wildcard
4594 static int SQLITE_TCLAPI
test_bind_parameter_name(
4598 Tcl_Obj
*CONST objv
[]
4600 sqlite3_stmt
*pStmt
;
4604 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT N");
4607 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4608 if( Tcl_GetIntFromObj(interp
, objv
[2], &i
) ) return TCL_ERROR
;
4609 Tcl_SetObjResult(interp
,
4610 Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt
,i
),-1)
4616 ** Usage: sqlite3_bind_parameter_index STMT NAME
4618 ** Return the index of the wildcard called NAME. Return 0 if there is
4619 ** no such wildcard.
4621 static int SQLITE_TCLAPI
test_bind_parameter_index(
4625 Tcl_Obj
*CONST objv
[]
4627 sqlite3_stmt
*pStmt
;
4630 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT NAME");
4633 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4634 Tcl_SetObjResult(interp
,
4636 sqlite3_bind_parameter_index(pStmt
,Tcl_GetString(objv
[2]))
4643 ** Usage: sqlite3_clear_bindings STMT
4646 static int SQLITE_TCLAPI
test_clear_bindings(
4650 Tcl_Obj
*CONST objv
[]
4652 sqlite3_stmt
*pStmt
;
4655 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
4658 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
4659 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt
)));
4664 ** Usage: sqlite3_sleep MILLISECONDS
4666 static int SQLITE_TCLAPI
test_sleep(
4670 Tcl_Obj
*CONST objv
[]
4675 Tcl_WrongNumArgs(interp
, 1, objv
, "MILLISECONDS");
4678 if( Tcl_GetIntFromObj(interp
, objv
[1], &ms
) ){
4681 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_sleep(ms
)));
4686 ** Usage: sqlite3_extended_errcode DB
4688 ** Return the string representation of the most recent sqlite3_* API
4689 ** error code. e.g. "SQLITE_ERROR".
4691 static int SQLITE_TCLAPI
test_ex_errcode(
4695 Tcl_Obj
*CONST objv
[]
4701 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4702 Tcl_GetString(objv
[0]), " DB", 0);
4705 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4706 rc
= sqlite3_extended_errcode(db
);
4707 Tcl_AppendResult(interp
, (char *)t1ErrorName(rc
), 0);
4713 ** Usage: sqlite3_errcode DB
4715 ** Return the string representation of the most recent sqlite3_* API
4716 ** error code. e.g. "SQLITE_ERROR".
4718 static int SQLITE_TCLAPI
test_errcode(
4722 Tcl_Obj
*CONST objv
[]
4728 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4729 Tcl_GetString(objv
[0]), " DB", 0);
4732 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4733 rc
= sqlite3_errcode(db
);
4734 Tcl_AppendResult(interp
, (char *)t1ErrorName(rc
), 0);
4739 ** Usage: sqlite3_errmsg DB
4741 ** Returns the UTF-8 representation of the error message string for the
4742 ** most recent sqlite3_* API call.
4744 static int SQLITE_TCLAPI
test_errmsg(
4748 Tcl_Obj
*CONST objv
[]
4754 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4755 Tcl_GetString(objv
[0]), " DB", 0);
4758 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4760 zErr
= sqlite3_errmsg(db
);
4761 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zErr
, -1));
4767 ** Usage: sqlite3_error_offset DB
4769 ** Return the byte offset into the input UTF8 SQL for the most recent
4770 ** error, or -1 of the error does not refer to a specific token.
4772 static int SQLITE_TCLAPI
test_error_offset(
4776 Tcl_Obj
*CONST objv
[]
4782 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4783 Tcl_GetString(objv
[0]), " DB", 0);
4786 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4788 iByteOffset
= sqlite3_error_offset(db
);
4789 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iByteOffset
));
4794 ** Usage: test_errmsg16 DB
4796 ** Returns the UTF-16 representation of the error message string for the
4797 ** most recent sqlite3_* API call. This is a byte array object at the TCL
4798 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the
4801 static int SQLITE_TCLAPI
test_errmsg16(
4805 Tcl_Obj
*CONST objv
[]
4807 #ifndef SQLITE_OMIT_UTF16
4814 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4815 Tcl_GetString(objv
[0]), " DB", 0);
4818 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4820 zErr
= sqlite3_errmsg16(db
);
4823 for(bytes
=0; z
[bytes
] || z
[bytes
+1]; bytes
+=2){}
4825 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(zErr
, bytes
));
4826 #endif /* SQLITE_OMIT_UTF16 */
4831 ** Usage: sqlite3_prepare DB sql bytes ?tailvar?
4833 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4834 ** database handle <DB>. The parameter <tailval> is the name of a global
4835 ** variable that is set to the unused portion of <sql> (if any). A
4836 ** STMT handle is returned.
4838 static int SQLITE_TCLAPI
test_prepare(
4842 Tcl_Obj
*CONST objv
[]
4847 const char *zTail
= 0;
4848 sqlite3_stmt
*pStmt
= 0;
4852 if( objc
!=5 && objc
!=4 ){
4853 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4854 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
4857 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4858 zSql
= Tcl_GetString(objv
[2]);
4859 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4861 rc
= sqlite3_prepare(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
4862 Tcl_ResetResult(interp
);
4863 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4864 if( zTail
&& objc
>=5 ){
4866 bytes
= bytes
- (int)(zTail
-zSql
);
4868 if( (int)strlen(zTail
)<bytes
){
4869 bytes
= (int)strlen(zTail
);
4871 Tcl_ObjSetVar2(interp
, objv
[4], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
4873 if( rc
!=SQLITE_OK
){
4875 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4876 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4881 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4882 Tcl_AppendResult(interp
, zBuf
, 0);
4888 ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar?
4890 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4891 ** database handle <DB>. The parameter <tailval> is the name of a global
4892 ** variable that is set to the unused portion of <sql> (if any). A
4893 ** STMT handle is returned.
4895 static int SQLITE_TCLAPI
test_prepare_v2(
4899 Tcl_Obj
*CONST objv
[]
4903 char *zCopy
= 0; /* malloc() copy of zSql */
4905 const char *zTail
= 0;
4906 const char **pzTail
;
4907 sqlite3_stmt
*pStmt
= 0;
4911 if( objc
!=5 && objc
!=4 ){
4912 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4913 Tcl_GetString(objv
[0]), " DB sql bytes tailvar", 0);
4916 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4917 zSql
= Tcl_GetString(objv
[2]);
4918 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4920 /* Instead of using zSql directly, make a copy into a buffer obtained
4921 ** directly from malloc(). The idea is to make it easier for valgrind
4922 ** to spot buffer overreads. */
4924 zCopy
= malloc(bytes
);
4925 memcpy(zCopy
, zSql
, bytes
);
4927 int n
= (int)strlen(zSql
) + 1;
4929 memcpy(zCopy
, zSql
, n
);
4931 pzTail
= objc
>=5 ? &zTail
: 0;
4932 rc
= sqlite3_prepare_v2(db
, zCopy
, bytes
, &pStmt
, pzTail
);
4934 zTail
= &zSql
[(zTail
- zCopy
)];
4938 assert(rc
==SQLITE_OK
|| pStmt
==0);
4939 Tcl_ResetResult(interp
);
4940 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
4941 if( rc
==SQLITE_OK
&& objc
>=5 && zTail
){
4943 bytes
= bytes
- (int)(zTail
-zSql
);
4945 Tcl_ObjSetVar2(interp
, objv
[4], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
4947 if( rc
!=SQLITE_OK
){
4949 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
4950 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
4955 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
4956 Tcl_AppendResult(interp
, zBuf
, 0);
4962 ** Usage: sqlite3_prepare_v3 DB sql bytes flags ?tailvar?
4964 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
4965 ** database handle <DB> and flags <flags>. The parameter <tailval> is
4966 ** the name of a global variable that is set to the unused portion of
4967 ** <sql> (if any). A STMT handle is returned.
4969 static int SQLITE_TCLAPI
test_prepare_v3(
4973 Tcl_Obj
*CONST objv
[]
4977 char *zCopy
= 0; /* malloc() copy of zSql */
4979 const char *zTail
= 0;
4980 const char **pzTail
;
4981 sqlite3_stmt
*pStmt
= 0;
4985 if( objc
!=6 && objc
!=5 ){
4986 Tcl_AppendResult(interp
, "wrong # args: should be \"",
4987 Tcl_GetString(objv
[0]), " DB sql bytes flags tailvar", 0);
4990 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
4991 zSql
= Tcl_GetString(objv
[2]);
4992 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
4993 if( Tcl_GetIntFromObj(interp
, objv
[4], &flags
) ) return TCL_ERROR
;
4995 /* Instead of using zSql directly, make a copy into a buffer obtained
4996 ** directly from malloc(). The idea is to make it easier for valgrind
4997 ** to spot buffer overreads. */
4999 zCopy
= malloc(bytes
);
5000 memcpy(zCopy
, zSql
, bytes
);
5002 int n
= (int)strlen(zSql
) + 1;
5004 memcpy(zCopy
, zSql
, n
);
5006 pzTail
= objc
>=6 ? &zTail
: 0;
5007 rc
= sqlite3_prepare_v3(db
, zCopy
, bytes
, (unsigned int)flags
,&pStmt
,pzTail
);
5009 zTail
= &zSql
[(zTail
- zCopy
)];
5011 assert(rc
==SQLITE_OK
|| pStmt
==0);
5012 Tcl_ResetResult(interp
);
5013 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
5014 if( rc
==SQLITE_OK
&& zTail
&& objc
>=6 ){
5016 bytes
= bytes
- (int)(zTail
-zSql
);
5018 Tcl_ObjSetVar2(interp
, objv
[5], 0, Tcl_NewStringObj(zTail
, bytes
), 0);
5020 if( rc
!=SQLITE_OK
){
5022 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
5023 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
5028 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
5029 Tcl_AppendResult(interp
, zBuf
, 0);
5035 ** Usage: sqlite3_prepare_tkt3134 DB
5037 ** Generate a prepared statement for a zero-byte string as a test
5038 ** for ticket #3134. The string should be preceded by a zero byte.
5040 static int SQLITE_TCLAPI
test_prepare_tkt3134(
5044 Tcl_Obj
*CONST objv
[]
5047 static const char zSql
[] = "\000SELECT 1";
5048 sqlite3_stmt
*pStmt
= 0;
5053 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5054 Tcl_GetString(objv
[0]), " DB sql bytes tailvar", 0);
5057 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5058 rc
= sqlite3_prepare_v2(db
, &zSql
[1], 0, &pStmt
, 0);
5059 assert(rc
==SQLITE_OK
|| pStmt
==0);
5060 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
5061 if( rc
!=SQLITE_OK
){
5063 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "(%d) ", rc
);
5064 Tcl_AppendResult(interp
, zBuf
, sqlite3_errmsg(db
), 0);
5069 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
5070 Tcl_AppendResult(interp
, zBuf
, 0);
5076 ** Usage: sqlite3_prepare16 DB sql bytes tailvar
5078 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
5079 ** database handle <DB>. The parameter <tailval> is the name of a global
5080 ** variable that is set to the unused portion of <sql> (if any). A
5081 ** STMT handle is returned.
5083 static int SQLITE_TCLAPI
test_prepare16(
5087 Tcl_Obj
*CONST objv
[]
5089 #ifndef SQLITE_OMIT_UTF16
5092 const void *zTail
= 0;
5094 sqlite3_stmt
*pStmt
= 0;
5097 int bytes
; /* The integer specified as arg 3 */
5098 int objlen
; /* The byte-array length of arg 2 */
5100 if( objc
!=5 && objc
!=4 ){
5101 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5102 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
5105 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5106 zSql
= Tcl_GetByteArrayFromObj(objv
[2], &objlen
);
5107 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
5109 rc
= sqlite3_prepare16(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
5110 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
5117 objlen
= objlen
- (int)((u8
*)zTail
-(u8
*)zSql
);
5121 pTail
= Tcl_NewByteArrayObj((u8
*)zTail
, objlen
);
5122 Tcl_IncrRefCount(pTail
);
5123 Tcl_ObjSetVar2(interp
, objv
[4], 0, pTail
, 0);
5124 Tcl_DecrRefCount(pTail
);
5128 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
5130 Tcl_AppendResult(interp
, zBuf
, 0);
5131 #endif /* SQLITE_OMIT_UTF16 */
5136 ** Usage: sqlite3_prepare16_v2 DB sql bytes ?tailvar?
5138 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using
5139 ** database handle <DB>. The parameter <tailval> is the name of a global
5140 ** variable that is set to the unused portion of <sql> (if any). A
5141 ** STMT handle is returned.
5143 static int SQLITE_TCLAPI
test_prepare16_v2(
5147 Tcl_Obj
*CONST objv
[]
5149 #ifndef SQLITE_OMIT_UTF16
5152 const void *zTail
= 0;
5154 sqlite3_stmt
*pStmt
= 0;
5157 int bytes
; /* The integer specified as arg 3 */
5158 int objlen
; /* The byte-array length of arg 2 */
5160 if( objc
!=5 && objc
!=4 ){
5161 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5162 Tcl_GetString(objv
[0]), " DB sql bytes ?tailvar?", 0);
5165 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
5166 zSql
= Tcl_GetByteArrayFromObj(objv
[2], &objlen
);
5167 if( Tcl_GetIntFromObj(interp
, objv
[3], &bytes
) ) return TCL_ERROR
;
5169 rc
= sqlite3_prepare16_v2(db
, zSql
, bytes
, &pStmt
, objc
>=5 ? &zTail
: 0);
5170 if( sqlite3TestErrCode(interp
, db
, rc
) ) return TCL_ERROR
;
5177 objlen
= objlen
- (int)((u8
*)zTail
-(u8
*)zSql
);
5181 pTail
= Tcl_NewByteArrayObj((u8
*)zTail
, objlen
);
5182 Tcl_IncrRefCount(pTail
);
5183 Tcl_ObjSetVar2(interp
, objv
[4], 0, pTail
, 0);
5184 Tcl_DecrRefCount(pTail
);
5188 if( sqlite3TestMakePointerStr(interp
, zBuf
, pStmt
) ) return TCL_ERROR
;
5190 Tcl_AppendResult(interp
, zBuf
, 0);
5191 #endif /* SQLITE_OMIT_UTF16 */
5196 ** Usage: sqlite3_open filename ?options-list?
5198 static int SQLITE_TCLAPI
test_open(
5202 Tcl_Obj
*CONST objv
[]
5204 const char *zFilename
;
5208 if( objc
!=3 && objc
!=2 && objc
!=1 ){
5209 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5210 Tcl_GetString(objv
[0]), " filename options-list", 0);
5214 zFilename
= objc
>1 ? Tcl_GetString(objv
[1]) : 0;
5215 sqlite3_open(zFilename
, &db
);
5217 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
5218 Tcl_AppendResult(interp
, zBuf
, 0);
5223 ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS
5225 static int SQLITE_TCLAPI
test_open_v2(
5229 Tcl_Obj
*CONST objv
[]
5231 const char *zFilename
;
5243 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME FLAGS VFS");
5246 zFilename
= Tcl_GetString(objv
[1]);
5247 zVfs
= Tcl_GetString(objv
[3]);
5248 if( zVfs
[0]==0x00 ) zVfs
= 0;
5250 rc
= Tcl_ListObjGetElements(interp
, objv
[2], &nFlag
, &apFlag
);
5251 if( rc
!=TCL_OK
) return rc
;
5252 for(i
=0; i
<nFlag
; i
++){
5258 { "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY
},
5259 { "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE
},
5260 { "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE
},
5261 { "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE
},
5262 { "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE
},
5263 { "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY
},
5264 { "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB
},
5265 { "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB
},
5266 { "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB
},
5267 { "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL
},
5268 { "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL
},
5269 { "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL
},
5270 { "SQLITE_OPEN_SUPER_JOURNAL", SQLITE_OPEN_SUPER_JOURNAL
},
5271 { "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX
},
5272 { "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX
},
5273 { "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE
},
5274 { "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE
},
5275 { "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL
},
5276 { "SQLITE_OPEN_URI", SQLITE_OPEN_URI
},
5277 { "SQLITE_OPEN_EXRESCODE", SQLITE_OPEN_EXRESCODE
},
5280 rc
= Tcl_GetIndexFromObjStruct(interp
, apFlag
[i
], aFlag
, sizeof(aFlag
[0]),
5283 if( rc
!=TCL_OK
) return rc
;
5284 flags
|= aFlag
[iFlag
].flag
;
5287 rc
= sqlite3_open_v2(zFilename
, &db
, flags
, zVfs
);
5288 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
5289 Tcl_AppendResult(interp
, zBuf
, 0);
5294 ** Usage: sqlite3_open16 filename options
5296 static int SQLITE_TCLAPI
test_open16(
5300 Tcl_Obj
*CONST objv
[]
5302 #ifndef SQLITE_OMIT_UTF16
5303 const void *zFilename
;
5308 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5309 Tcl_GetString(objv
[0]), " filename options-list", 0);
5313 zFilename
= Tcl_GetByteArrayFromObj(objv
[1], 0);
5314 sqlite3_open16(zFilename
, &db
);
5316 if( sqlite3TestMakePointerStr(interp
, zBuf
, db
) ) return TCL_ERROR
;
5317 Tcl_AppendResult(interp
, zBuf
, 0);
5318 #endif /* SQLITE_OMIT_UTF16 */
5323 ** Usage: sqlite3_complete16 <UTF-16 string>
5325 ** Return 1 if the supplied argument is a complete SQL statement, or zero
5328 static int SQLITE_TCLAPI
test_complete16(
5332 Tcl_Obj
*CONST objv
[]
5334 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16)
5338 Tcl_WrongNumArgs(interp
, 1, objv
, "<utf-16 sql>");
5342 zBuf
= (char*)Tcl_GetByteArrayFromObj(objv
[1], 0);
5343 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_complete16(zBuf
)));
5344 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */
5349 ** Usage: sqlite3_normalize SQL
5351 ** Return the normalized value for an SQL statement.
5353 static int SQLITE_TCLAPI
test_normalize(
5357 Tcl_Obj
*CONST objv
[]
5361 extern char *sqlite3_normalize(const char*);
5364 Tcl_WrongNumArgs(interp
, 1, objv
, "SQL");
5368 zSql
= (char*)Tcl_GetString(objv
[1]);
5369 zNorm
= sqlite3_normalize(zSql
);
5371 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zNorm
, -1));
5372 sqlite3_free(zNorm
);
5378 ** Usage: sqlite3_step STMT
5380 ** Advance the statement to the next row.
5382 static int SQLITE_TCLAPI
test_step(
5386 Tcl_Obj
*CONST objv
[]
5388 sqlite3_stmt
*pStmt
;
5392 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5393 Tcl_GetString(objv
[0]), " STMT", 0);
5397 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5398 rc
= sqlite3_step(pStmt
);
5400 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */
5401 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
5405 static int SQLITE_TCLAPI
test_sql(
5409 Tcl_Obj
*CONST objv
[]
5411 sqlite3_stmt
*pStmt
;
5414 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5418 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5419 Tcl_SetResult(interp
, (char *)sqlite3_sql(pStmt
), TCL_VOLATILE
);
5422 static int SQLITE_TCLAPI
test_ex_sql(
5426 Tcl_Obj
*CONST objv
[]
5428 sqlite3_stmt
*pStmt
;
5432 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5436 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5437 z
= sqlite3_expanded_sql(pStmt
);
5438 Tcl_SetResult(interp
, z
, TCL_VOLATILE
);
5442 #ifdef SQLITE_ENABLE_NORMALIZE
5443 static int SQLITE_TCLAPI
test_norm_sql(
5447 Tcl_Obj
*CONST objv
[]
5449 sqlite3_stmt
*pStmt
;
5452 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
5456 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5457 Tcl_SetResult(interp
, (char *)sqlite3_normalized_sql(pStmt
), TCL_VOLATILE
);
5460 #endif /* SQLITE_ENABLE_NORMALIZE */
5463 ** Usage: sqlite3_column_count STMT
5465 ** Return the number of columns returned by the sql statement STMT.
5467 static int SQLITE_TCLAPI
test_column_count(
5471 Tcl_Obj
*CONST objv
[]
5473 sqlite3_stmt
*pStmt
;
5476 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5477 Tcl_GetString(objv
[0]), " STMT column", 0);
5481 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5483 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_column_count(pStmt
)));
5488 ** Usage: sqlite3_column_type STMT column
5490 ** Return the type of the data in column 'column' of the current row.
5492 static int SQLITE_TCLAPI
test_column_type(
5496 Tcl_Obj
*CONST objv
[]
5498 sqlite3_stmt
*pStmt
;
5503 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5504 Tcl_GetString(objv
[0]), " STMT column", 0);
5508 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5509 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5511 tp
= sqlite3_column_type(pStmt
, col
);
5513 case SQLITE_INTEGER
:
5514 Tcl_SetResult(interp
, "INTEGER", TCL_STATIC
);
5517 Tcl_SetResult(interp
, "NULL", TCL_STATIC
);
5520 Tcl_SetResult(interp
, "FLOAT", TCL_STATIC
);
5523 Tcl_SetResult(interp
, "TEXT", TCL_STATIC
);
5526 Tcl_SetResult(interp
, "BLOB", TCL_STATIC
);
5536 ** Usage: sqlite3_column_int64 STMT column
5538 ** Return the data in column 'column' of the current row cast as an
5539 ** wide (64-bit) integer.
5541 static int SQLITE_TCLAPI
test_column_int64(
5545 Tcl_Obj
*CONST objv
[]
5547 sqlite3_stmt
*pStmt
;
5552 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5553 Tcl_GetString(objv
[0]), " STMT column", 0);
5557 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5558 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5560 iVal
= sqlite3_column_int64(pStmt
, col
);
5561 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(iVal
));
5566 ** Usage: sqlite3_column_blob STMT column
5568 static int SQLITE_TCLAPI
test_column_blob(
5572 Tcl_Obj
*CONST objv
[]
5574 sqlite3_stmt
*pStmt
;
5581 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5582 Tcl_GetString(objv
[0]), " STMT column", 0);
5586 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5587 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5589 len
= sqlite3_column_bytes(pStmt
, col
);
5590 pBlob
= sqlite3_column_blob(pStmt
, col
);
5591 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(pBlob
, len
));
5596 ** Usage: sqlite3_column_double STMT column
5598 ** Return the data in column 'column' of the current row cast as a double.
5600 static int SQLITE_TCLAPI
test_column_double(
5604 Tcl_Obj
*CONST objv
[]
5606 sqlite3_stmt
*pStmt
;
5611 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5612 Tcl_GetString(objv
[0]), " STMT column", 0);
5616 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5617 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5619 rVal
= sqlite3_column_double(pStmt
, col
);
5620 Tcl_SetObjResult(interp
, Tcl_NewDoubleObj(rVal
));
5625 ** Usage: sqlite3_data_count STMT
5627 ** Return the number of columns returned by the sql statement STMT.
5629 static int SQLITE_TCLAPI
test_data_count(
5633 Tcl_Obj
*CONST objv
[]
5635 sqlite3_stmt
*pStmt
;
5638 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5639 Tcl_GetString(objv
[0]), " STMT column", 0);
5643 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5645 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_data_count(pStmt
)));
5650 ** Usage: sqlite3_column_text STMT column
5652 ** Usage: sqlite3_column_decltype STMT column
5654 ** Usage: sqlite3_column_name STMT column
5656 static int SQLITE_TCLAPI
test_stmt_utf8(
5657 void * clientData
, /* Pointer to SQLite API function to be invoke */
5660 Tcl_Obj
*CONST objv
[]
5662 sqlite3_stmt
*pStmt
;
5664 const char *(*xFunc
)(sqlite3_stmt
*, int);
5667 xFunc
= (const char *(*)(sqlite3_stmt
*, int))clientData
;
5669 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5670 Tcl_GetString(objv
[0]), " STMT column", 0);
5674 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5675 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5676 zRet
= xFunc(pStmt
, col
);
5678 Tcl_SetResult(interp
, (char *)zRet
, 0);
5683 static int SQLITE_TCLAPI
test_global_recover(
5687 Tcl_Obj
*CONST objv
[]
5689 #ifndef SQLITE_OMIT_DEPRECATED
5692 Tcl_WrongNumArgs(interp
, 1, objv
, "");
5695 rc
= sqlite3_global_recover();
5696 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5702 ** Usage: sqlite3_column_text STMT column
5704 ** Usage: sqlite3_column_decltype STMT column
5706 ** Usage: sqlite3_column_name STMT column
5708 static int SQLITE_TCLAPI
test_stmt_utf16(
5709 void * clientData
, /* Pointer to SQLite API function to be invoked */
5712 Tcl_Obj
*CONST objv
[]
5714 #ifndef SQLITE_OMIT_UTF16
5715 sqlite3_stmt
*pStmt
;
5718 const void *zName16
;
5719 const void *(*xFunc
)(sqlite3_stmt
*, int);
5721 xFunc
= (const void *(*)(sqlite3_stmt
*, int))clientData
;
5723 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5724 Tcl_GetString(objv
[0]), " STMT column", 0);
5728 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5729 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5731 zName16
= xFunc(pStmt
, col
);
5734 const char *z
= zName16
;
5735 for(n
=0; z
[n
] || z
[n
+1]; n
+=2){}
5736 pRet
= Tcl_NewByteArrayObj(zName16
, n
+2);
5737 Tcl_SetObjResult(interp
, pRet
);
5739 #endif /* SQLITE_OMIT_UTF16 */
5745 ** Usage: sqlite3_column_int STMT column
5747 ** Usage: sqlite3_column_bytes STMT column
5749 ** Usage: sqlite3_column_bytes16 STMT column
5752 static int SQLITE_TCLAPI
test_stmt_int(
5753 void * clientData
, /* Pointer to SQLite API function to be invoked */
5756 Tcl_Obj
*CONST objv
[]
5758 sqlite3_stmt
*pStmt
;
5760 int (*xFunc
)(sqlite3_stmt
*, int);
5762 xFunc
= (int (*)(sqlite3_stmt
*, int))clientData
;
5764 Tcl_AppendResult(interp
, "wrong # args: should be \"",
5765 Tcl_GetString(objv
[0]), " STMT column", 0);
5769 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
5770 if( Tcl_GetIntFromObj(interp
, objv
[2], &col
) ) return TCL_ERROR
;
5772 Tcl_SetObjResult(interp
, Tcl_NewIntObj(xFunc(pStmt
, col
)));
5777 ** Usage: sqlite3_interrupt DB
5779 ** Trigger an interrupt on DB
5781 static int SQLITE_TCLAPI
test_interrupt(
5789 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0], " DB", 0);
5792 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5793 sqlite3_interrupt(db
);
5798 ** Usage: sqlite3_is_interrupted DB
5800 ** return true if an interrupt is current in effect on DB
5802 static int SQLITE_TCLAPI
test_is_interrupted(
5811 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0], " DB", 0);
5814 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5815 rc
= sqlite3_is_interrupted(db
);
5816 Tcl_AppendResult(interp
, rc
? "1" : "0", (void*)0);
5821 ** Usage: sqlite_delete_function DB function-name
5823 ** Delete the user function 'function-name' from database handle DB. It
5824 ** is assumed that the user function was created as UTF8, any number of
5825 ** arguments (the way the TCL interface does it).
5827 static int SQLITE_TCLAPI
delete_function(
5836 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5837 " DB function-name", 0);
5840 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5841 rc
= sqlite3_create_function(db
, argv
[2], -1, SQLITE_UTF8
, 0, 0, 0, 0);
5842 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5847 ** Usage: sqlite_delete_collation DB collation-name
5849 ** Delete the collation sequence 'collation-name' from database handle
5850 ** DB. It is assumed that the collation sequence was created as UTF8 (the
5851 ** way the TCL interface does it).
5853 static int SQLITE_TCLAPI
delete_collation(
5862 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5863 " DB function-name", 0);
5866 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5867 rc
= sqlite3_create_collation(db
, argv
[2], SQLITE_UTF8
, 0, 0);
5868 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
5873 ** Usage: sqlite3_get_autocommit DB
5875 ** Return true if the database DB is currently in auto-commit mode.
5876 ** Return false if not.
5878 static int SQLITE_TCLAPI
get_autocommit(
5887 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5891 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5892 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d", sqlite3_get_autocommit(db
));
5893 Tcl_AppendResult(interp
, zBuf
, 0);
5898 ** Usage: sqlite3_busy_timeout DB MS
5900 ** Set the busy timeout. This is more easily done using the timeout
5901 ** method of the TCL interface. But we need a way to test the case
5902 ** where it returns SQLITE_MISUSE.
5904 static int SQLITE_TCLAPI
test_busy_timeout(
5913 Tcl_AppendResult(interp
, "wrong # args: should be \"", argv
[0],
5917 if( getDbPointer(interp
, argv
[1], &db
) ) return TCL_ERROR
;
5918 if( Tcl_GetInt(interp
, argv
[2], &ms
) ) return TCL_ERROR
;
5919 rc
= sqlite3_busy_timeout(db
, ms
);
5920 Tcl_AppendResult(interp
, sqlite3ErrName(rc
), 0);
5925 ** Usage: tcl_variable_type VARIABLENAME
5927 ** Return the name of the internal representation for the
5928 ** value of the given variable.
5930 static int SQLITE_TCLAPI
tcl_variable_type(
5934 Tcl_Obj
*CONST objv
[]
5938 Tcl_WrongNumArgs(interp
, 1, objv
, "VARIABLE");
5941 pVar
= Tcl_GetVar2Ex(interp
, Tcl_GetString(objv
[1]), 0, TCL_LEAVE_ERR_MSG
);
5942 if( pVar
==0 ) return TCL_ERROR
;
5943 if( pVar
->typePtr
){
5944 Tcl_SetObjResult(interp
, Tcl_NewStringObj(pVar
->typePtr
->name
, -1));
5950 ** Usage: sqlite3_release_memory ?N?
5952 ** Attempt to release memory currently held but not actually required.
5953 ** The integer N is the number of bytes we are trying to release. The
5954 ** return value is the amount of memory actually released.
5956 static int SQLITE_TCLAPI
test_release_memory(
5960 Tcl_Obj
*CONST objv
[]
5962 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
5965 if( objc
!=1 && objc
!=2 ){
5966 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
5970 if( Tcl_GetIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
5974 amt
= sqlite3_release_memory(N
);
5975 Tcl_SetObjResult(interp
, Tcl_NewIntObj(amt
));
5982 ** Usage: sqlite3_db_release_memory DB
5984 ** Attempt to release memory currently held by database DB. Return the
5985 ** result code (which in the current implementation is always zero).
5987 static int SQLITE_TCLAPI
test_db_release_memory(
5991 Tcl_Obj
*CONST objv
[]
5996 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
5999 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6000 rc
= sqlite3_db_release_memory(db
);
6001 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6006 ** Usage: sqlite3_db_cacheflush DB
6008 ** Attempt to flush any dirty pages to disk.
6010 static int SQLITE_TCLAPI
test_db_cacheflush(
6014 Tcl_Obj
*CONST objv
[]
6019 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
6022 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6023 rc
= sqlite3_db_cacheflush(db
);
6025 Tcl_SetResult(interp
, (char *)sqlite3ErrStr(rc
), TCL_STATIC
);
6029 Tcl_ResetResult(interp
);
6034 ** Usage: sqlite3_system_errno DB
6036 ** Return the low-level system errno value.
6038 static int SQLITE_TCLAPI
test_system_errno(
6042 Tcl_Obj
*CONST objv
[]
6047 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
6050 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6051 iErrno
= sqlite3_system_errno(db
);
6052 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iErrno
));
6057 ** Usage: sqlite3_db_filename DB DBNAME
6059 ** Return the name of a file associated with a database.
6061 static int SQLITE_TCLAPI
test_db_filename(
6065 Tcl_Obj
*CONST objv
[]
6068 const char *zDbName
;
6070 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
6073 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6074 zDbName
= Tcl_GetString(objv
[2]);
6075 Tcl_AppendResult(interp
, sqlite3_db_filename(db
, zDbName
), (void*)0);
6080 ** Usage: sqlite3_db_readonly DB DBNAME
6082 ** Return 1 or 0 if DBNAME is readonly or not. Return -1 if DBNAME does
6085 static int SQLITE_TCLAPI
test_db_readonly(
6089 Tcl_Obj
*CONST objv
[]
6092 const char *zDbName
;
6094 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME");
6097 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6098 zDbName
= Tcl_GetString(objv
[2]);
6099 Tcl_SetObjResult(interp
, Tcl_NewIntObj(sqlite3_db_readonly(db
, zDbName
)));
6104 ** Usage: sqlite3_soft_heap_limit ?N?
6106 ** Query or set the soft heap limit for the current thread. The
6107 ** limit is only changed if the N is present. The previous limit
6110 static int SQLITE_TCLAPI
test_soft_heap_limit(
6114 Tcl_Obj
*CONST objv
[]
6118 if( objc
!=1 && objc
!=2 ){
6119 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
6123 if( Tcl_GetWideIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
6125 amt
= sqlite3_soft_heap_limit64(N
);
6126 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(amt
));
6131 ** Usage: sqlite3_hard_heap_limit ?N?
6133 ** Query or set the hard heap limit for the current thread. The
6134 ** limit is only changed if the N is present. The previous limit
6137 static int SQLITE_TCLAPI
test_hard_heap_limit(
6141 Tcl_Obj
*CONST objv
[]
6145 if( objc
!=1 && objc
!=2 ){
6146 Tcl_WrongNumArgs(interp
, 1, objv
, "?N?");
6150 if( Tcl_GetWideIntFromObj(interp
, objv
[1], &N
) ) return TCL_ERROR
;
6152 amt
= sqlite3_hard_heap_limit64(N
);
6153 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(amt
));
6158 ** Usage: sqlite3_thread_cleanup
6160 ** Call the sqlite3_thread_cleanup API.
6162 static int SQLITE_TCLAPI
test_thread_cleanup(
6166 Tcl_Obj
*CONST objv
[]
6168 #ifndef SQLITE_OMIT_DEPRECATED
6169 sqlite3_thread_cleanup();
6175 ** Usage: sqlite3_pager_refcounts DB
6177 ** Return a list of numbers which are the PagerRefcount for all
6178 ** pagers on each database connection.
6180 static int SQLITE_TCLAPI
test_pager_refcounts(
6184 Tcl_Obj
*CONST objv
[]
6192 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6193 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6196 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6197 pResult
= Tcl_NewObj();
6198 for(i
=0; i
<db
->nDb
; i
++){
6199 if( db
->aDb
[i
].pBt
==0 ){
6202 sqlite3_mutex_enter(db
->mutex
);
6203 a
= sqlite3PagerStats(sqlite3BtreePager(db
->aDb
[i
].pBt
));
6205 sqlite3_mutex_leave(db
->mutex
);
6207 Tcl_ListObjAppendElement(0, pResult
, Tcl_NewIntObj(v
));
6209 Tcl_SetObjResult(interp
, pResult
);
6215 ** tclcmd: working_64bit_int
6217 ** Some TCL builds (ex: cygwin) do not support 64-bit integers. This
6218 ** leads to a number of test failures. The present command checks the
6219 ** TCL build to see whether or not it supports 64-bit integers. It
6220 ** returns TRUE if it does and FALSE if not.
6222 ** This command is used to warn users that their TCL build is defective
6223 ** and that the errors they are seeing in the test scripts might be
6224 ** a result of their defective TCL rather than problems in SQLite.
6226 static int SQLITE_TCLAPI
working_64bit_int(
6227 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6228 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6229 int objc
, /* Number of arguments */
6230 Tcl_Obj
*CONST objv
[] /* Command arguments */
6235 pTestObj
= Tcl_NewWideIntObj(1000000*(i64
)1234567890);
6236 working
= strcmp(Tcl_GetString(pTestObj
), "1234567890000000")==0;
6237 Tcl_DecrRefCount(pTestObj
);
6238 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(working
));
6244 ** tclcmd: vfs_unlink_test
6246 ** This TCL command unregisters the primary VFS and then registers
6247 ** it back again. This is used to test the ability to register a
6248 ** VFS when none are previously registered, and the ability to
6249 ** unregister the only available VFS. Ticket #2738
6251 static int SQLITE_TCLAPI
vfs_unlink_test(
6252 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6253 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6254 int objc
, /* Number of arguments */
6255 Tcl_Obj
*CONST objv
[] /* Command arguments */
6259 sqlite3_vfs
*apVfs
[20];
6260 sqlite3_vfs one
, two
;
6262 sqlite3_vfs_unregister(0); /* Unregister of NULL is harmless */
6263 one
.zName
= "__one";
6264 two
.zName
= "__two";
6266 /* Calling sqlite3_vfs_register with 2nd argument of 0 does not
6267 ** change the default VFS
6269 pMain
= sqlite3_vfs_find(0);
6270 sqlite3_vfs_register(&one
, 0);
6271 assert( pMain
==0 || pMain
==sqlite3_vfs_find(0) );
6272 sqlite3_vfs_register(&two
, 0);
6273 assert( pMain
==0 || pMain
==sqlite3_vfs_find(0) );
6275 /* We can find a VFS by its name */
6276 assert( sqlite3_vfs_find("__one")==&one
);
6277 assert( sqlite3_vfs_find("__two")==&two
);
6279 /* Calling sqlite_vfs_register with non-zero second parameter changes the
6280 ** default VFS, even if the 1st parameter is an existing VFS that is
6281 ** previously registered as the non-default.
6283 sqlite3_vfs_register(&one
, 1);
6284 assert( sqlite3_vfs_find("__one")==&one
);
6285 assert( sqlite3_vfs_find("__two")==&two
);
6286 assert( sqlite3_vfs_find(0)==&one
);
6287 sqlite3_vfs_register(&two
, 1);
6288 assert( sqlite3_vfs_find("__one")==&one
);
6289 assert( sqlite3_vfs_find("__two")==&two
);
6290 assert( sqlite3_vfs_find(0)==&two
);
6292 sqlite3_vfs_register(pMain
, 1);
6293 assert( sqlite3_vfs_find("__one")==&one
);
6294 assert( sqlite3_vfs_find("__two")==&two
);
6295 assert( sqlite3_vfs_find(0)==pMain
);
6298 /* Unlink the default VFS. Repeat until there are no more VFSes
6301 for(i
=0; i
<sizeof(apVfs
)/sizeof(apVfs
[0]); i
++){
6302 apVfs
[i
] = sqlite3_vfs_find(0);
6304 assert( apVfs
[i
]==sqlite3_vfs_find(apVfs
[i
]->zName
) );
6305 sqlite3_vfs_unregister(apVfs
[i
]);
6306 assert( 0==sqlite3_vfs_find(apVfs
[i
]->zName
) );
6309 assert( 0==sqlite3_vfs_find(0) );
6311 /* Register the main VFS as non-default (will be made default, since
6312 ** it'll be the only one in existence).
6314 sqlite3_vfs_register(pMain
, 0);
6315 assert( sqlite3_vfs_find(0)==pMain
);
6317 /* Un-register the main VFS again to restore an empty VFS list */
6318 sqlite3_vfs_unregister(pMain
);
6319 assert( 0==sqlite3_vfs_find(0) );
6321 /* Relink all VFSes in reverse order. */
6322 for(i
=sizeof(apVfs
)/sizeof(apVfs
[0])-1; i
>=0; i
--){
6324 sqlite3_vfs_register(apVfs
[i
], 1);
6325 assert( apVfs
[i
]==sqlite3_vfs_find(0) );
6326 assert( apVfs
[i
]==sqlite3_vfs_find(apVfs
[i
]->zName
) );
6330 /* Unregister out sample VFSes. */
6331 sqlite3_vfs_unregister(&one
);
6332 sqlite3_vfs_unregister(&two
);
6334 /* Unregistering a VFS that is not currently registered is harmless */
6335 sqlite3_vfs_unregister(&one
);
6336 sqlite3_vfs_unregister(&two
);
6337 assert( sqlite3_vfs_find("__one")==0 );
6338 assert( sqlite3_vfs_find("__two")==0 );
6340 /* We should be left with the original default VFS back as the
6342 assert( sqlite3_vfs_find(0)==pMain
);
6348 ** tclcmd: vfs_initfail_test
6350 ** This TCL command attempts to vfs_find and vfs_register when the
6351 ** sqlite3_initialize() interface is failing. All calls should fail.
6353 static int SQLITE_TCLAPI
vfs_initfail_test(
6354 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6355 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6356 int objc
, /* Number of arguments */
6357 Tcl_Obj
*CONST objv
[] /* Command arguments */
6360 one
.zName
= "__one";
6362 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
6363 sqlite3_vfs_register(&one
, 0);
6364 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
6365 sqlite3_vfs_register(&one
, 1);
6366 if( sqlite3_vfs_find(0) ) return TCL_ERROR
;
6373 static sqlite3_vfs
*apVfs
[20];
6374 static int nVfs
= 0;
6377 ** tclcmd: vfs_unregister_all
6379 ** Unregister all VFSes.
6381 static int SQLITE_TCLAPI
vfs_unregister_all(
6382 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6383 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6384 int objc
, /* Number of arguments */
6385 Tcl_Obj
*CONST objv
[] /* Command arguments */
6388 for(i
=0; i
<ArraySize(apVfs
); i
++){
6389 apVfs
[i
] = sqlite3_vfs_find(0);
6390 if( apVfs
[i
]==0 ) break;
6391 sqlite3_vfs_unregister(apVfs
[i
]);
6397 ** tclcmd: vfs_reregister_all
6399 ** Restore all VFSes that were removed using vfs_unregister_all. Taking
6400 ** care to put the linked list back together in the same order as it was
6401 ** in before vfs_unregister_all was invoked.
6403 static int SQLITE_TCLAPI
vfs_reregister_all(
6404 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6405 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6406 int objc
, /* Number of arguments */
6407 Tcl_Obj
*CONST objv
[] /* Command arguments */
6410 for(i
=nVfs
-1; i
>=0; i
--){
6411 sqlite3_vfs_register(apVfs
[i
], 1);
6418 ** tclcmd: file_control_test DB
6420 ** This TCL command runs the sqlite3_file_control interface and
6421 ** verifies correct operation of the same.
6423 static int SQLITE_TCLAPI
file_control_test(
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 */
6434 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6435 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6438 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
6439 rc
= sqlite3_file_control(db
, 0, 0, &iArg
);
6440 assert( rc
==SQLITE_NOTFOUND
);
6441 rc
= sqlite3_file_control(db
, "notadatabase", SQLITE_FCNTL_LOCKSTATE
, &iArg
);
6442 assert( rc
==SQLITE_ERROR
);
6443 rc
= sqlite3_file_control(db
, "main", -1, &iArg
);
6444 assert( rc
==SQLITE_NOTFOUND
);
6445 rc
= sqlite3_file_control(db
, "temp", -1, &iArg
);
6446 assert( rc
==SQLITE_NOTFOUND
|| rc
==SQLITE_ERROR
);
6453 ** tclcmd: file_control_lasterrno_test DB
6455 ** This TCL command runs the sqlite3_file_control interface and
6456 ** verifies correct operation of the SQLITE_LAST_ERRNO verb.
6458 static int SQLITE_TCLAPI
file_control_lasterrno_test(
6459 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6460 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6461 int objc
, /* Number of arguments */
6462 Tcl_Obj
*CONST objv
[] /* Command arguments */
6469 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6470 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6473 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6476 rc
= sqlite3_file_control(db
, NULL
, SQLITE_LAST_ERRNO
, &iArg
);
6478 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6482 Tcl_AppendResult(interp
, "Unexpected non-zero errno: ",
6483 Tcl_GetStringFromObj(Tcl_NewIntObj(iArg
), 0), " ", 0);
6490 ** tclcmd: file_control_data_version DB DBNAME
6492 ** This TCL command runs the sqlite3_file_control with the
6493 ** SQLITE_FCNTL_DATA_VERSION opcode, returning the result.
6495 static int SQLITE_TCLAPI
file_control_data_version(
6496 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6497 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6498 int objc
, /* Number of arguments */
6499 Tcl_Obj
*CONST objv
[] /* Command arguments */
6501 unsigned int iVers
; /* data version */
6502 char *zDb
; /* Db name ("main", "temp" etc.) */
6503 sqlite3
*db
; /* Database handle */
6504 int rc
; /* file_control() return code */
6507 if( objc
!=3 && objc
!=2 ){
6508 Tcl_WrongNumArgs(interp
, 1, objv
, "DB [DBNAME]");
6511 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6514 zDb
= objc
==3 ? Tcl_GetString(objv
[2]) : NULL
;
6516 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_DATA_VERSION
, (void *)&iVers
);
6518 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6521 sqlite3_snprintf(sizeof(zBuf
),zBuf
,"%u",iVers
);
6522 Tcl_SetResult(interp
, (char *)zBuf
, TCL_VOLATILE
);
6528 ** tclcmd: file_control_chunksize_test DB DBNAME SIZE
6530 ** This TCL command runs the sqlite3_file_control interface and
6531 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
6532 ** SQLITE_SET_LOCKPROXYFILE verbs.
6534 static int SQLITE_TCLAPI
file_control_chunksize_test(
6535 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6536 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6537 int objc
, /* Number of arguments */
6538 Tcl_Obj
*CONST objv
[] /* Command arguments */
6540 int nSize
; /* New chunk size */
6541 char *zDb
; /* Db name ("main", "temp" etc.) */
6542 sqlite3
*db
; /* Database handle */
6543 int rc
; /* file_control() return code */
6546 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SIZE");
6549 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6550 || Tcl_GetIntFromObj(interp
, objv
[3], &nSize
)
6554 zDb
= Tcl_GetString(objv
[2]);
6555 if( zDb
[0]=='\0' ) zDb
= NULL
;
6557 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_CHUNK_SIZE
, (void *)&nSize
);
6559 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6566 ** tclcmd: file_control_sizehint_test DB DBNAME SIZE
6568 ** This TCL command runs the sqlite3_file_control interface
6569 ** with SQLITE_FCNTL_SIZE_HINT
6571 static int SQLITE_TCLAPI
file_control_sizehint_test(
6572 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6573 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6574 int objc
, /* Number of arguments */
6575 Tcl_Obj
*CONST objv
[] /* Command arguments */
6577 Tcl_WideInt nSize
; /* Hinted size */
6578 char *zDb
; /* Db name ("main", "temp" etc.) */
6579 sqlite3
*db
; /* Database handle */
6580 int rc
; /* file_control() return code */
6583 Tcl_WrongNumArgs(interp
, 1, objv
, "DB DBNAME SIZE");
6586 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6587 || Tcl_GetWideIntFromObj(interp
, objv
[3], &nSize
)
6591 zDb
= Tcl_GetString(objv
[2]);
6592 if( zDb
[0]=='\0' ) zDb
= NULL
;
6594 rc
= sqlite3_file_control(db
, zDb
, SQLITE_FCNTL_SIZE_HINT
, (void *)&nSize
);
6596 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_STATIC
);
6603 ** tclcmd: file_control_lockproxy_test DB PWD
6605 ** This TCL command runs the sqlite3_file_control interface and
6606 ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and
6607 ** SQLITE_SET_LOCKPROXYFILE verbs.
6609 static int SQLITE_TCLAPI
file_control_lockproxy_test(
6610 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6611 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6612 int objc
, /* Number of arguments */
6613 Tcl_Obj
*CONST objv
[] /* Command arguments */
6618 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6619 Tcl_GetStringFromObj(objv
[0], 0), " DB PWD", 0);
6622 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6626 #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
6627 # if defined(__APPLE__)
6628 # define SQLITE_ENABLE_LOCKING_STYLE 1
6630 # define SQLITE_ENABLE_LOCKING_STYLE 0
6633 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
6639 char proxyPath
[400];
6641 zPwd
= Tcl_GetStringFromObj(objv
[2], &nPwd
);
6642 if( sizeof(proxyPath
)<nPwd
+20 ){
6643 Tcl_AppendResult(interp
, "PWD too big", (void*)0);
6646 sqlite3_snprintf(sizeof(proxyPath
), proxyPath
, "%s/test.proxy", zPwd
);
6647 rc
= sqlite3_file_control(db
, NULL
, SQLITE_SET_LOCKPROXYFILE
, proxyPath
);
6649 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6652 rc
= sqlite3_file_control(db
, NULL
, SQLITE_GET_LOCKPROXYFILE
, &testPath
);
6653 if( strncmp(proxyPath
,testPath
,11) ){
6654 Tcl_AppendResult(interp
, "Lock proxy file did not match the "
6655 "previously assigned value", 0);
6659 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6662 rc
= sqlite3_file_control(db
, NULL
, SQLITE_SET_LOCKPROXYFILE
, proxyPath
);
6664 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
6674 ** tclcmd: file_control_win32_av_retry DB NRETRY DELAY
6676 ** This TCL command runs the sqlite3_file_control interface with
6677 ** the SQLITE_FCNTL_WIN32_AV_RETRY opcode.
6679 static int SQLITE_TCLAPI
file_control_win32_av_retry(
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 */
6691 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6692 Tcl_GetStringFromObj(objv
[0], 0), " DB NRETRY DELAY", 0);
6695 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6698 if( Tcl_GetIntFromObj(interp
, objv
[2], &a
[0]) ) return TCL_ERROR
;
6699 if( Tcl_GetIntFromObj(interp
, objv
[3], &a
[1]) ) return TCL_ERROR
;
6700 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_AV_RETRY
, (void*)a
);
6701 sqlite3_snprintf(sizeof(z
), z
, "%d %d %d", rc
, a
[0], a
[1]);
6702 Tcl_AppendResult(interp
, z
, (char*)0);
6707 ** tclcmd: file_control_win32_get_handle DB
6709 ** This TCL command runs the sqlite3_file_control interface with
6710 ** the SQLITE_FCNTL_WIN32_GET_HANDLE opcode.
6712 static int file_control_win32_get_handle(
6713 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6714 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6715 int objc
, /* Number of arguments */
6716 Tcl_Obj
*CONST objv
[] /* Command arguments */
6720 HANDLE hFile
= NULL
;
6724 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6725 Tcl_GetStringFromObj(objv
[0], 0), " DB", 0);
6728 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6731 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_GET_HANDLE
,
6733 sqlite3_snprintf(sizeof(z
), z
, "%d %p", rc
, (void*)hFile
);
6734 Tcl_AppendResult(interp
, z
, (char*)0);
6739 ** tclcmd: file_control_win32_set_handle DB HANDLE
6741 ** This TCL command runs the sqlite3_file_control interface with
6742 ** the SQLITE_FCNTL_WIN32_SET_HANDLE opcode.
6744 static int SQLITE_TCLAPI
file_control_win32_set_handle(
6745 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6746 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6747 int objc
, /* Number of arguments */
6748 Tcl_Obj
*CONST objv
[] /* Command arguments */
6752 HANDLE hFile
= NULL
;
6756 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6757 Tcl_GetStringFromObj(objv
[0], 0), " DB HANDLE", 0);
6760 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6763 if( getWin32Handle(interp
, Tcl_GetString(objv
[2]), &hFile
) ){
6766 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_WIN32_SET_HANDLE
,
6768 sqlite3_snprintf(sizeof(z
), z
, "%d %p", rc
, (void*)hFile
);
6769 Tcl_AppendResult(interp
, z
, (char*)0);
6775 ** tclcmd: file_control_persist_wal DB PERSIST-FLAG
6777 ** This TCL command runs the sqlite3_file_control interface with
6778 ** the SQLITE_FCNTL_PERSIST_WAL opcode.
6780 static int SQLITE_TCLAPI
file_control_persist_wal(
6781 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6782 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6783 int objc
, /* Number of arguments */
6784 Tcl_Obj
*CONST objv
[] /* Command arguments */
6792 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6793 Tcl_GetStringFromObj(objv
[0], 0), " DB FLAG", 0);
6796 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6799 if( Tcl_GetIntFromObj(interp
, objv
[2], &bPersist
) ) return TCL_ERROR
;
6800 rc
= sqlite3_file_control(db
, NULL
, SQLITE_FCNTL_PERSIST_WAL
, (void*)&bPersist
);
6801 sqlite3_snprintf(sizeof(z
), z
, "%d %d", rc
, bPersist
);
6802 Tcl_AppendResult(interp
, z
, (char*)0);
6807 ** tclcmd: file_control_powersafe_overwrite DB PSOW-FLAG
6809 ** This TCL command runs the sqlite3_file_control interface with
6810 ** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
6812 static int SQLITE_TCLAPI
file_control_powersafe_overwrite(
6813 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6814 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6815 int objc
, /* Number of arguments */
6816 Tcl_Obj
*CONST objv
[] /* Command arguments */
6824 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6825 Tcl_GetStringFromObj(objv
[0], 0), " DB FLAG", 0);
6828 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6831 if( Tcl_GetIntFromObj(interp
, objv
[2], &b
) ) return TCL_ERROR
;
6832 rc
= sqlite3_file_control(db
,NULL
,SQLITE_FCNTL_POWERSAFE_OVERWRITE
,(void*)&b
);
6833 sqlite3_snprintf(sizeof(z
), z
, "%d %d", rc
, b
);
6834 Tcl_AppendResult(interp
, z
, (char*)0);
6840 ** tclcmd: file_control_vfsname DB ?AUXDB?
6842 ** Return a string that describes the stack of VFSes.
6844 static int SQLITE_TCLAPI
file_control_vfsname(
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 */
6851 const char *zDbName
= "main";
6854 if( objc
!=2 && objc
!=3 ){
6855 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6856 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6859 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6863 zDbName
= Tcl_GetString(objv
[2]);
6865 sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_VFSNAME
,(void*)&zVfsName
);
6866 Tcl_AppendResult(interp
, zVfsName
, (char*)0);
6867 sqlite3_free(zVfsName
);
6872 ** tclcmd: file_control_reservebytes DB N
6874 static int SQLITE_TCLAPI
file_control_reservebytes(
6875 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6876 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6877 int objc
, /* Number of arguments */
6878 Tcl_Obj
*CONST objv
[] /* Command arguments */
6881 const char *zDbName
= "main";
6886 Tcl_WrongNumArgs(interp
, 1, objv
, "DB N");
6889 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
6890 || Tcl_GetIntFromObj(interp
, objv
[2], &n
)
6895 rc
= sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_RESERVE_BYTES
, (void*)&n
);
6896 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
6902 ** tclcmd: file_control_tempfilename DB ?AUXDB?
6904 ** Return a string that is a temporary filename
6906 static int SQLITE_TCLAPI
file_control_tempfilename(
6907 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6908 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6909 int objc
, /* Number of arguments */
6910 Tcl_Obj
*CONST objv
[] /* Command arguments */
6913 const char *zDbName
= "main";
6916 if( objc
!=2 && objc
!=3 ){
6917 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6918 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6921 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6925 zDbName
= Tcl_GetString(objv
[2]);
6927 sqlite3_file_control(db
, zDbName
, SQLITE_FCNTL_TEMPFILENAME
, (void*)&zTName
);
6928 Tcl_AppendResult(interp
, zTName
, (char*)0);
6929 sqlite3_free(zTName
);
6934 ** tclcmd: file_control_external_reader DB ?AUXDB?
6936 ** Return a string that is a temporary filename
6938 static int SQLITE_TCLAPI
file_control_external_reader(
6939 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6940 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6941 int objc
, /* Number of arguments */
6942 Tcl_Obj
*CONST objv
[] /* Command arguments */
6945 const char *zName
= "main";
6949 if( objc
!=2 && objc
!=3 ){
6950 Tcl_AppendResult(interp
, "wrong # args: should be \"",
6951 Tcl_GetStringFromObj(objv
[0], 0), " DB ?AUXDB?", 0);
6954 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
6958 zName
= Tcl_GetString(objv
[2]);
6960 rc
= sqlite3_file_control(db
, zName
, SQLITE_FCNTL_EXTERNAL_READER
, &iRes
);
6961 if( rc
!=SQLITE_OK
){
6962 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
6965 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iRes
));
6971 ** tclcmd: sqlite3_vfs_list
6973 ** Return a tcl list containing the names of all registered vfs's.
6975 static int SQLITE_TCLAPI
vfs_list(
6976 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
6977 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
6978 int objc
, /* Number of arguments */
6979 Tcl_Obj
*CONST objv
[] /* Command arguments */
6982 Tcl_Obj
*pRet
= Tcl_NewObj();
6984 Tcl_WrongNumArgs(interp
, 1, objv
, "");
6987 for(pVfs
=sqlite3_vfs_find(0); pVfs
; pVfs
=pVfs
->pNext
){
6988 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj(pVfs
->zName
, -1));
6990 Tcl_SetObjResult(interp
, pRet
);
6995 ** tclcmd: sqlite3_limit DB ID VALUE
6997 ** This TCL command runs the sqlite3_limit interface and
6998 ** verifies correct operation of the same.
7000 static int SQLITE_TCLAPI
test_limit(
7001 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7002 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7003 int objc
, /* Number of arguments */
7004 Tcl_Obj
*CONST objv
[] /* Command arguments */
7008 static const struct {
7012 { "SQLITE_LIMIT_LENGTH", SQLITE_LIMIT_LENGTH
},
7013 { "SQLITE_LIMIT_SQL_LENGTH", SQLITE_LIMIT_SQL_LENGTH
},
7014 { "SQLITE_LIMIT_COLUMN", SQLITE_LIMIT_COLUMN
},
7015 { "SQLITE_LIMIT_EXPR_DEPTH", SQLITE_LIMIT_EXPR_DEPTH
},
7016 { "SQLITE_LIMIT_COMPOUND_SELECT", SQLITE_LIMIT_COMPOUND_SELECT
},
7017 { "SQLITE_LIMIT_VDBE_OP", SQLITE_LIMIT_VDBE_OP
},
7018 { "SQLITE_LIMIT_FUNCTION_ARG", SQLITE_LIMIT_FUNCTION_ARG
},
7019 { "SQLITE_LIMIT_ATTACHED", SQLITE_LIMIT_ATTACHED
},
7020 { "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH
},
7021 { "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER
},
7022 { "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH
},
7023 { "SQLITE_LIMIT_WORKER_THREADS", SQLITE_LIMIT_WORKER_THREADS
},
7025 /* Out of range test cases */
7026 { "SQLITE_LIMIT_TOOSMALL", -1, },
7027 { "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_WORKER_THREADS
+1 },
7034 Tcl_AppendResult(interp
, "wrong # args: should be \"",
7035 Tcl_GetStringFromObj(objv
[0], 0), " DB ID VALUE", 0);
7038 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
7039 zId
= Tcl_GetString(objv
[2]);
7040 for(i
=0; i
<sizeof(aId
)/sizeof(aId
[0]); i
++){
7041 if( strcmp(zId
, aId
[i
].zName
)==0 ){
7046 if( i
>=sizeof(aId
)/sizeof(aId
[0]) ){
7047 Tcl_AppendResult(interp
, "unknown limit type: ", zId
, (char*)0);
7050 if( Tcl_GetIntFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
7051 rc
= sqlite3_limit(db
, id
, val
);
7052 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
7057 ** tclcmd: save_prng_state
7059 ** Save the state of the pseudo-random number generator.
7060 ** At the same time, verify that sqlite3_test_control works even when
7061 ** called with an out-of-range opcode.
7063 static int SQLITE_TCLAPI
save_prng_state(
7064 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7065 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7066 int objc
, /* Number of arguments */
7067 Tcl_Obj
*CONST objv
[] /* Command arguments */
7069 int rc
= sqlite3_test_control(9999);
7071 rc
= sqlite3_test_control(-1);
7073 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SAVE
);
7077 ** tclcmd: restore_prng_state
7079 static int SQLITE_TCLAPI
restore_prng_state(
7080 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7081 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7082 int objc
, /* Number of arguments */
7083 Tcl_Obj
*CONST objv
[] /* Command arguments */
7085 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESTORE
);
7089 ** tclcmd: reset_prng_state
7091 static int SQLITE_TCLAPI
reset_prng_state(
7092 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7093 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7094 int objc
, /* Number of arguments */
7095 Tcl_Obj
*CONST objv
[] /* Command arguments */
7097 sqlite3_randomness(0,0);
7101 ** tclcmd: prng_seed INT ?DB?
7103 ** Set up the SQLITE_TESTCTRL_PRNG_SEED pragma with parameter INT and DB.
7104 ** INT is an integer. DB is a database connection, or a NULL pointer if
7107 ** When INT!=0 and DB!=0, set the PRNG seed to the value of the schema
7108 ** cookie for DB, or to INT if the schema cookie happens to be zero.
7110 ** When INT!=0 and DB==0, set the PRNG seed to just INT.
7112 ** If INT==0 and DB==0 then use the default procedure of calling the
7113 ** xRandomness method on the default VFS to get the PRNG seed.
7115 static int SQLITE_TCLAPI
prng_seed(
7116 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7117 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7118 int objc
, /* Number of arguments */
7119 Tcl_Obj
*CONST objv
[] /* Command arguments */
7123 if( objc
!=2 && objc
!=3 ){
7124 Tcl_WrongNumArgs(interp
, 1, objv
, "SEED ?DB?");
7127 if( Tcl_GetIntFromObj(interp
,objv
[1],&i
) ) return TCL_ERROR
;
7128 if( objc
==3 && getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ){
7131 sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED
, i
, db
);
7136 ** tclcmd: extra_schema_checks BOOLEAN
7138 ** Enable or disable schema checks when parsing the sqlite_schema file.
7139 ** This is always enabled in production, but it is sometimes useful to
7140 ** disable the checks in order to make some internal error states reachable
7143 static int SQLITE_TCLAPI
extra_schema_checks(
7144 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7145 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7146 int objc
, /* Number of arguments */
7147 Tcl_Obj
*CONST objv
[] /* Command arguments */
7151 Tcl_WrongNumArgs(interp
, 1, objv
, "BOOLEAN");
7154 if( Tcl_GetBooleanFromObj(interp
,objv
[1],&i
) ) return TCL_ERROR
;
7155 sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS
, i
);
7160 ** tclcmd: use_long_double BOOLEAN|"default"
7162 ** If no argument, report the current value of the use-long-double flag.
7164 ** If argument is "default", set the use-long-double flag to the default
7165 ** value for this build, based on the size of LONGDOUBLE_TYPE.
7167 ** If argument is a boolean, set the use-long-double flag accordingly.
7169 ** Return the new setting.
7171 static int SQLITE_TCLAPI
use_long_double(
7172 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7173 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7174 int objc
, /* Number of arguments */
7175 Tcl_Obj
*CONST objv
[] /* Command arguments */
7179 if( strcmp(Tcl_GetString(objv
[1]),"default")==0 ){
7182 if( Tcl_GetBooleanFromObj(interp
,objv
[1],&i
) ) return TCL_ERROR
;
7185 i
= sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE
, i
);
7186 Tcl_SetObjResult(interp
, Tcl_NewIntObj(i
));
7191 ** tclcmd: database_may_be_corrupt
7193 ** Indicate that database files might be corrupt. In other words, set the normal
7194 ** state of operation.
7196 static int SQLITE_TCLAPI
database_may_be_corrupt(
7197 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7198 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7199 int objc
, /* Number of arguments */
7200 Tcl_Obj
*CONST objv
[] /* Command arguments */
7202 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT
, 0);
7206 ** tclcmd: database_never_corrupt
7208 ** Indicate that database files are always well-formed. This enables
7209 ** extra assert() statements that test conditions that are always true
7210 ** for well-formed databases.
7212 static int SQLITE_TCLAPI
database_never_corrupt(
7213 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7214 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7215 int objc
, /* Number of arguments */
7216 Tcl_Obj
*CONST objv
[] /* Command arguments */
7218 sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT
, 1);
7223 ** tclcmd: pcache_stats
7225 static int SQLITE_TCLAPI
test_pcache_stats(
7226 ClientData clientData
, /* Pointer to sqlite3_enable_XXX function */
7227 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7228 int objc
, /* Number of arguments */
7229 Tcl_Obj
*CONST objv
[] /* Command arguments */
7237 sqlite3PcacheStats(&nCurrent
, &nMax
, &nMin
, &nRecyclable
);
7239 pRet
= Tcl_NewObj();
7240 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("current", -1));
7241 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nCurrent
));
7242 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("max", -1));
7243 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nMax
));
7244 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("min", -1));
7245 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nMin
));
7246 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewStringObj("recyclable", -1));
7247 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nRecyclable
));
7249 Tcl_SetObjResult(interp
, pRet
);
7254 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
7255 static void test_unlock_notify_cb(void **aArg
, int nArg
){
7257 for(ii
=0; ii
<nArg
; ii
++){
7258 Tcl_EvalEx((Tcl_Interp
*)aArg
[ii
], "unlock_notify", -1, TCL_EVAL_GLOBAL
);
7261 #endif /* SQLITE_ENABLE_UNLOCK_NOTIFY */
7264 ** tclcmd: sqlite3_unlock_notify db
7266 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
7267 static int SQLITE_TCLAPI
test_unlock_notify(
7268 ClientData clientData
, /* Unused */
7269 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7270 int objc
, /* Number of arguments */
7271 Tcl_Obj
*CONST objv
[] /* Command arguments */
7277 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
7281 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7284 rc
= sqlite3_unlock_notify(db
, test_unlock_notify_cb
, (void *)interp
);
7285 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7291 ** tclcmd: sqlite3_wal_checkpoint db ?NAME?
7293 static int SQLITE_TCLAPI
test_wal_checkpoint(
7294 ClientData clientData
, /* Unused */
7295 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7296 int objc
, /* Number of arguments */
7297 Tcl_Obj
*CONST objv
[] /* Command arguments */
7303 if( objc
!=3 && objc
!=2 ){
7304 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?NAME?");
7308 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
7312 zDb
= Tcl_GetString(objv
[2]);
7314 rc
= sqlite3_wal_checkpoint(db
, zDb
);
7315 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
7320 ** tclcmd: sqlite3_wal_checkpoint_v2 db MODE ?NAME?
7322 ** This command calls the wal_checkpoint_v2() function with the specified
7323 ** mode argument (passive, full or restart). If present, the database name
7324 ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the
7325 ** NAME argument is not present, a NULL pointer is passed instead.
7327 ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or
7328 ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set
7329 ** to the error message obtained from sqlite3_errmsg().
7331 ** Otherwise, this command returns a list of three integers. The first integer
7332 ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers
7333 ** are the values returned via the output parameters by wal_checkpoint_v2() -
7334 ** the number of frames in the log and the number of frames in the log
7335 ** that have been checkpointed.
7337 static int SQLITE_TCLAPI
test_wal_checkpoint_v2(
7338 ClientData clientData
, /* Unused */
7339 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7340 int objc
, /* Number of arguments */
7341 Tcl_Obj
*CONST objv
[] /* Command arguments */
7352 const char * aMode
[] = { "passive", "full", "restart", "truncate", 0 };
7353 assert( SQLITE_CHECKPOINT_PASSIVE
==0 );
7354 assert( SQLITE_CHECKPOINT_FULL
==1 );
7355 assert( SQLITE_CHECKPOINT_RESTART
==2 );
7356 assert( SQLITE_CHECKPOINT_TRUNCATE
==3 );
7358 if( objc
!=3 && objc
!=4 ){
7359 Tcl_WrongNumArgs(interp
, 1, objv
, "DB MODE ?NAME?");
7364 zDb
= Tcl_GetString(objv
[3]);
7366 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) || (
7367 TCL_OK
!=Tcl_GetIntFromObj(0, objv
[2], &eMode
)
7368 && TCL_OK
!=Tcl_GetIndexFromObj(interp
, objv
[2], aMode
, "mode", 0, &eMode
)
7373 rc
= sqlite3_wal_checkpoint_v2(db
, zDb
, eMode
, &nLog
, &nCkpt
);
7374 if( rc
!=SQLITE_OK
&& rc
!=SQLITE_BUSY
){
7375 const char *zErrCode
= sqlite3ErrName(rc
);
7376 Tcl_ResetResult(interp
);
7377 Tcl_AppendResult(interp
, zErrCode
, " - ", (char *)sqlite3_errmsg(db
), 0);
7381 pRet
= Tcl_NewObj();
7382 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(rc
==SQLITE_BUSY
?1:0));
7383 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nLog
));
7384 Tcl_ListObjAppendElement(interp
, pRet
, Tcl_NewIntObj(nCkpt
));
7385 Tcl_SetObjResult(interp
, pRet
);
7391 ** tclcmd: sqlite3_wal_autocheckpoint db VALUE
7393 static int SQLITE_TCLAPI
test_wal_autocheckpoint(
7394 ClientData clientData
, /* Unused */
7395 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7396 int objc
, /* Number of arguments */
7397 Tcl_Obj
*CONST objv
[] /* Command arguments */
7405 Tcl_WrongNumArgs(interp
, 1, objv
, "DB VALUE");
7409 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
)
7410 || Tcl_GetIntFromObj(0, objv
[2], &iVal
)
7415 rc
= sqlite3_wal_autocheckpoint(db
, iVal
);
7416 Tcl_ResetResult(interp
);
7417 if( rc
!=SQLITE_OK
){
7418 const char *zErrCode
= sqlite3ErrName(rc
);
7419 Tcl_SetObjResult(interp
, Tcl_NewStringObj(zErrCode
, -1));
7428 ** tclcmd: test_sqlite3_log ?SCRIPT?
7430 static struct LogCallback
{
7431 Tcl_Interp
*pInterp
;
7433 } logcallback
= {0, 0};
7434 static void xLogcallback(void *unused
, int err
, char *zMsg
){
7435 Tcl_Obj
*pNew
= Tcl_DuplicateObj(logcallback
.pObj
);
7436 Tcl_IncrRefCount(pNew
);
7437 Tcl_ListObjAppendElement(
7438 0, pNew
, Tcl_NewStringObj(sqlite3ErrName(err
), -1)
7440 Tcl_ListObjAppendElement(0, pNew
, Tcl_NewStringObj(zMsg
, -1));
7441 Tcl_EvalObjEx(logcallback
.pInterp
, pNew
, TCL_EVAL_GLOBAL
|TCL_EVAL_DIRECT
);
7442 Tcl_DecrRefCount(pNew
);
7444 static int SQLITE_TCLAPI
test_sqlite3_log(
7445 ClientData clientData
,
7446 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
7447 int objc
, /* Number of arguments */
7448 Tcl_Obj
*CONST objv
[] /* Command arguments */
7451 Tcl_WrongNumArgs(interp
, 1, objv
, "SCRIPT");
7454 if( logcallback
.pObj
){
7455 Tcl_DecrRefCount(logcallback
.pObj
);
7456 logcallback
.pObj
= 0;
7457 logcallback
.pInterp
= 0;
7458 sqlite3_config(SQLITE_CONFIG_LOG
, (void*)0, (void*)0);
7461 logcallback
.pObj
= objv
[1];
7462 Tcl_IncrRefCount(logcallback
.pObj
);
7463 logcallback
.pInterp
= interp
;
7464 sqlite3_config(SQLITE_CONFIG_LOG
, xLogcallback
, (void*)0);
7470 ** tcl_objproc COMMANDNAME ARGS...
7472 ** Run a TCL command using its objProc interface. Throw an error if
7473 ** the command has no objProc interface.
7475 static int SQLITE_TCLAPI
runAsObjProc(
7479 Tcl_Obj
*CONST objv
[]
7481 Tcl_CmdInfo cmdInfo
;
7483 Tcl_WrongNumArgs(interp
, 1, objv
, "COMMAND ...");
7486 if( !Tcl_GetCommandInfo(interp
, Tcl_GetString(objv
[1]), &cmdInfo
) ){
7487 Tcl_AppendResult(interp
, "command not found: ",
7488 Tcl_GetString(objv
[1]), (char*)0);
7491 if( cmdInfo
.objProc
==0 ){
7492 Tcl_AppendResult(interp
, "command has no objProc: ",
7493 Tcl_GetString(objv
[1]), (char*)0);
7496 return cmdInfo
.objProc(cmdInfo
.objClientData
, interp
, objc
-1, objv
+1);
7499 #ifndef SQLITE_OMIT_EXPLAIN
7501 ** WARNING: The following function, printExplainQueryPlan() is an exact
7502 ** copy of example code from eqp.in (eqp.html). If this code is modified,
7503 ** then the documentation copy needs to be modified as well.
7506 ** Argument pStmt is a prepared SQL statement. This function compiles
7507 ** an EXPLAIN QUERY PLAN command to report on the prepared statement,
7508 ** and prints the report to stdout using printf().
7510 int printExplainQueryPlan(sqlite3_stmt
*pStmt
){
7511 const char *zSql
; /* Input SQL */
7512 char *zExplain
; /* SQL with EXPLAIN QUERY PLAN prepended */
7513 sqlite3_stmt
*pExplain
; /* Compiled EXPLAIN QUERY PLAN command */
7514 int rc
; /* Return code from sqlite3_prepare_v2() */
7516 zSql
= sqlite3_sql(pStmt
);
7517 if( zSql
==0 ) return SQLITE_ERROR
;
7519 zExplain
= sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql
);
7520 if( zExplain
==0 ) return SQLITE_NOMEM
;
7522 rc
= sqlite3_prepare_v2(sqlite3_db_handle(pStmt
), zExplain
, -1, &pExplain
, 0);
7523 sqlite3_free(zExplain
);
7524 if( rc
!=SQLITE_OK
) return rc
;
7526 while( SQLITE_ROW
==sqlite3_step(pExplain
) ){
7527 int iSelectid
= sqlite3_column_int(pExplain
, 0);
7528 int iOrder
= sqlite3_column_int(pExplain
, 1);
7529 int iFrom
= sqlite3_column_int(pExplain
, 2);
7530 const char *zDetail
= (const char *)sqlite3_column_text(pExplain
, 3);
7532 printf("%d %d %d %s\n", iSelectid
, iOrder
, iFrom
, zDetail
);
7535 return sqlite3_finalize(pExplain
);
7538 static int SQLITE_TCLAPI
test_print_eqp(
7542 Tcl_Obj
*CONST objv
[]
7545 sqlite3_stmt
*pStmt
;
7548 Tcl_WrongNumArgs(interp
, 1, objv
, "STMT");
7551 if( getStmtPointer(interp
, Tcl_GetString(objv
[1]), &pStmt
) ) return TCL_ERROR
;
7552 rc
= printExplainQueryPlan(pStmt
);
7553 /* This is needed on Windows so that a test case using this
7554 ** function can open a read pipe and get the output of
7555 ** printExplainQueryPlan() immediately.
7558 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), 0);
7561 #endif /* SQLITE_OMIT_EXPLAIN */
7565 ** This is an alternative localtime_r() implementation used for testing
7566 ** the 'localtime' and 'utc' modifiers of date-time functions. Because
7567 ** the OS-supplied localtime_r() is locale-dependent, this alternative is
7568 ** provided as a stable test platform.
7572 ** (1) Localtime is 30 minutes earlier than (west of) UTC on
7573 ** even days (counting from 1970-01-01)
7575 ** (2) Localtime is 30 minutes later than (east of) UTC on odd days.
7577 ** (3) The function fails for the specific date/time value
7578 ** of 2000-05-29 14:16:00 in order to test the ability of
7579 ** SQLite to deal with localtime_r() failures.
7581 static int testLocaltime(const void *aliasT
, void *aliasTM
){
7582 const time_t t
= *(const time_t*)aliasT
;
7583 struct tm
*pTm
= (struct tm
*)aliasTM
;
7586 int Z
, A
, B
, C
, D
, E
, X1
, S
;
7588 if( (t
/86400) & 1 ){
7589 altT
= t
+ 1800; /* 30 minutes later on odd days */
7591 altT
= t
- 1800; /* 30 minutes earlier on even days */
7593 iJD
= (sqlite3_int64
)(altT
+ 210866760000);
7594 Z
= (int)((iJD
+ 43200)/86400);
7595 A
= (int)((Z
- 1867216.25)/36524.25);
7596 A
= Z
+ 1 + A
- (A
/4);
7598 C
= (int)((B
- 122.1)/365.25);
7599 D
= (36525*(C
&32767))/100;
7600 E
= (int)((B
-D
)/30.6001);
7601 X1
= (int)(30.6001*E
);
7602 pTm
->tm_mday
= B
- D
- X1
;
7603 pTm
->tm_mon
= E
<14 ? E
-2 : E
-14;
7604 pTm
->tm_year
= (pTm
->tm_mon
>1 ? C
- 4716 : C
- 4715) - 1900;
7605 S
= (int)((iJD
+ 43200)%86400);
7606 pTm
->tm_hour
= S
/3600;
7607 pTm
->tm_min
= (S
/60)%60;
7608 pTm
->tm_sec
= S
% 60;
7609 return t
==959609760; /* Special case: 2000-05-29 14:16:00 fails */
7613 ** TCLCMD: strftime FORMAT UNIXTIMESTAMP
7615 ** Access to the C-library strftime() routine, so that its results
7616 ** can be compared against SQLite's internal strftime() SQL function
7619 static int SQLITE_TCLAPI
strftime_cmd(
7623 Tcl_Obj
*CONST objv
[]
7632 Tcl_WrongNumArgs(interp
, 1, objv
, "FORMAT UNIXTIMESTAMP");
7635 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &ts
) ) return TCL_ERROR
;
7636 zFmt
= Tcl_GetString(objv
[1]);
7639 n
= strftime(zBuf
, sizeof(zBuf
)-1, zFmt
, pTm
);
7640 if( n
>=0 && n
<sizeof(zBuf
) ){
7642 Tcl_SetResult(interp
, zBuf
, TCL_VOLATILE
);
7650 static int SQLITE_TCLAPI
test_treetrace(
7654 Tcl_Obj
*CONST objv
[]
7658 if( Tcl_GetIntFromObj(interp
, objv
[1], (int*)&v
)==TCL_OK
){
7659 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS
, 1, &v
);
7662 sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS
, 0, &v
);
7663 Tcl_SetObjResult(interp
, Tcl_NewIntObj((int)v
));
7668 ** sqlite3_test_control VERB ARGS...
7670 static int SQLITE_TCLAPI
test_test_control(
7674 Tcl_Obj
*CONST objv
[]
7680 { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT
},
7681 { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP
},
7682 { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER
},
7683 { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
},
7684 { "SQLITE_TESTCTRL_FK_NO_ACTION", SQLITE_TESTCTRL_FK_NO_ACTION
},
7692 Tcl_WrongNumArgs(interp
, 1, objv
, "VERB ARGS...");
7696 rc
= Tcl_GetIndexFromObjStruct(
7697 interp
, objv
[1], aVerb
, sizeof(aVerb
[0]), "VERB", 0, &iVerb
7699 if( rc
!=TCL_OK
) return rc
;
7701 iFlag
= aVerb
[iVerb
].i
;
7703 case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
: {
7706 Tcl_WrongNumArgs(interp
, 2, objv
, "DB");
7709 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7710 sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
, db
);
7713 case SQLITE_TESTCTRL_LOCALTIME_FAULT
: {
7716 Tcl_WrongNumArgs(interp
, 2, objv
, "0|1|2");
7719 if( Tcl_GetIntFromObj(interp
, objv
[2], &val
) ) return TCL_ERROR
;
7720 sqlite3_test_control(iFlag
, val
, testLocaltime
);
7724 case SQLITE_TESTCTRL_FK_NO_ACTION
: {
7728 Tcl_WrongNumArgs(interp
, 2, objv
, "DB BOOLEAN");
7731 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7732 if( Tcl_GetBooleanFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
7734 sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION
, db
, val
);
7738 case SQLITE_TESTCTRL_SORTER_MMAP
: {
7742 Tcl_WrongNumArgs(interp
, 2, objv
, "DB LIMIT");
7745 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7746 if( Tcl_GetIntFromObj(interp
, objv
[3], &val
) ) return TCL_ERROR
;
7747 sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP
, db
, val
);
7751 case SQLITE_TESTCTRL_IMPOSTER
: {
7753 const char *zDbName
;
7756 Tcl_WrongNumArgs(interp
, 2, objv
, "DB dbName onOff tnum");
7759 if( getDbPointer(interp
, Tcl_GetString(objv
[2]), &db
) ) return TCL_ERROR
;
7760 zDbName
= Tcl_GetString(objv
[3]);
7761 if( Tcl_GetIntFromObj(interp
, objv
[4], &onOff
) ) return TCL_ERROR
;
7762 if( Tcl_GetIntFromObj(interp
, objv
[5], &tnum
) ) return TCL_ERROR
;
7763 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER
, db
, zDbName
, onOff
, tnum
);
7768 Tcl_ResetResult(interp
);
7773 #include <sys/time.h>
7774 #include <sys/resource.h>
7776 static int SQLITE_TCLAPI
test_getrusage(
7780 Tcl_Obj
*CONST objv
[]
7784 memset(&r
, 0, sizeof(r
));
7785 getrusage(RUSAGE_SELF
, &r
);
7787 sqlite3_snprintf(sizeof(buf
), buf
,
7788 "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d",
7789 (int)r
.ru_utime
.tv_sec
, (int)r
.ru_utime
.tv_usec
,
7790 (int)r
.ru_stime
.tv_sec
, (int)r
.ru_stime
.tv_usec
,
7791 (int)r
.ru_minflt
, (int)r
.ru_majflt
7793 Tcl_SetObjResult(interp
, Tcl_NewStringObj(buf
, -1));
7800 ** Information passed from the main thread into the windows file locker
7801 ** background thread.
7803 struct win32FileLocker
{
7804 char *evName
; /* Name of event to signal thread startup */
7805 HANDLE h
; /* Handle of the file to be locked */
7806 int delay1
; /* Delay before locking */
7807 int delay2
; /* Delay before unlocking */
7808 int ok
; /* Finished ok */
7809 int err
; /* True if an error occurs */
7815 #include <process.h>
7817 ** The background thread that does file locking.
7819 static void SQLITE_CDECL
win32_file_locker(void *pAppData
){
7820 struct win32FileLocker
*p
= (struct win32FileLocker
*)pAppData
;
7822 HANDLE ev
= OpenEvent(EVENT_MODIFY_STATE
, FALSE
, p
->evName
);
7828 if( p
->delay1
) Sleep(p
->delay1
);
7829 if( LockFile(p
->h
, 0, 0, 100000000, 0) ){
7831 UnlockFile(p
->h
, 0, 0, 100000000, 0);
7845 ** lock_win32_file FILENAME DELAY1 DELAY2
7847 ** Get an exclusive manditory lock on file for DELAY2 milliseconds.
7848 ** Wait DELAY1 milliseconds before acquiring the lock.
7850 static int SQLITE_TCLAPI
win32_file_lock(
7854 Tcl_Obj
*CONST objv
[]
7856 static struct win32FileLocker x
= { "win32_file_lock", 0, 0, 0, 0, 0 };
7857 const char *zFilename
;
7863 if( objc
!=4 && objc
!=1 ){
7864 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME DELAY1 DELAY2");
7868 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%d %d %d %d %d",
7869 x
.ok
, x
.err
, x
.delay1
, x
.delay2
, x
.h
);
7870 Tcl_AppendResult(interp
, zBuf
, (char*)0);
7873 while( x
.h
&& retry
<30 ){
7878 Tcl_AppendResult(interp
, "busy", (char*)0);
7881 if( Tcl_GetIntFromObj(interp
, objv
[2], &x
.delay1
) ) return TCL_ERROR
;
7882 if( Tcl_GetIntFromObj(interp
, objv
[3], &x
.delay2
) ) return TCL_ERROR
;
7883 zFilename
= Tcl_GetString(objv
[1]);
7884 x
.h
= CreateFile(zFilename
, GENERIC_READ
|GENERIC_WRITE
,
7885 FILE_SHARE_READ
|FILE_SHARE_WRITE
, 0, OPEN_ALWAYS
,
7886 FILE_ATTRIBUTE_NORMAL
, 0);
7888 Tcl_AppendResult(interp
, "cannot open file: ", zFilename
, (char*)0);
7891 ev
= CreateEvent(NULL
, TRUE
, FALSE
, x
.evName
);
7893 Tcl_AppendResult(interp
, "cannot create event: ", x
.evName
, (char*)0);
7896 _beginthread(win32_file_locker
, 0, (void*)&x
);
7898 if ( (wResult
= WaitForSingleObject(ev
, 10000))!=WAIT_OBJECT_0
){
7899 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "0x%x", wResult
);
7900 Tcl_AppendResult(interp
, "wait failed: ", zBuf
, (char*)0);
7909 ** exists_win32_path PATH
7911 ** Returns non-zero if the specified path exists, whose fully qualified name
7912 ** may exceed 260 characters if it is prefixed with "\\?\".
7914 static int SQLITE_TCLAPI
win32_exists_path(
7918 Tcl_Obj
*CONST objv
[]
7921 Tcl_WrongNumArgs(interp
, 1, objv
, "PATH");
7924 Tcl_SetObjResult(interp
, Tcl_NewBooleanObj(
7925 GetFileAttributesW( Tcl_GetUnicode(objv
[1]))!=INVALID_FILE_ATTRIBUTES
));
7930 ** find_win32_file PATTERN
7932 ** Returns a list of entries in a directory that match the specified pattern,
7933 ** whose fully qualified name may exceed 248 characters if it is prefixed with
7936 static int SQLITE_TCLAPI
win32_find_file(
7940 Tcl_Obj
*CONST objv
[]
7942 HANDLE hFindFile
= INVALID_HANDLE_VALUE
;
7943 WIN32_FIND_DATAW findData
;
7947 Tcl_WrongNumArgs(interp
, 1, objv
, "PATTERN");
7950 hFindFile
= FindFirstFileW(Tcl_GetUnicode(objv
[1]), &findData
);
7951 if( hFindFile
==INVALID_HANDLE_VALUE
){
7952 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7955 listObj
= Tcl_NewObj();
7956 Tcl_IncrRefCount(listObj
);
7958 Tcl_ListObjAppendElement(interp
, listObj
, Tcl_NewUnicodeObj(
7959 findData
.cFileName
, -1));
7960 Tcl_ListObjAppendElement(interp
, listObj
, Tcl_NewWideIntObj(
7961 findData
.dwFileAttributes
));
7962 } while( FindNextFileW(hFindFile
, &findData
) );
7963 lastErrno
= GetLastError();
7964 if( lastErrno
!=NO_ERROR
&& lastErrno
!=ERROR_NO_MORE_FILES
){
7965 FindClose(hFindFile
);
7966 Tcl_DecrRefCount(listObj
);
7967 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7970 FindClose(hFindFile
);
7971 Tcl_SetObjResult(interp
, listObj
);
7976 ** delete_win32_file FILENAME
7978 ** Deletes the specified file, whose fully qualified name may exceed 260
7979 ** characters if it is prefixed with "\\?\".
7981 static int SQLITE_TCLAPI
win32_delete_file(
7985 Tcl_Obj
*CONST objv
[]
7988 Tcl_WrongNumArgs(interp
, 1, objv
, "FILENAME");
7991 if( !DeleteFileW(Tcl_GetUnicode(objv
[1])) ){
7992 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
7995 Tcl_ResetResult(interp
);
8000 ** make_win32_dir DIRECTORY
8002 ** Creates the specified directory, whose fully qualified name may exceed 248
8003 ** characters if it is prefixed with "\\?\".
8005 static int SQLITE_TCLAPI
win32_mkdir(
8009 Tcl_Obj
*CONST objv
[]
8012 Tcl_WrongNumArgs(interp
, 1, objv
, "DIRECTORY");
8015 if( !CreateDirectoryW(Tcl_GetUnicode(objv
[1]), NULL
) ){
8016 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
8019 Tcl_ResetResult(interp
);
8024 ** remove_win32_dir DIRECTORY
8026 ** Removes the specified directory, whose fully qualified name may exceed 248
8027 ** characters if it is prefixed with "\\?\".
8029 static int SQLITE_TCLAPI
win32_rmdir(
8033 Tcl_Obj
*CONST objv
[]
8036 Tcl_WrongNumArgs(interp
, 1, objv
, "DIRECTORY");
8039 if( !RemoveDirectoryW(Tcl_GetUnicode(objv
[1])) ){
8040 Tcl_SetObjResult(interp
, Tcl_NewWideIntObj(GetLastError()));
8043 Tcl_ResetResult(interp
);
8050 ** optimization_control DB OPT BOOLEAN
8052 ** Enable or disable query optimizations using the sqlite3_test_control()
8053 ** interface. Disable if BOOLEAN is false and enable if BOOLEAN is true.
8054 ** OPT is the name of the optimization to be disabled. OPT can also be a
8055 ** list or optimizations names, in which case all optimizations named are
8056 ** enabled or disabled.
8058 ** Each invocation of this control overrides all prior invocations. The
8059 ** changes are not cumulative.
8061 static int SQLITE_TCLAPI
optimization_control(
8065 Tcl_Obj
*CONST objv
[]
8073 static const struct {
8074 const char *zOptName
;
8077 { "all", SQLITE_AllOpts
},
8079 { "query-flattener", SQLITE_QueryFlattener
},
8080 { "groupby-order", SQLITE_GroupByOrder
},
8081 { "factor-constants", SQLITE_FactorOutConst
},
8082 { "distinct-opt", SQLITE_DistinctOpt
},
8083 { "cover-idx-scan", SQLITE_CoverIdxScan
},
8084 { "order-by-idx-join", SQLITE_OrderByIdxJoin
},
8085 { "transitive", SQLITE_Transitive
},
8086 { "omit-noop-join", SQLITE_OmitNoopJoin
},
8087 { "stat4", SQLITE_Stat4
},
8088 { "skip-scan", SQLITE_SkipScan
},
8089 { "push-down", SQLITE_PushDown
},
8090 { "balanced-merge", SQLITE_BalancedMerge
},
8091 { "propagate-const", SQLITE_PropagateConst
},
8092 { "one-pass", SQLITE_OnePass
},
8096 Tcl_WrongNumArgs(interp
, 1, objv
, "DB OPT BOOLEAN");
8099 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8100 if( Tcl_GetBooleanFromObj(interp
, objv
[3], &onoff
) ) return TCL_ERROR
;
8101 zOpt
= Tcl_GetString(objv
[2]);
8102 for(i
=0; i
<sizeof(aOpt
)/sizeof(aOpt
[0]); i
++){
8103 if( strstr(zOpt
, aOpt
[i
].zOptName
)!=0 ){
8104 mask
|= aOpt
[i
].mask
;
8108 if( onoff
) mask
= ~mask
;
8110 Tcl_AppendResult(interp
, "unknown optimization - should be one of:",
8112 for(i
=0; i
<sizeof(aOpt
)/sizeof(aOpt
[0]); i
++){
8113 Tcl_AppendResult(interp
, " ", aOpt
[i
].zOptName
, (char*)0);
8117 sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS
, db
, mask
);
8118 Tcl_SetObjResult(interp
, Tcl_NewIntObj(mask
));
8123 ** load_static_extension DB NAME ...
8125 ** Load one or more statically linked extensions.
8127 static int SQLITE_TCLAPI
tclLoadStaticExtensionCmd(
8131 Tcl_Obj
*CONST objv
[]
8133 extern int sqlite3_amatch_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8134 extern int sqlite3_appendvfs_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8135 extern int sqlite3_basexx_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8136 extern int sqlite3_carray_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8137 extern int sqlite3_closure_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8138 extern int sqlite3_csv_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8139 extern int sqlite3_eval_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8140 extern int sqlite3_explain_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8141 extern int sqlite3_fileio_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8142 extern int sqlite3_decimal_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8143 extern int sqlite3_fuzzer_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8144 extern int sqlite3_ieee_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8145 extern int sqlite3_nextchar_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8146 extern int sqlite3_percentile_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8147 #ifndef SQLITE_OMIT_VIRTUALTABLE
8148 extern int sqlite3_prefixes_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8150 extern int sqlite3_qpvtab_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8151 extern int sqlite3_regexp_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8152 extern int sqlite3_remember_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8153 extern int sqlite3_series_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8154 extern int sqlite3_spellfix_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8155 extern int sqlite3_totype_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8156 extern int sqlite3_wholenumber_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8157 extern int sqlite3_unionvtab_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8158 #ifdef SQLITE_HAVE_ZLIB
8159 extern int sqlite3_zipfile_init(sqlite3
*,char**,const sqlite3_api_routines
*);
8161 static const struct {
8162 const char *zExtName
;
8163 int (*pInit
)(sqlite3
*,char**,const sqlite3_api_routines
*);
8165 { "amatch", sqlite3_amatch_init
},
8166 { "appendvfs", sqlite3_appendvfs_init
},
8167 { "basexx", sqlite3_basexx_init
},
8168 { "carray", sqlite3_carray_init
},
8169 { "closure", sqlite3_closure_init
},
8170 { "csv", sqlite3_csv_init
},
8171 { "decimal", sqlite3_decimal_init
},
8172 { "eval", sqlite3_eval_init
},
8173 { "explain", sqlite3_explain_init
},
8174 { "fileio", sqlite3_fileio_init
},
8175 { "fuzzer", sqlite3_fuzzer_init
},
8176 { "ieee754", sqlite3_ieee_init
},
8177 { "nextchar", sqlite3_nextchar_init
},
8178 { "percentile", sqlite3_percentile_init
},
8179 #ifndef SQLITE_OMIT_VIRTUALTABLE
8180 { "prefixes", sqlite3_prefixes_init
},
8182 { "qpvtab", sqlite3_qpvtab_init
},
8183 { "regexp", sqlite3_regexp_init
},
8184 { "remember", sqlite3_remember_init
},
8185 { "series", sqlite3_series_init
},
8186 { "spellfix", sqlite3_spellfix_init
},
8187 { "totype", sqlite3_totype_init
},
8188 { "unionvtab", sqlite3_unionvtab_init
},
8189 { "wholenumber", sqlite3_wholenumber_init
},
8190 #ifdef SQLITE_HAVE_ZLIB
8191 { "zipfile", sqlite3_zipfile_init
},
8199 Tcl_WrongNumArgs(interp
, 1, objv
, "DB NAME ...");
8202 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8203 for(j
=2; j
<objc
; j
++){
8204 zName
= Tcl_GetString(objv
[j
]);
8205 for(i
=0; i
<ArraySize(aExtension
); i
++){
8206 if( strcmp(zName
, aExtension
[i
].zExtName
)==0 ) break;
8208 if( i
>=ArraySize(aExtension
) ){
8209 Tcl_AppendResult(interp
, "no such extension: ", zName
, (char*)0);
8212 if( aExtension
[i
].pInit
){
8213 rc
= aExtension
[i
].pInit(db
, &zErrMsg
, 0);
8217 if( (rc
!=SQLITE_OK
&& rc
!=SQLITE_OK_LOAD_PERMANENTLY
) || zErrMsg
){
8218 Tcl_AppendResult(interp
, "initialization of ", zName
, " failed: ", zErrMsg
,
8220 sqlite3_free(zErrMsg
);
8228 ** sorter_test_fakeheap BOOL
8231 static int SQLITE_TCLAPI
sorter_test_fakeheap(
8235 Tcl_Obj
*CONST objv
[]
8239 Tcl_WrongNumArgs(interp
, 1, objv
, "BOOL");
8243 if( Tcl_GetBooleanFromObj(interp
, objv
[1], &bArg
) ){
8248 if( sqlite3GlobalConfig
.pHeap
==0 ){
8249 sqlite3GlobalConfig
.pHeap
= SQLITE_INT_TO_PTR(-1);
8252 if( sqlite3GlobalConfig
.pHeap
==SQLITE_INT_TO_PTR(-1) ){
8253 sqlite3GlobalConfig
.pHeap
= 0;
8257 Tcl_ResetResult(interp
);
8262 ** sorter_test_sort4_helper DB SQL1 NSTEP SQL2
8264 ** Compile SQL statement $SQL1 and step it $NSTEP times. For each row,
8265 ** check that the leftmost and rightmost columns returned are both integers,
8266 ** and that both contain the same value.
8268 ** Then execute statement $SQL2. Check that the statement returns the same
8269 ** set of integers in the same order as in the previous step (using $SQL1).
8271 static int SQLITE_TCLAPI
sorter_test_sort4_helper(
8275 Tcl_Obj
*CONST objv
[]
8281 unsigned int iCksum1
= 0;
8282 unsigned int iCksum2
= 0;
8286 sqlite3_stmt
*pStmt
;
8289 Tcl_WrongNumArgs(interp
, 1, objv
, "DB SQL1 NSTEP SQL2");
8293 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8294 zSql1
= Tcl_GetString(objv
[2]);
8295 if( Tcl_GetIntFromObj(interp
, objv
[3], &nStep
) ) return TCL_ERROR
;
8296 zSql2
= Tcl_GetString(objv
[4]);
8298 rc
= sqlite3_prepare_v2(db
, zSql1
, -1, &pStmt
, 0);
8299 if( rc
!=SQLITE_OK
) goto sql_error
;
8301 iB
= sqlite3_column_count(pStmt
)-1;
8302 for(iStep
=0; iStep
<nStep
&& SQLITE_ROW
==sqlite3_step(pStmt
); iStep
++){
8303 int a
= sqlite3_column_int(pStmt
, 0);
8304 if( a
!=sqlite3_column_int(pStmt
, iB
) ){
8305 Tcl_AppendResult(interp
, "data error: (a!=b)", 0);
8309 iCksum1
+= (iCksum1
<< 3) + (unsigned int)a
;
8311 rc
= sqlite3_finalize(pStmt
);
8312 if( rc
!=SQLITE_OK
) goto sql_error
;
8314 rc
= sqlite3_prepare_v2(db
, zSql2
, -1, &pStmt
, 0);
8315 if( rc
!=SQLITE_OK
) goto sql_error
;
8316 for(iStep
=0; SQLITE_ROW
==sqlite3_step(pStmt
); iStep
++){
8317 int a
= sqlite3_column_int(pStmt
, 0);
8318 iCksum2
+= (iCksum2
<< 3) + (unsigned int)a
;
8320 rc
= sqlite3_finalize(pStmt
);
8321 if( rc
!=SQLITE_OK
) goto sql_error
;
8323 if( iCksum1
!=iCksum2
){
8324 Tcl_AppendResult(interp
, "checksum mismatch", 0);
8330 Tcl_AppendResult(interp
, "sql error: ", sqlite3_errmsg(db
), 0);
8335 #ifdef SQLITE_USER_AUTHENTICATION
8336 #include "sqlite3userauth.h"
8338 ** tclcmd: sqlite3_user_authenticate DB USERNAME PASSWORD
8340 static int SQLITE_TCLAPI
test_user_authenticate(
8341 ClientData clientData
, /* Unused */
8342 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
8343 int objc
, /* Number of arguments */
8344 Tcl_Obj
*CONST objv
[] /* Command arguments */
8353 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD");
8356 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
8359 zUser
= Tcl_GetString(objv
[2]);
8360 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
8361 rc
= sqlite3_user_authenticate(db
, zUser
, zPasswd
, nPasswd
);
8362 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
8365 #endif /* SQLITE_USER_AUTHENTICATION */
8367 #ifdef SQLITE_USER_AUTHENTICATION
8369 ** tclcmd: sqlite3_user_add DB USERNAME PASSWORD ISADMIN
8371 static int SQLITE_TCLAPI
test_user_add(
8372 ClientData clientData
, /* Unused */
8373 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
8374 int objc
, /* Number of arguments */
8375 Tcl_Obj
*CONST objv
[] /* Command arguments */
8385 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD ISADMIN");
8388 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
8391 zUser
= Tcl_GetString(objv
[2]);
8392 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
8393 Tcl_GetBooleanFromObj(interp
, objv
[4], &isAdmin
);
8394 rc
= sqlite3_user_add(db
, zUser
, zPasswd
, nPasswd
, isAdmin
);
8395 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
8398 #endif /* SQLITE_USER_AUTHENTICATION */
8400 #ifdef SQLITE_USER_AUTHENTICATION
8402 ** tclcmd: sqlite3_user_change DB USERNAME PASSWORD ISADMIN
8404 static int SQLITE_TCLAPI
test_user_change(
8405 ClientData clientData
, /* Unused */
8406 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
8407 int objc
, /* Number of arguments */
8408 Tcl_Obj
*CONST objv
[] /* Command arguments */
8418 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME PASSWORD ISADMIN");
8421 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
8424 zUser
= Tcl_GetString(objv
[2]);
8425 zPasswd
= Tcl_GetStringFromObj(objv
[3], &nPasswd
);
8426 Tcl_GetBooleanFromObj(interp
, objv
[4], &isAdmin
);
8427 rc
= sqlite3_user_change(db
, zUser
, zPasswd
, nPasswd
, isAdmin
);
8428 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
8431 #endif /* SQLITE_USER_AUTHENTICATION */
8433 #ifdef SQLITE_USER_AUTHENTICATION
8435 ** tclcmd: sqlite3_user_delete DB USERNAME
8437 static int SQLITE_TCLAPI
test_user_delete(
8438 ClientData clientData
, /* Unused */
8439 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
8440 int objc
, /* Number of arguments */
8441 Tcl_Obj
*CONST objv
[] /* Command arguments */
8448 Tcl_WrongNumArgs(interp
, 1, objv
, "DB USERNAME");
8451 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ){
8454 zUser
= Tcl_GetString(objv
[2]);
8455 rc
= sqlite3_user_delete(db
, zUser
);
8456 Tcl_SetResult(interp
, (char *)t1ErrorName(rc
), TCL_STATIC
);
8459 #endif /* SQLITE_USER_AUTHENTICATION */
8462 ** tclcmd: bad_behavior TYPE
8464 ** Do some things that should trigger a valgrind or -fsanitize=undefined
8465 ** warning. This is used to verify that errors and warnings output by those
8466 ** tools are detected by the test scripts.
8469 ** 1 Overflow a signed integer
8470 ** 2 Jump based on an uninitialized variable
8471 ** 3 Read after free
8474 static int SQLITE_TCLAPI
test_bad_behavior(
8475 ClientData clientData
, /* Pointer to an integer containing zero */
8476 Tcl_Interp
*interp
, /* The TCL interpreter that invoked this command */
8477 int objc
, /* Number of arguments */
8478 Tcl_Obj
*CONST objv
[] /* Command arguments */
8482 int i
= *(int*)clientData
;
8487 Tcl_WrongNumArgs(interp
, 1, objv
, "TYPE");
8490 if( Tcl_GetIntFromObj(interp
, objv
[1], &iType
) ) return TCL_ERROR
;
8493 xyz
= 0x7fffff00 - i
;
8495 Tcl_SetObjResult(interp
, Tcl_NewIntObj(xyz
));
8500 if( w
[i
]>0 ) w
[1]++;
8501 Tcl_SetObjResult(interp
, Tcl_NewIntObj(w
[1]));
8505 a
= malloc( sizeof(int)*10 );
8506 for(j
=0; j
<10; j
++) a
[j
] = j
;
8508 Tcl_SetObjResult(interp
, Tcl_NewIntObj(a
[i
]));
8512 Tcl_Panic("Deliberate panic");
8520 ** tclcmd: register_dbstat_vtab DB
8522 ** Cause the dbstat virtual table to be available on the connection DB
8524 static int SQLITE_TCLAPI
test_register_dbstat_vtab(
8528 Tcl_Obj
*CONST objv
[]
8530 #ifdef SQLITE_OMIT_VIRTUALTABLE
8531 Tcl_AppendResult(interp
, "dbstat not available because of "
8532 "SQLITE_OMIT_VIRTUALTABLE", (void*)0);
8535 struct SqliteDb
{ sqlite3
*db
; };
8537 Tcl_CmdInfo cmdInfo
;
8540 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
8544 zDb
= Tcl_GetString(objv
[1]);
8545 if( Tcl_GetCommandInfo(interp
, zDb
, &cmdInfo
) ){
8546 sqlite3
* db
= ((struct SqliteDb
*)cmdInfo
.objClientData
)->db
;
8547 sqlite3DbstatRegister(db
);
8550 #endif /* SQLITE_OMIT_VIRTUALTABLE */
8554 ** tclcmd: sqlite3_db_config DB SETTING VALUE
8556 ** Invoke sqlite3_db_config() for one of the setting values.
8558 static int SQLITE_TCLAPI
test_sqlite3_db_config(
8562 Tcl_Obj
*CONST objv
[]
8564 static const struct {
8568 { "FKEY", SQLITE_DBCONFIG_ENABLE_FKEY
},
8569 { "TRIGGER", SQLITE_DBCONFIG_ENABLE_TRIGGER
},
8570 { "FTS3_TOKENIZER", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
},
8571 { "LOAD_EXTENSION", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
},
8572 { "NO_CKPT_ON_CLOSE", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
},
8573 { "QPSG", SQLITE_DBCONFIG_ENABLE_QPSG
},
8574 { "TRIGGER_EQP", SQLITE_DBCONFIG_TRIGGER_EQP
},
8575 { "RESET_DB", SQLITE_DBCONFIG_RESET_DATABASE
},
8576 { "DEFENSIVE", SQLITE_DBCONFIG_DEFENSIVE
},
8577 { "WRITABLE_SCHEMA", SQLITE_DBCONFIG_WRITABLE_SCHEMA
},
8578 { "LEGACY_ALTER_TABLE", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE
},
8579 { "DQS_DML", SQLITE_DBCONFIG_DQS_DML
},
8580 { "DQS_DDL", SQLITE_DBCONFIG_DQS_DDL
},
8581 { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
},
8582 { "STMT_SCANSTATUS", SQLITE_DBCONFIG_STMT_SCANSTATUS
},
8586 const char *zSetting
;
8589 if( objc
!=4 && objc
!=3 ){
8590 Tcl_WrongNumArgs(interp
, 1, objv
, "DB SETTING [VALUE]");
8593 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8594 zSetting
= Tcl_GetString(objv
[2]);
8595 if( sqlite3_strglob("SQLITE_*", zSetting
)==0 ) zSetting
+= 7;
8596 if( sqlite3_strglob("DBCONFIG_*", zSetting
)==0 ) zSetting
+= 9;
8597 if( sqlite3_strglob("ENABLE_*", zSetting
)==0 ) zSetting
+= 7;
8598 for(i
=0; i
<ArraySize(aSetting
); i
++){
8599 if( strcmp(zSetting
, aSetting
[i
].zName
)==0 ) break;
8601 if( i
>=ArraySize(aSetting
) ){
8602 Tcl_SetObjResult(interp
,
8603 Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
8607 if( Tcl_GetIntFromObj(interp
, objv
[3], &v
) ) return TCL_ERROR
;
8611 sqlite3_db_config(db
, aSetting
[i
].eVal
, v
, &v
);
8612 Tcl_SetObjResult(interp
, Tcl_NewIntObj(v
));
8616 ** tclcmd: sqlite3_txn_state DB ?SCHEMA?
8618 ** Invoke sqlite3_txn_state(DB,SCHEMA) and return the
8619 ** numeric value that results. Use NULL for SCHEMA if the 3 argument
8622 static int SQLITE_TCLAPI
test_sqlite3_txn_state(
8626 Tcl_Obj
*CONST objv
[]
8629 const char *zSchema
;
8632 if( objc
!=2 && objc
!=3 ){
8633 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?SCHEMA?");
8636 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8637 zSchema
= objc
==3 ? Tcl_GetString(objv
[2]) : 0;
8638 iTxn
= sqlite3_txn_state(db
, zSchema
);
8639 Tcl_SetObjResult(interp
, Tcl_NewIntObj(iTxn
));
8644 ** Change the name of the main database schema from "main" to "icecube".
8646 static int SQLITE_TCLAPI
test_dbconfig_maindbname_icecube(
8650 Tcl_Obj
*CONST objv
[]
8654 extern int getDbPointer(Tcl_Interp
*, const char*, sqlite3
**);
8656 Tcl_WrongNumArgs(interp
, 1, objv
, "DB");
8659 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8660 rc
= sqlite3_db_config(db
, SQLITE_DBCONFIG_MAINDBNAME
, "icecube");
8661 Tcl_SetObjResult(interp
, Tcl_NewIntObj(rc
));
8667 ** Usage: sqlite3_mmap_warm DB DBNAME
8669 static int SQLITE_TCLAPI
test_mmap_warm(
8673 Tcl_Obj
*CONST objv
[]
8675 extern int getDbPointer(Tcl_Interp
*, const char*, sqlite3
**);
8676 extern int sqlite3_mmap_warm(sqlite3
*db
, const char *);
8678 if( objc
!=2 && objc
!=3 ){
8679 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?DBNAME?");
8684 const char *zDb
= 0;
8685 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8687 zDb
= Tcl_GetString(objv
[2]);
8689 rc
= sqlite3_mmap_warm(db
, zDb
);
8690 Tcl_SetObjResult(interp
, Tcl_NewStringObj(sqlite3ErrName(rc
), -1));
8696 ** Usage: test_write_db DB OFFSET DATA
8698 ** Obtain the sqlite3_file* object for the database file for the "main" db
8699 ** of handle DB. Then invoke its xWrite method to write data DATA to offset
8702 static int SQLITE_TCLAPI
test_write_db(
8706 Tcl_Obj
*CONST objv
[]
8709 Tcl_WideInt iOff
= 0;
8710 const unsigned char *aData
= 0;
8712 sqlite3_file
*pFile
= 0;
8716 Tcl_WrongNumArgs(interp
, 1, objv
, "DB OFFSET DATA");
8719 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8720 if( Tcl_GetWideIntFromObj(interp
, objv
[2], &iOff
) ) return TCL_ERROR
;
8721 aData
= Tcl_GetByteArrayFromObj(objv
[3], &nData
);
8723 sqlite3_file_control(db
, "main", SQLITE_FCNTL_FILE_POINTER
, (void*)&pFile
);
8724 rc
= pFile
->pMethods
->xWrite(pFile
, aData
, nData
, iOff
);
8726 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8731 ** Usage: sqlite3_register_cksumvfs
8734 static int SQLITE_TCLAPI
test_register_cksumvfs(
8738 Tcl_Obj
*CONST objv
[]
8741 Tcl_WrongNumArgs(interp
, 1, objv
, "");
8744 extern int sqlite3_register_cksumvfs(const char*);
8745 int rc
= sqlite3_register_cksumvfs(0);
8746 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8752 ** Usage: sqlite3_unregister_cksumvfs
8755 static int SQLITE_TCLAPI
test_unregister_cksumvfs(
8759 Tcl_Obj
*CONST objv
[]
8762 Tcl_WrongNumArgs(interp
, 1, objv
, "");
8765 extern int sqlite3_unregister_cksumvfs(void);
8766 int rc
= sqlite3_unregister_cksumvfs();
8767 Tcl_SetResult(interp
, (char *)sqlite3ErrName(rc
), TCL_VOLATILE
);
8773 ** Usage: decode_hexdb TEXT
8775 ** Example: db deserialize [decode_hexdb $output_of_dbtotxt]
8777 ** This routine returns a byte-array for an SQLite database file that
8778 ** is constructed from a text input which is the output of the "dbtotxt"
8781 static int SQLITE_TCLAPI
test_decode_hexdb(
8785 Tcl_Obj
*CONST objv
[]
8787 const char *zIn
= 0;
8788 unsigned char *a
= 0;
8797 Tcl_WrongNumArgs(interp
, 1, objv
, "HEXDB");
8800 zIn
= Tcl_GetString(objv
[1]);
8801 for(i
=0; zIn
[i
]; i
=iNext
){
8803 for(iNext
=i
; zIn
[iNext
] && zIn
[iNext
]!='\n'; iNext
++){}
8804 if( zIn
[iNext
]=='\n' ) iNext
++;
8805 while( zIn
[i
]==' ' || zIn
[i
]=='\t' ){ i
++; }
8808 rc
= sscanf(zIn
+i
, "| size %d pagesize %d", &n
, &pgsz
);
8809 if( rc
!=2 ) continue;
8810 if( pgsz
<512 || pgsz
>65536 || (pgsz
&(pgsz
-1))!=0 ){
8811 Tcl_AppendResult(interp
, "bad 'pagesize' field", (void*)0);
8814 n
= (n
+pgsz
-1)&~(pgsz
-1); /* Round n up to the next multiple of pgsz */
8816 Tcl_AppendResult(interp
, "bad 'size' field", (void*)0);
8821 Tcl_AppendResult(interp
, "out of memory", (void*)0);
8827 rc
= sscanf(zIn
+i
, "| page %d offset %d", &j
, &k
);
8832 rc
= sscanf(zIn
+i
,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
8833 &j
, &x
[0], &x
[1], &x
[2], &x
[3], &x
[4], &x
[5], &x
[6], &x
[7],
8834 &x
[8], &x
[9], &x
[10], &x
[11], &x
[12], &x
[13], &x
[14], &x
[15]);
8839 for(ii
=0; ii
<16; ii
++) a
[k
+ii
] = x
[ii
]&0xff;
8844 Tcl_SetObjResult(interp
, Tcl_NewByteArrayObj(a
, n
));
8850 ** Client data for the autovacuum_pages callback.
8852 struct AutovacPageData
{
8856 typedef struct AutovacPageData AutovacPageData
;
8859 ** Callback functions for sqlite3_autovacuum_pages
8861 static unsigned int test_autovacuum_pages_callback(
8863 const char *zSchema
,
8864 unsigned int nFilePages
,
8865 unsigned int nFreePages
,
8866 unsigned int nBytePerPage
8868 AutovacPageData
*pData
= (AutovacPageData
*)pClientData
;
8872 Tcl_DStringInit(&str
);
8873 Tcl_DStringAppend(&str
, pData
->zScript
, -1);
8874 Tcl_DStringAppendElement(&str
, zSchema
);
8875 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%u", nFilePages
);
8876 Tcl_DStringAppendElement(&str
, zBuf
);
8877 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%u", nFreePages
);
8878 Tcl_DStringAppendElement(&str
, zBuf
);
8879 sqlite3_snprintf(sizeof(zBuf
), zBuf
, "%u", nBytePerPage
);
8880 Tcl_DStringAppendElement(&str
, zBuf
);
8881 Tcl_ResetResult(pData
->interp
);
8882 Tcl_Eval(pData
->interp
, Tcl_DStringValue(&str
));
8883 Tcl_DStringFree(&str
);
8885 (void)Tcl_GetIntFromObj(0, Tcl_GetObjResult(pData
->interp
), (int*)&x
);
8890 ** Usage: sqlite3_autovacuum_pages DB SCRIPT
8892 ** Add an autovacuum-pages callback to database connection DB. The callback
8893 ** will invoke SCRIPT, after appending parameters.
8895 ** If SCRIPT is an empty string or is omitted, then the callback is
8898 static int SQLITE_TCLAPI
test_autovacuum_pages(
8902 Tcl_Obj
*CONST objv
[]
8904 AutovacPageData
*pData
;
8907 const char *zScript
;
8908 if( objc
!=2 && objc
!=3 ){
8909 Tcl_WrongNumArgs(interp
, 1, objv
, "DB ?SCRIPT?");
8912 if( getDbPointer(interp
, Tcl_GetString(objv
[1]), &db
) ) return TCL_ERROR
;
8913 zScript
= objc
==3 ? Tcl_GetString(objv
[2]) : 0;
8915 size_t nScript
= strlen(zScript
);
8916 pData
= sqlite3_malloc64( sizeof(*pData
) + nScript
+ 1 );
8918 Tcl_AppendResult(interp
, "out of memory", (void*)0);
8921 pData
->interp
= interp
;
8922 pData
->zScript
= (char*)&pData
[1];
8923 memcpy(pData
->zScript
, zScript
, nScript
+1);
8924 rc
= sqlite3_autovacuum_pages(db
,test_autovacuum_pages_callback
,
8925 pData
, sqlite3_free
);
8927 rc
= sqlite3_autovacuum_pages(db
, 0, 0, 0);
8931 sqlite3_snprintf(sizeof(zBuf
), zBuf
,
8932 "sqlite3_autovacuum_pages() returns %d", rc
);
8933 Tcl_AppendResult(interp
, zBuf
, (void*)0);
8940 ** Usage: number_of_cores
8942 ** Return a guess at the number of available cores available on the
8943 ** processor on which this process is running.
8945 static int SQLITE_TCLAPI
guess_number_of_cores(
8949 Tcl_Obj
*CONST objv
[]
8951 unsigned int nCore
= 1;
8953 SYSTEM_INFO sysinfo
;
8954 GetSystemInfo(&sysinfo
);
8955 nCore
= (unsigned int)sysinfo
.dwNumberOfProcessors
;
8956 #elif defined(__APPLE__)
8959 nm
[0] = CTL_HW
; nm
[1] = HW_AVAILCPU
;
8960 sysctl(nm
, 2, &nCore
, &len
, NULL
, 0);
8963 sysctl(nm
, 2, &nCore
, &len
, NULL
, 0);
8966 nCore
= sysconf(_SC_NPROCESSORS_ONLN
);
8968 if( nCore
<=0 ) nCore
= 1;
8969 Tcl_SetObjResult(interp
, Tcl_NewIntObj((int)nCore
));
8975 ** Register commands with the TCL interpreter.
8977 int Sqlitetest1_Init(Tcl_Interp
*interp
){
8978 extern int sqlite3_search_count
;
8979 extern int sqlite3_found_count
;
8980 extern int sqlite3_interrupt_count
;
8981 extern int sqlite3_open_file_count
;
8982 extern int sqlite3_sort_count
;
8983 extern int sqlite3_current_time
;
8984 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
8985 extern int sqlite3_hostid_num
;
8987 extern int sqlite3_max_blobsize
;
8988 extern int SQLITE_TCLAPI
sqlite3BtreeSharedCacheReport(void*,
8989 Tcl_Interp
*,int,Tcl_Obj
*CONST
*);
8990 static int iZero
= 0;
8995 { "db_enter", (Tcl_CmdProc
*)db_enter
},
8996 { "db_leave", (Tcl_CmdProc
*)db_leave
},
8997 { "sqlite3_mprintf_int", (Tcl_CmdProc
*)sqlite3_mprintf_int
},
8998 { "sqlite3_mprintf_int64", (Tcl_CmdProc
*)sqlite3_mprintf_int64
},
8999 { "sqlite3_mprintf_long", (Tcl_CmdProc
*)sqlite3_mprintf_long
},
9000 { "sqlite3_mprintf_str", (Tcl_CmdProc
*)sqlite3_mprintf_str
},
9001 { "sqlite3_snprintf_str", (Tcl_CmdProc
*)sqlite3_snprintf_str
},
9002 { "sqlite3_mprintf_stronly", (Tcl_CmdProc
*)sqlite3_mprintf_stronly
},
9003 { "sqlite3_mprintf_double", (Tcl_CmdProc
*)sqlite3_mprintf_double
},
9004 { "sqlite3_mprintf_scaled", (Tcl_CmdProc
*)sqlite3_mprintf_scaled
},
9005 { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc
*)sqlite3_mprintf_hexdouble
},
9006 { "sqlite3_mprintf_z_test", (Tcl_CmdProc
*)test_mprintf_z
},
9007 { "sqlite3_mprintf_n_test", (Tcl_CmdProc
*)test_mprintf_n
},
9008 { "sqlite3_snprintf_int", (Tcl_CmdProc
*)test_snprintf_int
},
9009 { "sqlite3_last_insert_rowid", (Tcl_CmdProc
*)test_last_rowid
},
9010 { "sqlite3_exec_printf", (Tcl_CmdProc
*)test_exec_printf
},
9011 { "sqlite3_exec_hex", (Tcl_CmdProc
*)test_exec_hex
},
9012 { "sqlite3_exec", (Tcl_CmdProc
*)test_exec
},
9013 { "sqlite3_exec_nr", (Tcl_CmdProc
*)test_exec_nr
},
9014 #ifndef SQLITE_OMIT_GET_TABLE
9015 { "sqlite3_get_table_printf", (Tcl_CmdProc
*)test_get_table_printf
},
9017 { "sqlite3_close", (Tcl_CmdProc
*)sqlite_test_close
},
9018 { "sqlite3_close_v2", (Tcl_CmdProc
*)sqlite_test_close_v2
},
9019 { "sqlite3_create_function", (Tcl_CmdProc
*)test_create_function
},
9020 { "sqlite3_create_aggregate", (Tcl_CmdProc
*)test_create_aggregate
},
9021 { "sqlite3_drop_modules", (Tcl_CmdProc
*)test_drop_modules
},
9022 { "sqlite_register_test_function", (Tcl_CmdProc
*)test_register_func
},
9023 { "sqlite_abort", (Tcl_CmdProc
*)sqlite_abort
},
9024 { "sqlite_bind", (Tcl_CmdProc
*)test_bind
},
9025 { "breakpoint", (Tcl_CmdProc
*)test_breakpoint
},
9026 { "sqlite3_key", (Tcl_CmdProc
*)test_key
},
9027 { "sqlite3_rekey", (Tcl_CmdProc
*)test_rekey
},
9028 { "sqlite3_interrupt", (Tcl_CmdProc
*)test_interrupt
},
9029 { "sqlite3_is_interrupted", (Tcl_CmdProc
*)test_is_interrupted
},
9030 { "sqlite_delete_function", (Tcl_CmdProc
*)delete_function
},
9031 { "sqlite_delete_collation", (Tcl_CmdProc
*)delete_collation
},
9032 { "sqlite3_get_autocommit", (Tcl_CmdProc
*)get_autocommit
},
9033 { "sqlite3_busy_timeout", (Tcl_CmdProc
*)test_busy_timeout
},
9034 { "printf", (Tcl_CmdProc
*)test_printf
},
9035 { "sqlite3IoTrace", (Tcl_CmdProc
*)test_io_trace
},
9036 { "clang_sanitize_address", (Tcl_CmdProc
*)clang_sanitize_address
},
9040 Tcl_ObjCmdProc
*xProc
;
9043 { "sqlite3_db_config", test_sqlite3_db_config
, 0 },
9044 { "sqlite3_txn_state", test_sqlite3_txn_state
, 0 },
9045 { "bad_behavior", test_bad_behavior
, (void*)&iZero
},
9046 { "register_dbstat_vtab", test_register_dbstat_vtab
},
9047 { "sqlite3_connection_pointer", get_sqlite_pointer
, 0 },
9048 { "intarray_addr", test_intarray_addr
, 0 },
9049 { "int64array_addr", test_int64array_addr
, 0 },
9050 { "doublearray_addr", test_doublearray_addr
, 0 },
9051 { "textarray_addr", test_textarray_addr
, 0 },
9052 { "sqlite3_bind_int", test_bind_int
, 0 },
9053 { "sqlite3_bind_zeroblob", test_bind_zeroblob
, 0 },
9054 { "sqlite3_bind_zeroblob64", test_bind_zeroblob64
, 0 },
9055 { "sqlite3_bind_int64", test_bind_int64
, 0 },
9056 { "sqlite3_bind_double", test_bind_double
, 0 },
9057 { "sqlite3_bind_null", test_bind_null
,0 },
9058 { "sqlite3_bind_text", test_bind_text
,0 },
9059 { "sqlite3_bind_text16", test_bind_text16
,0 },
9060 { "sqlite3_bind_blob", test_bind_blob
,0 },
9061 { "sqlite3_bind_value_from_select",test_bind_value_from_select
,0 },
9062 { "sqlite3_bind_value_from_preupdate",test_bind_value_from_preupdate
,0 },
9063 #ifndef SQLITE_OMIT_VIRTUALTABLE
9064 { "sqlite3_carray_bind", test_carray_bind
,0 },
9066 { "sqlite3_bind_parameter_count", test_bind_parameter_count
, 0},
9067 { "sqlite3_bind_parameter_name", test_bind_parameter_name
, 0},
9068 { "sqlite3_bind_parameter_index", test_bind_parameter_index
, 0},
9069 { "sqlite3_clear_bindings", test_clear_bindings
, 0},
9070 { "sqlite3_sleep", test_sleep
, 0},
9071 { "sqlite3_errcode", test_errcode
,0 },
9072 { "sqlite3_extended_errcode", test_ex_errcode
,0 },
9073 { "sqlite3_errmsg", test_errmsg
,0 },
9074 { "sqlite3_error_offset", test_error_offset
,0 },
9075 { "sqlite3_errmsg16", test_errmsg16
,0 },
9076 { "sqlite3_open", test_open
,0 },
9077 { "sqlite3_open16", test_open16
,0 },
9078 { "sqlite3_open_v2", test_open_v2
,0 },
9079 { "sqlite3_complete16", test_complete16
,0 },
9080 { "sqlite3_normalize", test_normalize
,0 },
9082 { "sqlite3_prepare", test_prepare
,0 },
9083 { "sqlite3_prepare16", test_prepare16
,0 },
9084 { "sqlite3_prepare_v2", test_prepare_v2
,0 },
9085 { "sqlite3_prepare_v3", test_prepare_v3
,0 },
9086 { "sqlite3_prepare_tkt3134", test_prepare_tkt3134
, 0},
9087 { "sqlite3_prepare16_v2", test_prepare16_v2
,0 },
9088 { "sqlite3_finalize", test_finalize
,0 },
9089 { "sqlite3_stmt_status", test_stmt_status
,0 },
9090 { "sqlite3_reset", test_reset
,0 },
9091 { "sqlite3_expired", test_expired
,0 },
9092 { "sqlite3_transfer_bindings", test_transfer_bind
,0 },
9093 { "sqlite3_changes", test_changes
,0 },
9094 { "sqlite3_step", test_step
,0 },
9095 { "sqlite3_sql", test_sql
,0 },
9096 { "sqlite3_expanded_sql", test_ex_sql
,0 },
9097 #ifdef SQLITE_ENABLE_NORMALIZE
9098 { "sqlite3_normalized_sql", test_norm_sql
,0 },
9100 { "sqlite3_next_stmt", test_next_stmt
,0 },
9101 { "sqlite3_stmt_readonly", test_stmt_readonly
,0 },
9102 { "sqlite3_stmt_isexplain", test_stmt_isexplain
,0 },
9103 { "sqlite3_stmt_explain", test_stmt_explain
,0 },
9104 { "sqlite3_stmt_busy", test_stmt_busy
,0 },
9105 { "uses_stmt_journal", uses_stmt_journal
,0 },
9107 { "sqlite3_release_memory", test_release_memory
, 0},
9108 { "sqlite3_db_release_memory", test_db_release_memory
, 0},
9109 { "sqlite3_db_cacheflush", test_db_cacheflush
, 0},
9110 { "sqlite3_system_errno", test_system_errno
, 0},
9111 { "sqlite3_db_filename", test_db_filename
, 0},
9112 { "sqlite3_db_readonly", test_db_readonly
, 0},
9113 { "sqlite3_soft_heap_limit", test_soft_heap_limit
, 0},
9114 { "sqlite3_soft_heap_limit64", test_soft_heap_limit
, 0},
9115 { "sqlite3_hard_heap_limit64", test_hard_heap_limit
, 0},
9116 { "sqlite3_thread_cleanup", test_thread_cleanup
, 0},
9117 { "sqlite3_pager_refcounts", test_pager_refcounts
, 0},
9119 { "sqlite3_load_extension", test_load_extension
, 0},
9120 { "sqlite3_enable_load_extension", test_enable_load
, 0},
9121 { "sqlite3_extended_result_codes", test_extended_result_codes
, 0},
9122 { "sqlite3_limit", test_limit
, 0},
9123 { "dbconfig_maindbname_icecube", test_dbconfig_maindbname_icecube
},
9125 { "save_prng_state", save_prng_state
, 0 },
9126 { "restore_prng_state", restore_prng_state
, 0 },
9127 { "reset_prng_state", reset_prng_state
, 0 },
9128 { "prng_seed", prng_seed
, 0 },
9129 { "extra_schema_checks", extra_schema_checks
, 0},
9130 { "use_long_double", use_long_double
, 0},
9131 { "database_never_corrupt", database_never_corrupt
, 0},
9132 { "database_may_be_corrupt", database_may_be_corrupt
, 0},
9133 { "optimization_control", optimization_control
,0},
9135 { "lock_win32_file", win32_file_lock
, 0 },
9136 { "exists_win32_path", win32_exists_path
, 0 },
9137 { "find_win32_file", win32_find_file
, 0 },
9138 { "delete_win32_file", win32_delete_file
, 0 },
9139 { "make_win32_dir", win32_mkdir
, 0 },
9140 { "remove_win32_dir", win32_rmdir
, 0 },
9142 { "tcl_objproc", runAsObjProc
, 0 },
9144 /* sqlite3_column_*() API */
9145 { "sqlite3_column_count", test_column_count
,0 },
9146 { "sqlite3_data_count", test_data_count
,0 },
9147 { "sqlite3_column_type", test_column_type
,0 },
9148 { "sqlite3_column_blob", test_column_blob
,0 },
9149 { "sqlite3_column_double", test_column_double
,0 },
9150 { "sqlite3_column_int64", test_column_int64
,0 },
9151 { "sqlite3_column_text", test_stmt_utf8
, (void*)sqlite3_column_text
},
9152 { "sqlite3_column_name", test_stmt_utf8
, (void*)sqlite3_column_name
},
9153 { "sqlite3_column_int", test_stmt_int
, (void*)sqlite3_column_int
},
9154 { "sqlite3_column_bytes", test_stmt_int
, (void*)sqlite3_column_bytes
},
9155 #ifndef SQLITE_OMIT_DECLTYPE
9156 { "sqlite3_column_decltype",test_stmt_utf8
,(void*)sqlite3_column_decltype
},
9158 #ifdef SQLITE_ENABLE_COLUMN_METADATA
9159 { "sqlite3_column_database_name",test_stmt_utf8
,(void*)sqlite3_column_database_name
},
9160 { "sqlite3_column_table_name",test_stmt_utf8
,(void*)sqlite3_column_table_name
},
9161 { "sqlite3_column_origin_name",test_stmt_utf8
,(void*)sqlite3_column_origin_name
},
9164 #ifndef SQLITE_OMIT_UTF16
9165 { "sqlite3_column_bytes16", test_stmt_int
, (void*)sqlite3_column_bytes16
},
9166 { "sqlite3_column_text16", test_stmt_utf16
, (void*)sqlite3_column_text16
},
9167 { "sqlite3_column_name16", test_stmt_utf16
, (void*)sqlite3_column_name16
},
9168 { "add_alignment_test_collations", add_alignment_test_collations
, 0 },
9169 #ifndef SQLITE_OMIT_DECLTYPE
9170 { "sqlite3_column_decltype16",test_stmt_utf16
,(void*)sqlite3_column_decltype16
},
9172 #ifdef SQLITE_ENABLE_COLUMN_METADATA
9173 {"sqlite3_column_database_name16",
9174 test_stmt_utf16
, (void*)sqlite3_column_database_name16
},
9175 {"sqlite3_column_table_name16", test_stmt_utf16
, (void*)sqlite3_column_table_name16
},
9176 {"sqlite3_column_origin_name16", test_stmt_utf16
, (void*)sqlite3_column_origin_name16
},
9179 { "sqlite3_create_collation_v2", test_create_collation_v2
, 0 },
9180 { "sqlite3_global_recover", test_global_recover
, 0 },
9181 { "working_64bit_int", working_64bit_int
, 0 },
9182 { "vfs_unlink_test", vfs_unlink_test
, 0 },
9183 { "vfs_initfail_test", vfs_initfail_test
, 0 },
9184 { "vfs_unregister_all", vfs_unregister_all
, 0 },
9185 { "vfs_reregister_all", vfs_reregister_all
, 0 },
9186 { "file_control_test", file_control_test
, 0 },
9187 { "file_control_lasterrno_test", file_control_lasterrno_test
, 0 },
9188 { "file_control_lockproxy_test", file_control_lockproxy_test
, 0 },
9189 { "file_control_chunksize_test", file_control_chunksize_test
, 0 },
9190 { "file_control_sizehint_test", file_control_sizehint_test
, 0 },
9191 { "file_control_data_version", file_control_data_version
, 0 },
9193 { "file_control_win32_av_retry", file_control_win32_av_retry
, 0 },
9194 { "file_control_win32_get_handle", file_control_win32_get_handle
, 0 },
9195 { "file_control_win32_set_handle", file_control_win32_set_handle
, 0 },
9197 { "file_control_persist_wal", file_control_persist_wal
, 0 },
9198 { "file_control_powersafe_overwrite",file_control_powersafe_overwrite
,0},
9199 { "file_control_vfsname", file_control_vfsname
, 0 },
9200 { "file_control_reservebytes", file_control_reservebytes
, 0 },
9201 { "file_control_tempfilename", file_control_tempfilename
, 0 },
9202 { "file_control_external_reader", file_control_external_reader
, 0 },
9203 { "sqlite3_vfs_list", vfs_list
, 0 },
9204 { "sqlite3_create_function_v2", test_create_function_v2
, 0 },
9206 /* Functions from os.h */
9207 #ifndef SQLITE_OMIT_UTF16
9208 { "add_test_collate", test_collate
, 0 },
9209 { "add_test_collate_needed", test_collate_needed
, 0 },
9210 { "add_test_function", test_function
, 0 },
9211 { "add_test_utf16bin_collate", test_utf16bin_collate
, 0 },
9213 { "sqlite3_test_errstr", test_errstr
, 0 },
9214 { "tcl_variable_type", tcl_variable_type
, 0 },
9215 #ifndef SQLITE_OMIT_SHARED_CACHE
9216 { "sqlite3_enable_shared_cache", test_enable_shared
, 0 },
9217 { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport
, 0},
9219 { "sqlite3_libversion_number", test_libversion_number
, 0 },
9220 { "sqlite3_table_column_metadata", test_table_column_metadata
, 0 },
9221 #ifndef SQLITE_OMIT_INCRBLOB
9222 { "sqlite3_blob_reopen", test_blob_reopen
, 0 },
9224 { "pcache_stats", test_pcache_stats
, 0 },
9225 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
9226 { "sqlite3_unlock_notify", test_unlock_notify
, 0 },
9228 { "sqlite3_wal_checkpoint", test_wal_checkpoint
, 0 },
9229 { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2
, 0 },
9230 { "sqlite3_wal_autocheckpoint",test_wal_autocheckpoint
, 0 },
9231 { "test_sqlite3_log", test_sqlite3_log
, 0 },
9232 #ifndef SQLITE_OMIT_EXPLAIN
9233 { "print_explain_query_plan", test_print_eqp
, 0 },
9235 { "strftime", strftime_cmd
},
9236 { "sqlite3_test_control", test_test_control
},
9237 { ".treetrace", test_treetrace
},
9239 { "getrusage", test_getrusage
},
9241 { "load_static_extension", tclLoadStaticExtensionCmd
},
9242 { "sorter_test_fakeheap", sorter_test_fakeheap
},
9243 { "sorter_test_sort4_helper", sorter_test_sort4_helper
},
9244 #ifdef SQLITE_USER_AUTHENTICATION
9245 { "sqlite3_user_authenticate", test_user_authenticate
, 0 },
9246 { "sqlite3_user_add", test_user_add
, 0 },
9247 { "sqlite3_user_change", test_user_change
, 0 },
9248 { "sqlite3_user_delete", test_user_delete
, 0 },
9250 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
9251 { "sqlite3_stmt_scanstatus", test_stmt_scanstatus
, 0 },
9252 { "sqlite3_stmt_scanstatus_reset", test_stmt_scanstatus_reset
, 0 },
9254 #ifdef SQLITE_ENABLE_SQLLOG
9255 { "sqlite3_config_sqllog", test_config_sqllog
, 0 },
9257 { "vfs_current_time_int64", vfsCurrentTimeInt64
, 0 },
9258 #ifdef SQLITE_ENABLE_SNAPSHOT
9259 { "sqlite3_snapshot_get", test_snapshot_get
, 0 },
9260 { "sqlite3_snapshot_open", test_snapshot_open
, 0 },
9261 { "sqlite3_snapshot_free", test_snapshot_free
, 0 },
9262 { "sqlite3_snapshot_cmp", test_snapshot_cmp
, 0 },
9263 { "sqlite3_snapshot_recover", test_snapshot_recover
, 0 },
9264 { "sqlite3_snapshot_get_blob", test_snapshot_get_blob
, 0 },
9265 { "sqlite3_snapshot_open_blob", test_snapshot_open_blob
, 0 },
9266 { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob
, 0 },
9268 { "sqlite3_delete_database", test_delete_database
, 0 },
9269 { "atomic_batch_write", test_atomic_batch_write
, 0 },
9270 { "sqlite3_mmap_warm", test_mmap_warm
, 0 },
9271 { "sqlite3_config_sorterref", test_config_sorterref
, 0 },
9272 { "sqlite3_autovacuum_pages", test_autovacuum_pages
, 0 },
9273 { "decode_hexdb", test_decode_hexdb
, 0 },
9274 { "test_write_db", test_write_db
, 0 },
9275 { "sqlite3_register_cksumvfs", test_register_cksumvfs
, 0 },
9276 { "sqlite3_unregister_cksumvfs", test_unregister_cksumvfs
, 0 },
9277 { "number_of_cores", guess_number_of_cores
, 0 },
9278 #ifndef SQLITE_OMIT_VIRTUALTABLE
9279 { "create_null_module", test_create_null_module
, 0 },
9282 static int bitmask_size
= sizeof(Bitmask
)*8;
9283 static int longdouble_size
= sizeof(LONGDOUBLE_TYPE
);
9285 extern int sqlite3_sync_count
, sqlite3_fullsync_count
;
9286 extern int sqlite3_opentemp_count
;
9287 extern int sqlite3_like_count
;
9288 extern int sqlite3_xferopt_count
;
9289 extern int sqlite3_pager_readdb_count
;
9290 extern int sqlite3_pager_writedb_count
;
9291 extern int sqlite3_pager_writej_count
;
9293 extern LONG
volatile sqlite3_os_type
;
9296 extern u32 sqlite3WhereTrace
;
9297 extern int sqlite3OSTrace
;
9298 extern int sqlite3WalTrace
;
9301 #ifdef SQLITE_ENABLE_FTS3
9302 extern int sqlite3_fts3_enable_parentheses
;
9306 for(i
=0; i
<sizeof(aCmd
)/sizeof(aCmd
[0]); i
++){
9307 Tcl_CreateCommand(interp
, aCmd
[i
].zName
, aCmd
[i
].xProc
, 0, 0);
9309 for(i
=0; i
<sizeof(aObjCmd
)/sizeof(aObjCmd
[0]); i
++){
9310 Tcl_CreateObjCommand(interp
, aObjCmd
[i
].zName
,
9311 aObjCmd
[i
].xProc
, aObjCmd
[i
].clientData
, 0);
9313 Tcl_LinkVar(interp
, "sqlite_search_count",
9314 (char*)&sqlite3_search_count
, TCL_LINK_INT
);
9315 Tcl_LinkVar(interp
, "sqlite_found_count",
9316 (char*)&sqlite3_found_count
, TCL_LINK_INT
);
9317 Tcl_LinkVar(interp
, "sqlite_sort_count",
9318 (char*)&sqlite3_sort_count
, TCL_LINK_INT
);
9319 Tcl_LinkVar(interp
, "sqlite3_max_blobsize",
9320 (char*)&sqlite3_max_blobsize
, TCL_LINK_INT
);
9321 Tcl_LinkVar(interp
, "sqlite_like_count",
9322 (char*)&sqlite3_like_count
, TCL_LINK_INT
);
9323 Tcl_LinkVar(interp
, "sqlite_interrupt_count",
9324 (char*)&sqlite3_interrupt_count
, TCL_LINK_INT
);
9325 Tcl_LinkVar(interp
, "sqlite_open_file_count",
9326 (char*)&sqlite3_open_file_count
, TCL_LINK_INT
);
9327 Tcl_LinkVar(interp
, "sqlite_current_time",
9328 (char*)&sqlite3_current_time
, TCL_LINK_INT
);
9329 #if SQLITE_OS_UNIX && defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE
9330 Tcl_LinkVar(interp
, "sqlite_hostid_num",
9331 (char*)&sqlite3_hostid_num
, TCL_LINK_INT
);
9333 Tcl_LinkVar(interp
, "sqlite3_xferopt_count",
9334 (char*)&sqlite3_xferopt_count
, TCL_LINK_INT
);
9335 Tcl_LinkVar(interp
, "sqlite3_pager_readdb_count",
9336 (char*)&sqlite3_pager_readdb_count
, TCL_LINK_INT
);
9337 Tcl_LinkVar(interp
, "sqlite3_pager_writedb_count",
9338 (char*)&sqlite3_pager_writedb_count
, TCL_LINK_INT
);
9339 Tcl_LinkVar(interp
, "sqlite3_pager_writej_count",
9340 (char*)&sqlite3_pager_writej_count
, TCL_LINK_INT
);
9341 #ifndef SQLITE_OMIT_UTF16
9342 Tcl_LinkVar(interp
, "unaligned_string_counter",
9343 (char*)&unaligned_string_counter
, TCL_LINK_INT
);
9345 #ifndef SQLITE_OMIT_UTF16
9346 Tcl_LinkVar(interp
, "sqlite_last_needed_collation",
9347 (char*)&pzNeededCollation
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
9350 Tcl_LinkVar(interp
, "sqlite_os_type",
9351 (char*)&sqlite3_os_type
, TCL_LINK_LONG
);
9355 static const char *query_plan
= "*** OBSOLETE VARIABLE ***";
9356 Tcl_LinkVar(interp
, "sqlite_query_plan",
9357 (char*)&query_plan
, TCL_LINK_STRING
|TCL_LINK_READ_ONLY
);
9361 Tcl_LinkVar(interp
, "sqlite_where_trace",
9362 (char*)&sqlite3WhereTrace
, TCL_LINK_INT
);
9363 Tcl_LinkVar(interp
, "sqlite_os_trace",
9364 (char*)&sqlite3OSTrace
, TCL_LINK_INT
);
9365 #ifndef SQLITE_OMIT_WAL
9366 Tcl_LinkVar(interp
, "sqlite_wal_trace",
9367 (char*)&sqlite3WalTrace
, TCL_LINK_INT
);
9370 #ifndef SQLITE_OMIT_DISKIO
9371 Tcl_LinkVar(interp
, "sqlite_opentemp_count",
9372 (char*)&sqlite3_opentemp_count
, TCL_LINK_INT
);
9374 Tcl_LinkVar(interp
, "sqlite_static_bind_value",
9375 (char*)&sqlite_static_bind_value
, TCL_LINK_STRING
);
9376 Tcl_LinkVar(interp
, "sqlite_static_bind_nbyte",
9377 (char*)&sqlite_static_bind_nbyte
, TCL_LINK_INT
);
9378 Tcl_LinkVar(interp
, "sqlite_temp_directory",
9379 (char*)&sqlite3_temp_directory
, TCL_LINK_STRING
);
9380 Tcl_LinkVar(interp
, "sqlite_data_directory",
9381 (char*)&sqlite3_data_directory
, TCL_LINK_STRING
);
9382 Tcl_LinkVar(interp
, "bitmask_size",
9383 (char*)&bitmask_size
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
9384 Tcl_LinkVar(interp
, "longdouble_size",
9385 (char*)&longdouble_size
, TCL_LINK_INT
|TCL_LINK_READ_ONLY
);
9386 Tcl_LinkVar(interp
, "sqlite_sync_count",
9387 (char*)&sqlite3_sync_count
, TCL_LINK_INT
);
9388 Tcl_LinkVar(interp
, "sqlite_fullsync_count",
9389 (char*)&sqlite3_fullsync_count
, TCL_LINK_INT
);
9390 #if defined(SQLITE_ENABLE_TREETRACE)
9391 Tcl_LinkVar(interp
, "sqlite3_unsupported_treetrace",
9392 (char*)&sqlite3TreeTrace
, TCL_LINK_INT
);
9394 #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST)
9395 Tcl_LinkVar(interp
, "sqlite_fts3_enable_parentheses",
9396 (char*)&sqlite3_fts3_enable_parentheses
, TCL_LINK_INT
);