From: drh <> Date: Mon, 2 Mar 2026 13:44:04 +0000 (+0000) Subject: Remove the experimental and incomplete ext/repair extension, to prevent AIs X-Git-Tag: version-3.52.0~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c1454ee8331088c922f1ded8ffa2374842f5dd21;p=thirdparty%2Fsqlite.git Remove the experimental and incomplete ext/repair extension, to prevent AIs from scanning the (incomplete) code and reporting bugs against it. FossilOrigin-Name: 213b1c6608af4b3e9d6e0d8de6432cc6857931427baf4beac1e0a4294e4dc6ce --- diff --git a/Makefile.msc b/Makefile.msc index 561d5f58e0..763616ce93 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2660,23 +2660,6 @@ sqltclsh.exe: sqltclsh.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(LTLINK) $(NO_WARN) $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS) -CHECKER_DEPS =\ - $(TOP)\tool\mkccode.tcl \ - sqlite3.c \ - tclsqlite-ex.c \ - $(TOP)\ext\repair\sqlite3_checker.tcl \ - $(TOP)\ext\repair\checkindex.c \ - $(TOP)\ext\repair\checkfreelist.c \ - $(TOP)\ext\misc\btreeinfo.c \ - $(TOP)\ext\repair\sqlite3_checker.c.in - -sqlite3_checker.c: $(CHECKER_DEPS) - $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@ - -sqlite3_checker.exe: sqlite3_checker.c $(LIBRESOBJS) - $(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \ - /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS) - dbdump.exe: $(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) $(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \ /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) diff --git a/ext/repair/README.md b/ext/repair/README.md deleted file mode 100644 index 927ceb7c44..0000000000 --- a/ext/repair/README.md +++ /dev/null @@ -1,16 +0,0 @@ -This folder contains extensions and utility programs intended to analyze -live database files, detect problems, and possibly fix them. - -As SQLite is being used on larger and larger databases, database sizes -are growing into the terabyte range. At that size, hardware malfunctions -and/or cosmic rays will occasionally corrupt a database file. Detecting -problems and fixing errors a terabyte-sized databases can take hours or days, -and it is undesirable to take applications that depend on the databases -off-line for such a long time. -The utilities in the folder are intended to provide mechanisms for -detecting and fixing problems in large databases while those databases -are in active use. - -The utilities and extensions in this folder are experimental and under -active development at the time of this writing (2017-10-12). If and when -they stabilize, this README will be updated to reflect that fact. diff --git a/ext/repair/checkfreelist.c b/ext/repair/checkfreelist.c deleted file mode 100644 index d1d3d54074..0000000000 --- a/ext/repair/checkfreelist.c +++ /dev/null @@ -1,310 +0,0 @@ -/* -** 2017 October 11 -** -** 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 module exports a single C function: -** -** int sqlite3_check_freelist(sqlite3 *db, const char *zDb); -** -** This function checks the free-list in database zDb (one of "main", -** "temp", etc.) and reports any errors by invoking the sqlite3_log() -** function. It returns SQLITE_OK if successful, or an SQLite error -** code otherwise. It is not an error if the free-list is corrupted but -** no IO or OOM errors occur. -** -** If this file is compiled and loaded as an SQLite loadable extension, -** it adds an SQL function "checkfreelist" to the database handle, to -** be invoked as follows: -** -** SELECT checkfreelist(); -** -** This function performs the same checks as sqlite3_check_freelist(), -** except that it returns all error messages as a single text value, -** separated by newline characters. If the freelist is not corrupted -** in any way, an empty string is returned. -** -** To compile this module for use as an SQLite loadable extension: -** -** gcc -Os -fPIC -shared checkfreelist.c -o checkfreelist.so -*/ - -#include "sqlite3ext.h" -SQLITE_EXTENSION_INIT1 - -#ifndef SQLITE_AMALGAMATION -# include -# include -# include -# include -# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) -# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 -# endif -# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) -# define ALWAYS(X) (1) -# define NEVER(X) (0) -# elif !defined(NDEBUG) -# define ALWAYS(X) ((X)?1:(assert(0),0)) -# define NEVER(X) ((X)?(assert(0),1):0) -# else -# define ALWAYS(X) (X) -# define NEVER(X) (X) -# endif - typedef unsigned char u8; - typedef unsigned short u16; - typedef unsigned int u32; -#define get4byte(x) ( \ - ((u32)((x)[0])<<24) + \ - ((u32)((x)[1])<<16) + \ - ((u32)((x)[2])<<8) + \ - ((u32)((x)[3])) \ -) -#endif - -/* -** Execute a single PRAGMA statement and return the integer value returned -** via output parameter (*pnOut). -** -** The SQL statement passed as the third argument should be a printf-style -** format string containing a single "%s" which will be replace by the -** value passed as the second argument. e.g. -** -** sqlGetInteger(db, "main", "PRAGMA %s.page_count", pnOut) -** -** executes "PRAGMA main.page_count" and stores the results in (*pnOut). -*/ -static int sqlGetInteger( - sqlite3 *db, /* Database handle */ - const char *zDb, /* Database name ("main", "temp" etc.) */ - const char *zFmt, /* SQL statement format */ - u32 *pnOut /* OUT: Integer value */ -){ - int rc, rc2; - char *zSql; - sqlite3_stmt *pStmt = 0; - int bOk = 0; - - zSql = sqlite3_mprintf(zFmt, zDb); - if( zSql==0 ){ - rc = SQLITE_NOMEM; - }else{ - rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - sqlite3_free(zSql); - } - - if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - *pnOut = (u32)sqlite3_column_int(pStmt, 0); - bOk = 1; - } - - rc2 = sqlite3_finalize(pStmt); - if( rc==SQLITE_OK ) rc = rc2; - if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_ERROR; - return rc; -} - -/* -** Argument zFmt must be a printf-style format string and must be -** followed by its required arguments. If argument pzOut is NULL, -** then the results of printf()ing the format string are passed to -** sqlite3_log(). Otherwise, they are appended to the string -** at (*pzOut). -*/ -static int checkFreelistError(char **pzOut, const char *zFmt, ...){ - int rc = SQLITE_OK; - char *zErr = 0; - va_list ap; - - va_start(ap, zFmt); - zErr = sqlite3_vmprintf(zFmt, ap); - if( zErr==0 ){ - rc = SQLITE_NOMEM; - }else{ - if( pzOut ){ - *pzOut = sqlite3_mprintf("%s%z%s", *pzOut?"\n":"", *pzOut, zErr); - if( *pzOut==0 ) rc = SQLITE_NOMEM; - }else{ - sqlite3_log(SQLITE_ERROR, "checkfreelist: %s", zErr); - } - sqlite3_free(zErr); - } - va_end(ap); - return rc; -} - -static int checkFreelist( - sqlite3 *db, - const char *zDb, - char **pzOut -){ - /* This query returns one row for each page on the free list. Each row has - ** two columns - the page number and page content. */ - const char *zTrunk = - "WITH freelist_trunk(i, d, n) AS (" - "SELECT 1, NULL, sqlite_readint32(data, 32) " - "FROM sqlite_dbpage(:1) WHERE pgno=1 " - "UNION ALL " - "SELECT n, data, sqlite_readint32(data) " - "FROM freelist_trunk, sqlite_dbpage(:1) WHERE pgno=n " - ")" - "SELECT i, d FROM freelist_trunk WHERE i!=1;"; - - int rc, rc2; /* Return code */ - sqlite3_stmt *pTrunk = 0; /* Compilation of zTrunk */ - u32 nPage = 0; /* Number of pages in db */ - u32 nExpected = 0; /* Expected number of free pages */ - u32 nFree = 0; /* Number of pages on free list */ - - if( zDb==0 ) zDb = "main"; - - if( (rc = sqlGetInteger(db, zDb, "PRAGMA %s.page_count", &nPage)) - || (rc = sqlGetInteger(db, zDb, "PRAGMA %s.freelist_count", &nExpected)) - ){ - return rc; - } - - rc = sqlite3_prepare_v2(db, zTrunk, -1, &pTrunk, 0); - if( rc!=SQLITE_OK ) return rc; - sqlite3_bind_text(pTrunk, 1, zDb, -1, SQLITE_STATIC); - while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){ - u32 i; - u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0); - const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1); - u32 nData = (u32)sqlite3_column_bytes(pTrunk, 1); - u32 iNext = get4byte(&aData[0]); - u32 nLeaf = get4byte(&aData[4]); - - if( nLeaf>((nData/4)-2-6) ){ - rc = checkFreelistError(pzOut, - "leaf count out of range (%d) on trunk page %d", - (int)nLeaf, (int)iTrunk - ); - nLeaf = (nData/4) - 2 - 6; - } - - nFree += 1+nLeaf; - if( iNext>nPage ){ - rc = checkFreelistError(pzOut, - "trunk page %d is out of range", (int)iNext - ); - } - - for(i=0; rc==SQLITE_OK && inPage ){ - rc = checkFreelistError(pzOut, - "leaf page %d is out of range (child %d of trunk page %d)", - (int)iLeaf, (int)i, (int)iTrunk - ); - } - } - } - - if( rc==SQLITE_OK && nFree!=nExpected ){ - rc = checkFreelistError(pzOut, - "free-list count mismatch: actual=%d header=%d", - (int)nFree, (int)nExpected - ); - } - - rc2 = sqlite3_finalize(pTrunk); - if( rc==SQLITE_OK ) rc = rc2; - return rc; -} - -int sqlite3_check_freelist(sqlite3 *db, const char *zDb){ - return checkFreelist(db, zDb, 0); -} - -static void checkfreelist_function( - sqlite3_context *pCtx, - int nArg, - sqlite3_value **apArg -){ - const char *zDb; - int rc; - char *zOut = 0; - sqlite3 *db = sqlite3_context_db_handle(pCtx); - - assert( nArg==1 ); - zDb = (const char*)sqlite3_value_text(apArg[0]); - rc = checkFreelist(db, zDb, &zOut); - if( rc==SQLITE_OK ){ - sqlite3_result_text(pCtx, zOut?zOut:"ok", -1, SQLITE_TRANSIENT); - }else{ - sqlite3_result_error_code(pCtx, rc); - } - - sqlite3_free(zOut); -} - -/* -** An SQL function invoked as follows: -** -** sqlite_readint32(BLOB) -- Decode 32-bit integer from start of blob -*/ -static void readint_function( - sqlite3_context *pCtx, - int nArg, - sqlite3_value **apArg -){ - const u8 *zBlob; - int nBlob; - int iOff = 0; - u32 iRet = 0; - - if( nArg!=1 && nArg!=2 ){ - sqlite3_result_error( - pCtx, "wrong number of arguments to function sqlite_readint32()", -1 - ); - return; - } - if( nArg==2 ){ - iOff = sqlite3_value_int(apArg[1]); - } - - zBlob = sqlite3_value_blob(apArg[0]); - nBlob = sqlite3_value_bytes(apArg[0]); - - if( nBlob>=(iOff+4) ){ - iRet = get4byte(&zBlob[iOff]); - } - - sqlite3_result_int64(pCtx, (sqlite3_int64)iRet); -} - -/* -** Register the SQL functions. -*/ -static int cflRegister(sqlite3 *db){ - int rc = sqlite3_create_function( - db, "sqlite_readint32", -1, SQLITE_UTF8, 0, readint_function, 0, 0 - ); - if( rc!=SQLITE_OK ) return rc; - rc = sqlite3_create_function( - db, "checkfreelist", 1, SQLITE_UTF8, 0, checkfreelist_function, 0, 0 - ); - return rc; -} - -/* -** Extension load function. -*/ -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_checkfreelist_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - SQLITE_EXTENSION_INIT2(pApi); - return cflRegister(db); -} diff --git a/ext/repair/checkindex.c b/ext/repair/checkindex.c deleted file mode 100644 index ed30357e5d..0000000000 --- a/ext/repair/checkindex.c +++ /dev/null @@ -1,929 +0,0 @@ -/* -** 2017 October 27 -** -** 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. -** -************************************************************************* -*/ - -#include "sqlite3ext.h" -SQLITE_EXTENSION_INIT1 - -/* -** Stuff that is available inside the amalgamation, but which we need to -** declare ourselves if this module is compiled separately. -*/ -#ifndef SQLITE_AMALGAMATION -# include -# include -# include -# include -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -#define get4byte(x) ( \ - ((u32)((x)[0])<<24) + \ - ((u32)((x)[1])<<16) + \ - ((u32)((x)[2])<<8) + \ - ((u32)((x)[3])) \ -) -#endif - -typedef struct CidxTable CidxTable; -typedef struct CidxCursor CidxCursor; - -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; /* Row number of the output */ - char *zIdxName; /* Copy of the index_name parameter */ - char *zAfterKey; /* Copy of the after_key parameter */ - sqlite3_stmt *pStmt; /* SQL statement that generates the output */ -}; - -typedef struct CidxColumn CidxColumn; -struct CidxColumn { - char *zExpr; /* Text for indexed expression */ - int bDesc; /* True for DESC columns, otherwise false */ - int bKey; /* Part of index, not PK */ -}; - -typedef struct CidxIndex CidxIndex; -struct CidxIndex { - char *zWhere; /* WHERE clause, if any */ - int nCol; /* Elements in aCol[] array */ - CidxColumn aCol[1]; /* Array of indexed columns */ -}; - -static void *cidxMalloc(int *pRc, int n){ - void *pRet = 0; - assert( n!=0 ); - if( *pRc==SQLITE_OK ){ - pRet = sqlite3_malloc(n); - if( pRet ){ - memset(pRet, 0, n); - }else{ - *pRc = SQLITE_NOMEM; - } - } - return pRet; -} - -static void cidxCursorError(CidxCursor *pCsr, const char *zFmt, ...){ - va_list ap; - va_start(ap, zFmt); - assert( pCsr->base.pVtab->zErrMsg==0 ); - pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap); - va_end(ap); -} - -/* -** Connect to the incremental_index_check virtual table. -*/ -static int cidxConnect( - sqlite3 *db, - void *pAux, - 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 -#define IIC_SCANNER_SQL 4 - rc = sqlite3_declare_vtab(db, - "CREATE TABLE xyz(" - " errmsg TEXT," /* Error message or NULL if everything is ok */ - " current_key TEXT," /* SQLite quote() text of key values */ - " index_name HIDDEN," /* IN: name of the index being scanned */ - " after_key HIDDEN," /* IN: Start scanning after this key */ - " scanner_sql HIDDEN" /* debugging info: SQL used for scanner */ - ")" - ); - pRet = cidxMalloc(&rc, sizeof(CidxTable)); - if( pRet ){ - pRet->db = db; - } - - *ppVtab = (sqlite3_vtab*)pRet; - return rc; -} - -/* -** Disconnect from or destroy an incremental_index_check virtual table. -*/ -static int cidxDisconnect(sqlite3_vtab *pVtab){ - CidxTable *pTab = (CidxTable*)pVtab; - sqlite3_free(pTab); - return SQLITE_OK; -} - -/* -** idxNum and idxStr are not used. There are only three possible plans, -** which are all distinguished by the number of parameters. -** -** No parameters: A degenerate plan. The result is zero rows. -** 1 Parameter: Scan all of the index starting with first entry -** 2 parameters: Scan the index starting after the "after_key". -** -** Provide successively smaller costs for each of these plans to encourage -** the query planner to select the one with the most parameters. -*/ -static int cidxBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pInfo){ - int iIdxName = -1; - int iAfterKey = -1; - int i; - - for(i=0; inConstraint; 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{ - pInfo->aConstraintUsage[iIdxName].argvIndex = 1; - pInfo->aConstraintUsage[iIdxName].omit = 1; - if( iAfterKey<0 ){ - pInfo->estimatedCost = 1000000.0; - }else{ - pInfo->aConstraintUsage[iAfterKey].argvIndex = 2; - pInfo->aConstraintUsage[iAfterKey].omit = 1; - pInfo->estimatedCost = 1000.0; - } - } - - return SQLITE_OK; -} - -/* -** Open a new btreeinfo cursor. -*/ -static int cidxOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ - CidxCursor *pRet; - int rc = SQLITE_OK; - - pRet = cidxMalloc(&rc, sizeof(CidxCursor)); - - *ppCursor = (sqlite3_vtab_cursor*)pRet; - return rc; -} - -/* -** Close a btreeinfo cursor. -*/ -static int cidxClose(sqlite3_vtab_cursor *pCursor){ - CidxCursor *pCsr = (CidxCursor*)pCursor; - sqlite3_finalize(pCsr->pStmt); - sqlite3_free(pCsr->zIdxName); - sqlite3_free(pCsr->zAfterKey); - sqlite3_free(pCsr); - return SQLITE_OK; -} - -/* -** Move a btreeinfo cursor to the next entry in the file. -*/ -static int cidxNext(sqlite3_vtab_cursor *pCursor){ - CidxCursor *pCsr = (CidxCursor*)pCursor; - int rc = sqlite3_step(pCsr->pStmt); - if( rc!=SQLITE_ROW ){ - 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; -*/ -static int cidxEof(sqlite3_vtab_cursor *pCursor){ - CidxCursor *pCsr = (CidxCursor*)pCursor; - return pCsr->pStmt==0; -} - -static char *cidxMprintf(int *pRc, const char *zFmt, ...){ - char *zRet = 0; - va_list ap; - va_start(ap, zFmt); - zRet = sqlite3_vmprintf(zFmt, ap); - if( *pRc==SQLITE_OK ){ - if( zRet==0 ){ - *pRc = SQLITE_NOMEM; - } - }else{ - sqlite3_free(zRet); - zRet = 0; - } - va_end(ap); - return zRet; -} - -static sqlite3_stmt *cidxPrepare( - int *pRc, CidxCursor *pCsr, const char *zFmt, ... -){ - sqlite3_stmt *pRet = 0; - char *zSql; - va_list ap; /* ... printf arguments */ - va_start(ap, zFmt); - - zSql = sqlite3_vmprintf(zFmt, ap); - if( *pRc==SQLITE_OK ){ - if( zSql==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sqlite3 *db = ((CidxTable*)pCsr->base.pVtab)->db; - *pRc = sqlite3_prepare_v2(db, zSql, -1, &pRet, 0); - if( *pRc!=SQLITE_OK ){ - cidxCursorError(pCsr, "SQL error: %s", sqlite3_errmsg(db)); - } - } - } - sqlite3_free(zSql); - va_end(ap); - - return pRet; -} - -static void cidxFinalize(int *pRc, sqlite3_stmt *pStmt){ - int rc = sqlite3_finalize(pStmt); - if( *pRc==SQLITE_OK ) *pRc = rc; -} - -char *cidxStrdup(int *pRc, const char *zStr){ - char *zRet = 0; - if( *pRc==SQLITE_OK ){ - int n = (int)strlen(zStr); - zRet = cidxMalloc(pRc, n+1); - if( zRet ) memcpy(zRet, zStr, n+1); - } - return zRet; -} - -static void cidxFreeIndex(CidxIndex *pIdx){ - if( pIdx ){ - int i; - for(i=0; inCol; i++){ - sqlite3_free(pIdx->aCol[i].zExpr); - } - sqlite3_free(pIdx->zWhere); - sqlite3_free(pIdx); - } -} - -static int cidx_isspace(char c){ - return c==' ' || c=='\t' || c=='\r' || c=='\n'; -} - -static int cidx_isident(char c){ - return c<0 - || (c>='0' && c<='9') || (c>='a' && c<='z') - || (c>='A' && c<='Z') || c=='_'; -} - -#define CIDX_PARSE_EOF 0 -#define CIDX_PARSE_COMMA 1 /* "," */ -#define CIDX_PARSE_OPEN 2 /* "(" */ -#define CIDX_PARSE_CLOSE 3 /* ")" */ - -/* -** Argument zIn points into the start, middle or end of a CREATE INDEX -** statement. If argument pbDoNotTrim is non-NULL, then this function -** scans the input until it finds EOF, a comma (",") or an open or -** close parenthesis character. It then sets (*pzOut) to point to said -** character and returns a CIDX_PARSE_XXX constant as appropriate. The -** parser is smart enough that special characters inside SQL strings -** or comments are not returned for. -** -** Or, if argument pbDoNotTrim is NULL, then this function sets *pzOut -** to point to the first character of the string that is not whitespace -** or part of an SQL comment and returns CIDX_PARSE_EOF. -** -** Additionally, if pbDoNotTrim is not NULL and the element immediately -** before (*pzOut) is an SQL comment of the form "-- comment", then -** (*pbDoNotTrim) is set before returning. In all other cases it is -** cleared. -*/ -static int cidxFindNext( - const char *zIn, - const char **pzOut, - int *pbDoNotTrim /* OUT: True if prev is -- comment */ -){ - const char *z = zIn; - - while( 1 ){ - while( cidx_isspace(*z) ) z++; - if( z[0]=='-' && z[1]=='-' ){ - z += 2; - while( z[0]!='\n' ){ - if( z[0]=='\0' ) return CIDX_PARSE_EOF; - z++; - } - while( cidx_isspace(*z) ) z++; - if( pbDoNotTrim ) *pbDoNotTrim = 1; - }else - if( z[0]=='/' && z[1]=='*' ){ - z += 2; - while( z[0]!='*' || z[1]!='/' ){ - if( z[1]=='\0' ) return CIDX_PARSE_EOF; - z++; - } - z += 2; - }else{ - *pzOut = z; - if( pbDoNotTrim==0 ) return CIDX_PARSE_EOF; - switch( *z ){ - case '\0': - return CIDX_PARSE_EOF; - case '(': - return CIDX_PARSE_OPEN; - case ')': - return CIDX_PARSE_CLOSE; - case ',': - return CIDX_PARSE_COMMA; - - case '"': - case '\'': - case '`': { - char q = *z; - z++; - while( *z ){ - if( *z==q ){ - z++; - if( *z!=q ) break; - } - z++; - } - break; - } - - case '[': - while( *z++!=']' ); - break; - - default: - z++; - break; - } - *pbDoNotTrim = 0; - } - } - - assert( 0 ); - return -1; -} - -static int cidxParseSQL(CidxCursor *pCsr, CidxIndex *pIdx, const char *zSql){ - const char *z = zSql; - const char *z1; - int e; - int rc = SQLITE_OK; - int nParen = 1; - int bDoNotTrim = 0; - CidxColumn *pCol = pIdx->aCol; - - e = cidxFindNext(z, &z, &bDoNotTrim); - if( e!=CIDX_PARSE_OPEN ) goto parse_error; - z1 = z+1; - z++; - while( nParen>0 ){ - e = cidxFindNext(z, &z, &bDoNotTrim); - if( e==CIDX_PARSE_EOF ) goto parse_error; - if( (e==CIDX_PARSE_COMMA || e==CIDX_PARSE_CLOSE) && nParen==1 ){ - const char *z2 = z; - if( pCol->zExpr ) goto parse_error; - - if( bDoNotTrim==0 ){ - while( cidx_isspace(z[-1]) ) z--; - if( !sqlite3_strnicmp(&z[-3], "asc", 3) && 0==cidx_isident(z[-4]) ){ - z -= 3; - while( cidx_isspace(z[-1]) ) z--; - }else - if( !sqlite3_strnicmp(&z[-4], "desc", 4) && 0==cidx_isident(z[-5]) ){ - z -= 4; - while( cidx_isspace(z[-1]) ) z--; - } - while( cidx_isspace(z1[0]) ) z1++; - } - - pCol->zExpr = cidxMprintf(&rc, "%.*s", z-z1, z1); - pCol++; - z = z1 = z2+1; - } - if( e==CIDX_PARSE_OPEN ) nParen++; - if( e==CIDX_PARSE_CLOSE ) nParen--; - z++; - } - - /* Search for a WHERE clause */ - cidxFindNext(z, &z, 0); - if( 0==sqlite3_strnicmp(z, "where", 5) ){ - pIdx->zWhere = cidxMprintf(&rc, "%s\n", &z[5]); - }else if( z[0]!='\0' ){ - goto parse_error; - } - - return rc; - - parse_error: - cidxCursorError(pCsr, "Parse error in: %s", zSql); - return SQLITE_ERROR; -} - -static int cidxLookupIndex( - CidxCursor *pCsr, /* Cursor object */ - const char *zIdx, /* Name of index to look up */ - CidxIndex **ppIdx, /* OUT: Description of columns */ - char **pzTab /* OUT: Table name */ -){ - int rc = SQLITE_OK; - char *zTab = 0; - CidxIndex *pIdx = 0; - - sqlite3_stmt *pFindTab = 0; - sqlite3_stmt *pInfo = 0; - - /* Find the table for this index. */ - pFindTab = cidxPrepare(&rc, pCsr, - "SELECT tbl_name, sql FROM sqlite_schema WHERE name=%Q AND type='index'", - zIdx - ); - if( rc==SQLITE_OK && sqlite3_step(pFindTab)==SQLITE_ROW ){ - const char *zSql = (const char*)sqlite3_column_text(pFindTab, 1); - zTab = cidxStrdup(&rc, (const char*)sqlite3_column_text(pFindTab, 0)); - - pInfo = cidxPrepare(&rc, pCsr, "PRAGMA index_xinfo(%Q)", zIdx); - if( rc==SQLITE_OK ){ - int nAlloc = 0; - int iCol = 0; - - while( sqlite3_step(pInfo)==SQLITE_ROW ){ - const char *zName = (const char*)sqlite3_column_text(pInfo, 2); - const char *zColl = (const char*)sqlite3_column_text(pInfo, 4); - CidxColumn *p; - if( zName==0 ) zName = "rowid"; - if( iCol==nAlloc ){ - int nByte = sizeof(CidxIndex) + sizeof(CidxColumn)*(nAlloc+8); - pIdx = (CidxIndex*)sqlite3_realloc(pIdx, nByte); - nAlloc += 8; - } - p = &pIdx->aCol[iCol++]; - p->bDesc = sqlite3_column_int(pInfo, 3); - p->bKey = sqlite3_column_int(pInfo, 5); - if( zSql==0 || p->bKey==0 ){ - p->zExpr = cidxMprintf(&rc, "\"%w\" COLLATE %s",zName,zColl); - }else{ - p->zExpr = 0; - } - pIdx->nCol = iCol; - pIdx->zWhere = 0; - } - cidxFinalize(&rc, pInfo); - } - - if( rc==SQLITE_OK && zSql ){ - rc = cidxParseSQL(pCsr, pIdx, zSql); - } - } - - cidxFinalize(&rc, pFindTab); - if( rc==SQLITE_OK && zTab==0 ){ - rc = SQLITE_ERROR; - } - - if( rc!=SQLITE_OK ){ - sqlite3_free(zTab); - cidxFreeIndex(pIdx); - }else{ - *pzTab = zTab; - *ppIdx = pIdx; - } - - return rc; -} - -static int cidxDecodeAfter( - CidxCursor *pCsr, - int nCol, - const char *zAfterKey, - char ***pazAfter -){ - char **azAfter; - int rc = SQLITE_OK; - int nAfterKey = (int)strlen(zAfterKey); - - azAfter = cidxMalloc(&rc, sizeof(char*)*nCol + nAfterKey+1); - if( rc==SQLITE_OK ){ - int i; - char *zCopy = (char*)&azAfter[nCol]; - char *p = zCopy; - memcpy(zCopy, zAfterKey, nAfterKey+1); - for(i=0; i='0' && *p<='9') - || *p=='.' || *p=='+' || *p=='-' || *p=='e' || *p=='E' - ){ - p++; - } - } - - while( *p==' ' ) p++; - if( *p!=(i==(nCol-1) ? '\0' : ',') ){ - goto parse_error; - } - *p++ = '\0'; - } - } - - *pazAfter = azAfter; - return rc; - - parse_error: - sqlite3_free(azAfter); - *pazAfter = 0; - cidxCursorError(pCsr, "%s", "error parsing after value"); - return SQLITE_ERROR; -} - -static char *cidxWhere( - int *pRc, CidxColumn *aCol, char **azAfter, int iGt, int bLastIsNull -){ - char *zRet = 0; - const char *zSep = ""; - int i; - - for(i=0; i"), - azAfter[iGt] - ); - }else{ - zRet = cidxMprintf(pRc, "%z%s(%s) IS NOT NULL", zRet, zSep,aCol[iGt].zExpr); - } - - return zRet; -} - -#define CIDX_CLIST_ALL 0 -#define CIDX_CLIST_ORDERBY 1 -#define CIDX_CLIST_CURRENT_KEY 2 -#define CIDX_CLIST_SUBWHERE 3 -#define CIDX_CLIST_SUBEXPR 4 - -/* -** This function returns various strings based on the contents of the -** CidxIndex structure and the eType parameter. -*/ -static char *cidxColumnList( - int *pRc, /* IN/OUT: Error code */ - const char *zIdx, - CidxIndex *pIdx, /* Indexed columns */ - int eType /* True to include ASC/DESC */ -){ - char *zRet = 0; - if( *pRc==SQLITE_OK ){ - const char *aDir[2] = {"", " DESC"}; - int i; - const char *zSep = ""; - - for(i=0; inCol; i++){ - CidxColumn *p = &pIdx->aCol[i]; - assert( pIdx->aCol[i].bDesc==0 || pIdx->aCol[i].bDesc==1 ); - switch( eType ){ - - case CIDX_CLIST_ORDERBY: - zRet = cidxMprintf(pRc, "%z%s%d%s", zRet, zSep, i+1, aDir[p->bDesc]); - zSep = ","; - break; - - case CIDX_CLIST_CURRENT_KEY: - zRet = cidxMprintf(pRc, "%z%squote(i%d)", zRet, zSep, i); - zSep = "||','||"; - break; - - case CIDX_CLIST_SUBWHERE: - if( p->bKey==0 ){ - zRet = cidxMprintf(pRc, "%z%s%s IS i.i%d", zRet, - zSep, p->zExpr, i - ); - zSep = " AND "; - } - break; - - case CIDX_CLIST_SUBEXPR: - if( p->bKey==1 ){ - zRet = cidxMprintf(pRc, "%z%s%s IS i.i%d", zRet, - zSep, p->zExpr, i - ); - zSep = " AND "; - } - break; - - default: - assert( eType==CIDX_CLIST_ALL ); - zRet = cidxMprintf(pRc, "%z%s(%s) AS i%d", zRet, zSep, p->zExpr, i); - zSep = ", "; - break; - } - } - } - - return zRet; -} - -/* -** Generate SQL (in memory obtained from sqlite3_malloc()) that will -** continue the index scan for zIdxName starting after zAfterKey. -*/ -int cidxGenerateScanSql( - CidxCursor *pCsr, /* The cursor which needs the new statement */ - const char *zIdxName, /* index to be scanned */ - const char *zAfterKey, /* start after this key, if not NULL */ - char **pzSqlOut /* OUT: Write the generated SQL here */ -){ - int rc; - char *zTab = 0; - char *zCurrentKey = 0; - char *zOrderBy = 0; - char *zSubWhere = 0; - char *zSubExpr = 0; - char *zSrcList = 0; - char **azAfter = 0; - CidxIndex *pIdx = 0; - - *pzSqlOut = 0; - rc = cidxLookupIndex(pCsr, zIdxName, &pIdx, &zTab); - - zOrderBy = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_ORDERBY); - zCurrentKey = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_CURRENT_KEY); - zSubWhere = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_SUBWHERE); - zSubExpr = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_SUBEXPR); - zSrcList = cidxColumnList(&rc, zIdxName, pIdx, CIDX_CLIST_ALL); - - if( rc==SQLITE_OK && zAfterKey ){ - rc = cidxDecodeAfter(pCsr, pIdx->nCol, zAfterKey, &azAfter); - } - - if( rc==SQLITE_OK ){ - if( zAfterKey==0 ){ - *pzSqlOut = cidxMprintf(&rc, - "SELECT (SELECT %s FROM %Q AS t WHERE %s), %s " - "FROM (SELECT %s FROM %Q INDEXED BY %Q %s%sORDER BY %s) AS i", - zSubExpr, zTab, zSubWhere, zCurrentKey, - zSrcList, zTab, zIdxName, - (pIdx->zWhere ? "WHERE " : ""), (pIdx->zWhere ? pIdx->zWhere : ""), - zOrderBy - ); - }else{ - const char *zSep = ""; - char *zSql; - int i; - - zSql = cidxMprintf(&rc, - "SELECT (SELECT %s FROM %Q WHERE %s), %s FROM (", - zSubExpr, zTab, zSubWhere, zCurrentKey - ); - for(i=pIdx->nCol-1; i>=0; i--){ - int j; - if( pIdx->aCol[i].bDesc && azAfter[i]==0 ) continue; - for(j=0; j<2; j++){ - char *zWhere = cidxWhere(&rc, pIdx->aCol, azAfter, i, j); - zSql = cidxMprintf(&rc, "%z" - "%sSELECT * FROM (" - "SELECT %s FROM %Q INDEXED BY %Q WHERE %s%s%z ORDER BY %s" - ")", - zSql, zSep, zSrcList, zTab, zIdxName, - pIdx->zWhere ? pIdx->zWhere : "", - pIdx->zWhere ? " AND " : "", - zWhere, zOrderBy - ); - zSep = " UNION ALL "; - if( pIdx->aCol[i].bDesc==0 ) break; - } - } - *pzSqlOut = cidxMprintf(&rc, "%z) AS i", zSql); - } - } - - sqlite3_free(zTab); - sqlite3_free(zCurrentKey); - sqlite3_free(zOrderBy); - sqlite3_free(zSubWhere); - sqlite3_free(zSubExpr); - sqlite3_free(zSrcList); - cidxFreeIndex(pIdx); - sqlite3_free(azAfter); - return rc; -} - - -/* -** Position a cursor back to the beginning. -*/ -static int cidxFilter( - sqlite3_vtab_cursor *pCursor, - int idxNum, const char *idxStr, - int argc, sqlite3_value **argv -){ - int rc = SQLITE_OK; - CidxCursor *pCsr = (CidxCursor*)pCursor; - const char *zIdxName = 0; - const char *zAfterKey = 0; - - sqlite3_free(pCsr->zIdxName); - pCsr->zIdxName = 0; - sqlite3_free(pCsr->zAfterKey); - pCsr->zAfterKey = 0; - sqlite3_finalize(pCsr->pStmt); - pCsr->pStmt = 0; - - if( argc>0 ){ - zIdxName = (const char*)sqlite3_value_text(argv[0]); - if( argc>1 ){ - zAfterKey = (const char*)sqlite3_value_text(argv[1]); - } - } - - if( zIdxName ){ - char *zSql = 0; - pCsr->zIdxName = sqlite3_mprintf("%s", zIdxName); - pCsr->zAfterKey = zAfterKey ? sqlite3_mprintf("%s", zAfterKey) : 0; - rc = cidxGenerateScanSql(pCsr, zIdxName, zAfterKey, &zSql); - if( zSql ){ - pCsr->pStmt = cidxPrepare(&rc, pCsr, "%z", zSql); - } - } - - 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_SCANNER_SQL ); - switch( iCol ){ - case 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); - break; - } - case IIC_CURRENT_KEY: { - sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, 1)); - break; - } - case IIC_INDEX_NAME: { - sqlite3_result_text(ctx, pCsr->zIdxName, -1, SQLITE_TRANSIENT); - break; - } - case IIC_AFTER_KEY: { - sqlite3_result_text(ctx, pCsr->zAfterKey, -1, SQLITE_TRANSIENT); - break; - } - case IIC_SCANNER_SQL: { - char *zSql = 0; - cidxGenerateScanSql(pCsr, pCsr->zIdxName, pCsr->zAfterKey, &zSql); - sqlite3_result_text(ctx, zSql, -1, sqlite3_free); - break; - } - } - return SQLITE_OK; -} - -/* Return the ROWID for the sqlite_btreeinfo table */ -static int cidxRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ - CidxCursor *pCsr = (CidxCursor*)pCursor; - *pRowid = pCsr->iRowid; - return SQLITE_OK; -} - -/* -** Register the virtual table modules with the database handle passed -** as the only argument. -*/ -static int ciInit(sqlite3 *db){ - static sqlite3_module cidx_module = { - 0, /* iVersion */ - 0, /* xCreate */ - cidxConnect, /* xConnect */ - cidxBestIndex, /* xBestIndex */ - cidxDisconnect, /* xDisconnect */ - 0, /* xDestroy */ - cidxOpen, /* xOpen - open a cursor */ - cidxClose, /* xClose - close a cursor */ - cidxFilter, /* xFilter - configure scan constraints */ - cidxNext, /* xNext - advance a cursor */ - cidxEof, /* xEof - check for end of scan */ - cidxColumn, /* xColumn - read data */ - cidxRowid, /* xRowid - read data */ - 0, /* xUpdate */ - 0, /* xBegin */ - 0, /* xSync */ - 0, /* xCommit */ - 0, /* xRollback */ - 0, /* xFindMethod */ - 0, /* xRename */ - 0, /* xSavepoint */ - 0, /* xRelease */ - 0, /* xRollbackTo */ - 0, /* xShadowName */ - 0 /* xIntegrity */ - }; - return sqlite3_create_module(db, "incremental_index_check", &cidx_module, 0); -} - -/* -** Extension load function. -*/ -#ifdef _WIN32 -__declspec(dllexport) -#endif -int sqlite3_checkindex_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi -){ - SQLITE_EXTENSION_INIT2(pApi); - return ciInit(db); -} diff --git a/ext/repair/sqlite3_checker.c.in b/ext/repair/sqlite3_checker.c.in deleted file mode 100644 index 96b15f2713..0000000000 --- a/ext/repair/sqlite3_checker.c.in +++ /dev/null @@ -1,85 +0,0 @@ -/* -** Read an SQLite database file and analyze its space utilization. Generate -** text on standard output. -*/ -#define TCLSH_INIT_PROC sqlite3_checker_init_proc -#define SQLITE_ENABLE_DBPAGE_VTAB 1 -#undef SQLITE_THREADSAFE -#define SQLITE_THREADSAFE 0 -#undef SQLITE_ENABLE_COLUMN_METADATA -#define SQLITE_OMIT_DECLTYPE 1 -#define SQLITE_OMIT_DEPRECATED 1 -#define SQLITE_OMIT_PROGRESS_CALLBACK 1 -#define SQLITE_OMIT_SHARED_CACHE 1 -#define SQLITE_DEFAULT_MEMSTATUS 0 -#define SQLITE_MAX_EXPR_DEPTH 0 -INCLUDE sqlite3.c -INCLUDE $ROOT/src/tclsqlite.c -INCLUDE $ROOT/ext/misc/btreeinfo.c -INCLUDE $ROOT/ext/repair/checkindex.c -INCLUDE $ROOT/ext/repair/checkfreelist.c - -/* -** Decode a pointer to an sqlite3 object. -*/ -int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ - struct SqliteDb *p; - Tcl_CmdInfo cmdInfo; - if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){ - p = (struct SqliteDb*)cmdInfo.objClientData; - *ppDb = p->db; - return TCL_OK; - }else{ - *ppDb = 0; - return TCL_ERROR; - } - return TCL_OK; -} - -/* -** sqlite3_imposter db main rootpage {CREATE TABLE...} ;# setup an imposter -** sqlite3_imposter db main ;# rm all imposters -*/ -static int sqlite3_imposter( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - sqlite3 *db; - const char *zSchema; - int iRoot; - const char *zSql; - - if( objc!=3 && objc!=5 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DB SCHEMA [ROOTPAGE SQL]"); - return TCL_ERROR; - } - if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; - zSchema = Tcl_GetString(objv[2]); - if( objc==3 ){ - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 1); - }else{ - if( Tcl_GetIntFromObj(interp, objv[3], &iRoot) ) return TCL_ERROR; - zSql = Tcl_GetString(objv[4]); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 1, iRoot); - sqlite3_exec(db, zSql, 0, 0, 0); - sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 0); - } - return TCL_OK; -} - -#include - -const char *sqlite3_checker_init_proc(Tcl_Interp *interp){ - Tcl_CreateObjCommand(interp, "sqlite3_imposter", - (Tcl_ObjCmdProc*)sqlite3_imposter, 0, 0); - sqlite3_auto_extension((void(*)(void))sqlite3_btreeinfo_init); - sqlite3_auto_extension((void(*)(void))sqlite3_checkindex_init); - sqlite3_auto_extension((void(*)(void))sqlite3_checkfreelist_init); - return -BEGIN_STRING -INCLUDE $ROOT/ext/repair/sqlite3_checker.tcl -END_STRING -; -} diff --git a/ext/repair/sqlite3_checker.tcl b/ext/repair/sqlite3_checker.tcl deleted file mode 100644 index 2ae6e15b12..0000000000 --- a/ext/repair/sqlite3_checker.tcl +++ /dev/null @@ -1,264 +0,0 @@ -# This TCL script is the main driver script for the sqlite3_checker utility -# program. -# - -# Special case: -# -# sqlite3_checker --test FILENAME ARGS -# -# uses FILENAME in place of this script. -# -if {[lindex $argv 0]=="--test" && [llength $argv]>1} { - set ::argv0 [lindex $argv 1] - set argv [lrange $argv 2 end] - source $argv0 - exit 0 -} - -# Emulate a TCL shell -# -proc tclsh {} { - set line {} - while {![eof stdin]} { - if {$line!=""} { - puts -nonewline "> " - } else { - puts -nonewline "% " - } - flush stdout - append line [gets stdin] - if {[info complete $line]} { - if {[catch {uplevel #0 $line} result]} { - puts stderr "Error: $result" - } elseif {$result!=""} { - puts $result - } - set line {} - } else { - append line \n - } - } -} - -# Do an incremental integrity check of a single index -# -proc check_index {idxname batchsize bTrace} { - 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 - if {$bTrace} { - set sql {SELECT errmsg, current_key AS key, - CASE WHEN rowid=1 THEN scanner_sql END AS traceOut - FROM incremental_index_check($idxname) - WHERE after_key=$key - LIMIT $batchsize} - } else { - set sql {SELECT errmsg, current_key AS key, NULL AS traceOut - FROM incremental_index_check($idxname) - WHERE after_key=$key - LIMIT $batchsize} - } - while {$more} { - set more 0 - db eval $sql { - set more 1 - if {$errmsg!=""} { - incr nerr - puts "$idxname: key($key): $errmsg" - } elseif {$traceOut!=""} { - puts "$idxname: $traceOut" - } - 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" - puts stderr { -Do sanity checking on a live SQLite3 database file specified by the -"database-filename" argument. - -Options: - - --batchsize N Number of rows to check per transaction - - --freelist Perform a freelist check - - --index NAME Run a check of the index NAME - - --summary Print summary information about the database - - --table NAME Run a check of all indexes for table NAME - - --tclsh Run the built-in TCL interpreter (for debugging) - - --trace (Debugging only:) Output trace information on the scan - - --version Show the version number of SQLite -} - exit 1 -} - -set file_to_analyze {} -append argv {} -set bFreelistCheck 0 -set bSummary 0 -set zIndex {} -set zTable {} -set batchsize 1000 -set bAll 1 -set bTrace 0 -set argc [llength $argv] -for {set i 0} {$i<$argc} {incr i} { - set arg [lindex $argv $i] - if {[regexp {^-+tclsh$} $arg]} { - tclsh - exit 0 - } - if {[regexp {^-+version$} $arg]} { - sqlite3 mem :memory: - puts [mem one {SELECT sqlite_version()||' '||sqlite_source_id()}] - mem close - exit 0 - } - if {[regexp {^-+freelist$} $arg]} { - set bFreelistCheck 1 - set bAll 0 - continue - } - if {[regexp {^-+summary$} $arg]} { - set bSummary 1 - set bAll 0 - continue - } - if {[regexp {^-+trace$} $arg]} { - set bTrace 1 - continue - } - if {[regexp {^-+batchsize$} $arg]} { - incr i - if {$i>=$argc} { - puts stderr "missing argument on $arg" - exit 1 - } - set batchsize [lindex $argv $i] - continue - } - if {[regexp {^-+index$} $arg]} { - incr i - if {$i>=$argc} { - puts stderr "missing argument on $arg" - exit 1 - } - set zIndex [lindex $argv $i] - set bAll 0 - continue - } - if {[regexp {^-+table$} $arg]} { - incr i - if {$i>=$argc} { - puts stderr "missing argument on $arg" - exit 1 - } - set zTable [lindex $argv $i] - set bAll 0 - continue - } - if {[regexp {^-} $arg]} { - puts stderr "Unknown option: $arg" - usage - } - if {$file_to_analyze!=""} { - usage - } else { - set file_to_analyze $arg - } -} -if {$file_to_analyze==""} usage - -# If a TCL script is specified on the command-line, then run that -# script. -# -if {[file extension $file_to_analyze]==".tcl"} { - source $file_to_analyze - exit 0 -} - -set root_filename $file_to_analyze -regexp {^file:(//)?([^?]*)} $file_to_analyze all x1 root_filename -if {![file exists $root_filename]} { - puts stderr "No such file: $root_filename" - exit 1 -} -if {![file readable $root_filename]} { - puts stderr "File is not readable: $root_filename" - exit 1 -} - -if {[catch {sqlite3 db $file_to_analyze} res]} { - puts stderr "Cannot open datababase $root_filename: $res" - exit 1 -} - -if {$bFreelistCheck || $bAll} { - puts -nonewline "freelist-check: " - flush stdout - db eval BEGIN - puts [db one {SELECT checkfreelist('main')}] - db eval END -} -if {$bSummary} { - set scale 0 - set pgsz [db one {PRAGMA page_size}] - db eval {SELECT nPage*$pgsz AS sz, name, tbl_name - FROM sqlite_btreeinfo - WHERE type='index' - ORDER BY 1 DESC, name} { - if {$scale==0} { - if {$sz>10000000} { - set scale 1000000.0 - set unit MB - } else { - set scale 1000.0 - set unit KB - } - } - puts [format {%7.1f %s index %s of table %s} \ - [expr {$sz/$scale}] $unit $name $tbl_name] - } -} -if {$zIndex!=""} { - check_index $zIndex $batchsize $bTrace -} -if {$zTable!=""} { - foreach idx [db eval {SELECT name FROM sqlite_master - WHERE type='index' AND rootpage>0 - AND tbl_name=$zTable}] { - check_index $idx $batchsize $bTrace - } -} -if {$bAll} { - set allidx [db eval {SELECT name FROM sqlite_btreeinfo('main') - WHERE type='index' AND rootpage>0 - ORDER BY nEntry}] - foreach idx $allidx { - check_index $idx $batchsize $bTrace - } -} diff --git a/ext/repair/test/README.md b/ext/repair/test/README.md deleted file mode 100644 index 8cc954adf5..0000000000 --- a/ext/repair/test/README.md +++ /dev/null @@ -1,13 +0,0 @@ -To run these tests, first build sqlite3_checker: - - -> make sqlite3_checker - - -Then run the "test.tcl" script using: - - -> ./sqlite3_checker --test $path/test.tcl - - -Optionally add the full pathnames of individual *.test modules diff --git a/ext/repair/test/checkfreelist01.test b/ext/repair/test/checkfreelist01.test deleted file mode 100644 index 7e2dd51c37..0000000000 --- a/ext/repair/test/checkfreelist01.test +++ /dev/null @@ -1,92 +0,0 @@ -# 2017-10-11 - -set testprefix checkfreelist - -do_execsql_test 1.0 { - PRAGMA page_size=1024; - CREATE TABLE t1(a, b); -} - -do_execsql_test 1.2 { SELECT checkfreelist('main') } {ok} -do_execsql_test 1.3 { - WITH s(i) AS ( - SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000 - ) - INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s; - DELETE FROM t1 WHERE rowid%3; - PRAGMA freelist_count; -} {6726} - -do_execsql_test 1.4 { SELECT checkfreelist('main') } {ok} -do_execsql_test 1.5 { - WITH freelist_trunk(i, d, n) AS ( - SELECT 1, NULL, sqlite_readint32(data, 32) FROM sqlite_dbpage WHERE pgno=1 - UNION ALL - SELECT n, data, sqlite_readint32(data) - FROM freelist_trunk, sqlite_dbpage WHERE pgno=n - ) - SELECT i FROM freelist_trunk WHERE i!=1; -} { - 10009 9715 9343 8969 8595 8222 7847 7474 7102 6727 6354 5982 5608 5234 - 4860 4487 4112 3740 3367 2992 2619 2247 1872 1499 1125 752 377 5 -} - -do_execsql_test 1.6 { SELECT checkfreelist('main') } {ok} - -proc set_int {blob idx newval} { - binary scan $blob I* ints - lset ints $idx $newval - binary format I* $ints -} -db func set_int set_int - -proc get_int {blob idx} { - binary scan $blob I* ints - lindex $ints $idx -} -db func get_int get_int - -do_execsql_test 1.7 { - BEGIN; - UPDATE sqlite_dbpage - SET data = set_int(data, 1, get_int(data, 1)-1) - WHERE pgno=4860; - SELECT checkfreelist('main'); - ROLLBACK; -} {{free-list count mismatch: actual=6725 header=6726}} - -do_execsql_test 1.8 { - BEGIN; - UPDATE sqlite_dbpage - SET data = set_int(data, 5, (SELECT * FROM pragma_page_count)+1) - WHERE pgno=4860; - SELECT checkfreelist('main'); - ROLLBACK; -} {{leaf page 10092 is out of range (child 3 of trunk page 4860)}} - -do_execsql_test 1.9 { - BEGIN; - UPDATE sqlite_dbpage - SET data = set_int(data, 5, 0) - WHERE pgno=4860; - SELECT checkfreelist('main'); - ROLLBACK; -} {{leaf page 0 is out of range (child 3 of trunk page 4860)}} - -do_execsql_test 1.10 { - BEGIN; - UPDATE sqlite_dbpage - SET data = set_int(data, get_int(data, 1)+1, 0) - WHERE pgno=5; - SELECT checkfreelist('main'); - ROLLBACK; -} {{leaf page 0 is out of range (child 247 of trunk page 5)}} - -do_execsql_test 1.11 { - BEGIN; - UPDATE sqlite_dbpage - SET data = set_int(data, 1, 249) - WHERE pgno=5; - SELECT checkfreelist('main'); - ROLLBACK; -} {{leaf count out of range (249) on trunk page 5}} diff --git a/ext/repair/test/checkindex01.test b/ext/repair/test/checkindex01.test deleted file mode 100644 index 97973aee71..0000000000 --- a/ext/repair/test/checkindex01.test +++ /dev/null @@ -1,349 +0,0 @@ -# 2017-10-11 -# -set testprefix checkindex - -do_execsql_test 1.0 { - CREATE TABLE t1(a, b); - CREATE INDEX i1 ON t1(a); - INSERT INTO t1 VALUES('one', 2); - INSERT INTO t1 VALUES('two', 4); - INSERT INTO t1 VALUES('three', 6); - INSERT INTO t1 VALUES('four', 8); - INSERT INTO t1 VALUES('five', 10); - - CREATE INDEX i2 ON t1(a DESC); -} {} - -proc incr_index_check {idx nStep} { - set Q { - SELECT errmsg, current_key FROM incremental_index_check($idx, $after) - LIMIT $nStep - } - - set res [list] - while {1} { - unset -nocomplain current_key - set res1 [db eval $Q] - if {[llength $res1]==0} break - set res [concat $res $res1] - set after [lindex $res end] - } - - return $res -} - -proc do_index_check_test {tn idx res} { - uplevel [list do_execsql_test $tn.1 " - SELECT errmsg, current_key FROM incremental_index_check('$idx'); - " $res] - - uplevel [list do_test $tn.2 "incr_index_check $idx 1" [list {*}$res]] - uplevel [list do_test $tn.3 "incr_index_check $idx 2" [list {*}$res]] - uplevel [list do_test $tn.4 "incr_index_check $idx 5" [list {*}$res]] -} - - -do_execsql_test 1.2.1 { - SELECT rowid, errmsg IS NULL, current_key FROM incremental_index_check('i1'); -} { - 1 1 'five',5 - 2 1 'four',4 - 3 1 'one',1 - 4 1 'three',3 - 5 1 'two',2 -} -do_execsql_test 1.2.2 { - SELECT errmsg IS NULL, current_key, index_name, after_key, scanner_sql - FROM incremental_index_check('i1') LIMIT 1; -} { - 1 - 'five',5 - i1 - {} - {SELECT (SELECT a IS i.i0 FROM 't1' AS t WHERE "rowid" COLLATE BINARY IS i.i1), quote(i0)||','||quote(i1) FROM (SELECT (a) AS i0, ("rowid" COLLATE BINARY) AS i1 FROM 't1' INDEXED BY 'i1' ORDER BY 1,2) AS i} -} - -do_index_check_test 1.3 i1 { - {} 'five',5 - {} 'four',4 - {} 'one',1 - {} 'three',3 - {} 'two',2 -} - -do_index_check_test 1.4 i2 { - {} 'two',2 - {} 'three',3 - {} 'one',1 - {} 'four',4 - {} 'five',5 -} - -do_test 1.5 { - set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t1' }] - sqlite3_imposter db main $tblroot {CREATE TABLE xt1(a,b)} - db eval { - UPDATE xt1 SET a='six' WHERE rowid=3; - DELETE FROM xt1 WHERE rowid = 5; - } - sqlite3_imposter db main -} {} - -do_index_check_test 1.6 i1 { - {row missing} 'five',5 - {} 'four',4 - {} 'one',1 - {row data mismatch} 'three',3 - {} 'two',2 -} - -do_index_check_test 1.7 i2 { - {} 'two',2 - {row data mismatch} 'three',3 - {} 'one',1 - {} 'four',4 - {row missing} 'five',5 -} - -#-------------------------------------------------------------------------- -do_execsql_test 2.0 { - - CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c, d); - - INSERT INTO t2 VALUES(1, NULL, 1, 1); - INSERT INTO t2 VALUES(2, 1, NULL, 1); - INSERT INTO t2 VALUES(3, 1, 1, NULL); - - INSERT INTO t2 VALUES(4, 2, 2, 1); - INSERT INTO t2 VALUES(5, 2, 2, 2); - INSERT INTO t2 VALUES(6, 2, 2, 3); - - INSERT INTO t2 VALUES(7, 2, 2, 1); - INSERT INTO t2 VALUES(8, 2, 2, 2); - INSERT INTO t2 VALUES(9, 2, 2, 3); - - CREATE INDEX i3 ON t2(b, c, d); - CREATE INDEX i4 ON t2(b DESC, c DESC, d DESC); - CREATE INDEX i5 ON t2(d, c DESC, b); -} {} - -do_index_check_test 2.1 i3 { - {} NULL,1,1,1 - {} 1,NULL,1,2 - {} 1,1,NULL,3 - {} 2,2,1,4 - {} 2,2,1,7 - {} 2,2,2,5 - {} 2,2,2,8 - {} 2,2,3,6 - {} 2,2,3,9 -} - -do_index_check_test 2.2 i4 { - {} 2,2,3,6 - {} 2,2,3,9 - {} 2,2,2,5 - {} 2,2,2,8 - {} 2,2,1,4 - {} 2,2,1,7 - {} 1,1,NULL,3 - {} 1,NULL,1,2 - {} NULL,1,1,1 -} - -do_index_check_test 2.3 i5 { - {} NULL,1,1,3 - {} 1,2,2,4 - {} 1,2,2,7 - {} 1,1,NULL,1 - {} 1,NULL,1,2 - {} 2,2,2,5 - {} 2,2,2,8 - {} 3,2,2,6 - {} 3,2,2,9 -} - -#-------------------------------------------------------------------------- -do_execsql_test 3.0 { - - CREATE TABLE t3(w, x, y, z PRIMARY KEY) WITHOUT ROWID; - CREATE INDEX t3wxy ON t3(w, x, y); - CREATE INDEX t3wxy2 ON t3(w DESC, x DESC, y DESC); - - INSERT INTO t3 VALUES(NULL, NULL, NULL, 1); - INSERT INTO t3 VALUES(NULL, NULL, NULL, 2); - INSERT INTO t3 VALUES(NULL, NULL, NULL, 3); - - INSERT INTO t3 VALUES('a', NULL, NULL, 4); - INSERT INTO t3 VALUES('a', NULL, NULL, 5); - INSERT INTO t3 VALUES('a', NULL, NULL, 6); - - INSERT INTO t3 VALUES('a', 'b', NULL, 7); - INSERT INTO t3 VALUES('a', 'b', NULL, 8); - INSERT INTO t3 VALUES('a', 'b', NULL, 9); - -} {} - -do_index_check_test 3.1 t3wxy { - {} NULL,NULL,NULL,1 {} NULL,NULL,NULL,2 {} NULL,NULL,NULL,3 - {} 'a',NULL,NULL,4 {} 'a',NULL,NULL,5 {} 'a',NULL,NULL,6 - {} 'a','b',NULL,7 {} 'a','b',NULL,8 {} 'a','b',NULL,9 -} -do_index_check_test 3.2 t3wxy2 { - {} 'a','b',NULL,7 {} 'a','b',NULL,8 {} 'a','b',NULL,9 - {} 'a',NULL,NULL,4 {} 'a',NULL,NULL,5 {} 'a',NULL,NULL,6 - {} NULL,NULL,NULL,1 {} NULL,NULL,NULL,2 {} NULL,NULL,NULL,3 -} - -#-------------------------------------------------------------------------- -# Test with an index that uses non-default collation sequences. -# -do_execsql_test 4.0 { - CREATE TABLE t4(a INTEGER PRIMARY KEY, c1 TEXT, c2 TEXT); - INSERT INTO t4 VALUES(1, 'aaa', 'bbb'); - INSERT INTO t4 VALUES(2, 'AAA', 'CCC'); - INSERT INTO t4 VALUES(3, 'aab', 'ddd'); - INSERT INTO t4 VALUES(4, 'AAB', 'EEE'); - - CREATE INDEX t4cc ON t4(c1 COLLATE nocase, c2 COLLATE nocase); -} - -do_index_check_test 4.1 t4cc { - {} 'aaa','bbb',1 - {} 'AAA','CCC',2 - {} 'aab','ddd',3 - {} 'AAB','EEE',4 -} - -do_test 4.2 { - set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t4' }] - sqlite3_imposter db main $tblroot \ - {CREATE TABLE xt4(a INTEGER PRIMARY KEY, c1 TEXT, c2 TEXT)} - - db eval { - UPDATE xt4 SET c1='hello' WHERE rowid=2; - DELETE FROM xt4 WHERE rowid = 3; - } - sqlite3_imposter db main -} {} - -do_index_check_test 4.3 t4cc { - {} 'aaa','bbb',1 - {row data mismatch} 'AAA','CCC',2 - {row missing} 'aab','ddd',3 - {} 'AAB','EEE',4 -} - -#-------------------------------------------------------------------------- -# Test an index on an expression. -# -do_execsql_test 5.0 { - CREATE TABLE t5(x INTEGER PRIMARY KEY, y TEXT, UNIQUE(y)); - INSERT INTO t5 VALUES(1, '{"x":1, "y":1}'); - INSERT INTO t5 VALUES(2, '{"x":2, "y":2}'); - INSERT INTO t5 VALUES(3, '{"x":3, "y":3}'); - INSERT INTO t5 VALUES(4, '{"w":4, "z":4}'); - INSERT INTO t5 VALUES(5, '{"x":5, "y":5}'); - - CREATE INDEX t5x ON t5( json_extract(y, '$.x') ); - CREATE INDEX t5y ON t5( json_extract(y, '$.y') DESC ); -} - -do_index_check_test 5.1.1 t5x { - {} NULL,4 {} 1,1 {} 2,2 {} 3,3 {} 5,5 -} - -do_index_check_test 5.1.2 t5y { - {} 5,5 {} 3,3 {} 2,2 {} 1,1 {} NULL,4 -} - -do_index_check_test 5.1.3 sqlite_autoindex_t5_1 { - {} {'{"w":4, "z":4}',4} - {} {'{"x":1, "y":1}',1} - {} {'{"x":2, "y":2}',2} - {} {'{"x":3, "y":3}',3} - {} {'{"x":5, "y":5}',5} -} - -do_test 5.2 { - set tblroot [db one { SELECT rootpage FROM sqlite_master WHERE name='t5' }] - sqlite3_imposter db main $tblroot \ - {CREATE TABLE xt5(a INTEGER PRIMARY KEY, c1 TEXT);} - db eval { - UPDATE xt5 SET c1='{"x":22, "y":11}' WHERE rowid=1; - DELETE FROM xt5 WHERE rowid = 4; - } - sqlite3_imposter db main -} {} - -do_index_check_test 5.3.1 t5x { - {row missing} NULL,4 - {row data mismatch} 1,1 - {} 2,2 - {} 3,3 - {} 5,5 -} - -do_index_check_test 5.3.2 sqlite_autoindex_t5_1 { - {row missing} {'{"w":4, "z":4}',4} - {row data mismatch} {'{"x":1, "y":1}',1} - {} {'{"x":2, "y":2}',2} - {} {'{"x":3, "y":3}',3} - {} {'{"x":5, "y":5}',5} -} - -#------------------------------------------------------------------------- -# -do_execsql_test 6.0 { - CREATE TABLE t6(x INTEGER PRIMARY KEY, y, z); - CREATE INDEX t6x1 ON t6(y, /* one,two,three */ z); - CREATE INDEX t6x2 ON t6(z, -- hello,world, - y); - - CREATE INDEX t6x3 ON t6(z -- hello,world - , y); - - INSERT INTO t6 VALUES(1, 2, 3); - INSERT INTO t6 VALUES(4, 5, 6); -} - -do_index_check_test 6.1 t6x1 { - {} 2,3,1 - {} 5,6,4 -} -do_index_check_test 6.2 t6x2 { - {} 3,2,1 - {} 6,5,4 -} -do_index_check_test 6.2 t6x3 { - {} 3,2,1 - {} 6,5,4 -} - -#------------------------------------------------------------------------- -# -do_execsql_test 7.0 { - CREATE TABLE t7(x INTEGER PRIMARY KEY, y, z); - INSERT INTO t7 VALUES(1, 1, 1); - INSERT INTO t7 VALUES(2, 2, 0); - INSERT INTO t7 VALUES(3, 3, 1); - INSERT INTO t7 VALUES(4, 4, 0); - - CREATE INDEX t7i1 ON t7(y) WHERE z=1; - CREATE INDEX t7i2 ON t7(y) /* hello,world */ WHERE z=1; - CREATE INDEX t7i3 ON t7(y) WHERE -- yep - z=1; - CREATE INDEX t7i4 ON t7(y) WHERE z=1 -- yep; -} -do_index_check_test 7.1 t7i1 { - {} 1,1 {} 3,3 -} -do_index_check_test 7.2 t7i2 { - {} 1,1 {} 3,3 -} -do_index_check_test 7.3 t7i3 { - {} 1,1 {} 3,3 -} -do_index_check_test 7.4 t7i4 { - {} 1,1 {} 3,3 -} diff --git a/ext/repair/test/test.tcl b/ext/repair/test/test.tcl deleted file mode 100644 index c073bb73c5..0000000000 --- a/ext/repair/test/test.tcl +++ /dev/null @@ -1,67 +0,0 @@ -# Run this script using -# -# sqlite3_checker --test $thisscript $testscripts -# -# The $testscripts argument is optional. If omitted, all *.test files -# in the same directory as $thisscript are run. -# -set NTEST 0 -set NERR 0 - - -# Invoke the do_test procedure to run a single test -# -# The $expected parameter is the expected result. The result is the return -# value from the last TCL command in $cmd. -# -# Normally, $expected must match exactly. But if $expected is of the form -# "/regexp/" then regular expression matching is used. If $expected is -# "~/regexp/" then the regular expression must NOT match. If $expected is -# of the form "#/value-list/" then each term in value-list must be numeric -# and must approximately match the corresponding numeric term in $result. -# Values must match within 10%. Or if the $expected term is A..B then the -# $result term must be in between A and B. -# -proc do_test {name cmd expected} { - if {[info exists ::testprefix]} { - set name "$::testprefix$name" - } - - incr ::NTEST - puts -nonewline $name... - flush stdout - - if {[catch {uplevel #0 "$cmd;\n"} result]} { - puts -nonewline $name... - puts "\nError: $result" - incr ::NERR - } else { - set ok [expr {[string compare $result $expected]==0}] - if {!$ok} { - puts "\n! $name expected: \[$expected\]\n! $name got: \[$result\]" - incr ::NERR - } else { - puts " Ok" - } - } - flush stdout -} - -# -# do_execsql_test TESTNAME SQL RES -# -proc do_execsql_test {testname sql {result {}}} { - uplevel [list do_test $testname [list db eval $sql] [list {*}$result]] -} - -if {[llength $argv]==0} { - set dir [file dirname $argv0] - set argv [glob -nocomplain $dir/*.test] -} -foreach testfile $argv { - file delete -force test.db - sqlite3 db test.db - source $testfile - catch {db close} -} -puts "$NERR errors out of $NTEST tests" diff --git a/main.mk b/main.mk index 8b5d2821cf..46d646d03a 100644 --- a/main.mk +++ b/main.mk @@ -1971,24 +1971,6 @@ sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqli $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3) xbin: sqlite3_expert$(T.exe) -CHECKER_DEPS =\ - $(TOP)/tool/mkccode.tcl \ - sqlite3.c \ - tclsqlite-ex.c \ - $(TOP)/ext/repair/sqlite3_checker.tcl \ - $(TOP)/ext/repair/checkindex.c \ - $(TOP)/ext/repair/checkfreelist.c \ - $(TOP)/ext/misc/btreeinfo.c \ - $(TOP)/ext/repair/sqlite3_checker.c.in - -sqlite3_checker.c: $(CHECKER_DEPS) - $(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ - -sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c - $(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC \ - $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3) -xbin: sqlite3_checker$(T.exe) - dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o $(T.link) -DDBDUMP_STANDALONE -o $@ \ $(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3) diff --git a/manifest b/manifest index 1e2d8e52db..559c825e7b 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Disable\stest\sshell1-5.0\sas\sit\sis\scausing\sa\suse\sof\sinitialized\sdeep\sinside\nof\sTCL. -D 2026-03-02T13:43:08.964 +C Remove\sthe\sexperimental\sand\sincomplete\sext/repair\sextension,\s\sto\sprevent\sAIs\nfrom\sscanning\sthe\s(incomplete)\scode\sand\sreporting\sbugs\sagainst\sit. +D 2026-03-02T13:44:04.938 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md 6bc480fc673fb4acbc4094e77edb326267dd460162d7723c7f30bee2d3d9e97d F Makefile.in 3ce07126d7e87c7464301482e161fdae6a51d0a2aa06b200b8f0000ef4d6163b F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 -F Makefile.msc 1fa179beafd6d438b8479146cae77fb1724dd35b330b09dbfebd8a2f0823c62a +F Makefile.msc 174764cb7e80c80f9003c46b3e388d74c68c8c40230208904b3af8fcabee5f4e F README.md 3fa51fc7ababc32edd175ae8b2986c86d5ea120c1cb1e57c7f7849492d1405ec F VERSION 74672bfd4c7826c0fc6f84762488a707c52e7d2d94af42ccb0edcc6c74311c41 F art/icon-243x273.gif 9750b734f82fdb3dc43127753d5e6fbf3b62c9f4e136c2fbf573b2f57ea87af5 @@ -488,15 +488,6 @@ F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e F ext/recover/sqlite3recover.c 56c216332ea91233d6d820d429f3384adbec9ecedda67aa98186b691d427cc57 F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/test_recover.c 3d0fb1df7823f5bc22a0b93955034d16a2dfa2eb1e443e9a0123a77f120599a3 -F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 -F ext/repair/checkfreelist.c e21f06995ff4efdc1622dcceaea4dcba2caa83ca2f31a1607b98a8509168a996 -F ext/repair/checkindex.c 7639b4f8928f82c10b950169e60cc45a7f6798df0b299771d17bef025736f657 -F ext/repair/sqlite3_checker.c.in 445118c5f7fea958b36fba1b2c464283e60ed4842039ddee3265f1698115ebf7 -F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa -F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e -F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc78249442da72ff3f8297398a69 -F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec -F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1 F ext/rtree/geopoly.c bd1971479184d559499ff3087c37f2823977d7b0ec80916141ae66f70345c88d F ext/rtree/rtree.c 9331997a76b88a9bc04e156bdfd6e2fe35c0aa93bc338ebc6aa0ae470fe4a852 @@ -660,7 +651,7 @@ F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca F ext/wasm/tests/opfs/sahpool/sahpool-pausing.js f264925cfc82155de38cecb3d204c36e0f6991460fff0cb7c15079454679a4e2 F ext/wasm/tests/opfs/sahpool/sahpool-worker.js bd25a43fc2ab2d1bafd8f2854ad3943ef673f7c3be03e95ecf1612ff6e8e2a61 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 9393d5982db60f26e72c5af24a8c11cf39374ff5e695fadb5a4e7376f28150c6 +F main.mk e1a03e9206f6a042a9147035915cb944e9242d570779bc3ccd7ed6a39df10cae F make.bat a136fd0b1c93e89854a86d5f4edcf0386d211e5d5ec2434480f6eea436c7420c F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -2197,8 +2188,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P e8976d5041c929675772039b7a8fc4ff0b609537d86f9aa6e445ecd512a10673 -R 196e96eb644b7fb48b6564a67ba146cd +P 440bd6091e3767f0a2f42ffdc92ca5e4736c0a73324fdd15397c3b5dbbc31fb8 +R c2e39b4a7bc89f40ea6792af5222cc7a U drh -Z db4a137667e1314416d854cef3854055 +Z 26aaa04451a5b488441824f4e50b1bf2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b3fac4eaf8..a60931df6c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -440bd6091e3767f0a2f42ffdc92ca5e4736c0a73324fdd15397c3b5dbbc31fb8 +213b1c6608af4b3e9d6e0d8de6432cc6857931427baf4beac1e0a4294e4dc6ce