Do not allow auxiliary columns in the rtree to interfere with query planning.
[sqlite.git] / src / test2.c
blob850e1e1a0448ef639178deb881528886bece8cc5
1 /*
2 ** 2001 September 15
3 **
4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing:
6 **
7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give.
11 *************************************************************************
12 ** Code for testing the pager.c module in SQLite. 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"
17 #if defined(INCLUDE_SQLITE_TCL_H)
18 # include "sqlite_tcl.h"
19 #else
20 # include "tcl.h"
21 #endif
22 #include <stdlib.h>
23 #include <string.h>
24 #include <ctype.h>
26 extern const char *sqlite3ErrName(int);
29 ** Page size and reserved size used for testing.
31 static int test_pagesize = 1024;
34 ** Dummy page reinitializer
36 static void pager_test_reiniter(DbPage *pNotUsed){
37 return;
41 ** Usage: pager_open FILENAME N-PAGE
43 ** Open a new pager
45 static int SQLITE_TCLAPI pager_open(
46 void *NotUsed,
47 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
48 int argc, /* Number of arguments */
49 const char **argv /* Text of each argument */
51 u32 pageSize;
52 Pager *pPager;
53 int nPage;
54 int rc;
55 char zBuf[100];
56 if( argc!=3 ){
57 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
58 " FILENAME N-PAGE\"", 0);
59 return TCL_ERROR;
61 if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
62 rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
63 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
64 pager_test_reiniter);
65 if( rc!=SQLITE_OK ){
66 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
67 return TCL_ERROR;
69 sqlite3PagerSetCachesize(pPager, nPage);
70 pageSize = test_pagesize;
71 sqlite3PagerSetPagesize(pPager, &pageSize, -1);
72 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager);
73 Tcl_AppendResult(interp, zBuf, 0);
74 return TCL_OK;
78 ** Usage: pager_close ID
80 ** Close the given pager.
82 static int SQLITE_TCLAPI pager_close(
83 void *NotUsed,
84 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
85 int argc, /* Number of arguments */
86 const char **argv /* Text of each argument */
88 Pager *pPager;
89 int rc;
90 if( argc!=2 ){
91 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
92 " ID\"", 0);
93 return TCL_ERROR;
95 pPager = sqlite3TestTextToPtr(argv[1]);
96 rc = sqlite3PagerClose(pPager, 0);
97 if( rc!=SQLITE_OK ){
98 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
99 return TCL_ERROR;
101 return TCL_OK;
105 ** Usage: pager_rollback ID
107 ** Rollback changes
109 static int SQLITE_TCLAPI pager_rollback(
110 void *NotUsed,
111 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
112 int argc, /* Number of arguments */
113 const char **argv /* Text of each argument */
115 Pager *pPager;
116 int rc;
117 if( argc!=2 ){
118 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
119 " ID\"", 0);
120 return TCL_ERROR;
122 pPager = sqlite3TestTextToPtr(argv[1]);
123 rc = sqlite3PagerRollback(pPager);
124 if( rc!=SQLITE_OK ){
125 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
126 return TCL_ERROR;
128 return TCL_OK;
132 ** Usage: pager_commit ID
134 ** Commit all changes
136 static int SQLITE_TCLAPI pager_commit(
137 void *NotUsed,
138 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
139 int argc, /* Number of arguments */
140 const char **argv /* Text of each argument */
142 Pager *pPager;
143 int rc;
144 if( argc!=2 ){
145 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
146 " ID\"", 0);
147 return TCL_ERROR;
149 pPager = sqlite3TestTextToPtr(argv[1]);
150 rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
151 if( rc!=SQLITE_OK ){
152 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
153 return TCL_ERROR;
155 rc = sqlite3PagerCommitPhaseTwo(pPager);
156 if( rc!=SQLITE_OK ){
157 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
158 return TCL_ERROR;
160 return TCL_OK;
164 ** Usage: pager_stmt_begin ID
166 ** Start a new checkpoint.
168 static int SQLITE_TCLAPI pager_stmt_begin(
169 void *NotUsed,
170 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
171 int argc, /* Number of arguments */
172 const char **argv /* Text of each argument */
174 Pager *pPager;
175 int rc;
176 if( argc!=2 ){
177 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
178 " ID\"", 0);
179 return TCL_ERROR;
181 pPager = sqlite3TestTextToPtr(argv[1]);
182 rc = sqlite3PagerOpenSavepoint(pPager, 1);
183 if( rc!=SQLITE_OK ){
184 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
185 return TCL_ERROR;
187 return TCL_OK;
191 ** Usage: pager_stmt_rollback ID
193 ** Rollback changes to a checkpoint
195 static int SQLITE_TCLAPI pager_stmt_rollback(
196 void *NotUsed,
197 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
198 int argc, /* Number of arguments */
199 const char **argv /* Text of each argument */
201 Pager *pPager;
202 int rc;
203 if( argc!=2 ){
204 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
205 " ID\"", 0);
206 return TCL_ERROR;
208 pPager = sqlite3TestTextToPtr(argv[1]);
209 rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, 0);
210 sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
211 if( rc!=SQLITE_OK ){
212 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
213 return TCL_ERROR;
215 return TCL_OK;
219 ** Usage: pager_stmt_commit ID
221 ** Commit changes to a checkpoint
223 static int SQLITE_TCLAPI pager_stmt_commit(
224 void *NotUsed,
225 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
226 int argc, /* Number of arguments */
227 const char **argv /* Text of each argument */
229 Pager *pPager;
230 int rc;
231 if( argc!=2 ){
232 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
233 " ID\"", 0);
234 return TCL_ERROR;
236 pPager = sqlite3TestTextToPtr(argv[1]);
237 rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
238 if( rc!=SQLITE_OK ){
239 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
240 return TCL_ERROR;
242 return TCL_OK;
246 ** Usage: pager_stats ID
248 ** Return pager statistics.
250 static int SQLITE_TCLAPI pager_stats(
251 void *NotUsed,
252 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
253 int argc, /* Number of arguments */
254 const char **argv /* Text of each argument */
256 Pager *pPager;
257 int i, *a;
258 if( argc!=2 ){
259 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
260 " ID\"", 0);
261 return TCL_ERROR;
263 pPager = sqlite3TestTextToPtr(argv[1]);
264 a = sqlite3PagerStats(pPager);
265 for(i=0; i<9; i++){
266 static char *zName[] = {
267 "ref", "page", "max", "size", "state", "err",
268 "hit", "miss", "ovfl",
270 char zBuf[100];
271 Tcl_AppendElement(interp, zName[i]);
272 sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",a[i]);
273 Tcl_AppendElement(interp, zBuf);
275 return TCL_OK;
279 ** Usage: pager_pagecount ID
281 ** Return the size of the database file.
283 static int SQLITE_TCLAPI pager_pagecount(
284 void *NotUsed,
285 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
286 int argc, /* Number of arguments */
287 const char **argv /* Text of each argument */
289 Pager *pPager;
290 char zBuf[100];
291 int nPage;
292 if( argc!=2 ){
293 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
294 " ID\"", 0);
295 return TCL_ERROR;
297 pPager = sqlite3TestTextToPtr(argv[1]);
298 sqlite3PagerPagecount(pPager, &nPage);
299 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage);
300 Tcl_AppendResult(interp, zBuf, 0);
301 return TCL_OK;
305 ** Usage: page_get ID PGNO
307 ** Return a pointer to a page from the database.
309 static int SQLITE_TCLAPI page_get(
310 void *NotUsed,
311 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
312 int argc, /* Number of arguments */
313 const char **argv /* Text of each argument */
315 Pager *pPager;
316 char zBuf[100];
317 DbPage *pPage = 0;
318 int pgno;
319 int rc;
320 if( argc!=3 ){
321 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
322 " ID PGNO\"", 0);
323 return TCL_ERROR;
325 pPager = sqlite3TestTextToPtr(argv[1]);
326 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
327 rc = sqlite3PagerSharedLock(pPager);
328 if( rc==SQLITE_OK ){
329 rc = sqlite3PagerGet(pPager, pgno, &pPage, 0);
331 if( rc!=SQLITE_OK ){
332 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
333 return TCL_ERROR;
335 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
336 Tcl_AppendResult(interp, zBuf, 0);
337 return TCL_OK;
341 ** Usage: page_lookup ID PGNO
343 ** Return a pointer to a page if the page is already in cache.
344 ** If not in cache, return an empty string.
346 static int SQLITE_TCLAPI page_lookup(
347 void *NotUsed,
348 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
349 int argc, /* Number of arguments */
350 const char **argv /* Text of each argument */
352 Pager *pPager;
353 char zBuf[100];
354 DbPage *pPage;
355 int pgno;
356 if( argc!=3 ){
357 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
358 " ID PGNO\"", 0);
359 return TCL_ERROR;
361 pPager = sqlite3TestTextToPtr(argv[1]);
362 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
363 pPage = sqlite3PagerLookup(pPager, pgno);
364 if( pPage ){
365 sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
366 Tcl_AppendResult(interp, zBuf, 0);
368 return TCL_OK;
372 ** Usage: pager_truncate ID PGNO
374 static int SQLITE_TCLAPI pager_truncate(
375 void *NotUsed,
376 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
377 int argc, /* Number of arguments */
378 const char **argv /* Text of each argument */
380 Pager *pPager;
381 int pgno;
382 if( argc!=3 ){
383 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
384 " ID PGNO\"", 0);
385 return TCL_ERROR;
387 pPager = sqlite3TestTextToPtr(argv[1]);
388 if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
389 sqlite3PagerTruncateImage(pPager, pgno);
390 return TCL_OK;
395 ** Usage: page_unref PAGE
397 ** Drop a pointer to a page.
399 static int SQLITE_TCLAPI page_unref(
400 void *NotUsed,
401 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
402 int argc, /* Number of arguments */
403 const char **argv /* Text of each argument */
405 DbPage *pPage;
406 if( argc!=2 ){
407 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
408 " PAGE\"", 0);
409 return TCL_ERROR;
411 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
412 sqlite3PagerUnref(pPage);
413 return TCL_OK;
417 ** Usage: page_read PAGE
419 ** Return the content of a page
421 static int SQLITE_TCLAPI page_read(
422 void *NotUsed,
423 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
424 int argc, /* Number of arguments */
425 const char **argv /* Text of each argument */
427 char zBuf[100];
428 DbPage *pPage;
429 if( argc!=2 ){
430 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
431 " PAGE\"", 0);
432 return TCL_ERROR;
434 pPage = sqlite3TestTextToPtr(argv[1]);
435 memcpy(zBuf, sqlite3PagerGetData(pPage), sizeof(zBuf));
436 Tcl_AppendResult(interp, zBuf, 0);
437 return TCL_OK;
441 ** Usage: page_number PAGE
443 ** Return the page number for a page.
445 static int SQLITE_TCLAPI page_number(
446 void *NotUsed,
447 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
448 int argc, /* Number of arguments */
449 const char **argv /* Text of each argument */
451 char zBuf[100];
452 DbPage *pPage;
453 if( argc!=2 ){
454 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
455 " PAGE\"", 0);
456 return TCL_ERROR;
458 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
459 sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage));
460 Tcl_AppendResult(interp, zBuf, 0);
461 return TCL_OK;
465 ** Usage: page_write PAGE DATA
467 ** Write something into a page.
469 static int SQLITE_TCLAPI page_write(
470 void *NotUsed,
471 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
472 int argc, /* Number of arguments */
473 const char **argv /* Text of each argument */
475 DbPage *pPage;
476 char *pData;
477 int rc;
478 if( argc!=3 ){
479 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
480 " PAGE DATA\"", 0);
481 return TCL_ERROR;
483 pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
484 rc = sqlite3PagerWrite(pPage);
485 if( rc!=SQLITE_OK ){
486 Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
487 return TCL_ERROR;
489 pData = sqlite3PagerGetData(pPage);
490 strncpy(pData, argv[2], test_pagesize-1);
491 pData[test_pagesize-1] = 0;
492 return TCL_OK;
495 #ifndef SQLITE_OMIT_DISKIO
497 ** Usage: fake_big_file N FILENAME
499 ** Write a few bytes at the N megabyte point of FILENAME. This will
500 ** create a large file. If the file was a valid SQLite database, then
501 ** the next time the database is opened, SQLite will begin allocating
502 ** new pages after N. If N is 2096 or bigger, this will test the
503 ** ability of SQLite to write to large files.
505 static int SQLITE_TCLAPI fake_big_file(
506 void *NotUsed,
507 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
508 int argc, /* Number of arguments */
509 const char **argv /* Text of each argument */
511 sqlite3_vfs *pVfs;
512 sqlite3_file *fd = 0;
513 int rc;
514 int n;
515 i64 offset;
516 char *zFile;
517 int nFile;
518 if( argc!=3 ){
519 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
520 " N-MEGABYTES FILE\"", 0);
521 return TCL_ERROR;
523 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
525 pVfs = sqlite3_vfs_find(0);
526 nFile = (int)strlen(argv[2]);
527 zFile = sqlite3_malloc( nFile+2 );
528 if( zFile==0 ) return TCL_ERROR;
529 memcpy(zFile, argv[2], nFile+1);
530 zFile[nFile+1] = 0;
531 rc = sqlite3OsOpenMalloc(pVfs, zFile, &fd,
532 (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
534 if( rc ){
535 Tcl_AppendResult(interp, "open failed: ", sqlite3ErrName(rc), 0);
536 sqlite3_free(zFile);
537 return TCL_ERROR;
539 offset = n;
540 offset *= 1024*1024;
541 rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
542 sqlite3OsCloseFree(fd);
543 sqlite3_free(zFile);
544 if( rc ){
545 Tcl_AppendResult(interp, "write failed: ", sqlite3ErrName(rc), 0);
546 return TCL_ERROR;
548 return TCL_OK;
550 #endif
554 ** test_control_pending_byte PENDING_BYTE
556 ** Set the PENDING_BYTE using the sqlite3_test_control() interface.
558 static int SQLITE_TCLAPI testPendingByte(
559 void *NotUsed,
560 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
561 int argc, /* Number of arguments */
562 const char **argv /* Text of each argument */
564 int pbyte;
565 int rc;
566 if( argc!=2 ){
567 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
568 " PENDING-BYTE\"", (void*)0);
569 return TCL_ERROR;
571 if( Tcl_GetInt(interp, argv[1], &pbyte) ) return TCL_ERROR;
572 rc = sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, pbyte);
573 Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
574 return TCL_OK;
578 ** The sqlite3FaultSim() callback:
580 static Tcl_Interp *faultSimInterp = 0;
581 static int faultSimScriptSize = 0;
582 static char *faultSimScript;
583 static int faultSimCallback(int x){
584 char zInt[30];
585 int i;
586 int isNeg;
587 int rc;
588 if( x==0 ){
589 memcpy(faultSimScript+faultSimScriptSize, "0", 2);
590 }else{
591 /* Convert x to text without using any sqlite3 routines */
592 if( x<0 ){
593 isNeg = 1;
594 x = -x;
595 }else{
596 isNeg = 0;
598 zInt[sizeof(zInt)-1] = 0;
599 for(i=sizeof(zInt)-2; i>0 && x>0; i--, x /= 10){
600 zInt[i] = (x%10) + '0';
602 if( isNeg ) zInt[i--] = '-';
603 memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i);
605 rc = Tcl_Eval(faultSimInterp, faultSimScript);
606 if( rc ){
607 fprintf(stderr, "fault simulator script failed: [%s]", faultSimScript);
608 rc = SQLITE_ERROR;
609 }else{
610 rc = atoi(Tcl_GetStringResult(faultSimInterp));
612 Tcl_ResetResult(faultSimInterp);
613 return rc;
617 ** sqlite3_test_control_fault_install SCRIPT
619 ** Arrange to invoke SCRIPT with the integer argument to sqlite3FaultSim()
620 ** appended, whenever sqlite3FaultSim() is called. Or, if SCRIPT is the
621 ** empty string, cancel the sqlite3FaultSim() callback.
623 static int SQLITE_TCLAPI faultInstallCmd(
624 void *NotUsed,
625 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
626 int argc, /* Number of arguments */
627 const char **argv /* Text of each argument */
629 const char *zScript;
630 int nScript;
631 int rc;
632 if( argc!=1 && argc!=2 ){
633 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
634 " SCRIPT\"", (void*)0);
636 zScript = argc==2 ? argv[1] : "";
637 nScript = (int)strlen(zScript);
638 if( faultSimScript ){
639 free(faultSimScript);
640 faultSimScript = 0;
642 if( nScript==0 ){
643 rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, 0);
644 }else{
645 faultSimScript = malloc( nScript+100 );
646 if( faultSimScript==0 ){
647 Tcl_AppendResult(interp, "out of memory", (void*)0);
648 return SQLITE_ERROR;
650 memcpy(faultSimScript, zScript, nScript);
651 faultSimScript[nScript] = ' ';
652 faultSimScriptSize = nScript+1;
653 faultSimInterp = interp;
654 rc = sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL, faultSimCallback);
656 Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
657 return SQLITE_OK;
661 ** sqlite3BitvecBuiltinTest SIZE PROGRAM
663 ** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
664 ** See comments on sqlite3BitvecBuiltinTest() for additional information.
666 static int SQLITE_TCLAPI testBitvecBuiltinTest(
667 void *NotUsed,
668 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
669 int argc, /* Number of arguments */
670 const char **argv /* Text of each argument */
672 int sz, rc;
673 int nProg = 0;
674 int aProg[100];
675 const char *z;
676 if( argc!=3 ){
677 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
678 " SIZE PROGRAM\"", (void*)0);
680 if( Tcl_GetInt(interp, argv[1], &sz) ) return TCL_ERROR;
681 z = argv[2];
682 while( nProg<99 && *z ){
683 while( *z && !sqlite3Isdigit(*z) ){ z++; }
684 if( *z==0 ) break;
685 aProg[nProg++] = atoi(z);
686 while( sqlite3Isdigit(*z) ){ z++; }
688 aProg[nProg] = 0;
689 rc = sqlite3_test_control(SQLITE_TESTCTRL_BITVEC_TEST, sz, aProg);
690 Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
691 return TCL_OK;
695 ** Register commands with the TCL interpreter.
697 int Sqlitetest2_Init(Tcl_Interp *interp){
698 extern int sqlite3_io_error_persist;
699 extern int sqlite3_io_error_pending;
700 extern int sqlite3_io_error_hit;
701 extern int sqlite3_io_error_hardhit;
702 extern int sqlite3_diskfull_pending;
703 extern int sqlite3_diskfull;
704 static struct {
705 char *zName;
706 Tcl_CmdProc *xProc;
707 } aCmd[] = {
708 { "pager_open", (Tcl_CmdProc*)pager_open },
709 { "pager_close", (Tcl_CmdProc*)pager_close },
710 { "pager_commit", (Tcl_CmdProc*)pager_commit },
711 { "pager_rollback", (Tcl_CmdProc*)pager_rollback },
712 { "pager_stmt_begin", (Tcl_CmdProc*)pager_stmt_begin },
713 { "pager_stmt_commit", (Tcl_CmdProc*)pager_stmt_commit },
714 { "pager_stmt_rollback", (Tcl_CmdProc*)pager_stmt_rollback },
715 { "pager_stats", (Tcl_CmdProc*)pager_stats },
716 { "pager_pagecount", (Tcl_CmdProc*)pager_pagecount },
717 { "page_get", (Tcl_CmdProc*)page_get },
718 { "page_lookup", (Tcl_CmdProc*)page_lookup },
719 { "page_unref", (Tcl_CmdProc*)page_unref },
720 { "page_read", (Tcl_CmdProc*)page_read },
721 { "page_write", (Tcl_CmdProc*)page_write },
722 { "page_number", (Tcl_CmdProc*)page_number },
723 { "pager_truncate", (Tcl_CmdProc*)pager_truncate },
724 #ifndef SQLITE_OMIT_DISKIO
725 { "fake_big_file", (Tcl_CmdProc*)fake_big_file },
726 #endif
727 { "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest },
728 { "sqlite3_test_control_pending_byte", (Tcl_CmdProc*)testPendingByte },
729 { "sqlite3_test_control_fault_install", (Tcl_CmdProc*)faultInstallCmd },
731 int i;
732 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
733 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
735 Tcl_LinkVar(interp, "sqlite_io_error_pending",
736 (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
737 Tcl_LinkVar(interp, "sqlite_io_error_persist",
738 (char*)&sqlite3_io_error_persist, TCL_LINK_INT);
739 Tcl_LinkVar(interp, "sqlite_io_error_hit",
740 (char*)&sqlite3_io_error_hit, TCL_LINK_INT);
741 Tcl_LinkVar(interp, "sqlite_io_error_hardhit",
742 (char*)&sqlite3_io_error_hardhit, TCL_LINK_INT);
743 Tcl_LinkVar(interp, "sqlite_diskfull_pending",
744 (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
745 Tcl_LinkVar(interp, "sqlite_diskfull",
746 (char*)&sqlite3_diskfull, TCL_LINK_INT);
747 #ifndef SQLITE_OMIT_WSD
748 Tcl_LinkVar(interp, "sqlite_pending_byte",
749 (char*)&sqlite3PendingByte, TCL_LINK_INT | TCL_LINK_READ_ONLY);
750 #endif
751 return TCL_OK;