Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Change the name of the sanity_check PRAGMA to "integrity_check" and make it available on all compiles. (CVS 381) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c6e9048e66c8d8e2d5f6c62aa724eef3 |
User & Date: | drh 2002-02-19 13:39:21.000 |
Context
2002-02-19
| ||
15:00 | Optimize simple min() and max() queries. (CVS 382) (check-in: cc5abfe392 user: drh tags: trunk) | |
13:39 | Change the name of the sanity_check PRAGMA to "integrity_check" and make it available on all compiles. (CVS 381) (check-in: c6e9048e66 user: drh tags: trunk) | |
00:30 | Version 2.3.3 (CVS 444) (check-in: 72c5a92aa6 user: drh tags: trunk) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.3.4 |
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.53 2002/02/19 13:39:22 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
2454 2455 2456 2457 2458 2459 2460 | return SQLITE_OK; } /****************************************************************************** ** The complete implementation of the BTree subsystem is above this line. ** All the code the follows is for testing and troubleshooting the BTree ** subsystem. None of the code that follows is used during normal operation. | < < < > | 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 | return SQLITE_OK; } /****************************************************************************** ** The complete implementation of the BTree subsystem is above this line. ** All the code the follows is for testing and troubleshooting the BTree ** subsystem. None of the code that follows is used during normal operation. ******************************************************************************/ /* ** Print a disassembly of the given page on standard output. This routine ** is used for debugging and testing only. */ #ifdef SQLITE_TEST int sqliteBtreePageDump(Btree *pBt, int pgno, int recursive){ int rc; MemPage *pPage; int i, j; int nFree; u16 idx; char range[20]; |
︙ | ︙ | |||
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 | idx = pCell->h.iNext; } sqliteBtreePageDump(pBt, pPage->u.hdr.rightChild, 1); } sqlitepager_unref(pPage); return SQLITE_OK; } /* ** Fill aResult[] with information about the entry and page that the ** cursor is pointing to. ** ** aResult[0] = The page number ** aResult[1] = The entry number ** aResult[2] = Total number of entries on this page | > > | 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 | idx = pCell->h.iNext; } sqliteBtreePageDump(pBt, pPage->u.hdr.rightChild, 1); } sqlitepager_unref(pPage); return SQLITE_OK; } #endif #ifdef SQLITE_TEST /* ** Fill aResult[] with information about the entry and page that the ** cursor is pointing to. ** ** aResult[0] = The page number ** aResult[1] = The entry number ** aResult[2] = Total number of entries on this page |
︙ | ︙ | |||
2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 | cnt++; idx = ((FreeBlk*)&pPage->u.aDisk[idx])->iNext; } aResult[5] = cnt; aResult[7] = pPage->u.hdr.rightChild; return SQLITE_OK; } /* ** Return the pager associated with a BTree. This routine is used for ** testing and debugging only. */ Pager *sqliteBtreePager(Btree *pBt){ return pBt->pPager; } /* ** This structure is passed around through all the sanity checking routines ** in order to keep track of some global state information. */ | > > > | | | | | | 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 | cnt++; idx = ((FreeBlk*)&pPage->u.aDisk[idx])->iNext; } aResult[5] = cnt; aResult[7] = pPage->u.hdr.rightChild; return SQLITE_OK; } #endif #ifdef SQLITE_TEST /* ** Return the pager associated with a BTree. This routine is used for ** testing and debugging only. */ Pager *sqliteBtreePager(Btree *pBt){ return pBt->pPager; } #endif /* ** This structure is passed around through all the sanity checking routines ** in order to keep track of some global state information. */ typedef struct IntegrityCk IntegrityCk; struct IntegrityCk { Btree *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ int nPage; /* Number of pages in the database */ int *anRef; /* Number of times each page is referenced */ int nTreePage; /* Number of BTree pages */ int nByte; /* Number of bytes of data stored on BTree pages */ char *zErrMsg; /* An error message. NULL of no errors seen. */ }; /* ** Append a message to the error message string. */ static void checkAppendMsg(IntegrityCk *pCheck, char *zMsg1, char *zMsg2){ if( pCheck->zErrMsg ){ char *zOld = pCheck->zErrMsg; pCheck->zErrMsg = 0; sqliteSetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, 0); sqliteFree(zOld); }else{ sqliteSetString(&pCheck->zErrMsg, zMsg1, zMsg2, 0); } } /* ** Add 1 to the reference count for page iPage. If this is the second ** reference to the page, add an error message to pCheck->zErrMsg. ** Return 1 if there are 2 ore more references to the page and 0 if ** if this is the first reference to the page. ** ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){ if( iPage==0 ) return 1; if( iPage>pCheck->nPage ){ char zBuf[100]; sprintf(zBuf, "invalid page number %d", iPage); checkAppendMsg(pCheck, zContext, zBuf); return 1; } if( pCheck->anRef[iPage]==1 ){ char zBuf[100]; sprintf(zBuf, "2nd reference to page %d", iPage); checkAppendMsg(pCheck, zContext, zBuf); return 1; } return (pCheck->anRef[iPage]++)>1; } /* ** Check the integrity of the freelist or of an overflow page list. ** Verify that the number of pages on the list is N. */ static void checkList(IntegrityCk *pCheck, int iPage, int N, char *zContext){ char zMsg[100]; while( N-- ){ OverflowPage *pOvfl; if( iPage<1 ){ sprintf(zMsg, "%d pages missing from overflow list", N+1); checkAppendMsg(pCheck, zContext, zMsg); break; |
︙ | ︙ | |||
2694 2695 2696 2697 2698 2699 2700 | ** 5. Check the integrity of overflow pages. ** 6. Recursively call checkTreePage on all children. ** 7. Verify that the depth of all children is the same. ** 8. Make sure this page is at least 33% full or else it is ** the root of the tree. */ static int checkTreePage( | | | 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 | ** 5. Check the integrity of overflow pages. ** 6. Recursively call checkTreePage on all children. ** 7. Verify that the depth of all children is the same. ** 8. Make sure this page is at least 33% full or else it is ** the root of the tree. */ static int checkTreePage( IntegrityCk *pCheck, /* Context for the sanity check */ int iPage, /* Page number of the page to check */ MemPage *pParent, /* Parent page */ char *zParentContext, /* Parent context */ char *zLowerBound, /* All keys should be greater than this, if not NULL */ int nLower, /* Number of characters in zLowerBound */ char *zUpperBound, /* All keys should be less than this, if not NULL */ int nUpper /* Number of characters in zUpperBound */ |
︙ | ︙ | |||
2839 2840 2841 2842 2843 2844 2845 | ** a table. nRoot is the number of entries in aRoot. ** ** If everything checks out, this routine returns NULL. If something is ** amiss, an error message is written into memory obtained from malloc() ** and a pointer to that error message is returned. The calling function ** is responsible for freeing the error message when it is done. */ | | | | 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 | ** a table. nRoot is the number of entries in aRoot. ** ** If everything checks out, this routine returns NULL. If something is ** amiss, an error message is written into memory obtained from malloc() ** and a pointer to that error message is returned. The calling function ** is responsible for freeing the error message when it is done. */ char *sqliteBtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){ int i; int nRef; IntegrityCk sCheck; nRef = *sqlitepager_stats(pBt->pPager); if( lockBtree(pBt)!=SQLITE_OK ){ return sqliteStrDup("Unable to acquire a read lock on the database"); } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; |
︙ | ︙ | |||
2893 2894 2895 2896 2897 2898 2899 | } /* Clean up and report errors. */ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } | < < | 2896 2897 2898 2899 2900 2901 2902 | } /* Clean up and report errors. */ sqliteFree(sCheck.anRef); return sCheck.zErrMsg; } |
Changes to src/btree.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** ** @(#) $Id: btree.h,v 1.23 2002/02/19 13:39:22 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ typedef struct Btree Btree; typedef struct BtCursor BtCursor; |
︙ | ︙ | |||
52 53 54 55 56 57 58 59 | int sqliteBtreeData(BtCursor*, int offset, int amt, char *zBuf); int sqliteBtreeCloseCursor(BtCursor*); #define SQLITE_N_BTREE_META 4 int sqliteBtreeGetMeta(Btree*, int*); int sqliteBtreeUpdateMeta(Btree*, int*); | > | < | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | int sqliteBtreeData(BtCursor*, int offset, int amt, char *zBuf); int sqliteBtreeCloseCursor(BtCursor*); #define SQLITE_N_BTREE_META 4 int sqliteBtreeGetMeta(Btree*, int*); int sqliteBtreeUpdateMeta(Btree*, int*); char *sqliteBtreeIntegrityCheck(Btree*, int*, int); #ifdef SQLITE_TEST int sqliteBtreePageDump(Btree*, int, int); int sqliteBtreeCursorDump(BtCursor*, int*); struct Pager *sqliteBtreePager(Btree*); #endif #endif /* _BTREE_H_ */ |
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.77 2002/02/19 13:39:22 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called after a single SQL statement has been ** parsed and we want to execute the VDBE code to implement |
︙ | ︙ | |||
1795 1796 1797 1798 1799 1800 1801 | sqliteParserTrace(stdout, "parser: "); }else{ sqliteParserTrace(0, 0); } }else #endif | < | | < | 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 | sqliteParserTrace(stdout, "parser: "); }else{ sqliteParserTrace(0, 0); } }else #endif if( sqliteStrICmp(zLeft, "integrity_check")==0 ){ static VdbeOp checkDb[] = { { OP_SetInsert, 0, 0, "2"}, { OP_Open, 0, 2, 0}, { OP_Rewind, 0, 6, 0}, { OP_Column, 0, 3, 0}, { OP_SetInsert, 0, 0, 0}, { OP_Next, 0, 3, 0}, { OP_IntegrityCk, 0, 0, 0}, { OP_ColumnCount, 1, 0, 0}, { OP_ColumnName, 0, 0, "sanity_check"}, { OP_Callback, 1, 0, 0}, }; Vdbe *v = sqliteGetVdbe(pParse); if( v==0 ) return; sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb); }else {} sqliteFree(zLeft); sqliteFree(zRight); } |
Changes to src/insert.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** ** $Id: insert.c,v 1.44 2002/02/19 13:39:22 drh Exp $ */ #include "sqliteInt.h" /* ** This routine is call to handle SQL of the following forms: ** ** insert into TABLE (IDLIST) values(EXPRLIST) |
︙ | ︙ | |||
364 365 366 367 368 369 370 | ** CHECK REPLACE Illegal. The results in an exception. ** ** Which action to take is determined by the overrideError parameter. ** Or if overrideError==OE_Default, then the pParse->onError parameter ** is used. Or if pParse->onError==OE_Default then the onError value ** for the constraint is used. ** | | | 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | ** CHECK REPLACE Illegal. The results in an exception. ** ** Which action to take is determined by the overrideError parameter. ** Or if overrideError==OE_Default, then the pParse->onError parameter ** is used. Or if pParse->onError==OE_Default then the onError value ** for the constraint is used. ** ** The calling routine must open a read/write cursor for pTab with ** cursor number "base". All indices of pTab must also have open ** read/write cursors with cursor number base+i for the i-th cursor. ** Except, if there is no possibility of a REPLACE action then ** cursors do not need to be open for indices where aIdxUsed[i]==0. ** ** If the isUpdate flag is true, it means that the "base" cursor is ** initially pointing to an entry that is being updated. The isUpdate |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.40 2002/02/19 13:39:22 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "os.h" #include <assert.h> #include <string.h> |
︙ | ︙ | |||
649 650 651 652 653 654 655 | /* ** Sync the journal and then write all free dirty pages to the database ** file. ** ** Writing all free dirty pages to the database after the sync is a ** non-obvious optimization. fsync() is an expensive operation so we | | | 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | /* ** Sync the journal and then write all free dirty pages to the database ** file. ** ** Writing all free dirty pages to the database after the sync is a ** non-obvious optimization. fsync() is an expensive operation so we ** want to minimize the number ot times it is called. After an fsync() call, ** we are free to write dirty pages back to the database. It is best ** to go ahead and write as many dirty pages as possible to minimize ** the risk of having to do another fsync() later on. Writing dirty ** free pages in this way was observed to make database operations go ** up to 10 times faster. ** ** If we are writing to temporary database, there is no need to preserve |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | } /* ** Set the checkpoint. ** ** This routine should be called with the transaction journal already ** open. A new checkpoint journal is created that can be used to rollback | | | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 | } /* ** Set the checkpoint. ** ** This routine should be called with the transaction journal already ** open. A new checkpoint journal is created that can be used to rollback ** changes of a single SQL command within a larger transaction. */ int sqlitepager_ckpt_begin(Pager *pPager){ int rc; char zTemp[SQLITE_TEMPNAME_SIZE]; assert( pPager->journalOpen ); assert( !pPager->ckptOpen ); pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 ); |
︙ | ︙ |
Changes to src/random.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** ** $Id: random.c,v 1.10 2002/02/19 13:39:23 drh Exp $ */ #include "sqliteInt.h" #include "os.h" /* ** Get a single 8-bit random value from the RC4 PRNG. The Mutex ** must be held while executing this routine. ** ** Why not just use a library random generator like lrand48() for this? ** Because the OP_NewRecno opcode in the VDBE depends on having a very ** good source of random numbers. The lrand48() library function may ** well be good enough. But maybe not. Or maybe lrand48() has some ** subtle problems on some systems that could cause problems. It is hard ** to know. To minimize the risk of problems due to bad lrand48() ** implementations, SQLite uses this random number generator based ** on RC4, which we know works very well. */ static int randomByte(){ int t; /* All threads share a single random number generator. ** This structure is the current state of the generator. |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.14 2002/02/19 13:39:23 drh Exp $ */ #include "sqliteInt.h" #include "pager.h" #include "btree.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
457 458 459 460 461 462 463 | } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; sqlitepager_refdump(sqliteBtreePager(pBt)); return TCL_OK; } /* | | | | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; sqlitepager_refdump(sqliteBtreePager(pBt)); return TCL_OK; } /* ** Usage: btree_integrity_check ID ROOT ... ** ** Look through every page of the given BTree file to verify correct ** formatting and linkage. Return a line of text for each problem found. ** Return an empty string if everything worked. */ static int btree_integrity_check( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ Btree *pBt; char *zResult; |
︙ | ︙ | |||
486 487 488 489 490 491 492 | } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; nRoot = argc-2; aRoot = malloc( sizeof(int)*(argc-2) ); for(i=0; i<argc-2; i++){ if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR; } | | | 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 | } if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR; nRoot = argc-2; aRoot = malloc( sizeof(int)*(argc-2) ); for(i=0; i<argc-2; i++){ if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR; } zResult = sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot); if( zResult ){ Tcl_AppendResult(interp, zResult, 0); free(zResult); } return TCL_OK; } |
︙ | ︙ | |||
829 830 831 832 833 834 835 | Tcl_CreateCommand(interp, "btree_move_to", btree_move_to, 0, 0); Tcl_CreateCommand(interp, "btree_delete", btree_delete, 0, 0); Tcl_CreateCommand(interp, "btree_insert", btree_insert, 0, 0); Tcl_CreateCommand(interp, "btree_next", btree_next, 0, 0); Tcl_CreateCommand(interp, "btree_key", btree_key, 0, 0); Tcl_CreateCommand(interp, "btree_data", btree_data, 0, 0); Tcl_CreateCommand(interp, "btree_cursor_dump", btree_cursor_dump, 0, 0); | | | 829 830 831 832 833 834 835 836 837 838 839 840 | Tcl_CreateCommand(interp, "btree_move_to", btree_move_to, 0, 0); Tcl_CreateCommand(interp, "btree_delete", btree_delete, 0, 0); Tcl_CreateCommand(interp, "btree_insert", btree_insert, 0, 0); Tcl_CreateCommand(interp, "btree_next", btree_next, 0, 0); Tcl_CreateCommand(interp, "btree_key", btree_key, 0, 0); Tcl_CreateCommand(interp, "btree_data", btree_data, 0, 0); Tcl_CreateCommand(interp, "btree_cursor_dump", btree_cursor_dump, 0, 0); Tcl_CreateCommand(interp, "btree_integrity_check", btree_integrity_check,0,0); Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager_refinfo_enable, TCL_LINK_INT); return TCL_OK; } |
Changes to src/vdbe.c.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** type to the other occurs as necessary. ** ** Most of the code in this file is taken up by the sqliteVdbeExec() ** function which does the work of interpreting a VDBE program. ** But other routines are also provided to help in building up ** a program instruction by instruction. ** ** $Id: vdbe.c,v 1.118 2002/02/19 13:39:23 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_MoveTo or the OP_Next opcode. The test |
︙ | ︙ | |||
864 865 866 867 868 869 870 | "ReadCookie", "SetCookie", "VerifyCookie", "Open", "OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux", "Close", "MoveTo", "NewRecno", "PutIntKey", "PutStrKey", "Distinct", "Found", "NotFound", "IsUnique", "NotExists", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", | | | 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 | "ReadCookie", "SetCookie", "VerifyCookie", "Open", "OpenTemp", "OpenWrite", "OpenAux", "OpenWrAux", "Close", "MoveTo", "NewRecno", "PutIntKey", "PutStrKey", "Distinct", "Found", "NotFound", "IsUnique", "NotExists", "Delete", "Column", "KeyAsData", "Recno", "FullKey", "Rewind", "Next", "Destroy", "Clear", "CreateIndex", "CreateTable", "IntegrityCk", "IdxPut", "IdxDelete", "IdxRecno", "IdxGT", "IdxGE", "MemLoad", "MemStore", "ListWrite", "ListRewind", "ListRead", "ListReset", "SortPut", "SortMakeRec", "SortMakeKey", "Sort", "SortNext", "SortCallback", "SortReset", "FileOpen", "FileRead", "FileColumn", "AggReset", "AggFocus", "AggIncr", "AggNext", "AggSet", "AggGet", "SetInsert", "SetFound", "SetNotFound", |
︙ | ︙ | |||
3477 3478 3479 3480 3481 3482 3483 | aStack[i].flags = STK_Int; *(u32*)pOp->p3 = pgno; pOp->p3 = 0; } break; } | | | < | | | < | 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 | aStack[i].flags = STK_Int; *(u32*)pOp->p3 = pgno; pOp->p3 = 0; } break; } /* Opcode: IntegrityCk P1 * * ** ** Do an analysis of the currently open database. Push onto the ** stack the text of an error message describing any problems. ** If there are no errors, push a "ok" onto the stack. ** ** P1 is the index of a set that contains the root page numbers ** for all tables and indices in this database. ** ** This opcode is used for testing purposes only. */ case OP_IntegrityCk: { int nRoot; int *aRoot; int tos = ++p->tos; int iSet = pOp->p1; Set *pSet; int j; HashElem *i; char *z; VERIFY( if( iSet<0 || iSet>=p->nSet ) goto bad_instruction; ) VERIFY( if( NeedStack(p, p->tos) ) goto no_mem; ) pSet = &p->aSet[iSet]; nRoot = sqliteHashCount(&pSet->hash); aRoot = sqliteMalloc( sizeof(int)*(nRoot+1) ); for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){ aRoot[j] = atoi((char*)sqliteHashKey(i)); } aRoot[j] = 0; z = sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot); if( z==0 || z[0]==0 ){ zStack[tos] = "ok"; aStack[tos].n = 3; aStack[tos].flags = STK_Str | STK_Static; if( z ) sqliteFree(z); }else{ zStack[tos] = z; aStack[tos].n = strlen(z) + 1; aStack[tos].flags = STK_Str | STK_Dyn; } sqliteFree(aRoot); break; } /* Opcode: Limit P1 P2 * ** ** Set a limit and offset on callbacks. P1 is the limit and P2 is ** the offset. If the offset counter is positive, no callbacks are |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** Header file for the Virtual DataBase Engine (VDBE) ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** ** $Id: vdbe.h,v 1.42 2002/02/19 13:39:23 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines |
︙ | ︙ | |||
100 101 102 103 104 105 106 | #define OP_Rewind 28 #define OP_Next 29 #define OP_Destroy 30 #define OP_Clear 31 #define OP_CreateIndex 32 #define OP_CreateTable 33 | | | 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #define OP_Rewind 28 #define OP_Next 29 #define OP_Destroy 30 #define OP_Clear 31 #define OP_CreateIndex 32 #define OP_CreateTable 33 #define OP_IntegrityCk 34 #define OP_IdxPut 35 #define OP_IdxDelete 36 #define OP_IdxRecno 37 #define OP_IdxGT 38 #define OP_IdxGE 39 |
︙ | ︙ |
Changes to test/btree.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # # $Id: btree.test,v 1.12 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info commands btree_open]!=""} { |
︙ | ︙ | |||
982 983 984 985 986 987 988 | btree_data $::c1 } $::data do_test btree-12.12 { btree_next $::c1 btree_key $::c1 } {402} do_test btree-13.1 { | | | 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 | btree_data $::c1 } $::data do_test btree-12.12 { btree_next $::c1 btree_key $::c1 } {402} do_test btree-13.1 { btree_integrity_check $::b1 2 3 } {} # To Do: # # 1. Do some deletes from the 3-layer tree # 2. Commit and reopen the database # 3. Read every 15th entry and make sure it works |
︙ | ︙ |
Changes to test/btree2.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # # $Id: btree2.test,v 1.10 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl if {[info commands btree_open]!=""} { |
︙ | ︙ | |||
49 50 51 52 53 54 55 | } {6} do_test btree2-1.5 { set ::c2 [btree_cursor $::b 2 1] btree_insert $::c2 {one} {1} btree_delete $::c2 btree_close_cursor $::c2 btree_commit $::b | | | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | } {6} do_test btree2-1.5 { set ::c2 [btree_cursor $::b 2 1] btree_insert $::c2 {one} {1} btree_delete $::c2 btree_close_cursor $::c2 btree_commit $::b btree_integrity_check $::b 2 3 4 5 6 } {} # This test module works by making lots of pseudo-random changes to a # database while simultaneously maintaining an invariant on that database. # Periodically, the script does a sanity check on the database and verifies # that the invariant is satisfied. # |
︙ | ︙ | |||
121 122 123 124 125 126 127 | return [string range $r 0 [expr {$len-1}]] } # Verify the invariants on the database. Return an empty string on # success or an error message if something is amiss. # proc check_invariants {} { | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | return [string range $r 0 [expr {$len-1}]] } # Verify the invariants on the database. Return an empty string on # success or an error message if something is amiss. # proc check_invariants {} { set ck [btree_integrity_check $::b 2 3 4 5 6] if {$ck!=""} { puts "\n*** SANITY:\n$ck" exit return $ck } btree_move_to $::c3 {} btree_move_to $::c4 {} |
︙ | ︙ | |||
255 256 257 258 259 260 261 | btree_delete $::c5 } if {$longdata} { btree_insert $::c6 $basekey $datalen } elseif {[btree_move_to $::c6 $basekey]==0} { btree_delete $::c6 } | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | btree_delete $::c5 } if {$longdata} { btree_insert $::c6 $basekey $datalen } elseif {[btree_move_to $::c6 $basekey]==0} { btree_delete $::c6 } # set ck [btree_integrity_check $::b 2 3 4 5 6] # if {$ck!=""} { # puts "\nSANITY CHECK FAILED!\n$ck" # exit # } # puts "PAGE 3:"; btree_page_dump $::b 3 # puts "PAGE 4:"; btree_page_dump $::b 4 } |
︙ | ︙ |
Changes to test/conflict.test.
︙ | ︙ | |||
9 10 11 12 13 14 15 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | # #*********************************************************************** # This file implements regression tests for SQLite library. # # This file implements tests for the conflict resolution extension # to SQLite. # # $Id: conflict.test,v 1.8 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create tables for the first group of tests. # do_test conflict-1.0 { |
︙ | ︙ | |||
374 375 376 377 378 379 380 | if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]} set r2 [execsql {SELECT x FROM t3}] list $r0 $r1 $r2 } [list $t0 $t1 $t2] } do_test insert-99.1 { | | | 374 375 376 377 378 379 380 381 382 383 384 385 386 | if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]} set r2 [execsql {SELECT x FROM t3}] list $r0 $r1 $r2 } [list $t0 $t1 $t2] } do_test insert-99.1 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} finish_test |
Changes to test/copy.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the COPY statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the COPY statement. # # $Id: copy.test,v 1.10 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create a file of data from which to copy. # set f [open data1.txt w] |
︙ | ︙ | |||
223 224 225 226 227 228 229 | do_test copy-5.7 { execsql { COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|'; } } {0} do_test copy-6.0 { | | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | do_test copy-5.7 { execsql { COPY OR IGNORE t1 FROM 'data5.txt' USING DELIMITERS '|'; } } {0} do_test copy-6.0 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} # Cleanup # file delete -force data1.txt data2.txt data3.txt data4.txt data5.txt data6.txt finish_test |
Changes to test/insert.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # # $Id: insert.test,v 1.9 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Try to insert into a non-existant table. # do_test insert-1.1 { |
︙ | ︙ | |||
153 154 155 156 157 158 159 | execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')} execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} } {111 -3.33 hi hum {}} do_test insert-3.4 { execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44} } {22 -4.44 hi abc-123 wham} do_test insert-3.5 { | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')} execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} } {111 -3.33 hi hum {}} do_test insert-3.4 { execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44} } {22 -4.44 hi abc-123 wham} do_test insert-3.5 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} do_test insert-4.1 { execsql { CREATE TABLE t3(a,b,c); |
︙ | ︙ |
Changes to test/insert2.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement that takes is # result from a SELECT. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement that takes is # result from a SELECT. # # $Id: insert2.test,v 1.7 2002/02/19 13:39:23 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Create some tables with data that we can select against # do_test insert2-1.0 { |
︙ | ︙ | |||
109 110 111 112 113 114 115 | DELETE FROM t3; INSERT INTO t3(c,a,b) SELECT x, 'hi', y FROM t4; SELECT * FROM t3; } } {hi 2 1} do_test insert2-4.0 { | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 | DELETE FROM t3; INSERT INTO t3(c,a,b) SELECT x, 'hi', y FROM t4; SELECT * FROM t3; } } {hi 2 1} do_test insert2-4.0 { set x [execsql {PRAGMA integrity_check}] if {$x==""} {set x ok} set x } {ok} finish_test |
Changes to www/changes.tcl.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2002 Feb 18 (2.3.3)} { <li>Allow identifiers to be quoted in square brackets, for compatibility with MS-Access.</li> <li>Added support for sub-queries in the FROM clause of a SELECT.</li> <li>More efficient implementation of sqliteFileExists() under Windows. (by Joel Luscy)</li> <li>The VALUES clause of an INSERT can now contain expressions, including scalar SELECT clauses.</li> <li>Added support for CREATE TABLE AS SELECT</li> <li>Bug fix: Creating and dropping a table all within a single transaction was not working.</li> } chng {2002 Feb 14 (2.3.2)} { <li>Bug fix: There was an incorrect assert() in pager.c. The real code was all correct (as far as is known) so everything should work OK if you | > > > > > | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | } proc chng {date desc} { puts "<DT><B>$date</B></DT>" puts "<DD><P><UL>$desc</UL></P></DD>" } chng {2002 Feb * (2.3.4)} { <li>Change the name of the sanity_check PRAGMA to <b>integrity_check</b> and make it available in all compiles.</li> } chng {2002 Feb 18 (2.3.3)} { <li>Allow identifiers to be quoted in square brackets, for compatibility with MS-Access.</li> <li>Added support for sub-queries in the FROM clause of a SELECT.</li> <li>More efficient implementation of sqliteFileExists() under Windows. (by Joel Luscy)</li> <li>The VALUES clause of an INSERT can now contain expressions, including scalar SELECT clauses.</li> <li>Added support for CREATE TABLE AS SELECT</li> <li>Bug fix: Creating and dropping a table all within a single transaction was not working.</li> } chng {2002 Feb 14 (2.3.2)} { <li>Bug fix: There was an incorrect assert() in pager.c. The real code was all correct (as far as is known) so everything should work OK if you compile with -DNDEBUG=1. When asserts are not disabled, there could be a fault.</li> } chng {2002 Feb 13 (2.3.1)} { <li>Bug fix: An assertion was failing if "PRAGMA full_column_names=ON;" was set and you did a query that used a rowid, like this: "SELECT rowid, * FROM ...".</li> |
︙ | ︙ |
Changes to www/lang.tcl.
1 2 3 | # # Run this Tcl script to generate the sqlite.html file. # | | | 1 2 3 4 5 6 7 8 9 10 11 | # # Run this Tcl script to generate the sqlite.html file. # set rcsid {$Id: lang.tcl,v 1.25 2002/02/19 13:39:23 drh Exp $} puts {<html> <head> <title>Query Language Understood By SQLite</title> </head> <body bgcolor=white> <h1 align=center> |
︙ | ︙ | |||
746 747 748 749 750 751 752 | <li><p><b>PRAGMA parser_trace = ON;<br>PRAGMA parser_trace = OFF;</b></p> <p>Turn tracing of the SQL parser inside of the SQLite library on and off. This is used for debugging. This only works if the library is compiled without the NDEBUG macro. </p></li> | | | < < | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | <li><p><b>PRAGMA parser_trace = ON;<br>PRAGMA parser_trace = OFF;</b></p> <p>Turn tracing of the SQL parser inside of the SQLite library on and off. This is used for debugging. This only works if the library is compiled without the NDEBUG macro. </p></li> <li><p><b>PRAGMA integrity_check;</b></p> <p>The command does an integrity check of the entire database. It looks for out-of-order records, missing pages, and malformed records. If any problems are found, then a single string is returned which is a description of all problems. If everything is in order, "ok" is returned.</p> <li><p><b>PRAGMA table_info(</b><i>table-name</i><b>);</b></p> <p>For each column in the named table, invoke the callback function once with information about that column, including the column name, data type, whether or not the column can be NULL, and the default value for the column.</p> |
︙ | ︙ |