Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Minor cleanup in checkindex.c. Add progress displays when checking a single index in the top-level TCL script for sqlite3_checker. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | checkindex |
Files: | files | file ages | folders |
SHA3-256: |
3ca31cc3ffe1cce4a9961d29801eebd4 |
User & Date: | drh 2017-11-01 13:09:02.677 |
Context
2017-11-01
| ||
18:05 | Move the test scripts for checkfreelist and checkindex over into the ext/repair/test directory. Run them now using the sqlite3_checker utility with the --test option. Some tests are currently failing due to an incomplete port. This is an incremental check-in. (check-in: 17f8d5e111 user: drh tags: checkindex) | |
13:09 | Minor cleanup in checkindex.c. Add progress displays when checking a single index in the top-level TCL script for sqlite3_checker. (check-in: 3ca31cc3ff user: drh tags: checkindex) | |
01:05 | When sqlite3_checker finds a problem, show the row key as part of the error message, not the row index number. (check-in: 6ffe917d10 user: drh tags: checkindex) | |
Changes
Changes to ext/repair/checkindex.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 48 49 50 51 | struct CidxTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; }; struct CidxCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ sqlite3_stmt *pStmt; }; typedef struct CidxColumn CidxColumn; struct CidxColumn { char *zExpr; /* Text for indexed expression */ int bDesc; /* True for DESC columns, otherwise false */ | > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | struct CidxTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; }; struct CidxCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ sqlite3_int64 iRowid; sqlite3_stmt *pStmt; }; typedef struct CidxColumn CidxColumn; struct CidxColumn { char *zExpr; /* Text for indexed expression */ int bDesc; /* True for DESC columns, otherwise false */ |
︙ | ︙ | |||
89 90 91 92 93 94 95 96 97 98 99 100 101 102 | int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int rc = SQLITE_OK; CidxTable *pRet; rc = sqlite3_declare_vtab(db, "CREATE TABLE xyz(" " errmsg TEXT, current_key TEXT," " index_name HIDDEN, after_key HIDDEN" ")" ); pRet = cidxMalloc(&rc, sizeof(CidxTable)); | > > > > | 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | int argc, const char *const*argv, sqlite3_vtab **ppVtab, char **pzErr ){ int rc = SQLITE_OK; CidxTable *pRet; #define IIC_ERRMSG 0 #define IIC_CURRENT_KEY 1 #define IIC_INDEX_NAME 2 #define IIC_AFTER_KEY 3 rc = sqlite3_declare_vtab(db, "CREATE TABLE xyz(" " errmsg TEXT, current_key TEXT," " index_name HIDDEN, after_key HIDDEN" ")" ); pRet = cidxMalloc(&rc, sizeof(CidxTable)); |
︙ | ︙ | |||
126 127 128 129 130 131 132 | int i; for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; | | | | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | int i; for(i=0; i<pInfo->nConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( p->iColumn==IIC_INDEX_NAME ){ iIdxName = i; } if( p->iColumn==IIC_AFTER_KEY ){ iAfterKey = i; } } if( iIdxName<0 ){ pInfo->estimatedCost = 1000000000.0; }else{ |
︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 200 201 202 | rc = sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; if( rc!=SQLITE_OK ){ sqlite3 *db = ((CidxTable*)pCsr->base.pVtab)->db; cidxCursorError(pCsr, "Cursor error: %s", sqlite3_errmsg(db)); } }else{ rc = SQLITE_OK; } return rc; } /* We have reached EOF if previous sqlite3_step() returned ** anything other than SQLITE_ROW; | > | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | rc = sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; if( rc!=SQLITE_OK ){ sqlite3 *db = ((CidxTable*)pCsr->base.pVtab)->db; cidxCursorError(pCsr, "Cursor error: %s", sqlite3_errmsg(db)); } }else{ pCsr->iRowid++; rc = SQLITE_OK; } return rc; } /* We have reached EOF if previous sqlite3_step() returned ** anything other than SQLITE_ROW; |
︙ | ︙ | |||
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | sqlite3_free(azAfter); } if( pCsr->pStmt ){ assert( rc==SQLITE_OK ); rc = cidxNext(pCursor); } return rc; } /* ** Return a column value. */ static int cidxColumn( sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int iCol ){ CidxCursor *pCsr = (CidxCursor*)pCursor; | > | | | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | sqlite3_free(azAfter); } if( pCsr->pStmt ){ assert( rc==SQLITE_OK ); rc = cidxNext(pCursor); } pCsr->iRowid = 1; return rc; } /* ** Return a column value. */ static int cidxColumn( sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, int iCol ){ CidxCursor *pCsr = (CidxCursor*)pCursor; assert( iCol>=IIC_ERRMSG && iCol<=IIC_AFTER_KEY ); if( iCol==IIC_ERRMSG ){ const char *zVal = 0; if( sqlite3_column_type(pCsr->pStmt, 0)==SQLITE_INTEGER ){ if( sqlite3_column_int(pCsr->pStmt, 0)==0 ){ zVal = "row data mismatch"; } }else{ zVal = "row missing"; } sqlite3_result_text(ctx, zVal, -1, SQLITE_STATIC); }else if( iCol==IIC_CURRENT_KEY ){ sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, 1)); } return SQLITE_OK; } /* Return the ROWID for the sqlite_btreeinfo table */ static int cidxRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ |
︙ | ︙ |
Changes to ext/repair/sqlite3_checker.tcl.
︙ | ︙ | |||
44 45 46 47 48 49 50 | # Do an incremental integrity check of a single index # proc check_index {idxname batchsize} { set i 0 set more 1 set nerr 0 | > > > | > < < < | > > > > > | < < < < > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | # Do an incremental integrity check of a single index # proc check_index {idxname batchsize} { set i 0 set more 1 set nerr 0 set pct 00.0 set max [db one {SELECT nEntry FROM sqlite_btreeinfo('main') WHERE name=$idxname}] puts -nonewline "$idxname: $i of $max rows ($pct%)\r" flush stdout while {$more} { set more 0 db eval {SELECT errmsg, current_key AS key FROM incremental_index_check($idxname) WHERE after_key=$key LIMIT $batchsize} { set more 1 if {$errmsg!=""} { incr nerr puts "$idxname: key($key): $errmsg" } incr i } set x [format {%.1f} [expr {($i*100.0)/$max}]] if {$x!=$pct} { puts -nonewline "$idxname: $i of $max rows ($pct%)\r" flush stdout set pct $x } } puts "$idxname: $nerr errors out of $i entries" } # Print a usage message on standard error, then quit. # proc usage {} { set argv0 [file rootname [file tail [info nameofexecutable]]] puts stderr "Usage: $argv0 OPTIONS database-filename" |
︙ | ︙ | |||
103 104 105 106 107 108 109 | set file_to_analyze {} append argv {} set bFreelistCheck 0 set bSummary 0 set zIndex {} set zTable {} | | | 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | set file_to_analyze {} append argv {} set bFreelistCheck 0 set bSummary 0 set zIndex {} set zTable {} set batchsize 1000 set bAll 1 set argc [llength $argv] for {set i 0} {$i<$argc} {incr i} { set arg [lindex $argv $i] if {[regexp {^-+tclsh$} $arg]} { tclsh exit 0 |
︙ | ︙ |