diff options
175 files changed, 1992 insertions, 1497 deletions
diff --git a/autoconf/tea/tclconfig/tcl.m4 b/autoconf/tea/tclconfig/tcl.m4 index c83d660e1..455a7964d 100644 --- a/autoconf/tea/tclconfig/tcl.m4 +++ b/autoconf/tea/tclconfig/tcl.m4 @@ -4064,4 +4064,4 @@ AC_DEFUN([TEA_ZIPFS_SUPPORT], [ # Local Variables: # mode: autoconf -# End:
\ No newline at end of file +# End: diff --git a/autoconf/tea/win/rules.vc b/autoconf/tea/win/rules.vc index 99471053c..f09e2ea48 100644 --- a/autoconf/tea/win/rules.vc +++ b/autoconf/tea/win/rules.vc @@ -708,4 +708,3 @@ TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" !message *** Link options '$(LINKERFLAGS)' !endif - @@ -10318,7 +10318,20 @@ USE_AMALGAMATION=1 # if not, then we fall back to plain tclsh. # TODO: try other versions before falling back? # -for ac_prog in tclsh8.7 tclsh8.6 tclsh8.5 tclsh +if test x"${with_tcl}" != x; then + if test ! -r ${with_tcl}/tclConfig.sh; then + as_fn_error $? "no tclConfig.sh file found in --with-tcl: ${with_tcl}" "$LINENO" 5 + else + . ${with_tcl}/tclConfig.sh + TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} + if test ! -x ${TCLSH_CMD}; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot use tclsh at: ${TCLSH_CMD}" >&5 +$as_echo "$as_me: WARNING: cannot use tclsh at: ${TCLSH_CMD}" >&2;} + TCLSH_CMD=none + fi + fi +else + for ac_prog in tclsh8.6 tclsh8.5 tclsh do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -10361,6 +10374,7 @@ fi done test -n "$TCLSH_CMD" || TCLSH_CMD="none" +fi if test "$TCLSH_CMD" = "none"; then # If we can't find a local tclsh, then building the amalgamation will fail. # We act as though --disable-amalgamation has been used. @@ -10368,6 +10382,12 @@ if test "$TCLSH_CMD" = "none"; then USE_AMALGAMATION=0 TCLSH_CMD="tclsh" fi +if test x"$TCLSH_CMD" = x; then + as_fn_error $? "cannot find a usable tclsh" "$LINENO" 5 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: using $TCLSH_CMD" >&5 +$as_echo "using $TCLSH_CMD" >&6; } +fi diff --git a/configure.ac b/configure.ac index 54f985fd7..9d8c594ba 100644 --- a/configure.ac +++ b/configure.ac @@ -119,8 +119,21 @@ USE_AMALGAMATION=1 # See whether we can run specific tclsh versions known to work well; # if not, then we fall back to plain tclsh. # TODO: try other versions before falling back? -# -AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.7 tclsh8.6 tclsh8.5 tclsh], none) +# +if test x"${with_tcl}" != x; then + if test ! -r ${with_tcl}/tclConfig.sh; then + AC_MSG_ERROR([no tclConfig.sh file found in --with-tcl: ${with_tcl}]) + else + . ${with_tcl}/tclConfig.sh + TCLSH_CMD=${TCL_EXEC_PREFIX}/bin/tclsh${TCL_VERSION} + if test ! -x ${TCLSH_CMD}; then + AC_MSG_WARN([cannot use tclsh at: ${TCLSH_CMD}]) + TCLSH_CMD=none + fi + fi +else + AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none) +fi if test "$TCLSH_CMD" = "none"; then # If we can't find a local tclsh, then building the amalgamation will fail. # We act as though --disable-amalgamation has been used. @@ -128,6 +141,11 @@ if test "$TCLSH_CMD" = "none"; then USE_AMALGAMATION=0 TCLSH_CMD="tclsh" fi +if test x"$TCLSH_CMD" = x; then + AC_MSG_ERROR([cannot find a usable tclsh]) +else + AC_MSG_RESULT([using $TCLSH_CMD]) +fi AC_SUBST(TCLSH_CMD) AC_ARG_VAR([TCLLIBDIR], [Where to install tcl plugin]) diff --git a/ext/expert/test_expert.c b/ext/expert/test_expert.c index 064c1908a..cae5d0f25 100644 --- a/ext/expert/test_expert.c +++ b/ext/expert/test_expert.c @@ -16,15 +16,7 @@ #include "sqlite3expert.h" #include <assert.h> #include <string.h> - -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/ext/fts3/fts3_term.c b/ext/fts3/fts3_term.c index f3a9746a0..655dd9f35 100644 --- a/ext/fts3/fts3_term.c +++ b/ext/fts3/fts3_term.c @@ -78,6 +78,8 @@ static int fts3termConnectMethod( iIndex = atoi(argv[4]); argc--; } + + *ppVtab = 0; /* The user should specify a single argument - the name of an fts3 table. */ if( argc!=4 ){ @@ -95,12 +97,17 @@ static int fts3termConnectMethod( rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA); if( rc!=SQLITE_OK ) return rc; - nByte = sizeof(Fts3termTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; - p = (Fts3termTable *)sqlite3_malloc64(nByte); + nByte = sizeof(Fts3termTable); + p = (Fts3termTable *)sqlite3Fts3MallocZero(nByte); if( !p ) return SQLITE_NOMEM; - memset(p, 0, (size_t)nByte); - p->pFts3Tab = (Fts3Table *)&p[1]; + p->pFts3Tab = (Fts3Table*)sqlite3Fts3MallocZero( + sizeof(Fts3Table) + nDb + nFts3 + 2 + ); + if( p->pFts3Tab==0 ){ + sqlite3_free(p); + return SQLITE_NOMEM; + } p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1]; p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1]; p->pFts3Tab->db = db; @@ -130,6 +137,7 @@ static int fts3termDisconnectMethod(sqlite3_vtab *pVtab){ sqlite3_finalize(pFts3->aStmt[i]); } sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(pFts3); sqlite3_free(p); return SQLITE_OK; } diff --git a/ext/fts3/fts3_test.c b/ext/fts3/fts3_test.c index 49a8476bf..3c42a7bf0 100644 --- a/ext/fts3/fts3_test.c +++ b/ext/fts3/fts3_test.c @@ -18,14 +18,7 @@ ** that the sqlite3_tokenizer_module.xLanguage() method is invoked correctly. */ -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #include <string.h> #include <assert.h> @@ -167,7 +160,8 @@ static int SQLITE_TCLAPI fts3_near_match_cmd( Tcl_Obj *pPhrasecount = 0; Tcl_Obj **apExprToken; - int nExprToken; + Tcl_Size nExprToken; + Tcl_Size nn; UNUSED_PARAMETER(clientData); @@ -201,23 +195,25 @@ static int SQLITE_TCLAPI fts3_near_match_cmd( } } - rc = Tcl_ListObjGetElements(interp, objv[1], &doc.nToken, &apDocToken); + rc = Tcl_ListObjGetElements(interp, objv[1], &nn, &apDocToken); + doc.nToken = (int)nn; if( rc!=TCL_OK ) goto near_match_out; doc.aToken = (NearToken *)ckalloc(doc.nToken*sizeof(NearToken)); for(ii=0; ii<doc.nToken; ii++){ - doc.aToken[ii].z = Tcl_GetStringFromObj(apDocToken[ii], &doc.aToken[ii].n); + doc.aToken[ii].z = Tcl_GetStringFromObj(apDocToken[ii], &nn); + doc.aToken[ii].n = (int)nn; } rc = Tcl_ListObjGetElements(interp, objv[2], &nExprToken, &apExprToken); if( rc!=TCL_OK ) goto near_match_out; - nPhrase = (nExprToken + 1) / 2; + nPhrase = (int)(nExprToken + 1) / 2; aPhrase = (NearPhrase *)ckalloc(nPhrase * sizeof(NearPhrase)); memset(aPhrase, 0, nPhrase * sizeof(NearPhrase)); for(ii=0; ii<nPhrase; ii++){ Tcl_Obj *pPhrase = apExprToken[ii*2]; Tcl_Obj **apToken; - int nToken; + Tcl_Size nToken; int jj; rc = Tcl_ListObjGetElements(interp, pPhrase, &nToken, &apToken); @@ -227,11 +223,12 @@ static int SQLITE_TCLAPI fts3_near_match_cmd( rc = TCL_ERROR; goto near_match_out; } - for(jj=0; jj<nToken; jj++){ + for(jj=0; jj<(int)nToken; jj++){ NearToken *pT = &aPhrase[ii].aToken[jj]; - pT->z = Tcl_GetStringFromObj(apToken[jj], &pT->n); + pT->z = Tcl_GetStringFromObj(apToken[jj], &nn); + pT->n = (int)nn; } - aPhrase[ii].nToken = nToken; + aPhrase[ii].nToken = (int)nToken; } for(ii=1; ii<nPhrase; ii++){ Tcl_Obj *pNear = apExprToken[2*ii-1]; diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index eab3f513e..24c237a89 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -226,11 +226,7 @@ int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <string.h> /* diff --git a/ext/fts5/fts5.h b/ext/fts5/fts5.h index 551618e71..d3042fcb8 100644 --- a/ext/fts5/fts5.h +++ b/ext/fts5/fts5.h @@ -238,6 +238,10 @@ struct Fts5PhraseIter { ** (i.e. if it is a contentless table), then this API always iterates ** through an empty set (all calls to xPhraseFirst() set iCol to -1). ** +** In all cases, matches are visited in (column ASC, offset ASC) order. +** i.e. all those in column 0, sorted by offset, followed by those in +** column 1, etc. +** ** xPhraseNext() ** See xPhraseFirst above. ** diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 0ed291c95..4311faceb 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -59,6 +59,22 @@ typedef sqlite3_uint64 u64; # define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) # define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) +/* The uptr type is an unsigned integer large enough to hold a pointer +*/ +#if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +#elif SQLITE_PTRSIZE==4 + typedef u32 uptr; +#else + typedef u64 uptr; +#endif + +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&3)==0) +#else +# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0) +#endif + #endif /* Truncate very long tokens to this many bytes. Hard limit is diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 3c7060356..732d4cf89 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1875,6 +1875,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm( }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } + assert( pParse->apPhrase!=0 ); pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase; } @@ -2469,6 +2470,8 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( ); if( pRight->eType==FTS5_EOF ){ + assert( pParse->apPhrase!=0 ); + assert( pParse->nPhrase>0 ); assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 333fefa2d..1f0a68d3e 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -831,11 +831,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); - sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + int szData = (sizeof(Fts5Data) + 7) & ~7; + sqlite3_int64 nAlloc = szData + nByte + FTS5_DATA_PADDING; pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; - aOut = pRet->p = (u8*)&pRet[1]; + aOut = pRet->p = (u8*)pRet + szData; }else{ rc = SQLITE_NOMEM; } @@ -858,6 +859,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ } assert( (pRet==0)==(p->rc!=SQLITE_OK) ); + assert( pRet==0 || EIGHT_BYTE_ALIGNMENT( pRet->p ) ); return pRet; } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index b0072268e..c6e7e346a 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1218,6 +1218,18 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ } /* +** Set the error message on the virtual table passed as the first argument. +*/ +static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ + va_list ap; /* ... printf arguments */ + va_start(ap, zFormat); + sqlite3_free(p->p.base.zErrMsg); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); + va_end(ap); +} + + +/* ** This is the xFilter interface for the virtual table. See ** the virtual table xFilter method documentation for additional ** information. @@ -1392,9 +1404,7 @@ static int fts5FilterMethod( } } }else if( pConfig->zContent==0 ){ - *pConfig->pzErrmsg = sqlite3_mprintf( - "%s: table does not support scanning", pConfig->zName - ); + fts5SetVtabError(pTab,"%s: table does not support scanning",pConfig->zName); rc = SQLITE_ERROR; }else{ /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup @@ -1469,6 +1479,7 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ return SQLITE_OK; } + /* ** If the cursor requires seeking (bSeekRequired flag is set), seek it. ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. @@ -1505,8 +1516,13 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; + fts5SetVtabError((Fts5FullTable*)pTab, + "fts5: missing row %lld from content table %s", + fts5CursorRowid(pCsr), + pTab->pConfig->zContent + ); }else if( pTab->pConfig->pzErrmsg ){ - *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + fts5SetVtabError((Fts5FullTable*)pTab, "%s", sqlite3_errmsg(pTab->pConfig->db) ); } @@ -1515,14 +1531,6 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ return rc; } -static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ - va_list ap; /* ... printf arguments */ - va_start(ap, zFormat); - assert( p->p.base.zErrMsg==0 ); - p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); - va_end(ap); -} - /* ** This function is called to handle an FTS INSERT command. In other words, ** an INSERT statement of the form: @@ -2496,7 +2504,10 @@ static void fts5ApiCallback( sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); }else{ + sqlite3_vtab *pTab = pCsr->base.pVtab; fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); + sqlite3_free(pTab->zErrMsg); + pTab->zErrMsg = 0; } } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index a04b152fb..0b676e6b4 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -447,7 +447,7 @@ static int fts5StorageDeleteFromIndex( zText, nText, (void*)&ctx, fts5StorageInsertCallback ); p->aTotalSize[iCol-1] -= (i64)ctx.szCol; - if( p->aTotalSize[iCol-1]<0 ){ + if( p->aTotalSize[iCol-1]<0 && rc==SQLITE_OK ){ rc = FTS5_CORRUPT; } } diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index c5b5f41f8..b67b037c4 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -14,14 +14,7 @@ #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #ifdef SQLITE_ENABLE_FTS5 @@ -297,12 +290,12 @@ static int SQLITE_TCLAPI xF5tApi( break; } CASE(3, "xTokenize") { - int nText; + Tcl_Size nText; char *zText = Tcl_GetStringFromObj(objv[2], &nText); F5tFunction ctx; ctx.interp = interp; ctx.pScript = objv[3]; - rc = p->pApi->xTokenize(p->pFts, zText, nText, &ctx, xTokenizeCb); + rc = p->pApi->xTokenize(p->pFts, zText, (int)nText, &ctx, xTokenizeCb); if( rc==SQLITE_OK ){ Tcl_ResetResult(interp); } @@ -605,15 +598,16 @@ static void xF5tFunction( sqlite3_result_error(pCtx, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); - int n; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ /* Only return a BLOB type if the Tcl variable is a bytearray and ** has no string representation. */ - unsigned char *data = Tcl_GetByteArrayFromObj(pVar, &n); - sqlite3_result_blob(pCtx, data, n, SQLITE_TRANSIENT); + Tcl_Size nn; + unsigned char *data = Tcl_GetByteArrayFromObj(pVar, &nn); + sqlite3_result_blob(pCtx, data, (int)nn, SQLITE_TRANSIENT); }else if( c=='b' && strcmp(zType,"boolean")==0 ){ + int n; Tcl_GetIntFromObj(0, pVar, &n); sqlite3_result_int(pCtx, n); }else if( c=='d' && strcmp(zType,"double")==0 ){ @@ -626,8 +620,9 @@ static void xF5tFunction( Tcl_GetWideIntFromObj(0, pVar, &v); sqlite3_result_int64(pCtx, v); }else{ - unsigned char *data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); - sqlite3_result_text(pCtx, (char *)data, n, SQLITE_TRANSIENT); + Tcl_Size nn; + unsigned char *data = (unsigned char *)Tcl_GetStringFromObj(pVar, &nn); + sqlite3_result_text(pCtx, (char*)data, (int)nn, SQLITE_TRANSIENT); } } } @@ -720,7 +715,7 @@ static int SQLITE_TCLAPI f5tTokenize( Tcl_Obj *CONST objv[] ){ char *zText; - int nText; + Tcl_Size nText; sqlite3 *db = 0; fts5_api *pApi = 0; Fts5Tokenizer *pTok = 0; @@ -729,7 +724,7 @@ static int SQLITE_TCLAPI f5tTokenize( void *pUserdata; int rc; - int nArg; + Tcl_Size nArg; const char **azArg; F5tTokenizeCtx ctx; @@ -761,7 +756,7 @@ static int SQLITE_TCLAPI f5tTokenize( return TCL_ERROR; } - rc = tokenizer.xCreate(pUserdata, &azArg[1], nArg-1, &pTok); + rc = tokenizer.xCreate(pUserdata, &azArg[1], (int)(nArg-1), &pTok); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "error in tokenizer.xCreate()", 0); return TCL_ERROR; @@ -773,7 +768,7 @@ static int SQLITE_TCLAPI f5tTokenize( ctx.pRet = pRet; ctx.zInput = zText; rc = tokenizer.xTokenize( - pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText, nText, xTokenizeCb2 + pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText,(int)nText, xTokenizeCb2 ); tokenizer.xDelete(pTok); if( rc!=SQLITE_OK ){ @@ -928,13 +923,13 @@ static int SQLITE_TCLAPI f5tTokenizerReturn( F5tTokenizerContext *p = (F5tTokenizerContext*)clientData; int iStart; int iEnd; - int nToken; + Tcl_Size nToken; int tflags = 0; char *zToken; int rc; if( objc==5 ){ - int nArg; + Tcl_Size nArg; char *zArg = Tcl_GetStringFromObj(objv[1], &nArg); if( nArg<=10 && nArg>=2 && memcmp("-colocated", zArg, nArg)==0 ){ tflags |= FTS5_TOKEN_COLOCATED; @@ -959,7 +954,7 @@ static int SQLITE_TCLAPI f5tTokenizerReturn( return TCL_ERROR; } - rc = p->xToken(p->pCtx, tflags, zToken, nToken, iStart, iEnd); + rc = p->xToken(p->pCtx, tflags, zToken, (int)nToken, iStart, iEnd); Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE); return rc==SQLITE_OK ? TCL_OK : TCL_ERROR; @@ -1083,7 +1078,7 @@ static int SQLITE_TCLAPI f5tTokenHash( Tcl_Obj *CONST objv[] ){ char *z; - int n; + Tcl_Size n; unsigned int iVal; int nSlot; @@ -1096,7 +1091,7 @@ static int SQLITE_TCLAPI f5tTokenHash( } z = Tcl_GetStringFromObj(objv[2], &n); - iVal = f5t_fts5HashKey(nSlot, z, n); + iVal = f5t_fts5HashKey(nSlot, z, (int)n); Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal)); return TCL_OK; } diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index a80a307a4..bcad9e724 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -440,7 +440,7 @@ do_execsql_test 16.1 { proc funk {} { db eval { UPDATE n1_config SET v=50 WHERE k='version' } set fd [db incrblob main n1_data block 10] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary # puts -nonewline $fd "\x44\x45" close $fd } @@ -453,7 +453,7 @@ db func funk funk # statement no longer fails. # do_catchsql_test 16.2 { - SELECT funk(), bm25(n1), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' + SELECT funk(), format('%g',bm25(n1)), funk() FROM n1 WHERE n1 MATCH 'a+b+c+d' } {0 {{} -1e-06 {}}} # {1 {SQL logic error}} diff --git a/ext/fts5/test/fts5content.test b/ext/fts5/test/fts5content.test index 5d5d8f919..05b5cc611 100644 --- a/ext/fts5/test/fts5content.test +++ b/ext/fts5/test/fts5content.test @@ -328,4 +328,41 @@ do_execsql_test 8.3.2 { INSERT INTO t1(t1) VALUES('rebuild') } do_execsql_test 8.3.3 { SELECT * FROM t1 WHERE rowid=1 } {one} do_execsql_test 8.3.4 { SELECT rowid FROM t1('two') } {2} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 9.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(1, 'one two three'); + INSERT INTO t1 VALUES(2, 'one two three'); + + CREATE VIRTUAL TABLE ft USING fts5(b, content=t1, content_rowid=a); + INSERT INTO ft(ft) VALUES('rebuild'); +} + +do_execsql_test 9.2 { + SELECT rowid, b FROM ft('two'); +} { + 1 {one two three} + 2 {one two three} +} + +do_execsql_test 9.3 { + DELETE FROM t1 WHERE a=2; +} + +do_catchsql_test 9.4 { + SELECT rowid FROM ft('two'); +} {0 {1 2}} + +do_catchsql_test 9.5 { + SELECT * FROM ft('two'); +} {1 {fts5: missing row 2 from content table 'main'.'t1'}} + +fts5_aux_test_functions db + +do_catchsql_test 9.6 { + SELECT rowid, fts5_columntext(ft, 0) FROM ft('two'); +} {1 SQLITE_CORRUPT_VTAB} + finish_test + diff --git a/ext/fts5/test/fts5contentless5.test b/ext/fts5/test/fts5contentless5.test index b08f810a6..356367886 100644 --- a/ext/fts5/test/fts5contentless5.test +++ b/ext/fts5/test/fts5contentless5.test @@ -20,6 +20,7 @@ ifcapable !fts5 { finish_test return } +unset -nocomplain res do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, content='', contentless_delete=1); diff --git a/ext/fts5/test/fts5corrupt.test b/ext/fts5/test/fts5corrupt.test index 1c7a1a6d0..ae07383b2 100644 --- a/ext/fts5/test/fts5corrupt.test +++ b/ext/fts5/test/fts5corrupt.test @@ -99,6 +99,6 @@ sqlite3_db_config db DEFENSIVE 0 do_catchsql_test 3.1 { DELETE FROM t3_content WHERE rowid = 3; SELECT * FROM t3 WHERE t3 MATCH 'o'; -} {1 {database disk image is malformed}} +} {1 {fts5: missing row 3 from content table 'main'.'t3_content'}} finish_test diff --git a/ext/fts5/test/fts5corrupt2.test b/ext/fts5/test/fts5corrupt2.test index 51141adf0..6b4d6d411 100644 --- a/ext/fts5/test/fts5corrupt2.test +++ b/ext/fts5/test/fts5corrupt2.test @@ -100,6 +100,7 @@ set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}] set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}] set all [db eval {SELECT rowid FROM t1}] sqlite3_db_config db DEFENSIVE 0 +unset -nocomplain res for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} { do_execsql_test 2.$i.1 { BEGIN; @@ -152,7 +153,7 @@ foreach {tn hdr} { execsql BEGIN set fd [db incrblob main x3_data block $rowid] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary set existing [read $fd [string length $hdr]] seek $fd 0 puts -nonewline $fd $hdr @@ -238,7 +239,7 @@ foreach {tn hdr} { execsql BEGIN set fd [db incrblob main x5_data block $rowid] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary puts -nonewline $fd $hdr close $fd diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index b76a9b794..e2a91e51e 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -4267,7 +4267,7 @@ do_test 35.0 { do_catchsql_test 35.1 { SELECT * FROM t1 WHERE t1 MATCH 'e*'; -} {1 {database disk image is malformed}} +} {1 {fts5: missing row 14 from content table 'main'.'t1_content'}} #------------------------------------------------------------------------- reset_db diff --git a/ext/fts5/test/fts5eb.test b/ext/fts5/test/fts5eb.test index b704cf4ec..bee9683c3 100644 --- a/ext/fts5/test/fts5eb.test +++ b/ext/fts5/test/fts5eb.test @@ -86,13 +86,13 @@ do_execsql_test 3.0 { INSERT INTO e1 VALUES ('just a few words with a / inside'); } do_execsql_test 3.1 { - SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank; + SELECT rowid, format('%g',bm25(e1)) FROM e1 WHERE e1 MATCH '"just"' ORDER BY rank; } {1 -1e-06} do_execsql_test 3.2 { SELECT rowid FROM e1 WHERE e1 MATCH '"/" OR "just"' } 1 do_execsql_test 3.3 { - SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank; + SELECT rowid, format('%g',bm25(e1)) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank; } {1 -1e-06} do_execsql_test 3.4 " diff --git a/ext/fts5/test/fts5first.test b/ext/fts5/test/fts5first.test index 357672de6..492681eed 100644 --- a/ext/fts5/test/fts5first.test +++ b/ext/fts5/test/fts5first.test @@ -22,6 +22,7 @@ do_execsql_test 1.0 { CREATE VIRTUAL TABLE x1 USING fts5(a, b); } +unset -nocomplain res foreach {tn expr ok} { 1 {^abc} 1 2 {^abc + def} 1 diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index d1365a47a..5c4002180 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -153,6 +153,7 @@ do_execsql_test 5.3 { INSERT INTO gg(gg) VALUES('integrity-check'); } +unset -nocomplain res do_test 5.4.1 { set ok 0 for {set i 0} {$i < 10000} {incr i} { diff --git a/ext/fts5/test/fts5interrupt.test b/ext/fts5/test/fts5interrupt.test index ca682852c..67ef5f7e9 100644 --- a/ext/fts5/test/fts5interrupt.test +++ b/ext/fts5/test/fts5interrupt.test @@ -33,6 +33,7 @@ proc progress_handler {args} { return 0 } +unset -nocomplain res foreach {tn sql} { 1 { INSERT INTO t1(rowid, a) VALUES(0, 'z z z z') } 2 { COMMIT } @@ -64,4 +65,3 @@ foreach {tn sql} { } finish_test - diff --git a/ext/fts5/test/fts5restart.test b/ext/fts5/test/fts5restart.test index 411433600..da58fe3ae 100644 --- a/ext/fts5/test/fts5restart.test +++ b/ext/fts5/test/fts5restart.test @@ -29,6 +29,7 @@ do_execsql_test 1.0 { # Run the 'optimize' command. Check that it does not disturb ongoing # full-text queries. # +unset -nocomplain lRowid do_test 1.1 { for {set i 1} {$i < 1000} {incr i} { execsql { INSERT INTO f1 VALUES('a b c d e') } diff --git a/ext/fts5/test/fts5unicode.test b/ext/fts5/test/fts5unicode.test index d7fb9670f..f10e0d02d 100644 --- a/ext/fts5/test/fts5unicode.test +++ b/ext/fts5/test/fts5unicode.test @@ -60,6 +60,7 @@ do_execsql_test 2.1 " # require 17 or more bits to store). # +unset -nocomplain A B C D set A [db one {SELECT char(0x1F75E)}] ;# Type So set B [db one {SELECT char(0x1F5FD)}] ;# Type So set C [db one {SELECT char(0x2F802)}] ;# Type Lo diff --git a/ext/fts5/test/fts5unicode2.test b/ext/fts5/test/fts5unicode2.test index 48daf4f10..dccaff0b1 100644 --- a/ext/fts5/test/fts5unicode2.test +++ b/ext/fts5/test/fts5unicode2.test @@ -116,6 +116,7 @@ set docs [list { connected by OR. }] +unset -nocomplain map set map(a) [list "\u00C4" "\u00E4"] ; # LATIN LETTER A WITH DIAERESIS set map(e) [list "\u00CB" "\u00EB"] ; # LATIN LETTER E WITH DIAERESIS set map(i) [list "\u00CF" "\u00EF"] ; # LATIN LETTER I WITH DIAERESIS diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index 9e20180c8..b1644527e 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -513,6 +513,7 @@ do_execsql_test 10.5 { INSERT INTO ft(a) VALUES('4 5 6'); } +unset -nocomplain x res do_test 10.6 { set res [list] db eval { SELECT rowid FROM ft('4') } x { diff --git a/ext/intck/test_intck.c b/ext/intck/test_intck.c index 412c9f201..d3a619b50 100644 --- a/ext/intck/test_intck.c +++ b/ext/intck/test_intck.c @@ -15,13 +15,7 @@ #include "sqlite3.h" #include "sqlite3intck.h" - -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif - +#include "tclsqlite.h" #include <string.h> #include <assert.h> diff --git a/ext/jni/src/org/sqlite/jni/capi/SQLTester.java b/ext/jni/src/org/sqlite/jni/capi/SQLTester.java index 81d6106be..c68785e2c 100644 --- a/ext/jni/src/org/sqlite/jni/capi/SQLTester.java +++ b/ext/jni/src/org/sqlite/jni/capi/SQLTester.java @@ -851,11 +851,26 @@ class JsonBlockCommand extends TableResultCommand { //! --new command class NewDbCommand extends OpenDbCommand { public NewDbCommand(){ super(true); } + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + if(argv.length>1){ + Util.unlink(argv[1]); + } + super.process(t, ts, argv); + } + } -//! Placeholder dummy/no-op commands +//! Placeholder dummy/no-op/unimplemented commands class NoopCommand extends Command { + private boolean verbose = false; + public NoopCommand(boolean verbose){ + this.verbose = verbose; + } + public NoopCommand(){} public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + if( this.verbose ){ + t.outln("Skipping unhandled command: "+argv[0]); + } } } @@ -1021,6 +1036,7 @@ class CommandDispatcher { case "db": rv = new DbCommand(); break; case "glob": rv = new GlobCommand(); break; case "json": rv = new JsonCommand(); break; + case "jsonglob": rv = new NoopCommand(true); break; case "json-block": rv = new JsonBlockCommand(); break; case "new": rv = new NewDbCommand(); break; case "notglob": rv = new NotGlobCommand(); break; @@ -1030,6 +1046,7 @@ class CommandDispatcher { case "print": rv = new PrintCommand(); break; case "result": rv = new ResultCommand(); break; case "run": rv = new RunCommand(); break; + case "stmt-cache": rv = new NoopCommand(); break; case "tableresult": rv = new TableResultCommand(); break; case "testcase": rv = new TestCaseCommand(); break; case "verbosity": rv = new VerbosityCommand(); break; diff --git a/ext/jni/src/org/sqlite/jni/test-script-interpreter.md b/ext/jni/src/org/sqlite/jni/test-script-interpreter.md index a51d64d10..939f77e1b 100644 --- a/ext/jni/src/org/sqlite/jni/test-script-interpreter.md +++ b/ext/jni/src/org/sqlite/jni/test-script-interpreter.md @@ -4,7 +4,7 @@ The purpose of the Test Script Interpreter is to read and interpret script files that contain SQL commands and desired results. The -interpreter will check results and report an discrepencies found. +interpreter will check results and report any discrepencies found. The test script files are ASCII text files. The filename always ends with ".test". Each script is evaluated independently; context does not carry @@ -87,6 +87,7 @@ Each command looks like an SQL comment. The command begins at the left margin (no leading space) and starts with exactly 2 minus signs ("-"). The command name consists of lowercase letters and maybe a "-" or two. Some commands have arguments. + The arguments are separated from the command name by one or more spaces. Commands have access to the input buffer and might reset the input buffer. @@ -159,9 +160,9 @@ the result buffer. This distinction does not matter for the --result command itself, but it is important for related commands like --glob and --notglob. Sometimes test cases will contains a bunch of SQL followed by multiple --glob and/or --notglob statements. All of the -globs should be evaluted agains the result buffer correct, but the SQL -should only be run once. This is accomplished by resetting the input -buffer but not the result buffer. +globs should be evaluated agains the result buffer, but the SQL should +only be run once. This is accomplished by resetting the input buffer +but not the result buffer. ### The --glob command @@ -187,7 +188,7 @@ The TEST-GLOB pattern is slightly different for a standard GLOB: ### The --notglob command The --notglob command works just like --glob except that it reports an -error if the GLOB does match, rather than if the GLOB does not matches. +error if the GLOB does match, rather than if the GLOB does not match. ### The --oom command diff --git a/ext/misc/completion.c b/ext/misc/completion.c index 987595a3d..54abc0ae1 100644 --- a/ext/misc/completion.c +++ b/ext/misc/completion.c @@ -251,7 +251,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){ zSql = sqlite3_mprintf( "%z%s" "SELECT pti.name FROM \"%w\".sqlite_schema AS sm" - " JOIN pragma_table_info(sm.name,%Q) AS pti" + " JOIN pragma_table_xinfo(sm.name,%Q) AS pti" " WHERE sm.type='table'", zSql, zSep, zDb, zDb ); diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index d83bc5b83..cccbaf025 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -57,6 +57,11 @@ ** (12) The percentile(Y,P) is implemented as a single C99 source-code ** file that compiles into a shared-library or DLL that can be loaded ** into SQLite using the sqlite3_load_extension() interface. +** +** (13) A separate median(Y) function is the equivalent percentile(Y,50). +** +** (14) A separate percentile_cond(Y,X) function is the equivalent of +** percentile(Y,X*100.0). */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -103,16 +108,32 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ double rPct; int eType; double y; - assert( argc==2 ); - - /* Requirement 3: P must be a number between 0 and 100 */ - eType = sqlite3_value_numeric_type(argv[1]); - rPct = sqlite3_value_double(argv[1]); - if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) - || rPct<0.0 || rPct>100.0 ){ - sqlite3_result_error(pCtx, "2nd argument to percentile() is not " - "a number between 0.0 and 100.0", -1); - return; + assert( argc==2 || argc==1 ); + + if( argc==1 ){ + /* Requirement 13: median(Y) is the same as percentile(Y,50). */ + rPct = 50.0; + }else if( sqlite3_user_data(pCtx)==0 ){ + /* Requirement 3: P must be a number between 0 and 100 */ + eType = sqlite3_value_numeric_type(argv[1]); + rPct = sqlite3_value_double(argv[1]); + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) + || rPct<0.0 || rPct>100.0 ){ + sqlite3_result_error(pCtx, "2nd argument to percentile() is not " + "a number between 0.0 and 100.0", -1); + return; + } + }else{ + /* Requirement 3: P must be a number between 0 and 1 */ + eType = sqlite3_value_numeric_type(argv[1]); + rPct = sqlite3_value_double(argv[1]); + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) + || rPct<0.0 || rPct>1.0 ){ + sqlite3_result_error(pCtx, "2nd argument to percentile_cont() is not " + "a number between 0.0 and 1.0", -1); + return; + } + rPct *= 100.0; } /* Allocate the session context. */ @@ -165,14 +186,52 @@ static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ } /* -** Compare to doubles for sorting using qsort() +** Sort an array of doubles. */ -static int SQLITE_CDECL doubleCmp(const void *pA, const void *pB){ - double a = *(double*)pA; - double b = *(double*)pB; - if( a==b ) return 0; - if( a<b ) return -1; - return +1; +static void sortDoubles(double *a, int n){ + int iLt; /* Entries with index less than iLt are less than rPivot */ + int iGt; /* Entries with index iGt or more are greater than rPivot */ + int i; /* Loop counter */ + double rPivot; /* The pivot value */ + double rTmp; /* Temporary used to swap two values */ + + if( n<2 ) return; + if( n>5 ){ + rPivot = (a[0] + a[n/2] + a[n-1])/3.0; + }else{ + rPivot = a[n/2]; + } + iLt = i = 0; + iGt = n; + while( i<iGt ){ + if( a[i]<rPivot ){ + if( i>iLt ){ + rTmp = a[i]; + a[i] = a[iLt]; + a[iLt] = rTmp; + } + iLt++; + i++; + }else if( a[i]>rPivot ){ + do{ + iGt--; + }while( iGt>i && a[iGt]>rPivot ); + rTmp = a[i]; + a[i] = a[iGt]; + a[iGt] = rTmp; + }else{ + i++; + } + } + if( iLt>=2 ) sortDoubles(a, iLt); + if( n-iGt>=2 ) sortDoubles(a+iGt, n-iGt); + +/* Uncomment for testing */ +#if 0 + for(i=0; i<n-1; i++){ + assert( a[i]<=a[i+1] ); + } +#endif } /* @@ -188,7 +247,7 @@ static void percentFinal(sqlite3_context *pCtx){ if( p==0 ) return; if( p->a==0 ) return; if( p->nUsed ){ - qsort(p->a, p->nUsed, sizeof(double), doubleCmp); + sortDoubles(p->a, p->nUsed); ix = (p->rPct-1.0)*(p->nUsed-1)*0.01; i1 = (unsigned)ix; i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; @@ -216,5 +275,15 @@ int sqlite3_percentile_init( rc = sqlite3_create_function(db, "percentile", 2, SQLITE_UTF8|SQLITE_INNOCUOUS, 0, 0, percentStep, percentFinal); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "median", 1, + SQLITE_UTF8|SQLITE_INNOCUOUS, 0, + 0, percentStep, percentFinal); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "percentile_cont", 2, + SQLITE_UTF8|SQLITE_INNOCUOUS, &percentStep, + 0, percentStep, percentFinal); + } return rc; } diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index af794d80f..969d6208d 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -17,14 +17,7 @@ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) #include "sqlite3rbu.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #include <assert.h> #include <string.h> @@ -432,11 +425,7 @@ int SqliteRbu_Init(Tcl_Interp *interp){ } #else -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" int SqliteRbu_Init(Tcl_Interp *interp){ return TCL_OK; } #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ #endif /* defined(SQLITE_TEST) */ diff --git a/ext/recover/recovercorrupt4.test b/ext/recover/recovercorrupt4.test index 0ff0b502d..25cfb88fa 100644 --- a/ext/recover/recovercorrupt4.test +++ b/ext/recover/recovercorrupt4.test @@ -34,11 +34,11 @@ if {[permutation]!="inmemory_journal"} { do_test 1.1 { set sz [expr [file size test.db] - 1024] set fd [open test.db] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary set data [read $fd $sz] set fd2 [open test.db2 w] - fconfigure $fd2 -encoding binary -translation binary + fconfigure $fd2 -translation binary puts -nonewline $fd2 $data close $fd2 set {} {} @@ -61,4 +61,3 @@ if {[permutation]!="inmemory_journal"} { } finish_test - diff --git a/ext/recover/recoverpgsz.test b/ext/recover/recoverpgsz.test index 1a91f0845..f921a7869 100644 --- a/ext/recover/recoverpgsz.test +++ b/ext/recover/recoverpgsz.test @@ -39,14 +39,14 @@ foreach {pgsz bOverflow} { set fd [open test.db] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd $pgsz set pg1 [read $fd $pgsz] set pg2 [read $fd $pgsz] close $fd set fd2 [open test.db2 w] - fconfigure $fd2 -encoding binary -translation binary + fconfigure $fd2 -translation binary seek $fd2 $pgsz puts -nonewline $fd2 $pg1 close $fd2 @@ -71,7 +71,7 @@ foreach {pgsz bOverflow} { forcedelete test.db2 set fd2 [open test.db2 w] - fconfigure $fd2 -encoding binary -translation binary + fconfigure $fd2 -translation binary seek $fd2 $pgsz puts -nonewline $fd2 $pg2 close $fd2 @@ -95,6 +95,3 @@ foreach {pgsz bOverflow} { finish_test - - - diff --git a/ext/recover/test_recover.c b/ext/recover/test_recover.c index ba8ef6da1..c1c0d8838 100644 --- a/ext/recover/test_recover.c +++ b/ext/recover/test_recover.c @@ -14,8 +14,7 @@ #include "sqlite3recover.h" #include "sqliteInt.h" - -#include <tcl.h> +#include "tclsqlite.h" #include <assert.h> #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -308,4 +307,3 @@ int TestRecover_Init(Tcl_Interp *interp){ #endif return TCL_OK; } - diff --git a/ext/rtree/test_rtreedoc.c b/ext/rtree/test_rtreedoc.c index cdbcb2e8d..0c042d05a 100644 --- a/ext/rtree/test_rtreedoc.c +++ b/ext/rtree/test_rtreedoc.c @@ -14,11 +14,7 @@ */ #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" @@ -90,7 +86,7 @@ static int invokeTclGeomCb( if( rc!=TCL_OK ){ rc = SQLITE_ERROR; }else{ - int nObj = 0; + Tcl_Size nObj = 0; Tcl_Obj **aObj = 0; pRes = Tcl_GetObjResult(interp); @@ -279,7 +275,7 @@ static int box_query(sqlite3_rtree_query_info *pInfo){ if( rc==SQLITE_OK ){ double rScore = 0.0; - int nObj = 0; + Tcl_Size nObj = 0; int eP = 0; Tcl_Obj **aObj = 0; Tcl_Obj *pRes = Tcl_GetObjResult(interp); diff --git a/ext/session/changesetfuzz1.test b/ext/session/changesetfuzz1.test index 20f5ac6de..d77fd53b9 100644 --- a/ext/session/changesetfuzz1.test +++ b/ext/session/changesetfuzz1.test @@ -27,7 +27,7 @@ if {$CF==""} { proc writefile {zFile data} { set fd [open $zFile w] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary puts -nonewline $fd $data close $fd } @@ -81,4 +81,3 @@ do_test 1.2 { finish_test - diff --git a/ext/session/session4.test b/ext/session/session4.test index de183a69a..55cb76f15 100644 --- a/ext/session/session4.test +++ b/ext/session/session4.test @@ -11,7 +11,10 @@ # This file implements regression tests for the session module. # -package require Tcl 8.6 +if {$tcl_version<8.6} { + puts "This module requires Tcl 8.6 or later" + return +} if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] @@ -136,7 +139,7 @@ foreach {tn blob} { do_test 2.$tn { set changeset [binary decode hex $blob] #set fd [open x.change w+] -#fconfigure $fd -encoding binary -translation binary +#fconfigure $fd -translation binary #puts -nonewline $fd $changeset #close $fd list [catch { sqlite3changeset_apply db $changeset xConflict } msg] $msg diff --git a/ext/session/sessiondiff.test b/ext/session/sessiondiff.test index b00af0eb3..461ce17c9 100644 --- a/ext/session/sessiondiff.test +++ b/ext/session/sessiondiff.test @@ -47,7 +47,7 @@ proc database_cksum {db1} { proc readfile {filename} { set fd [open $filename] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set data [read $fd] close $fd set data diff --git a/ext/session/sessionfault.test b/ext/session/sessionfault.test index 96e966b41..9c1b2b999 100644 --- a/ext/session/sessionfault.test +++ b/ext/session/sessionfault.test @@ -367,6 +367,7 @@ do_execsql_test 7.prep1 { } faultsim_save_and_close +unset -nocomplain res set res [list] for {set ::i 0} {$::i < 480} {incr ::i 4} { lappend res "INSERT t1 0 X. {} {i $::i i $::i}" diff --git a/ext/session/test_session.c b/ext/session/test_session.c index 00c3c2506..79ad000e1 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -5,14 +5,7 @@ #include "sqlite3session.h" #include <assert.h> #include <string.h> -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #ifndef SQLITE_AMALGAMATION typedef unsigned char u8; @@ -517,11 +510,11 @@ struct TestConflictHandler { }; static int test_obj_eq_string(Tcl_Obj *p, const char *z){ - int n; - int nObj; + Tcl_Size n; + Tcl_Size nObj; char *zObj; - n = (int)strlen(z); + n = (Tcl_Size)strlen(z); zObj = Tcl_GetStringFromObj(p, &nObj); return (nObj==n && (n==0 || 0==memcmp(zObj, z, n))); @@ -796,7 +789,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ - int nChangeset; /* Size of buffer aChangeset in bytes */ + Tcl_Size nChangeset; /* Size of buffer aChangeset in bytes */ TestConflictHandler ctx; TestStreamInput sStr; void *pRebase = 0; @@ -853,18 +846,18 @@ static int SQLITE_TCLAPI testSqlite3changesetApply( if( sStr.nStream==0 ){ if( bV2==0 ){ - rc = sqlite3changeset_apply(db, nChangeset, pChangeset, + rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx ); }else{ - rc = sqlite3changeset_apply_v2(db, nChangeset, pChangeset, + rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset, (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx, &pRebase, &nRebase, flags ); } }else{ sStr.aData = (unsigned char*)pChangeset; - sStr.nData = nChangeset; + sStr.nData = (int)nChangeset; if( bV2==0 ){ rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, (objc==5) ? test_filter_handler : 0, @@ -927,7 +920,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply_replace_all( Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ int rc; /* Return code from changeset_invert() */ void *pChangeset; /* Buffer containing changeset */ - int nChangeset; /* Size of buffer aChangeset in bytes */ + Tcl_Size nChangeset; /* Size of buffer aChangeset in bytes */ if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB CHANGESET"); @@ -940,7 +933,8 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply_replace_all( db = *(sqlite3 **)info.objClientData; pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); - rc = sqlite3changeset_apply(db, nChangeset, pChangeset, 0, replace_handler,0); + rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset, + 0, replace_handler,0); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc, 0); } @@ -959,6 +953,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_invert( Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ + Tcl_Size nn; TestStreamInput sIn; /* Input stream */ TestSessionsBlob sOut; /* Output blob */ @@ -970,7 +965,8 @@ static int SQLITE_TCLAPI test_sqlite3changeset_invert( memset(&sIn, 0, sizeof(sIn)); memset(&sOut, 0, sizeof(sOut)); sIn.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); - sIn.aData = Tcl_GetByteArrayFromObj(objv[1], &sIn.nData); + sIn.aData = Tcl_GetByteArrayFromObj(objv[1], &nn); + sIn.nData = (int)nn; if( sIn.nStream ){ rc = sqlite3changeset_invert_strm( @@ -999,6 +995,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat( Tcl_Obj *CONST objv[] ){ int rc; /* Return code from changeset_invert() */ + Tcl_Size nn; TestStreamInput sLeft; /* Input stream */ TestStreamInput sRight; /* Input stream */ @@ -1011,8 +1008,10 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat( memset(&sLeft, 0, sizeof(sLeft)); memset(&sRight, 0, sizeof(sRight)); - sLeft.aData = Tcl_GetByteArrayFromObj(objv[1], &sLeft.nData); - sRight.aData = Tcl_GetByteArrayFromObj(objv[2], &sRight.nData); + sLeft.aData = Tcl_GetByteArrayFromObj(objv[1], &nn); + sLeft.nData = (int)nn; + sRight.aData = Tcl_GetByteArrayFromObj(objv[2], &nn); + sRight.nData = (int)nn; sLeft.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); sRight.nStream = sLeft.nStream; @@ -1106,7 +1105,7 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach( Tcl_Obj *CONST objv[] ){ void *pChangeset; - int nChangeset; + Tcl_Size nChangeset; sqlite3_changeset_iter *pIter; int rc; Tcl_Obj *pVarname; @@ -1148,19 +1147,19 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach( if( isInvert ){ int f = SQLITE_CHANGESETSTART_INVERT; if( sStr.nStream==0 ){ - rc = sqlite3changeset_start_v2(&pIter, nChangeset, pChangeset, f); + rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, f); }else{ void *pCtx = (void*)&sStr; sStr.aData = (unsigned char*)pChangeset; - sStr.nData = nChangeset; + sStr.nData = (int)nChangeset; rc = sqlite3changeset_start_v2_strm(&pIter, testStreamInput, pCtx, f); } }else{ if( sStr.nStream==0 ){ - rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); + rc = sqlite3changeset_start(&pIter, (int)nChangeset, pChangeset); }else{ sStr.aData = (unsigned char*)pChangeset; - sStr.nData = nChangeset; + sStr.nData = (int)nChangeset; rc = sqlite3changeset_start_strm(&pIter, testStreamInput, (void*)&sStr); } } @@ -1237,9 +1236,9 @@ static int SQLITE_TCLAPI test_rebaser_cmd( assert( rc==SQLITE_OK ); switch( iSub ){ case 0: { /* configure */ - int nRebase = 0; + Tcl_Size nRebase = 0; unsigned char *pRebase = Tcl_GetByteArrayFromObj(objv[2], &nRebase); - rc = sqlite3rebaser_configure(p, nRebase, pRebase); + rc = sqlite3rebaser_configure(p, (int)nRebase, pRebase); break; } @@ -1250,10 +1249,12 @@ static int SQLITE_TCLAPI test_rebaser_cmd( default: { /* rebase */ TestStreamInput sStr; /* Input stream */ TestSessionsBlob sOut; /* Output blob */ + Tcl_Size nn; memset(&sStr, 0, sizeof(sStr)); memset(&sOut, 0, sizeof(sOut)); - sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &sStr.nData); + sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &nn); + sStr.nData = nn; sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); if( sStr.nStream ){ @@ -1392,7 +1393,7 @@ static int SQLITE_TCLAPI test_changeset( Tcl_Obj *CONST objv[] ){ void *pChangeset = 0; /* Buffer containing changeset */ - int nChangeset = 0; /* Size of buffer aChangeset in bytes */ + Tcl_Size nChangeset = 0; /* Size of buffer aChangeset in bytes */ int rc = SQLITE_OK; char *z = 0; @@ -1403,7 +1404,7 @@ static int SQLITE_TCLAPI test_changeset( pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[1], &nChangeset); Tcl_ResetResult(interp); - rc = sqlite3_test_changeset(nChangeset, pChangeset, &z); + rc = sqlite3_test_changeset((int)nChangeset, pChangeset, &z); if( rc!=SQLITE_OK ){ char *zErr = sqlite3_mprintf("(%d) - \"%s\"", rc, z); Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); @@ -1528,9 +1529,9 @@ static int SQLITE_TCLAPI test_changegroup_cmd( }; case 1: { /* add */ - int nByte = 0; + Tcl_Size nByte = 0; const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte); - rc = sqlite3changegroup_add(p->pGrp, nByte, (void*)aByte); + rc = sqlite3changegroup_add(p->pGrp, (int)nByte, (void*)aByte); if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); break; }; @@ -1678,7 +1679,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_start( ){ int isInvert = 0; void *pChangeset = 0; /* Buffer containing changeset */ - int nChangeset = 0; /* Size of buffer aChangeset in bytes */ + Tcl_Size nChangeset = 0; /* Size of buffer aChangeset in bytes */ TestChangeIter *pNew = 0; sqlite3_changeset_iter *pIter = 0; int flags = 0; @@ -1688,9 +1689,9 @@ static int SQLITE_TCLAPI test_sqlite3changeset_start( char zCmd[64]; if( objc==3 ){ - int n = 0; + Tcl_Size n = 0; const char *z = Tcl_GetStringFromObj(objv[1], &n); - isInvert = (n>=2 && sqlite3_strnicmp(z, "-invert", n)==0); + isInvert = (n>=2 && sqlite3_strnicmp(z, "-invert", (int)n)==0); } if( objc!=2 && (objc!=3 || !isInvert) ){ @@ -1700,7 +1701,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_start( flags = isInvert ? SQLITE_CHANGESETSTART_INVERT : 0; pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[objc-1], &nChangeset); - rc = sqlite3changeset_start_v2(&pIter, nChangeset, pChangeset, flags); + rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, flags); if( rc!=SQLITE_OK ){ char *zErr = sqlite3_mprintf( "error in sqlite3changeset_start_v2() - %d", rc diff --git a/ext/wasm/GNUmakefile b/ext/wasm/GNUmakefile index d9508e8d7..51531627b 100644 --- a/ext/wasm/GNUmakefile +++ b/ext/wasm/GNUmakefile @@ -233,6 +233,14 @@ SQLITE_OPT = \ # can be used to find errant uses of sqlite3_js_vfs_create_file() # in client code. +######################################################################## +# minimal=1 disables all "extraneous" stuff from sqlite3-wasm.c, the +# goal being to create a WASM file with only the core APIs. +minimal ?= 0 +ifeq (1,$(minimal)) + SQLITE_OPT += -DSQLITE_WASM_MINIMAL +endif + ########################################################################@ # It's important that sqlite3.h be built to completion before any # other parts of the build run, thus we use .NOTPARALLEL to disable @@ -413,11 +421,22 @@ emcc_opt_full := $(emcc_opt) -g3 ######################################################################## # EXPORTED_FUNCTIONS.* = files for use with Emscripten's # -sEXPORTED_FUNCTION flag. -EXPORTED_FUNCTIONS.api.main := $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api) -EXPORTED_FUNCTIONS.api.in := $(EXPORTED_FUNCTIONS.api.main) +EXPORTED_FUNCTIONS.api.core := $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core) +EXPORTED_FUNCTIONS.api.in := $(EXPORTED_FUNCTIONS.api.core) ifeq (1,$(SQLITE_C_IS_SEE)) EXPORTED_FUNCTIONS.api.in += $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see) endif +ifeq (0,$(minimal)) + EXPORTED_FUNCTIONS.api.in += \ + $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-auth) \ + $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-preupdate) \ + $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-session) \ + $(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-vtab) +else + $(info ========================================) + $(info This is a minimal-mode build) + $(info ========================================) +endif EXPORTED_FUNCTIONS.api := $(dir.tmp)/EXPORTED_FUNCTIONS.api $(EXPORTED_FUNCTIONS.api): $(EXPORTED_FUNCTIONS.api.in) $(sqlite3.c) $(MAKEFILE) cat $(EXPORTED_FUNCTIONS.api.in) > $@ @@ -441,21 +460,21 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-prologue.js # Emscripten glue: sqlite3-api.jses += $(dir.common)/whwasmutil.js sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js -# sqlite3-api-glue.js Glues the previous part together: -sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.js +# sqlite3-api-glue Glues the previous part together with sqlite: +sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.c-pp.js # $(sqlite3-api-build-version.js) = library version info sqlite3-api.jses += $(sqlite3-api-build-version.js) -# sqlite3-api-oo1.js = the oo1 API: -sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js -# sqlite3-api-worker.js = the Worker1 API: -sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js +# sqlite3-api-oo1 = the oo1 API: +sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.c-pp.js +# sqlite3-api-worker = the Worker1 API: +sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js # sqlite3-vfs-helper = helper APIs for VFSes: sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js # sqlite3-vtab-helper = helper APIs for VTABLEs: sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js -# sqlite3-vfs-opfs.c-pp.js = the first OPFS VFS: +# sqlite3-vfs-opfs = the first OPFS VFS: sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js -# sqlite3-vfs-opfs-sahpool.c-pp.js = the second OPFS VFS: +# sqlite3-vfs-opfs-sahpool = the second OPFS VFS: sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js # sqlite3-api-cleanup.js = "finalizes" the build and cleans up # any extraneous global symbols which are needed temporarily @@ -1059,9 +1078,9 @@ speedtest1.exit-runtime1 := -sEXIT_RUNTIME=1 # -sEXIT_RUNTIME=1 but we need EXIT_RUNTIME=0 for the worker-based app # which runs speedtest1 multiple times. -$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.main) +$(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.core) @echo "Making $@ ..." - @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.main); } > $@ + @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.core); } > $@ speedtest1.js := $(dir.dout)/speedtest1.js speedtest1.wasm := $(dir.dout)/speedtest1.wasm emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM @@ -1077,6 +1096,7 @@ $(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ $(emcc.speedtest1.common) \ $(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \ $(SQLITE_OPT) \ + -USQLITE_WASM_MINIMAL \ -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \ $(speedtest1.exit-runtime0) \ -o $@ $(speedtest1.cfiles) -lm @@ -1184,7 +1204,7 @@ endif # Push files to public wasm-testing.sqlite.org server wasm-testing.include = *.js *.mjs *.html \ ./tests \ - $(dir.dout) $(dir.common) $(dir.fiddle) $(dir.jacc) + $(dir.dout) $(dir.common) $(dir.fiddle) $(dir.fiddle-debug) $(dir.jacc) wasm-testing.exclude = sql/speedtest1.sql wasm-testing.dir = /jail/sites/wasm-testing wasm-testing.dest ?= wasm-testing:$(wasm-testing.dir) @@ -1233,3 +1253,4 @@ endif # Run local web server for the test/demo pages. httpd: althttpd -max-age 1 -enable-sab 1 -page index.html + diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-auth b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-auth new file mode 100644 index 000000000..085090821 --- /dev/null +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-auth @@ -0,0 +1 @@ +_sqlite3_set_authorizer diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core index 57cd61eb9..db47ee7db 100644 --- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core @@ -10,6 +10,7 @@ _sqlite3_bind_int64 _sqlite3_bind_null _sqlite3_bind_parameter_count _sqlite3_bind_parameter_index +_sqlite3_bind_parameter_name _sqlite3_bind_pointer _sqlite3_bind_text _sqlite3_busy_handler @@ -23,7 +24,7 @@ _sqlite3_collation_needed _sqlite3_column_blob _sqlite3_column_bytes _sqlite3_column_count -_sqlite3_column_count +_sqlite3_column_decltype _sqlite3_column_double _sqlite3_column_int _sqlite3_column_int64 @@ -40,15 +41,13 @@ _sqlite3_create_collation _sqlite3_create_collation_v2 _sqlite3_create_function _sqlite3_create_function_v2 -_sqlite3_create_module -_sqlite3_create_module_v2 _sqlite3_create_window_function _sqlite3_data_count _sqlite3_db_filename _sqlite3_db_handle _sqlite3_db_name +_sqlite3_db_readonly _sqlite3_db_status -_sqlite3_declare_vtab _sqlite3_deserialize _sqlite3_drop_modules _sqlite3_errcode @@ -65,6 +64,8 @@ _sqlite3_free _sqlite3_get_auxdata _sqlite3_get_autocommit _sqlite3_initialize +_sqlite3_interrupt +_sqlite3_is_interrupted _sqlite3_keyword_count _sqlite3_keyword_name _sqlite3_keyword_check @@ -80,12 +81,6 @@ _sqlite3_open_v2 _sqlite3_overload_function _sqlite3_prepare_v2 _sqlite3_prepare_v3 -_sqlite3_preupdate_blobwrite -_sqlite3_preupdate_count -_sqlite3_preupdate_depth -_sqlite3_preupdate_hook -_sqlite3_preupdate_new -_sqlite3_preupdate_old _sqlite3_progress_handler _sqlite3_randomness _sqlite3_realloc @@ -108,7 +103,6 @@ _sqlite3_result_zeroblob _sqlite3_result_zeroblob64 _sqlite3_rollback_hook _sqlite3_serialize -_sqlite3_set_authorizer _sqlite3_set_auxdata _sqlite3_set_last_insert_rowid _sqlite3_shutdown @@ -117,6 +111,8 @@ _sqlite3_sql _sqlite3_status _sqlite3_status64 _sqlite3_step +_sqlite3_stmt_busy +_sqlite3_stmt_explain _sqlite3_stmt_isexplain _sqlite3_stmt_readonly _sqlite3_stmt_status @@ -160,45 +156,3 @@ _sqlite3_vtab_in_next _sqlite3_vtab_nochange _sqlite3_vtab_on_conflict _sqlite3_vtab_rhs_value -_sqlite3changegroup_add -_sqlite3changegroup_add_strm -_sqlite3changegroup_delete -_sqlite3changegroup_new -_sqlite3changegroup_output -_sqlite3changegroup_output_strm -_sqlite3changeset_apply -_sqlite3changeset_apply_strm -_sqlite3changeset_apply_v2 -_sqlite3changeset_apply_v2_strm -_sqlite3changeset_concat -_sqlite3changeset_concat_strm -_sqlite3changeset_conflict -_sqlite3changeset_finalize -_sqlite3changeset_fk_conflicts -_sqlite3changeset_invert -_sqlite3changeset_invert_strm -_sqlite3changeset_new -_sqlite3changeset_next -_sqlite3changeset_old -_sqlite3changeset_op -_sqlite3changeset_pk -_sqlite3changeset_start -_sqlite3changeset_start_strm -_sqlite3changeset_start_v2 -_sqlite3changeset_start_v2_strm -_sqlite3session_attach -_sqlite3session_changeset -_sqlite3session_changeset_size -_sqlite3session_changeset_strm -_sqlite3session_config -_sqlite3session_create -_sqlite3session_delete -_sqlite3session_diff -_sqlite3session_enable -_sqlite3session_indirect -_sqlite3session_isempty -_sqlite3session_memory_used -_sqlite3session_object_config -_sqlite3session_patchset -_sqlite3session_patchset_strm -_sqlite3session_table_filter diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-preupdate b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-preupdate new file mode 100644 index 000000000..5c57a76b6 --- /dev/null +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-preupdate @@ -0,0 +1,6 @@ +_sqlite3_preupdate_blobwrite +_sqlite3_preupdate_count +_sqlite3_preupdate_depth +_sqlite3_preupdate_hook +_sqlite3_preupdate_new +_sqlite3_preupdate_old diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session new file mode 100644 index 000000000..5b7b53f95 --- /dev/null +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session @@ -0,0 +1,42 @@ +_sqlite3changegroup_add +_sqlite3changegroup_add_strm +_sqlite3changegroup_delete +_sqlite3changegroup_new +_sqlite3changegroup_output +_sqlite3changegroup_output_strm +_sqlite3changeset_apply +_sqlite3changeset_apply_strm +_sqlite3changeset_apply_v2 +_sqlite3changeset_apply_v2_strm +_sqlite3changeset_concat +_sqlite3changeset_concat_strm +_sqlite3changeset_conflict +_sqlite3changeset_finalize +_sqlite3changeset_fk_conflicts +_sqlite3changeset_invert +_sqlite3changeset_invert_strm +_sqlite3changeset_new +_sqlite3changeset_next +_sqlite3changeset_old +_sqlite3changeset_op +_sqlite3changeset_pk +_sqlite3changeset_start +_sqlite3changeset_start_strm +_sqlite3changeset_start_v2 +_sqlite3changeset_start_v2_strm +_sqlite3session_attach +_sqlite3session_changeset +_sqlite3session_changeset_size +_sqlite3session_changeset_strm +_sqlite3session_config +_sqlite3session_create +_sqlite3session_delete +_sqlite3session_diff +_sqlite3session_enable +_sqlite3session_indirect +_sqlite3session_isempty +_sqlite3session_memory_used +_sqlite3session_object_config +_sqlite3session_patchset +_sqlite3session_patchset_strm +_sqlite3session_table_filter diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-vtab b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-vtab new file mode 100644 index 000000000..1f6de9682 --- /dev/null +++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-vtab @@ -0,0 +1,11 @@ +_sqlite3_create_module +_sqlite3_create_module_v2 +_sqlite3_declare_vtab +_sqlite3_vtab_collation +_sqlite3_vtab_distinct +_sqlite3_vtab_in +_sqlite3_vtab_in_first +_sqlite3_vtab_in_next +_sqlite3_vtab_nochange +_sqlite3_vtab_on_conflict +_sqlite3_vtab_rhs_value diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.c-pp.js index 83b2ee172..e5eb0cfeb 100644 --- a/ext/wasm/api/sqlite3-api-glue.js +++ b/ext/wasm/api/sqlite3-api-glue.c-pp.js @@ -95,6 +95,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"], ["sqlite3_bind_parameter_count", "int", "sqlite3_stmt*"], ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"], + ["sqlite3_bind_parameter_name", "string", "sqlite3_stmt*", "int"], ["sqlite3_bind_pointer", "int", "sqlite3_stmt*", "int", "*", "string:static", "*"], ["sqlite3_busy_handler","int", [ @@ -115,6 +116,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"], ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"], ["sqlite3_column_count", "int", "sqlite3_stmt*"], + ["sqlite3_column_decltype", "string", "sqlite3_stmt*", "int"], ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"], ["sqlite3_column_int","int", "sqlite3_stmt*", "int"], ["sqlite3_column_name","string", "sqlite3_stmt*", "int"], @@ -152,6 +154,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_db_filename", "string", "sqlite3*", "string"], ["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"], ["sqlite3_db_name", "string", "sqlite3*", "int"], + ["sqlite3_db_readonly", "int", "sqlite3*", "string"], ["sqlite3_db_status", "int", "sqlite3*", "int", "*", "*", "int"], ["sqlite3_errcode", "int", "sqlite3*"], ["sqlite3_errmsg", "string", "sqlite3*"], @@ -192,10 +195,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_get_autocommit", "int", "sqlite3*"], ["sqlite3_get_auxdata", "*", "sqlite3_context*", "int"], ["sqlite3_initialize", undefined], - /*["sqlite3_interrupt", undefined, "sqlite3*" - ^^^ we cannot actually currently support this because JS is - single-threaded and we don't have a portable way to access a DB - from 2 SharedWorkers concurrently. ],*/ + ["sqlite3_interrupt", undefined, "sqlite3*"], + ["sqlite3_is_interrupted", "int", "sqlite3*"], ["sqlite3_keyword_count", "int"], ["sqlite3_keyword_name", "int", ["int", "**", "*"]], ["sqlite3_keyword_check", "int", ["string", "int"]], @@ -243,26 +244,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }), '*' ]], - ["sqlite3_set_authorizer", "int", [ - "sqlite3*", - new wasm.xWrap.FuncPtrAdapter({ - name: "sqlite3_set_authorizer::xAuth", - signature: "i(pi"+"ssss)", - contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/], - callProxy: (callback)=>{ - return (pV, iCode, s0, s1, s2, s3)=>{ - try{ - s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1); - s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3); - return callback(pV, iCode, s0, s1, s2, s3) || 0; - }catch(e){ - return e.resultCode || capi.SQLITE_ERROR; - } - } - } - }), - "*"/*pUserData*/ - ]], ["sqlite3_set_auxdata", undefined, [ "sqlite3_context*", "int", "*", new wasm.xWrap.FuncPtrAdapter({ @@ -276,8 +257,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_sql", "string", "sqlite3_stmt*"], ["sqlite3_status", "int", "int", "*", "*", "int"], ["sqlite3_step", "int", "sqlite3_stmt*"], - ["sqlite3_stmt_isexplain", "int", ["sqlite3_stmt*"]], - ["sqlite3_stmt_readonly", "int", ["sqlite3_stmt*"]], + ["sqlite3_stmt_busy", "int", "sqlite3_stmt*"], + ["sqlite3_stmt_readonly", "int", "sqlite3_stmt*"], ["sqlite3_stmt_status", "int", "sqlite3_stmt*", "int", "int"], ["sqlite3_strglob", "int", "string","string"], ["sqlite3_stricmp", "int", "string", "string"], @@ -322,6 +303,38 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"] ]/*wasm.bindingSignatures*/; + if( !!wasm.exports.sqlite3_stmt_explain ){ + wasm.bindingSignatures.push( + ["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"], + ["sqlite3_stmt_isexplain", "int", "sqlite3_stmt*"] + ); + } + + if( !!wasm.exports.sqlite3_set_authorizer ){ + wasm.bindingSignatures.push( + ["sqlite3_set_authorizer", "int", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: "sqlite3_set_authorizer::xAuth", + signature: "i(pi"+"ssss)", + contextKey: (argv, argIndex)=>argv[0/*(sqlite3*)*/], + callProxy: (callback)=>{ + return (pV, iCode, s0, s1, s2, s3)=>{ + try{ + s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1); + s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3); + return callback(pV, iCode, s0, s1, s2, s3) || 0; + }catch(e){ + return e.resultCode || capi.SQLITE_ERROR; + } + } + } + }), + "*"/*pUserData*/ + ]] + ); + }/* sqlite3_set_authorizer() */ + if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){ /* ^^^ "the problem" is that this is an option feature and the build-time function-export list does not currently take @@ -364,11 +377,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]], ["sqlite3_changes64","i64", ["sqlite3*"]], ["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]], - ["sqlite3_create_module", "int", - ["sqlite3*","string","sqlite3_module*","*"]], - ["sqlite3_create_module_v2", "int", - ["sqlite3*","string","sqlite3_module*","*","*"]], - ["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]], ["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"] /* Careful! Short version: de/serialize() are problematic because they might use a different allocator than the user for managing the @@ -382,26 +390,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ["sqlite3_malloc64", "*","i64"], ["sqlite3_msize", "i64", "*"], ["sqlite3_overload_function", "int", ["sqlite3*","string","int"]], - ["sqlite3_preupdate_blobwrite", "int", "sqlite3*"], - ["sqlite3_preupdate_count", "int", "sqlite3*"], - ["sqlite3_preupdate_depth", "int", "sqlite3*"], - ["sqlite3_preupdate_hook", "*", [ - "sqlite3*", - new wasm.xWrap.FuncPtrAdapter({ - name: 'sqlite3_preupdate_hook', - signature: "v(ppippjj)", - contextKey: (argv)=>argv[0/* sqlite3* */], - callProxy: (callback)=>{ - return (p,db,op,zDb,zTbl,iKey1,iKey2)=>{ - callback(p, db, op, wasm.cstrToJs(zDb), wasm.cstrToJs(zTbl), - iKey1, iKey2); - }; - } - }), - "*" - ]], - ["sqlite3_preupdate_new", "int", ["sqlite3*", "int", "**"]], - ["sqlite3_preupdate_old", "int", ["sqlite3*", "int", "**"]], ["sqlite3_realloc64", "*","*", "i64"], ["sqlite3_result_int64", undefined, "*", "i64"], ["sqlite3_result_zeroblob64", "int", "*", "i64"], @@ -424,21 +412,59 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "*" ]], ["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]], - ["sqlite3_value_int64","i64", "sqlite3_value*"], - ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"], - ["sqlite3_vtab_distinct","int", "sqlite3_index_info*"], - ["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"], - ["sqlite3_vtab_in_first", "int", "sqlite3_value*", "**"], - ["sqlite3_vtab_in_next", "int", "sqlite3_value*", "**"], - /*["sqlite3_vtab_config" is variadic and requires a hand-written - proxy.] */ - ["sqlite3_vtab_nochange","int", "sqlite3_context*"], - ["sqlite3_vtab_on_conflict","int", "sqlite3*"], - ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"] + ["sqlite3_value_int64","i64", "sqlite3_value*"] ]; + if( wasm.bigIntEnabled && !!wasm.exports.sqlite3_declare_vtab ){ + wasm.bindingSignatures.int64.push( + ["sqlite3_create_module", "int", + ["sqlite3*","string","sqlite3_module*","*"]], + ["sqlite3_create_module_v2", "int", + ["sqlite3*","string","sqlite3_module*","*","*"]], + ["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]], + ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"], + ["sqlite3_vtab_distinct","int", "sqlite3_index_info*"], + ["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"], + ["sqlite3_vtab_in_first", "int", "sqlite3_value*", "**"], + ["sqlite3_vtab_in_next", "int", "sqlite3_value*", "**"], + /*["sqlite3_vtab_config" is variadic and requires a hand-written + proxy.] */ + ["sqlite3_vtab_nochange","int", "sqlite3_context*"], + ["sqlite3_vtab_on_conflict","int", "sqlite3*"], + ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"] + ); + }/* virtual table APIs */ + + if(wasm.bigIntEnabled && !!wasm.exports.sqlite3_preupdate_hook){ + wasm.bindingSignatures.int64.push( + ["sqlite3_preupdate_blobwrite", "int", "sqlite3*"], + ["sqlite3_preupdate_count", "int", "sqlite3*"], + ["sqlite3_preupdate_depth", "int", "sqlite3*"], + ["sqlite3_preupdate_hook", "*", [ + "sqlite3*", + new wasm.xWrap.FuncPtrAdapter({ + name: 'sqlite3_preupdate_hook', + signature: "v(ppippjj)", + contextKey: (argv)=>argv[0/* sqlite3* */], + callProxy: (callback)=>{ + return (p,db,op,zDb,zTbl,iKey1,iKey2)=>{ + callback(p, db, op, wasm.cstrToJs(zDb), wasm.cstrToJs(zTbl), + iKey1, iKey2); + }; + } + }), + "*" + ]], + ["sqlite3_preupdate_new", "int", ["sqlite3*", "int", "**"]], + ["sqlite3_preupdate_old", "int", ["sqlite3*", "int", "**"]] + ); + } /* preupdate API */ + // Add session/changeset APIs... - if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){ + if(wasm.bigIntEnabled + && !!wasm.exports.sqlite3changegroup_add + && !!wasm.exports.sqlite3session_create + && !!wasm.exports.sqlite3_preupdate_hook /* required by the session API */){ /** FuncPtrAdapter options for session-related callbacks with the native signature "i(ps)". This proxy converts the 2nd argument @@ -714,12 +740,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ('sqlite3*', (v)=> __xArgPtr((v instanceof (sqlite3?.oo1?.DB || nilType)) ? v.pointer : v)) - ('sqlite3_index_info*', (v)=> - __xArgPtr((v instanceof (capi.sqlite3_index_info || nilType)) - ? v.pointer : v)) - ('sqlite3_module*', (v)=> - __xArgPtr((v instanceof (capi.sqlite3_module || nilType)) - ? v.pointer : v)) /** `sqlite3_vfs*`: @@ -742,6 +762,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return __xArgPtr((v instanceof (capi.sqlite3_vfs || nilType)) ? v.pointer : v); }); + if( wasm.exports.sqlite3_declare_vtab ){ + wasm.xWrap.argAdapter('sqlite3_index_info*', (v)=> + __xArgPtr((v instanceof (capi.sqlite3_index_info || nilType)) + ? v.pointer : v)) + ('sqlite3_module*', (v)=> + __xArgPtr((v instanceof (capi.sqlite3_module || nilType)) + ? v.pointer : v) + ); + } const __xRcPtr = wasm.xWrap.resultAdapter('*'); wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr) @@ -1020,12 +1049,16 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ 'sqlite3_update_hook' ]) { const x = wasm.exports[name]; + if( !x ){ + /* assume it was built without this API */ + continue; + } closeArgs.length = x.length/*==argument count*/ /* recall that undefined entries translate to 0 when passed to WASM. */; try{ capi[name](...closeArgs) } catch(e){ - console.warn("close-time call of",name+"(",closeArgs,") threw:",e); + sqlite3.config.warn("close-time call of",name+"(",closeArgs,") threw:",e); } } const m = __dbCleanupMap(pDb, 0); @@ -1076,7 +1109,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; }/*sqlite3_close_v2()*/ - if(capi.sqlite3session_table_filter){ + if(capi.sqlite3session_create){ const __sqlite3SessionDelete = wasm.xWrap( 'sqlite3session_delete', undefined, ['sqlite3_session*'] ); diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.c-pp.js index e557cbd57..3d6a24c77 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.c-pp.js @@ -82,10 +82,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ /** A map of sqlite3_vfs pointers to SQL code or a callback function to run when the DB constructor opens a database with the given - VFS. In the latter case, the call signature is (theDbObject,sqlite3Namespace) - and the callback is expected to throw on error. + VFS. In the latter case, the call signature is + (theDbObject,sqlite3Namespace) and the callback is expected to + throw on error. */ - const __vfsPostOpenSql = Object.create(null); + const __vfsPostOpenCallback = Object.create(null); //#if enable-see /** @@ -116,7 +117,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ are set. It throws if more than one is set or if any are set to values of an invalid type. - Returns true if it applies the key, else an unspecified falsy value. + Returns true if it applies the key, else an unspecified falsy + value. Note that applying the key does not imply that the key is + correct, only that it was passed on to the db. */ const dbCtorApplySEEKey = function(db,opt){ if( !capi.sqlite3_key_v2 ) return; @@ -178,10 +181,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ try{ stmt = db.prepare("PRAGMA "+keytype+"="+util.sqlite3__wasm_qfmt_token(key, 1)); stmt.step(); + return true; }finally{ if(stmt) stmt.finalize(); } - return true; }; //#endif enable-see @@ -279,7 +282,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ // Check for per-VFS post-open SQL/callback... const pVfs = capi.sqlite3_js_db_vfs(pDb) || toss3("Internal error: cannot get VFS for new db handle."); - const postInitSql = __vfsPostOpenSql[pVfs]; + const postInitSql = __vfsPostOpenCallback[pVfs]; if(postInitSql){ /** Reminder: if this db is encrypted and the client did _not_ pass @@ -303,18 +306,28 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }; /** - Sets SQL which should be exec()'d on a DB instance after it is - opened with the given VFS pointer. The SQL may be any type - supported by the "string:flexible" function argument conversion. - Alternately, the 2nd argument may be a function, in which case it - is called with (theOo1DbObject,sqlite3Namespace) at the end of - the DB() constructor. The function must throw on error, in which - case the db is closed and the exception is propagated. This - function is intended only for use by DB subclasses or sqlite3_vfs + Sets a callback which should be called after a db is opened with + the given sqlite3_vfs pointer. The 2nd argument must be a + function, which gets called with + (theOo1DbObject,sqlite3Namespace) at the end of the DB() + constructor. The function must throw on error, in which case the + db is closed and the exception is propagated. This function is + intended only for use by DB subclasses or sqlite3_vfs implementations. + + Prior to 2024-07-22, it was legal to pass SQL code as the second + argument, but that can interfere with a client's ability to run + pragmas which must be run before anything else, namely (pragma + locking_mode=exclusive) for use with WAL mode. That capability + had only ever been used as an internal detail of the two OPFS + VFSes, and they no longer use it that way. */ - dbCtorHelper.setVfsPostOpenSql = function(pVfs, sql){ - __vfsPostOpenSql[pVfs] = sql; + dbCtorHelper.setVfsPostOpenCallback = function(pVfs, callback){ + if( !(callback instanceof Function)){ + toss3("dbCtorHelper.setVfsPostOpenCallback() should not be used with "+ + "a non-function argument.",arguments); + } + __vfsPostOpenCallback[pVfs] = callback; }; /** @@ -482,6 +495,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ statement's preparation and when it is stepped may invalidate it. - `parameterCount`: the number of bindable parameters in the query. + + As a general rule, most methods of this class will throw if + called on an instance which has been finalized. For brevity's + sake, the method docs do not all repeat this warning. */ const Stmt = function(){ if(BindTypes!==arguments[2]){ @@ -1686,12 +1703,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ integer 0 or 1. It is not expected the distinction of binding doubles which have no fractional parts and integers is significant for the majority of clients due to sqlite3's data - typing model. If [BigInt] support is enabled then this - routine will bind BigInt values as 64-bit integers if they'll - fit in 64 bits. If that support disabled, it will store the - BigInt as an int32 or a double if it can do so without loss - of precision. If the BigInt is _too BigInt_ then it will - throw. + typing model. If BigInt support is enabled then this routine + will bind BigInt values as 64-bit integers if they'll fit in + 64 bits. If that support disabled, it will store the BigInt + as an int32 or a double if it can do so without loss of + precision. If the BigInt is _too BigInt_ then it will throw. - Strings are bound as strings (use bindAsBlob() to force blob binding). @@ -1797,9 +1813,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }, /** Steps the statement one time. If the result indicates that a - row of data is available, a truthy value is returned. - If no row of data is available, a falsy - value is returned. Throws on error. + row of data is available, a truthy value is returned. If no + row of data is available, a falsy value is returned. Throws on + error. */ step: function(){ affirmNotLockedByExec(this, 'step()'); @@ -1819,6 +1835,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Functions exactly like step() except that... 1) On success, it calls this.reset() and returns this object. + 2) On error, it throws and does not call reset(). This is intended to simplify constructs like: @@ -1842,7 +1859,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ throws. On success, it returns true if the step indicated that a row of - data was available, else it returns false. + data was available, else it returns a falsy value. This is intended to simplify use cases such as: @@ -1860,6 +1877,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ catch(e){/*ignored*/} } }, + /** Fetches the value from the given 0-based column index of the current data row, throwing if index is out of range. @@ -1884,7 +1902,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ If ndx is a plain object, this function behaves even differentlier: it assigns the properties of the object to - the values of their corresponding result columns. + the values of their corresponding result columns and returns + that object. Blobs are returned as Uint8Array instances. @@ -2030,6 +2049,39 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return (affirmStmtOpen(this).parameterCount ? capi.sqlite3_bind_parameter_index(this.pointer, name) : undefined); + }, + /** + If this statement has named bindable parameters and the given + index refers to one, its name is returned, else null is + returned. If this statement has no bound parameters, undefined + is returned. + + Added in 3.47. + */ + getParamName: function(ndx){ + return (affirmStmtOpen(this).parameterCount + ? capi.sqlite3_bind_parameter_name(this.pointer, ndx) + : undefined); + }, + + /** + Behaves like sqlite3_stmt_busy() but throws if this statement + is closed and returns a value of type boolean instead of integer. + + Added in 3.47. + */ + isBusy: function(){ + return 0!==capi.sqlite3_stmt_busy(affirmStmtOpen(this)); + }, + + /** + Behaves like sqlite3_stmt_readonly() but throws if this statement + is closed and returns a value of type boolean instead of integer. + + Added in 3.47. + */ + isReadOnly: function(){ + return 0!==capi.sqlite3_stmt_readonly(affirmStmtOpen(this)); } }/*Stmt.prototype*/; diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 689c79ae3..c8db3698c 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1278,9 +1278,10 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( option is not available on the client. Though the mount point name returned by this function is intended - to remain stable, clients should not hard-coded it anywhere. Always call this function to get the path. + to remain stable, clients should not hard-coded it + anywhere. Always call this function to get the path. - Note that this function is a no-op in must builds of this + Note that this function is a no-op in most builds of this library, as the WASMFS capability requires a custom build. */ diff --git a/ext/wasm/api/sqlite3-api-worker1.js b/ext/wasm/api/sqlite3-api-worker1.c-pp.js index 991862545..991862545 100644 --- a/ext/wasm/api/sqlite3-api-worker1.js +++ b/ext/wasm/api/sqlite3-api-worker1.c-pp.js diff --git a/ext/wasm/api/sqlite3-opfs-async-proxy.js b/ext/wasm/api/sqlite3-opfs-async-proxy.js index a2c052d32..ca5583971 100644 --- a/ext/wasm/api/sqlite3-opfs-async-proxy.js +++ b/ext/wasm/api/sqlite3-opfs-async-proxy.js @@ -87,35 +87,6 @@ const installAsyncProxy = function(){ const log = (...args)=>logImpl(2, ...args); const warn = (...args)=>logImpl(1, ...args); const error = (...args)=>logImpl(0, ...args); - const metrics = Object.create(null); - metrics.reset = ()=>{ - let k; - const r = (m)=>(m.count = m.time = m.wait = 0); - for(k in state.opIds){ - r(metrics[k] = Object.create(null)); - } - let s = metrics.s11n = Object.create(null); - s = s.serialize = Object.create(null); - s.count = s.time = 0; - s = metrics.s11n.deserialize = Object.create(null); - s.count = s.time = 0; - }; - metrics.dump = ()=>{ - let k, n = 0, t = 0, w = 0; - for(k in state.opIds){ - const m = metrics[k]; - n += m.count; - t += m.time; - w += m.wait; - m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0; - } - console.log(globalThis?.location?.href, - "metrics for",globalThis?.location?.href,":\n", - metrics, - "\nTotal of",n,"op(s) for",t,"ms", - "approx",w,"ms spent waiting on OPFS APIs."); - console.log("Serialization metrics:",metrics.s11n); - }; /** __openFiles is a map of sqlite3_file pointers (integers) to @@ -373,37 +344,6 @@ const installAsyncProxy = function(){ }; /** - We track 2 different timers: the "metrics" timer records how much - time we spend performing work. The "wait" timer records how much - time we spend waiting on the underlying OPFS timer. See the calls - to mTimeStart(), mTimeEnd(), wTimeStart(), and wTimeEnd() - throughout this file to see how they're used. - */ - const __mTimer = Object.create(null); - __mTimer.op = undefined; - __mTimer.start = undefined; - const mTimeStart = (op)=>{ - __mTimer.start = performance.now(); - __mTimer.op = op; - //metrics[op] || toss("Maintenance required: missing metrics for",op); - ++metrics[op].count; - }; - const mTimeEnd = ()=>( - metrics[__mTimer.op].time += performance.now() - __mTimer.start - ); - const __wTimer = Object.create(null); - __wTimer.op = undefined; - __wTimer.start = undefined; - const wTimeStart = (op)=>{ - __wTimer.start = performance.now(); - __wTimer.op = op; - //metrics[op] || toss("Maintenance required: missing metrics for",op); - }; - const wTimeEnd = ()=>( - metrics[__wTimer.op].wait += performance.now() - __wTimer.start - ); - - /** Gets set to true by the 'opfs-async-shutdown' command to quit the wait loop. This is only intended for debugging purposes: we cannot inspect this file's state while the tight waitLoop() is running and @@ -413,37 +353,24 @@ const installAsyncProxy = function(){ /** Asynchronous wrappers for sqlite3_vfs and sqlite3_io_methods - methods, as well as helpers like mkdir(). Maintenance reminder: - members are in alphabetical order to simplify finding them. + methods, as well as helpers like mkdir(). */ const vfsAsyncImpls = { - 'opfs-async-metrics': async ()=>{ - mTimeStart('opfs-async-metrics'); - metrics.dump(); - storeAndNotify('opfs-async-metrics', 0); - mTimeEnd(); - }, 'opfs-async-shutdown': async ()=>{ flagAsyncShutdown = true; storeAndNotify('opfs-async-shutdown', 0); }, mkdir: async (dirname)=>{ - mTimeStart('mkdir'); let rc = 0; - wTimeStart('mkdir'); try { await getDirForFilename(dirname+"/filepart", true); }catch(e){ state.s11n.storeException(2,e); rc = state.sq3Codes.SQLITE_IOERR; - }finally{ - wTimeEnd(); } storeAndNotify('mkdir', rc); - mTimeEnd(); }, xAccess: async (filename)=>{ - mTimeStart('xAccess'); /* OPFS cannot support the full range of xAccess() queries sqlite3 calls for. We can essentially just tell if the file is accessible, but if it is then it's automatically writable @@ -456,26 +383,20 @@ const installAsyncProxy = function(){ accessible, non-0 means not accessible. */ let rc = 0; - wTimeStart('xAccess'); try{ const [dh, fn] = await getDirForFilename(filename); await dh.getFileHandle(fn); }catch(e){ state.s11n.storeException(2,e); rc = state.sq3Codes.SQLITE_IOERR; - }finally{ - wTimeEnd(); } storeAndNotify('xAccess', rc); - mTimeEnd(); }, xClose: async function(fid/*sqlite3_file pointer*/){ const opName = 'xClose'; - mTimeStart(opName); __implicitLocks.delete(fid); const fh = __openFiles[fid]; let rc = 0; - wTimeStart(opName); if(fh){ delete __openFiles[fid]; await closeSyncHandle(fh); @@ -487,15 +408,11 @@ const installAsyncProxy = function(){ state.s11n.serialize(); rc = state.sq3Codes.SQLITE_NOTFOUND; } - wTimeEnd(); storeAndNotify(opName, rc); - mTimeEnd(); }, xDelete: async function(...args){ - mTimeStart('xDelete'); const rc = await vfsAsyncImpls.xDeleteNoWait(...args); storeAndNotify('xDelete', rc); - mTimeEnd(); }, xDeleteNoWait: async function(filename, syncDir = 0, recursive = false){ /* The syncDir flag is, for purposes of the VFS API's semantics, @@ -511,7 +428,6 @@ const installAsyncProxy = function(){ is false. */ let rc = 0; - wTimeStart('xDelete'); try { while(filename){ const [hDir, filenamePart] = await getDirForFilename(filename, false); @@ -527,14 +443,11 @@ const installAsyncProxy = function(){ state.s11n.storeException(2,e); rc = state.sq3Codes.SQLITE_IOERR_DELETE; } - wTimeEnd(); return rc; }, xFileSize: async function(fid/*sqlite3_file pointer*/){ - mTimeStart('xFileSize'); const fh = __openFiles[fid]; let rc = 0; - wTimeStart('xFileSize'); try{ const sz = await (await getSyncHandle(fh,'xFileSize')).getSize(); state.s11n.serialize(Number(sz)); @@ -543,19 +456,15 @@ const installAsyncProxy = function(){ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR); } await releaseImplicitLock(fh); - wTimeEnd(); storeAndNotify('xFileSize', rc); - mTimeEnd(); }, xLock: async function(fid/*sqlite3_file pointer*/, lockType/*SQLITE_LOCK_...*/){ - mTimeStart('xLock'); const fh = __openFiles[fid]; let rc = 0; const oldLockType = fh.xLock; fh.xLock = lockType; if( !fh.syncHandle ){ - wTimeStart('xLock'); try { await getSyncHandle(fh,'xLock'); __implicitLocks.delete(fid); @@ -564,18 +473,14 @@ const installAsyncProxy = function(){ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK); fh.xLock = oldLockType; } - wTimeEnd(); } storeAndNotify('xLock',rc); - mTimeEnd(); }, xOpen: async function(fid/*sqlite3_file pointer*/, filename, flags/*SQLITE_OPEN_...*/, opfsFlags/*OPFS_...*/){ const opName = 'xOpen'; - mTimeStart(opName); const create = (state.sq3Codes.SQLITE_OPEN_CREATE & flags); - wTimeStart('xOpen'); try{ let hDir, filenamePart; try { @@ -583,8 +488,6 @@ const installAsyncProxy = function(){ }catch(e){ state.s11n.storeException(1,e); storeAndNotify(opName, state.sq3Codes.SQLITE_NOTFOUND); - mTimeEnd(); - wTimeEnd(); return; } if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){ @@ -596,7 +499,6 @@ const installAsyncProxy = function(){ } } const hFile = await hDir.getFileHandle(filenamePart, {create}); - wTimeEnd(); const fh = Object.assign(Object.create(null),{ fid: fid, filenameAbs: filename, @@ -614,60 +516,47 @@ const installAsyncProxy = function(){ __openFiles[fid] = fh; storeAndNotify(opName, 0); }catch(e){ - wTimeEnd(); error(opName,e); state.s11n.storeException(1,e); storeAndNotify(opName, state.sq3Codes.SQLITE_IOERR); } - mTimeEnd(); }, xRead: async function(fid/*sqlite3_file pointer*/,n,offset64){ - mTimeStart('xRead'); let rc = 0, nRead; const fh = __openFiles[fid]; try{ - wTimeStart('xRead'); nRead = (await getSyncHandle(fh,'xRead')).read( fh.sabView.subarray(0, n), {at: Number(offset64)} ); - wTimeEnd(); if(nRead < n){/* Zero-fill remaining bytes */ fh.sabView.fill(0, nRead, n); rc = state.sq3Codes.SQLITE_IOERR_SHORT_READ; } }catch(e){ - if(undefined===nRead) wTimeEnd(); error("xRead() failed",e,fh); state.s11n.storeException(1,e); rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_READ); } await releaseImplicitLock(fh); storeAndNotify('xRead',rc); - mTimeEnd(); }, xSync: async function(fid/*sqlite3_file pointer*/,flags/*ignored*/){ - mTimeStart('xSync'); const fh = __openFiles[fid]; let rc = 0; if(!fh.readOnly && fh.syncHandle){ try { - wTimeStart('xSync'); await fh.syncHandle.flush(); }catch(e){ state.s11n.storeException(2,e); rc = state.sq3Codes.SQLITE_IOERR_FSYNC; } - wTimeEnd(); } storeAndNotify('xSync',rc); - mTimeEnd(); }, xTruncate: async function(fid/*sqlite3_file pointer*/,size){ - mTimeStart('xTruncate'); let rc = 0; const fh = __openFiles[fid]; - wTimeStart('xTruncate'); try{ affirmNotRO('xTruncate', fh); await (await getSyncHandle(fh,'xTruncate')).truncate(size); @@ -677,35 +566,27 @@ const installAsyncProxy = function(){ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_TRUNCATE); } await releaseImplicitLock(fh); - wTimeEnd(); storeAndNotify('xTruncate',rc); - mTimeEnd(); }, xUnlock: async function(fid/*sqlite3_file pointer*/, lockType/*SQLITE_LOCK_...*/){ - mTimeStart('xUnlock'); let rc = 0; const fh = __openFiles[fid]; if( fh.syncHandle && state.sq3Codes.SQLITE_LOCK_NONE===lockType /* Note that we do not differentiate between lock types in this VFS. We're either locked or unlocked. */ ){ - wTimeStart('xUnlock'); try { await closeSyncHandle(fh) } catch(e){ state.s11n.storeException(1,e); rc = state.sq3Codes.SQLITE_IOERR_UNLOCK; } - wTimeEnd(); } storeAndNotify('xUnlock',rc); - mTimeEnd(); }, xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){ - mTimeStart('xWrite'); let rc; const fh = __openFiles[fid]; - wTimeStart('xWrite'); try{ affirmNotRO('xWrite', fh); rc = ( @@ -719,9 +600,7 @@ const installAsyncProxy = function(){ rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_WRITE); } await releaseImplicitLock(fh); - wTimeEnd(); storeAndNotify('xWrite',rc); - mTimeEnd(); } }/*vfsAsyncImpls*/; @@ -755,8 +634,6 @@ const installAsyncProxy = function(){ } }; state.s11n.deserialize = function(clear=false){ - ++metrics.s11n.deserialize.count; - const t = performance.now(); const argc = viewU8[0]; const rc = argc ? [] : null; if(argc){ @@ -781,12 +658,9 @@ const installAsyncProxy = function(){ } if(clear) viewU8[0] = 0; //log("deserialize:",argc, rc); - metrics.s11n.deserialize.time += performance.now() - t; return rc; }; state.s11n.serialize = function(...args){ - const t = performance.now(); - ++metrics.s11n.serialize.count; if(args.length){ //log("serialize():",args); const typeIds = []; @@ -817,7 +691,6 @@ const installAsyncProxy = function(){ }else{ viewU8[0] = 0; } - metrics.s11n.serialize.time += performance.now() - t; }; state.s11n.storeException = state.asyncS11nExceptions @@ -899,7 +772,6 @@ const installAsyncProxy = function(){ } }); initS11n(); - metrics.reset(); log("init state",state); wPost('opfs-async-inited'); waitLoop(); @@ -912,9 +784,6 @@ const installAsyncProxy = function(){ waitLoop(); } break; - case 'opfs-async-metrics': - metrics.dump(); - break; } }; wPost('opfs-async-loaded'); diff --git a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js index 3f4182dac..d423bb0bb 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js @@ -78,8 +78,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ capi.SQLITE_OPEN_MAIN_DB | capi.SQLITE_OPEN_MAIN_JOURNAL | capi.SQLITE_OPEN_SUPER_JOURNAL | - capi.SQLITE_OPEN_WAL /* noting that WAL support is - unavailable in the WASM build.*/; + capi.SQLITE_OPEN_WAL; /** Subdirectory of the VFS's space where "opaque" (randomly-named) files are stored. Changing this effectively invalidates the data @@ -102,7 +101,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ clearOnInit: false, /* Logging verbosity 3+ == everything, 2 == warnings+errors, 1 == errors only. */ - verbosity: 2 + verbosity: 2, + forceReinitIfPreviouslyFailed: false }); /** Logging routines, from most to least serious. */ @@ -1004,9 +1004,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ return true; }; - /** Only for testing a rejection case. */ - let instanceCounter = 0; - /** installOpfsSAHPoolVfs() asynchronously initializes the OPFS SyncAccessHandle (a.k.a. SAH) Pool VFS. It returns a Promise which @@ -1081,12 +1078,26 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ the default directory. If no directory is explicitly provided then a directory name is synthesized from the `name` option. - Peculiarities of this VFS: + + - `forceReinitIfPreviouslyFailed`: (default=`false`) Is a fallback option + to assist in working around certain flaky environments which may + mysteriously fail to permit access to OPFS sync access handles on + an initial attempt but permit it on a second attemp. This option + should never be used but is provided for those who choose to + throw caution to the wind and trust such environments. If this + option is truthy _and_ the previous attempt to initialize this + VFS with the same `name` failed, the VFS will attempt to + initialize a second time instead of returning the cached + failure. See discussion at: + <https://github.com/sqlite/sqlite-wasm/issues/79> + + + Peculiarities of this VFS vis a vis other SQLite VFSes: - Paths given to it _must_ be absolute. Relative paths will not be properly recognized. This is arguably a bug but correcting it requires some hoop-jumping in routines which have no business - doing tricks. + doing such tricks. - It is possible to install multiple instances under different names, each sandboxed from one another inside their own private @@ -1207,13 +1218,25 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ handles are currently in use, e.g. by an sqlite3 db. */ sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){ - const vfsName = options.name || optionDefaults.name; - if(0 && 2===++instanceCounter){ - throw new Error("Just testing rejection."); + options = Object.assign(Object.create(null), optionDefaults, (options||{})); + const vfsName = options.name; + if(options.$testThrowPhase1){ + throw options.$testThrowPhase1; } if(initPromises[vfsName]){ - //console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]); - return initPromises[vfsName]; + try { + const p = await initPromises[vfsName]; + //log("installOpfsSAHPoolVfs() returning cached result",options,vfsName,p); + return p; + }catch(e){ + //log("installOpfsSAHPoolVfs() got cached failure",options,vfsName,e); + if( options.forceReinitIfPreviouslyFailed ){ + delete initPromises[vfsName]; + /* Fall through and try again. */ + }else{ + throw e; + } + } } if(!globalThis.FileSystemHandle || !globalThis.FileSystemDirectoryHandle || @@ -1238,8 +1261,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ ensues. */ return initPromises[vfsName] = apiVersionCheck().then(async function(){ - if(options.$testThrowInInit){ - throw options.$testThrowInInit; + if(options.$testThrowPhase2){ + throw options.$testThrowPhase2; } const thePool = new OpfsSAHPool(options); return thePool.isReady.then(async()=>{ @@ -1255,18 +1278,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ oo1.DB.dbCtorHelper.call(this, opt); }; OpfsSAHPoolDb.prototype = Object.create(oo1.DB.prototype); - // yes or no? OpfsSAHPoolDb.PoolUtil = poolUtil; poolUtil.OpfsSAHPoolDb = OpfsSAHPoolDb; - oo1.DB.dbCtorHelper.setVfsPostOpenSql( - theVfs.pointer, - function(oo1Db, sqlite3){ - sqlite3.capi.sqlite3_exec(oo1Db, [ - /* See notes in sqlite3-vfs-opfs.js */ - "pragma journal_mode=DELETE;", - "pragma cache_size=-16384;" - ], 0, 0, 0); - } - ); }/*extend sqlite3.oo1*/ thePool.log("VFS initialized."); return poolUtil; diff --git a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js index fc0fb9db9..2d11b3583 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js @@ -443,7 +443,7 @@ const installOpfsVfs = function callee(options){ OPFS_UNLINK_BEFORE_OPEN: 0x02, /** If true, any async routine which implicitly acquires a sync - access handle (i.e. an OPFS lock) will release that locks at + access handle (i.e. an OPFS lock) will release that lock at the end of the call which acquires it. If false, such "autolocks" are not released until the VFS is idle for some brief amount of time. @@ -470,9 +470,22 @@ const installOpfsVfs = function callee(options){ Atomics.notify(state.sabOPView, state.opIds.whichOp) /* async thread will take over here */; const t = performance.now(); - Atomics.wait(state.sabOPView, state.opIds.rc, -1) - /* When this wait() call returns, the async half will have - completed the operation and reported its results. */; + while('not-equal'!==Atomics.wait(state.sabOPView, state.opIds.rc, -1)){ + /* + The reason for this loop is buried in the details of a long + discussion at: + + https://github.com/sqlite/sqlite-wasm/issues/12 + + Summary: in at least one browser flavor, under high loads, + the wait()/notify() pairings can get out of sync. Calling + wait() here until it returns 'not-equal' gets them back in + sync. + */ + } + /* When the above wait() call returns 'not-equal', the async + half will have completed the operation and reported its results + in the state.opIds.rc slot of the SAB. */ const rc = Atomics.load(state.sabOPView, state.opIds.rc); metrics[op].wait += performance.now() - t; if(rc && state.asyncS11nExceptions){ @@ -1275,40 +1288,13 @@ const installOpfsVfs = function callee(options){ OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype); sqlite3.oo1.OpfsDb = OpfsDb; OpfsDb.importDb = opfsUtil.importDb; - sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenSql( + sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenCallback( opfsVfs.pointer, function(oo1Db, sqlite3){ /* Set a relatively high default busy-timeout handler to help OPFS dbs deal with multi-tab/multi-worker contention. */ sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000); - sqlite3.capi.sqlite3_exec(oo1Db, [ - /* As of July 2023, the PERSIST journal mode on OPFS is - somewhat slower than DELETE or TRUNCATE (it was faster - before Chrome version 108 or 109). TRUNCATE and DELETE - have very similar performance on OPFS. - - Roy Hashimoto notes that TRUNCATE and PERSIST modes may - decrease OPFS concurrency because multiple connections - can open the journal file in those modes: - - https://github.com/rhashimoto/wa-sqlite/issues/68 - - Given that, and the fact that testing has not revealed - any appreciable difference between performance of - TRUNCATE and DELETE modes on OPFS, we currently (as of - 2023-07-13) default to DELETE mode. - */ - "pragma journal_mode=DELETE;", - /* - This vfs benefits hugely from cache on moderate/large - speedtest1 --size 50 and --size 100 workloads. We - currently rely on setting a non-default cache size when - building sqlite3.wasm. If that policy changes, the cache - can be set here. - */ - "pragma cache_size=-16384;" - ], 0, 0, 0); } ); }/*extend sqlite3.oo1*/ diff --git a/ext/wasm/api/sqlite3-vtab-helper.c-pp.js b/ext/wasm/api/sqlite3-vtab-helper.c-pp.js index 7359ea39a..d78fbdbf3 100644 --- a/ext/wasm/api/sqlite3-vtab-helper.c-pp.js +++ b/ext/wasm/api/sqlite3-vtab-helper.c-pp.js @@ -11,10 +11,14 @@ /** This file installs sqlite3.vtab, a namespace of helpers for use in - the creation of JavaScript implementations virtual tables. + the creation of JavaScript implementations virtual tables. If built + without virtual table support then this function does nothing. */ 'use strict'; globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ + if( !sqlite3.wasm.exports.sqlite3_declare_vtab ){ + return; + } const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3; const vtab = Object.create(null); sqlite3.vtab = vtab; diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index 48ae2297a..7f7e69689 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -104,8 +104,8 @@ #ifndef SQLITE_ENABLE_EXPLAIN_COMMENTS # define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 #endif -#ifndef SQLITE_ENABLE_FTS4 -# define SQLITE_ENABLE_FTS4 1 +#ifndef SQLITE_ENABLE_FTS5 +# define SQLITE_ENABLE_FTS5 1 #endif #ifndef SQLITE_ENABLE_MATH_FUNCTIONS # define SQLITE_ENABLE_MATH_FUNCTIONS 1 @@ -172,6 +172,48 @@ # define SQLITE_EXTRA_INIT sqlite3_wasm_extra_init #endif +/* +** If SQLITE_WASM_MINIMAL is defined, undefine most of the ENABLE +** macros. +*/ +#ifdef SQLITE_WASM_MINIMAL +# undef SQLITE_ENABLE_DBPAGE_VTAB +# undef SQLITE_ENABLE_DBSTAT_VTAB +# undef SQLITE_ENABLE_EXPLAIN_COMMENTS +# undef SQLITE_ENABLE_FTS5 +# undef SQLITE_ENABLE_OFFSET_SQL_FUNC +# undef SQLITE_ENABLE_PREUPDATE_HOOK +# undef SQLITE_ENABLE_RTREE +# undef SQLITE_ENABLE_SESSION +# undef SQLITE_ENABLE_STMTVTAB +# undef SQLITE_OMIT_AUTHORIZATION +# define SQLITE_OMIT_AUTHORIZATION +/*Reminder re. custom sqlite3.c: + + fossil clean -x + ./configure + OPTS='-DSQLITE_OMIT_VIRTUALTABLE -DSQLITE_OMIT_EXPLAIN -DSQLITE_OMIT_TRIGGER' make -e sqlite3 +*/ +/*Requires a custom sqlite3.c +# undef SQLITE_OMIT_TRIGGER +# define SQLITE_OMIT_TRIGGER +*/ +/*TODO (requires build tweaks) +# undef SQLITE_OMIT_WINDOWFUNC +# define SQLITE_OMIT_WINDOWFUNC +*/ +/*Requires a custom sqlite3.c +# undef SQLITE_OMIT_EXPLAIN +# define SQLITE_OMIT_EXPLAIN +*/ +/*Requires a custom sqlite3.c +# undef SQLITE_OMIT_VIRTUALTABLE +# define SQLITE_OMIT_VIRTUALTABLE +*/ +# undef SQLITE_OMIT_JSON +# define SQLITE_OMIT_JSON +#endif + #include <assert.h> /* @@ -499,6 +541,7 @@ const char * sqlite3__wasm_enum_json(void){ } _DefGroup; DefGroup(changeset){ +#ifdef SQLITE_CHANGESETSTART_INVERT DefInt(SQLITE_CHANGESETSTART_INVERT); DefInt(SQLITE_CHANGESETAPPLY_NOSAVEPOINT); DefInt(SQLITE_CHANGESETAPPLY_INVERT); @@ -513,6 +556,7 @@ const char * sqlite3__wasm_enum_json(void){ DefInt(SQLITE_CHANGESET_OMIT); DefInt(SQLITE_CHANGESET_REPLACE); DefInt(SQLITE_CHANGESET_ABORT); +#endif } _DefGroup; DefGroup(config){ @@ -564,7 +608,6 @@ const char * sqlite3__wasm_enum_json(void){ DefInt(SQLITE_DBCONFIG_LOOKASIDE); DefInt(SQLITE_DBCONFIG_ENABLE_FKEY); DefInt(SQLITE_DBCONFIG_ENABLE_TRIGGER); - DefInt(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER); DefInt(SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION); DefInt(SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE); DefInt(SQLITE_DBCONFIG_ENABLE_QPSG); @@ -859,8 +902,10 @@ const char * sqlite3__wasm_enum_json(void){ } _DefGroup; DefGroup(session){ +#ifdef SQLITE_SESSION_CONFIG_STRMSIZE DefInt(SQLITE_SESSION_CONFIG_STRMSIZE); DefInt(SQLITE_SESSION_OBJCONFIG_SIZE); +#endif } _DefGroup; DefGroup(sqlite3Status){ @@ -922,6 +967,7 @@ const char * sqlite3__wasm_enum_json(void){ } _DefGroup; DefGroup(vtab) { +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL) DefInt(SQLITE_INDEX_SCAN_UNIQUE); DefInt(SQLITE_INDEX_CONSTRAINT_EQ); DefInt(SQLITE_INDEX_CONSTRAINT_GT); @@ -949,6 +995,7 @@ const char * sqlite3__wasm_enum_json(void){ DefInt(SQLITE_FAIL); //DefInt(SQLITE_ABORT); // Also an error code DefInt(SQLITE_REPLACE); +#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ } _DefGroup; #undef DefGroup @@ -1108,6 +1155,7 @@ const char * sqlite3__wasm_enum_json(void){ } _StructBinder; #undef CurrentStruct +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL) /** ** Workaround: in order to map the various inner structs from ** sqlite3_index_info, we have to uplift those into constructs we @@ -1184,6 +1232,8 @@ const char * sqlite3__wasm_enum_json(void){ } _StructBinder; #undef CurrentStruct +#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ + #if SQLITE_WASM_TESTS #define CurrentStruct WasmTestStruct StructBinder { @@ -1553,6 +1603,7 @@ sqlite3_kvvfs_methods * sqlite3__wasm_kvvfs_methods(void){ return &sqlite3KvvfsMethods; } +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL) /* ** This function is NOT part of the sqlite3 public API. It is strictly ** for use by the sqlite project's own JS/WASM bindings. @@ -1575,6 +1626,7 @@ int sqlite3__wasm_vtab_config(sqlite3 *pDb, int op, int arg){ return SQLITE_MISUSE; } } +#endif /*!SQLITE_OMIT_VIRTUALTABLE*/ /* ** This function is NOT part of the sqlite3 public API. It is strictly diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index 97cf189b0..1f0d9e2ad 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -42,6 +42,7 @@ fiddle.emcc-flags = \ -sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \ -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \ $(SQLITE_OPT) $(SHELL_OPT) \ + -USQLITE_WASM_MINIMAL \ -DSQLITE_SHELL_FIDDLE # -D_POSIX_C_SOURCE is needed for strdup() with emcc @@ -69,11 +70,10 @@ $(eval $(call call-make-pre-post,fiddle-module,vanilla)) define make-fiddle-rules fiddle-module.js$(2) := $(1)/fiddle-module.js fiddle-module.wasm$(2) := $$(subst .js,.wasm,$$(fiddle-module.js$(2))) -$(1): - @test -d "$$@" || mkdir -p "$$@" -$$(fiddle-module.js$(2)): $(1) $$(MAKEFILE) $$(MAKEFILE.fiddle) \ +$$(fiddle-module.js$(2)): $$(MAKEFILE) $$(MAKEFILE.fiddle) \ $$(EXPORTED_FUNCTIONS.fiddle) \ - $$(fiddle.cses) $$(pre-post-fiddle-module-vanilla.deps) $$(fiddle.SOAP.js$(2)) + $$(fiddle.cses) $$(pre-post-fiddle-module-vanilla.deps) $$(SOAP.js) + @test -d "$$(dir $$@)" || mkdir -p "$$(dir $$@)" $$(emcc.bin) -o $$@ $$(fiddle.emcc-flags$(2)) \ $$(pre-post-fiddle-module-vanilla.flags) \ $$(fiddle.cses) @@ -99,10 +99,10 @@ fiddle.debug: $(fiddle-module.js.debug) clean: clean-fiddle clean-fiddle: - rm -f $(fiddle-module.js) $(fiddle-module.js).gz \ - $(fiddle-module.wasm) $(fiddle-module.wasm).gz \ - $(dir.fiddle)/$(SOAP.js) \ - $(dir.fiddle)/fiddle-module.worker.js \ + rm -f $(fiddle-module.js) \ + $(fiddle-module.wasm) \ + $(dir.fiddle)/sqlite3-opfs-*.js \ + $(dir.fiddle)/*.gz \ EXPORTED_FUNCTIONS.fiddle rm -fr $(dir.fiddle-debug) .PHONY: fiddle fiddle.debug diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js index fe5bdc837..c49a82d36 100644 --- a/ext/wasm/tester1.c-pp.js +++ b/ext/wasm/tester1.c-pp.js @@ -461,7 +461,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; try{ sqlite3.SQLite3Error.toss("resultCode check") } catch(e){ T.assert(capi.SQLITE_ERROR === e.resultCode) - .assert('resultCode check' === e.message); + .assert('resultCode check' === e.message); } }) //////////////////////////////////////////////////////////////////// @@ -1475,7 +1475,8 @@ globalThis.sqlite3InitModule = sqlite3InitModule; let st = db.prepare("update t set b=:b where a='blob'"); try { - T.assert(0===st.columnCount); + T.assert(0===st.columnCount) + .assert( false===st.isReadOnly() ); const ndx = st.getParamIndex(':b'); T.assert(1===ndx); st.bindAsBlob(ndx, "ima blob") @@ -1509,6 +1510,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //////////////////////////////////////////////////////////////////// .t({ name: "sqlite3_set_authorizer()", + predicate: ()=>!!wasm.exports.sqlite3_set_authorizer || "Missing sqlite3_set_authorizer()", test:function(sqlite3){ T.assert(capi.SQLITE_IGNORE>0) .assert(capi.SQLITE_DENY>0); @@ -2064,6 +2066,15 @@ globalThis.sqlite3InitModule = sqlite3InitModule; }) //////////////////////////////////////////////////////////////////// + .t("Read-only", function(sqlite3){ + T.assert( 0===capi.sqlite3_db_readonly(this.db, "main") ); + const db = new sqlite3.oo1.DB('file://'+this.db.filename+'?mode=ro'); + T.assert( 1===capi.sqlite3_db_readonly(db, "main") ); + T.assert( -1===capi.sqlite3_db_readonly(db, "nope") ); + db.close(); + }) + + //////////////////////////////////////////////////////////////////// .t({ name: 'C-side WASM tests', predicate: ()=>(haveWasmCTests() || "Not compiled in."), @@ -2142,7 +2153,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //////////////////////////////////////////////////////////////////////// .t({ name: 'virtual table #1: eponymous w/ manual exception handling', - predicate: ()=>!!capi.sqlite3_index_info, + predicate: ()=>!!capi.sqlite3_create_module || "Missing vtab support", test: function(sqlite3){ const VT = sqlite3.vtab; const tmplCols = Object.assign(Object.create(null),{ @@ -2339,7 +2350,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; //////////////////////////////////////////////////////////////////////// .t({ name: 'virtual table #2: non-eponymous w/ automated exception wrapping', - predicate: ()=>!!capi.sqlite3_index_info, + predicate: ()=>!!capi.sqlite3_create_module || "Missing vtab support", test: function(sqlite3){ const VT = sqlite3.vtab; const tmplCols = Object.assign(Object.create(null),{ @@ -2751,7 +2762,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; })/* commit/rollback/update hooks */ .t({ name: "sqlite3_preupdate_hook()", - predicate: ()=>wasm.bigIntEnabled || "Pre-update hook requires int64", + predicate: ()=>capi.sqlite3_preupdate_hook || "Missing pre-update hook API", test: function(sqlite3){ const db = new sqlite3.oo1.DB(':memory:', 1 ? 'c' : 'ct'); const countHook = Object.create(null); @@ -2822,9 +2833,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.g('Session API') .t({ name: 'Session API sanity checks', - predicate: ()=>!!capi.sqlite3changegroup_add, + predicate: ()=>!!capi.sqlite3changegroup_add || "Missing session API", test: function(sqlite3){ - warn("The session API tests could use some expansion."); + //warn("The session API tests could use some expansion."); const db1 = new sqlite3.oo1.DB(), db2 = new sqlite3.oo1.DB(); const sqlInit = [ "create table t(rowid INTEGER PRIMARY KEY,a,b); ", @@ -2859,7 +2870,9 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .assert('b4' === db1.selectValue('select b from t where rowid=4')) .assert(3 === db1.selectValue('select count(*) from t')); - const testSessionEnable = false; + const testSessionEnable = + false /* it's not yet clear whether these test failures are + broken tests or broken bindings. */; if(testSessionEnable){ rc = capi.sqlite3session_enable(pSession, 0); T.assert( 0 === rc ) @@ -2870,7 +2883,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .assert( capi.sqlite3session_enable(pSession, -1) > 0 ) .assert(undefined === db1.selectValue('select a from t where rowid=2')); }else{ - warn("sqlite3session_enable() tests are currently disabled."); + //warn("sqlite3session_enable() tests are currently disabled."); } let db1Count = db1.selectValue("select count(*) from t"); T.assert( db1Count === (testSessionEnable ? 2 : 3) ); @@ -3101,11 +3114,25 @@ globalThis.sqlite3InitModule = sqlite3InitModule; T.assert(db instanceof sqlite3.oo1.DB) .assert(1 === u1.getFileCount()); db.exec([ + 'pragma locking_mode=exclusive;', + 'pragma journal_mode=wal;' + /* WAL mode only works in this VFS if locking_mode=exclusive + is invoked prior to the first db access, as this build + does not have the shared-memory APIs needed for WAL without + exclusive-mode locking. See: + + https://sqlite.org/wal.html#use_of_wal_without_shared_memory + + Note that WAL mode here DOES NOT add any concurrency capabilities + to this VFS, but it MAY provide slightly improved performance + over the other journaling modes. + */, 'create table t(a);', 'insert into t(a) values(1),(2),(3)' ]); - T.assert(1 === u1.getFileCount()); - T.assert(3 === db.selectValue('select count(*) from t')); + T.assert(2 === u1.getFileCount() /* one is the journal file */) + .assert(3 === db.selectValue('select count(*) from t')) + .assert('wal'===db.selectValue('pragma journal_mode')); db.close(); T.assert(1 === u1.getFileCount()); db = new u2.OpfsSAHPoolDb(dbName); @@ -3125,6 +3152,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .assert( dbytes.byteLength == nWrote ); let db2 = new u1.OpfsSAHPoolDb(dbName2); T.assert(db2 instanceof sqlite3.oo1.DB) + .assert('wal' !== db2.selectValue("pragma journal_mode") + /* importDb() unsets the WAL-mode header for + historical reasons. Because clients must + explicitly enable pragma locking_mode=exclusive + before using WAL, that behavior is retained. */) .assert(3 === db2.selectValue('select count(*) from t')); db2.close(); T.assert(true === u1.unlink(dbName2)) @@ -3177,20 +3209,108 @@ globalThis.sqlite3InitModule = sqlite3InitModule; .assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name)); let cErr, u3; - conf2.$testThrowInInit = new Error("Testing throwing during init."); + conf2.$testThrowPhase2 = new Error("Testing throwing during init."); conf2.name = sahPoolConfig.name+'-err'; const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e); - T.assert(P3 === conf2.$testThrowInInit) + T.assert(P3 === conf2.$testThrowPhase2) .assert(cErr === P3) .assert(undefined === u3) .assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name)); + delete conf2.$testThrowPhase2; + T.assert(cErr === await inst(conf2).catch(e=>e), + "Init result is cached even if it failed"); + + /* Ensure that the forceReinitIfPreviouslyFailed fallback bypasses + the VFS init cache... */ + cErr = u3 = undefined; + conf2.forceReinitIfPreviouslyFailed = true; + conf2.verbosity = 3; + const P3b = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e); + T.assert(undefined === cErr) + .assert(P3b === u3) + .assert(P3b === await inst(conf2)) + .assert(true === await u3.removeVfs()) + .assert(false === await P3b.removeVfs()); } }/*OPFS SAH Pool sanity checks*/) //////////////////////////////////////////////////////////////////////// + T.g('Misc. APIs') + .t('bind_parameter_...', function(sqlite3){ + const db = new sqlite3.oo1.DB(); + db.exec("create table t(a)"); + const stmt = db.prepare("insert into t(a) values($a)"); + T.assert( 1===capi.sqlite3_bind_parameter_count(stmt) ) + .assert( 1===capi.sqlite3_bind_parameter_index(stmt, "$a") ) + .assert( 0===capi.sqlite3_bind_parameter_index(stmt, ":a") ) + .assert( 1===stmt.getParamIndex("$a") ) + .assert( 0===stmt.getParamIndex(":a") ) + .assert( "$a"===capi.sqlite3_bind_parameter_name(stmt, 1) ) + .assert( null===capi.sqlite3_bind_parameter_name(stmt, 0) ) + .assert( "$a"===stmt.getParamName(1) ) + .assert( null===stmt.getParamName(0) ); + stmt.finalize(); + db.close(); + }) + + //////////////////////////////////////////////////////////////////// + .t("Misc. stmt_...", function(sqlite3){ + const db = new sqlite3.oo1.DB(); + db.exec("create table t(a doggiebiscuits); insert into t(a) values(123)"); + const stmt = db.prepare("select a, a+1 from t"); + T.assert( stmt.isReadOnly() ) + .assert( 0===capi.sqlite3_stmt_isexplain(stmt) ) + .assert( 0===capi.sqlite3_stmt_explain(stmt, 1) ) + .assert( 0!==capi.sqlite3_stmt_isexplain(stmt) ) + .assert( 0===capi.sqlite3_stmt_explain(stmt, 2) ) + .assert( 0!==capi.sqlite3_stmt_isexplain(stmt) ) + .assert( 0===capi.sqlite3_stmt_explain(stmt, 0) ) + .assert( 0===capi.sqlite3_stmt_isexplain(stmt) ); + let n = 0; + while( capi.SQLITE_ROW === capi.sqlite3_step(stmt) ){ + ++n; + T.assert( 0!==capi.sqlite3_stmt_explain(stmt, 1), + "Because stmt is busy" ) + .assert( capi.sqlite3_stmt_busy(stmt) ) + .assert( stmt.isBusy() ) + .assert( 0!==capi.sqlite3_stmt_readonly(stmt) ) + .assert( true===stmt.isReadOnly() ); + const sv = capi.sqlite3_column_value(stmt, 0); + T.assert( 123===capi.sqlite3_value_int(sv) ) + .assert( "doggiebiscuits"===capi.sqlite3_column_decltype(stmt,0) ) + .assert( null===capi.sqlite3_column_decltype(stmt,1) ); + } + T.assert( 1===n ) + .assert( 0===capi.sqlite3_stmt_busy(stmt) ) + .assert( !stmt.isBusy() ); + stmt.finalize(); + db.close(); + }) + + //////////////////////////////////////////////////////////////////// + .t("interrupt", function(sqlite3){ + const db = new sqlite3.oo1.DB(); + T.assert( 0===capi.sqlite3_is_interrupted(db) ); + capi.sqlite3_interrupt(db); + T.assert( 0!==capi.sqlite3_is_interrupted(db) ); + db.close(); + }) + + //////////////////////////////////////////////////////////////////////// T.g('Bug Reports') .t({ name: 'Delete via bound parameter in subquery', + predicate: function(sqlite3){ + const d = new sqlite3.oo1.DB(); + try{ + d.exec("create virtual table f using fts5(x)"); + return true; + }catch(e){ + return "FTS5 is not available"; + }finally{ + d.close(); + } + }, test: function(sqlite3){ // Testing https://sqlite.org/forum/forumpost/40ce55bdf5 // with the exception that that post uses "external content" diff --git a/ext/wasm/tests/opfs/concurrency/index.html b/ext/wasm/tests/opfs/concurrency/index.html index 595ab2452..54ed04a4f 100644 --- a/ext/wasm/tests/opfs/concurrency/index.html +++ b/ext/wasm/tests/opfs/concurrency/index.html @@ -35,6 +35,9 @@ re-opening the tab usually resolves it, but sometimes restarting the browser is required. </p> + <p> + Links for various testing options: <ul id='testlinks'></ul> + </p> <div class='input-wrapper'> <input type='checkbox' id='cb-log-reverse'> <label for='cb-log-reverse'>Reverse log order?</label> diff --git a/ext/wasm/tests/opfs/concurrency/test.js b/ext/wasm/tests/opfs/concurrency/test.js index 14cd6f514..1848901af 100644 --- a/ext/wasm/tests/opfs/concurrency/test.js +++ b/ext/wasm/tests/opfs/concurrency/test.js @@ -113,6 +113,31 @@ } }; + /* Set up links to launch this tool with various combinations of + flags... */ + const eTestLinks = document.querySelector('#testlinks'); + const optArgs = function(obj){ + const li = []; + for(const k of ['interval','iterations','workers','verbose','unlock-asap']){ + if( obj.hasOwnProperty(k) ) li.push(k+'='+obj[k]); + } + return li.join('&'); + }; + for(const opt of [ + {interval: 1000, workers: 5, iterations: 30}, + {interval: 500, workers: 5, iterations: 30}, + {interval: 250, workers: 3, iterations: 30}, + {interval: 600, workers: 5, iterations: 100} + ]){ + const li = document.createElement('li'); + eTestLinks.appendChild(li); + const a = document.createElement('a'); + li.appendChild(a); + const args = optArgs(opt); + a.setAttribute('href', '?'+args); + a.innerText = args; + } + stdout("Launching",options.workerCount,"workers. Options:",options); workers.uri = ( 'worker.js?' @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sexists-to-join\sbranch. -D 2024-06-27T14:54:15.037 +C Merge\sall\sthe\slatest\strunk\senhancements\sinto\sthe\sexists-to-join\sbranch. +D 2024-07-31T23:46:10.492 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -29,14 +29,14 @@ F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce F autoconf/tea/tclconfig/install-sh bdd5e293591621ae60d9824d86a4b1c5f22c3d00 -F autoconf/tea/tclconfig/tcl.m4 debe13280bd5a9d76dc34e7919cd9ed3a1408c7320400900357128c2d1abb723 +F autoconf/tea/tclconfig/tcl.m4 c6e5f2fc7178f40d087403daa044ef3b86a8e30793f3b121bdcbdf152c6a776a F autoconf/tea/win/makefile.vc 2c478a9a962e48b2bf9062734e04d7c63c556e217095419173f9d7938d7d78f7 F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea00342d1a1a7eaa19cb -F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 +F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 27d144c2edfa993ac155a2ad5e6b431e4ec811159598ef55a59f345bc2e5e533 x -F configure.ac f25bd7843120f2c2b8bc9db5a92b0502bbdd28e68907415c3d42fc8e57c657b9 +F configure e0efd210b151971f4158e3fdf93b34322882a668a96f88b6167a6f7a51edebec x +F configure.ac 7361a1dd862c0ba0d2daa3d978bc3b93fcccc1ef3efe204d0238722c19bbdcf5 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d @@ -60,7 +60,7 @@ F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3 F ext/expert/expert1.test 53a749de08939e3bc14f804e97410927d46fa772cbce0247d7e8fa6fc2523b0c F ext/expert/sqlite3expert.c c8cea5ff15fbe792cccc4992a9b40b706411c41d32611f617897fecac6ff06a4 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b -F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 +F ext/expert/test_expert.c b767b2039a0df707eb3147e86bcf68b252d8455d9a41774b1a836cd052ceca70 F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d @@ -75,10 +75,10 @@ F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8 F ext/fts3/fts3_snippet.c 610328fe128c047c6b0eba77768982ccf3933daae095d497949a75c9dfd47409 -F ext/fts3/fts3_term.c 845f0e2456b1be42f7f1bec1da1dfc05bc347531eff90775ffc6698902c281de -F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454 +F ext/fts3/fts3_term.c 6a96027ad364001432545fe43322b6af04ed28bb5619ec51af1f59d0710d6d69 +F ext/fts3/fts3_test.c 7a9cb3d61774134211bf4bfdf1adcb581a1a0377f2d050a121ae7ab44baef0e3 F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962 -F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 +F ext/fts3/fts3_tokenizer.c defede96b5dd5d658edfae77355b9c31ea65236eedc7bbe1adbc50d645cca5bc F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154 F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226 @@ -92,17 +92,17 @@ F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7 F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6dbd6348ef0cfc324a7 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl bc3a0ca78be7d3df08e7602c00ca48021ebae40682d75eb001bfdf6e54ffb44e -F ext/fts5/fts5.h 8856e11a5f0269cd346754cea0765efe8089635b80cad3222e8bfdb08cd5348a -F ext/fts5/fts5Int.h 407ee36addad0ae6df5d37a811f0bd509ab6708b29640884ed5c7509e5f75143 +F ext/fts5/fts5.h 6b49ce6eb2e395e7fd84557b21d32f5de8041f2fada4c617e481e99427e24b6e +F ext/fts5/fts5Int.h 41fb3a2dd40e818cc96c6f4176dbdf2aaa8f57043cfc9a8f2676e7e6a72ad764 F ext/fts5/fts5_aux.c 4584e88878e54828bf7d4d0d83deedd232ec60628b7731be02bad6adb62304b1 F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09 F ext/fts5/fts5_config.c 68cb87a49215f8e7028000b681df4057c430a4a6afbd676463886da94c9e1c37 -F ext/fts5/fts5_expr.c fb26894f8dd1081afefb70f0baa36a6e80b40d89df90140bc713d27194dc6dd9 +F ext/fts5/fts5_expr.c c7336d5f9ecc0e2b014d700be2bec0ea383b0e82c494a7c5c4ac622327c2bfad F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1 -F ext/fts5/fts5_index.c ee0f4d50bc0c58a7c5ef7d645e7e38e1e59315b8ea9d722ae00c5f949ee65379 -F ext/fts5/fts5_main.c 1d8bd88240f4ece62645c93df2a09162607e3b3d33838107bb711e8ad1f7cf14 -F ext/fts5/fts5_storage.c f9e31b0d155e9b2c92d5d3a09ad7a56b937fbf1c7f962e10f4ca6281349f3934 -F ext/fts5/fts5_tcl.c fdf7e2bb9a9186cfcaf2d2ce11d338309342b7a7593c2812bc54455db53da5d2 +F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe +F ext/fts5/fts5_main.c 77fefb37e7931095a5ff271a28fbe4f73ec46d5492ef1f35d405d98e137ad8ed +F ext/fts5/fts5_storage.c 1d7e08d4331da2f3f7e78e70eef2ed6a013d91ba16175c651adbc5ad672235aa +F ext/fts5/fts5_tcl.c 5ca3e3e35010d326f5b821a563e4fcde3913e052935f5c2c72c264122a26b48f F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c fa5493075101540270f572038fc1723d44fcc97bfbf237c8530013b8a27860be @@ -112,7 +112,7 @@ F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl bc33c6cc65e5d390f28a68aeeb3a526dadd2c3a947d2466ee1986c1a4002df56 -F ext/fts5/test/fts5aa.test 4db81519863244a3cab35795fe65ab6b592e7970c7409eba098b23ebbfc08d95 +F ext/fts5/test/fts5aa.test 015c81b84d53bfcedd77d624202c8b02e9f0cbbb4b51688e3a9c9f90bccbb4ac F ext/fts5/test/fts5ab.test 4bdb619fee409e11417e8827e320b857e42e926a01a0408fc9f143ec870a6ced F ext/fts5/test/fts5ac.test 4a73626de86f3d17c95738034880c4f0de8d54741fb943d819b528373657e59b F ext/fts5/test/fts5ad.test 058e616612964e61d19f70295f0e6eaedceb4b29b1fbf4f859615ef7e779dc22 @@ -139,15 +139,15 @@ F ext/fts5/test/fts5columnsize.test 0af91d63985afdf663455d4b572b935238380140d740 F ext/fts5/test/fts5config.test 017daf10d2642496e97402baa0134de8b5b46b9c37e53c229cd9ab711d21522c F ext/fts5/test/fts5conflict.test bf6030a77dbb1bedfcc42e589ed7980846c995765d77460551e448b56d741244 F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c073e19b3ae9126b2f4 -F ext/fts5/test/fts5content.test 84aa36c6c8b6cebc2b7be3a1e502e2b85c27c58b98614d7cc0fe9d3acf402601 +F ext/fts5/test/fts5content.test d5c0c2142e64cb305f0968de70c01f8e59dbc3ecc56520c22e739e5dd99ea3bb F ext/fts5/test/fts5contentless.test b107465f8cd27dde6313b9c60b61d7158a7753b9c663c5c553695f826bb3c0a5 F ext/fts5/test/fts5contentless2.test 70ffe6c611d8f278240da56734df8a77948f04e2739b358439e9bdcf56ced35f F ext/fts5/test/fts5contentless3.test 75eaae5ad6b284ee447788943974d323228f27cc35a1681da997135cff95bc6a F ext/fts5/test/fts5contentless4.test ec34dc69ef474ca9997dae6d91e072906e0e9a5a4b05ea89964c863833b6eff8 -F ext/fts5/test/fts5contentless5.test ceb53fcd635f726458fdee2e4482a37966e6b328fe94521ed02d04048f02dac5 -F ext/fts5/test/fts5corrupt.test 6d2143d2a30b2bd2795223f0c941457ae194b8f09fa490e0205ec670a68dea64 -F ext/fts5/test/fts5corrupt2.test a524eaa861aebecb33db919f065c8d2212f4871217446db3e5e79c1c4b49c798 -F ext/fts5/test/fts5corrupt3.test 12df0beb4b3e270d40dff3237b73e2dd2e9577404e1eca3f0847015ebe4f03ae +F ext/fts5/test/fts5contentless5.test 40cdcb4fe751672450829c5a96bd32c25fc2f6076279dd2ce5c58ac9a390132a +F ext/fts5/test/fts5corrupt.test a9bda1ded5112ebf1ee85c5381bd1fe8974952e2523cede4d5072804d2011503 +F ext/fts5/test/fts5corrupt2.test 335911e3f68b9625d850325f9e29a128db3f4276a8c9d4e32134580da8f924c4 +F ext/fts5/test/fts5corrupt3.test 3cbb18b8970c66ed4d741eb3eecf42c986bd4c430572a5050350a72030de66cf F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93f68f7d7a0d7d7dd733 F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76 F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06 @@ -158,7 +158,7 @@ F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3 F ext/fts5/test/fts5dlidx.test a7c42b0a74dc7c8aa1a46d586e0aadda4b6cc42c24450f8d3774b21166e93159 F ext/fts5/test/fts5doclist.test b7cb84758504519746957802db9cd31187bb4e0028b89d9087ba06e26cc4155f F ext/fts5/test/fts5ea.test cefdf66024550fa7920c03395c71ce5046235ed1a1a7a469d79b19e7aad5afb5 -F ext/fts5/test/fts5eb.test a7bd20ef7f5d37defb7eda93c8a7e65cba4a5aae95177df37020adca99600f76 +F ext/fts5/test/fts5eb.test 401f756fdb77083aeba8b696c1e0ad4d834c39dbd6f17e492bb55a2ad64b4296 F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 @@ -175,12 +175,12 @@ F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1 F ext/fts5/test/fts5faultG.test 0544411ffcb3e19b42866f757a8a5e0fb8fef3a62c06f61d14deebc571bb7ea9 F ext/fts5/test/fts5faultH.test 2b2b5b8cb1b3fd7679f488c06e22af44107fbc6137eaf45b3e771dc7b149312d -F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079 +F ext/fts5/test/fts5first.test bfd685b96905bf541d99d8644e0a7219d1d833455a08ab64e344071a613b6ba9 F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affcf7e979df59547b F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e F ext/fts5/test/fts5hash.test fd3e0367fbf0b0944d6936fdb22696350f57b9871069c6766251578a103e8a14 -F ext/fts5/test/fts5integrity.test 4c26d4663d002f90388d364a52827ae8729c232fbb6469bff1853b0e64a5c9aa -F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227 +F ext/fts5/test/fts5integrity.test 646796671205dae46af5bb12a49b5696483cfe8e12d71d21454940b13ace95ab +F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba1044c168db0e106f9ac92c F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1 F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fce79fa43004dff01c @@ -209,7 +209,7 @@ F ext/fts5/test/fts5prefix2.test a5bb43b8a2687efafa7ac4e5ccff6812015cf8cf18e3086 F ext/fts5/test/fts5query.test 0320a7a4b58a6e3e50ec8910b301649da90ace675001f9e0bf6392750ad4591d F ext/fts5/test/fts5rank.test 47c1e8e5d84754ff18e012fdd629776088b5a15de41bdd24957581cf084d8a00 F ext/fts5/test/fts5rebuild.test 83e72d77636378833233fadc7cb7517a2fa446ea7d1f94dd526ba3e7e104b9f5 -F ext/fts5/test/fts5restart.test ee7b40ac3f4ea027ea7d5f5422eddbcdaa14944ec4cc5791cfc1b796c71ae2a5 +F ext/fts5/test/fts5restart.test 9af2084b8e065130037b95f05f3f220bb7973903a7701e2c5fb916dff7cf80c5 F ext/fts5/test/fts5rowid.test 8632829fec04996832a4cfb4f0bd89721ba65b7e398c1731741bdb63f070e1a3 F ext/fts5/test/fts5savepoint.test 7f373184cf2d6c1c472d2bc732e1fce62211ffe023f13e381db0f5e4fd06e41d F ext/fts5/test/fts5secure.test a02f771742fb2b1b9bdcb4bf523bcf2d0aa1ff597831d40fe3e72aaa6d0ec40f @@ -234,14 +234,14 @@ F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10eb F ext/fts5/test/fts5trigram2.test c91f0a94f7e1ff859682228646abeab4c0eba2effc46af2cbc8f0f48b05a0566 F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 -F ext/fts5/test/fts5unicode.test 625f4ccd2fc4f480ca7af29349c1dea9d510aaca66bb8ec3aa90593b1e9e885b -F ext/fts5/test/fts5unicode2.test c7f5b338dc40c7f0480a94baf1a6ad0dc55ad7aefe51ba4655ffa9d4cf3dde19 +F ext/fts5/test/fts5unicode.test 41898f7e476e6515cd4b737c02a442cda5a580a74509788aa9072a2074948e0e +F ext/fts5/test/fts5unicode2.test 3ff7ea5d27310d65441779d9919055084cdbb570ed7743af1f8f4eeca1a3be26 F ext/fts5/test/fts5unicode3.test f4891a3dac3b49c3d7c0fdb29566e9eb0ecff35263370c89f9661b1952b20818 F ext/fts5/test/fts5unicode4.test 728c8f0caafb05567f524ad313d9f8b780fa45987b8a8df04eff87923c74b4d0 F ext/fts5/test/fts5unindexed.test 168838d2c385e131120bbf5b516d2432a5fabc4caa2259c932e1d49ae209a4ae F ext/fts5/test/fts5update.test b8affd796e45c94a4d19ad5c26606ea06065a0f162a9562d9f005b5a80ccf0bc F ext/fts5/test/fts5version.test c22d163c17e60a99f022cbc52de5a48bb7f84deaa00fe15e9bc4c3aa1996204e -F ext/fts5/test/fts5vocab.test 03a2e0b7fd6134a33fef7701076d8a3d4971afd324621abdac1c9c4f0019d63f +F ext/fts5/test/fts5vocab.test 2a2bdb60d0998fa3124d541b6d30b019504918dc43a6584645b63a24be72f992 F ext/fts5/test/fts5vocab2.test bbba149c254375d00055930c1a501c9a51e80b0d20bf7b98f3e9fa3b03786373 F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl c0d43c8590656f8240e622b00957b3a0facc49482411a9fdc2870b45c0c82f9f @@ -259,7 +259,7 @@ F ext/intck/intckcorrupt.test f6c302792326fb3db9dcfc70b554c55369bc4b52882eaaf039 F ext/intck/intckfault.test cff3f75dff74abb3edfcb13f6aa53f6436746ab64b09fe5e2028f051e985efab F ext/intck/sqlite3intck.c 0d10df36e2b7b438aa80ecd3f5e584d41b747586b038258fe6b407f66b81e7c5 F ext/intck/sqlite3intck.h 2b40c38e7063ab822c974c0bd4aed97dabb579ccfe2e180a4639bb3bbef0f1c9 -F ext/intck/test_intck.c 6050ed1f3e11eb58c66ed20f75af43dec0e37c88c9089b98b8a0a26022735dc3 +F ext/intck/test_intck.c 4f9eaadaedccb9df1d26ba41116a0a8e5b0c5556dc3098c8ff68633adcccdea8 F ext/jni/GNUmakefile 59eb05f2a363bdfac8d15d66bed624bfe1ff289229184f3861b95f98a19cf4b2 F ext/jni/README.md d899789a9082a07b99bf30b1bbb6204ae57c060efcaa634536fa669323918f42 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa @@ -289,7 +289,7 @@ F ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 01bc0c238eed2d5f9 F ext/jni/src/org/sqlite/jni/capi/ResultCode.java 8141171f1bcf9f46eef303b9d3c5dc2537a25ad1628f3638398d8a60cacefa7f F ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java e172210a2080e851ebb694c70e9f0bf89284237795e38710a7f5f1b61e3f6787 F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 0d1e9afc9ff8a2adb94a155b72385155fa3b8011a5cca0bb3c28468c7131c1a5 -F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1 +F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 0b25cde8c5fa77f3e7ad92368acf195c5c64fb1c5273b8ee71b2d7ab812aab34 F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615 F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f F ext/jni/src/org/sqlite/jni/capi/Tester1.java e5fa17301b7266c1cbe4bcce67788e08e45871c7c72c153d515abb37e501de0a @@ -315,7 +315,7 @@ F ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1efd1220ea328a32f2d2a1b F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java a8e88c3783d21cec51b0748568a96653fead88f8f4953376178d9c7385b197ea F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 9e2b954d210d572552b28aca523b272fae14bd41e318921b22f65b728d5bf978 F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 92bdaa3893bd684533004d64ade23d329843f809cd0d0f4f1a2856da6e6b4d90 -F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e +F ext/jni/src/org/sqlite/jni/test-script-interpreter.md 9bf7e9cab1183287b048bb77baee4b266f0c15baf1b624feec12fbf00cfa7e94 F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483 F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03 F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 27b141f5914c7cb0e40e90a301d5e05b77f3bd42236834a68031b7086381fafd @@ -385,7 +385,7 @@ F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c F ext/misc/carray.h 503209952ccf2431c7fd899ebb92bf46bf7635b38aace42ec8aa1b8d7b6e98a5 F ext/misc/cksumvfs.c 3a7931dd30667be6348af919f3f9e6188dfd7646b42af8e399a499b327f5bd63 F ext/misc/closure.c 0e04f52d93e678dd6f950f195f365992edf3c380df246f3d80425cba4c13891e -F ext/misc/completion.c ef78835483b43ac18c96be312b90b615d8368189909be03513ab7a9338131298 +F ext/misc/completion.c cb978c88d5577821323617a8ea775ce1b920e02dcdb593858f02044a4d008eea F ext/misc/compress.c 2c79a74330e0e0ba6cb3f7397f8ba5af12d46377ef5d3ee075e12dd8a6ed57f0 F ext/misc/csv.c 575c2c05fba0a451586a4d42c2c81e711780c41e797126f198d8d9e0a308dcdb F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01 @@ -404,7 +404,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58 F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0 F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 -F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 +F ext/misc/percentile.c af1941dc87d45dd0c2698a3087fbfe9ee0d157e5e72da521430c4b784abcbe81 F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed @@ -479,7 +479,7 @@ F ext/rbu/rbuvacuum3.test 3ce42695fdf21aaa3499e857d7d4253bc499ad759bcd6c9362042c F ext/rbu/rbuvacuum4.test ffccd22f67e2d0b380d2889685742159dfe0d19a3880ca3d2d1d69eefaebb205 F ext/rbu/sqlite3rbu.c 4a3376c0fb9a844a799ac529fb81260523f6b13c9f629bc270c632dbae5fc1f8 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 -F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 +F ext/rbu/test_rbu.c b9727c3394307d058e806c1da0f8bb7b24daf3c6bb94cb10cca88ea4d5c806c0 F ext/recover/dbdata.c a22ecd689f00ff2ad33b5633c4ef84c8f088c65faeac18d4eb73c128395c7aec F ext/recover/recover1.test e16d78e94183562abff569967b18b7c77451d7044365516cd0fe14713a284851 F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a @@ -488,17 +488,17 @@ F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1c F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49 F ext/recover/recovercorrupt2.test 1418f1710debc24ff38276cedfcea234beb37a34205708e7e3e6d76cc4a979db F ext/recover/recovercorrupt3.test 2e7b9a1b528ca23ed382cec6f64e3fcbbd0f8e852add7562397fd8df83f335d5 -F ext/recover/recovercorrupt4.test cc4a56086c50fba6a5b20db122a3f220195b3d4f11a86e0858c7f5f5d8ba58d1 +F ext/recover/recovercorrupt4.test 3e2794145dad2517c018cb68b96f59d4d55b18b3d6271e1d37852cfd7a30b50c F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1 F ext/recover/recoverfault2.test 730e7371bcda769554d15460cb23126abba1be8eca9539ccabf63623e7bb7e09 F ext/recover/recoverold.test 68db3d6f85dd2b98e785b6c4da4f5eea4bbe52ccf6674d9a94c7506dc92596aa -F ext/recover/recoverpgsz.test 3658ab8e68475b1bb87d6af88baa04551c84b73280a566a1be847182410ffc58 +F ext/recover/recoverpgsz.test 88766fcb810e52ee05335c456d4e5fb06d02b73d3ccb48c52bf293434305e2b1 F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 F ext/recover/sqlite3recover.c 65ef0f56301a16c0536c9839fb7e23540c9c4f75da0afe3b7b4d163c8f624404 F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 -F ext/recover/test_recover.c fd871a40f2238022bedcbdf3cb493b91225edaa94d6ae8892af97a10e7ccc4ba +F ext/recover/test_recover.c 072260d7452a3b81aba995b2b3269e7ec2aa7f06725544ba4c25b1b0a1dbc61a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 F ext/repair/checkfreelist.c e21f06995ff4efdc1622dcceaea4dcba2caa83ca2f31a1607b98a8509168a996 F ext/repair/checkindex.c af5c66463f51462d8a6f796b2c44ef8cfa1116bbdc35a15da07c67a705388bfd @@ -541,18 +541,18 @@ F ext/rtree/rtreedoc2.test 194ebb7d561452dcdc10bf03f44e30c082c2f0c14efeb07f5e02c F ext/rtree/rtreedoc3.test 555a878c4d79c4e37fa439a1c3b02ee65d3ebaf75d9e8d96a9c55d66db3efbf8 F ext/rtree/rtreefuzz001.test 44f680a23dbe00d1061dbde381d711119099846d166580c4381e402b9d62cb74 F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373 -F ext/rtree/test_rtreedoc.c de76b3472bc74b788d079342fdede22ff598796dd3d97acffe46e09228af83a3 +F ext/rtree/test_rtreedoc.c d20f51d1ad69c72947a4ac72194e5a12e70b3464e7492538fcef66fa871c5081 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1d2f94ac66 F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0fb58869cb5 F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa -F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a +F ext/session/changesetfuzz1.test 15b629004e58d5ffcc852e6842a603775bb64b1ce51254831f3d12b113b616cd F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a -F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 +F ext/session/session4.test 823f6f018fcbb8dacf61e2960f8b3b848d492b094f8b495eae1d9407d9ab7219 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926 F ext/session/session8.test 326f3273abf9d5d2d7d559eee8f5994c4ea74a5d935562454605e6607ee29904 @@ -572,8 +572,8 @@ F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b8541 F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf F ext/session/sessionchange.test 77c4702050f24270b58070e2cf01c95c3d232a3ef164b70f31974b386ce69903 F ext/session/sessionconflict.test 8b8cbd98548e2e636ddc17d0986276f60e833fb865617dd4f88ea5bbe3a16b96 -F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec -F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09 +F ext/session/sessiondiff.test e89f7aedcdd89e5ebac3a455224eb553a171e9586fc3e1e6a7b3388d2648ba8d +F ext/session/sessionfault.test c2b43d01213b389a3f518e90775fca2120812ba51e50444c4066962263e45c11 F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c F ext/session/sessionfault3.test 7c7547202775de268f3fe6f074c4d0d165151829710b4e64f90d4a01645ba9e7 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 @@ -588,12 +588,12 @@ F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc F ext/session/sqlite3session.c c7473aafbd88f796391a8c25aa90975a8f3729ab7f4f8cf74ab9d3b014e10abe F ext/session/sqlite3session.h 683ccbf16e2c2521661fc4c1cf918ce57002039efbcabcd8097fa4bca569104b -F ext/session/test_session.c 8bcc857125372e640f75ab63b4188080f9bbab92b65f86dfd160721c574b2044 +F ext/session/test_session.c 6acbe67db80ab0806147eb62a12f9e3a44930f4a740b68b0a4340dddda2c10d7 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 05727be716879b1345892ce8c61dd093aefe26ccc48ad9467f3864b85475993b +F ext/wasm/GNUmakefile d4f6586d9a36ee2869a8c7f77227a8b7f42b6c4623f3be594beafb1554ab20d9 F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff @@ -601,8 +601,12 @@ F ext/wasm/SQLTester/SQLTester.mjs ce765c0ad7d57f93553d12ef4dca574deb00300134a26 F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638 F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 -F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-auth 7ac80cc3b6a6d52e041bb295e85555ce797be78c15ef2008a64ae58815014080 +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 400213eb52a7e5ad5f448053d375cacf4dac2cf45d134f3edfe485ae4a49a183 w ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-preupdate d1d62a2212099f2c0782d730beb8cb84a7a52d99c15ead2cb9b1411fff5fd6b1 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-session 213b6c04267cb9bd760172db011eb1650732805fb3d01f9395478a8ceec18eb0 +F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-vtab fd57af1f4502a052be27d8402df74be1dc60fcb6a687d372972abd90e424120a F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73 F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac @@ -611,17 +615,17 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08 F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122 F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e -F ext/wasm/api/sqlite3-api-glue.js 114085f4dceb28e06d20d3fb597b2501a4aa69f4b6cd29234f7cc1cf81d5b92d -F ext/wasm/api/sqlite3-api-oo1.js c373cc04625a96bd3f01ce8ebeac93a5d38dbda6215818c925570df5a945565e -F ext/wasm/api/sqlite3-api-prologue.js b347a0c5350247f90174a0ad9b9e72a99a5f837f31f78f60fcdb829b2ca30b63 -F ext/wasm/api/sqlite3-api-worker1.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d +F ext/wasm/api/sqlite3-api-glue.c-pp.js 54b32b5321105a72d6f3d3e8b77f28f162d0367b08c63184263d3f85f3d7dbed w ext/wasm/api/sqlite3-api-glue.js +F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f w ext/wasm/api/sqlite3-api-oo1.js +F ext/wasm/api/sqlite3-api-prologue.js 6f1257e04885632ed9f44d43aba200b86e0bc16709ffdba29abbbeb1bc8e8b76 +F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d w ext/wasm/api/sqlite3-api-worker1.js F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 -F ext/wasm/api/sqlite3-opfs-async-proxy.js 881af4643f037b6590c491cef5fac8bcdd4118993197a1fa222ccb8b01e3504a +F ext/wasm/api/sqlite3-opfs-async-proxy.js e8f1df56e97a29004a95a2eddd26778f52c33b3e797d32d4b1b668a38e6493dd F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d -F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 8433ee332d5f5e39fb19427fccb7bad7f44aa99b5504daad3343fc128c311e78 -F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 0c3801a8e252944fdbaddbad698534316fde90d3db5eedae156e7774ab127710 -F ext/wasm/api/sqlite3-vtab-helper.c-pp.js a2fcbc3fecdd0eea229283584ebc122f29d98194083675dbe5cb2cf3a17fe309 -F ext/wasm/api/sqlite3-wasm.c 9267174b9b0591b4f71193542ab57adf95bb9415f7d3453acf4a8ca8052f5e6c +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js e529a99b7d5a088284821e2902b20d3404b561126969876997d5a73a656c9199 +F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e99e3d99f736937914527070f00ab13e9391d3f1cef884ab99a64cbcbee8d675 +F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616 +F ext/wasm/api/sqlite3-wasm.c 09a938fc570f282e602acd111147c7b74b5332da72540c512a79b916ab57882a F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5 F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7 @@ -644,7 +648,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make 828c6f3e45ba2541e61fd79c3d8b07a5be4cf13f9acb6430b562bcab3f251496 +F ext/wasm/fiddle.make 2406b02473878a99fb6a2eaff0923277017adc45eb041b2afb2d7707bf7b375c F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1 F ext/wasm/fiddle/index.html 739e0b75bc592679665d25e2f7649d2b8b2db678f3b41a772a8720b609b8482d @@ -667,9 +671,9 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555 F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 6d0a9aa44a97b4aadd582e0999ce45a2671b854a12ea3205d1c908da6bd4bdef -F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 -F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d +F ext/wasm/tester1.c-pp.js a88b9c669715adc1c5e76750ca8c0994ae33d04572e3bf295b6f4f5870f3bdf3 +F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e +F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966f1bc16a F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x @@ -688,7 +692,7 @@ F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 F src/alter.c e1b6782b85dd758f89e5c588e4e3eb82638c2dafc0c857b79a43bb8ec1746fca -F src/analyze.c a3df28274e2565ba5656577d7e3fd262169a213e6eb0bd47890e0f0729a4031c +F src/analyze.c 5c4e2bfd0aa8e5157f7fb91a17d86905510a74397326dc5767ec4e0588a4eea5 F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 @@ -705,7 +709,7 @@ F src/date.c 13dd752847afb32ed70510ad7345a5b9c841f51ad904dba5d010f1fa3a6a324e F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782 F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 -F src/expr.c af9c9242be0df17280faf36c9810339de9df3d7a64ac8d33a5190a1400086ee5 +F src/expr.c fe958028b36af640b70b2174354c044f75b8c4a4645c921592122aa2a022083a F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a F src/func.c 1f61e32e7a357e615b5d2e774bee563761fce4f2fd97ecb0f72c33e62a2ada5f @@ -742,12 +746,12 @@ F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d87210 F src/os_unix.c 2ea8d3ed496b8d1f9332a9505653424e5464fd797ea9d91f8e2e62f9dd0298d0 F src/os_win.c 6ff43bac175bd9ed79e7c0f96840b139f2f51d01689a638fd05128becf94908a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 9beb80f6e330dd63c5d8ba0f7a7f3a55fff22067a68d424949c389bfc6fa0c56 +F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a F src/parse.y 2bd540b3b1e79017eb41fca2396633a75e7dd430c05383c61fe52c6f4e97c6d8 -F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 +F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 -F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 +F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 F src/pragma.c 52bfbf6dfd668b69b5eb9bd1186e3a67367c8453807150d6e75239229924f684 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce @@ -755,81 +759,82 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 9c7786f032dea81487e7d94cb17849936f0e9b8891bfc91a6ac24ab193762804 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 -F src/select.c d92f158185cf5aedc058bbe1eefba070b5dc57a5d71cb66625c3d2a906037829 -F src/shell.c.in 2ccbed6a9fd451399b0f378aafa323ad2286fa9de54ae0cd28f32907cd94d18d -F src/sqlite.h.in 6c884a87bbf8828562b49272025a1e66e3801a196a58b0bdec87edcd2c9c8fc1 +F src/select.c cb28a79bda149b1a1c80797795c1249c6ae8c1a392a6a96ac4cb7c881757c385 +F src/shell.c.in 44c02fd1581d95e066b479241e081f37dc95c98452badd03627ef2a1c21bdc80 +F src/sqlite.h.in 1ad9110150773c38ebababbad11b5cb361bcd3997676dec1c91ac5e0416a7b86 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 -F src/sqliteInt.h 36aaff552ecdf273ab6d14bd87d01175d8d5c88267b6d8b04e8f513c5d27efc9 +F src/sqliteInt.h 146e1f57a480efff0bb17a2c61a66b61fe0b6b93b76958b2aeeac56c44190fb7 F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728 F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd -F src/test1.c 6bd203421934f2af4d4a4b673f609879f1e0c35164f7e21d0d6cdc0da2eeee8f -F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab -F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e -F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664 -F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d -F src/test6.c e53bc69dc3cb3815fb74df74f38159ec05ba6dd5273216062e26bc797f925530 -F src/test8.c 303c2e3bcf7795e888810a7ef03809602b851f0ebec8d6e06a429ed85cafd9a2 -F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 -F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a -F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 -F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 -F src/test_bestindex.c 1b5a1407b66c5caa67cfe1d93d96de5ec5d9d516bc69eb512482f85c037858c3 -F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce -F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 5fa77ee6064ba546e144c4fea870c5ede2c54314616f81485c6a9c4192100c75 +F src/tclsqlite.c 8e86ab2595c2ff7bb155331fb173e560180235bceaacce7931a718b1c2e6dfb4 +F src/tclsqlite.h c6af51f31a2b2172d674608763a4b98fdf5cd587e4025053e546fb8077757262 +F src/test1.c 51159784f29d3dfd4b50fd6ed9c43c8f7f36925c501a3ad3083528e5e5544bd7 +F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 +F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b +F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d +F src/test5.c bb87279ed12e199486894e6c83e58dc8cd1de9524ace171d59219d3ab696a0c1 +F src/test6.c 763b92489f11f4a77b773f0d3b8369ab0edd5292ac794043062c337019f12d8a +F src/test8.c 206d8f3cc73950d252906656e2646b5de0d580b07187b635fcb3edd8c2c5fbc0 +F src/test9.c 7a708ad27f8fda79113e5e15de66632710958c401e64c2f22bc04e2f5a7a1b62 +F src/test_async.c 0101173cf8137ba5473a84a695281fa9dedc2a1d155998c68623f2978017ad98 +F src/test_autoext.c 14d4bbd3d0bd1eec0f6d16b29e28cf1e2d0b020d454835f0721a5f68121ac10f +F src/test_backup.c bd901e3c116c7f3b3bbbd4aae4ce87d99b400c9cbb0a9e7b4610af451d9719a7 +F src/test_bestindex.c 3401bee51665cbf7f9ed2552b5795452a8b86365e4c9ece745b54155a55670c6 +F src/test_blob.c bcdf6a6c22d0bcc13c41479d63692ef413add2a4d30e1e26b9f74ab85b9fb4d5 +F src/test_btree.c 28283787d32b8fa953eb77412ad0de2c9895260e4e5bd5a94b3c7411664f90d5 +F src/test_config.c 46eaf39842cace9d540aeefb50fe24dd3204a622893a97952cbb49c20b2f8b21 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f -F src/test_demovfs.c 38a459d1c78fd9afa770445b224c485e079018d6ac07332ff9bd07b54d2b8ce9 +F src/test_demovfs.c 3efa2adf4f21e10d95521721687d5ca047aea91fa62dd8cc22ac9e5a9c942383 F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 -F src/test_fs.c 56cc17e4fdc57efa61695026e2ba96e910b17060d7ee01d775ec048791522e2f -F src/test_func.c 4d2dc7e3e0946e55091784ddaf0302294f2ee300614f6f3e19a4b38df77d5167 -F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd -F src/test_init.c f2cc4774b7c9140f76e45ecbb2ae219f68e3acbbe248c0179db666a70eae9f08 -F src/test_intarray.c 26ffba666beb658d73cd925d9b4fb56913a3ca9aaeac122b3691436abb192b92 +F src/test_fs.c c411c40baba679536fc34e2679349f59d8225570aed3488b5b3ef1908525a3d5 +F src/test_func.c 8c0e89192f70fac307822d1ac2911ee51751288780b3db0c5ab5ca75fa0fe851 +F src/test_hexio.c af6db9300edd2d7b786a2d40d64177cad4b8ee22085e8ca5fe812cdeffdb6502 +F src/test_init.c 17313332d58e90defc527129d5eda4a08bd6b6e8de7207a231523c8d98fb445e +F src/test_intarray.c e4216aadee9df2de7d1aee7e70f6b22c80ee79ece72a63d57105db74217639e5 F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd -F src/test_malloc.c 21121ea85b49ec0bdb69995847cef9036ef9beca3ce63bbb776e4ea2ecc44b97 -F src/test_md5.c 0472c86d561f7f9e4ff94080100c2783196f50e583bb83375b759450c5b81802 -F src/test_multiplex.c 70479161239d65af2a231550b270e9d11ece717ad7bf0e13ef42206586e9dd7f +F src/test_malloc.c a0295e022103b14a1bc5e0660cc2af7fbec05e0d029098782e326e50612e69d9 +F src/test_md5.c 811a45330c9391933360f998156a8907ee29909c828ab83ac05d329942cbea8f +F src/test_multiplex.c b99d7f43ec859e6b93a40aaa5455420b3ad133053cce3db739498d29ea30735f F src/test_multiplex.h f0ff5b6f4462bfd46dac165d6375b9530d08089b7bcbe75e88e0926110db5363 -F src/test_mutex.c cd5bac43f2fd168f43c4326b1febe0966439217fac52afb270a6b8215f94cb40 +F src/test_mutex.c f10fcbc2086b19c7b0ddf2752caf2095e42be74d8d7f6093619445b43b1f777b F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4 -F src/test_osinst.c 8e11faf10f5d4df10d3450ecee0b8f4cfa2b62e0f341fafbeb480a08cefeaec4 -F src/test_pcache.c 3960cd2c1350adc992c4bf7adcfb0d1ac0574733012bd1a5f94e195928577599 -F src/test_quota.c ea44c05f29b995bdb71c55eb0c602604884e55681d59b7736e604bbcc68b0464 +F src/test_osinst.c 7aa3feaa3a1da1b5f75bde2ce958dbfe14ec484f065bb2b5b9727d8851fa089b +F src/test_pcache.c 496da3f7e2ca66aefbc36bbf22138b1eff43ba0dff175c228b760fa020a37bd0 +F src/test_quota.c 07369655d24c3f3fbdbd8fd8f42e856a054a7497846ca1c83ed4be68152a251f F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d -F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b -F src/test_schema.c cbfd7a9a9b6b40d4377d0c76a6c5b2a58387385977f26edab4e77eb5f90a14ce +F src/test_rtree.c d844d746a3cc027247318b970025a927f14772339c991f40e7911583ea5ed0d9 +F src/test_schema.c b06d3ddc3edc173c143878f3edb869dd200d57d918ae2f38820534f9a5e3d7d9 F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a -F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e -F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca -F src/test_tclsh.c aaf0d1de4a518a8db5ad38e5262be3e48b4a74ad1909f2dba753cecb30979d5d -F src/test_tclvar.c 3273f9d59395b336e381b53cfc68ec6ebdaada4e93106a2e976ffb0550504e1c -F src/test_thread.c 7ddcf0c8b79fa3c1d172f82f322302c963d923cdb503c6171f3c8081586d0b01 -F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 -F src/test_vfs.c 193c18da3dbf62a0e33ae7a240bbef938a50846672ee947664512b77d853fe81 +F src/test_superlock.c 18355ca274746aa6909e3744163e5deb1196a85d5bc64b9cd377273cef626da7 +F src/test_syscall.c 9ad7ab39910c16d29411678d91b0d27a7a996a718df5ee93dcd635e846d0275c +F src/test_tclsh.c 6077f2bdc6b4ea2bace2a0cd6ea48e0a4651007ae7382c13efc0c495eb0c6956 +F src/test_tclvar.c 2c42fe9a74af0f3c8f87a339f66d9d3bd3a967fb5db1ed2500348055b954e391 +F src/test_thread.c d7a8bcea7445f37cc2a1f7f81dd6059634f45e0c61bfe80182b02872fb0328bb +F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3 +F src/test_vfs.c f298475e468c7e14945b20af885917181090c265aa3c4ade897849c9fbd396f2 F src/test_vfstrace.c a2ea82df2ed8927e9eba49bdba1aa1aeb1dcb13dbf6558cff036da813031de9a F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb775ebc50 -F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f +F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 3f703cacdab728d7741e5a6ac242006d74fe1c2754d4f03ed889d7253259bd68 -F src/treeview.c e4f0c5ca871371d26ca6868554bd5b06b7bd9554023bbec834e26c2b45814b0c +F src/treeview.c 774838df4e25956ca34ff79bef150266412cfc2640620d04e22d5c8a55a98992 F src/trigger.c 0858f75818ed1580332db274f1032bcc5effe567cb132df5c5be8b1d800ca97f F src/update.c 732404a04d1737ef14bb6ec6b84f74edf28b3c102a92ae46b4855438a710efe7 F src/upsert.c 2e60567a0e9e8520c18671b30712a88dc73534474304af94f32bb5f3ef65ac65 F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375 F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 -F src/vdbe.c b05777c3ff2ed7b9dfc347e7cdee18e371aa6811cef1fe83454691b0dbe2cc9f -F src/vdbe.h c2d78d15112c3fc5ab87f5e8e0b75d2db1c624409de2e858c3d1aafb1650bb4f +F src/vdbe.c de13de572eccb688b2b7cf50e2f9005c44bf9ae89e35245ef8eadfc60dfd2764 +F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c F src/vdbeapi.c 80235ac380e9467fec1cb0883354d841f2a771976e766995f7e0c77f845406df -F src/vdbeaux.c 6e37cb918506c28fe7657454fcbc2e01e66bfba4164f306c2f075fd5c5fef609 +F src/vdbeaux.c 25d685cafe119ff890c94345e884ea558a6b5d823bfa52ba708eb8ff3c70aa71 F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5 F src/vdbemem.c 831a244831eaa45335f9ae276b50a7a82ee10d8c46c2c72492d4eb8c98d94d89 F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 @@ -840,7 +845,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89 F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 -F src/where.c 70e12796956949658d6adb85f22d0760f0c05829f2ce882e89752eb28147baeb +F src/where.c d87a4160e26a7a96a2f7ca283b147b1b283b54ba545c46acb14cfcc6ec37ae9e F src/whereInt.h 002adc3aa2cc10733b9b27958fdbe893987cd989fab25a9853941c1f9b9b0a65 F src/wherecode.c c9cac0b0b8e809c5e7e79d7796918907fb685ad99be2aaa9737f9787aa47349c F src/whereexpr.c 7d0d34b42b9edfd8e8ca66beb3a6ef63fe211c001af54caf2ccbcd989b783290 @@ -908,7 +913,7 @@ F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec F test/autoinc.test 997d6f185f138229dc4251583a1d04816423dddc2fc034871a01aeb1d728cb39 -F test/autoindex1.test d34caffb0384003ee28eae87679214c029e9be4b332d9649a79e0b94ab70502c +F test/autoindex1.test 714cac6e60beeb5a26ed346dd46505ba60b5a5597e9122c9ed3a55f89a922aa4 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test ca502c8050166ac6107a7b4fe4e951f4d3270a23a958af02b14f1b962b83c4b6 F test/autoindex4.test 3c2105e9172920e26f950ba3c5823e4972190e022c1e6f260ba476b0af24c593 @@ -918,7 +923,7 @@ F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avfs.test 76f59743dc1f5fa533840d1818b420fe1ee45e21c0fd6bbac7942ba677903128 F test/avtrans.test b7dc25459ecbd86c6fa9c606ee3068f59d81e225118617dcf2bbb6ded2ade89e -F test/backcompat.test 3e64cedda754c778ef6bbe417b6e7a295e662a4d +F test/backcompat.test f2431465ed668f09fc3f6998e56e893a1506ccea6e8b6f409f085f759f431b48 F test/backup.test 3b08fd4af69f0fa786931103a31f4542b184aba16e239e5f22b18c3c2476697f F test/backup2.test 8facb54df1388419d34b362ab1f7e233310ff3a3af64e8ad5ec47ba3c2bbe5cf F test/backup4.test 8f6fd48e0dfde77b9a3bb26dc471ede3e101df32 @@ -976,7 +981,7 @@ F test/capi3c.test 31d3a6778f2d06f2d9222bd7660c41a516d1518a059b069e96ebbeadb5a49 F test/capi3d.test 8b778794af891b0dca3d900bd345fbc8ebd2aa2aae425a9dccdd10d5233dfbde F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/carray01.test 23ed7074307c4a829ba5ff2970993a9d87db7c5cdbbe1a2cbef672d0df6d6e31 -F test/cast.test af2286fdd28f3470b7dcad23977282b8cc117747ad55acff74a770dad3b19398 +F test/cast.test 42f7d79d88ab5e8080e96c650c52fcf72eef3e6476aaaee2c9f6e074396cfdfc F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef F test/changes.test 4377d202a487f66fc2822c1bf57c46798c8b2caf7446f4f701723b1dbb6b86f6 F test/changes2.test 07949edcc732af28cb54276bfb7d99723bccc1e905a423648bf57ac5cb0dc792 @@ -1005,10 +1010,10 @@ F test/conflict.test b705cddf025a675d3c13d62fa78ab1e2696fb8e07a3d7cccce1596ff8b3 F test/conflict2.test 5557909ce683b1073982f5d1b61dfb1d41e369533bfdaf003180c5bc87282dd1 F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 -F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3 -F test/corrupt2.test 9745c55b3ff2d84d9b6dc4f7365f91a99e70d90f3127ebc97ff0549c418e4d3d +F test/corrupt.test 54509b182b1927663e0a425b681b0935a08a01b11d8153a4a9545ed36760ebe2 +F test/corrupt2.test 4ce5eadd51baa1aedb48e141dd885d155946f5c3677bb032547e350ce91b17f4 F test/corrupt3.test 6a982535d52c8165654cbc79a043cfd0bf02495a5efbf4754295e056fc548539 -F test/corrupt4.test b5ae41607e8d17d9c1f3e94fdb572ce061ed3beeebdb46fb3a348181b8c8a097 +F test/corrupt4.test 5fa4559bcfd14afbb99670d463546ba75fb4975c710b7f6dfa592ae90471cce7 F test/corrupt5.test 387be3250795e2a86e6234745558b80efb248a357d0cd8e53bce75c7463f545d F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568 F test/corrupt7.test ffa86896fe63a3d00b0a131e1e64f402e4da9f7e5d89609d6501c851e511d73a @@ -1024,7 +1029,7 @@ F test/corruptG.test adf79b669cbfd19e28c8191a610d083ae53a6d51 F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test 9d8cbf6214e492abe9e822e759b9751ae336cec0a6fe3ff3b37bfbd8ff9c22ca F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 -F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af +F test/corruptK.test ac13504593d89d69690d45479547616ed12644d42b5cb7eeb2e759a76fc23dcb F test/corruptL.test 652fc8ac0763a6fd3eb28b951d481924167b2d9936083bcc68253b2274a0c8fe F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4 @@ -1032,7 +1037,7 @@ F test/cost.test cc434a026b1e9d0d98137a147e24e5daf1b1ad09e9ff7da63b34c83ddd136d9 F test/count.test cd4bd531066e8d77ef8fe1e3fc8253d042072e117ccab214b290cf83f1602249 F test/countofview.test 4088e461a10ee33e69803c177a69aa1d7bba81a9ffc2df66d76465a22ca7fdfc F test/coveridxscan.test f35c7208dedc4f98e471c569df64c0f95a49f6e072d8dc7c8f99bdee2697de1b -F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f +F test/crash.test f699152b8ae759bdf1c19c278b135f5d43fa4b6466e63489cd02edbc94aebad0 F test/crash2.test 5b14d4eb58b880e231361d3b609b216acda86651 F test/crash3.test 8f5de9d32ab9ab95475a9efe7f47a940aa889418 F test/crash4.test fe2821baf37168dc59dd733dcf7dba2a401487bc @@ -1074,7 +1079,7 @@ F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014 -F test/distinct2.test 931a242fccaa05f17232e23acc9b2debe42901d90db723ddca038f7758951b5f +F test/distinct2.test 4d6316b6487a0aa5a90bee111575c957e2a5ba5a9be9156febe9533ce78876e8 F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075 @@ -1106,12 +1111,12 @@ F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test 3302598f611220a6c61e29d9b7bb62fd4a43504509b978dbabdb0b3e56ae3bc0 +F test/eqp.test 815418b69f6be3a27037b1736c54699c72cc3e2e6b0bc878c01464d1dcec65fe F test/eqp2.test 6e8996148de88f0e7670491e92e712a2920a369b4406f21a27c3c9b6a46b68dd F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0 F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747 -F test/exclusive2.test 984090e8e9d1b331d2e8111daf6e5d61dda0bef7 +F test/exclusive2.test cd70b1d9c6fffd336f9795b711dcc5d9ceba133ad3f7001da3fda63615bdc91e F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7 F test/exists.test 79a75323c78f02bbe9c251ea502a092f9ef63dac F test/existsexpr.test bf1201621070e79c1060c1a8cf7d65d81fc6b336d94a371c63ecb08d357af2fd @@ -1245,14 +1250,14 @@ F test/func2.test 69f6ae3751b4ec765bdc3b803c0a255aa0f693f28f44805bef03e6b4a3fd24 F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test a3f9062487dbd826776f54f4e0e9517fe8c3cf689af92735308965774d51fac5 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a -F test/func6.test 9cc9b1f43b435af34fe1416eb1e318c8920448ea7a6962f2121972f5215cb9b0 -F test/func7.test adbfc910385a6ffd15dc47be3c619ef070c542fcb7488964badb17b2d9a4d080 +F test/func6.test 3bc89ec0f2605736d3a118f43d25ef58115a7db4dba8ae939a363917d815c0bb +F test/func7.test 7e009275f52c52954c8c028fdb62f8bc16cc47276fcc8753c1d2b22c6e074598 F test/func8.test c4e2ecacf9f16e47a245e7a25fbabcc7e78f9c7c41a80f158527cdfdc6dd299d F test/func9.test b32d313f679aa9698d52f39519d301c3941823cb72b4e23406c210eadd82c824 F test/fuzz-oss1.test 514dcabb24687818ea949fa6760229eaacad74ca70157743ef36d35bbe01ffb0 F test/fuzz.test 4608c1310cff4c3014a84bcced6278139743e080046e5f6784b0de7b069371d8 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 -F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c31 +F test/fuzz3.test 70ba57260364b83e964707b9d4b5625284239768ab907dd387c740c0370ce313 F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 @@ -1286,7 +1291,7 @@ F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test bb767ec1cfd1730256f0a83219f0acda36bc251b63f8b8bb7d8c7cff17875a4f F test/in5.test 4fd79c70dfa0681313e8cdca07f5ff0400bdc0e20f808a5c59eaef1e4b48082a F test/in6.test f5f40d6816a8bb7c784424b58a10ac38efb76ab29127a2c17399e0cbeeda0e4b -F test/in7.test 742b18c284cd9a9cd1347d3a8affeee44b8de11e875e91a1d40498c18ba16441 +F test/in7.test 9256cdb30dc487f2078bb4bb30f43f2c1ff4d277a9c7c9a14bd1c9510c9c8cae F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f F test/incrblob3.test 67621a04b3084113bf38ce03797d70eca012d9d8f948193b8f655df577b0da6f @@ -1296,7 +1301,7 @@ F test/incrblobfault.test de274b1e329169c2c3438f9528994807ea8201ebf38ae9f157d34b F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a F test/incrvacuum.test 3fa6145f5e71f603554fd7b8ec3da4290b1341029682313285cb5f9e1893d6ba F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d -F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a +F test/incrvacuum3.test 0bf0ffe7f2cbc87ba1d471e4bbadabbf10dacf8d4ee26b3a072708d575d637a9 F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 F test/index.test d866054c88b394fd42cbf2825628f127ca24dfac525fa019069a936674d92cbe F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 @@ -1327,11 +1332,11 @@ F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test aee694afed1a65c86c4e69ad030224b3fc268113d00685234d40079fca16bad3 F test/intreal.test 68829a8bb073ee1610ca3f8f9e0f99b0371fb36e0fa64862dd5ced4ef03c2343 F test/io.test f138f3fe696d1ed8c51dfea5b325910d319a1b29e1d25ea57231a02092f02cca -F test/ioerr.test 530d05801ff1b6327018b2e140da34a74effa2773a844ddb8dc79c32e9567318 +F test/ioerr.test c94eef1cd8bfc36f9aa493e41e151e9160281ac8e2d960cc9dcdcc8e6aa99ab3 F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c -F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 +F test/ioerr5.test 5984da7bf74b6540aa356f2ab0c6ae68a6d12039a3d798a9ac6a100abc17d520 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 F test/join.test f7abfef3faeaf2800308872e33a57e5b6e4a2b44fb8c6b90c6068412e71a6cf4 @@ -1391,7 +1396,7 @@ F test/lock.test be4fe08118fb988fed741f429b7dd5d65e1c90db F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00 F test/lock4.test 27143363eda1622f03c133efc8db808fc331afd973486cb571ea71cd717d37b8 -F test/lock5.test 626571313daef2c949ce002f861042d63d81119fa62a9e999721c8bbd85e1ec9 +F test/lock5.test 24693e40a805f71d80836f720d1f2034684a39b64f1e1990989002c7968c11ee F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431 F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413 @@ -1425,7 +1430,7 @@ F test/malloctraceviewer.tcl 3e3ddf11e30d2b20f53aa16aa6615082fb24a100bea61cca721 F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 -F test/memdb1.test 2fb27d5dadd4e7784d2229e570f6368b059fc0b7fe88ca25e46e17150ba8ad4c +F test/memdb1.test c737ac9aa5895092332b1dde24fae7ae494b7fcbcd346d22d600891096a3836d F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e @@ -1439,7 +1444,7 @@ F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87 F test/misc1.test e3e36262aff1bd9b8b9bf1eeb3af04adb3fc1e23f0a92dbff708bba9e939ace1 F test/misc2.test a1a3573cc02662becd967766021d6f16c54684d56df5f227481c7ef0d9df0bd0 -F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d +F test/misc3.test 651b88bca19b8ff6a7b6af73dae00c3fd5b3ea5bee0c0d1d91abd4c4b4748718 F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db0e F test/misc5.test 027cf0ac10314ea534173f335a33bb4059907ddabbac2c16786766d6f26c8923 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 @@ -1460,7 +1465,7 @@ F test/multiplex3.test fac575e0b1b852025575a6a8357701d80933e98b5d2fe6d35ddaa68f9 F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 F test/mutex1.test 42cb5e244c3a77bb0ef2b967e06fa5e7ba7d32d90a9b20bed98f6f5ede185a25 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 -F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1 +F test/nan.test 73ea63ab43668313e2f8cc9ef9e9a966672c7934f3ce76926fbe991235d07d91 F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e F test/normalize.test f23b6c5926c59548635fcf39678ac613e726121e073dd902a3062fbb83903b72 @@ -1505,8 +1510,8 @@ F test/pagesize.test 5769fc62d8c890a83a503f67d47508dfdc543305 F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035ce4b3 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 -F test/pendingrace.test 6aa33756b950c4529f79c4f3817a9a1e4025bd0d9961571a05c0279bd183d9c6 -F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff +F test/pendingrace.test e99efc5ab3584da3dfc8cd6a0ec4e5a42214820574f5ea24ee93f1d84655f463 +F test/percentile.test 74e383216a075251512d6ba98beb9dccd6da465e3f73817fc438379e3a628de7 F test/permutations.test 405542f1d659942994a6b38a9e024cf5cfd23eaa68c806aeb24a72d7c9186e80 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 11cb9310c42f921918f7f563e3c0b6e70f9f9c3a6a1cf12af8fccb6c574f3882 @@ -1521,7 +1526,7 @@ F test/printf.test 685fec5a0c5af2490ab0632775a301554361d674211d690f5bee0a97b0533 F test/printf2.test 3f55c1871a5a65507416076f6eb97e738d5210aeda7595a74ee895f2224cce60 F test/progress.test ebab27f670bd0d4eb9d20d49cef96e68141d92fb F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc -F test/pushdown.test 3330746a897ea271b1021bc1e7e57c6f8d49bcb8ca7d58a823d01aa64a303cc7 +F test/pushdown.test 84b525767442b3695d671f9df59dd91cf0ed8fb24cbbcdc55959f0dadeee8b39 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a @@ -1533,8 +1538,8 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/readonly.test c1985f0b4ab55041f2ba629dadc6578a3ff0f0e5b0ec7912e85c51f49c3e82fe -F test/recover.test 6463509a7404e0c35431dd9b4a1c3b4a29d7a6af8a08462b31670c8a5a616d3a +F test/readonly.test 69a7ccec846cad2e000b3539d56360d02f327061dc5e41f7f9a3e01f19719952 +F test/recover.test a163a156ea9f2beea63fa83c4dcd8dea6e57b8a569fc647155e3d2754eaac1b5 F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1 F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5 F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d @@ -1542,7 +1547,7 @@ F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/returning1.test 212cd4111bb941a60abf608f20250db666c21eb1bc4d49217e96c87ff3ab9d1a F test/returningfault.test ae4c4b5e8745813287a359d9ccdb9d5c883c2e68afb18fb0767937d5de5692a4 -F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa +F test/rollback.test 952c4d805bca96adc2be76f621ea22115fe40b330015af36fcc8028c8547fcee F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190cfd4 @@ -1552,7 +1557,7 @@ F test/rowid.test d27191b5ce794c05bf61081e8b2c546a1844c1641321dcaf7fb785234256cc F test/rowvalue.test baf4fa3ec1a8c1c920c3faa5fd25959cb454bbd99ac8960397c34549d9fc4abe F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 1347e25ca11c547c5a6ff0cc5626f95aa9740e9275bfaec096029f57cb2130ce -F test/rowvalue4.test 441e7e366ac6d939a3a95a574031c56ec2a854077a91d66eee5ff1d86cb5be58 +F test/rowvalue4.test bac9326d1e886656650f67c0ec484eb5f452244a8209c6af508e9a862ace08ed F test/rowvalue5.test 00740304ea6a53a8704640c7405690f0045d5d2a6b4b04dde7bccc14c3068ea7 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba @@ -1571,7 +1576,7 @@ F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e -F test/scanstatus2.test 688adc0c3ab1ffadead218cbce6446b10aa892004a8ea5e3640d59257fb836f2 +F test/scanstatus2.test d85d17f2b0b4c013dde95232f7beab749f11f0ef847f5ecffb9486d2f5ecf9f9 F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce @@ -1614,13 +1619,13 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 17a5ca9c6f24f807b2f505b4b38fcbce143d96cd8664c06c34bbbe0672bf7c30 +F test/shell1.test 490bf9d0c7c9564fea318c46d49369f4690b825b584c9a544dbdccf61bc0babc F test/shell2.test 56da24128304c9ab67da2964cc80beff7b35761c446ec6e6e98bff2775b15026 F test/shell3.test db1953a8e59d08e9240b7cc5948878e184f7eb2623591587f8fd1f1a5bd536d8 F test/shell4.test 522fdc628c55eff697b061504fb0a9e4e6dfc5d9087a633ab0f3dd11bcc4f807 -F test/shell5.test 6a49440bddc33a132f856fb189e71228f8132963655d12a2c8b8a161263b9632 +F test/shell5.test bafa4c0b67b7a8027e729970a625c9225cb7ef854acc4e52624c45074faaaddf F test/shell6.test e3b883b61d4916b6906678a35f9d19054861123ad91b856461e0a456273bdbb8 -F test/shell7.test 753c6ece5361df50025a50cadf378ea36db9cc05fb23d7a96cff7fa130626ef9 +F test/shell7.test 43fd8e511c533bab5232e95c7b4be93b243451709e89582600d4b6e67693d5c3 F test/shell8.test aea51ecbcd4494c746b096aeff51d841d04d5f0dc4b62eb42427f16109b87acd F test/shell9.test 8742a5b390cdcef6369f5aa223e415aa4255a4129ef249b177887dc635a87209 F test/shmlock.test 3dbf017d34ab0c60abe6a44e447d3552154bd0c87b41eaf5ceacd408dd13fda5 @@ -1679,7 +1684,7 @@ F test/subquery2.test 90cf944b9de8204569cf656028391e4af1ccc8c0cc02d4ef38ee3be8de F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b F test/subtype1.test 7a9c55ed84d4ce551203d18046f925e293d75f69da81bff71aaf2696e4a2a748 -F test/superlock.test ec94f0556b6488d97f71c79f9061ae08d9ab8f12 +F test/superlock.test 85256830339a6871ce36a2ef591c3f67716a701b5497788fb2068b90159c2442 F test/swarmvtab.test 250231404fcac88f61a6c147bb0e3a118ed879278cd3ccb0ae2d3a729e1e8e26 F test/swarmvtab2.test c948cb2fdfc5b01d85e8f6d6504854202dc1a0782ab2a0ed61538f27cbd0aa5c F test/swarmvtab3.test 41a3ab47cb7a834d4e5336425103b617410a67bb95d335ef536f887587ece073 @@ -1688,7 +1693,7 @@ F test/symlink.test 4368af0e213dd6e726a6240a16f2bb96a5a58f83f2d5d60652f27547b28c F test/symlink2.test 9531f475a53d8781c4f81373f87faf2e2aff4f5fb2102ec6386e0c827916a670 F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d4333092 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 -F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d +F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test f150d206294471d20f50029e6b46b76b87a7a010b16dc57eb44245c76dd02802 F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 @@ -1702,9 +1707,9 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl fe617b88c7eb08bdf983d2aaa31c20fbf439eee7b8e0d61ca636fcd0c305bbbf -F test/testrunner.tcl 1386667c04207d0a540ce1a9bc5ee0b734f7a3ba856c14a03943fb4f32de55bb -F test/testrunner_data.tcl 3d36660cfd55ea5e20e661e8f94c0520feebcb437848f9b98b33c483cc479c0c +F test/tester.tcl 640106bf8f7785d0ac67cda2837577eb9f2d936033bacedf9e705ca5451958ef +F test/testrunner.tcl 2d100e73245e5f423942b6c198176c699137ee65192ed872bd8c9d4ac2c779b3 +F test/testrunner_data.tcl c5ae2b1f9a99210b0600d002fb3af1fee350997cee9416551e83b93501360ebf F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1725,7 +1730,7 @@ F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 -F test/tkt-2d1a5c67d.test f143872a2102c62e777be3486b38ac2744c18ece31585ed3d0afcb573ca3b4f5 +F test/tkt-2d1a5c67d.test 92bf2a2de5757d2d24ef554f8a6a38476a6735074e32dc28c775b5b9a23f96a3 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 6fb8807851964da0d24e942f2e19c7c705b9fb58 F test/tkt-313723c356.test 4b306ad45c736cedf2f5221f6155b92143244b6d @@ -1831,7 +1836,7 @@ F test/tkt3357.test 77c37c6482b526fe89941ce951c22d011f5922ed F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812 F test/tkt3442.test c9d95b4c8f4f35a51b523f35d2afd0ce124937812af296545ad551ff763504fd -F test/tkt3457.test 5651e2cbb94645b677ec663160b9e192b87b7d365aecdfb24e19f749575a6fc2 +F test/tkt3457.test 5b9cc2b6cbbf896e9b973db83f6520f43f326f4d08604372a7b0379625e28412 F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19 F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218 F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d @@ -1900,7 +1905,7 @@ F test/tt3_stress.c f9a769ca8b026ecc76ee93ca8c9700a5619f8e51c581107c4053ba6ac97f F test/tt3_vacuum.c 71b254cde1fc49d6c8c44efd54f4668f3e57d7b3a8f4601ade069f75a999ba39 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac -F test/types3.test c9db8f9e80309edfa4252585cf16bcab7ed31f39eeb904d21e831199a3613fb0 +F test/types3.test c60e89c4d6babe44b23a2ea0090f3044e549403b20648b1c6bb65a69fea5f1ed F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7 F test/unionall.test 04d30726c5056f84f92b3a12bf8d8a1dbbe807d1ddc8af95def09e6ef2dd91e3 F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1 @@ -1960,7 +1965,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca +F test/vtabH.test 8e338acba32207085b6fe9cb2a58f7b408e74c8e1a2964cbdaca903ac82213cc F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtabJ.test a6aef49d558af90fae10565b29501f82a95781cb4f797f2d13e2d19f9b6bc77b F test/vtabK.test 13293177528fada1235c0112db0d187d754af1355c5a39371abd365104e3afbf @@ -1971,8 +1976,8 @@ F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/vtabdistinct.test 7688f0889358f849fd60bbfde1ded38b014b18066076d4bfbb75395804dfe072 F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12 F test/vtabrhs1.test 9b5ecbc74a689500c33a4b2b36761f9bcc22fcc4e3f9d21066ee0c9c74cf5f6c -F test/wal.test b7cc6984709f54afbf8441747ced1f646af120bf0c1b1d847bfa39306fbea089 -F test/wal2.test 31f6e2c404b9f2cdf9ca19b105a1742fdc19653c2c936da39e3658c617524046 +F test/wal.test 519c550255c78f55959e9159b93ebbfad2b4e9f36f5b76284da41f572f9d27da +F test/wal2.test 44fe1cb4935dbbddfa0a34c2c4fd90f0ba8654d59b83c4136eb90fb327fd264f F test/wal3.test 5de023bb862fd1eb9d2ad26fa8d9c43abb5370582e5b08b2ae0d6f93661bc310 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 9c11da7aeccd83a46d79a556ad11a18d3cb15aa9 @@ -1981,11 +1986,11 @@ F test/wal64k.test 2a525c0f45d709bae3765c71045ccec5df7d100ccbd3a7860fdba46c9addb F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test d9df3fba4caad5854ed69ed673c68482514203c8 F test/wal9.test 378e76a9ad09cd9bee06c172ad3547b0129a6750 -F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe +F test/wal_common.tcl 4589f701d5527ace2eba43823c96c2177e1f9dd2a6098256ee2203a0a313c13a F test/walbak.test 018d4e5a3d45c6298d11b99f09a8ef6876527946 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d -F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 +F test/walcksum.test ba02b4fe6d22cb42e57a323003cbae62f77a740983e1355b2b520e019ae261c7 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af @@ -2005,7 +2010,7 @@ F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cf F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b F test/walsetlk.test 34c901443b31ab720afc463f5b236c86ca5c4134402573dce91aa0761de8db5a F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 -F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f +F test/walslow.test 0c51843836c9dcf40a5ac05aa781bfb977b396ee2c872d92bd48b79d5dd9aa23 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test e1a6ad0f3c78e98b55c3d5f0889cf366cc0d0a1cb2bccb44ac9ec67384adc4a1 F test/where.test 59abb854eee24f166b5f7ba9d17eb250abc59ce0a66c48912ffb10763648196d @@ -2039,7 +2044,7 @@ F test/wherelimit3.test 22d73e046870cf8bbe15573eda6b432b07ebe64a88711f9f849c6b36 F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1 F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74 F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c -F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976 +F test/win32longpath.test 42210789bcfc5c0ac202643d6d0237db08df2c9218f2070d9a69e8af1eccf7d7 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc F test/window1.test 79dc3b9a2226f622d7e104a1fc750d1c4c3c08d6147b59085bdbe05352947ffa F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 @@ -2083,8 +2088,8 @@ F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501d F test/zeroblob.test 7b74cefc7b281dfa2b07cd237987fbe94b4a2037a7771e9e83f2d5f608b1d99e F test/zeroblobfault.test 861d8191a0d944dfebb3cb4d2c5b4e46a5a119eaec5a63dd996c2389f8063441 F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc -F test/zipfile.test 416adb0ca9bb54f978fe2e77978b1b964ce5e1c0199f45e381caa771e9f8cfc1 -F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d +F test/zipfile.test a36327c5697a03150a313ba06ab45842facef8b0c21be19d73a3a4fee58bc54c +F test/zipfile2.test 6df5f5ef9d247756f7200066f43e7f3f52cffff47f0c02cbefe4ce9c3284cb10 F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44 F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e04534bbf @@ -2120,7 +2125,7 @@ F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd -F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d +F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa @@ -2133,14 +2138,14 @@ F tool/mksqlite3c.tcl c6acfdf4e4ef93478ff3ce3cd593e17abb03f446036ce710c3156bcfa1 F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617f8423 -F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 +F tool/mkvsix.tcl 67b40996a50f985a573278eea32fc5a5eb6110bdf14d33f1d8086e48c69e540a F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 F tool/omittest.tcl e99c9fecc3f7a8ca2fa75d8ec8bdbb5acce33dc69f0c280aae53064693387f65 F tool/opcodesum.tcl 740ed206ba8c5040018988129abbf3089a0ccf4a F tool/pagesig.c ff0ca355fd3c2398e933da5e22439bbff89b803b -F tool/replace.tcl 937c931ad560688e85bdd6258bdc754371bb1e2732e1fb28ef441e44c9228fce -F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a +F tool/replace.tcl 511c61acfe563dfb58675efb4628bb158a13d48ff8322123ac447e9d25a82d9a +F tool/restore_jrnl.tcl 1079ecba47cc82fa82115b81c1f68097ab1f956f357ee8da5fc4b2589af6bd98 F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 F tool/showdb.c 0f74b54cc67076c76cba9b2b7f54d3e05b78d130c70ffc394eb84c5b41bab017 @@ -2159,7 +2164,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 -F tool/sqldiff.c 1e0a2c264c2ad5aca745d35deee3c7715cb00c703839cfb0b85be079db55194c +F tool/sqldiff.c 847fc8fcfddf5ce4797b7394cad6372f2f5dc17d8186e2ef8fb44d50fae4f44a F tool/sqlite3_analyzer.c.in 8da2b08f56eeac331a715036cf707cc20f879f231362be0c22efd682e2b89b4f F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 @@ -2194,12 +2199,12 @@ F vsixtest/Package.appxmanifest 6b6db1eb7df3a315c5d681059754d5f0e0c47a93 F vsixtest/pch.cpp cb823cfac36f1a39a7eb0acbd7e9a0b0de8f23af F vsixtest/pch.h 9cab7980f2ac4baa40807d8b5e52af32a21cf78c F vsixtest/vsixtest.sln 77cadbe4e96c1fe1bf51cd77de9e9b0a12ada547 -F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 +F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080bb302912 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8e3a1d2850337a902ab36b1d6a0dad4ae35030b71d1e15547f6e7487c1f86d18 d07085e2035b52a7edd27980523225e59c5bf851fb4a6de975f03e653b937c9c -R 4bccf9946bb839298bd611ecb98c6563 +P fc643f8a12e9b7448136b281f798e18dfebe0a3df5115d930b965c8a33933e2d ea9d88f9ca3399bca83bf03893689a927b73e481604b94527e42de43f103eb46 +R 9c00435044c1639ccc94034122bfb21c U drh -Z fabaa312611792ffca3e18aa282f1001 +Z 82c98548b7e1b613f913739aef63c0fc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 499a42453..3b6545ee3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc643f8a12e9b7448136b281f798e18dfebe0a3df5115d930b965c8a33933e2d +9084a4c8726a2c7ba1c381886e29c7b86121d531282be0d63d5988d84f6f448d diff --git a/src/analyze.c b/src/analyze.c index 8c48a8ff2..774eeeed2 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1832,6 +1832,7 @@ static int loadStatTbl( return SQLITE_NOMEM_BKPT; } pSpace = (tRowcnt*)&pIdx->aSample[nSample]; + assert( EIGHT_BYTE_ALIGNMENT( pSpace ) ); pIdx->aAvgEq = pSpace; pSpace += nIdxCol; pIdx->pTable->tabFlags |= TF_HasStat4; for(i=0; i<nSample; i++){ diff --git a/src/expr.c b/src/expr.c index bda91df83..53b0170ab 100644 --- a/src/expr.c +++ b/src/expr.c @@ -85,7 +85,9 @@ char sqlite3ExprAffinity(const Expr *pExpr){ op = pExpr->op; continue; } - if( op!=TK_REGISTER || (op = pExpr->op2)==TK_REGISTER ) break; + if( op!=TK_REGISTER ) break; + op = pExpr->op2; + if( NEVER( op==TK_REGISTER ) ) break; } return pExpr->affExpr; } @@ -3420,6 +3422,49 @@ void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY /* +** Scan all previously generated bytecode looking for an OP_BeginSubrtn +** that is compatible with pExpr. If found, add the y.sub values +** to pExpr and return true. If not found, return false. +*/ +static int findCompatibleInRhsSubrtn( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* IN operator with RHS that we want to reuse */ + SubrtnSig *pNewSig /* Signature for the IN operator */ +){ + VdbeOp *pOp, *pEnd; + SubrtnSig *pSig; + Vdbe *v; + + if( pNewSig==0 ) return 0; + if( (pParse->mSubrtnSig & (1<<(pNewSig->selId&7)))==0 ) return 0; + assert( pExpr->op==TK_IN ); + assert( !ExprUseYSub(pExpr) ); + assert( ExprUseXSelect(pExpr) ); + assert( pExpr->x.pSelect!=0 ); + assert( (pExpr->x.pSelect->selFlags & SF_All)==0 ); + v = pParse->pVdbe; + assert( v!=0 ); + pOp = sqlite3VdbeGetOp(v, 1); + pEnd = sqlite3VdbeGetLastOp(v); + for(; pOp<pEnd; pOp++){ + if( pOp->p4type!=P4_SUBRTNSIG ) continue; + assert( pOp->opcode==OP_BeginSubrtn ); + pSig = pOp->p4.pSubrtnSig; + assert( pSig!=0 ); + if( pNewSig->selId!=pSig->selId ) continue; + if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; + pExpr->y.sub.iAddr = pSig->iAddr; + pExpr->y.sub.regReturn = pSig->regReturn; + pExpr->iTable = pSig->iTable; + ExprSetProperty(pExpr, EP_Subrtn); + return 1; + } + return 0; +} +#endif /* SQLITE_OMIT_SUBQUERY */ + +#ifndef SQLITE_OMIT_SUBQUERY +/* ** Generate code that will construct an ephemeral table containing all terms ** in the RHS of an IN operator. The IN operator can be in either of two ** forms: @@ -3467,11 +3512,28 @@ void sqlite3CodeRhsOfIN( ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ - /* Reuse of the RHS is allowed */ - /* If this routine has already been coded, but the previous code - ** might not have been invoked yet, so invoke it now as a subroutine. + /* Reuse of the RHS is allowed + ** + ** Compute a signature for the RHS of the IN operator to facility + ** finding and reusing prior instances of the same IN operator. */ - if( ExprHasProperty(pExpr, EP_Subrtn) ){ + SubrtnSig *pSig = 0; + assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); + if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ + pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); + if( pSig ){ + pSig->selId = pExpr->x.pSelect->selId; + pSig->zAff = exprINAffinity(pParse, pExpr); + } + } + + /* Check to see if there is a prior materialization of the RHS of + ** this IN operator. If there is, then make use of that prior + ** materialization rather than recomputing it. + */ + if( ExprHasProperty(pExpr, EP_Subrtn) + || findCompatibleInRhsSubrtn(pParse, pExpr, pSig) + ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", @@ -3483,6 +3545,10 @@ void sqlite3CodeRhsOfIN( assert( iTab!=pExpr->iTable ); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeJumpHere(v, addrOnce); + if( pSig ){ + sqlite3DbFree(pParse->db, pSig->zAff); + sqlite3DbFree(pParse->db, pSig); + } return; } @@ -3493,7 +3559,13 @@ void sqlite3CodeRhsOfIN( pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; - + if( pSig ){ + pSig->iAddr = pExpr->y.sub.iAddr; + pSig->regReturn = pExpr->y.sub.regReturn; + pSig->iTable = iTab; + pParse->mSubrtnSig = 1 << (pSig->selId&7); + sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); + } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } @@ -3534,19 +3606,34 @@ void sqlite3CodeRhsOfIN( SelectDest dest; int i; int rc; + int addrBloom = 0; sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; + if( addrOnce && OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + int regBloom = ++pParse->nMem; + addrBloom = sqlite3VdbeAddOp2(v, OP_Blob, 10000, regBloom); + VdbeComment((v, "Bloom filter")); + dest.iSDParm2 = regBloom; + } testcase( pSelect->selFlags & SF_Distinct ); testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ pCopy = sqlite3SelectDup(pParse->db, pSelect, 0); rc = pParse->db->mallocFailed ? 1 :sqlite3Select(pParse, pCopy, &dest); sqlite3SelectDelete(pParse->db, pCopy); sqlite3DbFree(pParse->db, dest.zAffSdst); + if( addrBloom ){ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + if( dest.iSDParm2==0 ){ + sqlite3VdbeChangeToNoop(v, addrBloom); + }else{ + sqlite3VdbeGetOp(v, addrOnce)->p3 = dest.iSDParm2; + } + } if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; - } + } assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); @@ -3840,9 +3927,7 @@ static void sqlite3ExprCodeIN( if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); nVector = sqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)sqlite3DbMallocZero( - pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 - ); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, nVector*sizeof(int)); if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than @@ -3985,6 +4070,15 @@ static void sqlite3ExprCodeIN( sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + const VdbeOp *pOp = sqlite3VdbeGetOp(v, pExpr->y.sub.iAddr); + assert( pOp->opcode==OP_Once || pParse->nErr ); + if( pOp->opcode==OP_Once && pOp->p3>0 ){ + assert( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ); + sqlite3VdbeAddOp4Int(v, OP_Filter, pOp->p3, destIfFalse, + rLhs, nVector); VdbeCoverage(v); + } + } sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); goto sqlite3ExprCodeIN_finished; @@ -4270,10 +4364,14 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ void sqlite3ExprToRegister(Expr *pExpr, int iReg){ Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); if( NEVER(p==0) ) return; - p->op2 = p->op; - p->op = TK_REGISTER; - p->iTable = iReg; - ExprClearProperty(p, EP_Skip); + if( p->op==TK_REGISTER ){ + assert( p->iTable==iReg ); + }else{ + p->op2 = p->op; + p->op = TK_REGISTER; + p->iTable = iReg; + ExprClearProperty(p, EP_Skip); + } } /* diff --git a/src/pager.c b/src/pager.c index 268dc7db3..1ac858a07 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4064,6 +4064,7 @@ static int pagerAcquireMapPage( return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; + assert( EIGHT_BYTE_ALIGNMENT( p->pExtra ) ); p->flags = PGHDR_MMAP; p->nRef = 1; p->pPager = pPager; diff --git a/src/pcache.c b/src/pcache.c index 2974b0810..3429284dc 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -512,6 +512,7 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pData = pPage->pBuf; pPgHdr->pExtra = (void *)&pPgHdr[1]; memset(pPgHdr->pExtra, 0, 8); + assert( EIGHT_BYTE_ALIGNMENT( pPgHdr->pExtra ) ); pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; diff --git a/src/pcache1.c b/src/pcache1.c index 1591f014c..a0a8c7e28 100644 --- a/src/pcache1.c +++ b/src/pcache1.c @@ -320,7 +320,8 @@ static int pcache1InitBulk(PCache1 *pCache){ do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; - pX->page.pExtra = &pX[1]; + pX->page.pExtra = (u8*)pX + ROUND8(sizeof(*pX)); + assert( EIGHT_BYTE_ALIGNMENT( pX->page.pExtra ) ); pX->isBulkLocal = 1; pX->isAnchor = 0; pX->pNext = pCache->pFree; @@ -457,7 +458,8 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ if( pPg==0 ) return 0; p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage]; p->page.pBuf = pPg; - p->page.pExtra = &p[1]; + p->page.pExtra = (u8*)p + ROUND8(sizeof(*p)); + assert( EIGHT_BYTE_ALIGNMENT( p->page.pExtra ) ); p->isBulkLocal = 0; p->isAnchor = 0; p->pLruPrev = 0; /* Initializing this saves a valgrind error */ diff --git a/src/select.c b/src/select.c index f2d44bf36..6a4d0397f 100644 --- a/src/select.c +++ b/src/select.c @@ -1377,12 +1377,18 @@ static void selectInnerLoop( ** case the order does matter */ pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); + pDest->iSDParm2 = 0; /* Signal that any Bloom filter is unpopulated */ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + if( pDest->iSDParm2 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + regResult, nResultCol); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); } break; @@ -3316,6 +3322,11 @@ static int generateOutputSubroutine( r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); + if( pDest->iSDParm2>0 ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pDest->iSDParm2, 0, + pIn->iSdst, pIn->nSdst); + ExplainQueryPlan((pParse, 0, "CREATE BLOOM FILTER")); + } sqlite3ReleaseTempReg(pParse, r1); break; } @@ -5066,7 +5077,8 @@ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ ** ** NAME AMBIGUITY ** -** This optimization is called the "WHERE-clause push-down optimization". +** This optimization is called the "WHERE-clause push-down optimization" +** or sometimes the "predicate push-down optimization". ** ** Do not confuse this optimization with another unrelated optimization ** with a similar name: The "MySQL push-down optimization" causes WHERE @@ -8500,7 +8512,10 @@ int sqlite3Select( if( iOrderByCol ){ Expr *pX = p->pEList->a[iOrderByCol-1].pExpr; Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX); - if( ALWAYS(pBase!=0) && pBase->op!=TK_AGG_COLUMN ){ + if( ALWAYS(pBase!=0) + && pBase->op!=TK_AGG_COLUMN + && pBase->op!=TK_REGISTER + ){ sqlite3ExprToRegister(pX, iAMem+j); } } diff --git a/src/shell.c.in b/src/shell.c.in index a5bfab589..f389c1f47 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1200,6 +1200,7 @@ INCLUDE ../ext/misc/pcachetrace.c INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/uint.c INCLUDE ../ext/misc/decimal.c +INCLUDE ../ext/misc/percentile.c #undef sqlite3_base_init #define sqlite3_base_init sqlite3_base64_init INCLUDE ../ext/misc/base64.c @@ -5374,6 +5375,7 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_uint_init(p->db, 0, 0); sqlite3_stmtrand_init(p->db, 0, 0); sqlite3_decimal_init(p->db, 0, 0); + sqlite3_percentile_init(p->db, 0, 0); sqlite3_base64_init(p->db, 0, 0); sqlite3_base85_init(p->db, 0, 0); sqlite3_regexp_init(p->db, 0, 0); @@ -11974,27 +11976,29 @@ static char *find_home_dir(int clearFlag){ /* ** On non-Windows platforms, look for $XDG_CONFIG_HOME. ** If ${XDG_CONFIG_HOME}/sqlite3/sqliterc is found, return -** the path to it, else return 0. The result is cached for -** subsequent calls. +** the path to it. If there is no $(XDG_CONFIG_HOME) then +** look for $(HOME)/.config/sqlite3/sqliterc and if found +** return that. If none of these are found, return 0. +** +** The string returned is obtained from sqlite3_malloc() and +** should be freed by the caller. */ -static const char *find_xdg_config(void){ +static char *find_xdg_config(void){ #if defined(_WIN32) || defined(WIN32) || defined(_WIN32_WCE) \ || defined(__RTP__) || defined(_WRS_KERNEL) return 0; #else - static int alreadyTried = 0; - static char *zConfig = 0; + char *zConfig = 0; const char *zXdgHome; - if( alreadyTried!=0 ){ - return zConfig; - } - alreadyTried = 1; zXdgHome = getenv("XDG_CONFIG_HOME"); if( zXdgHome==0 ){ - return 0; + const char *zHome = getenv("HOME"); + if( zHome==0 ) return 0; + zConfig = sqlite3_mprintf("%s/.config/sqlite3/sqliterc", zHome); + }else{ + zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); } - zConfig = sqlite3_mprintf("%s/sqlite3/sqliterc", zXdgHome); shell_check_oom(zConfig); if( access(zConfig,0)!=0 ){ sqlite3_free(zConfig); @@ -12022,7 +12026,7 @@ static void process_sqliterc( int savedLineno = p->lineno; if( sqliterc == NULL ){ - sqliterc = find_xdg_config(); + sqliterc = zBuf = find_xdg_config(); } if( sqliterc == NULL ){ home_dir = find_home_dir(0); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 183fb2a08..027c0e62d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5820,7 +5820,7 @@ int sqlite3_value_encoding(sqlite3_value*); ** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. ** -** Every [application-defined SQL function] that invoke this interface +** Every [application-defined SQL function] that invokes this interface ** should include the [SQLITE_SUBTYPE] property in the text ** encoding argument when the function is [sqlite3_create_function|registered]. ** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype() diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 44914065c..bfe0bf94b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -143,10 +143,13 @@ /* ** Macro to disable warnings about missing "break" at the end of a "case". */ -#if GCC_VERSION>=7000000 -# define deliberate_fall_through __attribute__((fallthrough)); -#else -# define deliberate_fall_through +#if defined(__has_attribute) +# if __has_attribute(fallthrough) +# define deliberate_fall_through __attribute__((fallthrough)); +# endif +#endif +#if !defined(deliberate_fall_through) +# define deliberate_fall_through #endif /* @@ -3621,7 +3624,11 @@ struct Select { ** SRT_Set The result must be a single column. Store each ** row of result as the key in table pDest->iSDParm. ** Apply the affinity pDest->affSdst before storing -** results. Used to implement "IN (SELECT ...)". +** results. if pDest->iSDParm2 is positive, then it is +** a regsiter holding a Bloom filter for the IN operator +** that should be populated in addition to the +** pDest->iSDParm table. This SRT is used to +** implement "IN (SELECT ...)". ** ** SRT_EphemTab Create an temporary table pDest->iSDParm and store ** the result there. The cursor is left open after @@ -3830,6 +3837,7 @@ struct Parse { u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ u8 bHasWith; /* True if statement contains WITH */ u8 bHasExists; /* Has a correlated "EXISTS (SELECT ....)" expression */ + u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d91b2fa3f..906f429ab 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -35,14 +35,23 @@ # include "msvc.h" #endif +/****** Copy of tclsqlite.h ******/ #if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" +# include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ #else -# include "tcl.h" +# include <tcl.h> /* All normal cases */ # ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI +# define SQLITE_TCLAPI # endif #endif +/* Compatability between Tcl8.6 and Tcl9.0 */ +#if TCL_MAJOR_VERSION==9 +# define CONST const +#else + typedef int Tcl_Size; +#endif +/**** End copy of tclsqlite.h ****/ + #include <errno.h> /* @@ -209,7 +218,8 @@ struct SqliteDb { struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ - int iSeek; /* Current seek offset */ + sqlite3_int64 iSeek; /* Current seek offset */ + unsigned int isClosed; /* TCL_CLOSE_READ or TCL_CLOSE_WRITE */ Tcl_Channel channel; /* Channel identifier */ IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ @@ -249,14 +259,23 @@ static void closeIncrblobChannels(SqliteDb *pDb){ /* ** Close an incremental blob channel. */ -static int SQLITE_TCLAPI incrblobClose( +static int SQLITE_TCLAPI incrblobClose2( ClientData instanceData, - Tcl_Interp *interp + Tcl_Interp *interp, + int flags ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int rc = sqlite3_blob_close(p->pBlob); + int rc; sqlite3 *db = p->pDb->db; + if( flags ){ + p->isClosed |= flags; + return TCL_OK; + } + + /* If we reach this point, then we really do need to close the channel */ + rc = sqlite3_blob_close(p->pBlob); + /* Remove the channel from the SqliteDb.pIncrblob list. */ if( p->pNext ){ p->pNext->pPrev = p->pPrev; @@ -277,6 +296,13 @@ static int SQLITE_TCLAPI incrblobClose( } return TCL_OK; } +static int SQLITE_TCLAPI incrblobClose( + ClientData instanceData, + Tcl_Interp *interp +){ + return incrblobClose2(instanceData, interp, 0); +} + /* ** Read data from an incremental blob channel. @@ -288,9 +314,9 @@ static int SQLITE_TCLAPI incrblobInput( int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int nRead = bufSize; /* Number of bytes to read */ - int nBlob; /* Total size of the blob */ - int rc; /* sqlite error code */ + sqlite3_int64 nRead = bufSize; /* Number of bytes to read */ + sqlite3_int64 nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nRead)>nBlob ){ @@ -300,7 +326,7 @@ static int SQLITE_TCLAPI incrblobInput( return 0; } - rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek); + rc = sqlite3_blob_read(p->pBlob, (void *)buf, (int)nRead, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = rc; return -1; @@ -320,9 +346,9 @@ static int SQLITE_TCLAPI incrblobOutput( int *errorCodePtr ){ IncrblobChannel *p = (IncrblobChannel *)instanceData; - int nWrite = toWrite; /* Number of bytes to write */ - int nBlob; /* Total size of the blob */ - int rc; /* sqlite error code */ + sqlite3_int64 nWrite = toWrite; /* Number of bytes to write */ + sqlite3_int64 nBlob; /* Total size of the blob */ + int rc; /* sqlite error code */ nBlob = sqlite3_blob_bytes(p->pBlob); if( (p->iSeek+nWrite)>nBlob ){ @@ -333,7 +359,7 @@ static int SQLITE_TCLAPI incrblobOutput( return 0; } - rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek); + rc = sqlite3_blob_write(p->pBlob, (void*)buf,(int)nWrite, (int)p->iSeek); if( rc!=SQLITE_OK ){ *errorCodePtr = EIO; return -1; @@ -346,9 +372,9 @@ static int SQLITE_TCLAPI incrblobOutput( /* ** Seek an incremental blob channel. */ -static int SQLITE_TCLAPI incrblobSeek( +static long long SQLITE_TCLAPI incrblobWideSeek( ClientData instanceData, - long offset, + long long offset, int seekMode, int *errorCodePtr ){ @@ -370,6 +396,14 @@ static int SQLITE_TCLAPI incrblobSeek( return p->iSeek; } +static int SQLITE_TCLAPI incrblobSeek( + ClientData instanceData, + long offset, + int seekMode, + int *errorCodePtr +){ + return incrblobWideSeek(instanceData,offset,seekMode,errorCodePtr); +} static void SQLITE_TCLAPI incrblobWatch( @@ -388,7 +422,7 @@ static int SQLITE_TCLAPI incrblobHandle( static Tcl_ChannelType IncrblobChannelType = { "incrblob", /* typeName */ - TCL_CHANNEL_VERSION_2, /* version */ + TCL_CHANNEL_VERSION_5, /* version */ incrblobClose, /* closeProc */ incrblobInput, /* inputProc */ incrblobOutput, /* outputProc */ @@ -397,11 +431,11 @@ static Tcl_ChannelType IncrblobChannelType = { 0, /* getOptionProc */ incrblobWatch, /* watchProc (this is a no-op) */ incrblobHandle, /* getHandleProc (always returns error) */ - 0, /* close2Proc */ + incrblobClose2, /* close2Proc */ 0, /* blockModeProc */ 0, /* flushProc */ 0, /* handlerProc */ - 0, /* wideSeekProc */ + incrblobWideSeek, /* wideSeekProc */ }; /* @@ -433,8 +467,9 @@ static int createIncrblobChannel( } p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); - p->iSeek = 0; + memset(p, 0, sizeof(*p)); p->pBlob = pBlob; + if( (flags & TCL_WRITABLE)==0 ) p->isClosed |= TCL_CLOSE_WRITE; sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); @@ -474,7 +509,7 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ ** characters appear in pCmd, we will report the string as unsafe. */ const char *z; - int n; + Tcl_Size n; z = Tcl_GetStringFromObj(pCmd, &n); while( n-- > 0 ){ int c = *(z++); @@ -981,7 +1016,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ ** be preserved and reused on the next invocation. */ Tcl_Obj **aArg; - int nArg; + Tcl_Size nArg; if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); return; @@ -1044,7 +1079,7 @@ static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); }else{ Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); - int n; + Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); char c = zType[0]; @@ -1455,7 +1490,7 @@ static int dbPrepareAndBind( } } if( pVar ){ - int n; + Tcl_Size n; u8 *data; const char *zType = (pVar->typePtr ? pVar->typePtr->name : ""); c = zType[0]; @@ -1469,8 +1504,9 @@ static int dbPrepareAndBind( Tcl_IncrRefCount(pVar); pPreStmt->apParm[iParm++] = pVar; }else if( c=='b' && strcmp(zType,"boolean")==0 ){ - Tcl_GetIntFromObj(interp, pVar, &n); - sqlite3_bind_int(pStmt, i, n); + int nn; + Tcl_GetIntFromObj(interp, pVar, &nn); + sqlite3_bind_int(pStmt, i, nn); }else if( c=='d' && strcmp(zType,"double")==0 ){ double r; Tcl_GetDoubleFromObj(interp, pVar, &r); @@ -2034,7 +2070,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zAuth; - int len; + Tcl_Size len; if( pDb->zAuth ){ Tcl_Free(pDb->zAuth); } @@ -2137,7 +2173,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zCallback; - int len; + Tcl_Size len; if( pDb->zBindFallback ){ Tcl_Free(pDb->zBindFallback); } @@ -2167,7 +2203,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ char *zBusy; - int len; + Tcl_Size len; if( pDb->zBusy ){ Tcl_Free(pDb->zBusy); } @@ -2274,7 +2310,7 @@ static int SQLITE_TCLAPI DbObjCmd( SqlCollate *pCollate; char *zName; char *zScript; - int nScript; + Tcl_Size nScript; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); return TCL_ERROR; @@ -2333,7 +2369,7 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ const char *zCommit; - int len; + Tcl_Size len; if( pDb->zCommit ){ Tcl_Free(pDb->zCommit); } @@ -2653,7 +2689,8 @@ static int SQLITE_TCLAPI DbObjCmd( Tcl_Obj *pValue = 0; unsigned char *pBA; unsigned char *pData; - int len, xrc; + Tcl_Size len; + int xrc; sqlite3_int64 mxSize = 0; int i; int isReadonly = 0; @@ -3024,7 +3061,7 @@ deserialize_error: return TCL_ERROR; } if( objc==3 ){ - int len; + Tcl_Size len; char *zNull = Tcl_GetStringFromObj(objv[2], &len); if( pDb->zNull ){ Tcl_Free(pDb->zNull); @@ -3078,7 +3115,7 @@ deserialize_error: #endif }else if( objc==4 ){ char *zProgress; - int len; + Tcl_Size len; int N; if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ return TCL_ERROR; @@ -3124,7 +3161,7 @@ deserialize_error: } }else{ char *zProfile; - int len; + Tcl_Size len; if( pDb->zProfile ){ Tcl_Free(pDb->zProfile); } @@ -3335,7 +3372,7 @@ deserialize_error: } }else{ char *zTrace; - int len; + Tcl_Size len; if( pDb->zTrace ){ Tcl_Free(pDb->zTrace); } @@ -3375,7 +3412,7 @@ deserialize_error: } }else{ char *zTraceV2; - int len; + Tcl_Size len; Tcl_WideInt wMask = 0; if( objc==4 ){ static const char *TTYPE_strs[] = { @@ -3961,14 +3998,25 @@ EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} +/* +** Versions of all of the above entry points that omit the "3" at the end +** of the name. Years ago (circa 2004) the "3" was necessary to distinguish +** SQLite version 3 from Sqlite version 2. But two decades have elapsed. +** SQLite2 is not longer a conflict. So it is ok to omit the "3". +** +** Omitting the "3" helps TCL find the entry point. +*/ +EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} +EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } +EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } +EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } +EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; } +EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;} +/* Also variants with a lowercase "s" */ +EXTERN int sqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} +EXTERN int sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp);} -#ifndef SQLITE_3_SUFFIX_ONLY -int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } -int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } -int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } -#endif /* ** If the TCLSH macro is defined, add code to make a stand-alone program. diff --git a/src/tclsqlite.h b/src/tclsqlite.h new file mode 100644 index 000000000..b9a948ef1 --- /dev/null +++ b/src/tclsqlite.h @@ -0,0 +1,42 @@ +/* +** 2024-07-30 +** +** 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 header file defines the interface to TCL as used by SQLite. +** SQLite subcomponents that use TCL (the libsqlite3.c interface library +** and various test*.c pieces) should #include this file rather than +** including tcl.h directly. +*/ +/****** Any edits to this file must mirrored in tclsqlite.c ***********/ + +/* When compiling for Windows using STDCALL instead of CDECL calling +** conventions, the MSVC makefile has to build a customized version of +** the "tcl.h" header that specifies the calling conventions for each +** interface. That customized "tcl.h" is named "sqlite_tcl.h". +*/ +#if defined(INCLUDE_SQLITE_TCL_H) +# include "sqlite_tcl.h" /* Special case for Windows using STDCALL */ +#else +# include <tcl.h> /* All normal cases */ +# ifndef SQLITE_TCLAPI +# define SQLITE_TCLAPI +# endif +#endif + +/****** Any edits to this file must mirrored in tclsqlite.c ***********/ + +/* Compatability between Tcl8.6 and Tcl9.0 */ +#if TCL_MAJOR_VERSION==9 +# define CONST const +#else + typedef int Tcl_Size; +#endif + +/****** Any edits to this file must mirrored in tclsqlite.c ***********/ diff --git a/src/test1.c b/src/test1.c index 975758131..88bfdc06d 100644 --- a/src/test1.c +++ b/src/test1.c @@ -26,11 +26,7 @@ #endif #include "vdbeInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> @@ -1772,7 +1768,7 @@ static int SQLITE_TCLAPI blobHandleFromObj( sqlite3_blob **ppBlob ){ char *z; - int n; + Tcl_Size n; z = Tcl_GetStringFromObj(pObj, &n); if( n==0 ){ @@ -2339,13 +2335,13 @@ static int SQLITE_TCLAPI test_stmt_scanstatus( }; Tcl_Obj **aFlag = 0; - int nFlag = 0; + Tcl_Size nFlag = 0; int ii; if( Tcl_ListObjGetElements(interp, objv[2], &nFlag, &aFlag) ){ return TCL_ERROR; } - for(ii=0; ii<nFlag; ii++){ + for(ii=0; ii<(int)nFlag; ii++){ int iVal = 0; int res = Tcl_GetIndexFromObjStruct( interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal @@ -2766,7 +2762,7 @@ static int SQLITE_TCLAPI test_snapshot_open_blob( sqlite3 *db; char *zName; unsigned char *pBlob; - int nBlob; + Tcl_Size nBlob; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SNAPSHOT"); @@ -2801,8 +2797,8 @@ static int SQLITE_TCLAPI test_snapshot_cmp_blob( int res; unsigned char *p1; unsigned char *p2; - int n1; - int n2; + Tcl_Size n1; + Tcl_Size n2; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); @@ -4102,7 +4098,7 @@ static int SQLITE_TCLAPI test_bind_text( ){ sqlite3_stmt *pStmt; int idx; - int trueLength = 0; + Tcl_Size trueLength = 0; int bytes; char *value; int rc; @@ -4160,7 +4156,7 @@ static int SQLITE_TCLAPI test_bind_text16( char *value; char *toFree = 0; int rc; - int trueLength = 0; + Tcl_Size trueLength = 0; void (*xDel)(void*) = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT); Tcl_Obj *oStmt = objv[objc-4]; @@ -4214,7 +4210,8 @@ static int SQLITE_TCLAPI test_bind_blob( Tcl_Obj *CONST objv[] ){ sqlite3_stmt *pStmt; - int len, idx; + Tcl_Size len; + int idx; int bytes; char *value; int rc; @@ -4240,7 +4237,7 @@ static int SQLITE_TCLAPI test_bind_blob( if( bytes>len ){ char zBuf[200]; sqlite3_snprintf(sizeof(zBuf), zBuf, - "cannot use %d blob bytes, have %d", bytes, len); + "cannot use %d blob bytes, have %d", bytes, (int)len); Tcl_AppendResult(interp, zBuf, (char*)0); return TCL_ERROR; } @@ -4538,9 +4535,9 @@ static int SQLITE_TCLAPI test_carray_bind( struct iovec *a = sqlite3_malloc( sizeof(struct iovec)*nData ); if( a==0 ){ rc = SQLITE_NOMEM; goto carray_bind_done; } for(j=0; j<nData; j++){ - int n = 0; + Tcl_Size n = 0; unsigned char *v = Tcl_GetByteArrayFromObj(objv[i+i], &n); - a[j].iov_len = n; + a[j].iov_len = (size_t)n; a[j].iov_base = sqlite3_malloc64( n ); if( a[j].iov_base==0 ){ a[j].iov_len = 0; @@ -5116,7 +5113,7 @@ static int SQLITE_TCLAPI test_prepare16( char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ - int objlen; /* The byte-array length of arg 2 */ + Tcl_Size objlen; /* The byte-array length of arg 2 */ if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -5176,7 +5173,7 @@ static int SQLITE_TCLAPI test_prepare16_v2( char zBuf[50]; int rc; int bytes; /* The integer specified as arg 3 */ - int objlen; /* The byte-array length of arg 2 */ + Tcl_Size objlen; /* The byte-array length of arg 2 */ if( objc!=5 && objc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", @@ -5256,9 +5253,9 @@ static int SQLITE_TCLAPI test_open_v2( int rc; char zBuf[100]; - int nFlag; + Tcl_Size nFlag; Tcl_Obj **apFlag; - int i; + Tcl_Size i; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "FILENAME FLAGS VFS"); @@ -5967,6 +5964,145 @@ static int SQLITE_TCLAPI tcl_variable_type( return TCL_OK; } +#include <ctype.h> + +/* +** Usage: fpnum_compare STRING1 STRING2 +** +** Compare two strings. Return true if the strings are the same and +** false if they differ. +** +** For this comparison, the strings are analyzed as a sequenced of +** whitespace separated tokens. The whitespace is ignored. Only the +** tokens are compared. Comparison rules: +** +** A. Tokens that are not floating-point numbers must match exactly. +** +** B. Floating point number must have exactly the same digits before +** the decimal point. +** +** C. Digits must match after the decimal point up to 15 digits, +** taking rounding into consideration. +** +** D. An exponent on a floating point of the form "e+NN" will +** match "e+N" if NN==N. Likewise for the negative exponent. +** +** This routine is used for comparing results that might involve floating +** point values. Tcl9.0 and Tcl8.6 differ in the number of significant +** digits that they show, so there is no way to write a portable test result +** without this routine. +** +** This routine is only called after [string compare] fails, which is seldom, +** so performance is not a pressing concern. Better to get the correct answer +** slowly. +*/ +static int SQLITE_TCLAPI fpnum_compare( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + const unsigned char *zA; + const unsigned char *zB; + int i, j; + int nDigit; + + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "STRING1 STRING2"); + return TCL_ERROR; + } + zA = (const unsigned char*)Tcl_GetString(objv[1]); + zB = (const unsigned char*)Tcl_GetString(objv[2]); + i = j = 0; + while( 1 ){ + /* Skip whitespace before and after tokens */ + while( isspace(zA[i]) ){ i++; } + while( isspace(zB[j]) ){ j++; } + + if( zA[i]!=zB[j] ) break; /* First character must match */ + if( zA[i]=='-' && isdigit(zA[i+1]) ){ i++; j++; } /* Skip initial '-' */ + if( !isdigit(zA[i]) ){ + /* Not a number. Must match exactly */ + while( !isspace(zA[i]) && zA[i] && zA[i]==zB[j] ){ i++; j++; } + if( zA[i]!=zB[j] ) break; + if( isspace(zA[i]) ) continue; + break; + } + + /* At this point we know we are dealing with a number zA[i] and zB[j] + ** are both digits (leading "-" have been skipped). See if they are + ** the same number. Start by matching digits before the decimal + ** point, which must all be the same. */ + nDigit = 0; + while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; nDigit++; } + if( zA[i]!=zB[j] ) break; + if( zA[i]==0 ) break; + if( zA[i]=='.' && zB[j]=='.' ){ + /* Count more matching digits after the decimal point */ + i++; + j++; + while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; nDigit++; } + if( zA[i]==0 ){ + while( zB[j]=='0' || (isdigit(zB[j]) && nDigit>=15) ){ j++; nDigit++; } + break; + } + if( zB[j]==0 ){ + while( zA[i]=='0' || (isdigit(zA[i]) && nDigit>=15) ){ i++; nDigit++; } + break; + } + if( isspace(zA[i]) && isspace(zB[j]) ) continue; + + if( isdigit(zA[i]) && isdigit(zB[j]) ){ + /* A and B are both digits, but different digits */ + if( zA[i]==zB[j]+1 && !isdigit(zA[i+1]) && isdigit(zB[j+1]) ){ + /* Is A a rounded up version of B? */ + j++; + while( zB[j]=='9' ){ j++; nDigit++; } + if( nDigit<14 && (!isdigit(zB[j]) || zB[j]<5) ) break; + while( isdigit(zB[j]) ){ j++; } + i++; + }else if( zB[j]==zA[i]+1 && !isdigit(zB[j+1]) && isdigit(zA[i+1]) ){ + /* Is B a rounded up version of A? */ + i++; + while( zA[i]=='9' ){ i++; nDigit++; } + if( nDigit<14 && (!isdigit(zA[i]) || zA[i]<5) ) break; + while( isdigit(zA[i]) ){ i++; } + j++; + }else{ + break; + } + }else if( !isdigit(zA[i]) && isdigit(zB[j]) ){ + while( zB[j]=='0' ){ j++; nDigit++; } + if( nDigit<15 ) break; + while( isdigit(zB[j]) ){ j++; } + }else if( !isdigit(zB[j]) && isdigit(zA[i]) ){ + while( zA[i]=='0' ){ i++; nDigit++; } + if( nDigit<15 ) break; + while( isdigit(zA[i]) ){ i++; } + }else{ + break; + } + } + if( zA[i]=='e' && zB[j]=='e' ){ + i++; + j++; + if( (zA[i]=='+' || zA[i]=='-') && zB[j]==zA[i] ){ i++; j++; } + if( zA[i]!=zB[j] ){ + if( zA[i]=='0' && zA[i+1]==zB[j] ){ i++; } + if( zB[j]=='0' && zB[j+1]==zA[i] ){ j++; } + } + while( zA[i]==zB[j] && isdigit(zA[i]) ){ i++; j++; } + if( zA[i]!=zB[j] ) break; + if( zA[i]==0 ) break; + continue; + } + } + while( isspace(zA[i]) ){ i++; } + while( isspace(zB[j]) ){ j++; } + Tcl_SetObjResult(interp, Tcl_NewIntObj(zA[i]==0 && zB[j]==0)); + return TCL_OK; +} + /* ** Usage: sqlite3_release_memory ?N? ** @@ -6655,7 +6791,7 @@ static int SQLITE_TCLAPI file_control_lockproxy_test( { char *testPath; int rc; - int nPwd; + Tcl_Size nPwd; const char *zPwd; char proxyPath[400]; @@ -7925,145 +8061,6 @@ static int SQLITE_TCLAPI win32_file_lock( CloseHandle(ev); return TCL_OK; } - -/* -** exists_win32_path PATH -** -** Returns non-zero if the specified path exists, whose fully qualified name -** may exceed 260 characters if it is prefixed with "\\?\". -*/ -static int SQLITE_TCLAPI win32_exists_path( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "PATH"); - return TCL_ERROR; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - GetFileAttributesW( Tcl_GetUnicode(objv[1]))!=INVALID_FILE_ATTRIBUTES )); - return TCL_OK; -} - -/* -** find_win32_file PATTERN -** -** Returns a list of entries in a directory that match the specified pattern, -** whose fully qualified name may exceed 248 characters if it is prefixed with -** "\\?\". -*/ -static int SQLITE_TCLAPI win32_find_file( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - HANDLE hFindFile = INVALID_HANDLE_VALUE; - WIN32_FIND_DATAW findData; - Tcl_Obj *listObj; - DWORD lastErrno; - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "PATTERN"); - return TCL_ERROR; - } - hFindFile = FindFirstFileW(Tcl_GetUnicode(objv[1]), &findData); - if( hFindFile==INVALID_HANDLE_VALUE ){ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError())); - return TCL_ERROR; - } - listObj = Tcl_NewObj(); - Tcl_IncrRefCount(listObj); - do { - Tcl_ListObjAppendElement(interp, listObj, Tcl_NewUnicodeObj( - findData.cFileName, -1)); - Tcl_ListObjAppendElement(interp, listObj, Tcl_NewWideIntObj( - findData.dwFileAttributes)); - } while( FindNextFileW(hFindFile, &findData) ); - lastErrno = GetLastError(); - if( lastErrno!=NO_ERROR && lastErrno!=ERROR_NO_MORE_FILES ){ - FindClose(hFindFile); - Tcl_DecrRefCount(listObj); - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError())); - return TCL_ERROR; - } - FindClose(hFindFile); - Tcl_SetObjResult(interp, listObj); - return TCL_OK; -} - -/* -** delete_win32_file FILENAME -** -** Deletes the specified file, whose fully qualified name may exceed 260 -** characters if it is prefixed with "\\?\". -*/ -static int SQLITE_TCLAPI win32_delete_file( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); - return TCL_ERROR; - } - if( !DeleteFileW(Tcl_GetUnicode(objv[1])) ){ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError())); - return TCL_ERROR; - } - Tcl_ResetResult(interp); - return TCL_OK; -} - -/* -** make_win32_dir DIRECTORY -** -** Creates the specified directory, whose fully qualified name may exceed 248 -** characters if it is prefixed with "\\?\". -*/ -static int SQLITE_TCLAPI win32_mkdir( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY"); - return TCL_ERROR; - } - if( !CreateDirectoryW(Tcl_GetUnicode(objv[1]), NULL) ){ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError())); - return TCL_ERROR; - } - Tcl_ResetResult(interp); - return TCL_OK; -} - -/* -** remove_win32_dir DIRECTORY -** -** Removes the specified directory, whose fully qualified name may exceed 248 -** characters if it is prefixed with "\\?\". -*/ -static int SQLITE_TCLAPI win32_rmdir( - void *clientData, - Tcl_Interp *interp, - int objc, - Tcl_Obj *CONST objv[] -){ - if( objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "DIRECTORY"); - return TCL_ERROR; - } - if( !RemoveDirectoryW(Tcl_GetUnicode(objv[1])) ){ - Tcl_SetObjResult(interp, Tcl_NewWideIntObj(GetLastError())); - return TCL_ERROR; - } - Tcl_ResetResult(interp); - return TCL_OK; -} #endif @@ -8370,7 +8367,7 @@ static int SQLITE_TCLAPI test_user_authenticate( ){ char *zUser = 0; char *zPasswd = 0; - int nPasswd = 0; + Tcl_Size nPasswd = 0; sqlite3 *db; int rc; @@ -8383,7 +8380,7 @@ static int SQLITE_TCLAPI test_user_authenticate( } zUser = Tcl_GetString(objv[2]); zPasswd = Tcl_GetStringFromObj(objv[3], &nPasswd); - rc = sqlite3_user_authenticate(db, zUser, zPasswd, nPasswd); + rc = sqlite3_user_authenticate(db, zUser, zPasswd, (int)nPasswd); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); return TCL_OK; } @@ -8733,7 +8730,7 @@ static int SQLITE_TCLAPI test_write_db( sqlite3 *db = 0; Tcl_WideInt iOff = 0; const unsigned char *aData = 0; - int nData = 0; + Tcl_Size nData = 0; sqlite3_file *pFile = 0; int rc; @@ -8746,7 +8743,7 @@ static int SQLITE_TCLAPI test_write_db( aData = Tcl_GetByteArrayFromObj(objv[3], &nData); sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, (void*)&pFile); - rc = pFile->pMethods->xWrite(pFile, aData, nData, iOff); + rc = pFile->pMethods->xWrite(pFile, aData, (int)(nData&0x7fffffff), iOff); Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); return TCL_OK; @@ -9158,11 +9155,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, - { "exists_win32_path", win32_exists_path, 0 }, - { "find_win32_file", win32_find_file, 0 }, - { "delete_win32_file", win32_delete_file, 0 }, - { "make_win32_dir", win32_mkdir, 0 }, - { "remove_win32_dir", win32_rmdir, 0 }, #endif { "tcl_objproc", runAsObjProc, 0 }, @@ -9237,6 +9229,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ #endif { "sqlite3_test_errstr", test_errstr, 0 }, { "tcl_variable_type", tcl_variable_type, 0 }, + { "fpnum_compare", fpnum_compare, 0 }, #ifndef SQLITE_OMIT_SHARED_CACHE { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, { "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0}, diff --git a/src/test2.c b/src/test2.c index c75fa2eba..a9549aa7f 100644 --- a/src/test2.c +++ b/src/test2.c @@ -14,11 +14,7 @@ ** testing of the SQLite library. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <ctype.h> diff --git a/src/test3.c b/src/test3.c index 7fd766247..f1b2b0168 100644 --- a/src/test3.c +++ b/src/test3.c @@ -15,11 +15,7 @@ */ #include "sqliteInt.h" #include "btreeInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> @@ -623,6 +619,7 @@ static int SQLITE_TCLAPI btree_insert( BtCursor *pCur; int rc; BtreePayload x; + Tcl_Size n; if( objc!=4 && objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE"); @@ -633,10 +630,11 @@ static int SQLITE_TCLAPI btree_insert( if( objc==4 ){ if( Tcl_GetIntFromObj(interp, objv[2], &rc) ) return TCL_ERROR; x.nKey = rc; - x.pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &x.nData); + x.pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &n); + x.nData = (int)n; }else{ - x.pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &rc); - x.nKey = rc; + x.pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &n); + x.nKey = (int)n; } pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); diff --git a/src/test4.c b/src/test4.c index 2043a3383..8a68f7d3e 100644 --- a/src/test4.c +++ b/src/test4.c @@ -12,11 +12,7 @@ ** Code for testing the SQLite library in a multithreaded environment. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #if SQLITE_OS_UNIX && SQLITE_THREADSAFE #include <stdlib.h> #include <string.h> diff --git a/src/test5.c b/src/test5.c index 0d9242862..334b5d07f 100644 --- a/src/test5.c +++ b/src/test5.c @@ -17,11 +17,7 @@ */ #include "sqliteInt.h" #include "vdbeInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> @@ -36,7 +32,7 @@ static int SQLITE_TCLAPI binarize( int objc, Tcl_Obj *CONST objv[] ){ - int len; + Tcl_Size len; char *bytes; Tcl_Obj *pRet; assert(objc==2); @@ -133,7 +129,7 @@ static int SQLITE_TCLAPI test_translate( sqlite3_value *pVal; char *z; - int len; + Tcl_Size len; void (*xDel)(void *p) = SQLITE_STATIC; if( objc!=4 && objc!=5 ){ @@ -164,7 +160,7 @@ static int SQLITE_TCLAPI test_translate( z = (char*)Tcl_GetByteArrayFromObj(objv[1], &len); if( objc==5 ){ char *zTmp = z; - z = sqlite3_malloc(len); + z = sqlite3_malloc64(len); memcpy(z, zTmp, len); } sqlite3ValueSetStr(pVal, -1, z, enc_from, xDel); diff --git a/src/test6.c b/src/test6.c index 5d8e6b9be..76db640c4 100644 --- a/src/test6.c +++ b/src/test6.c @@ -16,11 +16,7 @@ */ #if SQLITE_TEST /* This file is used for testing only */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #ifndef SQLITE_OMIT_DISKIO /* This file is a no-op if disk I/O is disabled */ @@ -751,7 +747,7 @@ static int processDevSymArgs( int setDeviceChar = 0; for(i=0; i<objc; i+=2){ - int nOpt; + Tcl_Size nOpt; char *zOpt = Tcl_GetStringFromObj(objv[i], &nOpt); if( (nOpt>11 || nOpt<2 || strncmp("-sectorsize", zOpt, nOpt)) @@ -776,11 +772,11 @@ static int processDevSymArgs( }else{ int j; Tcl_Obj **apObj; - int nObj; + Tcl_Size nObj; if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){ return TCL_ERROR; } - for(j=0; j<nObj; j++){ + for(j=0; j<(int)nObj; j++){ int rc; int iChoice; Tcl_Obj *pFlag = Tcl_DuplicateObj(apObj[j]); @@ -925,7 +921,8 @@ static int SQLITE_TCLAPI crashParamsObjCmd( ){ int iDelay; const char *zCrashFile; - int nCrashFile, iDc, iSectorSize; + Tcl_Size nCrashFile; + int iDc, iSectorSize; iDc = -1; iSectorSize = -1; diff --git a/src/test8.c b/src/test8.c index 4aeb555c7..8a13f5d55 100644 --- a/src/test8.c +++ b/src/test8.c @@ -14,11 +14,7 @@ ** testing of the SQLite library. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> diff --git a/src/test9.c b/src/test9.c index 5b139e8a5..b5362adb7 100644 --- a/src/test9.c +++ b/src/test9.c @@ -15,11 +15,7 @@ ** as there is not much point in binding to Tcl. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> diff --git a/src/test_async.c b/src/test_async.c index c32c74c66..afe401ac6 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -14,15 +14,8 @@ ** (defined in ext/async/sqlite3async.h) to Tcl. */ -#define TCL_THREADS -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#define TCL_THREADS +#include "tclsqlite.h" #ifdef SQLITE_ENABLE_ASYNCIO diff --git a/src/test_autoext.c b/src/test_autoext.c index e23e41a08..74ca55879 100644 --- a/src/test_autoext.c +++ b/src/test_autoext.c @@ -11,14 +11,7 @@ ************************************************************************* ** Test extension for testing the sqlite3_auto_extension() function. */ -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #include "sqlite3ext.h" #ifndef SQLITE_OMIT_LOAD_EXTENSION diff --git a/src/test_backup.c b/src/test_backup.c index 9b684a28f..8051888ee 100644 --- a/src/test_backup.c +++ b/src/test_backup.c @@ -13,14 +13,7 @@ ** */ -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #include "sqlite3.h" #include <assert.h> diff --git a/src/test_bestindex.c b/src/test_bestindex.c index c89cab2e3..2f9203d85 100644 --- a/src/test_bestindex.c +++ b/src/test_bestindex.c @@ -93,11 +93,7 @@ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -352,14 +348,14 @@ static int tclFilter( */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; - int nElem; + Tcl_Size nElem; rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem); if( rc!=TCL_OK ){ const char *zErr = Tcl_GetStringResult(interp); rc = SQLITE_ERROR; pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr); }else{ - for(ii=0; rc==SQLITE_OK && ii<nElem; ii+=2){ + for(ii=0; rc==SQLITE_OK && ii<(int)nElem; ii+=2){ const char *zCmd = Tcl_GetString(apElem[ii]); Tcl_Obj *p = apElem[ii+1]; if( sqlite3_stricmp("sql", zCmd)==0 ){ @@ -664,7 +660,7 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ */ Tcl_Obj *pRes = Tcl_GetObjResult(interp); Tcl_Obj **apElem = 0; - int nElem; + Tcl_Size nElem; rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem); if( rc!=TCL_OK ){ const char *zErr = Tcl_GetStringResult(interp); @@ -673,7 +669,7 @@ static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ }else{ int ii; int iArgv = 1; - for(ii=0; rc==SQLITE_OK && ii<nElem; ii+=2){ + for(ii=0; rc==SQLITE_OK && ii<(int)nElem; ii+=2){ const char *zCmd = Tcl_GetString(apElem[ii]); Tcl_Obj *p = apElem[ii+1]; if( sqlite3_stricmp("cost", zCmd)==0 ){ diff --git a/src/test_blob.c b/src/test_blob.c index cbdf9f069..bddad240c 100644 --- a/src/test_blob.c +++ b/src/test_blob.c @@ -12,11 +12,7 @@ ** */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> @@ -58,7 +54,7 @@ static int blobHandleFromObj( sqlite3_blob **ppBlob ){ char *z; - int n; + Tcl_Size n; z = Tcl_GetStringFromObj(pObj, &n); if( n==0 ){ @@ -88,7 +84,7 @@ static int blobHandleFromObj( ** NULL Pointer is returned. */ static char *blobStringFromObj(Tcl_Obj *pObj){ - int n; + Tcl_Size n; char *z; z = Tcl_GetStringFromObj(pObj, &n); return (n ? z : 0); @@ -112,7 +108,7 @@ static int SQLITE_TCLAPI test_blob_open( Tcl_WideInt iRowid; int flags; const char *zVarname; - int nVarname; + Tcl_Size nVarname; sqlite3_blob *pBlob = (sqlite3_blob*)&flags; /* Non-zero initialization */ int rc; @@ -281,7 +277,8 @@ static int SQLITE_TCLAPI test_blob_write( int rc; unsigned char *zBuf; - int nBuf; + Tcl_Size nBuf; + int n; if( objc!=4 && objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET DATA ?NDATA?"); @@ -294,10 +291,11 @@ static int SQLITE_TCLAPI test_blob_write( } zBuf = Tcl_GetByteArrayFromObj(objv[3], &nBuf); - if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ + n = (int)(nBuf & 0x7fffffff); + if( objc==5 && Tcl_GetIntFromObj(interp, objv[4], &n) ){ return TCL_ERROR; } - rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); + rc = sqlite3_blob_write(pBlob, zBuf, n, iOffset); if( rc!=SQLITE_OK ){ Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); } diff --git a/src/test_btree.c b/src/test_btree.c index 03b8b207c..168a10f1f 100644 --- a/src/test_btree.c +++ b/src/test_btree.c @@ -14,11 +14,7 @@ ** testing of the SQLite library. */ #include "btreeInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* ** Usage: sqlite3_shared_cache_report diff --git a/src/test_config.c b/src/test_config.c index 76904e5bf..58de5a462 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -24,11 +24,7 @@ # include "os_win.h" #endif -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> diff --git a/src/test_demovfs.c b/src/test_demovfs.c index e990e98f2..e92fd5613 100644 --- a/src/test_demovfs.c +++ b/src/test_demovfs.c @@ -645,14 +645,7 @@ sqlite3_vfs *sqlite3_demovfs(void){ #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" #if SQLITE_OS_UNIX static int SQLITE_TCLAPI register_demovfs( diff --git a/src/test_fs.c b/src/test_fs.c index f88f3a942..d821a83b9 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -62,12 +62,7 @@ ** SELECT * FROM fstree WHERE path LIKE '/home/dan/sqlite/%' */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif - +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <sys/types.h> diff --git a/src/test_func.c b/src/test_func.c index 80df48828..8c06705ae 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -13,11 +13,7 @@ ** implements new SQL functions used by the test scripts. */ #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> diff --git a/src/test_hexio.c b/src/test_hexio.c index 61a41d5b1..8999d84d2 100644 --- a/src/test_hexio.c +++ b/src/test_hexio.c @@ -18,11 +18,7 @@ ** easier and safer to build our own mechanism. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> @@ -155,7 +151,8 @@ static int SQLITE_TCLAPI hexio_write( Tcl_Obj *CONST objv[] ){ int offset; - int nIn, nOut, written; + Tcl_Size nIn; + int nOut, written; const char *zFile; const unsigned char *zIn; unsigned char *aOut; @@ -168,11 +165,11 @@ static int SQLITE_TCLAPI hexio_write( if( Tcl_GetIntFromObj(interp, objv[2], &offset) ) return TCL_ERROR; zFile = Tcl_GetString(objv[1]); zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[3], &nIn); - aOut = sqlite3_malloc( 1 + nIn/2 ); + aOut = sqlite3_malloc64( 1 + nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } - nOut = sqlite3TestHexToBin(zIn, nIn, aOut); + nOut = sqlite3TestHexToBin(zIn, (int)nIn, aOut); out = fopen(zFile, "r+b"); if( out==0 ){ out = fopen(zFile, "r+"); @@ -203,7 +200,8 @@ static int SQLITE_TCLAPI hexio_get_int( Tcl_Obj *CONST objv[] ){ int val; - int nIn, nOut; + Tcl_Size nIn; + int nOut; const unsigned char *zIn; unsigned char *aOut; unsigned char aNum[4]; @@ -213,11 +211,11 @@ static int SQLITE_TCLAPI hexio_get_int( return TCL_ERROR; } zIn = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &nIn); - aOut = sqlite3_malloc( 1 + nIn/2 ); + aOut = sqlite3_malloc64( 1 + nIn/2 ); if( aOut==0 ){ return TCL_ERROR; } - nOut = sqlite3TestHexToBin(zIn, nIn, aOut); + nOut = sqlite3TestHexToBin(zIn, (int)nIn, aOut); if( nOut>=4 ){ memcpy(aNum, aOut, 4); }else{ @@ -300,7 +298,7 @@ static int SQLITE_TCLAPI utf8_to_utf8( Tcl_Obj *CONST objv[] ){ #ifdef SQLITE_DEBUG - int n; + Tcl_Size n; int nOut; const unsigned char *zOrig; unsigned char *z; @@ -309,8 +307,8 @@ static int SQLITE_TCLAPI utf8_to_utf8( return TCL_ERROR; } zOrig = (unsigned char *)Tcl_GetStringFromObj(objv[1], &n); - z = sqlite3_malloc( n+4 ); - n = sqlite3TestHexToBin(zOrig, n, z); + z = sqlite3_malloc64( n+4 ); + n = sqlite3TestHexToBin(zOrig, (int)n, z); z[n] = 0; nOut = sqlite3Utf8To8(z); sqlite3TestBinToHex(z,nOut); @@ -361,7 +359,7 @@ static int SQLITE_TCLAPI read_fts3varint( int objc, Tcl_Obj *CONST objv[] ){ - int nBlob; + Tcl_Size nBlob; unsigned char *zBlob; sqlite3_int64 iVal; int nVal; @@ -388,10 +386,10 @@ static int SQLITE_TCLAPI make_fts3record( Tcl_Obj *CONST objv[] ){ Tcl_Obj **aArg = 0; - int nArg = 0; + Tcl_Size nArg = 0; unsigned char *aOut = 0; - int nOut = 0; - int nAlloc = 0; + sqlite3_int64 nOut = 0; + sqlite3_int64 nAlloc = 0; int i; if( objc!=2 ){ @@ -402,7 +400,7 @@ static int SQLITE_TCLAPI make_fts3record( return TCL_ERROR; } - for(i=0; i<nArg; i++){ + for(i=0; i<(int)nArg; i++){ sqlite3_int64 iVal; if( TCL_OK==Tcl_GetWideIntFromObj(0, aArg[i], &iVal) ){ if( nOut+10>nAlloc ){ @@ -417,11 +415,11 @@ static int SQLITE_TCLAPI make_fts3record( } nOut += putFts3Varint((char*)&aOut[nOut], iVal); }else{ - int nVal = 0; + Tcl_Size nVal = 0; char *zVal = Tcl_GetStringFromObj(aArg[i], &nVal); while( (nOut + nVal)>nAlloc ){ - int nNew = nAlloc?nAlloc*2:128; - unsigned char *aNew = sqlite3_realloc(aOut, nNew); + sqlite3_int64 nNew = nAlloc?nAlloc*2:128; + unsigned char *aNew = sqlite3_realloc64(aOut, nNew); if( aNew==0 ){ sqlite3_free(aOut); return TCL_ERROR; diff --git a/src/test_init.c b/src/test_init.c index 400ab9a2b..f7b85875b 100644 --- a/src/test_init.c +++ b/src/test_init.c @@ -27,11 +27,7 @@ #include "sqliteInt.h" #include <string.h> -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" static struct Wrapped { sqlite3_pcache_methods2 pcache; diff --git a/src/test_intarray.c b/src/test_intarray.c index a978ed585..16c1df2e9 100644 --- a/src/test_intarray.c +++ b/src/test_intarray.c @@ -279,14 +279,7 @@ SQLITE_API int sqlite3_intarray_bind( ** Everything below is interface for testing this module. */ #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" /* ** Routines to encode and decode pointers diff --git a/src/test_malloc.c b/src/test_malloc.c index 8146501c9..21faa0d29 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -14,11 +14,7 @@ ** memory allocation subsystem. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> @@ -387,7 +383,8 @@ static int SQLITE_TCLAPI test_memset( Tcl_Obj *CONST objv[] ){ void *p; - int size, n, i; + int size, i; + Tcl_Size n; char *zHex; char *zOut; char zBin[100]; @@ -409,7 +406,7 @@ static int SQLITE_TCLAPI test_memset( } zHex = Tcl_GetStringFromObj(objv[3], &n); if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2; - n = sqlite3TestHexToBin(zHex, n, zBin); + n = sqlite3TestHexToBin(zHex, (int)n, zBin); if( n==0 ){ Tcl_AppendResult(interp, "no data", (char*)0); return TCL_ERROR; @@ -624,7 +621,7 @@ static int SQLITE_TCLAPI test_memdebug_fail( if( Tcl_GetIntFromObj(interp, objv[1], &iFail) ) return TCL_ERROR; for(ii=2; ii<objc; ii+=2){ - int nOption; + Tcl_Size nOption; char *zOption = Tcl_GetStringFromObj(objv[ii], &nOption); char *zErr = 0; diff --git a/src/test_md5.c b/src/test_md5.c index 7903797db..a09f1ad6c 100644 --- a/src/test_md5.c +++ b/src/test_md5.c @@ -16,14 +16,7 @@ #include <stdlib.h> #include <string.h> #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" /* * This code implements the MD5 message-digest algorithm. diff --git a/src/test_multiplex.c b/src/test_multiplex.c index d06ed2f79..e5b43f4cc 100644 --- a/src/test_multiplex.c +++ b/src/test_multiplex.c @@ -1219,14 +1219,7 @@ int sqlite3_multiplex_shutdown(int eForce){ /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" extern const char *sqlite3ErrName(int); diff --git a/src/test_mutex.c b/src/test_mutex.c index a203208ab..e60a06df3 100644 --- a/src/test_mutex.c +++ b/src/test_mutex.c @@ -11,12 +11,7 @@ ************************************************************************* ** This file contains test logic for the sqlite3_mutex interfaces. */ - -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include "sqlite3.h" #include "sqliteInt.h" #include <stdlib.h> diff --git a/src/test_osinst.c b/src/test_osinst.c index 062e83159..2d03d2bbc 100644 --- a/src/test_osinst.c +++ b/src/test_osinst.c @@ -1109,14 +1109,7 @@ int sqlite3_vfslog_register(sqlite3 *db){ #if defined(SQLITE_TEST) || defined(TCLSH) -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" static int SQLITE_TCLAPI test_vfslog( void *clientData, diff --git a/src/test_pcache.c b/src/test_pcache.c index 5266d6769..ceefa13e5 100644 --- a/src/test_pcache.c +++ b/src/test_pcache.c @@ -99,7 +99,7 @@ static void testpcacheShutdown(void *pArg){ */ typedef struct testpcache testpcache; struct testpcache { - int szPage; /* Size of each page. Multiple of 8. */ + sqlite3_int64 szPage; /* Size of each page. Multiple of 8. */ int szExtra; /* Size of extra data that accompanies each page */ int bPurgeable; /* True if the page cache is purgeable */ int nFree; /* Number of unused slots in a[] */ @@ -141,6 +141,7 @@ static sqlite3_pcache *testpcacheCreate( int i; assert( testpcacheGlobal.pDummy!=0 ); szPage = (szPage+7)&~7; + szExtra = (szPage+7)&~7; nMem = sizeof(testpcache) + TESTPCACHE_NPAGE*(szPage+szExtra); p = sqlite3_malloc( nMem ); if( p==0 ) return 0; diff --git a/src/test_quota.c b/src/test_quota.c index b436de466..1bfc5ce11 100644 --- a/src/test_quota.c +++ b/src/test_quota.c @@ -1278,14 +1278,7 @@ int sqlite3_quota_remove(const char *zFilename){ /***************************** Test Code ***********************************/ #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" /* ** Argument passed to a TCL quota-over-limit callback. @@ -1420,7 +1413,7 @@ static int SQLITE_TCLAPI test_quota_set( Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */ int rc; /* Value returned by quota_set() */ TclQuotaCallback *p; /* Callback object */ - int nScript; /* Length of callback script */ + Tcl_Size nScript; /* Length of callback script */ void (*xDestroy)(void*); /* Optional destructor for pArg */ void (*xCallback)(const char *, sqlite3_int64 *, sqlite3_int64, void *); diff --git a/src/test_rtree.c b/src/test_rtree.c index 0c6dbf3cd..53af6e5cf 100644 --- a/src/test_rtree.c +++ b/src/test_rtree.c @@ -14,11 +14,7 @@ */ #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" /* Solely for the UNUSED_PARAMETER() macro. */ #include "sqliteInt.h" @@ -357,11 +353,7 @@ static int bfs_query_func(sqlite3_rtree_query_info *p){ *************************************************************************/ #include <assert.h> -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" typedef struct Cube Cube; struct Cube { diff --git a/src/test_schema.c b/src/test_schema.c index 2cbc18e2b..660d21ea4 100644 --- a/src/test_schema.c +++ b/src/test_schema.c @@ -36,11 +36,7 @@ */ #ifdef SQLITE_TEST # include "sqliteInt.h" -# if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -# else -# include "tcl.h" -# endif +# include "tclsqlite.h" #else # include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 diff --git a/src/test_superlock.c b/src/test_superlock.c index 45d0d623a..7f3bf163a 100644 --- a/src/test_superlock.c +++ b/src/test_superlock.c @@ -256,14 +256,7 @@ int sqlite3demo_superlock( #ifdef SQLITE_TEST -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" struct InterpAndScript { Tcl_Interp *interp; diff --git a/src/test_syscall.c b/src/test_syscall.c index 3cd1034d3..af2ae1001 100644 --- a/src/test_syscall.c +++ b/src/test_syscall.c @@ -76,11 +76,7 @@ #include "sqliteInt.h" #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> #include <assert.h> @@ -197,7 +193,7 @@ static int tsIsFail(void){ */ static int tsErrno(const char *zFunc){ int i; - int nFunc = strlen(zFunc); + size_t nFunc = strlen(zFunc); for(i=0; aSyscall[i].zName; i++){ if( strlen(aSyscall[i].zName)!=nFunc ) continue; if( memcmp(aSyscall[i].zName, zFunc, nFunc) ) continue; @@ -429,7 +425,7 @@ static int SQLITE_TCLAPI test_syscall_install( Tcl_Obj *CONST objv[] ){ sqlite3_vfs *pVfs; - int nElem; + Tcl_Size nElem; int i; Tcl_Obj **apElem; @@ -442,7 +438,7 @@ static int SQLITE_TCLAPI test_syscall_install( } pVfs = sqlite3_vfs_find(0); - for(i=0; i<nElem; i++){ + for(i=0; i<(int)nElem; i++){ int iCall; int rc = Tcl_GetIndexFromObjStruct(interp, apElem[i], aSyscall, sizeof(aSyscall[0]), "system-call", 0, &iCall @@ -502,7 +498,7 @@ static int SQLITE_TCLAPI test_syscall_reset( rc = pVfs->xSetSystemCall(pVfs, 0, 0); for(i=0; aSyscall[i].zName; i++) aSyscall[i].xOrig = 0; }else{ - int nFunc; + Tcl_Size nFunc; char *zFunc = Tcl_GetStringFromObj(objv[2], &nFunc); rc = pVfs->xSetSystemCall(pVfs, Tcl_GetString(objv[2]), 0); for(i=0; rc==SQLITE_OK && aSyscall[i].zName; i++){ diff --git a/src/test_tclsh.c b/src/test_tclsh.c index 4697c3b85..db362049e 100644 --- a/src/test_tclsh.c +++ b/src/test_tclsh.c @@ -20,14 +20,7 @@ ** in an effort to keep the tclsqlite.c file pure. */ #include "sqlite3.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -# ifndef SQLITE_TCLAPI -# define SQLITE_TCLAPI -# endif -#endif +#include "tclsqlite.h" /* Needed for the setrlimit() system call on unix */ #if defined(unix) diff --git a/src/test_tclvar.c b/src/test_tclvar.c index 36165bc27..9be877449 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -36,11 +36,7 @@ ** according to "fullname" and "value" only. */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #include <stdlib.h> #include <string.h> @@ -150,10 +146,10 @@ static int next2(Tcl_Interp *interp, tclvar_cursor *pCur, Tcl_Obj *pObj){ Tcl_IncrRefCount(pCur->pList2); assert( pCur->i2==0 ); }else{ - int n = 0; + Tcl_Size n = 0; pCur->i2++; Tcl_ListObjLength(0, pCur->pList2, &n); - if( pCur->i2>=n ){ + if( pCur->i2>=(int)n ){ Tcl_DecrRefCount(pCur->pList2); pCur->pList2 = 0; pCur->i2 = 0; @@ -167,14 +163,14 @@ static int next2(Tcl_Interp *interp, tclvar_cursor *pCur, Tcl_Obj *pObj){ static int tclvarNext(sqlite3_vtab_cursor *cur){ Tcl_Obj *pObj; - int n = 0; + Tcl_Size n = 0; int ok = 0; tclvar_cursor *pCur = (tclvar_cursor *)cur; Tcl_Interp *interp = ((tclvar_vtab *)(cur->pVtab))->interp; Tcl_ListObjLength(0, pCur->pList1, &n); - while( !ok && pCur->i1<n ){ + while( !ok && pCur->i1<(int)n ){ Tcl_ListObjIndex(0, pCur->pList1, pCur->i1, &pObj); ok = next2(interp, pCur, pObj); if( !ok ){ diff --git a/src/test_thread.c b/src/test_thread.c index 126fd9836..7c06d110a 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -16,11 +16,7 @@ */ #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #if SQLITE_THREADSAFE @@ -94,7 +90,7 @@ static int SQLITE_TCLAPI tclScriptEvent(Tcl_Event *evPtr, int flags){ static void postToParent(SqlThread *p, Tcl_Obj *pScript){ EvalEvent *pEvent; char *zMsg; - int nMsg; + Tcl_Size nMsg; zMsg = Tcl_GetStringFromObj(pScript, &nMsg); pEvent = (EvalEvent *)ckalloc(sizeof(EvalEvent)+nMsg+1); @@ -181,8 +177,8 @@ static int SQLITE_TCLAPI sqlthread_spawn( SqlThread *pNew; int rc; - int nVarname; char *zVarname; - int nScript; char *zScript; + Tcl_Size nVarname; char *zVarname; + Tcl_Size nScript; char *zScript; /* Parameters for thread creation */ const int nStack = TCL_THREAD_STACK_DEFAULT; @@ -232,7 +228,7 @@ static int SQLITE_TCLAPI sqlthread_parent( ){ EvalEvent *pEvent; char *zMsg; - int nMsg; + Tcl_Size nMsg; SqlThread *p = (SqlThread *)clientData; assert(objc==3); diff --git a/src/test_vdbecov.c b/src/test_vdbecov.c index a001b1df0..283936aeb 100644 --- a/src/test_vdbecov.c +++ b/src/test_vdbecov.c @@ -15,11 +15,7 @@ #include "sqlite3.h" #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" #ifdef SQLITE_VDBE_COVERAGE diff --git a/src/test_vfs.c b/src/test_vfs.c index 312e1a1be..9f84b4f80 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -28,11 +28,7 @@ #include "sqlite3.h" #include "sqliteInt.h" -#if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" -#else -# include "tcl.h" -#endif +#include "tclsqlite.h" typedef struct Testvfs Testvfs; typedef struct TestvfsShm TestvfsShm; @@ -1150,15 +1146,15 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( return TCL_ERROR; } if( objc==4 ){ - int n; + Tcl_Size n; u8 *a = Tcl_GetByteArrayFromObj(objv[3], &n); int pgsz = pBuffer->pgsz; if( pgsz==0 ) pgsz = 65536; - for(i=0; i*pgsz<n; i++){ + for(i=0; i*pgsz<(int)n; i++){ int nByte = pgsz; tvfsAllocPage(pBuffer, i, pgsz); if( n-i*pgsz<pgsz ){ - nByte = n; + nByte = (int)n; } memcpy(pBuffer->aPage[i], &a[i*pgsz], nByte); } @@ -1203,7 +1199,7 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( { "xFileControl", TESTVFS_FCNTL_MASK }, }; Tcl_Obj **apElem = 0; - int nElem = 0; + Tcl_Size nElem = 0; int mask = 0; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "LIST"); @@ -1213,7 +1209,7 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( return TCL_ERROR; } Tcl_ResetResult(interp); - for(i=0; i<nElem; i++){ + for(i=0; i<(int)nElem; i++){ int iMethod; char *zElem = Tcl_GetString(apElem[i]); for(iMethod=0; iMethod<ArraySize(vfsmethod); iMethod++){ @@ -1239,7 +1235,7 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( */ case CMD_SCRIPT: { if( objc==3 ){ - int nByte; + Tcl_Size nByte; if( p->pScript ){ Tcl_DecrRefCount(p->pScript); p->pScript = 0; @@ -1337,13 +1333,13 @@ static int SQLITE_TCLAPI testvfs_obj_cmd( int j; int iNew = 0; Tcl_Obj **flags = 0; - int nFlags = 0; + Tcl_Size nFlags = 0; if( Tcl_ListObjGetElements(interp, objv[2], &nFlags, &flags) ){ return TCL_ERROR; } - for(j=0; j<nFlags; j++){ + for(j=0; j<(int)nFlags; j++){ int idx = 0; if( Tcl_GetIndexFromObjStruct(interp, flags[j], aFlag, sizeof(aFlag[0]), "flag", 0, &idx) @@ -1491,7 +1487,7 @@ static int SQLITE_TCLAPI testvfs_cmd( if( objc<2 || 0!=(objc%2) ) goto bad_args; for(i=2; i<objc; i += 2){ - int nSwitch; + Tcl_Size nSwitch; char *zSwitch; zSwitch = Tcl_GetStringFromObj(objv[i], &nSwitch); diff --git a/src/test_window.c b/src/test_window.c index 48ab02211..631b20162 100644 --- a/src/test_window.c +++ b/src/test_window.c @@ -16,7 +16,7 @@ #ifdef SQLITE_TEST #include "sqliteInt.h" -#include <tcl.h> +#include "tclsqlite.h" extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); extern const char *sqlite3ErrName(int); diff --git a/src/treeview.c b/src/treeview.c index 054265338..3960d2859 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -237,14 +237,12 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } if( pItem->pSelect ){ - sqlite3TreeViewPush(&pView, i+1<pSrc->nSrc); if( pItem->pTab ){ Table *pTab = pItem->pTab; sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); } assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); - sqlite3TreeViewPop(&pView); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); @@ -286,7 +284,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ n = 1000; }else{ n = 0; - if( p->pSrc && p->pSrc->nSrc ) n++; + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ) n++; if( p->pWhere ) n++; if( p->pGroupBy ) n++; if( p->pHaving ) n++; @@ -312,7 +310,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewPop(&pView); } #endif - if( p->pSrc && p->pSrc->nSrc ){ + if( p->pSrc && p->pSrc->nSrc && p->pSrc->nAlloc ){ sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); diff --git a/src/vdbe.c b/src/vdbe.c index 28f12e054..d097bfd8b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5308,6 +5308,7 @@ case OP_Found: { /* jump, in3, ncycle */ r.pKeyInfo = pC->pKeyInfo; r.default_rc = 0; #ifdef SQLITE_DEBUG + (void)sqlite3FaultSim(50); /* For use by --counter in TH3 */ for(ii=0; ii<r.nField; ii++){ assert( memIsValid(&r.aMem[ii]) ); assert( (r.aMem[ii].flags & MEM_Zero)==0 || r.aMem[ii].n==0 ); @@ -7670,18 +7671,29 @@ case OP_AggInverse: case OP_AggStep: { int n; sqlite3_context *pCtx; + u64 nAlloc; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + - (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); + + /* Allocate space for (a) the context object and (n-1) extra pointers + ** to append to the sqlite3_context.argv[1] array, and (b) a memory + ** cell in which to store the accumulation. Be careful that the memory + ** cell is 8-byte aligned, even on platforms where a pointer is 32-bits. + ** + ** Note: We could avoid this by using a regular memory cell from aMem[] for + ** the accumulator, instead of allocating one here. */ + nAlloc = ROUND8P( sizeof(pCtx[0]) + (n-1)*sizeof(sqlite3_value*) ); + pCtx = sqlite3DbMallocRawNN(db, nAlloc + sizeof(Mem)); if( pCtx==0 ) goto no_mem; - pCtx->pMem = 0; - pCtx->pOut = (Mem*)&(pCtx->argv[n]); + pCtx->pOut = (Mem*)((u8*)pCtx + nAlloc); + assert( EIGHT_BYTE_ALIGNMENT(pCtx->pOut) ); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; diff --git a/src/vdbe.h b/src/vdbe.h index 9001ace2e..f40f68d24 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -32,6 +32,19 @@ typedef struct Vdbe Vdbe; */ typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; +typedef struct SubrtnSig SubrtnSig; + +/* +** A signature for a reusable subroutine that materializes the RHS of +** an IN operator. +*/ +struct SubrtnSig { + int selId; /* SELECT-id for the SELECT statement on the RHS */ + char *zAff; /* Affinity of the overall IN expression */ + int iTable; /* Ephemeral table generated by the subroutine */ + int iAddr; /* Subroutine entry address */ + int regReturn; /* Register used to hold return address */ +}; /* ** A single instruction of the virtual machine has an opcode @@ -60,6 +73,7 @@ struct VdbeOp { u32 *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ Table *pTab; /* Used when p4type is P4_TABLE */ + SubrtnSig *pSubrtnSig; /* Used when p4type is P4_SUBRTNSIG */ #ifdef SQLITE_ENABLE_CURSOR_HINTS Expr *pExpr; /* Used when p4type is P4_EXPR */ #endif @@ -127,6 +141,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ #define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ +#define P4_SUBRTNSIG (-17) /* P4 is a SubrtnSig pointer */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 665f6cd17..f1e0cccdc 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1413,6 +1413,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = (SubrtnSig*)p4; + sqlite3DbFree(db, pSig->zAff); + sqlite3DbFree(db, pSig); + break; + } } } @@ -1992,6 +1998,11 @@ char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ zP4 = pOp->p4.pTab->zName; break; } + case P4_SUBRTNSIG: { + SubrtnSig *pSig = pOp->p4.pSubrtnSig; + sqlite3_str_appendf(&x, "subrtnsig:%d,%s", pSig->selId, pSig->zAff); + break; + } default: { zP4 = pOp->p4.z; } diff --git a/src/where.c b/src/where.c index ba4631c6c..a9a258995 100644 --- a/src/where.c +++ b/src/where.c @@ -719,6 +719,12 @@ static void translateColumnToCopy( VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("CHECKING for column-to-copy on cursor %d for %d..%d\n", + iTabCur, iStart, iEnd); + } +#endif for(; iStart<iEnd; iStart++, pOp++){ if( pOp->p1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ diff --git a/test/autoindex1.test b/test/autoindex1.test index 08bd9f74e..b294a2721 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -185,7 +185,8 @@ do_eqp_test autoindex1-500.1 { QUERY PLAN |--SEARCH t501 USING INTEGER PRIMARY KEY (rowid=?) `--LIST SUBQUERY xxxxxx - `--SCAN t502 + |--SCAN t502 + `--CREATE BLOOM FILTER } do_eqp_test autoindex1-501 { SELECT b FROM t501 diff --git a/test/backcompat.test b/test/backcompat.test index 87ffc4b3e..d477d4466 100644 --- a/test/backcompat.test +++ b/test/backcompat.test @@ -112,7 +112,7 @@ proc read_file {zFile} { set zData {} if {[file exists $zFile]} { set fd [open $zFile] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary if {[file size $zFile]<=$::sqlite_pending_byte || $zFile != "test.db"} { set zData [read $fd] @@ -129,7 +129,7 @@ proc read_file {zFile} { } proc write_file {zFile zData} { set fd [open $zFile w] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary puts -nonewline $fd $zData close $fd } diff --git a/test/cast.test b/test/cast.test index ebfea5aa0..7f48ed80b 100644 --- a/test/cast.test +++ b/test/cast.test @@ -234,6 +234,7 @@ do_test cast-3.1 { do_test cast-3.2 { execsql {SELECT CAST(9223372036854774800 AS numeric)} } 9223372036854774800 +breakpoint do_realnum_test cast-3.3 { execsql {SELECT CAST(9223372036854774800 AS real)} } 9.22337203685477e+18 diff --git a/test/corrupt.test b/test/corrupt.test index 62ead4d9a..ff61cc0bb 100644 --- a/test/corrupt.test +++ b/test/corrupt.test @@ -290,7 +290,7 @@ ifcapable oversize_cell_check { # detecting corruption was not possible at that point, and an assert() failed. # set fd [open test.db r+] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd [expr 1024+8] puts -nonewline $fd "\x03\x14" close $fd diff --git a/test/corrupt2.test b/test/corrupt2.test index 2e36cbd30..fc24cb376 100644 --- a/test/corrupt2.test +++ b/test/corrupt2.test @@ -69,7 +69,7 @@ do_test corrupt2-1.3 { forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] - fconfigure $f -encoding binary + fconfigure $f -translation binary seek $f 16 start puts -nonewline $f "\x00\xFF" close $f @@ -89,7 +89,7 @@ do_test corrupt2-1.4 { forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] - fconfigure $f -encoding binary + fconfigure $f -translation binary seek $f 101 start puts -nonewline $f "\xFF\xFF" close $f @@ -109,7 +109,7 @@ do_test corrupt2-1.5 { forcedelete corrupt.db-journal forcecopy test.db corrupt.db set f [open corrupt.db RDWR] - fconfigure $f -encoding binary + fconfigure $f -translation binary seek $f 101 start puts -nonewline $f "\x00\xC8" seek $f 200 start @@ -179,7 +179,7 @@ do_test corrupt2-3.1 { # of the DROP TABLE operation below. # set fd [open corrupt.db r+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd [expr 1024*3 + 12] set zCelloffset [read $fd 2] binary scan $zCelloffset S iCelloffset @@ -227,7 +227,7 @@ do_test corrupt2-5.1 { # This block links a page from table t2 into the t1 table structure. # set fd [open corrupt.db r+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd [expr 1024 + 12] set zCelloffset [read $fd 2] binary scan $zCelloffset S iCelloffset @@ -392,7 +392,7 @@ corruption_test -sqlprep $sqlprep -corrupt { # 0x0D (interpreted by SQLite as "leaf page of a table B-Tree"). # set fd [open corrupt.db r+] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd [expr 1024*2 + 8] set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild @@ -410,7 +410,7 @@ corruption_test -sqlprep $sqlprep -corrupt { # The corruption is detected as part of an OP_Prev opcode. # set fd [open corrupt.db r+] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd [expr 1024*2 + 12] set zCellOffset [read $fd 2] binary scan $zCellOffset S iCellOffset @@ -431,7 +431,7 @@ corruption_test -sqlprep $sqlprep -corrupt { # 0x0A (interpreted by SQLite as "leaf page of an index B-Tree"). # set fd [open corrupt.db r+] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd [expr 1024*1 + 8] set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild @@ -459,7 +459,7 @@ corruption_test -sqlprep { CREATE TABLE x6(a, b, c); CREATE TABLE xD(a, b, c); CREATE TABLE xJ(a, b, c); } -corrupt { set fd [open corrupt.db r+] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd 108 set zRightChild [read $fd 4] binary scan $zRightChild I iRightChild diff --git a/test/corrupt4.test b/test/corrupt4.test index 5b0965a83..544ac3305 100644 --- a/test/corrupt4.test +++ b/test/corrupt4.test @@ -122,7 +122,7 @@ proc put4byte {fd offset val} { # the second rightmost child page number of page 1 to 1. # set fd [open test.db r+] -fconfigure $fd -encoding binary -translation binary +fconfigure $fd -translation binary set nChild [get2byte $fd 103] set offChild [get2byte $fd [expr 100+12+($nChild-2)*2]] set pgnoChild [get4byte $fd $offChild] diff --git a/test/corruptK.test b/test/corruptK.test index 1569afe4a..0bdb3c45b 100644 --- a/test/corruptK.test +++ b/test/corruptK.test @@ -60,7 +60,7 @@ do_test 1.2 { sqlite3 db test.db set fd [db incrblob t1 x 3] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd 30 puts -nonewline $fd "\x18" close $fd @@ -102,7 +102,7 @@ do_test 2.2 { sqlite3 db test.db set fd [db incrblob t1 x 5] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd 22 puts -nonewline $fd "\x5d" diff --git a/test/crash.test b/test/crash.test index c1901daec..f63163659 100644 --- a/test/crash.test +++ b/test/crash.test @@ -399,7 +399,7 @@ do_test crash-7.1 { # Change the checksum value for the master journal name. set f [open test.db-journal a] - fconfigure $f -encoding binary + fconfigure $f -translation binary seek $f [expr [file size test.db-journal] - 12] puts -nonewline $f "\00\00\00\00" close $f diff --git a/test/distinct2.test b/test/distinct2.test index 023e2e333..980b0b1e3 100644 --- a/test/distinct2.test +++ b/test/distinct2.test @@ -362,4 +362,22 @@ do_execsql_test 5070 { SELECT v4.e FROM t3 LEFT JOIN v4 ON true GROUP BY 1; } NULL +# 2024-06-28 dbsqlfuzz 46343912848a603e32c6072cae792eb056bac897 +# Do not call sqlite3ExprToRegister() on an expression that is already +# a register. +# +do_execsql_test 5080 { + CREATE TABLE dual(dummy TEXT); + INSERT INTO dual VALUES('X'); + SELECT 11 = ( + SELECT b + FROM ( + SELECT a AS b + FROM dual + LEFT JOIN (SELECT 22 AS a FROM dual) + ) + GROUP BY b, b + ); +} 0 + finish_test diff --git a/test/eqp.test b/test/eqp.test index cd441c271..7da78665a 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -311,7 +311,8 @@ det 3.3.1 { QUERY PLAN |--SCAN t1 `--LIST SUBQUERY xxxxxx - `--SCAN t2 + |--SCAN t2 + `--CREATE BLOOM FILTER } det 3.3.2 { SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x) diff --git a/test/exclusive2.test b/test/exclusive2.test index 92fcd76ab..0a5d2b6eb 100644 --- a/test/exclusive2.test +++ b/test/exclusive2.test @@ -41,7 +41,7 @@ sqlite3_soft_heap_limit 0 proc pagerChangeCounter {filename new {fd ""}} { if {$fd==""} { set fd [open $filename RDWR] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set needClose 1 } else { set needClose 0 @@ -70,7 +70,7 @@ proc pagerChangeCounter {filename new {fd ""}} { proc readPagerChangeCounter {filename} { set fd [open $filename RDONLY] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary seek $fd 24 foreach {a b c d} [list 0 0 0 0] {} diff --git a/test/func6.test b/test/func6.test index fe90a755d..acca490f3 100644 --- a/test/func6.test +++ b/test/func6.test @@ -43,7 +43,7 @@ do_execsql_test func6-100 { # string. proc loadhex {file} { set fd [open $file] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set data [read $fd] close $fd binary encode hex $data diff --git a/test/func7.test b/test/func7.test index bb4f80b32..6026b557f 100644 --- a/test/func7.test +++ b/test/func7.test @@ -100,13 +100,13 @@ do_execsql_test func7-pg-300 { SELECT acos(1); } {0.0} do_execsql_test func7-pg-301 { - SELECT degrees(acos(0.5)); + SELECT format('%f',degrees(acos(0.5))); } {60.0} do_execsql_test func7-pg-310 { SELECT round( asin(1), 7); } {1.5707963} do_execsql_test func7-pg-311 { - SELECT degrees( asin(0.5) ); + SELECT format('%f',degrees( asin(0.5) )); } {30.0} do_execsql_test func7-pg-320 { SELECT round( atan(1), 7); @@ -139,7 +139,7 @@ do_execsql_test func7-pg-420 { SELECT round( tan(1), 7); } {1.5574077} do_execsql_test func7-pg-421 { - SELECT tan( radians(45) ); + SELECT round(tan( radians(45) ),10); } {1.0} do_execsql_test func7-pg-500 { SELECT round( sinh(1), 7); diff --git a/test/fuzz3.test b/test/fuzz3.test index bf778ed2b..8ac1f4d58 100644 --- a/test/fuzz3.test +++ b/test/fuzz3.test @@ -83,7 +83,7 @@ proc modify_database {iMod} { set offset [expr {$iMod>>8}] set fd [open test.db r+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd $offset set old_blob [read $fd 1] seek $fd $offset diff --git a/test/in7.test b/test/in7.test index 099f75c5f..29013ff59 100644 --- a/test/in7.test +++ b/test/in7.test @@ -137,5 +137,61 @@ do_execsql_test 2.1 { SELECT b FROM t1 WHERE a IN (1,2,3) ORDER BY b ASC NULLS LAST; } {one three {}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE x1(a); + INSERT INTO x1 VALUES(1), (2), (3); + + CREATE TABLE x2(b); + INSERT INTO x2 VALUES(4), (5), (6); + + CREATE TABLE t1(u); + INSERT INTO t1 VALUES(1), (2), (3), (4), (5), (6); + + CREATE VIEW v1 AS SELECT u FROM t1 WHERE u IN ( + SELECT a FROM x1 + ); + CREATE VIEW v2 AS SELECT u FROM t1 WHERE u IN ( + SELECT b FROM x2 + ); +} + +do_execsql_test 3.1 { + SELECT * FROM v1 +} { + 1 2 3 +} + +do_execsql_test 3.2 { + SELECT * FROM v2 +} { + 4 5 6 +} + +do_execsql_test 3.3 { + SELECT * FROM v2 + UNION ALL + SELECT * FROM v1 +} { + 4 5 6 + 1 2 3 +} + +do_execsql_test 3.4 { + WITH w1 AS ( + SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 + ), + w2 AS ( + SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 + ) + SELECT * FROM v1 WHERE u IN w1 + UNION ALL + SELECT * FROM v2 WHERE u IN w2 +} { + 1 2 3 4 5 6 +} + + finish_test diff --git a/test/incrvacuum3.test b/test/incrvacuum3.test index e901bfe1f..b4cbc8b0c 100644 --- a/test/incrvacuum3.test +++ b/test/incrvacuum3.test @@ -50,8 +50,8 @@ proc check_on_disk {} { set sz [file size test.db] set fd [open test.db] set fd2 [open test2.db w] - fconfigure $fd -encoding binary -translation binary - fconfigure $fd2 -encoding binary -translation binary + fconfigure $fd -translation binary + fconfigure $fd2 -translation binary if {$sz>$::sqlite_pending_byte} { puts -nonewline $fd2 [read $fd $::sqlite_pending_byte] seek $fd [expr $::sqlite_pending_byte+512] diff --git a/test/ioerr.test b/test/ioerr.test index 29a3dede8..fb54d8b38 100644 --- a/test/ioerr.test +++ b/test/ioerr.test @@ -225,7 +225,7 @@ if {$tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0} { } forcecopy test2.db-journal test.db-journal set f [open test.db-journal a] - fconfigure $f -encoding binary + fconfigure $f -translation binary puts -nonewline $f "hello" puts -nonewline $f "\x00\x00\x00\x05\x01\x02\x03\x04" puts -nonewline $f "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" diff --git a/test/ioerr5.test b/test/ioerr5.test index a430f5340..a0a74bd95 100644 --- a/test/ioerr5.test +++ b/test/ioerr5.test @@ -117,7 +117,7 @@ foreach locking_mode {normal exclusive} { # Read the contents of the database file into a Tcl variable. # set fd [open test.db] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set zDatabase [read $fd] close $fd @@ -138,7 +138,7 @@ foreach locking_mode {normal exclusive} { # do_test ioerr5-1.$locking_mode-$iFail.4 { set fd [open test.db] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set zDatabase2 [read $fd] close $fd expr {$zDatabase eq $zDatabase2} diff --git a/test/lock5.test b/test/lock5.test index d5950118c..e0c88aedc 100644 --- a/test/lock5.test +++ b/test/lock5.test @@ -207,7 +207,7 @@ if {[permutation]!="inmemory_journal"} { # not commit it. # 3. Make a copy of the database files on disk. # 4. Try to read from the copy using unix-dotfile VFS. This fails because - # the dotfile still exists, so SQLite things the database is locked. + # the dotfile still exists, so SQLite thinks the database is locked. # 5. Remove the dotfile. # 6. Try to read the db again. This time, the old transaction is rolled # back and the read permitted. @@ -269,5 +269,3 @@ if {[permutation]!="inmemory_journal"} { } finish_test - - diff --git a/test/memdb1.test b/test/memdb1.test index 3a31c8e28..c0510abae 100644 --- a/test/memdb1.test +++ b/test/memdb1.test @@ -245,7 +245,7 @@ if {[wal_is_capable]} { db close set fd [open test.db] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set data [read $fd [expr 20*1024]] close $fd diff --git a/test/misc3.test b/test/misc3.test index bc1f0ff91..f64b0fe1d 100644 --- a/test/misc3.test +++ b/test/misc3.test @@ -88,8 +88,8 @@ do_test misc3-2.4 { execsql {SELECT 2e-25*0.5e250} } 1e+225 do_test misc3-2.5 { - execsql {SELECT 2.0e-250*0.5e25} -} 1e-225 + execsql {SELECT format('%.15e',2.0e-250*0.5e25)} +} {1.0000000000000e-225} do_test misc3-2.6 { execsql {SELECT '-2.0e-127' * '-0.5e27'} } 1e-100 diff --git a/test/nan.test b/test/nan.test index 615a4ad22..8d8a98ab3 100644 --- a/test/nan.test +++ b/test/nan.test @@ -281,6 +281,7 @@ do_test nan-4.14 { # These tests test some really, really small floating point numbers. # +load_static_extension db decimal if {$tcl_platform(platform) != "symbian"} { # These two are not run on symbian because tcl has trouble converting # the very small numbers back to text form (probably due to a difference @@ -291,15 +292,15 @@ if {$tcl_platform(platform) != "symbian"} { set small \ [string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" - db eval {SELECT x, typeof(x) FROM t1} - } {9.88131291682493e-324 real} + db eval {SELECT decimal_exp(x), typeof(x) FROM t1} + } {/9\.88131291682493\d*e-324 real/} do_test nan-4.16 { db eval {DELETE FROM t1} set small \ -[string repeat 0 10000].[string repeat 0 323][string repeat 9 10000] db eval "INSERT INTO t1 VALUES($small)" - db eval {SELECT x, typeof(x) FROM t1} - } {-9.88131291682493e-324 real} + db eval {SELECT decimal_exp(x), typeof(x) FROM t1} + } {/-9\.88131291682493\d*e-324 real/} } do_test nan-4.17 { db eval {DELETE FROM t1} diff --git a/test/pendingrace.test b/test/pendingrace.test index ef42578f2..80160149a 100644 --- a/test/pendingrace.test +++ b/test/pendingrace.test @@ -61,12 +61,12 @@ proc my_db_restore {} { forcecopy sv_test.db-journal test.db-journal set fd1 [open sv_test.db r] - fconfigure $fd1 -encoding binary -translation binary + fconfigure $fd1 -translation binary set data [read $fd1] close $fd1 set fd1 [open test.db w] - fconfigure $fd1 -encoding binary -translation binary + fconfigure $fd1 -translation binary puts -nonewline $fd1 $data close $fd1 } diff --git a/test/percentile.test b/test/percentile.test index b2bd061e8..ab5b4883f 100644 --- a/test/percentile.test +++ b/test/percentile.test @@ -38,6 +38,23 @@ foreach {in out} { execsql {SELECT percentile(x,$in) FROM t1} } $out } +do_execsql_test percentile-1.1.median { + SELECT median(x) FROM t1; +} 8.0 + +foreach {in out} { + 1.0 11.0 + 0.5 8.0 + 0.125 4.0 + 0.15 4.4 + 0.2 5.2 + 0.8 11.0 + 0.89 11.0 +} { + do_test percentile-1.1b-$in { + execsql {SELECT percentile_cont(x,$in) FROM t1} + } $out +} # Add some NULL values. # @@ -109,6 +126,9 @@ do_test percentile-1.11 { do_test percentile-1.12 { catchsql {SELECT percentile(x,x'3530') FROM t1} } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}} +do_test percentile-1.12b { + catchsql {SELECT percentile_cont(x,x'3530') FROM t1} +} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}} # Second argument is out of range # @@ -118,6 +138,9 @@ do_test percentile-1.13 { do_test percentile-1.14 { catchsql {SELECT percentile(x,100.0000001) FROM t1} } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}} +do_test percentile-1.14b { + catchsql {SELECT percentile_cont(x,1.0000001) FROM t1} +} {1 {2nd argument to percentile_cont() is not a number between 0.0 and 1.0}} # First argument is not NULL and is not NUMERIC # diff --git a/test/pushdown.test b/test/pushdown.test index 5c3e8182d..271d412e7 100644 --- a/test/pushdown.test +++ b/test/pushdown.test @@ -275,14 +275,13 @@ do_eqp_test 6.1 { | | `--LIST SUBQUERY xxxxxx | | |--MATERIALIZE k | | | `--SCAN 3 CONSTANT ROWS - | | `--SCAN k + | | |--SCAN k + | | `--CREATE BLOOM FILTER | `--UNION ALL | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) - | `--LIST SUBQUERY xxxxxx - | `--SCAN k + | `--REUSE LIST SUBQUERY xxxxxx |--SEARCH t0 - `--LIST SUBQUERY xxxxxx - `--SCAN k + `--REUSE LIST SUBQUERY xxxxxx } # ^^^^--- The key feature above is that the SEARCH for each subquery # uses all three fields of the index w, x, and y. Prior to the push-down @@ -300,18 +299,13 @@ do_eqp_test 6.2 { | | `--LIST SUBQUERY xxxxxx | | |--CO-ROUTINE v1 | | | `--SCAN 3 CONSTANT ROWS - | | `--SCAN v1 + | | |--SCAN v1 + | | `--CREATE BLOOM FILTER | `--UNION ALL | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) - | `--LIST SUBQUERY xxxxxx - | |--CO-ROUTINE v1 - | | `--SCAN 3 CONSTANT ROWS - | `--SCAN v1 + | `--REUSE LIST SUBQUERY xxxxxx |--SEARCH t0 - `--LIST SUBQUERY xxxxxx - |--CO-ROUTINE v1 - | `--SCAN 3 CONSTANT ROWS - `--SCAN v1 + `--REUSE LIST SUBQUERY xxxxxx } do_eqp_test 6.3 { SELECT max(z) FROM t0 WHERE w=123 AND x IN k1 AND y BETWEEN 44 AND 55; @@ -322,14 +316,13 @@ do_eqp_test 6.3 { | |--LEFT-MOST SUBQUERY | | |--SEARCH t01 USING INDEX t01x (w=? AND x=? AND y>? AND y<?) | | `--LIST SUBQUERY xxxxxx - | | `--SCAN k1 + | | |--SCAN k1 + | | `--CREATE BLOOM FILTER | `--UNION ALL | |--SEARCH t02 USING INDEX t02x (w=? AND x=? AND y>? AND y<?) - | `--LIST SUBQUERY xxxxxx - | `--SCAN k1 + | `--REUSE LIST SUBQUERY xxxxxx |--SEARCH t0 - `--LIST SUBQUERY xxxxxx - `--SCAN k1 + `--REUSE LIST SUBQUERY xxxxxx } finish_test diff --git a/test/readonly.test b/test/readonly.test index 1ccbcee28..303300e6f 100644 --- a/test/readonly.test +++ b/test/readonly.test @@ -15,7 +15,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$tcl_platform(platform)=="windows"} finish_test +if {$tcl_platform(platform)=="windows"} { + finish_test + return +} source $testdir/lock_common.tcl source $testdir/wal_common.tcl set ::testprefix readonly diff --git a/test/recover.test b/test/recover.test index 5495b7a00..268d3a55b 100644 --- a/test/recover.test +++ b/test/recover.test @@ -43,7 +43,6 @@ proc compare_dbs {db1 db2} { proc recover_with_opts {opts} { set cmd ".recover $opts" set fd [open [list |$::CLI test.db $cmd]] - fconfigure $fd -encoding binary fconfigure $fd -translation binary set sql [read $fd] close $fd diff --git a/test/rollback.test b/test/rollback.test index 423bf20fc..f32ce523e 100644 --- a/test/rollback.test +++ b/test/rollback.test @@ -111,7 +111,7 @@ if {$tcl_platform(platform) == "unix" ] set iOffset [expr (([file size testA.db-journal] + 511)/512)*512] set fd [open testA.db-journal a+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd $iOffset puts -nonewline $fd $zAppend diff --git a/test/rowvalue4.test b/test/rowvalue4.test index 784859cb1..1ef5fc292 100644 --- a/test/rowvalue4.test +++ b/test/rowvalue4.test @@ -236,9 +236,11 @@ do_eqp_test 5.1 { QUERY PLAN |--SEARCH d2 USING INDEX d2ab (a=? AND b=?) |--LIST SUBQUERY xxxxxx - | `--SCAN d1 + | |--SCAN d1 + | `--CREATE BLOOM FILTER `--LIST SUBQUERY xxxxxx - `--SCAN d1 + |--SCAN d1 + `--CREATE BLOOM FILTER } do_execsql_test 6.0 { diff --git a/test/scanstatus2.test b/test/scanstatus2.test index 7f107cd2e..c94db88f2 100644 --- a/test/scanstatus2.test +++ b/test/scanstatus2.test @@ -265,7 +265,7 @@ ifcapable trace { } proc trace {stmt sql} { - array set A [sqlite3_stmt_scanstatus -flags complex [format %x $stmt] 0] + array set A [sqlite3_stmt_scanstatus -flags complex [format %llx $stmt] 0] lappend ::trace_explain $A(zExplain) } db trace_v2 trace diff --git a/test/shell1.test b/test/shell1.test index 206fb0a4f..f355989c3 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -1059,7 +1059,7 @@ do_test shell1-5.0 { continue } # Tcl 8.7 maps 0x80 through 0x9f into valid UTF8. So skip those tests. - if {$i>=0x80 && $i<=0x9f} continue + if {$i>=0x80 && ($i<=0x9F || $tcl_version>=9.0)} continue if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"} continue if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"} continue set hex [format %02X $i] diff --git a/test/shell5.test b/test/shell5.test index 8727edaaf..31d5449fd 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -410,7 +410,7 @@ CREATE TABLE t4(a, b); # do_test shell5-3.1 { set fd [open shell5.csv w] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary puts -nonewline $fd "\"test 1\"\x1F,test 2\r\n\x1E" puts -nonewline $fd "test 3\x1Ftest 4\n" close $fd diff --git a/test/shell7.test b/test/shell7.test index dfd9e47c2..460789e54 100644 --- a/test/shell7.test +++ b/test/shell7.test @@ -33,7 +33,6 @@ do_execsql_test 1.0 { foreach {tn l x} [db eval { SELECT tn, length(x) AS l, x FROM f1 }] { forcedelete shell7_test.bin set fd [open shell7_test.bin w] - fconfigure $fd -encoding binary fconfigure $fd -translation binary puts -nonewline $fd $x close $fd diff --git a/test/superlock.test b/test/superlock.test index 704b0677a..10e7caa29 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -166,7 +166,7 @@ do_multiclient_test tn { proc read_content {file} { if {[file exists $file]==0} {return ""} set fd [open $file] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary set content [read $fd] close $fd return $content @@ -174,7 +174,7 @@ proc read_content {file} { proc write_content {file content} { set fd [open $file w+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary puts -nonewline $fd $content close $fd } diff --git a/test/syscall.test b/test/syscall.test index 19313a5e6..fe4a4177f 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -211,7 +211,7 @@ forcedelete test.db test.db2 proc create_db_file {nByte} { set fd [open test.db w] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary puts -nonewline $fd [string range "xSQLite" 1 $nByte] close $fd } diff --git a/test/tester.tcl b/test/tester.tcl index b96bc505d..63c83187a 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -310,66 +310,6 @@ proc do_delete_file {force args} { } } -if {$::tcl_platform(platform) eq "windows"} { - proc do_remove_win32_dir {args} { - set nRetry [getFileRetries] ;# Maximum number of retries. - set nDelay [getFileRetryDelay] ;# Delay in ms before retrying. - - foreach dirName $args { - # On windows, sometimes even a [remove_win32_dir] can fail just after - # a directory is emptied. The cause is usually "tag-alongs" - programs - # like anti-virus software, automatic backup tools and various explorer - # extensions that keep a file open a little longer than we expect, - # causing the delete to fail. - # - # The solution is to wait a short amount of time before retrying the - # removal. - # - if {$nRetry > 0} { - for {set i 0} {$i < $nRetry} {incr i} { - set rc [catch { - remove_win32_dir $dirName - } msg] - if {$rc == 0} break - if {$nDelay > 0} { after $nDelay } - } - if {$rc} { error $msg } - } else { - remove_win32_dir $dirName - } - } - } - - proc do_delete_win32_file {args} { - set nRetry [getFileRetries] ;# Maximum number of retries. - set nDelay [getFileRetryDelay] ;# Delay in ms before retrying. - - foreach fileName $args { - # On windows, sometimes even a [delete_win32_file] can fail just after - # a file is closed. The cause is usually "tag-alongs" - programs like - # anti-virus software, automatic backup tools and various explorer - # extensions that keep a file open a little longer than we expect, - # causing the delete to fail. - # - # The solution is to wait a short amount of time before retrying the - # delete. - # - if {$nRetry > 0} { - for {set i 0} {$i < $nRetry} {incr i} { - set rc [catch { - delete_win32_file $fileName - } msg] - if {$rc == 0} break - if {$nDelay > 0} { after $nDelay } - } - if {$rc} { error $msg } - } else { - delete_win32_file $fileName - } - } - } -} - proc execpresql {handle args} { trace remove execution $handle enter [list execpresql $handle] if {[info exists ::G(perm:presql)]} { @@ -847,6 +787,9 @@ proc do_test {name cmd expected} { } } else { set ok [expr {[string compare $result $expected]==0}] + if {!$ok} { + set ok [fpnum_compare $result $expected] + } } if {!$ok} { # if {![info exists ::testprefix] || $::testprefix eq ""} { @@ -897,7 +840,7 @@ proc catchsafecmd {db {cmd ""}} { proc catchcmdex {db {cmd ""}} { global CLI set out [open cmds.txt w] - fconfigure $out -encoding binary -translation binary + fconfigure $out -translation binary puts -nonewline $out $cmd close $out set line "exec -keepnewline -- $CLI $db < cmds.txt" @@ -905,7 +848,7 @@ proc catchcmdex {db {cmd ""}} { foreach chan $chans { catch { set modes($chan) [fconfigure $chan] - fconfigure $chan -encoding binary -translation binary -buffering none + fconfigure $chan -translation binary -buffering none } } set rc [catch { eval $line } msg] diff --git a/test/testrunner.tcl b/test/testrunner.tcl index fd8271676..b32052873 100644 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -399,7 +399,7 @@ if {[llength $argv]==1 } sqlite3 mydb $TRG(dbname) - mydb timeout 1000 + mydb timeout 2000 mydb eval BEGIN set cmdline [mydb one { SELECT value FROM config WHERE name='cmdline' }] @@ -447,7 +447,7 @@ if {[llength $argv]==1 } job { display_job [array get job] } - set nOmit [db one {SELECT count(*) FROM jobs WHERE state='omit'}] + set nOmit [mydb one {SELECT count(*) FROM jobs WHERE state='omit'}] if {$nOmit} { puts "$nOmit jobs omitted due to failures" } @@ -963,6 +963,7 @@ proc add_jobs_from_cmdline {patternlist} { proc make_new_testset {} { global TRG + trdb eval {PRAGMA journal_mode=WAL;} r_write_db { trdb eval $TRG(schema) set nJob $TRG(nJob) @@ -1117,7 +1118,7 @@ proc launch_another_job {iJob} { set fd [open "|$TRG(runcmd) 2>@1" r] cd $pwd - fconfigure $fd -blocking false + fconfigure $fd -blocking false -translation binary fileevent $fd readable [list script_input_ready $fd $iJob $job(jobid)] } diff --git a/test/testrunner_data.tcl b/test/testrunner_data.tcl index f8f12d91a..af480fc4c 100644 --- a/test/testrunner_data.tcl +++ b/test/testrunner_data.tcl @@ -486,7 +486,7 @@ proc make_sh_script {srcdir opts cflags makeOpts configOpts} { TCLDIR="$tcldir" if [ ! -f Makefile ] ; then - \$SRCDIR/configure --with-tcl=\$TCL $configOpts + \$SRCDIR/configure --with-tcl=\$TCLDIR $configOpts fi $myopts diff --git a/test/tkt-2d1a5c67d.test b/test/tkt-2d1a5c67d.test index 1f797686b..5dad78169 100644 --- a/test/tkt-2d1a5c67d.test +++ b/test/tkt-2d1a5c67d.test @@ -102,6 +102,7 @@ do_test 3.4 { set blobs [list] for {set i 1} {$i<100} {incr i} { set b [db incrblob -readonly t3 b $i] + fconfigure $b -translation binary read $b lappend blobs $b } diff --git a/test/tkt3457.test b/test/tkt3457.test index 24b4f0eac..027349463 100644 --- a/test/tkt3457.test +++ b/test/tkt3457.test @@ -58,7 +58,7 @@ do_test tkt3457-1.1 { # start of the first journal-header has not been written by SQLite. # So write it now. set fd [open bak.db-journal a+] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary seek $fd 0 puts -nonewline $fd "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7" close $fd diff --git a/test/types3.test b/test/types3.test index 0ff346ce2..457ee6d68 100644 --- a/test/types3.test +++ b/test/types3.test @@ -18,10 +18,9 @@ source $testdir/tester.tcl # A variable with only a string representation comes in as TEXT do_test types3-1.1 { - set V {} - append V x + set V [format %s xxxxx] concat [tcl_variable_type V] [execsql {SELECT typeof(:V)}] -} {string text} +} {text} # A variable with an integer representation comes in as INTEGER do_test types3-1.2 { diff --git a/test/vtabH.test b/test/vtabH.test index f1a046655..cf3dcafd9 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -128,10 +128,10 @@ if {$tcl_platform(platform)=="windows"} { set drive [string range [pwd] 0 1] set ::env(fstreeDrive) $drive } +reset_db +register_fs_module db if {$tcl_platform(platform)!="windows" || \ [regexp -nocase -- {^[A-Z]:} $drive]} { - reset_db - register_fs_module db do_execsql_test 3.0 { SELECT name FROM fsdir WHERE dir = '.' AND name = 'test.db'; SELECT name FROM fsdir WHERE dir = '.' AND name = '.' diff --git a/test/wal.test b/test/wal.test index 234668240..50988debe 100644 --- a/test/wal.test +++ b/test/wal.test @@ -1219,7 +1219,7 @@ foreach {tn pgsz works} { set framehdr [binary format IIIIII $pg 5 22 23 $c1 $c2] set fd [open test.db-wal w] - fconfigure $fd -encoding binary -translation binary + fconfigure $fd -translation binary puts -nonewline $fd $walhdr puts -nonewline $fd $framehdr puts -nonewline $fd $framebody diff --git a/test/wal2.test b/test/wal2.test index ae6134d8b..5e4c4ebc2 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -1098,7 +1098,11 @@ if {$::tcl_platform(platform) == "unix"} { 3 00600 4 00755 } { - set effective [format %.5o [expr $permissions & ~$umask]] + if {$tcl_version>=9.0} { + set effective [format %.5d [expr $permissions & ~$umask]] + } else { + set effective [format %.5o [expr $permissions & ~$umask]] + } do_test wal2-12.2.$tn.1 { file attributes test.db -permissions $permissions string map {o 0} [file attributes test.db -permissions] diff --git a/test/wal_common.tcl b/test/wal_common.tcl index 917ad598f..cdba53b5b 100644 --- a/test/wal_common.tcl +++ b/test/wal_common.tcl @@ -65,7 +65,6 @@ proc wal_set_walhdr {filename {intlist {}}} { set fd [open $filename r+] fconfigure $fd -translation binary - fconfigure $fd -encoding binary seek $fd 0 puts -nonewline $fd $blob close $fd @@ -73,7 +72,6 @@ proc wal_set_walhdr {filename {intlist {}}} { set fd [open $filename] fconfigure $fd -translation binary - fconfigure $fd -encoding binary set blob [read $fd 24] close $fd @@ -89,5 +87,3 @@ proc wal_fix_walindex_cksum {hdrvar} { lset hdr 10 $c1 lset hdr 11 $c2 } - - diff --git a/test/walcksum.test b/test/walcksum.test index f3fc42711..10329ba6c 100644 --- a/test/walcksum.test +++ b/test/walcksum.test @@ -22,7 +22,6 @@ ifcapable !wal {finish_test ; return } # proc readfile {filename} { set fd [open $filename] - fconfigure $fd -encoding binary fconfigure $fd -translation binary set data [read $fd] close $fd @@ -59,7 +58,6 @@ proc log_checksum_write {filename iFrame endian} { set bin [binary format II $c1 $c2] set fd [open $filename r+] - fconfigure $fd -encoding binary fconfigure $fd -translation binary seek $fd $offset puts -nonewline $fd $bin @@ -114,7 +112,6 @@ proc log_checksum_writemagic {filename endian} { set val [expr {0x377f0682 | ($endian == "big" ? 1 : 0)}] set bin [binary format I $val] set fd [open $filename r+] - fconfigure $fd -encoding binary fconfigure $fd -translation binary puts -nonewline $fd $bin diff --git a/test/walslow.test b/test/walslow.test index 2a52a225d..6a0f147a0 100644 --- a/test/walslow.test +++ b/test/walslow.test @@ -109,7 +109,6 @@ foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { forcecopy test.db-wal test2.db-wal set fd [open test2.db-wal r+] - fconfigure $fd -encoding binary fconfigure $fd -translation binary seek $fd $iOff diff --git a/test/win32longpath.test b/test/win32longpath.test index 01b4af70a..c0eac8d9d 100644 --- a/test/win32longpath.test +++ b/test/win32longpath.test @@ -49,19 +49,19 @@ set longPath(1) \\\\?\\$path\\[pid] set uriPath(1a) %5C%5C%3F%5C$path\\[pid] set uriPath(1b) %5C%5C%3F%5C$rawPath/[pid] -make_win32_dir $longPath(1) +file mkdir $longPath(1) set longPath(2) $longPath(1)\\[string repeat X 255] set uriPath(2a) $uriPath(1a)\\[string repeat X 255] set uriPath(2b) $uriPath(1b)/[string repeat X 255] -make_win32_dir $longPath(2) +file mkdir $longPath(2) set longPath(3) $longPath(2)\\[string repeat Y 255] set uriPath(3a) $uriPath(2a)\\[string repeat Y 255] set uriPath(3b) $uriPath(2b)/[string repeat Y 255] -make_win32_dir $longPath(3) +file mkdir $longPath(3) set fileName $longPath(3)\\test.db @@ -92,7 +92,6 @@ do_test 1.4 { } {5 6 7 8} db3 close -# puts " Database exists \{[exists_win32_path $fileName]\}" sqlite3 db3 $fileName -vfs win32-longpath @@ -115,7 +114,6 @@ do_test 1.6 { } {5 6 7 8 9 10 11 12} db3 close -# puts " Database exists \{[exists_win32_path $fileName]\}" foreach tn {1a 1b 1c 1d 1e 1f} { sqlite3 db3 $uri($tn) -vfs win32-longpath -uri 1 -translatefilename 0 @@ -129,11 +127,9 @@ foreach tn {1a 1b 1c 1d 1e 1f} { db3 close } -do_delete_win32_file $fileName -# puts " Files remaining \{[find_win32_file $longPath(3)\\*]\}" - -do_remove_win32_dir $longPath(3) -do_remove_win32_dir $longPath(2) -do_remove_win32_dir $longPath(1) +file delete -force $fileName +file delete -force $longPath(3) +file delete -force $longPath(2) +file delete -force $longPath(1) finish_test diff --git a/test/zipfile.test b/test/zipfile.test index 4d09e08b1..0f854a676 100644 --- a/test/zipfile.test +++ b/test/zipfile.test @@ -10,7 +10,10 @@ #*********************************************************************** # -package require Tcl 8.6 +if {$tcl_version<8.6} { + puts "Requires TCL 8.6 or later" + return +} set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -30,7 +33,7 @@ if {[catch {load_static_extension db fileio} error]} { proc readfile {f} { set fd [open $f] - fconfigure $fd -translation binary -encoding binary + fconfigure $fd -translation binary set data [read $fd] close $fd set data diff --git a/test/zipfile2.test b/test/zipfile2.test index 987e4f0cf..5277cd58f 100644 --- a/test/zipfile2.test +++ b/test/zipfile2.test @@ -10,7 +10,10 @@ #*********************************************************************** # -package require Tcl 8.6 +if {$tcl_version<8.6} { + puts "Requires TCL 8.6 or later" + return +} set testdir [file dirname $argv0] source $testdir/tester.tcl diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 6cb145db8..792695255 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -23,7 +23,7 @@ if {$argc==0} { proc readFile { fileName } { set file_id [open $fileName RDONLY] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result @@ -31,7 +31,7 @@ proc readFile { fileName } { proc writeFile { fileName data } { set file_id [open $fileName {WRONLY CREAT TRUNC}] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" diff --git a/tool/mkvsix.tcl b/tool/mkvsix.tcl index c874d538f..066321363 100644 --- a/tool/mkvsix.tcl +++ b/tool/mkvsix.tcl @@ -156,7 +156,7 @@ proc readFile { fileName } { # may contain binary data. # set file_id [open $fileName RDONLY] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result @@ -168,7 +168,7 @@ proc writeFile { fileName data } { # binary data. # set file_id [open $fileName {WRONLY CREAT TRUNC}] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" diff --git a/tool/replace.tcl b/tool/replace.tcl index e87cb922f..6a462d95f 100644 --- a/tool/replace.tcl +++ b/tool/replace.tcl @@ -4,8 +4,8 @@ # only lines successfully modified with a regular # expression. # -fconfigure stdout -translation binary -encoding binary -fconfigure stderr -translation binary -encoding binary +fconfigure stdout -translation binary +fconfigure stderr -translation binary set mode [string tolower [lindex $argv 0]] set from [lindex $argv 1] set to [lindex $argv 2] diff --git a/tool/restore_jrnl.tcl b/tool/restore_jrnl.tcl index 05af4f9a2..200f9b1d2 100644 --- a/tool/restore_jrnl.tcl +++ b/tool/restore_jrnl.tcl @@ -114,40 +114,40 @@ proc dump_jrnl_page {jrnl_pgno} { set db_pgno [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset] 4]] set chksum [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] 4]] set nonce [calc_nonce $jrnl_pgno] - puts [ format {jrnl_pg_offset: %08x (%d) jrnl_pgno: %d db_pgno: %d} \
- $jrnl_pg_offset $jrnl_pg_offset \
- $jrnl_pgno $db_pgno]
- puts [ format {nonce: %08x chksum: %08x} \
- $nonce $chksum]
+ puts [ format {jrnl_pg_offset: %08x (%d) jrnl_pgno: %d db_pgno: %d} \ + $jrnl_pg_offset $jrnl_pg_offset \ + $jrnl_pgno $db_pgno] + puts [ format {nonce: %08x chksum: %08x} \ + $nonce $chksum] # now hex dump the data - # This is derived from the Tcler's WIKI
- set fid [open $jrnl_name r]
- fconfigure $fid -translation binary -encoding binary
- seek $fid [expr $jrnl_pg_offset+4]
- set data [read $fid $db_pgsz]
- close $fid
+ # This is derived from the Tcler's WIKI + set fid [open $jrnl_name r] + fconfigure $fid -translation binary + seek $fid [expr $jrnl_pg_offset+4] + set data [read $fid $db_pgsz] + close $fid for {set addr 0} {$addr<$db_pgsz} {set addr [expr $addr+16]} { - # get 16 bytes of data
- set s [string range $data $addr [expr $addr+16]]
-
- # Convert the data to hex and to characters.
- binary scan $s H*@0a* hex ascii
-
- # Replace non-printing characters in the data.
- regsub -all -- {[^[:graph:] ]} $ascii {.} ascii
-
- # Split the 16 bytes into two 8-byte chunks
- regexp -- {(.{16})(.{0,16})} $hex -> hex1 hex2
-
- # Convert the hex to pairs of hex digits
- regsub -all -- {..} $hex1 {& } hex1
- regsub -all -- {..} $hex2 {& } hex2
-
- # Print the hex and ascii data
- puts [ format {%08x %-24s %-24s %-16s} \
- $addr $hex1 $hex2 $ascii ]
- }
+ # get 16 bytes of data + set s [string range $data $addr [expr $addr+16]] + + # Convert the data to hex and to characters. + binary scan $s H*@0a* hex ascii + + # Replace non-printing characters in the data. + regsub -all -- {[^[:graph:] ]} $ascii {.} ascii + + # Split the 16 bytes into two 8-byte chunks + regexp -- {(.{16})(.{0,16})} $hex -> hex1 hex2 + + # Convert the hex to pairs of hex digits + regsub -all -- {..} $hex1 {& } hex1 + regsub -all -- {..} $hex2 {& } hex2 + + # Print the hex and ascii data + puts [ format {%08x %-24s %-24s %-16s} \ + $addr $hex1 $hex2 $ascii ] + } } # Setup for the tests. Make a backup copy of the files. @@ -230,4 +230,3 @@ do_test restore_jrnl-1.0 { catchsql {PRAGMA integrity_check} } {0 ok} db close - diff --git a/tool/sqldiff.c b/tool/sqldiff.c index a213a6704..8b2293caf 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -31,7 +31,7 @@ ** correctly on Windows: ** ** fprintf() -> Wfprintf() -** +** */ #if defined(_WIN32) # include "console_io.h" @@ -65,7 +65,7 @@ struct GlobalVars { static void strFree(sqlite3_str *pStr){ sqlite3_free(sqlite3_str_finish(pStr)); } - + /* ** Print an error resulting from faulting command-line arguments and ** abort the program. @@ -1998,7 +1998,7 @@ int main(int argc, char **argv){ if( g.bSchemaOnly && g.bSchemaCompare ){ cmdlineError("The --schema option is useless with --table %s .", zTab); } - rc = sqlite3_open(zDb1, &g.db); + rc = sqlite3_open_v2(zDb1, &g.db, SQLITE_OPEN_READONLY, 0); if( rc ){ cmdlineError("cannot open database file \"%s\"", zDb1); } @@ -2006,6 +2006,13 @@ int main(int argc, char **argv){ if( rc || zErrMsg ){ cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1); } + { + sqlite3 *db2 = 0; + if( sqlite3_open_v2(zDb2, &db2, SQLITE_OPEN_READONLY, 0) ){ + cmdlineError("cannot open database file \"%s\"", zDb2); + } + sqlite3_close(db2); + } #ifndef SQLITE_OMIT_LOAD_EXTENSION sqlite3_enable_load_extension(g.db, 1); for(i=0; i<nExt; i++){ diff --git a/vsixtest/vsixtest.tcl b/vsixtest/vsixtest.tcl index 5dce821dc..8b2288be3 100644 --- a/vsixtest/vsixtest.tcl +++ b/vsixtest/vsixtest.tcl @@ -132,7 +132,7 @@ proc readFile { fileName } { # may contain binary data. # set file_id [open $fileName RDONLY] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary set result [read $file_id] close $file_id return $result @@ -144,7 +144,7 @@ proc writeFile { fileName data } { # binary data. # set file_id [open $fileName {WRONLY CREAT TRUNC}] - fconfigure $file_id -encoding binary -translation binary + fconfigure $file_id -translation binary puts -nonewline $file_id $data close $file_id return "" |