From 28935364ef9c2aa4844c66592f28325a5eaf4d0c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 20:39:19 +0000 Subject: [PATCH 01/55] If the SQLITE_ENABLE_CURSOR_HINTS macro is defined, then invoke the sqlite3BtreeCursorHint() interface to provide hints to the storage engine about rows that need not be returned. Hints can be disabled using SQLITE_TESTCTRL_OPTIMIZATIONS with SQLITE_CursorHints (0x2000). Cursor hints are not used by the built-in storage engine of SQLite but might be useful to applications that provide their own storage engine. The current code is work-in-progrss and contains bugs. FossilOrigin-Name: 3a9bec524ef2de44028b4058e67dc962082888d3 --- manifest | 27 +++++++++++++++------------ manifest.uuid | 2 +- src/btree.c | 15 +++++++++++++++ src/btree.h | 3 +++ src/sqliteInt.h | 1 + src/vdbe.c | 18 ++++++++++++++++++ src/vdbe.h | 4 ++++ src/vdbeaux.c | 21 +++++++++++++++++++++ src/where.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 124 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7cdbd89e49..5b7ad9402f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.8.3. -D 2013-12-07T17:01:23.631 +C If\sthe\sSQLITE_ENABLE_CURSOR_HINTS\smacro\sis\sdefined,\sthen\sinvoke\sthe\nsqlite3BtreeCursorHint()\sinterface\sto\sprovide\shints\sto\sthe\sstorage\sengine\nabout\srows\sthat\sneed\snot\sbe\sreturned.\s\sHints\scan\sbe\sdisabled\susing\nSQLITE_TESTCTRL_OPTIMIZATIONS\swith\sSQLITE_CursorHints\s(0x2000).\s\sCursor\nhints\sare\snot\sused\sby\sthe\sbuilt-in\sstorage\sengine\sof\sSQLite\sbut\smight\nbe\suseful\sto\sapplications\sthat\sprovide\stheir\sown\sstorage\sengine.\s\sThe\ncurrent\scode\sis\swork-in-progrss\sand\scontains\sbugs. +D 2013-12-07T20:39:19.762 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,8 +166,8 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 4037f58ef3f4459d0b9bb1fc1aee1136277d9ba6 -F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 +F src/btree.c 9e6d189894f54744d1a20c63de5afb66342f0904 +F src/btree.h 450f1c6022ec89da529a57f3e704e87c6c14b34d F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 9b40580b62916612678bdb69ce0286e39c29a862 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 @@ -224,7 +224,7 @@ F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h f3a5d663fe9c6c0b2ee7fc2e20a6204eaea5bc7c +F src/sqliteInt.h 081102b2fb2aedc0c67d7a631d16a1fb34accc85 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -280,11 +280,11 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 54894fde8dc806d259e015ac7c9680145e725835 -F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 +F src/vdbe.c 88a037e01278bd8c8093bb3399b250cb02c6e865 +F src/vdbe.h 57b87844270b2e92647b8b82a8948f7a29efae8d F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 09b79d475f5af2b3b5068f639609d88e0ced9d95 +F src/vdbeaux.c c7c9219cb31cef9917db3b3b41604ac74c5bc41b F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c 20e349d2ca928802fc8f2d42a2cc488fd6981d3f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c e6a4e713abe6f995495ea53dd6a5e48f88b53883 +F src/where.c c3bdcd3886e93c129d0ed5a8db17cabde6ea7e73 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1146,7 +1146,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 369a23e00644f3ff8b6a2d2ed73b8cb65e9f124b -R 0fdea442d6dfa8b801d4e6d289982778 +P 23d00f22872a907a8ebf5b80689ff7aa66686a07 +R d784a3d34f33a329aefe46bc5926417e +T *branch * cursor-hints +T *sym-cursor-hints * +T -sym-trunk * U drh -Z 0e445b98f25b8020cec84ec084909f7b +Z c7784e25ec311e9981c59aaad7fb1809 diff --git a/manifest.uuid b/manifest.uuid index 0d9cda82d6..f94f4e8d01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23d00f22872a907a8ebf5b80689ff7aa66686a07 \ No newline at end of file +3a9bec524ef2de44028b4058e67dc962082888d3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a0b6c6ba24..2e2dab0509 100644 --- a/src/btree.c +++ b/src/btree.c @@ -764,6 +764,21 @@ int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ return SQLITE_OK; } +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Give a hint to the cursor that it only has to deliver rows for which +** the expression pExpr is true. Within this expression, rows of the +** cursor are identified by Expr.op==TK_COLUMN with Expr.iTable==iTable. +** +** This interfaces is not used by the standard storage engine of SQLite. +** It is only useful to application that replace SQLite's built-in storage +** engine with their own. +*/ +void sqlite3BtreeCursorHint(BtCursor *pCur, int iTable, const Expr *pExpr){ + /* Alternative storage engines might use this. */ +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + #ifndef SQLITE_OMIT_AUTOVACUUM /* ** Given a page number of a regular database page, return the page diff --git a/src/btree.h b/src/btree.h index 3eb5906955..15816d68ac 100644 --- a/src/btree.h +++ b/src/btree.h @@ -167,6 +167,9 @@ int sqlite3BtreeMovetoUnpacked( int *pRes ); int sqlite3BtreeCursorHasMoved(BtCursor*, int*); +#ifdef SQLITE_ENABLE_CURSOR_HINTS +void sqlite3BtreeCursorHint(BtCursor*, int, const Expr*); +#endif int sqlite3BtreeDelete(BtCursor*); int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8bf05a9c8e..45d78f5663 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1064,6 +1064,7 @@ struct sqlite3 { #define SQLITE_OmitNoopJoin 0x0400 /* Omit unused tables in joins */ #define SQLITE_Stat3 0x0800 /* Use the SQLITE_STAT3 table */ #define SQLITE_AdjustOutEst 0x1000 /* Adjust output estimates using WHERE */ +#define SQLITE_CursorHints 0x2000 /* Add OP_CursorHint opcodes */ #define SQLITE_AllOpts 0xffff /* All optimizations */ /* diff --git a/src/vdbe.c b/src/vdbe.c index 8ae4ce484c..59c6bc6b14 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6170,6 +6170,24 @@ case OP_Trace: { } #endif +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* Opcode: CursorHint P1 P2 * P4 * +** +** Provide a hint to cursor P1 that it only needs to return rows that +** satisfy the Expr tree given in P4. P2 is the table number of cursor P1 +** such that references to cursor P1 in the Expr tree are given by +** Expr.iTable==P2. +*/ +case OP_CursorHint: { + VdbeCursor *pC; + + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( pOp->p4type==P4_EXPR ); + pC = p->apCsr[pOp->p1]; + if( pC ) sqlite3BtreeCursorHint(pC->pCursor, pOp->p2, pOp->p4.pExpr); + break; +} +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* Opcode: Noop * * * * * ** diff --git a/src/vdbe.h b/src/vdbe.h index 62d9aa2711..9f22a1f33c 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -59,6 +59,9 @@ struct VdbeOp { KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ int *ai; /* Used when p4type is P4_INTARRAY */ SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS + Expr *pExpr; /* Used when p4type is P4_EXPR */ +#endif int (*xAdvance)(BtCursor *, int *); } p4; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS @@ -106,6 +109,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */ #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */ #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */ +#define P4_EXPR (-7) /* P4 is a pointer to an Expr tree */ #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */ #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */ #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5b5d82aed8..cd55592cfe 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -639,6 +639,12 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break; } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + case P4_EXPR: { + sqlite3ExprDelete(db, (Expr*)p4); + break; + } +#endif case P4_MPRINTF: { if( db->pnBytesFreed==0 ) sqlite3_free(p4); break; @@ -756,6 +762,15 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ }else if( n==P4_KEYINFO ){ pOp->p4.p = (void*)zP4; pOp->p4type = P4_KEYINFO; +#ifdef SQLITE_ENABLE_CURSOR_HINTS + }else if( n==P4_EXPR ){ + /* Responsibility for deleting the Expr tree is handed over to the + ** VDBE by this operation. The caller should have already invoked + ** sqlite3ExprDup() or whatever other routine is needed to make a + ** private copy of the tree. */ + pOp->p4.pExpr = (Expr*)zP4; + pOp->p4type = P4_EXPR; +#endif }else if( n==P4_VTAB ){ pOp->p4.p = (void*)zP4; pOp->p4type = P4_VTAB; @@ -973,6 +988,12 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ assert( ip4.pColl; sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName); diff --git a/src/where.c b/src/where.c index 7d3ec48dac..bbe5939ed2 100644 --- a/src/where.c +++ b/src/where.c @@ -2715,6 +2715,49 @@ static void explainOneScan( # define explainOneScan(u,v,w,x,y,z) #endif /* SQLITE_OMIT_EXPLAIN */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Insert an OP_CursorHint instruction if it is appropriate to do so. +*/ +static void codeCursorHint( + WhereInfo *pWInfo, + int iLevel +){ + Parse *pParse = pWInfo->pParse; + sqlite3 *db = pParse->db; + Vdbe *v = pParse->pVdbe; + WhereLevel *pLevel; + Expr *pExpr = 0; + int iCur; + Bitmask msk; + WhereClause *pWC; + WhereTerm *pTerm; + WhereLoop *pWLoop; + int i, j; + + if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; + pLevel = &pWInfo->a[iLevel]; + pWLoop = pLevel->pWLoop; + iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; + msk = ~getMask(&pWInfo->sMaskSet, iCur); + pWC = &pWInfo->sWC; + for(i=0; inTerm; i++){ + pTerm = &pWC->a[i]; + if( pTerm->prereqAll & msk ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; + pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); + } + if( pExpr!=0 ){ + sqlite3VdbeAddOp4(v, OP_CursorHint, pLevel->iTabCur, iCur, 0, + (const char*)pExpr, P4_EXPR); + } +} +#else +# define codeCursorHint(A,B) /* No-op */ +#endif /* SQLITE_ENABLE_CURSOR_HINTS */ + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause @@ -2876,6 +2919,7 @@ static Bitmask codeOneLoopStart( pStart = pEnd; pEnd = pTerm; } + codeCursorHint(pWInfo, iLevel); if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ @@ -3061,6 +3105,7 @@ static Bitmask codeOneLoopStart( start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ + codeCursorHint(pWInfo, iLevel); nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; @@ -3408,6 +3453,7 @@ static Bitmask codeOneLoopStart( static const u8 aStep[] = { OP_Next, OP_Prev }; static const u8 aStart[] = { OP_Rewind, OP_Last }; assert( bRev==0 || bRev==1 ); + codeCursorHint(pWInfo, iLevel); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); From 5b88bc4bec6a66d61d1819a69f2c306e3d328e03 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 7 Dec 2013 23:35:21 +0000 Subject: [PATCH 02/55] Do not allow cursor hints to use expressions containing subqueries. This change fixes the problem seen in the previous check-in. FossilOrigin-Name: bfefc57554853e467ee6aeaba8d08331406fa216 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/expr.c | 16 ++++++++++++++++ src/select.c | 6 +++--- src/sqliteInt.h | 2 ++ src/where.c | 1 + 6 files changed, 32 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 5b7ad9402f..03b9a88b67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\sSQLITE_ENABLE_CURSOR_HINTS\smacro\sis\sdefined,\sthen\sinvoke\sthe\nsqlite3BtreeCursorHint()\sinterface\sto\sprovide\shints\sto\sthe\sstorage\sengine\nabout\srows\sthat\sneed\snot\sbe\sreturned.\s\sHints\scan\sbe\sdisabled\susing\nSQLITE_TESTCTRL_OPTIMIZATIONS\swith\sSQLITE_CursorHints\s(0x2000).\s\sCursor\nhints\sare\snot\sused\sby\sthe\sbuilt-in\sstorage\sengine\sof\sSQLite\sbut\smight\nbe\suseful\sto\sapplications\sthat\sprovide\stheir\sown\sstorage\sengine.\s\sThe\ncurrent\scode\sis\swork-in-progrss\sand\scontains\sbugs. -D 2013-12-07T20:39:19.762 +C Do\snot\sallow\scursor\shints\sto\suse\sexpressions\scontaining\ssubqueries.\s\sThis\nchange\sfixes\sthe\sproblem\sseen\sin\sthe\sprevious\scheck-in. +D 2013-12-07T23:35:21.843 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 -F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf +F src/expr.c cdfc50b604ea9c9bbaa44f1f0a5c6cc835e84a32 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -219,12 +219,12 @@ F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a +F src/select.c 44fa5a4a270ce70b59acb616b01bc897e6d1e7ac F src/shell.c 936a72ff784efff3832cce274a96ed0b036e6758 F src/sqlite.h.in 125dc0b76f0116f1cd6f13536db52ba981e1c5bd F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 081102b2fb2aedc0c67d7a631d16a1fb34accc85 +F src/sqliteInt.h ccf72d12670132233750c6275a8ed978a95839aa F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c c3bdcd3886e93c129d0ed5a8db17cabde6ea7e73 +F src/where.c 34cf76979535b933b39403f81c8c757cf3c4fe9f F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1146,10 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 23d00f22872a907a8ebf5b80689ff7aa66686a07 -R d784a3d34f33a329aefe46bc5926417e -T *branch * cursor-hints -T *sym-cursor-hints * -T -sym-trunk * +P 3a9bec524ef2de44028b4058e67dc962082888d3 +R e725a27255f076e1cf88ead0905058a7 U drh -Z c7784e25ec311e9981c59aaad7fb1809 +Z 572bab5aee8e2ee9e755c685fab22b9b diff --git a/manifest.uuid b/manifest.uuid index f94f4e8d01..1397cacead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3a9bec524ef2de44028b4058e67dc962082888d3 \ No newline at end of file +bfefc57554853e467ee6aeaba8d08331406fa216 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6c8a8cce77..8601d4a9b9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1264,6 +1264,22 @@ int sqlite3ExprIsConstantOrFunction(Expr *p){ return exprIsConst(p, 2); } +#ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Walk an expression tree. Return 1 if the expression contains a +** subquery of some kind. Return 0 if there are no subqueries. +*/ +int sqlite3ExprContainsSubquery(Expr *p){ + Walker w; + memset(&w, 0, sizeof(w)); + w.u.i = 1; + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = selectNodeIsConstant; + sqlite3WalkExpr(&w, p); + return w.u.i==0; +} +#endif + /* ** If the expression p codes a constant integer that is small enough ** to fit in a 32-bit integer, return 1 and put the value of the integer diff --git a/src/select.c b/src/select.c index aa8e54b02f..bb979b8f0e 100644 --- a/src/select.c +++ b/src/select.c @@ -3689,7 +3689,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ** Walker.xSelectCallback is set to do something useful for every ** subquery in the parser tree. */ -static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ +int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return WRC_Continue; } @@ -3710,7 +3710,7 @@ static int exprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ Walker w; memset(&w, 0, sizeof(w)); - w.xExprCallback = exprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; if( pParse->hasCompound ){ w.xSelectCallback = convertCompoundSelectToSubquery; @@ -3774,7 +3774,7 @@ static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ Walker w; memset(&w, 0, sizeof(w)); w.xSelectCallback = selectAddSubqueryTypeInfo; - w.xExprCallback = exprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; w.bSelectDepthFirst = 1; sqlite3WalkSelect(&w, pSelect); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 45d78f5663..8cb7820e3d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2617,6 +2617,7 @@ int sqlite3WalkExprList(Walker*, ExprList*); int sqlite3WalkSelect(Walker*, Select*); int sqlite3WalkSelectExpr(Walker*, Select*); int sqlite3WalkSelectFrom(Walker*, Select*); +int sqlite3ExprWalkNoop(Walker*, Expr*); /* ** Return code from the parse-tree walking primitives and their @@ -2971,6 +2972,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3*); int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*); +int sqlite3ExprContainsSubquery(Expr*); int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int); diff --git a/src/where.c b/src/where.c index bbe5939ed2..9d6679a866 100644 --- a/src/where.c +++ b/src/where.c @@ -2745,6 +2745,7 @@ static void codeCursorHint( pTerm = &pWC->a[i]; if( pTerm->prereqAll & msk ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} if( jnLTerm ) continue; pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); From 159c1a18db659f3747111fb8ee83946710252867 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 14 Jul 2014 19:04:29 +0000 Subject: [PATCH 03/55] In the expression passed to sqlite3BtreeCursorHint() for the inner loops of joins, replace any TK_COLUMN references to columns in the outer loops with TK_REGISTER expressions (Expr.iTable indicates the specific register containing the value). FossilOrigin-Name: f9dddd008c6ef7940a1d66363fbb456cff7207c1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 03b9a88b67..b8747caf6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\scursor\shints\sto\suse\sexpressions\scontaining\ssubqueries.\s\sThis\nchange\sfixes\sthe\sproblem\sseen\sin\sthe\sprevious\scheck-in. -D 2013-12-07T23:35:21.843 +C In\sthe\sexpression\spassed\sto\ssqlite3BtreeCursorHint()\sfor\sthe\sinner\sloops\sof\sjoins,\sreplace\sany\sTK_COLUMN\sreferences\sto\scolumns\sin\sthe\souter\sloops\swith\sTK_REGISTER\sexpressions\s(Expr.iTable\sindicates\sthe\sspecific\sregister\scontaining\sthe\svalue). +D 2014-07-14T19:04:29.385 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 34cf76979535b933b39403f81c8c757cf3c4fe9f +F src/where.c dcea6104452e837cc63bd1c3c5cb05868bb356ba F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1146,7 +1146,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3a9bec524ef2de44028b4058e67dc962082888d3 -R e725a27255f076e1cf88ead0905058a7 -U drh -Z 572bab5aee8e2ee9e755c685fab22b9b +P bfefc57554853e467ee6aeaba8d08331406fa216 +R d30e9be65b11497e93ad990065d669d6 +U dan +Z c72f8637bcd1205d8e636acedbe3ca98 diff --git a/manifest.uuid b/manifest.uuid index 1397cacead..9676e57f7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfefc57554853e467ee6aeaba8d08331406fa216 \ No newline at end of file +f9dddd008c6ef7940a1d66363fbb456cff7207c1 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 9d6679a866..a218fd56c6 100644 --- a/src/where.c +++ b/src/where.c @@ -2716,6 +2716,41 @@ static void explainOneScan( #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_CURSOR_HINTS + +/* +** This function is called on every node of an expression tree used as an +** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN +** that accesses any cursor other than (pWalker->u.i), do the following: +** +** 1) allocate a register and code an OP_Column instruction to read +** the specified column into the new register, and +** +** 2) transform the expression node to a TK_REGISTER node that reads +** from the newly populated register. +*/ +static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ + int rc = WRC_Continue; + if( pExpr->op==TK_COLUMN && pExpr->iTable!=pWalker->u.i ){ + Vdbe *v = pWalker->pParse->pVdbe; + int reg = ++pWalker->pParse->nMem; /* Register for column value */ + sqlite3ExprCodeGetColumnOfTable( + v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg + ); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pExpr->op==TK_AGG_FUNCTION ){ + /* An aggregate function in the WHERE clause of a query means this must + ** be a correlated sub-query, and expression pExpr is an aggregate from + ** the parent context. Do not walk the function arguments in this case. + ** + ** todo: It should be possible to replace this node with a TK_REGISTER + ** expression, as the result of the expression must be stored in a + ** register at this point. The same holds for TK_AGG_COLUMN nodes. */ + rc = WRC_Prune; + } + return rc; +} + /* ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ @@ -2739,20 +2774,26 @@ static void codeCursorHint( pLevel = &pWInfo->a[iLevel]; pWLoop = pLevel->pWLoop; iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; - msk = ~getMask(&pWInfo->sMaskSet, iCur); pWC = &pWInfo->sWC; for(i=0; inTerm; i++){ pTerm = &pWC->a[i]; - if( pTerm->prereqAll & msk ) continue; + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( pTerm->prereqAll & pLevel->notReady ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} if( jnLTerm ) continue; pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); - } + } if( pExpr!=0 ){ - sqlite3VdbeAddOp4(v, OP_CursorHint, pLevel->iTabCur, iCur, 0, - (const char*)pExpr, P4_EXPR); + const char *a = (const char*)pExpr; + Walker sWalker; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.xExprCallback = codeCursorHintFixExpr; + sWalker.pParse = pParse; + sWalker.u.i = pLevel->iTabCur; + sqlite3WalkExpr(&sWalker, pExpr); + sqlite3VdbeAddOp4(v, OP_CursorHint, pLevel->iTabCur, iCur, 0, a, P4_EXPR); } } #else From 91d3a61f8abed1078103bbf53dcd491ab73eb5be Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 15 Jul 2014 11:59:44 +0000 Subject: [PATCH 04/55] Add simple tests for new sqlite3BtreeCursorHint() functionality. FossilOrigin-Name: 1efa6ed584172291edce78faf9021e577583d03b --- main.mk | 1 + manifest | 20 +++--- manifest.uuid | 2 +- src/tclsqlite.c | 2 + src/test_cursorhint.c | 162 ++++++++++++++++++++++++++++++++++++++++++ src/vdbe.c | 8 ++- src/where.c | 1 - test/cursorhint.test | 72 +++++++++++++++++++ 8 files changed, 256 insertions(+), 12 deletions(-) create mode 100644 src/test_cursorhint.c create mode 100644 test/cursorhint.test diff --git a/main.mk b/main.mk index 41d1743832..3523243994 100644 --- a/main.mk +++ b/main.mk @@ -242,6 +242,7 @@ TESTSRC = \ $(TOP)/src/test_backup.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ + $(TOP)/src/test_cursorhint.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/manifest b/manifest index b8747caf6d..6cff144128 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sexpression\spassed\sto\ssqlite3BtreeCursorHint()\sfor\sthe\sinner\sloops\sof\sjoins,\sreplace\sany\sTK_COLUMN\sreferences\sto\scolumns\sin\sthe\souter\sloops\swith\sTK_REGISTER\sexpressions\s(Expr.iTable\sindicates\sthe\sspecific\sregister\scontaining\sthe\svalue). -D 2014-07-14T19:04:29.385 +C Add\ssimple\stests\sfor\snew\ssqlite3BtreeCursorHint()\sfunctionality. +D 2014-07-15T11:59:44.612 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -142,7 +142,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff -F main.mk 82fd90375561d7b66287ae5a8b09e1e027394019 +F main.mk a6fa2dee82ed65ef48edc82baa0b480366f53212 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 @@ -228,7 +228,7 @@ F src/sqliteInt.h ccf72d12670132233750c6275a8ed978a95839aa F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 +F src/tclsqlite.c 571af8d366a8c00106c8c4bfa5b2ab07a9e58baf F src/test1.c 760e0419705f712d80595f47199568cd7e3b57a4 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -243,6 +243,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 F src/test_config.c 10d0e00dd6315879a6d9fac20bd063c7bbbfb8f8 +F src/test_cursorhint.c 7c37315e15d6543689e8b48979a8eb370baa3cfc F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -280,7 +281,7 @@ F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 76ed0519296e3f62e97e57dab1999e34184c8e49 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 88a037e01278bd8c8093bb3399b250cb02c6e865 +F src/vdbe.c 54e269c6268a6f37697e27d6bc572674f14b1581 F src/vdbe.h 57b87844270b2e92647b8b82a8948f7a29efae8d F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -293,7 +294,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c dcea6104452e837cc63bd1c3c5cb05868bb356ba +F src/where.c 907fd82f4f8fc89d8a72d44caf5a5679c0769630 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -420,6 +421,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 +F test/cursorhint.test e55ad8c466327ffb3511b60007102bca22314d0a F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1146,7 +1148,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P bfefc57554853e467ee6aeaba8d08331406fa216 -R d30e9be65b11497e93ad990065d669d6 +P f9dddd008c6ef7940a1d66363fbb456cff7207c1 +R 9fb1051a18f0e187efee634c86c45e62 U dan -Z c72f8637bcd1205d8e636acedbe3ca98 +Z 04e07c13931dc702da8721e6980ca969 diff --git a/manifest.uuid b/manifest.uuid index 9676e57f7d..f1780b6a8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f9dddd008c6ef7940a1d66363fbb456cff7207c1 \ No newline at end of file +1efa6ed584172291edce78faf9021e577583d03b \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 0f57dda6ca..c592d854cc 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3672,6 +3672,7 @@ static void init_all(Tcl_Interp *interp){ extern int Sqlitetest9_Init(Tcl_Interp*); extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetest_autoext_Init(Tcl_Interp*); + extern int Sqlitetest_cursorhint_Init(Tcl_Interp*); extern int Sqlitetest_demovfs_Init(Tcl_Interp *); extern int Sqlitetest_func_Init(Tcl_Interp*); extern int Sqlitetest_hexio_Init(Tcl_Interp*); @@ -3715,6 +3716,7 @@ static void init_all(Tcl_Interp *interp){ Sqlitetest9_Init(interp); Sqlitetestasync_Init(interp); Sqlitetest_autoext_Init(interp); + Sqlitetest_cursorhint_Init(interp); Sqlitetest_demovfs_Init(interp); Sqlitetest_func_Init(interp); Sqlitetest_hexio_Init(interp); diff --git a/src/test_cursorhint.c b/src/test_cursorhint.c new file mode 100644 index 0000000000..9d2450da27 --- /dev/null +++ b/src/test_cursorhint.c @@ -0,0 +1,162 @@ +/* +** 2008 March 19 +** +** 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. +** +************************************************************************* +** Code for testing all sorts of SQLite interfaces. This code +** implements new SQL functions used by the test scripts. +*/ +#include "sqlite3.h" +#include "tcl.h" +#include +#include +#include + +#include "sqliteInt.h" +#include "vdbeInt.h" + +struct CursorHintGlobal { + Tcl_Interp *interp; + Tcl_Obj *pScript; +} cursorhintglobal; + +static char *exprToString(Mem *aMem, Expr *pExpr){ + char *zRet = 0; + char *zBinOp = 0; + + switch( pExpr->op ){ + case TK_STRING: + zRet = sqlite3_mprintf("%Q", pExpr->u.zToken); + break; + + case TK_INTEGER: + zRet = sqlite3_mprintf("%d", pExpr->u.iValue); + break; + + case TK_NULL: + zRet = sqlite3_mprintf("%s", "NULL"); + break; + + case TK_REGISTER: { + Mem *pMem = &aMem[pExpr->iTable]; + if( pMem->flags & MEM_Int ){ + zRet = sqlite3_mprintf("%lld", pMem->u.i); + } + else if( pMem->flags & MEM_Real ){ + zRet = sqlite3_mprintf("%f", pMem->r); + } + else if( pMem->flags & MEM_Str ){ + zRet = sqlite3_mprintf("%.*Q", pMem->n, pMem->z); + } + else if( pMem->flags & MEM_Blob ){ + } + else{ + zRet = sqlite3_mprintf("%s", "NULL"); + } + break; + } + + case TK_COLUMN: { + zRet = sqlite3_mprintf("col(%d)", (int)pExpr->iColumn); + break; + } + + case TK_LT: zBinOp = "<"; break; + case TK_LE: zBinOp = "<="; break; + case TK_GT: zBinOp = ">"; break; + case TK_GE: zBinOp = ">="; break; + case TK_NE: zBinOp = "!="; break; + case TK_EQ: zBinOp = "=="; break; + case TK_IS: zBinOp = "IS"; break; + case TK_ISNOT: zBinOp = "IS NOT"; break; + case TK_AND: zBinOp = "AND"; break; + case TK_OR: zBinOp = "OR"; break; + case TK_PLUS: zBinOp = "+"; break; + case TK_STAR: zBinOp = "*"; break; + case TK_MINUS: zBinOp = "-"; break; + case TK_REM: zBinOp = "%"; break; + case TK_BITAND: zBinOp = "&"; break; + case TK_BITOR: zBinOp = "|"; break; + case TK_SLASH: zBinOp = "/"; break; + case TK_LSHIFT: zBinOp = "<<"; break; + case TK_RSHIFT: zBinOp = ">>"; break; + case TK_CONCAT: zBinOp = "||"; break; + + default: + zRet = sqlite3_mprintf("%s", "expr"); + break; + } + + if( zBinOp ){ + zRet = sqlite3_mprintf("(%z %s %z)", + exprToString(aMem, pExpr->pLeft), + zBinOp, + exprToString(aMem, pExpr->pRight) + ); + } + + return zRet; +} + +void sqlite3BtreeCursorHintTest(Mem *aMem, Expr *pExpr){ + if( cursorhintglobal.pScript ){ + Tcl_Obj *pEval = Tcl_DuplicateObj(cursorhintglobal.pScript); + char *zExpr; + Tcl_Obj *pObj; + Tcl_IncrRefCount(pEval); + zExpr = exprToString(aMem, pExpr); + pObj = Tcl_NewStringObj(zExpr, -1); + sqlite3_free(zExpr); + Tcl_ListObjAppendElement(cursorhintglobal.interp, pEval, pObj); + Tcl_EvalObjEx(cursorhintglobal.interp, pEval, TCL_GLOBAL_ONLY); + Tcl_DecrRefCount(pEval); + } +} + +/* +** Usage: cursorhint_hook SCRIPT +*/ +static int install_cursorhint_hook( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + if( objc!=1 && objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "?SCRIPT?"); + return TCL_ERROR; + } + if( cursorhintglobal.pScript ){ + Tcl_DecrRefCount(cursorhintglobal.pScript); + memset(&cursorhintglobal, 0, sizeof(cursorhintglobal)); + } + if( objc==2 ){ + cursorhintglobal.interp = interp; + cursorhintglobal.pScript = Tcl_DuplicateObj(objv[1]); + } + return TCL_OK; +} + +/* +** Register commands with the TCL interpreter. +*/ +int Sqlitetest_cursorhint_Init(Tcl_Interp *interp){ + static struct { + char *zName; + Tcl_ObjCmdProc *xProc; + } aObjCmd[] = { + { "cursorhint_hook", install_cursorhint_hook }, + }; + int i; + for(i=0; ip1>=0 && pOp->p1nCursor ); assert( pOp->p4type==P4_EXPR ); pC = p->apCsr[pOp->p1]; - if( pC ) sqlite3BtreeCursorHint(pC->pCursor, pOp->p2, pOp->p4.pExpr); + if( pC ){ + sqlite3BtreeCursorHint(pC->pCursor, pOp->p2, pOp->p4.pExpr); +#ifdef SQLITE_TEST + void sqlite3BtreeCursorHintTest(Mem*, Expr*); + sqlite3BtreeCursorHintTest(p->aMem, pOp->p4.pExpr); +#endif + } break; } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ diff --git a/src/where.c b/src/where.c index a218fd56c6..4e825260ff 100644 --- a/src/where.c +++ b/src/where.c @@ -2764,7 +2764,6 @@ static void codeCursorHint( WhereLevel *pLevel; Expr *pExpr = 0; int iCur; - Bitmask msk; WhereClause *pWC; WhereTerm *pTerm; WhereLoop *pWLoop; diff --git a/test/cursorhint.test b/test/cursorhint.test new file mode 100644 index 0000000000..b4bd7dc14a --- /dev/null +++ b/test/cursorhint.test @@ -0,0 +1,72 @@ +# 2014 July 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cursorhint + +do_execsql_test 1.0 { + CREATE TABLE t1(a,b); + CREATE TABLE t2(x,y); + INSERT INTO t1 VALUES(10, 15); + INSERT INTO t1 VALUES(20, 25); + INSERT INTO t2 VALUES('ten', 'fifteen'); + INSERT INTO t2 VALUES('twenty', 'twentyfive'); + PRAGMA automatic_index = 0; +} + +proc H {expr} { + lappend ::cursorhint $expr +} + +proc do_cursorhint_test {tn sql hints} { + cursorhint_hook H + set ::cursorhint [list] + set testbody [subst { + execsql {$sql} + set ::cursorhint + }] + uplevel [list do_test $tn $testbody [list {*}$hints]] + cursorhint_hook +} + + +do_cursorhint_test 1.1 { + SELECT * FROM t1 CROSS JOIN t2 WHERE a=x; +} { + {(10 == col(0))} + {(20 == col(0))} +} + +do_cursorhint_test 1.2 { + SELECT * FROM t2 CROSS JOIN t1 WHERE a=x; +} { + {(col(0) == 'ten')} + {(col(0) == 'twenty')} +} + +do_cursorhint_test 1.3 { + SELECT * FROM t1 CROSS JOIN t2 WHERE b=15; +} { + {(col(1) == 15)} +} + +do_cursorhint_test 1.3 { + SELECT * FROM t1 CROSS JOIN t2 WHERE y=b+1; +} { + {(col(1) == (15 + 1))} + {(col(1) == (25 + 1))} +} + + +finish_test From 07194bff0ebf4af386650c8630f7f6a5f540113b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Aug 2015 20:34:41 +0000 Subject: [PATCH 05/55] Fix a bug in sqlite3ExprContainsSubquery(). FossilOrigin-Name: be254715b5f56900e57ed57a179ca8d7bb68685d --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b82bc92d48..348a2457f5 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C Merge\sin\sall\sthe\strunk\schanges\sfrom\sthe\sprevious\syear.\s\sThis\sbreaks\sthe\ncursor-hint\smechanism,\sbut\sprovides\sa\sbaseline\sfor\strouble-shooting. -D 2015-08-13T20:07:13.412 +C Fix\sa\sbug\sin\ssqlite3ExprContainsSubquery(). +D 2015-08-13T20:34:41.283 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.msc 5f7861c62c41fe8e3205ef14b90ebed28fa21f1b F Makefile.vxworks e1b65dea203f054e71653415bd8f96dcaed47858 -F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 w README +F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION ccfc4d1576dbfdeece0a4372a2e6a2e37d3e7975 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F addopcodes.awk 9eb448a552d5c0185cf62c463f9c173cedae3811 @@ -26,7 +26,7 @@ F autoconf/missing d7c9981a81af13370d4ed152b24c0a82b7028585 x F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac 93d43c79e936fb16556e22498177d7e8571efa04 w autoconf/tea/configure.in +F autoconf/tea/configure.ac 93d43c79e936fb16556e22498177d7e8571efa04 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in 3ef61715cf1c7bdcff56947ffadb26bc991ca39d @@ -285,9 +285,9 @@ F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 5a0b735dc95604766f5dac73973658eef782ee8b F src/date.c 8ec787fed4929d8ccdf6b1bc360fccc3e1d2ca58 -F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a w src/test_stat.c +F src/dbstat.c f402e77e25089c6003d0c60b3233b9b3947d599a F src/delete.c 8857a6f27560718f65d43bdbec86c967ae1f8dfa -F src/expr.c 0cd7fabb57cb42a9eacd7e8224add005786ae428 +F src/expr.c e1fc69ce92a27bbb8074db56eece7914393b3ef6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c9b63a217d86582c22121699a47f22f524608869 F src/func.c 824bea430d3a2b7dbc62806ad54da8fdb8ed9e3f @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1efa6ed584172291edce78faf9021e577583d03b 851a875ad6b81f90960caf4d03b116afc911858d -R cf16c1d2c53a66a19fa5c8a95e530360 +P 82a7a61bc0883b1e7432548e4890791717aa1bb3 +R c0d78b933f8c8505165f8dab4ed556fa U drh -Z da64436fc89077040f5c1e43409c46ff +Z 08da2f71cfba0ab0d4b8feee8d71be50 diff --git a/manifest.uuid b/manifest.uuid index 279ca65dab..db2f1d9f72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82a7a61bc0883b1e7432548e4890791717aa1bb3 \ No newline at end of file +be254715b5f56900e57ed57a179ca8d7bb68685d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0b9b1fd0ea..41fc5c33a2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1411,7 +1411,7 @@ int sqlite3ExprContainsSubquery(Expr *p){ w.xExprCallback = sqlite3ExprWalkNoop; w.xSelectCallback = selectNodeIsConstant; sqlite3WalkExpr(&w, p); - return w.u.n==0; + return w.eCode==0; } #endif From f7e369070e78887164632b4f142502c1034925b1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Aug 2015 21:32:41 +0000 Subject: [PATCH 06/55] Convert the hint expression of the CursorHint opcode into a string for display by EXPLAIN. FossilOrigin-Name: 206884718782331a7aaacc2c811e4e9d2effae91 --- manifest | 14 +++++----- manifest.uuid | 2 +- src/vdbeInt.h | 11 ++++++++ src/vdbeaux.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 348a2457f5..6e7833ee1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\ssqlite3ExprContainsSubquery(). -D 2015-08-13T20:34:41.283 +C Convert\sthe\shint\sexpression\sof\sthe\sCursorHint\sopcode\sinto\sa\sstring\sfor\ndisplay\sby\sEXPLAIN. +D 2015-08-13T21:32:41.246 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -401,9 +401,9 @@ F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c eeef2e6ee7c377c31a1b3f6c2b2812f3f711c2d7 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 -F src/vdbeInt.h 8b54e01ad0463590e7cffabce0bc36da9ee4f816 +F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 -F src/vdbeaux.c 6194de3a1c44acc4027612240e1d9d664070814f +F src/vdbeaux.c 56077f78bfc96e80f31ad595a05d4d73ac45f5c0 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 82a7a61bc0883b1e7432548e4890791717aa1bb3 -R c0d78b933f8c8505165f8dab4ed556fa +P be254715b5f56900e57ed57a179ca8d7bb68685d +R 35eb49e0fc9f5ab493d2ccd36c0aabff U drh -Z 08da2f71cfba0ab0d4b8feee8d71be50 +Z c266af41e61c50699b530df37cf4ff5a diff --git a/manifest.uuid b/manifest.uuid index db2f1d9f72..ad135c79ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be254715b5f56900e57ed57a179ca8d7bb68685d \ No newline at end of file +206884718782331a7aaacc2c811e4e9d2effae91 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4a90ed6483..b5470c2dda 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -26,6 +26,17 @@ # define SQLITE_MAX_SCHEMA_RETRY 50 #endif +/* +** VDBE_DISPLAY_P4 is true or false depending on whether or not the +** "explain" P4 display logic is enabled. +*/ +#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ + || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) +# define VDBE_DISPLAY_P4 1 +#else +# define VDBE_DISPLAY_P4 0 +#endif + /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 01c6a0fcad..b2bc88db88 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1084,9 +1084,78 @@ static int displayComment( } #endif /* SQLITE_DEBUG */ +#if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) +/* +** Translate the P4.pExpr value for an OP_CursorHint opcode into text +** that can be displayed in the P4 column of EXPLAIN output. +*/ +static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ + const char *zBinOp = 0; + switch( pExpr->op ){ + case TK_STRING: + sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken); + break; -#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) \ - || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG) + case TK_INTEGER: + sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue); + break; + + case TK_NULL: + sqlite3_snprintf(nTemp, zTemp, "NULL"); + break; + + case TK_REGISTER: { + sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable); + break; + } + + case TK_COLUMN: { + sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn); + break; + } + + case TK_LT: zBinOp = "<"; break; + case TK_LE: zBinOp = "<="; break; + case TK_GT: zBinOp = ">"; break; + case TK_GE: zBinOp = ">="; break; + case TK_NE: zBinOp = "!="; break; + case TK_EQ: zBinOp = "=="; break; + case TK_IS: zBinOp = " IS "; break; + case TK_ISNOT: zBinOp = " IS NOT "; break; + case TK_AND: zBinOp = " AND "; break; + case TK_OR: zBinOp = " OR "; break; + case TK_PLUS: zBinOp = "+"; break; + case TK_STAR: zBinOp = "*"; break; + case TK_MINUS: zBinOp = "-"; break; + case TK_REM: zBinOp = "%"; break; + case TK_BITAND: zBinOp = "&"; break; + case TK_BITOR: zBinOp = "|"; break; + case TK_SLASH: zBinOp = "/"; break; + case TK_LSHIFT: zBinOp = "<<"; break; + case TK_RSHIFT: zBinOp = ">>"; break; + case TK_CONCAT: zBinOp = "||"; break; + + default: + sqlite3_snprintf(nTemp, zTemp, "%s", "expr"); + break; + } + + if( zBinOp && nTemp>5 ){ + int n = 1; + zTemp[0] = '('; + n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft); + sqlite3_snprintf(nTemp-n, zTemp+n, "%s", zBinOp); + n += sqlite3Strlen30(zTemp+n); + n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight); + sqlite3_snprintf(nTemp-n, zTemp+n, ")"); + } + + return sqlite3Strlen30(zTemp); +} +#endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ + + +#if VDBE_DISPLAY_P4 /* ** Compute a string that describes the P4 parameter for an opcode. ** Use zTemp for any required temporary buffer space. @@ -1127,7 +1196,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } #ifdef SQLITE_ENABLE_CURSOR_HINTS case P4_EXPR: { - sqlite3_snprintf(nTemp, zTemp, "(expr)"); + displayP4Expr(nTemp, zTemp, pOp->p4.pExpr); break; } #endif @@ -1206,7 +1275,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ assert( zP4!=0 ); return zP4; } -#endif +#endif /* VDBE_DISPLAY_P4 */ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. From ffc648cfa98dcc7d507448851c06980eb0295f86 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 13 Aug 2015 21:38:09 +0000 Subject: [PATCH 07/55] Fix a harmless compiler warning. FossilOrigin-Name: 608ab4ac1911d5f32a17ea043bd5f0748598691d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6e7833ee1e..1f5b47bef5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Convert\sthe\shint\sexpression\sof\sthe\sCursorHint\sopcode\sinto\sa\sstring\sfor\ndisplay\sby\sEXPLAIN. -D 2015-08-13T21:32:41.246 +C Fix\sa\sharmless\scompiler\swarning. +D 2015-08-13T21:38:09.150 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -340,7 +340,7 @@ F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4 -F src/sqliteInt.h b12cb9c5e277061a79d6f81ca3d8bb6ef1d5c6f1 +F src/sqliteInt.h ea5885ac6df1de2444846d0a79c6252e2fa444ab F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P be254715b5f56900e57ed57a179ca8d7bb68685d -R 35eb49e0fc9f5ab493d2ccd36c0aabff +P 206884718782331a7aaacc2c811e4e9d2effae91 +R f5dc80740c0c127675d801f8d87e4c24 U drh -Z c266af41e61c50699b530df37cf4ff5a +Z b21aee07c484f8ec189fb6d6a7ed9bda diff --git a/manifest.uuid b/manifest.uuid index ad135c79ee..b4945b51a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -206884718782331a7aaacc2c811e4e9d2effae91 \ No newline at end of file +608ab4ac1911d5f32a17ea043bd5f0748598691d \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 4f0055c452..f1658d12f2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3405,7 +3405,9 @@ int sqlite3ExprIsConstant(Expr*); int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsTableConstant(Expr*,int); +#ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); +#endif int sqlite3ExprIsInteger(Expr*, int*); int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); From fe66352d176c73212a9ff4dc65f333ed6a314365 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 01:03:21 +0000 Subject: [PATCH 08/55] Fix the CursorHint so that it includes the scan boundary constraints. On the expression text for the CursorHint opcode, show rowid correctly. FossilOrigin-Name: f0d428d13a787251c2ca7685fec2a91b550eefba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 6 +++++- src/wherecode.c | 2 -- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1f5b47bef5..fbb13100cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2015-08-13T21:38:09.150 +C Fix\sthe\sCursorHint\sso\sthat\sit\sincludes\sthe\sscan\sboundary\sconstraints.\nOn\sthe\sexpression\stext\sfor\sthe\sCursorHint\sopcode,\sshow\srowid\scorrectly. +D 2015-08-14T01:03:21.023 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -403,7 +403,7 @@ F src/vdbe.c eeef2e6ee7c377c31a1b3f6c2b2812f3f711c2d7 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 -F src/vdbeaux.c 56077f78bfc96e80f31ad595a05d4d73ac45f5c0 +F src/vdbeaux.c 8bb1ef79af006d02d218171af15b73b9005095d4 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -415,7 +415,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c c745d3aa78ad1aa8982febb99f2f17ee5cbac069 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 00a5d75121f528e03c96a48b2bd46d91ec41c866 +F src/wherecode.c 28d838348209430566640907b4c59eb51dc34493 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 206884718782331a7aaacc2c811e4e9d2effae91 -R f5dc80740c0c127675d801f8d87e4c24 +P 608ab4ac1911d5f32a17ea043bd5f0748598691d +R f6a8eae9d2bc039b93361863b21e0bb5 U drh -Z b21aee07c484f8ec189fb6d6a7ed9bda +Z f7fd48c7e80e896401cf3a4f28b4906c diff --git a/manifest.uuid b/manifest.uuid index b4945b51a0..372777a718 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -608ab4ac1911d5f32a17ea043bd5f0748598691d \ No newline at end of file +f0d428d13a787251c2ca7685fec2a91b550eefba \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index b2bc88db88..bec307e1b7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1110,7 +1110,11 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ } case TK_COLUMN: { - sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn); + if( pExpr->iColumn<0 ){ + sqlite3_snprintf(nTemp, zTemp, "rowid"); + }else{ + sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn); + } break; } diff --git a/src/wherecode.c b/src/wherecode.c index fccd00a62e..b00ff71276 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -652,8 +652,6 @@ static void codeCursorHint( if( pTerm->prereqAll & pLevel->notReady ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; - for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} - if( jnLTerm ) continue; pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ From 0df57012da9866182f78f202aa89156b050fb426 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 15:05:55 +0000 Subject: [PATCH 09/55] Refactor the sqlite3BtreeCursorHint() interface for improved maintainability. FossilOrigin-Name: fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a --- manifest | 18 ++++++++--------- manifest.uuid | 2 +- src/btree.c | 40 ++++++++++++++++++++++---------------- src/btree.h | 51 +++++++++++++++++++++++++++++++++++++++++++------ src/vdbe.c | 16 +++++++++------- src/wherecode.c | 6 ++---- 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index fbb13100cf..4a1861f11c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sCursorHint\sso\sthat\sit\sincludes\sthe\sscan\sboundary\sconstraints.\nOn\sthe\sexpression\stext\sfor\sthe\sCursorHint\sopcode,\sshow\srowid\scorrectly. -D 2015-08-14T01:03:21.023 +C Refactor\sthe\ssqlite3BtreeCursorHint()\sinterface\sfor\simproved\smaintainability. +D 2015-08-14T15:05:55.881 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,8 +277,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 060f2482ef871363617b13c68a1d1c09faf356cc -F src/btree.h 88803367b892853c05052e12a946b66508eb6610 +F src/btree.c 84ae3d2d5b0f74257ecb95badc9c9516e6bf6cb6 +F src/btree.h a1f058c495f5020068b864b67b89b13896174137 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c 4acc35c4e0a2d94c906abd164568cd6fc989cfbb F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -399,7 +399,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c eeef2e6ee7c377c31a1b3f6c2b2812f3f711c2d7 +F src/vdbe.c 74561c2d15895f930f08e4216d454efaaaf530c4 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 @@ -415,7 +415,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c c745d3aa78ad1aa8982febb99f2f17ee5cbac069 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 28d838348209430566640907b4c59eb51dc34493 +F src/wherecode.c 3180ac6422b82e4d71fbaae8727f9dd036efd320 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 608ab4ac1911d5f32a17ea043bd5f0748598691d -R f6a8eae9d2bc039b93361863b21e0bb5 +P f0d428d13a787251c2ca7685fec2a91b550eefba +R 3107bb0cdaaeeac152b5b9d7e7511034 U drh -Z f7fd48c7e80e896401cf3a4f28b4906c +Z 84636ad24c17c3565bc4b3192fff4413 diff --git a/manifest.uuid b/manifest.uuid index 372777a718..d53c4b5ca8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0d428d13a787251c2ca7685fec2a91b550eefba \ No newline at end of file +fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 159ca2b039..0ef1a0555d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -839,16 +839,32 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ #ifdef SQLITE_ENABLE_CURSOR_HINTS /* -** Give a hint to the cursor that it only has to deliver rows for which -** the expression pExpr is true. Within this expression, rows of the -** cursor are identified by Expr.op==TK_COLUMN with Expr.iTable==iTable. +** Provide hints to the cursor. The particular hint given (and the type +** and number of the varargs parameters) is determined by the eHintType +** parameter. See the definitions of the BTREE_HINT_* macros for details. ** -** This interfaces is not used by the standard storage engine of SQLite. -** It is only useful to application that replace SQLite's built-in storage -** engine with their own. +** Hints are not (currently) used by the native SQLite implementation. +** This mechanism is provided for systems that substitute an alternative +** storage engine. */ -void sqlite3BtreeCursorHint(BtCursor *pCur, int iTable, const Expr *pExpr){ - /* Alternative storage engines might use this. */ +void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ + va_list ap; + va_start(ap, eHintType); + switch( eHintType ){ + case BTREE_HINT_FLAGS: { + pCur->hints = va_arg(ap, unsigned int); + assert( pCur->hints==BTREE_SEEK_EQ || pCur->hints==BTREE_BULKLOAD + || pCur->hints==0 ); + break; + } + case BTREE_HINT_RANGE: { + (void)va_arg(ap, Expr*); + (void)va_arg(ap, struct Mem*); + /* Range expression not used in this implementation */ + break; + } + } + va_end(ap); } #endif /* SQLITE_ENABLE_CURSOR_HINTS */ @@ -9564,14 +9580,6 @@ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ return rc; } -/* -** set the mask of hint flags for cursor pCsr. -*/ -void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ - assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 ); - pCsr->hints = mask; -} - #ifdef SQLITE_DEBUG /* ** Return true if the cursor has a hint specified. This routine is diff --git a/src/btree.h b/src/btree.h index 05246b765d..de6f3b9467 100644 --- a/src/btree.h +++ b/src/btree.h @@ -150,8 +150,47 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_DATA_VERSION 15 /* A virtual meta-value */ /* -** Values that may be OR'd together to form the second argument of an -** sqlite3BtreeCursorHints() call. +** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() +** interface. +** +** Note that cursor hints are not used by the canonical SQLite b-tree +** ayer. Cursor hints are provided so that systems that substitute their +** on custom b-tree layer can have access to additional information that might +** boost performance. Hints are only provided if SQLite is compiled with +** SQLITE_ENABLE_CURSOR_HINTS. The hinting interface is undocumented +** (except for comments such as this) and is subject to change from one +** release of SQLite to the next. +** +** BTREE_HINT_FLAGS (arguments: unsigned int) +** +** Some combinatation of BTREE_BULKLOAD and BTREE_SEEK_EQ flags. The +** argument is a single unsigned integer which overwrites all prior +** flag settings. +** +** BTREE_HINT_RANGE (arguments: Expr*, Mem*) +** +** The first argument is an Expr* (which is guaranteed to be constant for +** the lifetime of the cursor) that defines constraints on which rows +** might be fetched with this cursor. The Expr* tree may contain +** TK_REGISTER nodes that refer to values stored in the array of registers +** passed as the second parameter. In other words, if Expr.op==TK_REGISTER +** then the value of the node is the value in Mem[pExpr.iTable]. Any +** TK_COLUMN node in the expression tree refers to the Expr.iColumn-th +** column of the b-tree of the cursor. The Expr tree will not contain +** any function calls nor subqueries nor references to b-trees other than +** the cursor being hinted. +** +** The design of the _RANGE hint is aid b-tree implementations that try +** to prefetch content from remote machines - to provide those +** implementations with limits on what needs to be prefetched and thereby +** reduce network bandwidth. +*/ +#define BTREE_HINT_FLAGS 1 /* Set flags indicating cursor usage */ +#define BTREE_HINT_RANGE 2 /* Range constraints on queries */ + +/* +** Values that may be OR'd together to form the argument to the +** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): ** ** The BTREE_BULKLOAD flag is set on index cursors when the index is going ** to be filled with content that is already in sorted order. @@ -165,6 +204,10 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ +#ifdef SQLITE_ENABLE_CURSOR_HINTS +void sqlite3BtreeCursorHint(BtCursor*, int, ...); +#endif + int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ @@ -185,9 +228,6 @@ int sqlite3BtreeMovetoUnpacked( ); int sqlite3BtreeCursorHasMoved(BtCursor*); int sqlite3BtreeCursorRestore(BtCursor*, int*); -#ifdef SQLITE_ENABLE_CURSOR_HINTS -void sqlite3BtreeCursorHint(BtCursor*, int, const Expr*); -#endif int sqlite3BtreeDelete(BtCursor*); int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, @@ -211,7 +251,6 @@ int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeIncrblobCursor(BtCursor *); void sqlite3BtreeClearCursor(BtCursor *); int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); -void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); #ifdef SQLITE_DEBUG int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); #endif diff --git a/src/vdbe.c b/src/vdbe.c index fc53511057..f1a5545444 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3384,8 +3384,10 @@ case OP_OpenWrite: open_cursor_set_hints: assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); - sqlite3BtreeCursorHints(pCur->pCursor, - (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); +#ifdef SQLITE_ENABLE_CURSOR_HINTS + sqlite3BtreeCursorHint(pCur->pCursor, BTREE_HINT_FLAGS, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); +#endif break; } @@ -6553,12 +6555,12 @@ case OP_Init: { /* jump */ } #ifdef SQLITE_ENABLE_CURSOR_HINTS -/* Opcode: CursorHint P1 P2 * P4 * +/* Opcode: CursorHint P1 * * P4 * ** ** Provide a hint to cursor P1 that it only needs to return rows that -** satisfy the Expr tree given in P4. P2 is the table number of cursor P1 -** such that references to cursor P1 in the Expr tree are given by -** Expr.iTable==P2. +** satisfy the Expr in P4. TK_REGISTER terms in the P4 expression refer +** to values currently held in registers. TK_COLUMN terms in the P4 +** expression refer to columns in the b-tree to which cursor P1 is pointing. */ case OP_CursorHint: { VdbeCursor *pC; @@ -6567,7 +6569,7 @@ case OP_CursorHint: { assert( pOp->p4type==P4_EXPR ); pC = p->apCsr[pOp->p1]; if( pC ){ - sqlite3BtreeCursorHint(pC->pCursor, pOp->p2, pOp->p4.pExpr); + sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); #ifdef SQLITE_TEST void sqlite3BtreeCursorHintTest(Mem*, Expr*); sqlite3BtreeCursorHintTest(p->aMem, pOp->p4.pExpr); diff --git a/src/wherecode.c b/src/wherecode.c index b00ff71276..7b9db0cb2f 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -592,7 +592,7 @@ static void whereLikeOptimizationStringFixup( /* ** This function is called on every node of an expression tree used as an ** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN -** that accesses any cursor other than (pWalker->u.i), do the following: +** that accesses any cursor other than (pWalker->u.n), do the following: ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and @@ -638,12 +638,10 @@ static void codeCursorHint( int iCur; WhereClause *pWC; WhereTerm *pTerm; - WhereLoop *pWLoop; - int i, j; + int i; if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; pLevel = &pWInfo->a[iLevel]; - pWLoop = pLevel->pWLoop; iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; pWC = &pWInfo->sWC; for(i=0; inTerm; i++){ From 2f2b02785ad756015d111813971e3433c5d0399f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 18:50:04 +0000 Subject: [PATCH 10/55] Fix the cursor hint mechanism so that it does the right thing for indexed lookups. FossilOrigin-Name: 581e3d4988e98975fea5daaeb9f854c54a4976b7 --- manifest | 18 ++++----- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/vdbeaux.c | 4 +- src/where.c | 3 ++ src/wherecode.c | 97 ++++++++++++++++++++++++++++++++++++++----------- 6 files changed, 91 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 4a1861f11c..a0e60280dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\ssqlite3BtreeCursorHint()\sinterface\sfor\simproved\smaintainability. -D 2015-08-14T15:05:55.881 +C Fix\sthe\scursor\shint\smechanism\sso\sthat\sit\sdoes\sthe\sright\sthing\sfor\sindexed\nlookups. +D 2015-08-14T18:50:04.420 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -340,7 +340,7 @@ F src/shell.c b1f91e60918df3a68efad1e3a11696b9a7e23d23 F src/sqlite.h.in 447ead0a6b3293206f04a0896553955d07cfb4b9 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h a0b948ebc89bac13941254641326a6aa248c2cc4 -F src/sqliteInt.h ea5885ac6df1de2444846d0a79c6252e2fa444ab +F src/sqliteInt.h cbd6d166c5f8aa17e4be463ccefef41cd1d40286 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -403,7 +403,7 @@ F src/vdbe.c 74561c2d15895f930f08e4216d454efaaaf530c4 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 -F src/vdbeaux.c 8bb1ef79af006d02d218171af15b73b9005095d4 +F src/vdbeaux.c 9f726265d3c4a64264c9aa80d35aa19c51a3c6f4 F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -413,9 +413,9 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 6fb6b68969e4692593c2552c4e7bff5882de2cb8 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 -F src/where.c c745d3aa78ad1aa8982febb99f2f17ee5cbac069 +F src/where.c ef95e56b6e7cdfa3ae0b6f72e3578391addfa965 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 3180ac6422b82e4d71fbaae8727f9dd036efd320 +F src/wherecode.c 16045545fb44878a7ba61db645521f30f9265893 F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1375,7 +1375,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f0d428d13a787251c2ca7685fec2a91b550eefba -R 3107bb0cdaaeeac152b5b9d7e7511034 +P fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a +R 020be40332ddb39fbaad6fc302316e47 U drh -Z 84636ad24c17c3565bc4b3192fff4413 +Z 56068f8a083e66d3150e6ce38cb011fe diff --git a/manifest.uuid b/manifest.uuid index d53c4b5ca8..3a1ba3442d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a \ No newline at end of file +581e3d4988e98975fea5daaeb9f854c54a4976b7 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f1658d12f2..41c193114d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2994,6 +2994,7 @@ struct Walker { int iCur; /* A cursor number */ SrcList *pSrcList; /* FROM clause */ struct SrcCount *pSrcCount; /* Counting column references */ + struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ } u; }; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index bec307e1b7..df6ac61f82 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1593,12 +1593,12 @@ int sqlite3VdbeList( pMem->u.i = pOp->p3; /* P3 */ pMem++; - if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */ + if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ assert( p->db->mallocFailed ); return SQLITE_ERROR; } pMem->flags = MEM_Str|MEM_Term; - zP4 = displayP4(pOp, pMem->z, 32); + zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); if( zP4!=pMem->z ){ sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); }else{ diff --git a/src/where.c b/src/where.c index 3c0f767db6..359f1506d9 100644 --- a/src/where.c +++ b/src/where.c @@ -4217,6 +4217,9 @@ WhereInfo *sqlite3WhereBegin( SQLITE_INT_TO_PTR(n), P4_INT32); assert( n<=pTab->nCol ); } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + if( pLoop->u.btree.pIndex!=0 ) sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); +#endif #ifdef SQLITE_ENABLE_COLUMN_USED_MASK sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, (const u8*)&pTabItem->colUsed, P4_INT64); diff --git a/src/wherecode.c b/src/wherecode.c index 7b9db0cb2f..5052e2d378 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -588,28 +588,70 @@ static void whereLikeOptimizationStringFixup( } #ifdef SQLITE_ENABLE_CURSOR_HINTS +/* +** Information is passed from codeCursorHint() down to individual nodes of +** the expression tree (by sqlite3WalkExpr()) using an instance of this +** structure. +*/ +struct CCurHint { + int iTabCur; /* Cursor for the main table */ + int iIdxCur; /* Cursor for the index, if pIdx!=0. Unused otherwise */ + Index *pIdx; /* The index used to access the table */ +}; + +/* +** This function is called for every node of an expression that is a candidate +** for a cursor hint on an index cursor. For TK_COLUMN nodes that reference +** the table CCurHint.iTabCur, verify that the same column can be +** accessed through the index. If it cannot, then set pWalker->eCode to 1. +*/ +static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ + struct CCurHint *pHint = pWalker->u.pCCurHint; + assert( pHint->pIdx!=0 ); + if( pExpr->op==TK_COLUMN + && pExpr->iTable==pHint->iTabCur + && sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn)<0 + ){ + pWalker->eCode = 1; + } + return WRC_Continue; +} + /* ** This function is called on every node of an expression tree used as an ** argument to the OP_CursorHint instruction. If the node is a TK_COLUMN -** that accesses any cursor other than (pWalker->u.n), do the following: +** that accesses any table other than the one identified by +** CCurHint.iTabCur, then do the following: ** ** 1) allocate a register and code an OP_Column instruction to read ** the specified column into the new register, and ** ** 2) transform the expression node to a TK_REGISTER node that reads ** from the newly populated register. +** +** Also, if the node is a TK_COLUMN that does access the table idenified +** by pCCurHint.iTabCur, and an index is being used (which we will +** know because CCurHint.pIdx!=0) then transform the TK_COLUMN into +** an access of the index rather than the original table. */ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ int rc = WRC_Continue; - if( pExpr->op==TK_COLUMN && pExpr->iTable!=pWalker->u.n ){ - Vdbe *v = pWalker->pParse->pVdbe; - int reg = ++pWalker->pParse->nMem; /* Register for column value */ - sqlite3ExprCodeGetColumnOfTable( - v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg - ); - pExpr->op = TK_REGISTER; - pExpr->iTable = reg; + struct CCurHint *pHint = pWalker->u.pCCurHint; + if( pExpr->op==TK_COLUMN ){ + if( pExpr->iTable!=pHint->iTabCur ){ + Vdbe *v = pWalker->pParse->pVdbe; + int reg = ++pWalker->pParse->nMem; /* Register for column value */ + sqlite3ExprCodeGetColumnOfTable( + v, pExpr->pTab, pExpr->iTable, pExpr->iColumn, reg + ); + pExpr->op = TK_REGISTER; + pExpr->iTable = reg; + }else if( pHint->pIdx!=0 ){ + pExpr->iTable = pHint->iIdxCur; + pExpr->iColumn = sqlite3ColumnOfIndex(pHint->pIdx, pExpr->iColumn); + assert( pExpr->iColumn>=0 ); + } }else if( pExpr->op==TK_AGG_FUNCTION ){ /* An aggregate function in the WHERE clause of a query means this must ** be a correlated sub-query, and expression pExpr is an aggregate from @@ -628,21 +670,29 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ */ static void codeCursorHint( WhereInfo *pWInfo, - int iLevel + WhereLevel *pLevel ){ Parse *pParse = pWInfo->pParse; sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; - WhereLevel *pLevel; Expr *pExpr = 0; + WhereLoop *pLoop = pLevel->pWLoop; int iCur; WhereClause *pWC; WhereTerm *pTerm; int i; + struct CCurHint sHint; + Walker sWalker; if( OptimizationDisabled(db, SQLITE_CursorHints) ) return; - pLevel = &pWInfo->a[iLevel]; - iCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor; + iCur = pLevel->iTabCur; + assert( iCur==pWInfo->pTabList->a[pLevel->iFrom].iCursor ); + sHint.iTabCur = iCur; + sHint.iIdxCur = pLevel->iIdxCur; + sHint.pIdx = pLoop->u.btree.pIndex; + memset(&sWalker, 0, sizeof(sWalker)); + sWalker.pParse = pParse; + sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; for(i=0; inTerm; i++){ pTerm = &pWC->a[i]; @@ -650,17 +700,20 @@ static void codeCursorHint( if( pTerm->prereqAll & pLevel->notReady ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + if( sHint.pIdx!=0 ){ + sWalker.eCode = 0; + sWalker.xExprCallback = codeCursorHintCheckExpr; + sqlite3WalkExpr(&sWalker, pTerm->pExpr); + if( sWalker.eCode ) continue; + } pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ - const char *a = (const char*)pExpr; - Walker sWalker; - memset(&sWalker, 0, sizeof(sWalker)); sWalker.xExprCallback = codeCursorHintFixExpr; - sWalker.pParse = pParse; - sWalker.u.n = pLevel->iTabCur; sqlite3WalkExpr(&sWalker, pExpr); - sqlite3VdbeAddOp4(v, OP_CursorHint, pLevel->iTabCur, iCur, 0, a, P4_EXPR); + sqlite3VdbeAddOp4(v, OP_CursorHint, + (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, + (const char*)pExpr, P4_EXPR); } } #else @@ -830,7 +883,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pStart = pEnd; pEnd = pTerm; } - codeCursorHint(pWInfo, iLevel); + codeCursorHint(pWInfo, pLevel); if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ @@ -1053,7 +1106,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ - codeCursorHint(pWInfo, iLevel); + codeCursorHint(pWInfo, pLevel); nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; @@ -1481,7 +1534,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ - codeCursorHint(pWInfo, iLevel); + codeCursorHint(pWInfo, pLevel); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); From 1eb6eeb829c126d0be49a3049be24a9b589b7d83 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 20:08:13 +0000 Subject: [PATCH 11/55] Updated testing of cursor-hints. Remove the test_cursorhint.c file and associated logic in the core and do tests based purely on the newly enhanced EXPLAIN output. FossilOrigin-Name: bf383e665a191a4f33a540d1240960a922e22813 --- main.mk | 1 - manifest | 19 +++-- manifest.uuid | 2 +- src/tclsqlite.c | 3 - src/test_cursorhint.c | 162 ------------------------------------------ src/vdbe.c | 4 -- test/cursorhint.test | 133 +++++++++++++++++++++++----------- 7 files changed, 102 insertions(+), 222 deletions(-) delete mode 100644 src/test_cursorhint.c diff --git a/main.mk b/main.mk index 44f4bbf094..f3bdae6a83 100644 --- a/main.mk +++ b/main.mk @@ -262,7 +262,6 @@ TESTSRC = \ $(TOP)/src/test_blob.c \ $(TOP)/src/test_btree.c \ $(TOP)/src/test_config.c \ - $(TOP)/src/test_cursorhint.c \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_fs.c \ diff --git a/manifest b/manifest index a0e60280dd..794278256f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\scursor\shint\smechanism\sso\sthat\sit\sdoes\sthe\sright\sthing\sfor\sindexed\nlookups. -D 2015-08-14T18:50:04.420 +C Updated\stesting\sof\scursor-hints.\s\sRemove\sthe\stest_cursorhint.c\sfile\sand\nassociated\slogic\sin\sthe\score\sand\sdo\stests\sbased\spurely\son\sthe\snewly\senhanced\nEXPLAIN\soutput. +D 2015-08-14T20:08:13.528 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -256,7 +256,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 389329247c56b23329a9285155106cd6b6ebad42 +F main.mk 73167b34b0e67c0be32c1da2d988a376851c9ab1 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea F mkopcodeh.awk 0e7f04a8eb90f92259e47d80110e4e98d7ce337a F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 @@ -344,7 +344,7 @@ F src/sqliteInt.h cbd6d166c5f8aa17e4be463ccefef41cd1d40286 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c f266ad8a2892d659b74f0f50cb6a88b6e7c12179 F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e -F src/tclsqlite.c 72f4dd747d5604a508bbb6935817d3afe5ffd6e2 +F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 F src/test1.c d339ae9b9baf9221c657c9628c9061d88bd831f6 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622 @@ -360,7 +360,6 @@ F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f F src/test_config.c fb2e5d354d9a077f5fbb261652eff4787deb104f -F src/test_cursorhint.c bba837177d1693037f5c83dcb443cf453ee656ed F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -399,7 +398,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 74561c2d15895f930f08e4216d454efaaaf530c4 +F src/vdbe.c 882cac44eb4f53d18e31c79fc1741d400016f867 F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 @@ -561,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test e55ad8c466327ffb3511b60007102bca22314d0a +F test/cursorhint.test c3844bed3eec3506b38b98ab5f0ca22a4ab9ecb4 F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1375,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P fc3fb5cd0d2c123a069e5b18b62bb1f708c8698a -R 020be40332ddb39fbaad6fc302316e47 +P 581e3d4988e98975fea5daaeb9f854c54a4976b7 +R 32fb6312a84d28df618932a2d55ba493 U drh -Z 56068f8a083e66d3150e6ce38cb011fe +Z 247ce995f99250cbca60587acaa0c7c9 diff --git a/manifest.uuid b/manifest.uuid index 3a1ba3442d..00b59df147 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -581e3d4988e98975fea5daaeb9f854c54a4976b7 \ No newline at end of file +bf383e665a191a4f33a540d1240960a922e22813 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index f8073fe3ef..f024317e90 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3739,7 +3739,6 @@ static void init_all(Tcl_Interp *interp){ extern int Sqlitetestasync_Init(Tcl_Interp*); extern int Sqlitetest_autoext_Init(Tcl_Interp*); extern int Sqlitetest_blob_Init(Tcl_Interp*); - extern int Sqlitetest_cursorhint_Init(Tcl_Interp*); extern int Sqlitetest_demovfs_Init(Tcl_Interp *); extern int Sqlitetest_func_Init(Tcl_Interp*); extern int Sqlitetest_hexio_Init(Tcl_Interp*); @@ -3785,8 +3784,6 @@ static void init_all(Tcl_Interp *interp){ Sqlitetestasync_Init(interp); Sqlitetest_autoext_Init(interp); Sqlitetest_blob_Init(interp); - Sqlitetest_cursorhint_Init(interp); - Sqlitetest_demovfs_Init(interp); Sqlitetest_demovfs_Init(interp); Sqlitetest_func_Init(interp); Sqlitetest_hexio_Init(interp); diff --git a/src/test_cursorhint.c b/src/test_cursorhint.c deleted file mode 100644 index 0f94232696..0000000000 --- a/src/test_cursorhint.c +++ /dev/null @@ -1,162 +0,0 @@ -/* -** 2008 March 19 -** -** 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. -** -************************************************************************* -** Code for testing all sorts of SQLite interfaces. This code -** implements new SQL functions used by the test scripts. -*/ -#include "sqlite3.h" -#include "tcl.h" -#include -#include -#include - -#include "sqliteInt.h" -#include "vdbeInt.h" - -struct CursorHintGlobal { - Tcl_Interp *interp; - Tcl_Obj *pScript; -} cursorhintglobal; - -static char *exprToString(Mem *aMem, Expr *pExpr){ - char *zRet = 0; - char *zBinOp = 0; - - switch( pExpr->op ){ - case TK_STRING: - zRet = sqlite3_mprintf("%Q", pExpr->u.zToken); - break; - - case TK_INTEGER: - zRet = sqlite3_mprintf("%d", pExpr->u.iValue); - break; - - case TK_NULL: - zRet = sqlite3_mprintf("%s", "NULL"); - break; - - case TK_REGISTER: { - Mem *pMem = &aMem[pExpr->iTable]; - if( pMem->flags & MEM_Int ){ - zRet = sqlite3_mprintf("%lld", pMem->u.i); - } - else if( pMem->flags & MEM_Real ){ - zRet = sqlite3_mprintf("%f", pMem->u.r); - } - else if( pMem->flags & MEM_Str ){ - zRet = sqlite3_mprintf("%.*Q", pMem->n, pMem->z); - } - else if( pMem->flags & MEM_Blob ){ - } - else{ - zRet = sqlite3_mprintf("%s", "NULL"); - } - break; - } - - case TK_COLUMN: { - zRet = sqlite3_mprintf("col(%d)", (int)pExpr->iColumn); - break; - } - - case TK_LT: zBinOp = "<"; break; - case TK_LE: zBinOp = "<="; break; - case TK_GT: zBinOp = ">"; break; - case TK_GE: zBinOp = ">="; break; - case TK_NE: zBinOp = "!="; break; - case TK_EQ: zBinOp = "=="; break; - case TK_IS: zBinOp = "IS"; break; - case TK_ISNOT: zBinOp = "IS NOT"; break; - case TK_AND: zBinOp = "AND"; break; - case TK_OR: zBinOp = "OR"; break; - case TK_PLUS: zBinOp = "+"; break; - case TK_STAR: zBinOp = "*"; break; - case TK_MINUS: zBinOp = "-"; break; - case TK_REM: zBinOp = "%"; break; - case TK_BITAND: zBinOp = "&"; break; - case TK_BITOR: zBinOp = "|"; break; - case TK_SLASH: zBinOp = "/"; break; - case TK_LSHIFT: zBinOp = "<<"; break; - case TK_RSHIFT: zBinOp = ">>"; break; - case TK_CONCAT: zBinOp = "||"; break; - - default: - zRet = sqlite3_mprintf("%s", "expr"); - break; - } - - if( zBinOp ){ - zRet = sqlite3_mprintf("(%z %s %z)", - exprToString(aMem, pExpr->pLeft), - zBinOp, - exprToString(aMem, pExpr->pRight) - ); - } - - return zRet; -} - -void sqlite3BtreeCursorHintTest(Mem *aMem, Expr *pExpr){ - if( cursorhintglobal.pScript ){ - Tcl_Obj *pEval = Tcl_DuplicateObj(cursorhintglobal.pScript); - char *zExpr; - Tcl_Obj *pObj; - Tcl_IncrRefCount(pEval); - zExpr = exprToString(aMem, pExpr); - pObj = Tcl_NewStringObj(zExpr, -1); - sqlite3_free(zExpr); - Tcl_ListObjAppendElement(cursorhintglobal.interp, pEval, pObj); - Tcl_EvalObjEx(cursorhintglobal.interp, pEval, TCL_GLOBAL_ONLY); - Tcl_DecrRefCount(pEval); - } -} - -/* -** Usage: cursorhint_hook SCRIPT -*/ -static int install_cursorhint_hook( - ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ - Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ - int objc, /* Number of arguments */ - Tcl_Obj *CONST objv[] /* Command arguments */ -){ - if( objc!=1 && objc!=2 ){ - Tcl_WrongNumArgs(interp, 1, objv, "?SCRIPT?"); - return TCL_ERROR; - } - if( cursorhintglobal.pScript ){ - Tcl_DecrRefCount(cursorhintglobal.pScript); - memset(&cursorhintglobal, 0, sizeof(cursorhintglobal)); - } - if( objc==2 ){ - cursorhintglobal.interp = interp; - cursorhintglobal.pScript = Tcl_DuplicateObj(objv[1]); - } - return TCL_OK; -} - -/* -** Register commands with the TCL interpreter. -*/ -int Sqlitetest_cursorhint_Init(Tcl_Interp *interp){ - static struct { - char *zName; - Tcl_ObjCmdProc *xProc; - } aObjCmd[] = { - { "cursorhint_hook", install_cursorhint_hook }, - }; - int i; - for(i=0; iapCsr[pOp->p1]; if( pC ){ sqlite3BtreeCursorHint(pC->pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); -#ifdef SQLITE_TEST - void sqlite3BtreeCursorHintTest(Mem*, Expr*); - sqlite3BtreeCursorHintTest(p->aMem, pOp->p4.pExpr); -#endif } break; } diff --git a/test/cursorhint.test b/test/cursorhint.test index b4bd7dc14a..b9677b640d 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -16,57 +16,108 @@ source $testdir/tester.tcl set testprefix cursorhint do_execsql_test 1.0 { - CREATE TABLE t1(a,b); - CREATE TABLE t2(x,y); - INSERT INTO t1 VALUES(10, 15); - INSERT INTO t1 VALUES(20, 25); - INSERT INTO t2 VALUES('ten', 'fifteen'); - INSERT INTO t2 VALUES('twenty', 'twentyfive'); + CREATE TABLE t1(a,b,c,d); + CREATE TABLE t2(x,y,z); + INSERT INTO t1(a,b) VALUES(10, 15); + INSERT INTO t1(a,b) VALUES(20, 25); + INSERT INTO t2(x,y) VALUES('ten', 'fifteen'); + INSERT INTO t2(x,y) VALUES('twenty', 'twentyfive'); + CREATE TABLE t3(id TEXT PRIMARY KEY, a, b, c, d) WITHOUT ROWID; + INSERT INTO t3(id,a,b,c,d) SELECT rowid, a, b, c, d FROM t1; PRAGMA automatic_index = 0; } -proc H {expr} { - lappend ::cursorhint $expr +# Run EXPLAIN on $sql. Return a list of P4 values for all $opcode +# opcodes. +# +proc p4_of_opcode {db opcode sql} { + set res {} + $db eval "EXPLAIN $sql" x { + if {$x(opcode)==$opcode} {lappend res $x(p4)} + } + return $res } -proc do_cursorhint_test {tn sql hints} { - cursorhint_hook H - set ::cursorhint [list] - set testbody [subst { - execsql {$sql} - set ::cursorhint - }] - uplevel [list do_test $tn $testbody [list {*}$hints]] - cursorhint_hook +# Run EXPLAIN on $sql. Return a list of P5 values for all $opcode +# opcodes that contain regexp $comment in their comment +# +proc p5_of_opcode {db opcode comment sql} { + set res {} + $db eval "EXPLAIN $sql" x { + if {$x(opcode)==$opcode && [regexp $comment $x(comment)]} { + lappend res $x(p5) + } + } + return $res } +# Verify that when t1 is in the outer loop and t2 is in the inner loop, +# no cursor hints occur for t1 (since it is a full table scan) but that +# each t2 access has a cursor hint based on the current t1.a value. +# +do_test 1.1 { + p4_of_opcode db CursorHint { + SELECT * FROM t1 CROSS JOIN t2 WHERE a=x + } +} {/(r*==c0)/} +do_test 1.2 { + p5_of_opcode db OpenRead . { + SELECT * FROM t1 CROSS JOIN t2 WHERE a=x + } +} {00 00} -do_cursorhint_test 1.1 { - SELECT * FROM t1 CROSS JOIN t2 WHERE a=x; -} { - {(10 == col(0))} - {(20 == col(0))} -} +# Do the same test the other way around. +# +do_test 2.1 { + p4_of_opcode db CursorHint { + SELECT * FROM t2 CROSS JOIN t1 WHERE a=x + } +} {/(c0==r*)/} +do_test 2.2 { + p5_of_opcode db OpenRead . { + SELECT * FROM t2 CROSS JOIN t1 WHERE a=x + } +} {00 00} -do_cursorhint_test 1.2 { - SELECT * FROM t2 CROSS JOIN t1 WHERE a=x; -} { - {(col(0) == 'ten')} - {(col(0) == 'twenty')} -} +# Various expressions captured by CursorHint +# +do_test 3.1 { + p4_of_opcode db CursorHint { + SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98 + } +} {/(c0==15).*(c2==22).*(rowid!=98)/} +do_test 3.2 { + p4_of_opcode db CursorHint { + SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98 + } +} {/(c1<15).*(c2>22).*(c0!=98)/} -do_cursorhint_test 1.3 { - SELECT * FROM t1 CROSS JOIN t2 WHERE b=15; -} { - {(col(1) == 15)} -} - -do_cursorhint_test 1.3 { - SELECT * FROM t1 CROSS JOIN t2 WHERE y=b+1; -} { - {(col(1) == (15 + 1))} - {(col(1) == (25 + 1))} -} +# Indexed queries +# +do_test 4.1 { + db eval { + CREATE INDEX t1bc ON t1(b,c); + CREATE INDEX t2yz ON t2(y,z); + } + p4_of_opcode db CursorHint { + SELECT * FROM t1 WHERE b>11; + } +} {/(c0>11)/} +do_test 4.2 { + p5_of_opcode db OpenRead . { + SELECT * FROM t1 WHERE b>11; + } +} {02 00} +do_test 4.3 { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b>11; + } +} {/(c0>11)/} +do_test 4.4 { + p5_of_opcode db OpenRead . { + SELECT c FROM t1 WHERE b>11; + } +} {00} finish_test From 0403cb3012059c27bb6b793e9fc57b16116dc439 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 14 Aug 2015 23:57:04 +0000 Subject: [PATCH 12/55] Always provide the BTREE_BULKLOAD hint, even when SQLITE_ENABLE_CURSOR_HINTS is not defined, as that hint gives a 4% performance increase. FossilOrigin-Name: 83a844357e132683ab3d88eee0fe32a8beeb6662 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 28 +++++++++------------------- src/btree.h | 18 ++++++------------ src/vdbe.c | 6 ++++-- 5 files changed, 28 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index 794278256f..931701bf6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updated\stesting\sof\scursor-hints.\s\sRemove\sthe\stest_cursorhint.c\sfile\sand\nassociated\slogic\sin\sthe\score\sand\sdo\stests\sbased\spurely\son\sthe\snewly\senhanced\nEXPLAIN\soutput. -D 2015-08-14T20:08:13.528 +C Always\sprovide\sthe\sBTREE_BULKLOAD\shint,\seven\swhen\sSQLITE_ENABLE_CURSOR_HINTS\nis\snot\sdefined,\sas\sthat\shint\sgives\sa\s4%\sperformance\sincrease. +D 2015-08-14T23:57:04.215 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -277,8 +277,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 4d9134dc988a87838c06056c89c0e8c4700a0452 F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 84ae3d2d5b0f74257ecb95badc9c9516e6bf6cb6 -F src/btree.h a1f058c495f5020068b864b67b89b13896174137 +F src/btree.c b8083a37c09df6a30af497086d7ba05c1526d359 +F src/btree.h 6310645beddbd3eef89fa9b6d1062065976a93c8 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c 4acc35c4e0a2d94c906abd164568cd6fc989cfbb F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -398,7 +398,7 @@ F src/update.c 487747b328b7216bb7f6af0695d6937d5c9e605f F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c bc9dd64b5db544218b871b66243871c202b2781f F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 882cac44eb4f53d18e31c79fc1741d400016f867 +F src/vdbe.c 4dbcceb38f5c3e42c0725a56e7c76eb12adedebb F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 581e3d4988e98975fea5daaeb9f854c54a4976b7 -R 32fb6312a84d28df618932a2d55ba493 +P bf383e665a191a4f33a540d1240960a922e22813 +R 87aadf49a7545642a0a9fb9a1d94cce7 U drh -Z 247ce995f99250cbca60587acaa0c7c9 +Z 44853a09e3a1d8da8995535278d599e8 diff --git a/manifest.uuid b/manifest.uuid index 00b59df147..9c7ac55d4b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf383e665a191a4f33a540d1240960a922e22813 \ No newline at end of file +83a844357e132683ab3d88eee0fe32a8beeb6662 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 0ef1a0555d..18a22de93c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -837,36 +837,26 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ return SQLITE_OK; } -#ifdef SQLITE_ENABLE_CURSOR_HINTS /* ** Provide hints to the cursor. The particular hint given (and the type ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. -** -** Hints are not (currently) used by the native SQLite implementation. -** This mechanism is provided for systems that substitute an alternative -** storage engine. */ void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ va_list ap; va_start(ap, eHintType); - switch( eHintType ){ - case BTREE_HINT_FLAGS: { - pCur->hints = va_arg(ap, unsigned int); - assert( pCur->hints==BTREE_SEEK_EQ || pCur->hints==BTREE_BULKLOAD - || pCur->hints==0 ); - break; - } - case BTREE_HINT_RANGE: { - (void)va_arg(ap, Expr*); - (void)va_arg(ap, struct Mem*); - /* Range expression not used in this implementation */ - break; - } +#ifdef SQLITE_ENABLE_CURSOR_HINTS + if( eHintType==BTREE_HINT_FLAGS ) +#else + assert( eHintType==BTREE_HINT_FLAGS ); +#endif + { + pCur->hints = va_arg(ap, unsigned int); + assert( pCur->hints==BTREE_SEEK_EQ || pCur->hints==BTREE_BULKLOAD + || pCur->hints==0 ); } va_end(ap); } -#endif /* SQLITE_ENABLE_CURSOR_HINTS */ #ifndef SQLITE_OMIT_AUTOVACUUM /* diff --git a/src/btree.h b/src/btree.h index de6f3b9467..e0c9ab0ab1 100644 --- a/src/btree.h +++ b/src/btree.h @@ -153,14 +153,6 @@ int sqlite3BtreeNewDb(Btree *p); ** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() ** interface. ** -** Note that cursor hints are not used by the canonical SQLite b-tree -** ayer. Cursor hints are provided so that systems that substitute their -** on custom b-tree layer can have access to additional information that might -** boost performance. Hints are only provided if SQLite is compiled with -** SQLITE_ENABLE_CURSOR_HINTS. The hinting interface is undocumented -** (except for comments such as this) and is subject to change from one -** release of SQLite to the next. -** ** BTREE_HINT_FLAGS (arguments: unsigned int) ** ** Some combinatation of BTREE_BULKLOAD and BTREE_SEEK_EQ flags. The @@ -184,6 +176,11 @@ int sqlite3BtreeNewDb(Btree *p); ** to prefetch content from remote machines - to provide those ** implementations with limits on what needs to be prefetched and thereby ** reduce network bandwidth. +** +** Note that BTREE_HINT_FLAGS with BTREE_BULKLOAD is the only hint used by +** standard SQLite. The other hints are provided for extentions that use +** the SQLite parser and code generator but substitute their own storage +** engine. */ #define BTREE_HINT_FLAGS 1 /* Set flags indicating cursor usage */ #define BTREE_HINT_RANGE 2 /* Range constraints on queries */ @@ -204,10 +201,6 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ -#ifdef SQLITE_ENABLE_CURSOR_HINTS -void sqlite3BtreeCursorHint(BtCursor*, int, ...); -#endif - int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ @@ -217,6 +210,7 @@ int sqlite3BtreeCursor( ); int sqlite3BtreeCursorSize(void); void sqlite3BtreeCursorZero(BtCursor*); +void sqlite3BtreeCursorHint(BtCursor*, int, ...); int sqlite3BtreeCloseCursor(BtCursor*); int sqlite3BtreeMovetoUnpacked( diff --git a/src/vdbe.c b/src/vdbe.c index a18608aa60..c8d2f3adbb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3384,10 +3384,12 @@ case OP_OpenWrite: open_cursor_set_hints: assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ ); -#ifdef SQLITE_ENABLE_CURSOR_HINTS + testcase( pOp->p5 & OPFLAG_BULKCSR ); +#ifdef SQLITE_ENABLE_CURSOR_HINT + testcase( pOp->p2 & OPFLAG_SEEKEQ ); +#endif sqlite3BtreeCursorHint(pCur->pCursor, BTREE_HINT_FLAGS, (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); -#endif break; } From a67a31624d3e1133538d0d4c0b39980a86c61d4f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 15 Aug 2015 00:51:23 +0000 Subject: [PATCH 13/55] Change the display of the P4 operand of CursorHint in EXPLAIN output to function notation. FossilOrigin-Name: bee73d429cb0e99b43fb191ac15e298d0353b135 --- manifest | 14 ++++----- manifest.uuid | 2 +- src/vdbeaux.c | 68 +++++++++++++++++++++++--------------------- test/cursorhint.test | 12 ++++---- 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 931701bf6b..32218e8eda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sprovide\sthe\sBTREE_BULKLOAD\shint,\seven\swhen\sSQLITE_ENABLE_CURSOR_HINTS\nis\snot\sdefined,\sas\sthat\shint\sgives\sa\s4%\sperformance\sincrease. -D 2015-08-14T23:57:04.215 +C Change\sthe\sdisplay\sof\sthe\sP4\soperand\sof\sCursorHint\sin\sEXPLAIN\soutput\sto\nfunction\snotation. +D 2015-08-15T00:51:23.737 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -402,7 +402,7 @@ F src/vdbe.c 4dbcceb38f5c3e42c0725a56e7c76eb12adedebb F src/vdbe.h 529bb4a7bedcd28dccba5abb3927e3c5cb70a832 F src/vdbeInt.h 7258d75fc2dad0bccdef14d7d8d2fd50fd1bf2d2 F src/vdbeapi.c adabbd66eb2e3a10f3998485ee0be7e326d06ee4 -F src/vdbeaux.c 9f726265d3c4a64264c9aa80d35aa19c51a3c6f4 +F src/vdbeaux.c e8dbcc838ca29f0d2767e789f4fe5883541e4f6e F src/vdbeblob.c 4f2e8e075d238392df98c5e03a64342465b03f90 F src/vdbemem.c ae38a0d35ae71cf604381a887c170466ba518090 F src/vdbesort.c f5009e7a35e3065635d8918b9a31f498a499976b @@ -560,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test c3844bed3eec3506b38b98ab5f0ca22a4ab9ecb4 +F test/cursorhint.test 0d79cce943e4e61910d9a5cf73b1e57b2b42429f F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bf383e665a191a4f33a540d1240960a922e22813 -R 87aadf49a7545642a0a9fb9a1d94cce7 +P 83a844357e132683ab3d88eee0fe32a8beeb6662 +R 64f1f656f75dd3e1a8b619dc73ce4cbc U drh -Z 44853a09e3a1d8da8995535278d599e8 +Z 780f279750b73ad9a07ce3a651ba66ad diff --git a/manifest.uuid b/manifest.uuid index 9c7ac55d4b..dd4f395a20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83a844357e132683ab3d88eee0fe32a8beeb6662 \ No newline at end of file +bee73d429cb0e99b43fb191ac15e298d0353b135 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index df6ac61f82..37be7f44c8 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1090,25 +1090,22 @@ static int displayComment( ** that can be displayed in the P4 column of EXPLAIN output. */ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ - const char *zBinOp = 0; + const char *zOp = 0; + int n; switch( pExpr->op ){ case TK_STRING: sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken); break; - case TK_INTEGER: sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue); break; - case TK_NULL: sqlite3_snprintf(nTemp, zTemp, "NULL"); break; - case TK_REGISTER: { sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable); break; } - case TK_COLUMN: { if( pExpr->iColumn<0 ){ sqlite3_snprintf(nTemp, zTemp, "rowid"); @@ -1117,43 +1114,48 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ } break; } - - case TK_LT: zBinOp = "<"; break; - case TK_LE: zBinOp = "<="; break; - case TK_GT: zBinOp = ">"; break; - case TK_GE: zBinOp = ">="; break; - case TK_NE: zBinOp = "!="; break; - case TK_EQ: zBinOp = "=="; break; - case TK_IS: zBinOp = " IS "; break; - case TK_ISNOT: zBinOp = " IS NOT "; break; - case TK_AND: zBinOp = " AND "; break; - case TK_OR: zBinOp = " OR "; break; - case TK_PLUS: zBinOp = "+"; break; - case TK_STAR: zBinOp = "*"; break; - case TK_MINUS: zBinOp = "-"; break; - case TK_REM: zBinOp = "%"; break; - case TK_BITAND: zBinOp = "&"; break; - case TK_BITOR: zBinOp = "|"; break; - case TK_SLASH: zBinOp = "/"; break; - case TK_LSHIFT: zBinOp = "<<"; break; - case TK_RSHIFT: zBinOp = ">>"; break; - case TK_CONCAT: zBinOp = "||"; break; + case TK_LT: zOp = "LT"; break; + case TK_LE: zOp = "LE"; break; + case TK_GT: zOp = "GT"; break; + case TK_GE: zOp = "GE"; break; + case TK_NE: zOp = "NE"; break; + case TK_EQ: zOp = "EQ"; break; + case TK_IS: zOp = "IS"; break; + case TK_ISNOT: zOp = "ISNOT"; break; + case TK_AND: zOp = "AND"; break; + case TK_OR: zOp = "OR"; break; + case TK_PLUS: zOp = "ADD"; break; + case TK_STAR: zOp = "MUL"; break; + case TK_MINUS: zOp = "SUB"; break; + case TK_REM: zOp = "REM"; break; + case TK_BITAND: zOp = "BITAND"; break; + case TK_BITOR: zOp = "BITOR"; break; + case TK_SLASH: zOp = "DIV"; break; + case TK_LSHIFT: zOp = "LSHIFT"; break; + case TK_RSHIFT: zOp = "RSHIFT"; break; + case TK_CONCAT: zOp = "CONCAT"; break; + case TK_UMINUS: zOp = "MINUS"; break; + case TK_UPLUS: zOp = "PLUS"; break; + case TK_BITNOT: zOp = "BITNOT"; break; + case TK_NOT: zOp = "NOT"; break; + case TK_ISNULL: zOp = "ISNULL"; break; + case TK_NOTNULL: zOp = "NOTNULL"; break; default: sqlite3_snprintf(nTemp, zTemp, "%s", "expr"); break; } - if( zBinOp && nTemp>5 ){ - int n = 1; - zTemp[0] = '('; + if( zOp ){ + sqlite3_snprintf(nTemp, zTemp, "%s(", zOp); + n = sqlite3Strlen30(zTemp); n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft); - sqlite3_snprintf(nTemp-n, zTemp+n, "%s", zBinOp); - n += sqlite3Strlen30(zTemp+n); - n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight); + if( npRight ){ + zTemp[n++] = ','; + n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight); + } sqlite3_snprintf(nTemp-n, zTemp+n, ")"); } - return sqlite3Strlen30(zTemp); } #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ diff --git a/test/cursorhint.test b/test/cursorhint.test index b9677b640d..9d12c90d7b 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -59,7 +59,7 @@ do_test 1.1 { p4_of_opcode db CursorHint { SELECT * FROM t1 CROSS JOIN t2 WHERE a=x } -} {/(r*==c0)/} +} {{EQ(r[1],c0)}} do_test 1.2 { p5_of_opcode db OpenRead . { SELECT * FROM t1 CROSS JOIN t2 WHERE a=x @@ -72,7 +72,7 @@ do_test 2.1 { p4_of_opcode db CursorHint { SELECT * FROM t2 CROSS JOIN t1 WHERE a=x } -} {/(c0==r*)/} +} {{EQ(c0,r[1])}} do_test 2.2 { p5_of_opcode db OpenRead . { SELECT * FROM t2 CROSS JOIN t1 WHERE a=x @@ -85,12 +85,12 @@ do_test 3.1 { p4_of_opcode db CursorHint { SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98 } -} {/(c0==15).*(c2==22).*(rowid!=98)/} +} {AND(AND(EQ(c0,15),EQ(c2,22)),NE(rowid,98))} do_test 3.2 { p4_of_opcode db CursorHint { SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98 } -} {/(c1<15).*(c2>22).*(c0!=98)/} +} {AND(AND(LT(c1,15),GT(c2,22)),NE(c0,98))} # Indexed queries # @@ -102,7 +102,7 @@ do_test 4.1 { p4_of_opcode db CursorHint { SELECT * FROM t1 WHERE b>11; } -} {/(c0>11)/} +} {GT(c0,11)} do_test 4.2 { p5_of_opcode db OpenRead . { SELECT * FROM t1 WHERE b>11; @@ -112,7 +112,7 @@ do_test 4.3 { p4_of_opcode db CursorHint { SELECT c FROM t1 WHERE b>11; } -} {/(c0>11)/} +} {GT(c0,11)} do_test 4.4 { p5_of_opcode db OpenRead . { SELECT c FROM t1 WHERE b>11; From b413a5467acba99dcd3fcf12e0b9ca4292722649 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 17 Aug 2015 17:19:28 +0000 Subject: [PATCH 14/55] Avoid generating hints using constraints that are also used to initialize the cursor, since presumably the cursor already knows about those constraints. FossilOrigin-Name: 142b048ac778620dd4e448c2e969982eb8188501 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 31 ++++++++++++++++++++++++------- test/cursorhint.test | 42 ++++++++++++++++++++++++++++++++++++------ 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 32218e8eda..f152345340 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sdisplay\sof\sthe\sP4\soperand\sof\sCursorHint\sin\sEXPLAIN\soutput\sto\nfunction\snotation. -D 2015-08-15T00:51:23.737 +C Avoid\sgenerating\shints\susing\sconstraints\sthat\sare\salso\sused\sto\sinitialize\sthe\ncursor,\ssince\spresumably\sthe\scursor\salready\sknows\sabout\sthose\sconstraints. +D 2015-08-17T17:19:28.483 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -414,7 +414,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c ef95e56b6e7cdfa3ae0b6f72e3578391addfa965 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 16045545fb44878a7ba61db645521f30f9265893 +F src/wherecode.c 148c5dc225551309f489a5c44b8a0f7800c9794b F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -560,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test 0d79cce943e4e61910d9a5cf73b1e57b2b42429f +F test/cursorhint.test b1f86e9c959231094d8fe214518667548083063e F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 83a844357e132683ab3d88eee0fe32a8beeb6662 -R 64f1f656f75dd3e1a8b619dc73ce4cbc +P bee73d429cb0e99b43fb191ac15e298d0353b135 +R f415b0a9be4e26d1aeb927a138261bed U drh -Z 780f279750b73ad9a07ce3a651ba66ad +Z dbc2b5253d321af49bf9c502e3a1dded diff --git a/manifest.uuid b/manifest.uuid index dd4f395a20..6fdfe94f71 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bee73d429cb0e99b43fb191ac15e298d0353b135 \ No newline at end of file +142b048ac778620dd4e448c2e969982eb8188501 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 5052e2d378..5e7710ae8a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -669,8 +669,9 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( - WhereInfo *pWInfo, - WhereLevel *pLevel + WhereInfo *pWInfo, /* The where clause */ + WhereLevel *pLevel, /* Which loop to provide hints for */ + WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ ){ Parse *pParse = pWInfo->pParse; sqlite3 *db = pParse->db; @@ -680,7 +681,8 @@ static void codeCursorHint( int iCur; WhereClause *pWC; WhereTerm *pTerm; - int i; + WhereLoop *pWLoop; + int i, j; struct CCurHint sHint; Walker sWalker; @@ -694,18 +696,33 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; + pWLoop = pLevel->pWLoop; for(i=0; inTerm; i++){ pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + + /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize + ** the cursor. No need to hint initialization terms. */ + if( pTerm!=pEndRange ){ + for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; + } + + /* No subqueries or non-deterministic functions allowed */ if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + + /* For an index scan, make sure referenced columns are actually in + ** the index. */ if( sHint.pIdx!=0 ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintCheckExpr; sqlite3WalkExpr(&sWalker, pTerm->pExpr); if( sWalker.eCode ) continue; } + + /* If we survive all prior tests, that means this term is worth hinting */ pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ @@ -717,7 +734,7 @@ static void codeCursorHint( } } #else -# define codeCursorHint(A,B) /* No-op */ +# define codeCursorHint(A,B,C) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ /* @@ -883,7 +900,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pStart = pEnd; pEnd = pTerm; } - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, pEnd); if( pStart ){ Expr *pX; /* The expression that defines the start bound */ int r1, rTemp; /* Registers for holding the start boundary */ @@ -1106,7 +1123,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, pRangeEnd); nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; @@ -1534,7 +1551,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** a pseudo-cursor. No need to Rewind or Next such cursors. */ pLevel->op = OP_Noop; }else{ - codeCursorHint(pWInfo, pLevel); + codeCursorHint(pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrBrk); diff --git a/test/cursorhint.test b/test/cursorhint.test index 9d12c90d7b..4ff7faa859 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -94,13 +94,18 @@ do_test 3.2 { # Indexed queries # -do_test 4.1 { +do_test 4.1asc { db eval { CREATE INDEX t1bc ON t1(b,c); CREATE INDEX t2yz ON t2(y,z); } p4_of_opcode db CursorHint { - SELECT * FROM t1 WHERE b>11; + SELECT * FROM t1 WHERE b>11 ORDER BY b ASC; + } +} {} +do_test 4.1desc { + p4_of_opcode db CursorHint { + SELECT * FROM t1 WHERE b>11 ORDER BY b DESC; } } {GT(c0,11)} do_test 4.2 { @@ -108,16 +113,41 @@ do_test 4.2 { SELECT * FROM t1 WHERE b>11; } } {02 00} -do_test 4.3 { +do_test 4.3asc { p4_of_opcode db CursorHint { - SELECT c FROM t1 WHERE b>11; + SELECT c FROM t1 WHERE b<11 ORDER BY b ASC; } -} {GT(c0,11)} +} {LT(c0,11)} +do_test 4.3desc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b<11 ORDER BY b DESC; + } +} {} do_test 4.4 { p5_of_opcode db OpenRead . { - SELECT c FROM t1 WHERE b>11; + SELECT c FROM t1 WHERE b<11; } } {00} +do_test 4.5asc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC; + } +} {LE(c0,20)} +do_test 4.5desc { + p4_of_opcode db CursorHint { + SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC; + } +} {GE(c0,10)} +do_test 4.6asc { + p4_of_opcode db CursorHint { + SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC; + } +} {LE(c1,20)} +do_test 4.6desc { + p4_of_opcode db CursorHint { + SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC; + } +} {GE(c1,10)} finish_test From bcf40a7f122fcaf59c0264f59e940eafa1631865 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 18 Aug 2015 15:58:05 +0000 Subject: [PATCH 15/55] Provide hints for all terms in a range constraint if there are any equality terms anywhere in the constraint. Range constraint terms are only omitted for a pure range constraint with no equality prefix. FossilOrigin-Name: b5897bc0f003c470eeb2a75e0a2b2bb202681531 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 31 +++++++++++++++---------------- test/cursorhint.test | 8 ++++++-- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index f152345340..1f849deb21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sgenerating\shints\susing\sconstraints\sthat\sare\salso\sused\sto\sinitialize\sthe\ncursor,\ssince\spresumably\sthe\scursor\salready\sknows\sabout\sthose\sconstraints. -D 2015-08-17T17:19:28.483 +C Provide\shints\sfor\sall\sterms\sin\sa\srange\sconstraint\sif\sthere\sare\sany\sequality\nterms\sanywhere\sin\sthe\sconstraint.\s\sRange\sconstraint\sterms\sare\sonly\somitted\nfor\sa\spure\srange\sconstraint\swith\sno\sequality\sprefix. +D 2015-08-18T15:58:05.895 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 2fc9ca6bf5949d415801c007ed3004a4bdb7c380 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -414,7 +414,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804 F src/where.c ef95e56b6e7cdfa3ae0b6f72e3578391addfa965 F src/whereInt.h 5f87e3c4b0551747d119730dfebddd3c54f04047 -F src/wherecode.c 148c5dc225551309f489a5c44b8a0f7800c9794b +F src/wherecode.c ec90321e51bd13a0396f305403bc8ced2af7407e F src/whereexpr.c 9ce1c9cfedbf80c93c7d899497025ec8256ce652 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -560,7 +560,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test b1f86e9c959231094d8fe214518667548083063e +F test/cursorhint.test 7d94f7602e22ec129ca51836f333b5ff994a2b02 F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1374,7 +1374,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bee73d429cb0e99b43fb191ac15e298d0353b135 -R f415b0a9be4e26d1aeb927a138261bed +P 142b048ac778620dd4e448c2e969982eb8188501 +R e232e29543e31c41650c4e43b7879d83 U drh -Z dbc2b5253d321af49bf9c502e3a1dded +Z 6f609828180274045282332efd8f8026 diff --git a/manifest.uuid b/manifest.uuid index 6fdfe94f71..c4758539e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -142b048ac778620dd4e448c2e969982eb8188501 \ No newline at end of file +b5897bc0f003c470eeb2a75e0a2b2bb202681531 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 5e7710ae8a..0428495d40 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -681,7 +681,6 @@ static void codeCursorHint( int iCur; WhereClause *pWC; WhereTerm *pTerm; - WhereLoop *pWLoop; int i, j; struct CCurHint sHint; Walker sWalker; @@ -696,7 +695,6 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; - pWLoop = pLevel->pWLoop; for(i=0; inTerm; i++){ pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -704,10 +702,11 @@ static void codeCursorHint( if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; /* All terms in pWLoop->aLTerm[] except pEndRange are used to initialize - ** the cursor. No need to hint initialization terms. */ - if( pTerm!=pEndRange ){ - for(j=0; jnLTerm && pWLoop->aLTerm[j]!=pTerm; j++){} - if( jnLTerm ) continue; + ** the cursor. These terms are not needed as hints for a pure range + ** scan (that has no == terms) so omit them. */ + if( pLoop->u.btree.nEq==0 && pTerm!=pEndRange ){ + for(j=0; jnLTerm && pLoop->aLTerm[j]!=pTerm; j++){} + if( jnLTerm ) continue; } /* No subqueries or non-deterministic functions allowed */ @@ -1094,15 +1093,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( } assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); - /* Generate code to evaluate all constraint terms using == or IN - ** and store the values of those terms in an array of registers - ** starting at regBase. - */ - regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); - assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); - if( zStartAff ) cEndAff = zStartAff[nEq]; - addrNxt = pLevel->addrNxt; - /* If we are doing a reverse order scan on an ascending index, or ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). @@ -1114,6 +1104,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( SWAP(u8, bSeekPastNull, bStopAtNull); } + /* Generate code to evaluate all constraint terms using == or IN + ** and store the values of those terms in an array of registers + ** starting at regBase. + */ + codeCursorHint(pWInfo, pLevel, pRangeEnd); + regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); + if( zStartAff ) cEndAff = zStartAff[nEq]; + addrNxt = pLevel->addrNxt; + testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); testcase( pRangeEnd && (pRangeEnd->eOperator & WO_LE)!=0 ); @@ -1123,7 +1123,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( start_constraints = pRangeStart || nEq>0; /* Seek the index cursor to the start of the range. */ - codeCursorHint(pWInfo, pLevel, pRangeEnd); nConstraint = nEq; if( pRangeStart ){ Expr *pRight = pRangeStart->pExpr->pRight; diff --git a/test/cursorhint.test b/test/cursorhint.test index 4ff7faa859..75f3eb04e2 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -139,15 +139,19 @@ do_test 4.5desc { SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC; } } {GE(c0,10)} + +# If there are any equality terms used in the constraint, then all terms +# should be hinted. +# do_test 4.6asc { p4_of_opcode db CursorHint { SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC; } -} {LE(c1,20)} +} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))} do_test 4.6desc { p4_of_opcode db CursorHint { SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC; } -} {GE(c1,10)} +} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))} finish_test From b0df96346553ba7d5aa58f077c0e462e874ba1a2 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Oct 2015 23:55:08 +0000 Subject: [PATCH 16/55] Fix a comment in expr.c and add a CORRUPT_DB to an assert() in btree.c. FossilOrigin-Name: 0df371d1a51c2028aefa4c704707773750317689 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 4 +++- src/expr.c | 4 ++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d339fd779d..8845573c60 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhancements\sto\sthe\sMSVC\smakefile. -D 2015-10-16T20:13:57.036 +C Fix\sa\scomment\sin\sexpr.c\sand\sadd\sa\sCORRUPT_DB\sto\san\sassert()\sin\sbtree.c. +D 2015-10-16T23:55:08.882 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -280,7 +280,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 0b74bc28b2dc907cba03b5b4b3b81584273be699 +F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285 @@ -290,7 +290,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7 F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44 -F src/expr.c e8765542b21bc7ff801ca82d5cf11f0b13a219af +F src/expr.c d9896fda47a8f67d0ed203e1fa981444424200c6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P eb2317429fc3fc81ccd92e6f84f873585829259d -R c8195ddfd54e61d102ea2ab84cfcbce4 -U mistachkin -Z 0b9815ef53884597c48f7e60955b08c9 +P 39e8a5d93fa370afb03223bf0c20ea0f3448b9fc +R 7f916530a28273810e372e1a6552332a +U drh +Z 831fa17e60715846d1a74c0ef53a246d diff --git a/manifest.uuid b/manifest.uuid index 2d3dfc6c5d..c38b191fbe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39e8a5d93fa370afb03223bf0c20ea0f3448b9fc \ No newline at end of file +0df371d1a51c2028aefa4c704707773750317689 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2c1a9983e5..b26a95c801 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4499,7 +4499,9 @@ static int accessPayload( /* If required, populate the overflow page-list cache. */ if( (pCur->curFlags & BTCF_ValidOvfl)!=0 ){ - assert(!pCur->aOverflow[iIdx] || pCur->aOverflow[iIdx]==nextPage); + assert( pCur->aOverflow[iIdx]==0 + || pCur->aOverflow[iIdx]==nextPage + || CORRUPT_DB ); pCur->aOverflow[iIdx] = nextPage; } diff --git a/src/expr.c b/src/expr.c index a93bab991d..02cb4a5b47 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3356,6 +3356,10 @@ void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ ** ** The SQLITE_ECEL_FACTOR argument allows constant arguments to be ** factored out into initialization code. +** +** The SQLITE_ECEL_REF flag means that expressions in the list with +** ExprList.a[].u.x.iOrderByCol>0 have already been evaluated and stored +** in registers at srcReg, and so the value can be copied from there. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ From 05903e6a87865386de086f3de2a6b150f4bbae4c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Oct 2015 19:49:01 +0000 Subject: [PATCH 17/55] Handle equality and range constraints on the "term" column of fts5vocab tables. Also have the same module report columns using names instead of indexes. FossilOrigin-Name: 6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7 --- ext/fts5/fts5Int.h | 2 +- ext/fts5/fts5_index.c | 4 +- ext/fts5/fts5_main.c | 12 +-- ext/fts5/fts5_vocab.c | 179 ++++++++++++++++++++++++++++------- ext/fts5/test/fts5vocab.test | 143 ++++++++++++++++++++++++++-- manifest | 22 ++--- manifest.uuid | 2 +- 7 files changed, 299 insertions(+), 65 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 3671da1f12..bef185b07b 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -475,7 +475,7 @@ int sqlite3Fts5GetTokenizer( char **pzErr ); -Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, int*); +Fts5Index *sqlite3Fts5IndexFromCsrid(Fts5Global*, i64, Fts5Config **); /* ** End of interface to code in fts5.c. diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 5f3316f623..e006c9b36d 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4597,9 +4597,7 @@ int sqlite3Fts5IndexQuery( Fts5Buffer buf = {0, 0, 0}; /* If the QUERY_SCAN flag is set, all other flags must be clear. */ - assert( (flags & FTS5INDEX_QUERY_SCAN)==0 - || (flags & FTS5INDEX_QUERY_SCAN)==FTS5INDEX_QUERY_SCAN - ); + assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); if( sqlite3Fts5BufferGrow(&p->rc, &buf, nToken+1)==0 ){ memcpy(&buf.p[1], pToken, nToken); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index a301a82f24..a133cf41b9 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -2021,20 +2021,20 @@ static void fts5ApiCallback( ** Given cursor id iId, return a pointer to the corresponding Fts5Index ** object. Or NULL If the cursor id does not exist. ** -** If successful, set *pnCol to the number of indexed columns in the -** table before returning. +** If successful, set *ppConfig to point to the associated config object +** before returning. */ Fts5Index *sqlite3Fts5IndexFromCsrid( - Fts5Global *pGlobal, - i64 iCsrId, - int *pnCol + Fts5Global *pGlobal, /* FTS5 global context for db handle */ + i64 iCsrId, /* Id of cursor to find */ + Fts5Config **ppConfig /* OUT: Configuration object */ ){ Fts5Cursor *pCsr; Fts5Table *pTab; pCsr = fts5CursorFromCsrid(pGlobal, iCsrId); pTab = (Fts5Table*)pCsr->base.pVtab; - *pnCol = pTab->pConfig->nCol; + *ppConfig = pTab->pConfig; return pTab->pIndex; } diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index adbe526b7b..f47a7d3ec5 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -55,16 +55,18 @@ struct Fts5VocabCursor { int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ + int nLeTerm; /* Size of zLeTerm in bytes */ + char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ + /* These are used by 'col' tables only */ - int nCol; + Fts5Config *pConfig; /* Fts5 table configuration */ int iCol; i64 *aCnt; i64 *aDoc; - /* Output values */ + /* Output values used by 'row' and 'col' tables */ i64 rowid; /* This table's current rowid value */ Fts5Buffer term; /* Current value of 'term' column */ - i64 aVal[3]; /* Up to three columns left of 'term' */ }; #define FTS5_VOCAB_COL 0 @@ -73,6 +75,14 @@ struct Fts5VocabCursor { #define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" #define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" +/* +** Bits for the mask used as the idxNum value by xBestIndex/xFilter. +*/ +#define FTS5_VOCAB_TERM_EQ 0x01 +#define FTS5_VOCAB_TERM_GE 0x02 +#define FTS5_VOCAB_TERM_LE 0x04 + + /* ** Translate a string containing an fts5vocab table type to an ** FTS5_VOCAB_XXX constant. If successful, set *peType to the output @@ -230,6 +240,46 @@ static int fts5VocabBestIndexMethod( sqlite3_vtab *pVTab, sqlite3_index_info *pInfo ){ + int i; + int iTermEq = -1; + int iTermGe = -1; + int iTermLe = -1; + int idxNum = 0; + int nArg = 0; + + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; + if( p->usable==0 ) continue; + if( p->iColumn==0 ){ /* term column */ + if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; + if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i; + if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i; + if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i; + if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i; + } + } + + if( iTermEq>=0 ){ + idxNum |= FTS5_VOCAB_TERM_EQ; + pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg; + pInfo->aConstraintUsage[iTermEq].omit = 1; + pInfo->estimatedCost = 100; + }else{ + pInfo->estimatedCost = 1000000; + if( iTermGe>=0 ){ + idxNum |= FTS5_VOCAB_TERM_GE; + pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg; + pInfo->estimatedCost = pInfo->estimatedCost / 2; + } + if( iTermLe>=0 ){ + idxNum |= FTS5_VOCAB_TERM_LE; + pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg; + pInfo->estimatedCost = pInfo->estimatedCost / 2; + } + } + + pInfo->idxNum = idxNum; + return SQLITE_OK; } @@ -242,12 +292,11 @@ static int fts5VocabOpenMethod( ){ Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab; Fts5Index *pIndex = 0; - int nCol = 0; + Fts5Config *pConfig = 0; Fts5VocabCursor *pCsr = 0; int rc = SQLITE_OK; sqlite3_stmt *pStmt = 0; char *zSql = 0; - int nByte; zSql = sqlite3Fts5Mprintf(&rc, "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'", @@ -262,7 +311,7 @@ static int fts5VocabOpenMethod( if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ i64 iId = sqlite3_column_int64(pStmt, 0); - pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &nCol); + pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig); } if( rc==SQLITE_OK && pIndex==0 ){ @@ -276,14 +325,17 @@ static int fts5VocabOpenMethod( } } - nByte = nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor); - pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); + if( rc==SQLITE_OK ){ + int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor); + pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); + } + if( pCsr ){ pCsr->pIndex = pIndex; pCsr->pStmt = pStmt; - pCsr->nCol = nCol; + pCsr->pConfig = pConfig; pCsr->aCnt = (i64*)&pCsr[1]; - pCsr->aDoc = &pCsr->aCnt[nCol]; + pCsr->aDoc = &pCsr->aCnt[pConfig->nCol]; }else{ sqlite3_finalize(pStmt); } @@ -296,6 +348,9 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ pCsr->rowid = 0; sqlite3Fts5IterClose(pCsr->pIter); pCsr->pIter = 0; + sqlite3_free(pCsr->zLeTerm); + pCsr->nLeTerm = -1; + pCsr->zLeTerm = 0; } /* @@ -319,16 +374,17 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; int rc = SQLITE_OK; + int nCol = pCsr->pConfig->nCol; pCsr->rowid++; if( pTab->eType==FTS5_VOCAB_COL ){ - for(pCsr->iCol++; pCsr->iColnCol; pCsr->iCol++){ + for(pCsr->iCol++; pCsr->iColiCol++){ if( pCsr->aCnt[pCsr->iCol] ) break; } } - if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=pCsr->nCol ){ + if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){ if( sqlite3Fts5IterEof(pCsr->pIter) ){ pCsr->bEof = 1; }else{ @@ -336,10 +392,18 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ int nTerm; zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + if( pCsr->nLeTerm>=0 ){ + int nCmp = MIN(nTerm, pCsr->nLeTerm); + int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); + if( bCmp<0 || (bCmp==0 && pCsr->nLeTermbEof = 1; + return SQLITE_OK; + } + } + sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); - memset(pCsr->aVal, 0, sizeof(pCsr->aVal)); - memset(pCsr->aCnt, 0, pCsr->nCol * sizeof(i64)); - memset(pCsr->aDoc, 0, pCsr->nCol * sizeof(i64)); + memset(pCsr->aCnt, 0, nCol * sizeof(i64)); + memset(pCsr->aDoc, 0, nCol * sizeof(i64)); pCsr->iCol = 0; assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); @@ -353,9 +417,9 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( rc==SQLITE_OK ){ if( pTab->eType==FTS5_VOCAB_ROW ){ while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aVal[1]++; + pCsr->aCnt[0]++; } - pCsr->aVal[0]++; + pCsr->aDoc[0]++; }else{ int iCol = -1; while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ @@ -369,9 +433,12 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ } rc = sqlite3Fts5IterNextScan(pCsr->pIter); } + if( rc==SQLITE_OK ){ zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); - if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ) break; + if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){ + break; + } if( sqlite3Fts5IterEof(pCsr->pIter) ) break; } } @@ -380,9 +447,7 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++; - pCsr->aVal[0] = pCsr->iCol; - pCsr->aVal[1] = pCsr->aDoc[pCsr->iCol]; - pCsr->aVal[2] = pCsr->aCnt[pCsr->iCol]; + assert( pCsr->iColpConfig->nCol ); } return rc; } @@ -399,10 +464,46 @@ static int fts5VocabFilterMethod( ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; int rc; - const int flags = FTS5INDEX_QUERY_SCAN; + + int iVal = 0; + int f = FTS5INDEX_QUERY_SCAN; + const char *zTerm = 0; + int nTerm = 0; + + sqlite3_value *pEq = 0; + sqlite3_value *pGe = 0; + sqlite3_value *pLe = 0; fts5VocabResetCursor(pCsr); - rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, 0, &pCsr->pIter); + if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; + if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; + if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; + + if( pEq ){ + zTerm = sqlite3_value_text(pEq); + nTerm = sqlite3_value_bytes(pEq); + f = 0; + }else{ + if( pGe ){ + zTerm = sqlite3_value_text(pGe); + nTerm = sqlite3_value_bytes(pGe); + } + if( pLe ){ + const char *zCopy = sqlite3_value_text(pLe); + pCsr->nLeTerm = sqlite3_value_bytes(pLe); + pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); + if( pCsr->zLeTerm==0 ){ + rc = SQLITE_NOMEM; + }else{ + memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1); + } + } + } + + + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); + } if( rc==SQLITE_OK ){ rc = fts5VocabNextMethod(pCursor); } @@ -425,17 +526,29 @@ static int fts5VocabColumnMethod( int iCol /* Index of column to read value from */ ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; - switch( iCol ){ - case 0: /* term */ - sqlite3_result_text( - pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT - ); - break; - default: - assert( iCol<4 && iCol>0 ); - sqlite3_result_int64(pCtx, pCsr->aVal[iCol-1]); - break; + if( iCol==0 ){ + sqlite3_result_text( + pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT + ); + } + else if( ((Fts5VocabTable*)(pCursor->pVtab))->eType==FTS5_VOCAB_COL ){ + assert( iCol==1 || iCol==2 || iCol==3 ); + if( iCol==1 ){ + const char *z = pCsr->pConfig->azCol[pCsr->iCol]; + sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); + }else if( iCol==2 ){ + sqlite3_result_int64(pCtx, pCsr->aDoc[pCsr->iCol]); + }else{ + sqlite3_result_int64(pCtx, pCsr->aCnt[pCsr->iCol]); + } + }else{ + assert( iCol==1 || iCol==2 ); + if( iCol==1 ){ + sqlite3_result_int64(pCtx, pCsr->aDoc[0]); + }else{ + sqlite3_result_int64(pCtx, pCsr->aCnt[0]); + } } return SQLITE_OK; } diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index c95f50b835..fd898d958e 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -56,7 +56,7 @@ do_execsql_test 1.4.1 { do_execsql_test 1.4.2 { SELECT * FROM v2; -} {x 0 2 4 y 0 1 1 z 0 1 1} +} {x one 2 4 y one 1 1 z one 1 1} do_execsql_test 1.5.1 { BEGIN; @@ -67,7 +67,7 @@ do_execsql_test 1.5.1 { do_execsql_test 1.5.2 { SELECT * FROM v2 WHERE term<'d'; COMMIT; -} {a 0 1 1 b 0 1 1 c 0 1 1} +} {a one 1 1 b one 1 1 c one 1 1} do_execsql_test 1.6 { DELETE FROM t1 WHERE one = 'a b c'; @@ -91,14 +91,14 @@ do_execsql_test 2.0 { } set res_col { - a 0 6 11 a 1 7 9 - b 0 6 7 b 1 7 7 - c 0 6 12 c 1 5 8 - d 0 4 6 d 1 9 13 - e 0 6 7 e 1 6 6 - f 0 9 10 f 1 7 10 - g 0 5 7 g 1 5 7 - x 0 1 1 y 1 1 1 + a a 6 11 a b 7 9 + b a 6 7 b b 7 7 + c a 6 12 c b 5 8 + d a 4 6 d b 9 13 + e a 6 7 e b 6 6 + f a 9 10 f b 7 10 + g a 5 7 g b 5 7 + x a 1 1 y b 1 1 } set res_row { a 10 20 b 9 14 c 9 20 d 9 19 @@ -213,5 +213,128 @@ do_catchsql_test 6.2 { SELECT * FROM vocab3; } {1 {no such fts5 table: main.lll}} +#------------------------------------------------------------------------- +# Test single term queries on fts5vocab tables (i.e. those with term=? +# constraints in the WHERE clause). +# +do_execsql_test 7.0 { + CREATE VIRTUAL TABLE tx USING fts5(one, two); + INSERT INTO tx VALUES('g a ggg g a b eee', 'cc d aa ff g ee'); + INSERT INTO tx VALUES('dd fff i a i jjj', 'f fff hh jj e f'); + INSERT INTO tx VALUES('ggg a f f fff dd aa', 'd ggg f f j gg ddd'); + INSERT INTO tx VALUES('e bb h jjj ii gg', 'e aa e f c fff'); + INSERT INTO tx VALUES('j ff aa a h', 'h a j bbb bb'); + INSERT INTO tx VALUES('cc i ff c d f', 'dd ii fff f c cc d'); + INSERT INTO tx VALUES('jjj g i bb cc eee', 'hhh iii aaa b bbb aaa'); + INSERT INTO tx VALUES('hhh hhh hhh bb fff f', 'fff gg aa ii h a'); + INSERT INTO tx VALUES('b c cc aaa iii ggg f', 'iii ff ee a ff c cc'); + INSERT INTO tx VALUES('hhh b hhh aaa j i i', 'dd ee ee aa bbb iii'); + INSERT INTO tx VALUES('hh dd h b g ff i', 'ccc bb cc ccc f a d'); + INSERT INTO tx VALUES('g d b ggg jj', 'fff jj ff jj g gg ee'); + INSERT INTO tx VALUES('g ee ggg ggg cc bb eee', 'aa j jjj bbb dd eee ff'); + INSERT INTO tx VALUES('c jjj hh ddd dd h', 'e aaa h jjj gg'); + + CREATE VIRTUAL TABLE txr USING fts5vocab(tx, row); + CREATE VIRTUAL TABLE txc USING fts5vocab(tx, col); +} + +proc cont {L elem} { + set n 0 + foreach e $L { if {$elem==$e} {incr n} } + set n +} +db func cont cont + +foreach {term} { + a aa aaa + b bb bbb + c cc ccc + d dd ddd + e ee eee + f ff fff + g gg ggg + h hh hhh + i ii iii + j jj jjj +} { + set resr [db eval { + SELECT $term, + sum(cont(one || ' ' || two, $term) > 0), + sum(cont(one || ' ' || two, $term)) + FROM tx + }] + if {[lindex $resr 1]==0} {set resr [list]} + + set r1 [db eval { + SELECT $term, 'one', sum(cont(one, $term)>0), sum(cont(one, $term)) FROM tx + }] + if {[lindex $r1 2]==0} {set r1 [list]} + + set r2 [db eval { + SELECT $term, 'two', sum(cont(two, $term)>0), sum(cont(two, $term)) FROM tx + }] + if {[lindex $r2 2]==0} {set r2 [list]} + + set resc [concat $r1 $r2] + do_execsql_test 7.$term.1 {SELECT * FROM txc WHERE term=$term} $resc + do_execsql_test 7.$term.2 {SELECT * FROM txr WHERE term=$term} $resr +} + +do_execsql_test 7.1 { + CREATE TABLE txr_c AS SELECT * FROM txr; + CREATE TABLE txc_c AS SELECT * FROM txc; +} + +# Test range queries on the fts5vocab tables created above. +# +foreach {tn a b} { + 1 a jjj + 2 bb j + 3 ccc ddd + 4 dd xyz + 5 xzy dd + 6 h hh +} { + do_execsql_test 7.2.$tn.1 { + SELECT * FROM txr WHERE term>=$a + } [db eval {SELECT * FROM txr_c WHERE term>=$a}] + do_execsql_test 7.2.$tn.2 { + SELECT * FROM txr WHERE term<=$b + } [db eval {SELECT * FROM txr_c WHERE term <=$b}] + do_execsql_test 7.2.$tn.3 { + SELECT * FROM txr WHERE term>=$a AND term<=$b + } [db eval {SELECT * FROM txr_c WHERE term>=$a AND term <=$b}] + + do_execsql_test 7.2.$tn.4 { + SELECT * FROM txc WHERE term>=$a + } [db eval {SELECT * FROM txc_c WHERE term>=$a}] + do_execsql_test 7.2.$tn.5 { + SELECT * FROM txc WHERE term<=$b + } [db eval {SELECT * FROM txc_c WHERE term <=$b}] + do_execsql_test 7.2.$tn.6 { + SELECT * FROM txc WHERE term>=$a AND term<=$b + } [db eval {SELECT * FROM txc_c WHERE term>=$a AND term <=$b}] + + do_execsql_test 7.2.$tn.7 { + SELECT * FROM txr WHERE term>$a + } [db eval {SELECT * FROM txr_c WHERE term>$a}] + do_execsql_test 7.2.$tn.8 { + SELECT * FROM txr WHERE term<$b + } [db eval {SELECT * FROM txr_c WHERE term<$b}] + do_execsql_test 7.2.$tn.9 { + SELECT * FROM txr WHERE term>$a AND term<$b + } [db eval {SELECT * FROM txr_c WHERE term>$a AND term <$b}] + + do_execsql_test 7.2.$tn.10 { + SELECT * FROM txc WHERE term>$a + } [db eval {SELECT * FROM txc_c WHERE term>$a}] + do_execsql_test 7.2.$tn.11 { + SELECT * FROM txc WHERE term<$b + } [db eval {SELECT * FROM txc_c WHERE term<$b}] + do_execsql_test 7.2.$tn.12 { + SELECT * FROM txc WHERE term>$a AND term<$b + } [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}] +} + finish_test diff --git a/manifest b/manifest index 8845573c60..844d674b9e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scomment\sin\sexpr.c\sand\sadd\sa\sCORRUPT_DB\sto\san\sassert()\sin\sbtree.c. -D 2015-10-16T23:55:08.882 +C Handle\sequality\sand\srange\sconstraints\son\sthe\s"term"\scolumn\sof\sfts5vocab\stables.\sAlso\shave\sthe\ssame\smodule\sreport\scolumns\susing\snames\sinstead\sof\sindexes. +D 2015-10-17T19:49:01.860 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -103,21 +103,21 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 -F ext/fts5/fts5Int.h 38667e39859ff3f3bc91f47efe672023a145a118 +F ext/fts5/fts5Int.h 0332d12fdca0f4fe2231df71bd7544b3cef81122 F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 F ext/fts5/fts5_buffer.c 9a3aa73a4e7b26b1c805b9c92c1344ba3d19d2a8 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c c76d636d6cd22e3b82b1dbf3a3993447091c3bed -F ext/fts5/fts5_main.c d3fde32e1fdd7962dc7062400d1d8c7ec2297acf +F ext/fts5/fts5_index.c 632fdcb1971f6c9d7d6b2bd31f6c41e4189162bb +F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 9b30115742b758706de70595a8d1d084e940c978 F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c 85ebf2e93089c9d3d136cc69163370592fc040f3 +F ext/fts5/fts5_vocab.c f7c03dabb858896d42165bc54e4aa4f82650ecea F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d @@ -180,7 +180,7 @@ F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e -F ext/fts5/test/fts5vocab.test cdf97b9678484e9bad5062edf9c9106e5c3b0c5c +F ext/fts5/test/fts5vocab.test 7dec771fd2388c11f7c336d6d155d31e12e4001a F ext/fts5/tool/fts5txt2db.tcl 3d19fb8ffb234031d33d7d2151acfbc55e9cfcc4 F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3 F ext/fts5/tool/mkfts5c.tcl 09ce6a7997440508360f5ba1651ab7e923a8bf31 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 39e8a5d93fa370afb03223bf0c20ea0f3448b9fc -R 7f916530a28273810e372e1a6552332a -U drh -Z 831fa17e60715846d1a74c0ef53a246d +P 0df371d1a51c2028aefa4c704707773750317689 +R 97767b5f8bc213fefd21674fa8888cb4 +U dan +Z b5428af5c06a042c6ac8c829b1afb62f diff --git a/manifest.uuid b/manifest.uuid index c38b191fbe..6b22c8a106 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0df371d1a51c2028aefa4c704707773750317689 \ No newline at end of file +6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7 \ No newline at end of file From 0206920e27d48c9b7cd22e2716f45fd9c26c5ad2 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Oct 2015 20:34:49 +0000 Subject: [PATCH 18/55] Add tests to cover new branches added to the fts5 code by the previous commit. FossilOrigin-Name: cf618334a8a05a067e844236e4d461b2e5706da6 --- ext/fts5/fts5_vocab.c | 1 - ext/fts5/test/fts5fault5.test | 8 ++++++++ ext/fts5/test/fts5vocab.test | 9 +++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index f47a7d3ec5..80e3455900 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -262,7 +262,6 @@ static int fts5VocabBestIndexMethod( if( iTermEq>=0 ){ idxNum |= FTS5_VOCAB_TERM_EQ; pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg; - pInfo->aConstraintUsage[iTermEq].omit = 1; pInfo->estimatedCost = 100; }else{ pInfo->estimatedCost = 1000000; diff --git a/ext/fts5/test/fts5fault5.test b/ext/fts5/test/fts5fault5.test index c14f394eb6..41de5208b2 100644 --- a/ext/fts5/test/fts5fault5.test +++ b/ext/fts5/test/fts5fault5.test @@ -90,6 +90,14 @@ do_faultsim_test 3.1 -faults oom-t* -body { faultsim_test_result {0 {0 1 10 11 12 13 14 15 16 17 18 19 2 3 4 5 6 7 8 9}} } +do_faultsim_test 3.2 -faults oom-t* -body { + db eval { + SELECT term FROM tv WHERE term BETWEEN '1' AND '2'; + } +} -test { + faultsim_test_result {0 {1 10 11 12 13 14 15 16 17 18 19 2}} +} + finish_test diff --git a/ext/fts5/test/fts5vocab.test b/ext/fts5/test/fts5vocab.test index fd898d958e..dc5099c6e3 100644 --- a/ext/fts5/test/fts5vocab.test +++ b/ext/fts5/test/fts5vocab.test @@ -336,5 +336,14 @@ foreach {tn a b} { } [db eval {SELECT * FROM txc_c WHERE term>$a AND term <$b}] } +do_execsql_test 7.3.1 { + SELECT count(*) FROM txr, txr_c WHERE txr.term = txr_c.term; +} {30} + +do_execsql_test 7.3.2 { + SELECT count(*) FROM txc, txc_c + WHERE txc.term = txc_c.term AND txc.col=txc_c.col; +} {57} + finish_test diff --git a/manifest b/manifest index 844d674b9e..955c828ace 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Handle\sequality\sand\srange\sconstraints\son\sthe\s"term"\scolumn\sof\sfts5vocab\stables.\sAlso\shave\sthe\ssame\smodule\sreport\scolumns\susing\snames\sinstead\sof\sindexes. -D 2015-10-17T19:49:01.860 +C Add\stests\sto\scover\snew\sbranches\sadded\sto\sthe\sfts5\scode\sby\sthe\sprevious\scommit. +D 2015-10-17T20:34:49.498 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -117,7 +117,7 @@ F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c f7c03dabb858896d42165bc54e4aa4f82650ecea +F ext/fts5/fts5_vocab.c 4bf7e418bd3f857c7aea8221fc2c159283d30c6b F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d @@ -152,7 +152,7 @@ F ext/fts5/test/fts5fault1.test 7a562367cb4a735b57b410dbdb62dcc8d971faec F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 F ext/fts5/test/fts5fault4.test 762991d526ee67c2b374351a17248097ea38bee7 -F ext/fts5/test/fts5fault5.test 54da9fd4c3434a1d4f6abdcb6469299d91cf5875 +F ext/fts5/test/fts5fault5.test f2b8645053d48982e8979749e93994c43011c118 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 @@ -180,7 +180,7 @@ F ext/fts5/test/fts5unicode2.test c1dd890ba32b7609adba78e420faa847abe43b59 F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e -F ext/fts5/test/fts5vocab.test 7dec771fd2388c11f7c336d6d155d31e12e4001a +F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0 F ext/fts5/tool/fts5txt2db.tcl 3d19fb8ffb234031d33d7d2151acfbc55e9cfcc4 F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3 F ext/fts5/tool/mkfts5c.tcl 09ce6a7997440508360f5ba1651ab7e923a8bf31 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0df371d1a51c2028aefa4c704707773750317689 -R 97767b5f8bc213fefd21674fa8888cb4 +P 6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7 +R 22a259a71e3233ba8022de14ef31c49b U dan -Z b5428af5c06a042c6ac8c829b1afb62f +Z d5f5675976d14f9fce086eaa482cce6e diff --git a/manifest.uuid b/manifest.uuid index 6b22c8a106..8e55d16504 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7 \ No newline at end of file +cf618334a8a05a067e844236e4d461b2e5706da6 \ No newline at end of file From 3c060c2aef3b99abe24f409064321ef0b1452140 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Oct 2015 15:59:08 +0000 Subject: [PATCH 19/55] Fix a problem in the fts5txt2db.tcl script causing it to fail when creating tables with more than 8 columns. FossilOrigin-Name: 68ee426a6432ac63655909ff70cb22bde33cf28c --- ext/fts5/tool/fts5txt2db.tcl | 25 +++++-------------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/ext/fts5/tool/fts5txt2db.tcl b/ext/fts5/tool/fts5txt2db.tcl index 23f607a801..c22c5dae72 100644 --- a/ext/fts5/tool/fts5txt2db.tcl +++ b/ext/fts5/tool/fts5txt2db.tcl @@ -25,7 +25,7 @@ is exhausted. exit -1 } -set O(aColsize) [list 10 10 10] +set O(aColSize) [list 10 10 10] set O(tblname) t1 set O(fts) fts5 @@ -61,22 +61,7 @@ if {$i > [llength $argv]-2} usage set O(db) [lindex $argv $i] set O(files) [lrange $argv [expr $i+1] end] -foreach {k v} [lrange $argv 0 end-2] { - switch -- $k { - -colsize { - set O(aColSize) $v - } - - -colsize { - set O(aColSize) $v - } - } - -} - sqlite3 db $O(db) -load_static_extension db fts5 - # Create the FTS table in the db. Return a list of the table columns. # @@ -84,7 +69,7 @@ proc create_table {} { global O set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z] - set nCol [llength $O(aColsize)] + set nCol [llength $O(aColSize)] set cols [lrange $cols 0 [expr $nCol-1]] set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) (" @@ -117,14 +102,14 @@ set i 0 set cols [create_table] set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]" foreach c [lrange $cols 1 end] { - append sql ", \$$c" + append sql ", \$A($c)" } append sql ")" db eval BEGIN while {$i < $N} { - foreach c $cols s $O(aColsize) { - set $c [lrange $tokens $i [expr $i+$s-1]] + foreach c $cols s $O(aColSize) { + set A($c) [lrange $tokens $i [expr $i+$s-1]] incr i $s } db eval $sql diff --git a/manifest b/manifest index 955c828ace..2671464cd0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\scover\snew\sbranches\sadded\sto\sthe\sfts5\scode\sby\sthe\sprevious\scommit. -D 2015-10-17T20:34:49.498 +C Fix\sa\sproblem\sin\sthe\sfts5txt2db.tcl\sscript\scausing\sit\sto\sfail\swhen\screating\stables\swith\smore\sthan\s8\scolumns. +D 2015-10-19T15:59:08.318 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -181,7 +181,7 @@ F ext/fts5/test/fts5unicode3.test 35c3d02aa7acf7d43d8de3bfe32c15ba96e8928e F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0 -F ext/fts5/tool/fts5txt2db.tcl 3d19fb8ffb234031d33d7d2151acfbc55e9cfcc4 +F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84 F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3 F ext/fts5/tool/mkfts5c.tcl 09ce6a7997440508360f5ba1651ab7e923a8bf31 F ext/fts5/tool/showfts5.tcl 9eaf6c3df352f98a2ab5ce1921dd94128ab1381d @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6020d96ab47a0bebe41f691a3f44fd55d8b2d2b7 -R 22a259a71e3233ba8022de14ef31c49b +P cf618334a8a05a067e844236e4d461b2e5706da6 +R 30a0ced4e8757449657c5453f9890b65 U dan -Z d5f5675976d14f9fce086eaa482cce6e +Z 120618455a1082447e4825d9f82b93ec diff --git a/manifest.uuid b/manifest.uuid index 8e55d16504..0d152ea1ff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf618334a8a05a067e844236e4d461b2e5706da6 \ No newline at end of file +68ee426a6432ac63655909ff70cb22bde33cf28c \ No newline at end of file From 5e5b454cd818e226005ffd4ae6fabbc838e5411c Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Oct 2015 17:43:24 +0000 Subject: [PATCH 20/55] Another tweak to improve performance of fts5 prefix queries. FossilOrigin-Name: 69be427c864dc3de804ca3c5f1c6addcd33cd188 --- ext/fts5/fts5_index.c | 46 +++++++++++++++++++++++-------------------- manifest | 12 +++++------ manifest.uuid | 2 +- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index e006c9b36d..cf4f3d8bb3 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4111,15 +4111,6 @@ static int fts5AppendPoslist( int iSv2; int iData; - /* Append iDelta */ - iSv1 = pBuf->n; - fts5BufferSafeAppendVarint(pBuf, iDelta); - - /* WRITEPOSLISTSIZE */ - iSv2 = pBuf->n; - fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2); - iData = pBuf->n; - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf && (pColset==0 || pColset->nCol==1) ){ @@ -4127,24 +4118,37 @@ static int fts5AppendPoslist( int nPos; if( pColset ){ nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]); + if( nPos==0 ) return 1; }else{ nPos = pSeg->nPos; } + assert( nPos>0 ); + fts5BufferSafeAppendVarint(pBuf, iDelta); + fts5BufferSafeAppendVarint(pBuf, nPos*2); fts5BufferSafeAppendBlob(pBuf, pPos, nPos); }else{ - fts5SegiterPoslist(p, pSeg, pColset, pBuf); - } + /* Append iDelta */ + iSv1 = pBuf->n; + fts5BufferSafeAppendVarint(pBuf, iDelta); - if( pColset ){ - int nActual = pBuf->n - iData; - if( nActual!=pSeg->nPos ){ - if( nActual==0 ){ - pBuf->n = iSv1; - return 1; - }else{ - int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2)); - while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; } - sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2); + /* WRITEPOSLISTSIZE */ + iSv2 = pBuf->n; + fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2); + iData = pBuf->n; + + fts5SegiterPoslist(p, pSeg, pColset, pBuf); + + if( pColset ){ + int nActual = pBuf->n - iData; + if( nActual!=pSeg->nPos ){ + if( nActual==0 ){ + pBuf->n = iSv1; + return 1; + }else{ + int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2)); + while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; } + sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2); + } } } } diff --git a/manifest b/manifest index 2671464cd0..84b919c298 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\sfts5txt2db.tcl\sscript\scausing\sit\sto\sfail\swhen\screating\stables\swith\smore\sthan\s8\scolumns. -D 2015-10-19T15:59:08.318 +C Another\stweak\sto\simprove\sperformance\sof\sfts5\sprefix\squeries. +D 2015-10-19T17:43:24.360 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 9a3aa73a4e7b26b1c805b9c92c1344ba3d19d2a8 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 632fdcb1971f6c9d7d6b2bd31f6c41e4189162bb +F ext/fts5/fts5_index.c 8468e41855bba133107760badda415bc7f86c12c F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 9b30115742b758706de70595a8d1d084e940c978 F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cf618334a8a05a067e844236e4d461b2e5706da6 -R 30a0ced4e8757449657c5453f9890b65 +P 68ee426a6432ac63655909ff70cb22bde33cf28c +R b1e8d85157aaa205dae46563b3080619 U dan -Z 120618455a1082447e4825d9f82b93ec +Z e2816fa336eec46724399248fb4f473f diff --git a/manifest.uuid b/manifest.uuid index 0d152ea1ff..833def65e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -68ee426a6432ac63655909ff70cb22bde33cf28c \ No newline at end of file +69be427c864dc3de804ca3c5f1c6addcd33cd188 \ No newline at end of file From 8789fbb2bdbc784976064ec687f16891104ca9c9 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Oct 2015 20:49:10 +0000 Subject: [PATCH 21/55] Another optimization for fts5 prefix (and other) queries. FossilOrigin-Name: 60a8bde055a960c5b8cb4e231802c75617c942d8 --- ext/fts5/fts5Int.h | 7 ++++++- ext/fts5/fts5_buffer.c | 42 ++++++++++++++++++------------------------ ext/fts5/fts5_index.c | 12 +++++++----- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 40 insertions(+), 39 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index bef185b07b..b6c498fc3f 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -224,6 +224,7 @@ struct Fts5Buffer { int nSpace; }; +int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int); int sqlite3Fts5BufferGrow(int*, Fts5Buffer*, int); void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*); @@ -237,13 +238,17 @@ void sqlite3Fts5BufferAppend32(int*, Fts5Buffer*, int); char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferZero(x) sqlite3Fts5BufferZero(x) -#define fts5BufferGrow(a,b,c) sqlite3Fts5BufferGrow(a,b,c) #define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferAppend32(a,b,c) sqlite3Fts5BufferAppend32(a,b,c) +#define fts5BufferGrow(pRc,pBuf,nn) ( \ + (pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \ + sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \ +) + /* Write and decode big-endian 32-bit integer values */ void sqlite3Fts5Put32(u8*, int); int sqlite3Fts5Get32(const u8*); diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 07d8516ce4..bb64ce70d1 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -15,36 +15,30 @@ #include "fts5Int.h" -int sqlite3Fts5BufferGrow(int *pRc, Fts5Buffer *pBuf, int nByte){ - - if( (pBuf->n + nByte) > pBuf->nSpace ){ - u8 *pNew; - int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64; - - /* A no-op if an error has already occurred */ - if( *pRc ) return 1; - - while( nNew<(pBuf->n + nByte) ){ - nNew = nNew * 2; - } - pNew = sqlite3_realloc(pBuf->p, nNew); - if( pNew==0 ){ - *pRc = SQLITE_NOMEM; - return 1; - }else{ - pBuf->nSpace = nNew; - pBuf->p = pNew; - } +int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, int nByte){ + int nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64; + u8 *pNew; + while( nNewp, nNew); + if( pNew==0 ){ + *pRc = SQLITE_NOMEM; + return 1; + }else{ + pBuf->nSpace = nNew; + pBuf->p = pNew; } return 0; } + /* ** Encode value iVal as an SQLite varint and append it to the buffer object ** pBuf. If an OOM error occurs, set the error code in p. */ void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){ - if( sqlite3Fts5BufferGrow(pRc, pBuf, 9) ) return; + if( fts5BufferGrow(pRc, pBuf, 9) ) return; pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal); } @@ -60,7 +54,7 @@ int sqlite3Fts5Get32(const u8 *aBuf){ } void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){ - if( sqlite3Fts5BufferGrow(pRc, pBuf, 4) ) return; + if( fts5BufferGrow(pRc, pBuf, 4) ) return; sqlite3Fts5Put32(&pBuf->p[pBuf->n], iVal); pBuf->n += 4; } @@ -77,7 +71,7 @@ void sqlite3Fts5BufferAppendBlob( const u8 *pData ){ assert( *pRc || nData>=0 ); - if( sqlite3Fts5BufferGrow(pRc, pBuf, nData) ) return; + if( fts5BufferGrow(pRc, pBuf, nData) ) return; memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; } @@ -227,7 +221,7 @@ int sqlite3Fts5PoslistWriterAppend( ){ static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; int rc = SQLITE_OK; - if( 0==sqlite3Fts5BufferGrow(&rc, pBuf, 5+5+5) ){ + if( 0==fts5BufferGrow(&rc, pBuf, 5+5+5) ){ if( (iPos & colmask) != (pWriter->iPrev & colmask) ){ pBuf->p[pBuf->n++] = 1; pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index cf4f3d8bb3..19ea73ab96 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4107,9 +4107,6 @@ static int fts5AppendPoslist( assert( fts5MultiIterEof(p, pMulti)==0 ); assert( pSeg->nPos>0 ); if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){ - int iSv1; - int iSv2; - int iData; if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf && (pColset==0 || pColset->nCol==1) @@ -4127,6 +4124,10 @@ static int fts5AppendPoslist( fts5BufferSafeAppendVarint(pBuf, nPos*2); fts5BufferSafeAppendBlob(pBuf, pPos, nPos); }else{ + int iSv1; + int iSv2; + int iData; + /* Append iDelta */ iSv1 = pBuf->n; fts5BufferSafeAppendVarint(pBuf, iDelta); @@ -4152,6 +4153,7 @@ static int fts5AppendPoslist( } } } + } } @@ -4240,7 +4242,7 @@ static void fts5MergePrefixLists( memset(&out, 0, sizeof(out)); memset(&tmp, 0, sizeof(tmp)); - sqlite3Fts5BufferGrow(&p->rc, &out, p1->n + p2->n); + fts5BufferGrow(&p->rc, &out, p1->n + p2->n); fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); while( p->rc==SQLITE_OK && (i1.aPoslist!=0 || i2.aPoslist!=0) ){ @@ -4603,7 +4605,7 @@ int sqlite3Fts5IndexQuery( /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); - if( sqlite3Fts5BufferGrow(&p->rc, &buf, nToken+1)==0 ){ + if( fts5BufferGrow(&p->rc, &buf, nToken+1)==0 ){ memcpy(&buf.p[1], pToken, nToken); #ifdef SQLITE_DEBUG diff --git a/manifest b/manifest index 84b919c298..3418ca7815 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\stweak\sto\simprove\sperformance\sof\sfts5\sprefix\squeries. -D 2015-10-19T17:43:24.360 +C Another\soptimization\sfor\sfts5\sprefix\s(and\sother)\squeries. +D 2015-10-19T20:49:10.124 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -103,13 +103,13 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 -F ext/fts5/fts5Int.h 0332d12fdca0f4fe2231df71bd7544b3cef81122 +F ext/fts5/fts5Int.h db1d5a18bae953c749198fe6d87862055ef55a1d F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 -F ext/fts5/fts5_buffer.c 9a3aa73a4e7b26b1c805b9c92c1344ba3d19d2a8 +F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 8468e41855bba133107760badda415bc7f86c12c +F ext/fts5/fts5_index.c 38d7ddd4d5650007ee83000f0f96967ff83c710c F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 9b30115742b758706de70595a8d1d084e940c978 F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 68ee426a6432ac63655909ff70cb22bde33cf28c -R b1e8d85157aaa205dae46563b3080619 +P 69be427c864dc3de804ca3c5f1c6addcd33cd188 +R cf51e15890c7ae1ec9dc153fd0832e0a U dan -Z e2816fa336eec46724399248fb4f473f +Z 01b7158ec138174afd0e008584d0b467 diff --git a/manifest.uuid b/manifest.uuid index 833def65e8..4e22ea3ddd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69be427c864dc3de804ca3c5f1c6addcd33cd188 \ No newline at end of file +60a8bde055a960c5b8cb4e231802c75617c942d8 \ No newline at end of file From 3f9bfa740f6bd337a9e1620cfadd4be99c79ede8 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Oct 2015 15:49:02 +0000 Subject: [PATCH 22/55] Initialize variables in the fts5 integrity-check code to avoid compiler warnings. FossilOrigin-Name: e979e2cccac257ad554803e6a1103558b0f159d8 --- ext/fts5/fts5_storage.c | 4 ++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index ce38762cad..ff4aea50e1 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -914,12 +914,12 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ /* Check that the %_docsize and %_content tables contain the expected ** number of rows. */ if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ - i64 nRow; + i64 nRow = 0; rc = fts5StorageCount(p, "content", &nRow); if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; } if( rc==SQLITE_OK && pConfig->bColumnsize ){ - i64 nRow; + i64 nRow = 0; rc = fts5StorageCount(p, "docsize", &nRow); if( rc==SQLITE_OK && nRow!=p->nTotalRow ) rc = FTS5_CORRUPT; } diff --git a/manifest b/manifest index 3418ca7815..7f3a3228ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\soptimization\sfor\sfts5\sprefix\s(and\sother)\squeries. -D 2015-10-19T20:49:10.124 +C Initialize\svariables\sin\sthe\sfts5\sintegrity-check\scode\sto\savoid\scompiler\swarnings. +D 2015-10-20T15:49:02.194 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -111,7 +111,7 @@ F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f F ext/fts5/fts5_index.c 38d7ddd4d5650007ee83000f0f96967ff83c710c F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef -F ext/fts5/fts5_storage.c 9b30115742b758706de70595a8d1d084e940c978 +F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 69be427c864dc3de804ca3c5f1c6addcd33cd188 -R cf51e15890c7ae1ec9dc153fd0832e0a +P 60a8bde055a960c5b8cb4e231802c75617c942d8 +R 507ca9e6ed1f2a8dcb12d2eaeb7b0450 U dan -Z 01b7158ec138174afd0e008584d0b467 +Z c40a91b7d33ce0f422b5ec994684bd4f diff --git a/manifest.uuid b/manifest.uuid index 4e22ea3ddd..74827af32d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -60a8bde055a960c5b8cb4e231802c75617c942d8 \ No newline at end of file +e979e2cccac257ad554803e6a1103558b0f159d8 \ No newline at end of file From 9cc4ae6f2aec8b46201856dc5b33a381fbc9ee4d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Oct 2015 19:55:35 +0000 Subject: [PATCH 23/55] Fix #line directives added to generated file fts5.c. FossilOrigin-Name: 1f5f5804cd394a81b1c0712ce6d1052f228d0a40 --- ext/fts5/fts5_index.c | 38 ++++++++++++++++++-------------------- ext/fts5/tool/mkfts5c.tcl | 8 +++++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 19ea73ab96..927d0a94dc 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -374,26 +374,6 @@ struct Fts5SegWriter { int iBtPage; /* Page number corresponding to btterm */ }; -/* -** Object for iterating through the merged results of one or more segments, -** visiting each term/rowid pair in the merged data. -** -** nSeg is always a power of two greater than or equal to the number of -** segments that this object is merging data from. Both the aSeg[] and -** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded -** with zeroed objects - these are handled as if they were iterators opened -** on empty segments. -** -** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an -** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the -** comparison in this context is the index of the iterator that currently -** points to the smaller term/rowid combination. Iterators at EOF are -** considered to be greater than all other iterators. -** -** aFirst[1] contains the index in aSeg[] of the iterator that points to -** the smallest key overall. aFirst[0] is unused. -*/ - typedef struct Fts5CResult Fts5CResult; struct Fts5CResult { u16 iFirst; /* aSeg[] index of firstest iterator */ @@ -500,6 +480,24 @@ struct Fts5SegIter { #define fts5LeafFirstRowidOff(x) (fts5GetU16((x)->p)) /* +** Object for iterating through the merged results of one or more segments, +** visiting each term/rowid pair in the merged data. +** +** nSeg is always a power of two greater than or equal to the number of +** segments that this object is merging data from. Both the aSeg[] and +** aFirst[] arrays are sized at nSeg entries. The aSeg[] array is padded +** with zeroed objects - these are handled as if they were iterators opened +** on empty segments. +** +** The results of comparing segments aSeg[N] and aSeg[N+1], where N is an +** even number, is stored in aFirst[(nSeg+N)/2]. The "result" of the +** comparison in this context is the index of the iterator that currently +** points to the smaller term/rowid combination. Iterators at EOF are +** considered to be greater than all other iterators. +** +** aFirst[1] contains the index in aSeg[] of the iterator that points to +** the smallest key overall. aFirst[0] is unused. +** ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. diff --git a/ext/fts5/tool/mkfts5c.tcl b/ext/fts5/tool/mkfts5c.tcl index 535506de1b..797811d46e 100644 --- a/ext/fts5/tool/mkfts5c.tcl +++ b/ext/fts5/tool/mkfts5c.tcl @@ -78,7 +78,7 @@ proc fts5c_printfile {zIn} { global G set data [readfile $zIn] set zTail [file tail $zIn] - puts $G(fd) "#line 2 \"$zTail\"" + puts $G(fd) "#line 1 \"$zTail\"" set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]] if {$zTail=="fts5parse.c"} { @@ -86,8 +86,10 @@ proc fts5c_printfile {zIn} { } foreach line [split $data "\n"] { - if {[regexp {^#include.*fts5} $line]} continue - if { ![regexp { sqlite3Fts5Init\(} $line] + if {[regexp {^#include.*fts5} $line]} { + set line "/* $line */" + } elseif { + ![regexp { sqlite3Fts5Init\(} $line] && [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line] } { set line "static $line" diff --git a/manifest b/manifest index 7f3a3228ee..d0b4c559b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initialize\svariables\sin\sthe\sfts5\sintegrity-check\scode\sto\savoid\scompiler\swarnings. -D 2015-10-20T15:49:02.194 +C Fix\s#line\sdirectives\sadded\sto\sgenerated\sfile\sfts5.c. +D 2015-10-20T19:55:35.406 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 38d7ddd4d5650007ee83000f0f96967ff83c710c +F ext/fts5/fts5_index.c 903ca7a882d6f7ae4a08575b233fc95894daaf0b F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -183,7 +183,7 @@ F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0 F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84 F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3 -F ext/fts5/tool/mkfts5c.tcl 09ce6a7997440508360f5ba1651ab7e923a8bf31 +F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl 9eaf6c3df352f98a2ab5ce1921dd94128ab1381d F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c b2732aef0b076e4276d9b39b5a33cec7a05e1413 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 60a8bde055a960c5b8cb4e231802c75617c942d8 -R 507ca9e6ed1f2a8dcb12d2eaeb7b0450 +P e979e2cccac257ad554803e6a1103558b0f159d8 +R 44b3b756f766dbcb6a6fd920376ac78a U dan -Z c40a91b7d33ce0f422b5ec994684bd4f +Z 5fc3ef172eb8863d82203d5aa10e31b9 diff --git a/manifest.uuid b/manifest.uuid index 74827af32d..4e786e8270 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e979e2cccac257ad554803e6a1103558b0f159d8 \ No newline at end of file +1f5f5804cd394a81b1c0712ce6d1052f228d0a40 \ No newline at end of file From 219f4d48a2820cfdd3f7422892017a8b5755f07f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Oct 2015 21:05:53 +0000 Subject: [PATCH 24/55] More optimizations for fts5 prefix queries. FossilOrigin-Name: b8fb263ed1b36d085437131795505e53af103d26 --- ext/fts5/fts5_index.c | 38 +++++++++++++++++++++++++++++++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 927d0a94dc..6747b9387b 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2591,6 +2591,34 @@ static void fts5MultiIterNext( } } +static void fts5MultiIterNext2( + Fts5Index *p, + Fts5IndexIter *pIter, + int *pbNewTerm /* OUT: True if *might* be new term */ +){ + if( p->rc==SQLITE_OK ){ + do { + int iFirst = pIter->aFirst[1].iFirst; + Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + int bNewTerm = 0; + + fts5SegIterNext(p, pSeg, &bNewTerm); + if( pSeg->pLeaf==0 || bNewTerm + || fts5MultiIterAdvanceRowid(p, pIter, iFirst) + ){ + fts5MultiIterAdvanced(p, pIter, iFirst, 1); + fts5MultiIterSetEof(pIter); + *pbNewTerm = 1; + }else{ + *pbNewTerm = 0; + } + fts5AssertMultiIterSetup(p, pIter); + + }while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) ); + } +} + + static Fts5IndexIter *fts5MultiIterAlloc( Fts5Index *p, /* FTS5 backend to iterate within */ int nSeg @@ -4058,7 +4086,7 @@ static int fts5IndexExtractCol( const u8 *pEnd = &p[n]; /* One byte past end of position list */ u8 prev = 0; - while( iCol!=iCurrent ){ + while( iCol>iCurrent ){ /* Advance pointer p until it points to pEnd or an 0x01 byte that is ** not part of a varint */ while( (prev & 0x80) || *p!=0x01 ){ @@ -4068,6 +4096,7 @@ static int fts5IndexExtractCol( *pa = p++; p += fts5GetVarint32(p, iCurrent); } + if( iCol!=iCurrent ) return 0; /* Advance pointer p until it points to pEnd or an 0x01 byte that is ** not part of a varint */ @@ -4331,17 +4360,20 @@ static void fts5SetupPrefixIter( Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; Fts5Buffer doclist; + int bNewTerm; memset(&doclist, 0, sizeof(doclist)); for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1); fts5MultiIterEof(p, p1)==0; - fts5MultiIterNext(p, p1, 0, 0) + fts5MultiIterNext2(p, p1, &bNewTerm) ){ i64 iRowid = fts5MultiIterRowid(p1); int nTerm; const u8 *pTerm = fts5MultiIterTerm(p1, &nTerm); assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); - if( nTerm0 && iRowid<=iLastRowid ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ diff --git a/manifest b/manifest index d0b4c559b0..d75668e6c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\s#line\sdirectives\sadded\sto\sgenerated\sfile\sfts5.c. -D 2015-10-20T19:55:35.406 +C More\soptimizations\sfor\sfts5\sprefix\squeries. +D 2015-10-20T21:05:53.203 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 903ca7a882d6f7ae4a08575b233fc95894daaf0b +F ext/fts5/fts5_index.c 45856922243dc5f9d5bdc3b677d68e27997df600 F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e979e2cccac257ad554803e6a1103558b0f159d8 -R 44b3b756f766dbcb6a6fd920376ac78a +P 1f5f5804cd394a81b1c0712ce6d1052f228d0a40 +R 843f1263cb5ed99ae94cdac9953fa2b8 U dan -Z 5fc3ef172eb8863d82203d5aa10e31b9 +Z 0e003a47783a27c94ee2f0e7d256c7c6 diff --git a/manifest.uuid b/manifest.uuid index 4e786e8270..c7f268a7a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f5f5804cd394a81b1c0712ce6d1052f228d0a40 \ No newline at end of file +b8fb263ed1b36d085437131795505e53af103d26 \ No newline at end of file From 6d7734c27d3556568c828e999f65b0c9d2cbdb3f Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 20 Oct 2015 23:27:14 +0000 Subject: [PATCH 25/55] Fix harmless compiler warnings in FTS5. FossilOrigin-Name: 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5 --- ext/fts5/fts5_index.c | 2 +- ext/fts5/fts5_vocab.c | 8 ++++---- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 6747b9387b..1628018b48 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4360,7 +4360,7 @@ static void fts5SetupPrefixIter( Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; Fts5Buffer doclist; - int bNewTerm; + int bNewTerm = 0; memset(&doclist, 0, sizeof(doclist)); for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1); diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 80e3455900..1d13b9cd63 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -462,7 +462,7 @@ static int fts5VocabFilterMethod( sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; - int rc; + int rc = SQLITE_OK; int iVal = 0; int f = FTS5INDEX_QUERY_SCAN; @@ -479,16 +479,16 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; if( pEq ){ - zTerm = sqlite3_value_text(pEq); + zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); f = 0; }else{ if( pGe ){ - zTerm = sqlite3_value_text(pGe); + zTerm = (const char *)sqlite3_value_text(pGe); nTerm = sqlite3_value_bytes(pGe); } if( pLe ){ - const char *zCopy = sqlite3_value_text(pLe); + const char *zCopy = (const char *)sqlite3_value_text(pLe); pCsr->nLeTerm = sqlite3_value_bytes(pLe); pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); if( pCsr->zLeTerm==0 ){ diff --git a/manifest b/manifest index d75668e6c4..e406cb4dc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\soptimizations\sfor\sfts5\sprefix\squeries. -D 2015-10-20T21:05:53.203 +C Fix\sharmless\scompiler\swarnings\sin\sFTS5. +D 2015-10-20T23:27:14.365 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 45856922243dc5f9d5bdc3b677d68e27997df600 +F ext/fts5/fts5_index.c d3503c75d329f027140b855149566c97c078c18d F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -117,7 +117,7 @@ F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c 4bf7e418bd3f857c7aea8221fc2c159283d30c6b +F ext/fts5/fts5_vocab.c fc319264ebbf1b4518afd9cacd3801ac526536d8 F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 1f5f5804cd394a81b1c0712ce6d1052f228d0a40 -R 843f1263cb5ed99ae94cdac9953fa2b8 -U dan -Z 0e003a47783a27c94ee2f0e7d256c7c6 +P b8fb263ed1b36d085437131795505e53af103d26 +R 95702bd1633e56deaa7f0c8cd9294ab7 +U mistachkin +Z 2868708b35b26115fe25354e42651fac diff --git a/manifest.uuid b/manifest.uuid index c7f268a7a4..ea64a17af2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b8fb263ed1b36d085437131795505e53af103d26 \ No newline at end of file +0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5 \ No newline at end of file From 5c22e82a175b6015df5b6fe70eabec413fca8a23 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Oct 2015 08:26:01 +0000 Subject: [PATCH 26/55] Add extra debugging function to test_rbu.c. Enhance the documentation for sqlite3rbu_db() to define the validity of the returned database handles. FossilOrigin-Name: b9c4aa521156d8ca09151a82a7e80aa8d1d7a313 --- ext/rbu/sqlite3rbu.h | 3 +++ ext/rbu/test_rbu.c | 36 ++++++++++++++++++++++++++++++------ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/ext/rbu/sqlite3rbu.h b/ext/rbu/sqlite3rbu.h index 65d1c5f6e5..f1a0f3cd84 100644 --- a/ext/rbu/sqlite3rbu.h +++ b/ext/rbu/sqlite3rbu.h @@ -341,6 +341,9 @@ sqlite3rbu *sqlite3rbu_open( ** If an error has occurred, either while opening or stepping the RBU object, ** this function may return NULL. The error code and message may be collected ** when sqlite3rbu_close() is called. +** +** Database handles returned by this function remain valid until the next +** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db(). */ sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); diff --git a/ext/rbu/test_rbu.c b/ext/rbu/test_rbu.c index 6648f28e8b..3fa85b7569 100644 --- a/ext/rbu/test_rbu.c +++ b/ext/rbu/test_rbu.c @@ -56,20 +56,34 @@ static int test_sqlite3rbu_cmd( ){ int ret = TCL_OK; sqlite3rbu *pRbu = (sqlite3rbu*)clientData; - const char *azMethod[] = { - "step", "close", "create_rbu_delta", "savestate", 0 + struct RbuCmd { + const char *zName; + int nArg; + const char *zUsage; + } aCmd[] = { + {"step", 2, ""}, /* 0 */ + {"close", 2, ""}, /* 1 */ + {"create_rbu_delta", 2, ""}, /* 2 */ + {"savestate", 2, ""}, /* 3 */ + {"dbMain_eval", 3, "SQL"}, /* 4 */ + {0,0,0} }; - int iMethod; + int iCmd; - if( objc!=2 ){ + if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "METHOD"); return TCL_ERROR; } - if( Tcl_GetIndexFromObj(interp, objv[1], azMethod, "method", 0, &iMethod) ){ + ret = Tcl_GetIndexFromObjStruct( + interp, objv[1], aCmd, sizeof(aCmd[0]), "method", 0, &iCmd + ); + if( ret ) return TCL_ERROR; + if( objc!=aCmd[iCmd].nArg ){ + Tcl_WrongNumArgs(interp, 1, objv, aCmd[iCmd].zUsage); return TCL_ERROR; } - switch( iMethod ){ + switch( iCmd ){ case 0: /* step */ { int rc = sqlite3rbu_step(pRbu); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); @@ -112,6 +126,16 @@ static int test_sqlite3rbu_cmd( break; } + case 4: /* dbMain_eval */ { + sqlite3 *db = sqlite3rbu_db(pRbu, 0); + int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0); + if( rc!=SQLITE_OK ){ + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1)); + ret = TCL_ERROR; + } + break; + } + default: /* seems unlikely */ assert( !"cannot happen" ); break; diff --git a/manifest b/manifest index e406cb4dc0..05c2a89ea4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sFTS5. -D 2015-10-20T23:27:14.365 +C Add\sextra\sdebugging\sfunction\sto\stest_rbu.c.\sEnhance\sthe\sdocumentation\sfor\ssqlite3rbu_db()\sto\sdefine\sthe\svalidity\sof\sthe\sreturned\sdatabase\shandles. +D 2015-10-21T08:26:01.477 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -230,8 +230,8 @@ F ext/rbu/rbufault2.test 9a7f19edd6ea35c4c9f807d8a3db0a03a5670c06 F ext/rbu/rbufts.test 828cd689da825f0a7b7c53ffc1f6f7fdb6fa5bda F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48 F ext/rbu/sqlite3rbu.c ea47de615e911b3a69a8e7fb3be3866298403a25 -F ext/rbu/sqlite3rbu.h 1d568cb33738d7900975cc5c72e6f68049f15914 -F ext/rbu/test_rbu.c 2a3652241fa45d5eaa141775e4ae68c1d3582c03 +F ext/rbu/sqlite3rbu.h 0bdeb3be211aaba7d85445fa36f4701a25a3dbde +F ext/rbu/test_rbu.c 4a4cdcef4ef9379fc2a21f008805c80b27bcf573 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/rtree.c 0f9b595bd0debcbedf1d7a63d0e0678d619e6c9c F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8fb263ed1b36d085437131795505e53af103d26 -R 95702bd1633e56deaa7f0c8cd9294ab7 -U mistachkin -Z 2868708b35b26115fe25354e42651fac +P 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5 +R c0f5065bff60d0df79ae9d2bf6514716 +U dan +Z 2c0acb856eea548f945a4e7fa327a156 diff --git a/manifest.uuid b/manifest.uuid index ea64a17af2..c6965600bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5 \ No newline at end of file +b9c4aa521156d8ca09151a82a7e80aa8d1d7a313 \ No newline at end of file From f2c9995dbe5ea7bd4968e57ef8a3ce784c5667d2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Oct 2015 20:07:08 +0000 Subject: [PATCH 27/55] Minor optimization for fts5 queries. FossilOrigin-Name: 363b36d50b6f3e3d3e79c538be1167b071a5a710 --- ext/fts5/fts5_index.c | 9 ++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1628018b48..9e3a9e0ff7 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1828,7 +1828,14 @@ static void fts5SegIterNext( if( pbNewTerm ) *pbNewTerm = 1; } }else{ - fts5SegIterLoadNPos(p, pIter); + /* The following could be done by calling fts5SegIterLoadNPos(). But + ** this block is particularly performance critical, so equivalent + ** code is inlined. */ + int nSz; + assert( p->rc==SQLITE_OK ); + fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); + pIter->bDel = (nSz & 0x0001); + pIter->nPos = nSz>>1; } } } diff --git a/manifest b/manifest index 05c2a89ea4..a9a1d123ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\sdebugging\sfunction\sto\stest_rbu.c.\sEnhance\sthe\sdocumentation\sfor\ssqlite3rbu_db()\sto\sdefine\sthe\svalidity\sof\sthe\sreturned\sdatabase\shandles. -D 2015-10-21T08:26:01.477 +C Minor\soptimization\sfor\sfts5\squeries. +D 2015-10-21T20:07:08.658 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c d3503c75d329f027140b855149566c97c078c18d +F ext/fts5/fts5_index.c 47ef0002b49b1dba5d5a49c8f2b02160a146a4ff F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 0a903ec26bfbbe9bfd18bc34934e689ffdb01ce5 -R c0f5065bff60d0df79ae9d2bf6514716 +P b9c4aa521156d8ca09151a82a7e80aa8d1d7a313 +R 4d88206e8c01136d0ea377b3eae363fe U dan -Z 2c0acb856eea548f945a4e7fa327a156 +Z 08a5e9e12273e463d7b7c3c870bc7777 diff --git a/manifest.uuid b/manifest.uuid index c6965600bc..cac1a13281 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9c4aa521156d8ca09151a82a7e80aa8d1d7a313 \ No newline at end of file +363b36d50b6f3e3d3e79c538be1167b071a5a710 \ No newline at end of file From 99b25309d064198001d6d619e3581109c671e503 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Oct 2015 20:56:27 +0000 Subject: [PATCH 28/55] Remove some branches made unreachable by recent changes from fts5. FossilOrigin-Name: ae350bfbfd59f912c469a51bf7d1409f3c8d958a --- ext/fts5/fts5Int.h | 2 -- ext/fts5/fts5_buffer.c | 6 ------ ext/fts5/fts5_index.c | 48 ++++++++++++++++++++++++------------------ manifest | 16 +++++++------- manifest.uuid | 2 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index b6c498fc3f..76b3ac3928 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -233,7 +233,6 @@ void sqlite3Fts5BufferFree(Fts5Buffer*); void sqlite3Fts5BufferZero(Fts5Buffer*); void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*); void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); -void sqlite3Fts5BufferAppend32(int*, Fts5Buffer*, int); char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); @@ -242,7 +241,6 @@ char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferFree(a) sqlite3Fts5BufferFree(a) #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) -#define fts5BufferAppend32(a,b,c) sqlite3Fts5BufferAppend32(a,b,c) #define fts5BufferGrow(pRc,pBuf,nn) ( \ (pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \ diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index bb64ce70d1..e9aab4622a 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -53,12 +53,6 @@ int sqlite3Fts5Get32(const u8 *aBuf){ return (aBuf[0] << 24) + (aBuf[1] << 16) + (aBuf[2] << 8) + aBuf[3]; } -void sqlite3Fts5BufferAppend32(int *pRc, Fts5Buffer *pBuf, int iVal){ - if( fts5BufferGrow(pRc, pBuf, 4) ) return; - sqlite3Fts5Put32(&pBuf->p[pBuf->n], iVal); - pBuf->n += 4; -} - /* ** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set ** the error code in p. If an error has already occurred when this function diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 9e3a9e0ff7..6285fa9af3 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1006,6 +1006,18 @@ static int fts5StructureCountSegments(Fts5Structure *pStruct){ } #endif +#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \ + assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \ + memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \ + (pBuf)->n += nBlob; \ +} + +#define fts5BufferSafeAppendVarint(pBuf, iVal) { \ + (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \ + assert( (pBuf)->nSpace>=(pBuf)->n ); \ +} + + /* ** Serialize and store the "structure" record. ** @@ -1024,11 +1036,14 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ /* Append the current configuration cookie */ iCookie = p->pConfig->iCookie; if( iCookie<0 ) iCookie = 0; - fts5BufferAppend32(&p->rc, &buf, iCookie); - fts5BufferAppendVarint(&p->rc, &buf, pStruct->nLevel); - fts5BufferAppendVarint(&p->rc, &buf, pStruct->nSegment); - fts5BufferAppendVarint(&p->rc, &buf, (i64)pStruct->nWriteCounter); + if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ + sqlite3Fts5Put32(buf.p, iCookie); + buf.n = 4; + fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); + fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); + fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter); + } for(iLvl=0; iLvlnLevel; iLvl++){ int iSeg; /* Used to iterate through segments */ @@ -2603,6 +2618,7 @@ static void fts5MultiIterNext2( Fts5IndexIter *pIter, int *pbNewTerm /* OUT: True if *might* be new term */ ){ + assert( pIter->bSkipEmpty ); if( p->rc==SQLITE_OK ){ do { int iFirst = pIter->aFirst[1].iFirst; @@ -2621,7 +2637,7 @@ static void fts5MultiIterNext2( } fts5AssertMultiIterSetup(p, pIter); - }while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) ); + }while( fts5MultiIterIsEmpty(p, pIter) ); } } @@ -3379,9 +3395,12 @@ static void fts5WriteInit( pWriter->bFirstTermInPage = 1; pWriter->iBtPage = 1; + assert( pWriter->writer.buf.n==0 ); + assert( pWriter->writer.pgidx.n==0 ); + /* Grow the two buffers to pgsz + padding bytes in size. */ - fts5BufferGrow(&p->rc, &pWriter->writer.pgidx, nBuffer); - fts5BufferGrow(&p->rc, &pWriter->writer.buf, nBuffer); + sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer); + sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer); if( p->pIdxWriter==0 ){ Fts5Config *pConfig = p->pConfig; @@ -3734,17 +3753,6 @@ static int fts5PoslistPrefix(const u8 *aBuf, int nMax){ return ret; } -#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \ - assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) ); \ - memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob); \ - (pBuf)->n += nBlob; \ -} - -#define fts5BufferSafeAppendVarint(pBuf, iVal) { \ - (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \ - assert( (pBuf)->nSpace>=(pBuf)->n ); \ -} - /* ** Flush the contents of in-memory hash table iHash to a new level-0 ** segment on disk. Also update the corresponding structure record. @@ -4276,7 +4284,7 @@ static void fts5MergePrefixLists( memset(&out, 0, sizeof(out)); memset(&tmp, 0, sizeof(tmp)); - fts5BufferGrow(&p->rc, &out, p1->n + p2->n); + sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); while( p->rc==SQLITE_OK && (i1.aPoslist!=0 || i2.aPoslist!=0) ){ @@ -4642,7 +4650,7 @@ int sqlite3Fts5IndexQuery( /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); - if( fts5BufferGrow(&p->rc, &buf, nToken+1)==0 ){ + if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ memcpy(&buf.p[1], pToken, nToken); #ifdef SQLITE_DEBUG diff --git a/manifest b/manifest index a9a1d123ff..53c1c13210 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\soptimization\sfor\sfts5\squeries. -D 2015-10-21T20:07:08.658 +C Remove\ssome\sbranches\smade\sunreachable\sby\srecent\schanges\sfrom\sfts5. +D 2015-10-21T20:56:27.613 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e @@ -103,13 +103,13 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 -F ext/fts5/fts5Int.h db1d5a18bae953c749198fe6d87862055ef55a1d +F ext/fts5/fts5Int.h dfe8390b65e84846e1bd7a2fccc076d350e83f8a F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 -F ext/fts5/fts5_buffer.c 6d4082daa71eef87812b8caa9d60ae57a6a9ebc0 +F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 47ef0002b49b1dba5d5a49c8f2b02160a146a4ff +F ext/fts5/fts5_index.c ffb95101cab310700ccedd641f4ac8a92b1bace8 F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b9c4aa521156d8ca09151a82a7e80aa8d1d7a313 -R 4d88206e8c01136d0ea377b3eae363fe +P 363b36d50b6f3e3d3e79c538be1167b071a5a710 +R 78a6349126aa9306d06a1fd8711337ce U dan -Z 08a5e9e12273e463d7b7c3c870bc7777 +Z 67153b352bb25ea8149714857c236ba9 diff --git a/manifest.uuid b/manifest.uuid index cac1a13281..621961a6e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -363b36d50b6f3e3d3e79c538be1167b071a5a710 \ No newline at end of file +ae350bfbfd59f912c469a51bf7d1409f3c8d958a \ No newline at end of file From 1dfaa5c4b2688da792baeb07cba5bc744b9894fe Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 21 Oct 2015 22:07:25 +0000 Subject: [PATCH 29/55] Fix compilation of 'testfixture' with MSVC when the FTS5 and JSON1 extensions are enabled. FossilOrigin-Name: e31aa97a9298e49507256036cfb8fa7517a48461 --- Makefile.msc | 2 -- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 63fbfad6ca..408073c651 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1084,11 +1084,9 @@ TESTEXT = \ $(TOP)\ext\misc\eval.c \ $(TOP)\ext\misc\fileio.c \ $(TOP)\ext\misc\fuzzer.c \ - fts5.c \ $(TOP)\ext\fts5\fts5_tcl.c \ $(TOP)\ext\fts5\fts5_test_mi.c \ $(TOP)\ext\misc\ieee754.c \ - $(TOP)\ext\misc\json1.c \ $(TOP)\ext\misc\nextchar.c \ $(TOP)\ext\misc\percentile.c \ $(TOP)\ext\misc\regexp.c \ diff --git a/manifest b/manifest index 53c1c13210..7f4be2d02f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Remove\ssome\sbranches\smade\sunreachable\sby\srecent\schanges\sfrom\sfts5. -D 2015-10-21T20:56:27.613 +C Fix\scompilation\sof\s'testfixture'\swith\sMSVC\swhen\sthe\sFTS5\sand\sJSON1\sextensions\sare\senabled. +D 2015-10-21T22:07:25.256 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 4eb750e0fdf52050a06d881e1b060f4bb116ed7e +F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION a47917b59f38b632b3a8662d14fd20f94956bdd0 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 363b36d50b6f3e3d3e79c538be1167b071a5a710 -R 78a6349126aa9306d06a1fd8711337ce -U dan -Z 67153b352bb25ea8149714857c236ba9 +P ae350bfbfd59f912c469a51bf7d1409f3c8d958a +R 94370da87418177dbfd07035771f078a +U mistachkin +Z b64a69f65dcbfbb052541ed7b4c602d1 diff --git a/manifest.uuid b/manifest.uuid index 621961a6e3..fdefa58cb3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae350bfbfd59f912c469a51bf7d1409f3c8d958a \ No newline at end of file +e31aa97a9298e49507256036cfb8fa7517a48461 \ No newline at end of file From 16158eeb49f6de3a373cae5b41a4bbf3976432d7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 21 Oct 2015 22:08:36 +0000 Subject: [PATCH 30/55] Fix harmless compiler warnings in FTS5. FossilOrigin-Name: aa4e01ea1af327d1f8398ebea1c5bacc46698c3d --- ext/fts5/fts5Int.h | 1 - ext/fts5/fts5_index.c | 4 ++++ ext/fts5/fts5_vocab.c | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 76b3ac3928..8626962067 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -225,7 +225,6 @@ struct Fts5Buffer { }; int sqlite3Fts5BufferSize(int*, Fts5Buffer*, int); -int sqlite3Fts5BufferGrow(int*, Fts5Buffer*, int); void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, int, const u8*); void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 6285fa9af3..e70bc85351 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5335,9 +5335,11 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ Fts5IndexIter *pIter; /* Used to iterate through entire index */ Fts5Structure *pStruct; /* Index structure */ +#ifdef SQLITE_DEBUG /* Used by extra internal tests only run if NDEBUG is not defined */ u64 cksum3 = 0; /* Checksum based on contents of indexes */ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ +#endif /* Load the FTS index structure */ pStruct = fts5StructureRead(p); @@ -5393,7 +5395,9 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT; fts5StructureRelease(pStruct); +#ifdef SQLITE_DEBUG fts5BufferFree(&term); +#endif fts5BufferFree(&poslist); return fts5IndexReturn(p); } diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 1d13b9cd63..860cfedb9b 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -180,7 +180,7 @@ static int fts5VocabInitVtab( const char *zType = bDb ? argv[5] : argv[4]; int nDb = (int)strlen(zDb)+1; int nTab = (int)strlen(zTab)+1; - int eType; + int eType = 0; rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ diff --git a/manifest b/manifest index 7f4be2d02f..253f2f9505 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scompilation\sof\s'testfixture'\swith\sMSVC\swhen\sthe\sFTS5\sand\sJSON1\sextensions\sare\senabled. -D 2015-10-21T22:07:25.256 +C Fix\sharmless\scompiler\swarnings\sin\sFTS5. +D 2015-10-21T22:08:36.772 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -103,13 +103,13 @@ F ext/fts3/unicode/mkunicode.tcl 95cf7ec186e48d4985e433ff8a1c89090a774252 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 8b9a13b309b180e9fb88ea5666c0d8d73c6102d9 -F ext/fts5/fts5Int.h dfe8390b65e84846e1bd7a2fccc076d350e83f8a +F ext/fts5/fts5Int.h 06594fd3e5a3c74da6df9141e165975dc0ea6ef4 F ext/fts5/fts5_aux.c 1f384972d606375b8fa078319f25ab4b5feb1b35 F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c ffb95101cab310700ccedd641f4ac8a92b1bace8 +F ext/fts5/fts5_index.c 2bd3cb65b36160f7b411e70c4360d0619c965e4e F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -117,7 +117,7 @@ F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c fc319264ebbf1b4518afd9cacd3801ac526536d8 +F ext/fts5/fts5_vocab.c 3742d0abfe8aa8c3cb4a7df56aa38f2e3c3fb1c2 F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P ae350bfbfd59f912c469a51bf7d1409f3c8d958a -R 94370da87418177dbfd07035771f078a +P e31aa97a9298e49507256036cfb8fa7517a48461 +R 606f7dfef62137a51a41fcb520dc155f U mistachkin -Z b64a69f65dcbfbb052541ed7b4c602d1 +Z be7e8557e6be3b3a5f61a53f0769e842 diff --git a/manifest.uuid b/manifest.uuid index fdefa58cb3..0399ec5e0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e31aa97a9298e49507256036cfb8fa7517a48461 \ No newline at end of file +aa4e01ea1af327d1f8398ebea1c5bacc46698c3d \ No newline at end of file From 7ef855f156175964bb2d193208776044144b8f32 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 22 Oct 2015 18:06:40 +0000 Subject: [PATCH 31/55] Alternate compiler warning fix for sqlite3StatusHighwater. FossilOrigin-Name: 4315d20200d578c9252dcb26e60739063a8eff1d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/status.c | 21 ++++++++++++--------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 253f2f9505..9f8c896ecd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sFTS5. -D 2015-10-21T22:08:36.772 +C Alternate\scompiler\swarning\sfix\sfor\ssqlite3StatusHighwater. +D 2015-10-22T18:06:40.381 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -345,7 +345,7 @@ F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 -F src/status.c 286f6398a4d2cd1e8ff0771e3d30f8dddb4768ea +F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e31aa97a9298e49507256036cfb8fa7517a48461 -R 606f7dfef62137a51a41fcb520dc155f +P aa4e01ea1af327d1f8398ebea1c5bacc46698c3d +R a22db3919509c137f252ea9c4c395816 U mistachkin -Z be7e8557e6be3b3a5f61a53f0769e842 +Z cd96591ebe18ee957344d1fc4f75aaa9 diff --git a/manifest.uuid b/manifest.uuid index 0399ec5e0b..48569933f6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aa4e01ea1af327d1f8398ebea1c5bacc46698c3d \ No newline at end of file +4315d20200d578c9252dcb26e60739063a8eff1d \ No newline at end of file diff --git a/src/status.c b/src/status.c index a7fddf060f..69f92ff7c6 100644 --- a/src/status.c +++ b/src/status.c @@ -19,15 +19,15 @@ /* ** Variables in which to record status information. */ +#if SQLITE_PTRSIZE>4 +typedef sqlite3_int64 sqlite3StatValueType; +#else +typedef u32 sqlite3StatValueType; +#endif typedef struct sqlite3StatType sqlite3StatType; static SQLITE_WSD struct sqlite3StatType { -#if SQLITE_PTRSIZE>4 - sqlite3_int64 nowValue[10]; /* Current value */ - sqlite3_int64 mxValue[10]; /* Maximum value */ -#else - u32 nowValue[10]; /* Current value */ - u32 mxValue[10]; /* Maximum value */ -#endif + sqlite3StatValueType nowValue[10]; /* Current value */ + sqlite3StatValueType mxValue[10]; /* Maximum value */ } sqlite3Stat = { {0,}, {0,} }; /* @@ -112,7 +112,10 @@ void sqlite3StatusDown(int op, int N){ ** The caller must hold the appropriate mutex. */ void sqlite3StatusHighwater(int op, int X){ + sqlite3StatValueType newValue; wsdStatInit; + assert( X>=0 ); + newValue = (sqlite3StatValueType)X; assert( op>=0 && op=0 && opwsdStat.mxValue[op] ){ - wsdStat.mxValue[op] = X; + if( newValue>wsdStat.mxValue[op] ){ + wsdStat.mxValue[op] = newValue; } } From fd261ec67efbb3a6e1c22f55f0999bae224ebce6 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Oct 2015 20:54:33 +0000 Subject: [PATCH 32/55] Modifications to pass a flag to internal routine sqlite3BtreeCursor() when a cursor that is used solely for deleting b-tree entries, or for obtaining the components of keys to delete from other b-trees, is opened. FossilOrigin-Name: cdc92919e600007cae5eb61223684f48a65babc0 --- manifest | 38 +++++++++++---------- manifest.uuid | 2 +- src/btree.c | 10 +++--- src/btree.h | 6 ++++ src/delete.c | 5 +-- src/insert.c | 5 ++- src/pragma.c | 2 +- src/sqliteInt.h | 5 +-- src/test3.c | 1 + src/update.c | 2 +- src/vdbe.c | 8 ++--- src/where.c | 9 +++-- src/whereInt.h | 1 + test/fordelete.test | 80 +++++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 139 insertions(+), 35 deletions(-) create mode 100644 test/fordelete.test diff --git a/manifest b/manifest index 9f8c896ecd..24f91f41c7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Alternate\scompiler\swarning\sfix\sfor\ssqlite3StatusHighwater. -D 2015-10-22T18:06:40.381 +C Modifications\sto\spass\sa\sflag\sto\sinternal\sroutine\ssqlite3BtreeCursor()\swhen\sa\scursor\sthat\sis\sused\ssolely\sfor\sdeleting\sb-tree\sentries,\sor\sfor\sobtaining\sthe\scomponents\sof\skeys\sto\sdelete\sfrom\sother\sb-trees,\sis\sopened. +D 2015-10-22T20:54:33.626 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -280,8 +280,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c ea8c62f65e57e49bd6b0988cd681aca7246b51af -F src/btree.h 40189aefdc2b830d25c8b58fd7d56538481bfdd7 +F src/btree.c 9d684e19f84633323de7a767da2e2b8cf51fa600 +F src/btree.h ccc489437299e48ba5f7d957baa686a9adf2d1ba F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -289,7 +289,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7 -F src/delete.c 35c939eb8bacc9dd8a6715964e5f69feb8c20e44 +F src/delete.c c4c6fb9da78b946fcba2a6aac5b24bc5c15e752a F src/expr.c d9896fda47a8f67d0ed203e1fa981444424200c6 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 @@ -298,7 +298,7 @@ F src/global.c 508e4087f7b41d688e4762dcf4d4fe28cfbc87f9 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 6dadbb671c2cc035ddbbf11a0b0209185d5bfe2c +F src/insert.c 419a947f27ce2da18eebf440a5aa80cc825defae F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 @@ -331,7 +331,7 @@ F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7 F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035 -F src/pragma.c dcfe3a35d2de935feeaba1455528b4a5c4f1208c +F src/pragma.c 8fd4c8a12e25f0d916426f160255ebe25415eba7 F src/pragma.h 631a91c8b0e6ca8f051a1d8a4a0da4150e04620a F src/prepare.c 82e5db1013846a819f198336fed72c44c974e7b1 F src/printf.c 0c4bcdd1c2e2521024f0a69cb5eb334f86b3652a @@ -343,14 +343,14 @@ F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 -F src/sqliteInt.h 1ad779ee62efee60494af0a75d8d45592f9f53c3 +F src/sqliteInt.h 835fce874a55144491d441f22c21a954bd17a1f3 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d -F src/test3.c 64d2afdd68feac1bb5e2ffb8226c8c639f798622 +F src/test3.c 11b13d561846e5d1ffd29653be340d2f4b59a723 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 @@ -397,11 +397,11 @@ F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 338bc8f7c9dd103188952cda7964696bacac6d22 F src/treeview.c 154f0acc622fa3514de8777dcedf4c8a8802b4ce F src/trigger.c 322f23aad694e8f31d384dcfa386d52a48d3c52f -F src/update.c aa10336a2719bd1b9f89004f3d7ba6d566623a49 +F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c e9315575bed64f9aa559151283c873be34143914 +F src/vdbe.c 3f22833a67dbee98f5b8d7acac0f5097ecc4dcb5 F src/vdbe.h 4bc88bd0e06f8046ee6ab7487c0015e85ad949ad F src/vdbeInt.h 777dd76d513347acb1a71d94df2be00516add637 F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca @@ -415,8 +415,8 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844 -F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 +F src/where.c 0bb01a0545afb9ee064d64e4821f34a79742a6cf +F src/whereInt.h 87b0b66cf0a337c8b282a33e4233e9dad14b626b F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3 F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -628,6 +628,7 @@ F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 +F test/fordelete.test a30de567eb69a377e0c3ab1a8be4d74588de2a33 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -1391,7 +1392,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P aa4e01ea1af327d1f8398ebea1c5bacc46698c3d -R a22db3919509c137f252ea9c4c395816 -U mistachkin -Z cd96591ebe18ee957344d1fc4f75aaa9 +P 4315d20200d578c9252dcb26e60739063a8eff1d +R f9b9301d7918e2f3aec8c2ac058ff295 +T *branch * btree-fordelete-flag +T *sym-btree-fordelete-flag * +T -sym-trunk * +U dan +Z 49648c9fd09be094288b39d12da5947c diff --git a/manifest.uuid b/manifest.uuid index 48569933f6..ed6782c8b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4315d20200d578c9252dcb26e60739063a8eff1d \ No newline at end of file +cdc92919e600007cae5eb61223684f48a65babc0 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b26a95c801..4ebaf4c271 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4055,13 +4055,16 @@ static int btreeCursor( BtCursor *pX; /* Looping over other all cursors */ assert( sqlite3BtreeHoldsMutex(p) ); - assert( wrFlag==0 || wrFlag==1 ); + assert( wrFlag==0 + || wrFlag==BTREE_WRCSR + || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) + ); /* The following assert statements verify that if this is a sharable ** b-tree database, the connection is holding the required table locks, ** and that no other connection has any open cursor that conflicts with ** this lock. */ - assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) ); + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) ); assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); /* Assert that the caller has opened the required transaction. */ @@ -4086,8 +4089,7 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - assert( wrFlag==0 || wrFlag==BTCF_WriteFlag ); - pCur->curFlags = wrFlag; + pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY; /* If there are two or more cursors on the same btree, then all such ** cursors *must* have the BTCF_Multiple flag set. */ diff --git a/src/btree.h b/src/btree.h index f7e92a2609..66420f8413 100644 --- a/src/btree.h +++ b/src/btree.h @@ -165,6 +165,12 @@ int sqlite3BtreeNewDb(Btree *p); #define BTREE_BULKLOAD 0x00000001 /* Used to full index in sorted order */ #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ +/* +** Flags passed as the third argument to sqlite3BtreeCursor(). +*/ +#define BTREE_WRCSR 0x00000004 /* read-write cursor */ +#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ + int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ diff --git a/src/delete.c b/src/delete.c index faef3a814e..cd683e37d8 100644 --- a/src/delete.c +++ b/src/delete.c @@ -478,12 +478,13 @@ void sqlite3DeleteFrom( */ if( !isView ){ int iAddrOnce = 0; + u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE); if( eOnePass==ONEPASS_MULTI ){ iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v); } testcase( IsVirtual(pTab) ); - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, - &iDataCur, &iIdxCur); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur, + aToOpen, &iDataCur, &iIdxCur); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); diff --git a/src/insert.c b/src/insert.c index 9274b0771d..3d213a8d37 100644 --- a/src/insert.c +++ b/src/insert.c @@ -762,7 +762,7 @@ void sqlite3Insert( /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; - nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0, + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ @@ -1650,6 +1650,7 @@ int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ int op, /* OP_OpenRead or OP_OpenWrite */ + u8 p5, /* P5 value for OP_Open* instructions */ int iBase, /* Use this for the table cursor, if there is one */ u8 *aToOpen, /* If not NULL: boolean for each table and index */ int *piDataCur, /* Write the database source cursor number here */ @@ -1662,6 +1663,7 @@ int sqlite3OpenTableAndIndices( Vdbe *v; assert( op==OP_OpenRead || op==OP_OpenWrite ); + assert( op==OP_OpenWrite || p5==0 ); if( IsVirtual(pTab) ){ /* This routine is a no-op for virtual tables. Leave the output ** variables *piDataCur and *piIdxCur uninitialized so that valgrind @@ -1689,6 +1691,7 @@ int sqlite3OpenTableAndIndices( if( aToOpen==0 || aToOpen[i+1] ){ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeChangeP5(v, p5); VdbeComment((v, "%s", pIdx->zName)); } } diff --git a/src/pragma.c b/src/pragma.c index 64614a7ebc..14c4811746 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1465,7 +1465,7 @@ void sqlite3Pragma( sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9c28a9a8c1..7d01305964 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2794,7 +2794,8 @@ struct AuthContext { #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ -#define OPFLAG_P2ISREG 0x04 /* P2 to OP_Open** is a register number */ +#define OPFLAG_FORDELETE 0x08 /* OP_Open is opening for-delete csr */ +#define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ /* @@ -3460,7 +3461,7 @@ void sqlite3ResolvePartIdxLabel(Parse*,int); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*); void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); -int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); +int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); void sqlite3BeginWriteOperation(Parse*, int, int); void sqlite3MultiWrite(Parse*); void sqlite3MayAbort(Parse*); diff --git a/src/test3.c b/src/test3.c index 07d12d28c0..7cb29bedcb 100644 --- a/src/test3.c +++ b/src/test3.c @@ -214,6 +214,7 @@ static int btree_cursor( pBt = sqlite3TestTextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR; + if( wrFlag ) wrFlag = BTREE_WRCSR; pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize()); memset(pCur, 0, sqlite3BtreeCursorSize()); sqlite3BtreeEnter(pBt); diff --git a/src/update.c b/src/update.c index 5cb5574909..1335c269ed 100644 --- a/src/update.c +++ b/src/update.c @@ -429,7 +429,7 @@ void sqlite3Update( if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; } - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen, + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, 0, 0); } diff --git a/src/vdbe.c b/src/vdbe.c index b93ab160f6..9b391c14d2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3324,7 +3324,6 @@ case OP_ReopenIdx: { case OP_OpenRead: case OP_OpenWrite: - assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 ); assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ ); assert( p->bIsReader ); assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx @@ -3345,7 +3344,8 @@ case OP_OpenWrite: pX = pDb->pBt; assert( pX!=0 ); if( pOp->opcode==OP_OpenWrite ){ - wrFlag = 1; + assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); + wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; @@ -3465,11 +3465,11 @@ case OP_OpenEphemeral: { assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); pCx->pKeyInfo = pKeyInfo; - rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, pKeyInfo, pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, pgno, BTREE_WRCSR, pKeyInfo, pCx->pCursor); } pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); + rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, BTREE_WRCSR, 0, pCx->pCursor); pCx->isTable = 1; } } diff --git a/src/where.c b/src/where.c index af8e2f35fd..3f83511b04 100644 --- a/src/where.c +++ b/src/where.c @@ -3991,6 +3991,7 @@ WhereInfo *sqlite3WhereBegin( int ii; /* Loop counter */ sqlite3 *db; /* Database connection */ int rc; /* Return code */ + u8 bFordelete = 0; assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 @@ -4246,8 +4247,11 @@ WhereInfo *sqlite3WhereBegin( && 0==(wsFlags & WHERE_VIRTUALTABLE) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; - if( HasRowid(pTabList->a[0].pTab) ){ - pWInfo->a[0].pWLoop->wsFlags &= ~WHERE_IDX_ONLY; + if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ + if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){ + bFordelete = OPFLAG_FORDELETE; + } + pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY); } } } @@ -4284,6 +4288,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->aiCurOnePass[0] = pTabItem->iCursor; }; sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + sqlite3VdbeChangeP5(v, bFordelete); assert( pTabItem->iCursor==pLevel->iTabCur ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); diff --git a/src/whereInt.h b/src/whereInt.h index cae09acc82..f4bc4077e4 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -530,3 +530,4 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ +#define WHERE_FORDELETE 0x00040000 /* Table cursor is "for-delete" */ diff --git a/test/fordelete.test b/test/fordelete.test new file mode 100644 index 0000000000..dd0f953310 --- /dev/null +++ b/test/fordelete.test @@ -0,0 +1,80 @@ +# 2001 September 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the SELECT statement. +# +# $Id: select1.test,v 1.70 2009/05/28 01:00:56 drh Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix fordelete + +# This function returns a list of the tables or indexes opened with +# OP_OpenWrite instructions when the SQL statement passed as the only +# argument is executed. If the OPFLAG_FORDELETE flag is specified on +# the OP_OpenWrite, an asterix is appended to the object name. The list +# is sorted in [lsort] order before it is returned. +# +proc analyze_delete_program {sql} { + # Build a map from root page to table/index name. + db eval { + SELECT name, rootpage FROM sqlite_master + } { + set T($rootpage) $name + } + + # Calculate the results. + set res [list] + db eval "EXPLAIN $sql" R { + if {$R(opcode) == "OpenWrite"} { + set obj $T($R(p2)) + if {"0x$R(p5)" & 0x08} { append obj *} + lappend res $obj + } + } + + lsort $res +} + +proc do_adp_test {tn sql res} { + uplevel [list do_test $tn [list analyze_delete_program $sql] [list {*}$res]] +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); +} + +foreach {tn sql res} { + 1 { DELETE FROM t1 WHERE a=?} { sqlite_autoindex_t1_1 t1* } + 2 { DELETE FROM t1 WHERE a=? AND b=? } { sqlite_autoindex_t1_1 t1 } + 3 { DELETE FROM t1 WHERE a>? } { sqlite_autoindex_t1_1 t1* } + 4 { DELETE FROM t1 WHERE rowid=? } { sqlite_autoindex_t1_1* t1 } +} { + do_adp_test 1.$tn $sql $res +} + +do_execsql_test 2.0 { + CREATE TABLE t2(a, b, c); + CREATE INDEX t2a ON t2(a); + CREATE INDEX t2b ON t2(b); + CREATE INDEX t2c ON t2(c); +} +foreach {tn sql res} { + 1 { DELETE FROM t2 WHERE a=?} { t2* t2a t2b* t2c* } + 2 { DELETE FROM t2 WHERE a=? AND +b=?} { t2 t2a t2b* t2c* } + 3 { DELETE FROM t2 WHERE a=? OR b=?} { t2 t2a* t2b* t2c* } + 4 { DELETE FROM t2 WHERE +a=? } { t2 t2a* t2b* t2c* } + 5 { DELETE FROM t2 WHERE rowid=? } { t2 t2a* t2b* t2c* } +} { + do_adp_test 2.$tn $sql $res +} + +finish_test From 2b4e95226c5ecff77baec79ff9da567bdbd73f77 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 23 Oct 2015 11:50:23 +0000 Subject: [PATCH 33/55] Remove an unused #define from whereInt.h. Add comments describing the new sqlite3BtreeCursor() flags. FossilOrigin-Name: 4c0ba8be43bb7c7100456bd8cd6921c164be31e1 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/btree.h | 14 ++++++++++++-- src/whereInt.h | 1 - 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 24f91f41c7..6617a2ff55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modifications\sto\spass\sa\sflag\sto\sinternal\sroutine\ssqlite3BtreeCursor()\swhen\sa\scursor\sthat\sis\sused\ssolely\sfor\sdeleting\sb-tree\sentries,\sor\sfor\sobtaining\sthe\scomponents\sof\skeys\sto\sdelete\sfrom\sother\sb-trees,\sis\sopened. -D 2015-10-22T20:54:33.626 +C Remove\san\sunused\s#define\sfrom\swhereInt.h.\sAdd\scomments\sdescribing\sthe\snew\ssqlite3BtreeCursor()\sflags. +D 2015-10-23T11:50:23.745 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -281,7 +281,7 @@ F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 F src/btree.c 9d684e19f84633323de7a767da2e2b8cf51fa600 -F src/btree.h ccc489437299e48ba5f7d957baa686a9adf2d1ba +F src/btree.h cf936d962b3f4179948d53ea58f3580de9b2ed0c F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -416,7 +416,7 @@ F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 0bb01a0545afb9ee064d64e4821f34a79742a6cf -F src/whereInt.h 87b0b66cf0a337c8b282a33e4233e9dad14b626b +F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3 F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1392,10 +1392,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4315d20200d578c9252dcb26e60739063a8eff1d -R f9b9301d7918e2f3aec8c2ac058ff295 -T *branch * btree-fordelete-flag -T *sym-btree-fordelete-flag * -T -sym-trunk * +P cdc92919e600007cae5eb61223684f48a65babc0 +R 372ed0826353f0987c018dd56c7ed9e6 U dan -Z 49648c9fd09be094288b39d12da5947c +Z 7d97368360f9df42d106befc4db01e49 diff --git a/manifest.uuid b/manifest.uuid index ed6782c8b4..cd45c7b9d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cdc92919e600007cae5eb61223684f48a65babc0 \ No newline at end of file +4c0ba8be43bb7c7100456bd8cd6921c164be31e1 \ No newline at end of file diff --git a/src/btree.h b/src/btree.h index 66420f8413..a0e2e33d4b 100644 --- a/src/btree.h +++ b/src/btree.h @@ -167,9 +167,19 @@ int sqlite3BtreeNewDb(Btree *p); /* ** Flags passed as the third argument to sqlite3BtreeCursor(). +** +** For read-only cursors the wrFlag argument is always zero. For read-write +** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or +** (BTREE_WRCSR). If the BTREE_FORDELETE flag is set, then the cursor will +** only be used by SQLite for the following: +** +** * to seek to and delete specific entries, and/or +** +** * to read values that will be used to create keys that other +** BTREE_FORDELETE cursors will seek to and delete. */ -#define BTREE_WRCSR 0x00000004 /* read-write cursor */ -#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ +#define BTREE_WRCSR 0x00000004 /* read-write cursor */ +#define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ diff --git a/src/whereInt.h b/src/whereInt.h index f4bc4077e4..cae09acc82 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -530,4 +530,3 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_SKIPSCAN 0x00008000 /* Uses the skip-scan algorithm */ #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ -#define WHERE_FORDELETE 0x00040000 /* Table cursor is "for-delete" */ From fb785b2c2b91c49362c8d70e162aac96f85e8534 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 24 Oct 2015 20:31:22 +0000 Subject: [PATCH 34/55] When creating an automatic-index on a sub-query, add a unique integer to the end of each index key to ensure the entire key is unique. Fix for [8a2adec1]. FossilOrigin-Name: bfea226d0d226a046a8bfb7a7a6288850d69bd26 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 37 ++++++++++++++++++++++++++++--------- test/autoindex5.test | 21 +++++++++++++++++++++ 4 files changed, 58 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 9f8c896ecd..23d91d98fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Alternate\scompiler\swarning\sfix\sfor\ssqlite3StatusHighwater. -D 2015-10-22T18:06:40.381 +C When\screating\san\sautomatic-index\son\sa\ssub-query,\sadd\sa\sunique\sinteger\sto\sthe\send\sof\seach\sindex\skey\sto\sensure\sthe\sentire\skey\sis\sunique.\sFix\sfor\s[8a2adec1]. +D 2015-10-24T20:31:22.639 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -415,7 +415,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c 4c4646675e794ac71e701289edefd7cd81bac844 +F src/where.c e3724b7b31d1e13869308ed4125305364f7d823a F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3 F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed @@ -465,7 +465,7 @@ F test/autoindex1.test 14b63a9f1e405fe6d5bfc8c8d00249c2ebaf13ea F test/autoindex2.test af7e595c6864cc6ef5fc38d5db579a3e34940cb8 F test/autoindex3.test a3be0d1a53a7d2edff208a5e442312957047e972 F test/autoindex4.test 49d3cd791a9baa16fb461d7ea3de80d019a819cf -F test/autoindex5.test 6f487290ce2a667c24517191651bfb8c7d86b6dc +F test/autoindex5.test 96f084a5e6024ea07cace5888df3223f3ea86990 F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 F test/avtrans.test 0252654f4295ddda3b2cce0e894812259e655a85 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P aa4e01ea1af327d1f8398ebea1c5bacc46698c3d -R a22db3919509c137f252ea9c4c395816 -U mistachkin -Z cd96591ebe18ee957344d1fc4f75aaa9 +P 4315d20200d578c9252dcb26e60739063a8eff1d +R dc911a631bba00e9a0808ae6a2dfaef0 +U dan +Z 6491941420be3020676420319ae4eec9 diff --git a/manifest.uuid b/manifest.uuid index 48569933f6..59b584ce70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4315d20200d578c9252dcb26e60739063a8eff1d \ No newline at end of file +bfea226d0d226a046a8bfb7a7a6288850d69bd26 \ No newline at end of file diff --git a/src/where.c b/src/where.c index af8e2f35fd..0adc698401 100644 --- a/src/where.c +++ b/src/where.c @@ -485,14 +485,20 @@ static LogEst estLog(LogEst N){ ** Convert OP_Column opcodes to OP_Copy in previously generated code. ** ** This routine runs over generated VDBE code and translates OP_Column -** opcodes into OP_Copy, and OP_Rowid into OP_Null, when the table is being -** accessed via co-routine instead of via table lookup. +** opcodes into OP_Copy when the table is being accessed via co-routine +** instead of via table lookup. +** +** If the bIncrRowid parameter is 0, then any OP_Rowid instructions on +** cursor iTabCur are transformed into OP_Null. Or, if bIncrRowid is non-zero, +** then each OP_Rowid is transformed into an instruction to increment the +** value stored in its output register. */ static void translateColumnToCopy( Vdbe *v, /* The VDBE containing code to translate */ int iStart, /* Translate from this opcode to the end */ int iTabCur, /* OP_Column/OP_Rowid references to this table */ - int iRegister /* The first column is in this register */ + int iRegister, /* The first column is in this register */ + int bIncrRowid /* If non-zero, transform OP_rowid to OP_AddImm(1) */ ){ VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); int iEnd = sqlite3VdbeCurrentAddr(v); @@ -504,9 +510,16 @@ static void translateColumnToCopy( pOp->p2 = pOp->p3; pOp->p3 = 0; }else if( pOp->opcode==OP_Rowid ){ - pOp->opcode = OP_Null; - pOp->p1 = 0; - pOp->p3 = 0; + if( bIncrRowid ){ + /* Increment the value stored in the P2 operand of the OP_Rowid. */ + pOp->opcode = OP_AddImm; + pOp->p1 = pOp->p2; + pOp->p2 = 1; + }else{ + pOp->opcode = OP_Null; + pOp->p1 = 0; + pOp->p3 = 0; + } } } } @@ -614,6 +627,8 @@ static void constructAutomaticIndex( Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ struct SrcList_item *pTabItem; /* FROM clause term being indexed */ + int addrCounter; /* Address where integer counter is initialized */ + int regBase; /* Array of registers where record is assembled */ /* Generate code to skip over the creation and initialization of the ** transient index on 2nd and subsequent iterations of the loop. */ @@ -742,6 +757,7 @@ static void constructAutomaticIndex( pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; + addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); @@ -755,12 +771,15 @@ static void constructAutomaticIndex( pLoop->wsFlags |= WHERE_PARTIALIDX; } regRecord = sqlite3GetTempReg(pParse); - sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0); + regBase = sqlite3GenerateIndexKey( + pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 + ); sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pTabItem->fg.viaCoroutine ){ - translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult); + sqlite3VdbeChangeP2(v, addrCounter, regBase+n); + translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult, 1); sqlite3VdbeGoto(v, addrTop); pTabItem->fg.viaCoroutine = 0; }else{ @@ -4509,7 +4528,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ */ if( pTabItem->fg.viaCoroutine && !db->mallocFailed ){ translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur, - pTabItem->regResult); + pTabItem->regResult, 0); continue; } diff --git a/test/autoindex5.test b/test/autoindex5.test index 2d5fad2eda..649ae123a4 100644 --- a/test/autoindex5.test +++ b/test/autoindex5.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix autoindex5 # Schema is from the Debian security database # @@ -103,6 +104,26 @@ do_execsql_test autoindex5-1.1 { OR sp.release = 'wheezy' OR sp.release = 'squeeze' ) ORDER BY sp.name, st.bug_name, sp.release, sp.subrelease; } {/SEARCH SUBQUERY 2 USING AUTOMATIC COVERING INDEX .bug_name=/} + +#------------------------------------------------------------------------- +# Test that ticket [8a2adec1] has been fixed. +# +do_execsql_test 2.1 { + CREATE TABLE one(o); + INSERT INTO one DEFAULT VALUES; + + CREATE TABLE t1(x, z); + INSERT INTO t1 VALUES('aaa', 4.0); + INSERT INTO t1 VALUES('aaa', 4.0); + CREATE VIEW vvv AS + SELECT * FROM t1 + UNION ALL + SELECT 0, 0 WHERE 0; + + SELECT ( + SELECT sum(z) FROM vvv WHERE x='aaa' + ) FROM one; +} {8.0} finish_test From 56d90be18309072182e9b8bb22a0d26286ab0ffb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Oct 2015 12:55:56 +0000 Subject: [PATCH 35/55] Remove an unreachable branch in malloc.c. FossilOrigin-Name: a36b7fe92372a13ff0b6e08f1704496045c6f62a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/malloc.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 23d91d98fd..d5c461ba4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\screating\san\sautomatic-index\son\sa\ssub-query,\sadd\sa\sunique\sinteger\sto\sthe\send\sof\seach\sindex\skey\sto\sensure\sthe\sentire\skey\sis\sunique.\sFix\sfor\s[8a2adec1]. -D 2015-10-24T20:31:22.639 +C Remove\san\sunreachable\sbranch\sin\smalloc.c. +D 2015-10-26T12:55:56.255 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -304,7 +304,7 @@ F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 F src/main.c fec97668771438033a7559883401067b139729e1 -F src/malloc.c 0a2e42b835c980ba91c17866e9b6a9810ff54d75 +F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 52485a88f22649c3b3b4f3eb15760505d49ccf71 F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4315d20200d578c9252dcb26e60739063a8eff1d -R dc911a631bba00e9a0808ae6a2dfaef0 -U dan -Z 6491941420be3020676420319ae4eec9 +P bfea226d0d226a046a8bfb7a7a6288850d69bd26 +R 71bd1944f2afa43b9641de175600fe9d +U drh +Z a960b5da2c918e1209a303de326b24d2 diff --git a/manifest.uuid b/manifest.uuid index 59b584ce70..ca08f0beac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfea226d0d226a046a8bfb7a7a6288850d69bd26 \ No newline at end of file +a36b7fe92372a13ff0b6e08f1704496045c6f62a \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 32047a2a5f..a4968aaa2f 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -455,7 +455,7 @@ void sqlite3_free(void *p){ ** *db->pnBytesFreed. */ static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ - if( p ) *db->pnBytesFreed += sqlite3DbMallocSize(db,p); + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); } /* From 46e6ea028283946b5bb0b2c8417944a5a0d649ee Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Oct 2015 14:41:35 +0000 Subject: [PATCH 36/55] When compiling with SQLITE_HAS_CODEC, honor the hexkey= query parameter on URI pathnames in sqlite3_open_v2(). FossilOrigin-Name: e0ce3fc089c2523b8b718b4a4f9ab8c4d0432fc7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d5c461ba4f..2fa695a375 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sin\smalloc.c. -D 2015-10-26T12:55:56.255 +C When\scompiling\swith\sSQLITE_HAS_CODEC,\shonor\sthe\shexkey=\squery\sparameter\son\nURI\spathnames\sin\ssqlite3_open_v2(). +D 2015-10-26T14:41:35.868 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -303,7 +303,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c fec97668771438033a7559883401067b139729e1 +F src/main.c 1cae029707c323292b5691e4d0a4c5c44561c877 F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 52485a88f22649c3b3b4f3eb15760505d49ccf71 @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P bfea226d0d226a046a8bfb7a7a6288850d69bd26 -R 71bd1944f2afa43b9641de175600fe9d +P a36b7fe92372a13ff0b6e08f1704496045c6f62a +R b06039a97a9cf0855388e699ea924396 U drh -Z a960b5da2c918e1209a303de326b24d2 +Z 746928cfbf856735825bc415cbbeefac diff --git a/manifest.uuid b/manifest.uuid index ca08f0beac..cca9fc08e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a36b7fe92372a13ff0b6e08f1704496045c6f62a \ No newline at end of file +e0ce3fc089c2523b8b718b4a4f9ab8c4d0432fc7 \ No newline at end of file diff --git a/src/main.c b/src/main.c index ef2fa66ec3..9dd05cdf1d 100644 --- a/src/main.c +++ b/src/main.c @@ -2954,6 +2954,21 @@ opendb_out: void *pArg = sqlite3GlobalConfig.pSqllogArg; sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } +#endif +#if defined(SQLITE_HAS_CODEC) + if( rc==SQLITE_OK ){ + const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey"); + if( zHexKey && zHexKey[0] ){ + u8 iByte; + int i; + char zKey[40]; + for(i=0, iByte=0; i Date: Mon, 26 Oct 2015 14:54:32 +0000 Subject: [PATCH 37/55] Fix a C99-ism and a harmless compiler warning. FossilOrigin-Name: 138783b553602a055b3efdeac5947cf5ccd76b5d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/mem1.c | 3 ++- src/where.c | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2fa695a375..fa40bac9a9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\scompiling\swith\sSQLITE_HAS_CODEC,\shonor\sthe\shexkey=\squery\sparameter\son\nURI\spathnames\sin\ssqlite3_open_v2(). -D 2015-10-26T14:41:35.868 +C Fix\sa\sC99-ism\sand\sa\sharmless\scompiler\swarning. +D 2015-10-26T14:54:32.296 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -306,7 +306,7 @@ F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 F src/main.c 1cae029707c323292b5691e4d0a4c5c44561c877 F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c 52485a88f22649c3b3b4f3eb15760505d49ccf71 +F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c c1ab1153bd6443bdf6f71e4213c6fb31221b9eb7 @@ -415,7 +415,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb F src/wal.c 18b0ed49830cf04fe2d68224b41838a73ac6cd24 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba -F src/where.c e3724b7b31d1e13869308ed4125305364f7d823a +F src/where.c 7b9e8d72e3eb52cec98617a5d6a029191bf1bcc8 F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 F src/wherecode.c b924b78acd9e623fb69bfa2cb65cd7d542166dd3 F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed @@ -1391,7 +1391,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a36b7fe92372a13ff0b6e08f1704496045c6f62a -R b06039a97a9cf0855388e699ea924396 +P e0ce3fc089c2523b8b718b4a4f9ab8c4d0432fc7 +R 2133c21a41df33b66ecf042f1953a26d U drh -Z 746928cfbf856735825bc415cbbeefac +Z 7527955b7ce1cc200d4d1a233d6e1b75 diff --git a/manifest.uuid b/manifest.uuid index cca9fc08e5..3da3b3d71f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0ce3fc089c2523b8b718b4a4f9ab8c4d0432fc7 \ No newline at end of file +138783b553602a055b3efdeac5947cf5ccd76b5d \ No newline at end of file diff --git a/src/mem1.c b/src/mem1.c index da6ae33e4c..b960ccfd47 100644 --- a/src/mem1.c +++ b/src/mem1.c @@ -171,11 +171,12 @@ static void sqlite3MemFree(void *pPrior){ ** or xRealloc(). */ static int sqlite3MemSize(void *pPrior){ - assert( pPrior!=0 ); #ifdef SQLITE_MALLOCSIZE + assert( pPrior!=0 ); return (int)SQLITE_MALLOCSIZE(pPrior); #else sqlite3_int64 *p; + assert( pPrior!=0 ); p = (sqlite3_int64*)pPrior; p--; return (int)p[0]; diff --git a/src/where.c b/src/where.c index 0adc698401..f079fb02ce 100644 --- a/src/where.c +++ b/src/where.c @@ -627,7 +627,7 @@ static void constructAutomaticIndex( Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ struct SrcList_item *pTabItem; /* FROM clause term being indexed */ - int addrCounter; /* Address where integer counter is initialized */ + int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ /* Generate code to skip over the creation and initialization of the From 6b513640c093974b1016148b05e4003c96bf0b3d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Oct 2015 16:31:18 +0000 Subject: [PATCH 38/55] Test that the binary record "0x01 0x00" is interpreted by OP_Column as a vector of NULL (or default) values. FossilOrigin-Name: 5bdc3c82bd10f924c12568eb0fa7a07393fc864f --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/test3.c | 49 +++++++++++++++++++++++++++++++++++++++++- test/fordelete.test | 52 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 107 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6617a2ff55..afc30e4aa5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\s#define\sfrom\swhereInt.h.\sAdd\scomments\sdescribing\sthe\snew\ssqlite3BtreeCursor()\sflags. -D 2015-10-23T11:50:23.745 +C Test\sthat\sthe\sbinary\srecord\s"0x01\s0x00"\sis\sinterpreted\sby\sOP_Column\sas\sa\svector\sof\sNULL\s(or\sdefault)\svalues. +D 2015-10-26T16:31:18.909 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -350,7 +350,7 @@ F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d -F src/test3.c 11b13d561846e5d1ffd29653be340d2f4b59a723 +F src/test3.c 5d5e771bee407b2a8bee1602228eca167f8f649a F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 @@ -628,7 +628,7 @@ F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 -F test/fordelete.test a30de567eb69a377e0c3ab1a8be4d74588de2a33 +F test/fordelete.test ba12ec1d27cc34a4c23db4446029126d773f3849 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -1392,7 +1392,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P cdc92919e600007cae5eb61223684f48a65babc0 -R 372ed0826353f0987c018dd56c7ed9e6 +P 4c0ba8be43bb7c7100456bd8cd6921c164be31e1 +R 034dc33437dfb21294c759656e936af8 U dan -Z 7d97368360f9df42d106befc4db01e49 +Z d7a6f95ed6a65ff4ab5499c664dec3c3 diff --git a/manifest.uuid b/manifest.uuid index cd45c7b9d4..aadca6e500 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c0ba8be43bb7c7100456bd8cd6921c164be31e1 \ No newline at end of file +5bdc3c82bd10f924c12568eb0fa7a07393fc864f \ No newline at end of file diff --git a/src/test3.c b/src/test3.c index 7cb29bedcb..da3296022a 100644 --- a/src/test3.c +++ b/src/test3.c @@ -219,7 +219,7 @@ static int btree_cursor( memset(pCur, 0, sqlite3BtreeCursorSize()); sqlite3BtreeEnter(pBt); #ifndef SQLITE_OMIT_SHARED_CACHE - rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag); + rc = sqlite3BtreeLockTable(pBt, iTable, !!wrFlag); #endif if( rc==SQLITE_OK ){ rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur); @@ -599,6 +599,51 @@ static int btree_set_cache_size( return TCL_OK; } +/* +** usage: btree_insert CSR ?KEY? VALUE +** +** Set the size of the cache used by btree $ID. +*/ +static int btree_insert( + ClientData clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *const objv[] +){ + BtCursor *pCur; + int rc; + int bIntkey = 0; + void *pKey = 0; + int nKey = 0; + void *pData = 0; + int nData = 0; + + if( objc!=4 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "?-intkey? CSR KEY VALUE"); + return TCL_ERROR; + } + + if( objc==4 ){ + if( Tcl_GetIntFromObj(interp, objv[2], &nKey) ) return TCL_ERROR; + pData = (void*)Tcl_GetByteArrayFromObj(objv[3], &nData); + }else{ + pKey = (void*)Tcl_GetByteArrayFromObj(objv[2], &nKey); + } + pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); + + sqlite3BtreeEnter(pCur->pBtree); + if( rc==SQLITE_OK ){ + rc = sqlite3BtreeInsert(pCur, pKey, nKey, pData, nData, 0, 0, 0); + } + sqlite3BtreeLeave(pCur->pBtree); + + Tcl_ResetResult(interp); + if( rc ){ + Tcl_AppendResult(interp, sqlite3ErrName(rc), 0); + return TCL_ERROR; + } + return TCL_OK; +} /* @@ -630,5 +675,7 @@ int Sqlitetest3_Init(Tcl_Interp *interp){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } + Tcl_CreateObjCommand(interp, "btree_insert", btree_insert, 0, 0); + return TCL_OK; } diff --git a/test/fordelete.test b/test/fordelete.test index dd0f953310..1e860e8867 100644 --- a/test/fordelete.test +++ b/test/fordelete.test @@ -76,5 +76,55 @@ foreach {tn sql res} { } { do_adp_test 2.$tn $sql $res } - + +#------------------------------------------------------------------------- +# Test that a record that consists of the bytes: +# +# 0x01 0x00 +# +# is interpreted by OP_Column as a vector of NULL values (assuming the +# default column values are NULL). Also test that: +# +# 0x00 +# +# is handled in the same way. +# +do_execsql_test 3.0 { + CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c, d); + CREATE TABLE x2(a INTEGER PRIMARY KEY, b, c, d); +} + +do_test 3.1 { + set root [db one { SELECT rootpage FROM sqlite_master WHERE name = 'x1' }] + db eval { + BEGIN IMMEDIATE; + } + set bt [btree_from_db db] + set csr [btree_cursor $bt $root 1] + btree_insert $csr 5 "\000" + btree_close_cursor $csr + db eval { COMMIT } + + db eval { + SELECT * FROM x1; + } +} {5 {} {} {}} + +do_test 3.2 { + set root [db one { SELECT rootpage FROM sqlite_master WHERE name = 'x2' }] + db eval { + BEGIN IMMEDIATE; + } + set bt [btree_from_db db] + set csr [btree_cursor $bt $root 1] + btree_insert $csr 6 "\000" + btree_close_cursor $csr + db eval { COMMIT } + + db eval { + SELECT * FROM x2; + } +} {6 {} {} {}} + finish_test + From 433d5aaed1ba5d5fda3a670d65571290cd2c2d9e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Oct 2015 16:34:13 +0000 Subject: [PATCH 39/55] Fix an uninitialized variable problem in the test code added by the previous commit. FossilOrigin-Name: 7849662ef94fa48fe53177db5623f46b3cb401e8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test3.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index afc30e4aa5..805b102db1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\sthat\sthe\sbinary\srecord\s"0x01\s0x00"\sis\sinterpreted\sby\sOP_Column\sas\sa\svector\sof\sNULL\s(or\sdefault)\svalues. -D 2015-10-26T16:31:18.909 +C Fix\san\suninitialized\svariable\sproblem\sin\sthe\stest\scode\sadded\sby\sthe\sprevious\scommit. +D 2015-10-26T16:34:13.792 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -350,7 +350,7 @@ F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d -F src/test3.c 5d5e771bee407b2a8bee1602228eca167f8f649a +F src/test3.c cf88d53cdd2e3d0f5f5cc20344d681f2a1417ce2 F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e F src/test5.c 5a34feec76d9b3a86aab30fd4f6cc9c48cbab4c1 F src/test6.c 41cacf3b0dd180823919bf9e1fbab287c9266723 @@ -1392,7 +1392,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 4c0ba8be43bb7c7100456bd8cd6921c164be31e1 -R 034dc33437dfb21294c759656e936af8 +P 5bdc3c82bd10f924c12568eb0fa7a07393fc864f +R 16eb9141567c1088c3120eb0503b5cc1 U dan -Z d7a6f95ed6a65ff4ab5499c664dec3c3 +Z 5262f0deb2fbfabd92647f1b6ad4a5a0 diff --git a/manifest.uuid b/manifest.uuid index aadca6e500..5495cb268d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bdc3c82bd10f924c12568eb0fa7a07393fc864f \ No newline at end of file +7849662ef94fa48fe53177db5623f46b3cb401e8 \ No newline at end of file diff --git a/src/test3.c b/src/test3.c index da3296022a..8197107688 100644 --- a/src/test3.c +++ b/src/test3.c @@ -632,9 +632,7 @@ static int btree_insert( pCur = (BtCursor*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3BtreeEnter(pCur->pBtree); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeInsert(pCur, pKey, nKey, pData, nData, 0, 0, 0); - } + rc = sqlite3BtreeInsert(pCur, pKey, nKey, pData, nData, 0, 0, 0); sqlite3BtreeLeave(pCur->pBtree); Tcl_ResetResult(interp); From 2853c688ad89156e7817342097bdf6eabccd5edc Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Oct 2015 20:39:56 +0000 Subject: [PATCH 40/55] Add new extended error code SQLITE_IOERR_AUTH. FossilOrigin-Name: b4e70dd08e79decaa09f7b99e2dc7e2df92f26ee --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 1 + 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 173858da0a..7bc59a3525 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Capture\sBTREE_FORDELETE\stest\scases\sthat\swere\smistakenly\somitted\sfrom\sthe\nprevious\smerge. -D 2015-10-26T18:01:36.030 +C Add\snew\sextended\serror\scode\sSQLITE_IOERR_AUTH. +D 2015-10-26T20:39:56.458 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -340,7 +340,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c dbf1fb82317043304da334a33206add211487f96 F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 -F src/sqlite.h.in 839c818e16ea68703d90d17bd2bb3607191debce +F src/sqlite.h.in 070b49c253bd41607ec43505a16163aa4b537b83 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h 835fce874a55144491d441f22c21a954bd17a1f3 @@ -1392,8 +1392,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 871b1c78bcbea1cb03d482f2f424c4e012633695 7849662ef94fa48fe53177db5623f46b3cb401e8 -R 410be704ee6d7da9328468f968a33ccc -T +closed 7849662ef94fa48fe53177db5623f46b3cb401e8 -U drh -Z 490c42bd7c47e077e17c4d7082be3a75 +P de6972515f65c5cf5da7cfdf876a05718299e9b8 +R 4eb922ad778b7d33d7840d32c90fdca7 +U dan +Z 576bf69fcd2542cc0c74c72ff3821475 diff --git a/manifest.uuid b/manifest.uuid index e61d0eb32a..5e36aaf7a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de6972515f65c5cf5da7cfdf876a05718299e9b8 \ No newline at end of file +b4e70dd08e79decaa09f7b99e2dc7e2df92f26ee \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index b5d12334d8..d9be3a5e6f 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -478,6 +478,7 @@ int sqlite3_exec( #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) #define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8)) +#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) From f7854c73291d49ba6541b17baac9c333f3aa82cf Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Oct 2015 13:24:37 +0000 Subject: [PATCH 41/55] Split out sqlite3BtreeCursorHintFlags() from sqlite3BtreeCursorHint() the interface for improved performance. FossilOrigin-Name: b3ec9a0d62c5543e91d4be2cd634ec4a3d6dca11 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btree.c | 25 ++++++++++++------------- src/btree.h | 12 ++++-------- src/test_config.c | 6 ++++++ src/vdbe.c | 4 ++-- test/cursorhint.test | 5 +++++ 7 files changed, 41 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 289ffeb941..7410e88e6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sBTREE_FORDELETE\senhancement\swith\sthis\sbranch. -D 2015-10-26T20:11:24.886 +C Split\sout\ssqlite3BtreeCursorHintFlags()\sfrom\ssqlite3BtreeCursorHint()\s\nthe\sinterface\sfor\simproved\sperformance. +D 2015-10-27T13:24:37.039 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -280,8 +280,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c c3a9c4209439b806c44cf30daf466955727bf46c F src/bitvec.c d1f21d7d91690747881f03940584f4cc548c9d3d F src/btmutex.c 45a968cc85afed9b5e6cf55bf1f42f8d18107f79 -F src/btree.c 8022201b3008c9ff151cf56cf2c36a0db93689fd -F src/btree.h 1957827f808875473750026cf60ca0c2b3676c98 +F src/btree.c 77343aac89c50bb5e06cbca3ace8c057c14de57c +F src/btree.h b512723e4f27d7ba16b4b985cdecdb82c0f6d0c0 F src/btreeInt.h 8177c9ab90d772d6d2c6c517e05bed774b7c92c0 F src/build.c d6162335d690396dfc5c4bd59e8b2b0c14ba6285 F src/callback.c 7b44ce59674338ad48b0e84e7b72f935ea4f68b0 @@ -362,7 +362,7 @@ F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 2e6e6a081870150f20c526a2e9d0d29cda47d803 F src/test_blob.c e5a7a81d61a780da79101aeb1e60d300af169e07 F src/test_btree.c 2e9978eca99a9a4bfa8cae949efb00886860a64f -F src/test_config.c ada6f38b0acb6722fb7f0ed8c54fd66df41085b9 +F src/test_config.c 426527fbb12fc23669a1e973ecdc8c5e92c2e2cf F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -401,7 +401,7 @@ F src/update.c 40e51cd0883cb5bfd6abb7d8a7cd8aa47fab2945 F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c F src/util.c fc612367108b74573c5fd13a85d0a23027f438bd F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 1cdfa13e37dba217916112fffc639dee83406192 +F src/vdbe.c dfbaae2570172c523bce14299021d352b8508f7f F src/vdbe.h efb7a8c1459e31f3ea4377824c6a7e4cb5068637 F src/vdbeInt.h 33403622c6a8feaaac5f0f3f17f5d1bf6df42286 F src/vdbeapi.c 020681b943e77766b32ae1cddf86d7831b7374ca @@ -563,7 +563,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 -F test/cursorhint.test 7d94f7602e22ec129ca51836f333b5ff994a2b02 +F test/cursorhint.test 432811b62bd5ffb812729f49bba3b9ad687550bb F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 @@ -1393,7 +1393,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 53d5a4add6b60722ad77daf98b6b8983b081e16a de6972515f65c5cf5da7cfdf876a05718299e9b8 -R eb548650b5c16f458e4886ea4649dc57 -U dan -Z 682420f21bcc754cb8ec9b887c5ab3d8 +P 20da0849ce910ceb445954dfc5f985acf9a02695 +R 452da66a52ee276332ecb816f5e027f4 +U drh +Z 67947be805126d86b3d9fe642be25131 diff --git a/manifest.uuid b/manifest.uuid index 02251806a8..1580a0d419 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20da0849ce910ceb445954dfc5f985acf9a02695 \ No newline at end of file +b3ec9a0d62c5543e91d4be2cd634ec4a3d6dca11 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 1370bef2d0..8d183efb31 100644 --- a/src/btree.c +++ b/src/btree.c @@ -858,26 +858,25 @@ int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ return SQLITE_OK; } +#ifdef SQLITE_ENABLE_CURSOR_HINTS /* ** Provide hints to the cursor. The particular hint given (and the type ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. */ void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ - va_list ap; - va_start(ap, eHintType); -#ifdef SQLITE_ENABLE_CURSOR_HINTS - if( eHintType==BTREE_HINT_FLAGS ) -#else - assert( eHintType==BTREE_HINT_FLAGS ); -#endif - { - pCur->hints = va_arg(ap, unsigned int); - assert( pCur->hints==BTREE_SEEK_EQ || pCur->hints==BTREE_BULKLOAD - || pCur->hints==0 ); - } - va_end(ap); + /* Used only by system that substitute their own storage engine */ } +#endif + +/* +** Provide flag hints to the cursor. +*/ +void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ + assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); + pCur->hints = x; +} + #ifndef SQLITE_OMIT_AUTOVACUUM /* diff --git a/src/btree.h b/src/btree.h index ba6cc5a948..f37ec5e7fc 100644 --- a/src/btree.h +++ b/src/btree.h @@ -153,12 +153,6 @@ int sqlite3BtreeNewDb(Btree *p); ** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() ** interface. ** -** BTREE_HINT_FLAGS (arguments: unsigned int) -** -** Some combinatation of BTREE_BULKLOAD and BTREE_SEEK_EQ flags. The -** argument is a single unsigned integer which overwrites all prior -** flag settings. -** ** BTREE_HINT_RANGE (arguments: Expr*, Mem*) ** ** The first argument is an Expr* (which is guaranteed to be constant for @@ -182,8 +176,7 @@ int sqlite3BtreeNewDb(Btree *p); ** the SQLite parser and code generator but substitute their own storage ** engine. */ -#define BTREE_HINT_FLAGS 1 /* Set flags indicating cursor usage */ -#define BTREE_HINT_RANGE 2 /* Range constraints on queries */ +#define BTREE_HINT_RANGE 0 /* Range constraints on queries */ /* ** Values that may be OR'd together to form the argument to the @@ -226,7 +219,10 @@ int sqlite3BtreeCursor( ); int sqlite3BtreeCursorSize(void); void sqlite3BtreeCursorZero(BtCursor*); +void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); +#ifdef SQLITE_ENABLE_CURSOR_HINTS void sqlite3BtreeCursorHint(BtCursor*, int, ...); +#endif int sqlite3BtreeCloseCursor(BtCursor*); int sqlite3BtreeMovetoUnpacked( diff --git a/src/test_config.c b/src/test_config.c index 5da2df16b7..be43f87e73 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -119,6 +119,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "8_3_names", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_CURSOR_HINTS + Tcl_SetVar2(interp, "sqlite_options", "cursorhints", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "cursorhints", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_MEMSYS3 Tcl_SetVar2(interp, "sqlite_options", "mem3", "1", TCL_GLOBAL_ONLY); #else diff --git a/src/vdbe.c b/src/vdbe.c index d702313b84..c5508a2b26 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3401,8 +3401,8 @@ open_cursor_set_hints: #ifdef SQLITE_ENABLE_CURSOR_HINT testcase( pOp->p2 & OPFLAG_SEEKEQ ); #endif - sqlite3BtreeCursorHint(pCur->pCursor, BTREE_HINT_FLAGS, - (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); + sqlite3BtreeCursorHintFlags(pCur->pCursor, + (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); break; } diff --git a/test/cursorhint.test b/test/cursorhint.test index 75f3eb04e2..69bc248cd7 100644 --- a/test/cursorhint.test +++ b/test/cursorhint.test @@ -15,6 +15,11 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix cursorhint +ifcapable !cursorhints { + finish_test + return +} + do_execsql_test 1.0 { CREATE TABLE t1(a,b,c,d); CREATE TABLE t2(x,y,z); From 24b845791168e481e9c6870f8a41f7123d8fb101 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Oct 2015 17:48:57 +0000 Subject: [PATCH 42/55] Fix problems with prefix queries in fts5. FossilOrigin-Name: 3b5758c647530bd5c2e68d0ee3e9f58a96347ca4 --- ext/fts5/fts5_index.c | 27 +++++++---- ext/fts5/test/fts5integrity.test | 49 ++++++++++++++++++- ext/fts5/test/fts5query.test | 83 ++++++++++++++++++++++++++++++++ ext/fts5/tool/showfts5.tcl | 13 +++++ manifest | 20 ++++---- manifest.uuid | 2 +- 6 files changed, 172 insertions(+), 22 deletions(-) create mode 100644 ext/fts5/test/fts5query.test diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index e70bc85351..b3f4372965 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -1499,6 +1499,7 @@ static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){ pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; pIter->iLeafOffset = iOff; + assert_nc( pIter->nPos>=0 ); } } @@ -1672,12 +1673,13 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ if( pNew ){ /* iTermLeafOffset may be equal to szLeaf if the term is the last ** thing on the page - i.e. the first rowid is on the following page. - ** In this case leaf pIter->pLeaf==0, this iterator is at EOF. */ - if( pIter->iLeafPgno==pIter->iTermLeafPgno - && pIter->iTermLeafOffsetszLeaf - ){ - pIter->pLeaf = pNew; - pIter->iLeafOffset = pIter->iTermLeafOffset; + ** In this case leave pIter->pLeaf==0, this iterator is at EOF. */ + if( pIter->iLeafPgno==pIter->iTermLeafPgno ){ + assert( pIter->pLeaf==0 ); + if( pIter->iTermLeafOffsetszLeaf ){ + pIter->pLeaf = pNew; + pIter->iLeafOffset = pIter->iTermLeafOffset; + } }else{ int iRowidOff; iRowidOff = fts5LeafFirstRowidOff(pNew); @@ -1851,6 +1853,7 @@ static void fts5SegIterNext( fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; + assert_nc( pIter->nPos>=0 ); } } } @@ -2059,11 +2062,14 @@ static void fts5LeafSeek( if( pIter->pLeaf==0 ) return; a = pIter->pLeaf->p; if( fts5LeafIsTermless(pIter->pLeaf)==0 ){ - fts5GetVarint32(&pIter->pLeaf->p[pIter->pLeaf->szLeaf], iOff); + iPgidx = pIter->pLeaf->szLeaf; + iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff); if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; }else{ nKeep = 0; + iTermOff = iOff; + n = pIter->pLeaf->nn; iOff += fts5GetVarint32(&a[iOff], nNew); break; } @@ -4375,7 +4381,7 @@ static void fts5SetupPrefixIter( Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; Fts5Buffer doclist; - int bNewTerm = 0; + int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1); @@ -5582,8 +5588,9 @@ static int fts5DecodeDoclist(int *pRc, Fts5Buffer *pBuf, const u8 *a, int n){ } while( iOff10" { + puts $d + } +} + diff --git a/manifest b/manifest index 980451cf38..9057c85e7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\shints\sto\sthe\sstorage\sengine\susing\sthe\ssqlite3BtreeCursorHint()\ninterface\swhen\scompiling\swith\sSQLITE_ENABLE_CURSOR_HINTS. -D 2015-10-27T13:35:14.170 +C Fix\sproblems\swith\sprefix\squeries\sin\sfts5. +D 2015-10-27T17:48:57.642 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -109,7 +109,7 @@ F ext/fts5/fts5_buffer.c 1e49512a535045e621246dc7f4f65f3593fa0fc2 F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f -F ext/fts5/fts5_index.c 2bd3cb65b36160f7b411e70c4360d0619c965e4e +F ext/fts5/fts5_index.c 356481ce027cc2ede8e462c316b578260cda29d2 F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd @@ -157,7 +157,7 @@ F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5hash.test 7cf4607b8657c383f0b520668a99971e95d8b139 -F ext/fts5/test/fts5integrity.test 29f41d2c7126c6122fbb5d54e556506456876145 +F ext/fts5/test/fts5integrity.test 87db5d4e7da0ce04a1dcba5ba91658673c997a65 F ext/fts5/test/fts5matchinfo.test 2163b0013e824bba65499da9e34ea4da41349cc2 F ext/fts5/test/fts5merge.test 8f3cdba2ec9c5e7e568246e81b700ad37f764367 F ext/fts5/test/fts5near.test b214cddb1c1f1bddf45c75af768f20145f7e71cc @@ -168,6 +168,7 @@ F ext/fts5/test/fts5plan.test 6a55ecbac9890765b0e16f8c421c7e0888cfe436 F ext/fts5/test/fts5porter.test 7cdc07bef301d70eebbfa75dcaf45c3680e1d0e1 F ext/fts5/test/fts5porter2.test 2e65633d58a1c525d5af0f6c01e5a59155bb3487 F ext/fts5/test/fts5prefix.test 7ccbdf180ed561a912acef520519e85af8642239 +F ext/fts5/test/fts5query.test f5ec25f5f2fbb70033424113cdffc101b1985a40 F ext/fts5/test/fts5rank.test 11dcebba31d822f7e99685b4ea2c2ae3ec0b16f1 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 @@ -184,7 +185,7 @@ F ext/fts5/test/fts5vocab.test c88a5554d0409494da95ba647bbdb4879b2624b0 F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84 F ext/fts5/tool/loadfts5.tcl 58e90407cc5c2b1770460119488fd7c0090d4dd3 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 -F ext/fts5/tool/showfts5.tcl 9eaf6c3df352f98a2ab5ce1921dd94128ab1381d +F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 F ext/icu/icu.c b2732aef0b076e4276d9b39b5a33cec7a05e1413 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 @@ -1393,8 +1394,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b4e70dd08e79decaa09f7b99e2dc7e2df92f26ee b3ec9a0d62c5543e91d4be2cd634ec4a3d6dca11 -R 4646a6990e647428ec4d0d5814dac399 -T +closed b3ec9a0d62c5543e91d4be2cd634ec4a3d6dca11 -U drh -Z 02443220badb4130f058a2b797287082 +P 45d3539e152a44629639723f18ce70d9ef01f31a +R fbe2860d8975b512a1715e460bd017e7 +U dan +Z 8f449fae999a2e5acc0c44c5783d72e3 diff --git a/manifest.uuid b/manifest.uuid index 1e5f93daa3..36934c91ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45d3539e152a44629639723f18ce70d9ef01f31a \ No newline at end of file +3b5758c647530bd5c2e68d0ee3e9f58a96347ca4 \ No newline at end of file From 36c33aa6339d60c3a20326364bc98df22cb46997 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 27 Oct 2015 20:04:53 +0000 Subject: [PATCH 43/55] Have contentless and external content fts5 tables ignore "OR REPLACE" conflict handling. FossilOrigin-Name: a85c2a4758c27e8d5d0395751eb3cfd9985ce696 --- ext/fts5/fts5_main.c | 5 ++- ext/fts5/fts5_storage.c | 16 ++++---- ext/fts5/test/fts5aa.test | 2 +- ext/fts5/test/fts5conflict.test | 70 +++++++++++++++++++++++++++++++++ manifest | 17 ++++---- manifest.uuid | 2 +- 6 files changed, 94 insertions(+), 18 deletions(-) create mode 100644 ext/fts5/test/fts5conflict.test diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index a133cf41b9..bd004cf824 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1451,7 +1451,10 @@ static int fts5UpdateMethod( ** ** Cases 3 and 4 may violate the rowid constraint. */ - int eConflict = sqlite3_vtab_on_conflict(pConfig->db); + int eConflict = SQLITE_ABORT; + if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + eConflict = sqlite3_vtab_on_conflict(pConfig->db); + } assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); assert( nArg!=1 || eType0==SQLITE_INTEGER ); diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index ff4aea50e1..5fd5dc51a2 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -513,13 +513,15 @@ int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel){ } /* Delete the %_content record */ - if( rc==SQLITE_OK ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); - } - if( rc==SQLITE_OK ){ - sqlite3_bind_int64(pDel, 1, iDel); - sqlite3_step(pDel); - rc = sqlite3_reset(pDel); + if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( rc==SQLITE_OK ){ + rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pDel, 1, iDel); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); + } } /* Write the averages record */ diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index f8ea6a8f71..59b8ab86d1 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -15,7 +15,7 @@ source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5aa -# If SQLITE_ENABLE_FTS3 is defined, omit this file. +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. ifcapable !fts5 { finish_test return diff --git a/ext/fts5/test/fts5conflict.test b/ext/fts5/test/fts5conflict.test new file mode 100644 index 0000000000..5c1e593249 --- /dev/null +++ b/ext/fts5/test/fts5conflict.test @@ -0,0 +1,70 @@ +# 2015 October 27 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# This file implements regression tests for SQLite library. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5conflict + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, a, b); + CREATE VIRTUAL TABLE ft USING fts5(a, b, content=t1, content_rowid=x); +} + +do_execsql_test 1.1 { + REPLACE INTO ft(rowid, a, b) VALUES(1, 'a b c', 'a b c'); + REPLACE INTO t1 VALUES(1, 'a b c', 'a b c'); +} + +do_execsql_test 1.2 { + INSERT INTO ft(ft) VALUES('integrity-check'); +} + +do_execsql_test 2.0 { + CREATE TABLE tbl(a INTEGER PRIMARY KEY, b, c); + CREATE VIRTUAL TABLE fts_idx USING fts5(b, c, content=tbl, content_rowid=a); + CREATE TRIGGER tbl_ai AFTER INSERT ON tbl BEGIN + INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c); + END; + CREATE TRIGGER tbl_ad AFTER DELETE ON tbl BEGIN + INSERT INTO fts_idx(fts_idx, rowid, b, c) + VALUES('delete', old.a, old.b, old.c); + END; + CREATE TRIGGER tbl_au AFTER UPDATE ON tbl BEGIN + INSERT INTO fts_idx(fts_idx, rowid, b, c) + VALUES('delete', old.a, old.b, old.c); + INSERT INTO fts_idx(rowid, b, c) VALUES (new.a, new.b, new.c); + END; +} + +do_execsql_test 2.1 { + PRAGMA recursive_triggers = 1; + INSERT INTO tbl VALUES(1, 'x y z', '1 2 3'); + INSERT INTO tbl VALUES(10, 'x y z', '1 2 3'); + INSERT INTO tbl VALUES(100, 'x 1 z', '1 y 3'); + + UPDATE tbl SET b = '1 2 x' WHERE rowid=10; + REPLACE INTO tbl VALUES(1, '4 5 6', '3 2 1'); + DELETE FROM tbl WHERE a=100; + + INSERT INTO fts_idx(fts_idx) VALUES('integrity-check'); +} + +finish_test + + diff --git a/manifest b/manifest index 9057c85e7b..200cb097f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sprefix\squeries\sin\sfts5. -D 2015-10-27T17:48:57.642 +C Have\scontentless\sand\sexternal\scontent\sfts5\stables\signore\s"OR\sREPLACE"\sconflict\shandling. +D 2015-10-27T20:04:53.777 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -110,8 +110,8 @@ F ext/fts5/fts5_config.c 88a77f5d5e4dfbb2355b8f6cc9969b7f02d94685 F ext/fts5/fts5_expr.c 28b15c9ae296204bc0a2e5cf7a667d840a9d2900 F ext/fts5/fts5_hash.c a9d4c1efebc2a91d26ad7ebdfcbf2678ceac405f F ext/fts5/fts5_index.c 356481ce027cc2ede8e462c316b578260cda29d2 -F ext/fts5/fts5_main.c 520a29136ba07448331f73bdc36d0ffa1e9dcfef -F ext/fts5/fts5_storage.c 8038a54a88d3beb94dc7f9db6428a3bc08b718bb +F ext/fts5/fts5_main.c 39358d3d8f0d6ea3757c40e0ddcbb6bc435604c3 +F ext/fts5/fts5_storage.c 9ea3d92178743758b6c54d9fe8836bbbdcc92e3b F ext/fts5/fts5_tcl.c 3bf445e66de32137d4693694ff7b1fd6074e32bd F ext/fts5/fts5_test_mi.c e96be827aa8f571031e65e481251dc1981d608bf F ext/fts5/fts5_tokenize.c 12c5d925286491a71bb3dad7c8924ce9cfd18320 @@ -121,7 +121,7 @@ F ext/fts5/fts5_vocab.c 3742d0abfe8aa8c3cb4a7df56aa38f2e3c3fb1c2 F ext/fts5/fts5parse.y e83dca6028e3309178d05b5bd920e372dc295d35 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 51f7ef3af444b89c6f6ce3896a0ac349ff4e996d -F ext/fts5/test/fts5aa.test 34ad813e9e958115d388658b2c4a8dde6b1474a5 +F ext/fts5/test/fts5aa.test 2c553eea4dab4bc5a75928f56729277c7bc1d206 F ext/fts5/test/fts5ab.test 6fe3a56731d15978afbb74ae51b355fc9310f2ad F ext/fts5/test/fts5ac.test 9737992d08c56bfd4803e933744d2d764e23795c F ext/fts5/test/fts5ad.test e3dfb150fce971b4fd832498c29f56924d451b63 @@ -140,6 +140,7 @@ F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 F ext/fts5/test/fts5config.test ad2ff42ddc856aed2d05bf89dc1c578c8a39ea3b +F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c @@ -1394,7 +1395,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 45d3539e152a44629639723f18ce70d9ef01f31a -R fbe2860d8975b512a1715e460bd017e7 +P 3b5758c647530bd5c2e68d0ee3e9f58a96347ca4 +R 12dc88416f949cd01baa0c732f28f65c U dan -Z 8f449fae999a2e5acc0c44c5783d72e3 +Z bfdbdd08273e5e7ba3b496b0efa58731 diff --git a/manifest.uuid b/manifest.uuid index 36934c91ef..cfeac69b08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3b5758c647530bd5c2e68d0ee3e9f58a96347ca4 \ No newline at end of file +a85c2a4758c27e8d5d0395751eb3cfd9985ce696 \ No newline at end of file From 9109b7f8e1be2f0dc1437762d1c1f3effd878c0d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Oct 2015 16:05:10 +0000 Subject: [PATCH 44/55] Factor out adding NOT expression nodes in the parser into a subroutine. FossilOrigin-Name: 001854181640bd9b088f2bc16083d84808c3da18 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 19 +++++++++++++------ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 200cb097f7..b070a768f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\scontentless\sand\sexternal\scontent\sfts5\stables\signore\s"OR\sREPLACE"\sconflict\shandling. -D 2015-10-27T20:04:53.777 +C Factor\sout\sadding\sNOT\sexpression\snodes\sin\sthe\sparser\sinto\sa\ssubroutine. +D 2015-10-28T16:05:10.981 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -329,7 +329,7 @@ F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2fbeeba28f4e6d08a15bc106f36c43346a81f09e F src/pager.h ac213f8143ebfee6a8bfb91cf4ca02c9a83343c5 -F src/parse.y f599aa5e871a493330d567ced93de696f61f48f7 +F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 F src/pcache1.c 902e1bc7bdaa81b40f8543407c5e2ac8ef4dc035 @@ -1395,7 +1395,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3b5758c647530bd5c2e68d0ee3e9f58a96347ca4 -R 12dc88416f949cd01baa0c732f28f65c -U dan -Z bfdbdd08273e5e7ba3b496b0efa58731 +P a85c2a4758c27e8d5d0395751eb3cfd9985ce696 +R fb08eb2aea7ef14b6808d0fed46a7f2e +U drh +Z 776eb09f5d20f370f46eb3dbeaa8d2e2 diff --git a/manifest.uuid b/manifest.uuid index cfeac69b08..0f39a06726 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a85c2a4758c27e8d5d0395751eb3cfd9985ce696 \ No newline at end of file +001854181640bd9b088f2bc16083d84808c3da18 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index e99feeefc1..797fa9bdeb 100644 --- a/src/parse.y +++ b/src/parse.y @@ -929,6 +929,13 @@ term(A) ::= CTIME_KW(OP). { pOut->zStart = pLeft->zStart; pOut->zEnd = pRight->zEnd; } + + /* If doNot is true, then add a TK_NOT Expr-node wrapper around the + ** outside of *ppExpr. + */ + static void exprNot(Parse *pParse, int doNot, Expr **ppExpr){ + if( doNot ) *ppExpr = sqlite3PExpr(pParse, TK_NOT, *ppExpr, 0, 0); + } } expr(A) ::= expr(X) AND(OP) expr(Y). {spanBinaryExpr(&A,pParse,@OP,&X,&Y);} @@ -951,7 +958,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y). [LIKE_KW] { pList = sqlite3ExprListAppend(pParse,0, Y.pExpr); pList = sqlite3ExprListAppend(pParse,pList, X.pExpr); A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); - if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, OP.bNot, &A.pExpr); A.zStart = X.zStart; A.zEnd = Y.zEnd; if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; @@ -962,7 +969,7 @@ expr(A) ::= expr(X) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] { pList = sqlite3ExprListAppend(pParse,pList, X.pExpr); pList = sqlite3ExprListAppend(pParse,pList, E.pExpr); A.pExpr = sqlite3ExprFunction(pParse, pList, &OP.eOperator); - if( OP.bNot ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, OP.bNot, &A.pExpr); A.zStart = X.zStart; A.zEnd = E.zEnd; if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc; @@ -1052,7 +1059,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, N, &A.pExpr); A.zStart = W.zStart; A.zEnd = Y.zEnd; } @@ -1107,7 +1114,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { }else{ sqlite3ExprListDelete(pParse->db, Y); } - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, N, &A.pExpr); } A.zStart = X.zStart; A.zEnd = &E.z[E.n]; @@ -1133,7 +1140,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { }else{ sqlite3SelectDelete(pParse->db, Y); } - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, N, &A.pExpr); A.zStart = X.zStart; A.zEnd = &E.z[E.n]; } @@ -1147,7 +1154,7 @@ expr(A) ::= expr(W) between_op(N) expr(X) AND expr(Y). [BETWEEN] { }else{ sqlite3SrcListDelete(pParse->db, pSrc); } - if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0); + exprNot(pParse, N, &A.pExpr); A.zStart = X.zStart; A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n]; } From 6fa255fd5c728be68381ce23beead03d38a10dac Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 28 Oct 2015 19:46:57 +0000 Subject: [PATCH 45/55] Add experimental API sqlite3_db_cacheflush(). FossilOrigin-Name: 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 --- manifest | 27 +++--- manifest.uuid | 2 +- src/main.c | 33 +++++++ src/pager.c | 17 ++++ src/pager.h | 1 + src/sqlite.h.in | 30 +++++++ src/test1.c | 29 ++++++ test/cacheflush.test | 207 +++++++++++++++++++++++++++++++++++++++++++ test/cffault.test | 57 ++++++++++++ 9 files changed, 391 insertions(+), 12 deletions(-) create mode 100644 test/cacheflush.test create mode 100644 test/cffault.test diff --git a/manifest b/manifest index b070a768f7..866a53b656 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sadding\sNOT\sexpression\snodes\sin\sthe\sparser\sinto\sa\ssubroutine. -D 2015-10-28T16:05:10.981 +C Add\sexperimental\sAPI\ssqlite3_db_cacheflush(). +D 2015-10-28T19:46:57.460 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -305,7 +305,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c 1cae029707c323292b5691e4d0a4c5c44561c877 +F src/main.c b9d020342b2a2b13808c6260792ef233d7af5b1d F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -327,8 +327,8 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2fbeeba28f4e6d08a15bc106f36c43346a81f09e -F src/pager.h ac213f8143ebfee6a8bfb91cf4ca02c9a83343c5 +F src/pager.c 059991ce76b1a857cb84dd2469cfcfaaae1d77fa +F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef F src/pcache.h 9968603796240cdf83da7e7bef76edf90619cea9 @@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 167b4e9058bc8e997d18d6b6b20ecbb0c9c457af F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 -F src/sqlite.h.in 070b49c253bd41607ec43505a16163aa4b537b83 +F src/sqlite.h.in e7da8d15141d0753bfe14945bd64592a42575c04 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556 @@ -350,7 +350,7 @@ F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e F src/tclsqlite.c d9439b6a910985b7fff43ba6756bcef00de22649 -F src/test1.c 8fff9c5aa63d6490f516d018b70c12a9cb9a4d8a +F src/test1.c 9ac5cbfe3c859ab7518edc5109a2959d6bf7b059 F src/test2.c 577961fe48961b2f2e5c8b56ee50c3f459d3359d F src/test3.c f7ae1d6a4aa07aac257de18a43800c1199b513fc F src/test4.c d168f83cc78d02e8d35567bb5630e40dcd85ac1e @@ -503,6 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de +F test/cacheflush.test 95944e4210100c525ec301c060721e82210c33a5 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -510,6 +511,7 @@ F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 +F test/cffault.test 1383919788fa50db60f6119da5785c62fbc8b527 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -1395,7 +1397,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a85c2a4758c27e8d5d0395751eb3cfd9985ce696 -R fb08eb2aea7ef14b6808d0fed46a7f2e -U drh -Z 776eb09f5d20f370f46eb3dbeaa8d2e2 +P 001854181640bd9b088f2bc16083d84808c3da18 +R 2dbc861fa3cf60b53d3ec06b17c9981a +T *branch * cacheflush +T *sym-cacheflush * +T -sym-trunk * +U dan +Z c07109c8cca9fe678b00367209f93a20 diff --git a/manifest.uuid b/manifest.uuid index 0f39a06726..ac6d5b874a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -001854181640bd9b088f2bc16083d84808c3da18 \ No newline at end of file +65b86dc1fa4a57cc3cde86a820d9f848aa288a15 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 9dd05cdf1d..324415b0cf 100644 --- a/src/main.c +++ b/src/main.c @@ -740,6 +740,39 @@ int sqlite3_db_release_memory(sqlite3 *db){ return SQLITE_OK; } +/* +** Flush any dirty pages in the pager-cache for any attached database +** to disk. +*/ +int sqlite3_db_cacheflush(sqlite3 *db){ + int i; + int rc = SQLITE_OK; + int bSeenBusy = 0; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + for(i=0; rc==SQLITE_OK && inDb; i++){ + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeIsInTrans(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerFlush(pPager); + if( rc==SQLITE_BUSY ){ + bSeenBusy = 1; + rc = SQLITE_OK; + } + } + } + if( rc!=SQLITE_OK ){ + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + } + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); + return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); +} + /* ** Configuration settings for an individual database connection */ diff --git a/src/pager.c b/src/pager.c index 399070af01..f21f0802ba 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4473,6 +4473,23 @@ static int pagerStress(void *p, PgHdr *pPg){ return pager_error(pPager, rc); } +/* +** Flush all unreferenced dirty pages to disk. +*/ +int sqlite3PagerFlush(Pager *pPager){ + int rc = SQLITE_OK; + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; + } + + return rc; +} /* ** Allocate and initialize a new Pager object and put a pointer to it diff --git a/src/pager.h b/src/pager.h index 99a7aebc78..8e0e942efe 100644 --- a/src/pager.h +++ b/src/pager.h @@ -132,6 +132,7 @@ int sqlite3PagerGetJournalMode(Pager*); int sqlite3PagerOkToChangeJournalMode(Pager*); i64 sqlite3PagerJournalSizeLimit(Pager *, i64); sqlite3_backup **sqlite3PagerBackupPtr(Pager*); +int sqlite3PagerFlush(Pager*); /* Functions used to obtain and release page references. */ int sqlite3PagerAcquire(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d9be3a5e6f..6c04ff5102 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7792,6 +7792,36 @@ int sqlite3_stmt_scanstatus( */ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); +/* +** CAPI3REF: Flush caches to disk mid-transaction +** +** If a write-transaction is open when this function is called, any dirty +** pages in the pager-cache that are not currently in use are written out +** to disk. A dirty page may be in use if a database cursor created by an +** active SQL statement is reading from it, or if it is page 1 of a database +** file (page 1 is always "in use"). Dirty pages are flushed for all +** databases - "main", "temp" and any attached databases. +** +** If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. If said locks cannot be obtained +** immediately and there is a busy-handler callback configured, it is invoked +** in the usual manner. If the required lock still cannot be obtained, then +** the database is skipped and an attempt made to flush any dirty pages +** belonging to the next (if any) database. If any databases are skipped +** because locks cannot be obtained, but no other error occurs, this +** function returns SQLITE_BUSY. +** +** If any other error occurs while flushing dirty pages to disk (for +** example an IO error or out-of-memory condition), then processing is +** abandoned and an SQLite error code returned to the caller immediately. +** In this case the open transaction may be automatically rolled back. +** +** Otherwise, if no error occurs, SQLITE_OK is returned. +** +** This function does not set the database handle error code or message +** returned by the sqlite3_errcode() and sqlite3_errmsg() functions. +*/ +int sqlite3_db_cacheflush(sqlite3*); /* ** Undo the hack that converts floating point types to integer for diff --git a/src/test1.c b/src/test1.c index 6c47754bf9..dd190feebc 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4688,6 +4688,34 @@ static int test_db_release_memory( return TCL_OK; } +/* +** Usage: sqlite3_db_cacheflush DB +** +** Attempt to flush any dirty pages to disk. +*/ +static int test_db_cacheflush( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int rc; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + rc = sqlite3_db_cacheflush(db); + if( rc ){ + Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC); + return TCL_ERROR; + } + + Tcl_ResetResult(interp); + return TCL_OK; +} + /* ** Usage: sqlite3_db_filename DB DBNAME ** @@ -6876,6 +6904,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_release_memory", test_release_memory, 0}, { "sqlite3_db_release_memory", test_db_release_memory, 0}, + { "sqlite3_db_cacheflush", test_db_cacheflush, 0}, { "sqlite3_db_filename", test_db_filename, 0}, { "sqlite3_db_readonly", test_db_readonly, 0}, { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, diff --git a/test/cacheflush.test b/test/cacheflush.test new file mode 100644 index 0000000000..a9ee672b9f --- /dev/null +++ b/test/cacheflush.test @@ -0,0 +1,207 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains test cases for sqlite3_db_cacheflush API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cacheflush +test_set_config_pagecache 0 0 + +# Run the supplied SQL on a copy of the database currently stored on +# disk in file $dbfile. +proc diskquery {dbfile sql} { + forcecopy $dbfile dq.db + sqlite3 dq dq.db + set res [execsql $sql dq] + dq close + set res +} + +# Simplest possible test. +# +do_execsql_test 1.1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2); + BEGIN; + INSERT INTO t1 VALUES(3, 4); +} +do_test 1.1.1 { + diskquery test.db { SELECT * FROM t1 } +} {1 2} +do_test 1.1.2 { + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1 } +} {1 2 3 4} + +# Test that multiple pages may be flushed to disk. +# +do_execsql_test 1.2.0 { + COMMIT; + CREATE TABLE t2(a, b); + BEGIN; + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t2 VALUES('a', 'b'); +} +do_test 1.2.1 { + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {1 2 3 4} +do_test 1.2.2 { + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + } +} {1 2 3 4 5 6 a b} + +# Test that pages with nRef!=0 are not flushed to disk. +# +do_execsql_test 1.3.0 { + COMMIT; + CREATE TABLE t3(a, b); + BEGIN; + INSERT INTO t1 VALUES(7, 8); + INSERT INTO t2 VALUES('c', 'd'); + INSERT INTO t3 VALUES('i', 'ii'); +} +do_test 1.3.1 { + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 a b} +do_test 1.3.2 { + db eval { SELECT a FROM t1 } { + if {$a==3} { + sqlite3_db_cacheflush db + } + } + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 a b c d i ii} +do_test 1.3.2 { + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + SELECT * FROM t2; + SELECT * FROM t3; + } +} {1 2 3 4 5 6 7 8 a b c d i ii} + +# Check that SQLITE_BUSY is returned if pages cannot be flushed due to +# conflicting read locks. +# +do_execsql_test 1.4.0 { + COMMIT; + BEGIN; + INSERT INTO t1 VALUES(9, 10); +} +do_test 1.4.1 { + sqlite3 db2 test.db + db2 eval { + BEGIN; + SELECT * FROM t1; + } + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8} +do_test 1.4.2 { + list [catch { sqlite3_db_cacheflush db } msg] $msg +} {1 {database is locked}} +do_test 1.4.3 { + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8} +do_test 1.4.4 { + db2 close + sqlite3_db_cacheflush db + diskquery test.db { + SELECT * FROM t1; + } +} {1 2 3 4 5 6 7 8 9 10} +do_execsql_test 1.4.5 { COMMIT } + +#------------------------------------------------------------------------- +# Test that ATTACHed database caches are also flushed. +# +forcedelete test.db2 +do_execsql_test 2.1.0 { + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.t4(x, y); + INSERT INTO t4 VALUES('A', 'B'); + BEGIN; + INSERT INTO t1 VALUES(11, 12); + INSERT INTO t4 VALUES('C', 'D'); +} +do_test 2.1.1 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10} +do_test 2.1.2 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B} +do_test 2.1.3 { + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.1.4 { + sqlite3_db_cacheflush db + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D} +do_execsql_test 2.1.5 { COMMIT } + +# And that hitting an SQLITE_BUSY when flushing "main" does not stop +# SQLite from going on to flush "aux". +# +do_execsql_test 2.2.0 { + BEGIN; + INSERT INTO t1 VALUES(13, 14); + INSERT INTO t4 VALUES('E', 'F'); +} +do_test 2.2.1 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.2.2 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D} +do_test 2.2.3 { + sqlite3 db2 test.db + execsql { + BEGIN; + SELECT * FROM t1; + } db2 + list [catch { sqlite3_db_cacheflush db } msg] $msg +} {1 {database is locked}} +do_test 2.2.4 { + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12} +do_test 2.2.5 { + diskquery test.db2 { SELECT * FROM t4; } +} {A B C D E F} +do_test 2.2.6 { + db2 close + sqlite3_db_cacheflush db + diskquery test.db { SELECT * FROM t1; } +} {1 2 3 4 5 6 7 8 9 10 11 12 13 14} +do_execsql_test 2.2.7 { COMMIT } + +test_restore_config_pagecache +finish_test + diff --git a/test/cffault.test b/test/cffault.test new file mode 100644 index 0000000000..e90bbac55f --- /dev/null +++ b/test/cffault.test @@ -0,0 +1,57 @@ +# 2011 November 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains fault-injection test cases for the +# sqlite3_db_cacheflush API. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix cacheflush +source $testdir/malloc_common.tcl + +# Run the supplied SQL on a copy of the database currently stored on +# disk in file $dbfile. +proc diskquery {dbfile sql} { + forcecopy $dbfile dq.db + sqlite3 dq dq.db + set res [execsql $sql dq] + dq close + set res +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b); + CREATE INDEX i1 ON t1(b); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES(5, 6); + INSERT INTO t1 VALUES(7, 8); +} +faultsim_save_and_close + +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval COMMIT } + faultsim_integrity_check +} + + +finish_test + From 1167d32716f252b2db4a5478f7dba406ed6f30b3 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Oct 2015 20:01:45 +0000 Subject: [PATCH 46/55] Make the internal sqlite3PExpr() interface responsive to the TKFLG_DONTFOLD flag on the operator parameter. FossilOrigin-Name: b10ab59fb8a696d11a269f3904e799c687246aea --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 4 ++-- src/wherecode.c | 2 +- tool/addopcodes.tcl | 12 ++++++++++++ 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index b070a768f7..8de5fc1b0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sadding\sNOT\sexpression\snodes\sin\sthe\sparser\sinto\sa\ssubroutine. -D 2015-10-28T16:05:10.981 +C Make\sthe\sinternal\ssqlite3PExpr()\sinterface\sresponsive\sto\sthe\s\nTKFLG_DONTFOLD\sflag\son\sthe\soperator\sparameter. +D 2015-10-28T20:01:45.528 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -292,7 +292,7 @@ F src/ctime.c 509ef9c64d1321f42448f111da86400b1799218a F src/date.c fb1c99172017dcc8e237339132c91a21a0788584 F src/dbstat.c e637e7a7ff40ef32132a418c6fdf1cfb63aa27c7 F src/delete.c c4c6fb9da78b946fcba2a6aac5b24bc5c15e752a -F src/expr.c ea3e0c2981ffc7bd358714fa6d5132cb2cd5fc3a +F src/expr.c 0080c0f12806eca91e75a23a121a68918e9da357 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 31900763094a3736a5fc887469202eb579fef2d0 F src/func.c ecdd69ec6a1e406f04cc73324be2ebbf6354197f @@ -419,7 +419,7 @@ F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 2e14d17f592d176b6dc879c33fbdec4fbccaa2ba F src/where.c 6aceb72cc58dc06922a9e1604d559c8ca4c3e728 F src/whereInt.h 7892bb54cf9ca0ae5c7e6094491b94c9286dc647 -F src/wherecode.c 9aa2043685ec3eb73e87fa6f50aa4ec092f197dd +F src/wherecode.c 4c96182e7b25e4be54008dee2da5b9c2f8480b9b F src/whereexpr.c e63244ca06c503e5f3c5b7f3c9aea0db826089ed F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1338,7 +1338,7 @@ F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 8606413d3035c05373a0d7fae82ebf59ae9e16c3 -F tool/addopcodes.tcl 7cc82ecca456a6b3148abf492b0419b83140881a +F tool/addopcodes.tcl 26892c394964c194fe96b9a79b8b9f87347c7151 F tool/build-all-msvc.bat 2b1703b322da121e56b955cb58de091107f777c3 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1395,7 +1395,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P a85c2a4758c27e8d5d0395751eb3cfd9985ce696 -R fb08eb2aea7ef14b6808d0fed46a7f2e +P 001854181640bd9b088f2bc16083d84808c3da18 +R ca779455a4e2d31dd1a99251ed996c19 U drh -Z 776eb09f5d20f370f46eb3dbeaa8d2e2 +Z ce0b658ce638a8cefdcd82fe22a3bf7b diff --git a/manifest.uuid b/manifest.uuid index 0f39a06726..dc744792e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -001854181640bd9b088f2bc16083d84808c3da18 \ No newline at end of file +b10ab59fb8a696d11a269f3904e799c687246aea \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 1c6d7879fc..6371e15ca7 100644 --- a/src/expr.c +++ b/src/expr.c @@ -548,11 +548,11 @@ Expr *sqlite3PExpr( const Token *pToken /* Argument token */ ){ Expr *p; - if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){ + if( op==TK_AND && pParse->nErr==0 ){ /* Take advantage of short-circuit false optimization for AND */ p = sqlite3ExprAnd(pParse->db, pLeft, pRight); }else{ - p = sqlite3ExprAlloc(pParse->db, op, pToken, 1); + p = sqlite3ExprAlloc(pParse->db, op & TKFLG_MASK, pToken, 1); sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); } if( p ) { diff --git a/src/wherecode.c b/src/wherecode.c index cf3d601e2b..87db0e0a25 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1399,7 +1399,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); } if( pAndExpr ){ - pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0); + pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0); } } diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index 46675cb258..c5c3525ad4 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -43,3 +43,15 @@ foreach x $extras { incr max puts [format "#define TK_%-29s %4d" $x $max] } + +# Some additional #defines related to token codes. +# +puts "\n/* The token codes above must all fit in 8 bits */" +puts [format "#define %-20s %-6s" TKFLG_MASK 0xff] +puts "\n/* Flags that can be added to a token code when it is not" +puts "** being stored in a u8: */" +foreach {fg val comment} { + TKFLG_DONTFOLD 0x100 {/* Omit constant folding optimizations */} +} { + puts [format "#define %-20s %-6s %s" $fg $val $comment] +} From de4148e304512686cac28013cb1cdccb1978918a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 29 Oct 2015 01:11:39 +0000 Subject: [PATCH 47/55] Enhance comments in the MSVC batch build tool. FossilOrigin-Name: 2964ce25864e8aec86272af741caf49c23c86590 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/build-all-msvc.bat | 4 ++++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8de5fc1b0f..8948b0157f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\sinternal\ssqlite3PExpr()\sinterface\sresponsive\sto\sthe\s\nTKFLG_DONTFOLD\sflag\son\sthe\soperator\sparameter. -D 2015-10-28T20:01:45.528 +C Enhance\scomments\sin\sthe\sMSVC\sbatch\sbuild\stool. +D 2015-10-29T01:11:39.776 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -1339,7 +1339,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 8606413d3035c05373a0d7fae82ebf59ae9e16c3 F tool/addopcodes.tcl 26892c394964c194fe96b9a79b8b9f87347c7151 -F tool/build-all-msvc.bat 2b1703b322da121e56b955cb58de091107f777c3 x +F tool/build-all-msvc.bat e42141ca3c3812315432f9813ef9eb78aa8d99c9 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -1395,7 +1395,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 001854181640bd9b088f2bc16083d84808c3da18 -R ca779455a4e2d31dd1a99251ed996c19 -U drh -Z ce0b658ce638a8cefdcd82fe22a3bf7b +P b10ab59fb8a696d11a269f3904e799c687246aea +R cc38e20a3bed22c727ef2060f0363586 +U mistachkin +Z f9c898158c1864e737c38818df859932 diff --git a/manifest.uuid b/manifest.uuid index dc744792e0..2101e8fe36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b10ab59fb8a696d11a269f3904e799c687246aea \ No newline at end of file +2964ce25864e8aec86272af741caf49c23c86590 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index a8ba1bc293..e081c73b38 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -95,6 +95,10 @@ REM example: REM REM SET NMAKE_ARGS=FOR_WINRT=1 REM +REM Using the above command before running this tool will cause the compiled +REM binaries to target the WinRT environment, which provides a subset of the +REM Win32 API. +REM SETLOCAL REM SET __ECHO=ECHO From c56fac7483c195e4d309efc5e4459579fde2e77e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Oct 2015 13:48:15 +0000 Subject: [PATCH 48/55] Fix uses of ctype functions (ex: isspace()) on signed characters in test programs and in some obscure extensions. No changes to the core. FossilOrigin-Name: 34eb6911afee09e779318b79baf953f616200128 --- autoconf/tea/win/nmakehlp.c | 6 +-- ext/fts1/fts1.c | 6 +-- ext/fts1/simple_tokenizer.c | 2 +- ext/misc/amatch.c | 4 +- ext/misc/closure.c | 4 +- ext/misc/spellfix.c | 2 +- manifest | 46 ++++++++++----------- manifest.uuid | 2 +- mptest/mptest.c | 41 ++++++++++--------- test/fuzzcheck.c | 9 ++-- test/speedtest1.c | 6 ++- test/wordcount.c | 5 ++- tool/fuzzershell.c | 3 +- tool/lemon.c | 82 ++++++++++++++++++++----------------- tool/showdb.c | 12 +++--- tool/showstat4.c | 4 +- tool/showwal.c | 7 +++- tool/speedtest16.c | 4 +- tool/speedtest8inst1.c | 4 +- 19 files changed, 139 insertions(+), 110 deletions(-) diff --git a/autoconf/tea/win/nmakehlp.c b/autoconf/tea/win/nmakehlp.c index 2868857efd..e00f1b4996 100644 --- a/autoconf/tea/win/nmakehlp.c +++ b/autoconf/tea/win/nmakehlp.c @@ -603,8 +603,8 @@ SubstituteFile( sp = fopen(substitutions, "rt"); if (sp != NULL) { while (fgets(szBuffer, cbBuffer, sp) != NULL) { - char *ks, *ke, *vs, *ve; - ks = szBuffer; + unsigned char *ks, *ke, *vs, *ve; + ks = (unsigned char*)szBuffer; while (ks && *ks && isspace(*ks)) ++ks; ke = ks; while (ke && *ke && !isspace(*ke)) ++ke; @@ -613,7 +613,7 @@ SubstituteFile( ve = vs; while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve; *ke = 0, *ve = 0; - list_insert(&substPtr, ks, vs); + list_insert(&substPtr, (char*)ks, (char*)vs); } fclose(sp); } diff --git a/ext/fts1/fts1.c b/ext/fts1/fts1.c index 482cf759ba..77fa9e23f5 100644 --- a/ext/fts1/fts1.c +++ b/ext/fts1/fts1.c @@ -205,13 +205,13 @@ static int getVarint32(const char *p, int *pi){ */ /* TODO(shess) Is __isascii() a portable version of (c&0x80)==0? */ static int safe_isspace(char c){ - return (c&0x80)==0 ? isspace(c) : 0; + return (c&0x80)==0 ? isspace((unsigned char)c) : 0; } static int safe_tolower(char c){ - return (c&0x80)==0 ? tolower(c) : c; + return (c&0x80)==0 ? tolower((unsigned char)c) : c; } static int safe_isalnum(char c){ - return (c&0x80)==0 ? isalnum(c) : 0; + return (c&0x80)==0 ? isalnum((unsigned char)c) : 0; } typedef enum DocListType { diff --git a/ext/fts1/simple_tokenizer.c b/ext/fts1/simple_tokenizer.c index d00a77089d..0ddc7055af 100644 --- a/ext/fts1/simple_tokenizer.c +++ b/ext/fts1/simple_tokenizer.c @@ -138,7 +138,7 @@ static int simpleNext( ** case-insensitivity. */ char ch = c->pCurrent[ii]; - c->zToken[ii] = (unsigned char)ch<0x80 ? tolower(ch) : ch; + c->zToken[ii] = (unsigned char)ch<0x80 ? tolower((unsigned char)ch):ch; } c->zToken[n] = '\0'; *ppToken = c->zToken; diff --git a/ext/misc/amatch.c b/ext/misc/amatch.c index d08ef57aad..852491988a 100644 --- a/ext/misc/amatch.c +++ b/ext/misc/amatch.c @@ -816,10 +816,10 @@ static const char *amatchValueOfKey(const char *zKey, const char *zStr){ int i; if( nStr #include +#define ISSPACE(X) isspace((unsigned char)(X)) +#define ISDIGIT(X) isdigit((unsigned char)(X)) + /* The suffix to append to the child command lines, if any */ #if defined(_WIN32) # define GETPID (int)GetCurrentProcessId @@ -187,10 +190,10 @@ int strglob(const char *zGlob, const char *z){ } if( c2==0 || (seen ^ invert)==0 ) return 0; }else if( c=='#' ){ - if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++; - if( !isdigit(z[0]) ) return 0; + if( (z[0]=='-' || z[0]=='+') && ISDIGIT(z[1]) ) z++; + if( !ISDIGIT(z[0]) ) return 0; z++; - while( isdigit(z[0]) ){ z++; } + while( ISDIGIT(z[0]) ){ z++; } }else{ if( c!=(*(z++)) ) return 0; } @@ -289,7 +292,7 @@ static void logMessage(const char *zFormat, ...){ */ static int clipLength(const char *z){ int n = (int)strlen(z); - while( n>0 && isspace(z[n-1]) ){ n--; } + while( n>0 && ISSPACE(z[n-1]) ){ n--; } return n; } @@ -444,7 +447,7 @@ static void stringAppendTerm(String *p, const char *z){ stringAppend(p, "nil", 3); return; } - for(i=0; z[i] && !isspace(z[i]); i++){} + for(i=0; z[i] && !ISSPACE(z[i]); i++){} if( i>0 && z[i]==0 ){ stringAppend(p, z, i); return; @@ -699,7 +702,7 @@ static char *readFile(const char *zFilename){ */ static int tokenLength(const char *z, int *pnLine){ int n = 0; - if( isspace(z[0]) || (z[0]=='/' && z[1]=='*') ){ + if( ISSPACE(z[0]) || (z[0]=='/' && z[1]=='*') ){ int inC = 0; int c; if( z[0]=='/' ){ @@ -708,7 +711,7 @@ static int tokenLength(const char *z, int *pnLine){ } while( (c = z[n++])!=0 ){ if( c=='\n' ) (*pnLine)++; - if( isspace(c) ) continue; + if( ISSPACE(c) ) continue; if( inC && c=='*' && z[n]=='/' ){ n++; inC = 0; @@ -734,7 +737,7 @@ static int tokenLength(const char *z, int *pnLine){ } }else{ int c; - for(n=1; (c = z[n])!=0 && !isspace(c) && c!='"' && c!='\'' && c!=';'; n++){} + for(n=1; (c = z[n])!=0 && !ISSPACE(c) && c!='"' && c!='\'' && c!=';'; n++){} } return n; } @@ -748,7 +751,7 @@ static int extractToken(const char *zIn, int nIn, char *zOut, int nOut){ zOut[0] = 0; return 0; } - for(i=0; i=2 ) logMessage("%.*s", len, zScript+ii); n = extractToken(zScript+ii+2, len-2, zCmd, sizeof(zCmd)); for(nArg=0; n=len-2 ) break; n += extractToken(zScript+ii+2+n, len-2-n, azArg[nArg], sizeof(azArg[nArg])); @@ -976,7 +979,7 @@ static void runScript( if( strcmp(zCmd, "match")==0 ){ int jj; char *zAns = zScript+ii; - for(jj=7; jj #include #include "sqlite3.h" +#define ISSPACE(X) isspace((unsigned char)(X)) +#define ISDIGIT(X) isdigit((unsigned char)(X)) + #ifdef __unix__ # include @@ -633,9 +636,9 @@ static void runSql(sqlite3 *db, const char *zSql, unsigned runFlags){ if( runFlags & SQL_TRACE ){ const char *z = zSql; int n; - while( z0 && isspace(z[n-1]) ) n--; + while( n>0 && ISSPACE(z[n-1]) ) n--; if( n==0 ) break; if( pStmt==0 ){ printf("TRACE: %.*s (error: %s)\n", n, z, sqlite3_errmsg(db)); @@ -757,7 +760,7 @@ static int integerValue(const char *zArg){ zArg++; } }else{ - while( isdigit(zArg[0]) ){ + while( ISDIGIT(zArg[0]) ){ v = v*10 + zArg[0] - '0'; zArg++; } diff --git a/test/speedtest1.c b/test/speedtest1.c index b34dae65ae..b41c732053 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -47,6 +47,8 @@ static const char zHelp[] = #include #include #include +#define ISSPACE(X) isspace((unsigned char)(X)) +#define ISDIGIT(X) isdigit((unsigned char)(X)) #if SQLITE_VERSION_NUMBER<3005000 # define sqlite3_int64 sqlite_int64 @@ -315,7 +317,7 @@ void speedtest1_final(void){ /* Print an SQL statement to standard output */ static void printSql(const char *zSql){ int n = (int)strlen(zSql); - while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } + while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ){ n--; } if( g.bExplain ) printf("EXPLAIN "); printf("%.*s;\n", n, zSql); if( g.bExplain @@ -414,7 +416,7 @@ void speedtest1_run(void){ /* The sqlite3_trace() callback function */ static void traceCallback(void *NotUsed, const char *zSql){ int n = (int)strlen(zSql); - while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ) n--; + while( n>0 && (zSql[n-1]==';' || ISSPACE(zSql[n-1])) ) n--; fprintf(stderr,"%.*s;\n", n, zSql); } diff --git a/test/wordcount.c b/test/wordcount.c index cf63e983c2..72aa6b2f0b 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -80,6 +80,7 @@ #include #include #include "sqlite3.h" +#define ISALPHA(X) isalpha((unsigned char)(X)) /* Return the current wall-clock time */ static sqlite3_int64 realTime(void){ @@ -392,8 +393,8 @@ int main(int argc, char **argv){ /* Process the input file */ while( fgets(zInput, sizeof(zInput), in) ){ for(i=0; zInput[i]; i++){ - if( !isalpha(zInput[i]) ) continue; - for(j=i+1; isalpha(zInput[j]); j++){} + if( !ISALPHA(zInput[i]) ) continue; + for(j=i+1; ISALPHA(zInput[j]); j++){} /* Found a new word at zInput[i] that is j-i bytes long. ** Process it into the wordcount table. */ diff --git a/tool/fuzzershell.c b/tool/fuzzershell.c index 6754a071e3..2c778bce6e 100644 --- a/tool/fuzzershell.c +++ b/tool/fuzzershell.c @@ -67,6 +67,7 @@ #include #include #include "sqlite3.h" +#define ISDIGIT(X) isdigit((unsigned char)(X)) /* ** All global variables are gathered into the "g" singleton. @@ -383,7 +384,7 @@ static int integerValue(const char *zArg){ zArg++; } }else{ - while( isdigit(zArg[0]) ){ + while( ISDIGIT(zArg[0]) ){ v = v*10 + zArg[0] - '0'; zArg++; } diff --git a/tool/lemon.c b/tool/lemon.c index 2e8054b5cc..d704deb624 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -13,6 +13,14 @@ #include #include +#define ISSPACE(X) isspace((unsigned char)(X)) +#define ISDIGIT(X) isdigit((unsigned char)(X)) +#define ISALNUM(X) isalnum((unsigned char)(X)) +#define ISALPHA(X) isalpha((unsigned char)(X)) +#define ISUPPER(X) isupper((unsigned char)(X)) +#define ISLOWER(X) islower((unsigned char)(X)) + + #ifndef __WIN32__ # if defined(_WIN32) || defined(WIN32) # define __WIN32__ @@ -93,9 +101,9 @@ static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){ int iWidth = 0; lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0); c = zFormat[++i]; - if( isdigit(c) || (c=='-' && isdigit(zFormat[i+1])) ){ + if( ISDIGIT(c) || (c=='-' && ISDIGIT(zFormat[i+1])) ){ if( c=='-' ) i++; - while( isdigit(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0'; + while( ISDIGIT(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0'; if( c=='-' ) iWidth = -iWidth; c = zFormat[i]; } @@ -1578,7 +1586,7 @@ int main(int argc, char **argv) while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; } assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 ); lem.nsymbol = i - 1; - for(i=1; isupper(lem.symbols[i]->name[0]); i++); + for(i=1; ISUPPER(lem.symbols[i]->name[0]); i++); lem.nterminal = i; /* Generate a reprint of the grammar, if requested on the command line */ @@ -2121,7 +2129,7 @@ static void parseonetoken(struct pstate *psp) case WAITING_FOR_DECL_OR_RULE: if( x[0]=='%' ){ psp->state = WAITING_FOR_DECL_KEYWORD; - }else if( islower(x[0]) ){ + }else if( ISLOWER(x[0]) ){ psp->lhs = Symbol_new(x); psp->nrhs = 0; psp->lhsalias = 0; @@ -2151,7 +2159,7 @@ to follow the previous rule."); } break; case PRECEDENCE_MARK_1: - if( !isupper(x[0]) ){ + if( !ISUPPER(x[0]) ){ ErrorMsg(psp->filename,psp->tokenlineno, "The precedence symbol must be a terminal."); psp->errorcnt++; @@ -2191,7 +2199,7 @@ to follow the previous rule."); } break; case LHS_ALIAS_1: - if( isalpha(x[0]) ){ + if( ISALPHA(x[0]) ){ psp->lhsalias = x; psp->state = LHS_ALIAS_2; }else{ @@ -2260,7 +2268,7 @@ to follow the previous rule."); psp->prevrule = rp; } psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isalpha(x[0]) ){ + }else if( ISALPHA(x[0]) ){ if( psp->nrhs>=MAXRHS ){ ErrorMsg(psp->filename,psp->tokenlineno, "Too many symbols on RHS of rule beginning at \"%s\".", @@ -2289,7 +2297,7 @@ to follow the previous rule."); msp->subsym = (struct symbol **) realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]); - if( islower(x[1]) || islower(msp->subsym[0]->name[0]) ){ + if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){ ErrorMsg(psp->filename,psp->tokenlineno, "Cannot form a compound containing a non-terminal"); psp->errorcnt++; @@ -2304,7 +2312,7 @@ to follow the previous rule."); } break; case RHS_ALIAS_1: - if( isalpha(x[0]) ){ + if( ISALPHA(x[0]) ){ psp->alias[psp->nrhs-1] = x; psp->state = RHS_ALIAS_2; }else{ @@ -2326,7 +2334,7 @@ to follow the previous rule."); } break; case WAITING_FOR_DECL_KEYWORD: - if( isalpha(x[0]) ){ + if( ISALPHA(x[0]) ){ psp->declkeyword = x; psp->declargslot = 0; psp->decllinenoslot = 0; @@ -2406,7 +2414,7 @@ to follow the previous rule."); } break; case WAITING_FOR_DESTRUCTOR_SYMBOL: - if( !isalpha(x[0]) ){ + if( !ISALPHA(x[0]) ){ ErrorMsg(psp->filename,psp->tokenlineno, "Symbol name missing after %%destructor keyword"); psp->errorcnt++; @@ -2420,7 +2428,7 @@ to follow the previous rule."); } break; case WAITING_FOR_DATATYPE_SYMBOL: - if( !isalpha(x[0]) ){ + if( !ISALPHA(x[0]) ){ ErrorMsg(psp->filename,psp->tokenlineno, "Symbol name missing after %%type keyword"); psp->errorcnt++; @@ -2445,7 +2453,7 @@ to follow the previous rule."); case WAITING_FOR_PRECEDENCE_SYMBOL: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) ){ + }else if( ISUPPER(x[0]) ){ struct symbol *sp; sp = Symbol_new(x); if( sp->prec>=0 ){ @@ -2463,7 +2471,7 @@ to follow the previous rule."); } break; case WAITING_FOR_DECL_ARG: - if( x[0]=='{' || x[0]=='\"' || isalnum(x[0]) ){ + if( x[0]=='{' || x[0]=='\"' || ISALNUM(x[0]) ){ const char *zOld, *zNew; char *zBuf, *z; int nOld, n, nLine = 0, nNew, nBack; @@ -2524,7 +2532,7 @@ to follow the previous rule."); case WAITING_FOR_FALLBACK_ID: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ + }else if( !ISUPPER(x[0]) ){ ErrorMsg(psp->filename, psp->tokenlineno, "%%fallback argument \"%s\" should be a token", x); psp->errorcnt++; @@ -2545,7 +2553,7 @@ to follow the previous rule."); case WAITING_FOR_WILDCARD_ID: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( !isupper(x[0]) ){ + }else if( !ISUPPER(x[0]) ){ ErrorMsg(psp->filename, psp->tokenlineno, "%%wildcard argument \"%s\" should be a token", x); psp->errorcnt++; @@ -2561,7 +2569,7 @@ to follow the previous rule."); } break; case WAITING_FOR_CLASS_ID: - if( !islower(x[0]) ){ + if( !ISLOWER(x[0]) ){ ErrorMsg(psp->filename, psp->tokenlineno, "%%token_class must be followed by an identifier: ", x); psp->errorcnt++; @@ -2580,12 +2588,12 @@ to follow the previous rule."); case WAITING_FOR_CLASS_TOKEN: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; - }else if( isupper(x[0]) || ((x[0]=='|' || x[0]=='/') && isupper(x[1])) ){ + }else if( ISUPPER(x[0]) || ((x[0]=='|' || x[0]=='/') && ISUPPER(x[1])) ){ struct symbol *msp = psp->tkclass; msp->nsubsym++; msp->subsym = (struct symbol **) realloc(msp->subsym, sizeof(struct symbol*)*msp->nsubsym); - if( !isupper(x[0]) ) x++; + if( !ISUPPER(x[0]) ) x++; msp->subsym[msp->nsubsym-1] = Symbol_new(x); }else{ ErrorMsg(psp->filename, psp->tokenlineno, @@ -2618,7 +2626,7 @@ static void preprocess_input(char *z){ for(i=0; z[i]; i++){ if( z[i]=='\n' ) lineno++; if( z[i]!='%' || (i>0 && z[i-1]!='\n') ) continue; - if( strncmp(&z[i],"%endif",6)==0 && isspace(z[i+6]) ){ + if( strncmp(&z[i],"%endif",6)==0 && ISSPACE(z[i+6]) ){ if( exclude ){ exclude--; if( exclude==0 ){ @@ -2626,13 +2634,13 @@ static void preprocess_input(char *z){ } } for(j=i; z[j] && z[j]!='\n'; j++) z[j] = ' '; - }else if( (strncmp(&z[i],"%ifdef",6)==0 && isspace(z[i+6])) - || (strncmp(&z[i],"%ifndef",7)==0 && isspace(z[i+7])) ){ + }else if( (strncmp(&z[i],"%ifdef",6)==0 && ISSPACE(z[i+6])) + || (strncmp(&z[i],"%ifndef",7)==0 && ISSPACE(z[i+7])) ){ if( exclude ){ exclude++; }else{ - for(j=i+7; isspace(z[j]); j++){} - for(n=0; z[j+n] && !isspace(z[j+n]); n++){} + for(j=i+7; ISSPACE(z[j]); j++){} + for(n=0; z[j+n] && !ISSPACE(z[j+n]); n++){} exclude = 1; for(k=0; kiStart ) fprintf(out,"%.*s",i-iStart,&line[iStart]); fprintf(out,"%s",name); @@ -3478,9 +3486,9 @@ PRIVATE void translate_code(struct lemon *lemp, struct rule *rp){ /* This const cast is wrong but harmless, if we're careful. */ for(cp=(char *)rp->code; *cp; cp++){ - if( isalpha(*cp) && (cp==rp->code || (!isalnum(cp[-1]) && cp[-1]!='_')) ){ + if( ISALPHA(*cp) && (cp==rp->code || (!ISALNUM(cp[-1]) && cp[-1]!='_')) ){ char saved; - for(xp= &cp[1]; isalnum(*xp) || *xp=='_'; xp++); + for(xp= &cp[1]; ISALNUM(*xp) || *xp=='_'; xp++); saved = *xp; *xp = 0; if( rp->lhsalias && strcmp(cp,rp->lhsalias)==0 ){ @@ -3645,9 +3653,9 @@ void print_stack_union( cp = sp->datatype; if( cp==0 ) cp = lemp->vartype; j = 0; - while( isspace(*cp) ) cp++; + while( ISSPACE(*cp) ) cp++; while( *cp ) stddt[j++] = *cp++; - while( j>0 && isspace(stddt[j-1]) ) j--; + while( j>0 && ISSPACE(stddt[j-1]) ) j--; stddt[j] = 0; if( lemp->tokentype && strcmp(stddt, lemp->tokentype)==0 ){ sp->dtnum = 0; @@ -3857,8 +3865,8 @@ void ReportTable( name = lemp->name ? lemp->name : "Parse"; if( lemp->arg && lemp->arg[0] ){ i = lemonStrlen(lemp->arg); - while( i>=1 && isspace(lemp->arg[i-1]) ) i--; - while( i>=1 && (isalnum(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; + while( i>=1 && ISSPACE(lemp->arg[i-1]) ) i--; + while( i>=1 && (ISALNUM(lemp->arg[i-1]) || lemp->arg[i-1]=='_') ) i--; fprintf(out,"#define %sARG_SDECL %s;\n",name,lemp->arg); lineno++; fprintf(out,"#define %sARG_PDECL ,%s\n",name,lemp->arg); lineno++; fprintf(out,"#define %sARG_FETCH %s = yypParser->%s\n", @@ -4666,7 +4674,7 @@ struct symbol *Symbol_new(const char *x) sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); MemoryCheck(sp); sp->name = Strsafe(x); - sp->type = isupper(*x) ? TERMINAL : NONTERMINAL; + sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL; sp->rule = 0; sp->fallback = 0; sp->prec = -1; diff --git a/tool/showdb.c b/tool/showdb.c index 892cacd552..38b92f1f7d 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -3,6 +3,8 @@ */ #include #include +#define ISDIGIT(X) isdigit((unsigned char)(X)) +#define ISPRINT(X) isprint((unsigned char)(X)) #include #include #include @@ -217,7 +219,7 @@ static unsigned char *print_byte_range( if( i+j>nByte ){ fprintf(stdout, " "); }else{ - fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); + fprintf(stdout,"%c", ISPRINT(aData[i+j]) ? aData[i+j] : '.'); } } fprintf(stdout,"\n"); @@ -600,7 +602,7 @@ static void decodeCell( }else{ zConst[0] = '\''; for(ii=1, jj=0; jj #include "sqlite3.h" +#define ISPRINT(X) isprint((unsigned char)(X)) + typedef sqlite3_int64 i64; /* 64-bit signed integer type */ @@ -131,7 +133,7 @@ int main(int argc, char **argv){ printf("%s\"", zSep); for(j=0; j #include +#define ISDIGIT(X) isdigit((unsigned char)(X)) +#define ISPRINT(X) isprint((unsigned char)(X)) + #if !defined(_MSC_VER) #include #else @@ -159,7 +162,7 @@ static void print_byte_range( if( i+j>nByte ){ fprintf(stdout, " "); }else{ - fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); + fprintf(stdout,"%c", ISPRINT(aData[i+j]) ? aData[i+j] : '.'); } } fprintf(stdout,"\n"); @@ -550,7 +553,7 @@ int main(int argc, char **argv){ print_wal_header(0); continue; } - if( !isdigit(argv[i][0]) ){ + if( !ISDIGIT(argv[i][0]) ){ fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]); continue; } diff --git a/tool/speedtest16.c b/tool/speedtest16.c index e81f1a6dba..993cc19268 100644 --- a/tool/speedtest16.c +++ b/tool/speedtest16.c @@ -29,6 +29,8 @@ #include #include "sqlite3.h" +#define ISSPACE(X) isspace((unsigned char)(X)) + /* ** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. @@ -140,7 +142,7 @@ int main(int argc, char **argv){ zSql[j+1] = c; if( isComplete ){ zSql[j] = 0; - while( i #include "sqlite3.h" +#define ISSPACE(X) isspace((unsigned char)(X)) + #include "test_osinst.c" /* @@ -197,7 +199,7 @@ int main(int argc, char **argv){ zSql[j+1] = c; if( isComplete ){ zSql[j] = 0; - while( i Date: Thu, 29 Oct 2015 18:16:40 +0000 Subject: [PATCH 49/55] Avoid automatically rolling back the transaction if an SQLITE_IOERR or SQLITE_FULL error occurs within sqlite3_db_cacheflush(). FossilOrigin-Name: 370b5d520c6523526988d0db5299f1bd09567782 --- manifest | 21 ++++------ manifest.uuid | 2 +- src/main.c | 3 -- src/pager.c | 20 +++++---- src/sqlite.h.in | 1 - test/cffault.test | 104 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 125 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 866a53b656..4ea95b624f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\sAPI\ssqlite3_db_cacheflush(). -D 2015-10-28T19:46:57.460 +C Avoid\sautomatically\srolling\sback\sthe\stransaction\sif\san\sSQLITE_IOERR\sor\sSQLITE_FULL\serror\soccurs\swithin\ssqlite3_db_cacheflush(). +D 2015-10-29T18:16:40.382 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -305,7 +305,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/lempar.c d344a95d60c24e2f490ee59db9784b1b17439012 F src/loadext.c 18586e45a215325f15096821e9c082035d4fb810 -F src/main.c b9d020342b2a2b13808c6260792ef233d7af5b1d +F src/main.c f393acc6e5d604cbe0054376d62f668a5560b3f1 F src/malloc.c 337bbe9c7d436ef9b7d06b5dd10bbfc8f3025972 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 059991ce76b1a857cb84dd2469cfcfaaae1d77fa +F src/pager.c 2f9de81ebc87f92814ffc1e34f478a6de7c869b0 F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -342,7 +342,7 @@ F src/resolve.c 1954a0f01bf65d78d7d559aea3d5c67f33376d91 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 167b4e9058bc8e997d18d6b6b20ecbb0c9c457af F src/shell.c d25df04168d6ba5a4fa05bdbf859df667f9eb621 -F src/sqlite.h.in e7da8d15141d0753bfe14945bd64592a42575c04 +F src/sqlite.h.in 3cfc86c55e57c63d86b9e1e92869e2bfb162ca8e F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h 4b66e3e3435da4b4c8c83696d0349f0c503b3924 F src/sqliteInt.h b1e72ffe282c91ae30a2bf403319126dbaebd556 @@ -511,7 +511,7 @@ F test/capi3c.test fdc0d67a2cb8e8fc400d5b7735e330161ea057a2 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/cffault.test 1383919788fa50db60f6119da5785c62fbc8b527 +F test/cffault.test 1647eef45512817265c360ed4539538eed26ac69 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -1397,10 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 001854181640bd9b088f2bc16083d84808c3da18 -R 2dbc861fa3cf60b53d3ec06b17c9981a -T *branch * cacheflush -T *sym-cacheflush * -T -sym-trunk * +P 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 +R a2eb49b0b44e5f6d387cfe5db61ab944 U dan -Z c07109c8cca9fe678b00367209f93a20 +Z 0108dff3f79bd94c840ccf22fb26067f diff --git a/manifest.uuid b/manifest.uuid index ac6d5b874a..114b47522f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -65b86dc1fa4a57cc3cde86a820d9f848aa288a15 \ No newline at end of file +370b5d520c6523526988d0db5299f1bd09567782 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 324415b0cf..56d4588494 100644 --- a/src/main.c +++ b/src/main.c @@ -765,9 +765,6 @@ int sqlite3_db_cacheflush(sqlite3 *db){ } } } - if( rc!=SQLITE_OK ){ - sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - } sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); diff --git a/src/pager.c b/src/pager.c index f21f0802ba..09d4935f27 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4477,9 +4477,10 @@ static int pagerStress(void *p, PgHdr *pPg){ ** Flush all unreferenced dirty pages to disk. */ int sqlite3PagerFlush(Pager *pPager){ - int rc = SQLITE_OK; + int rc = pPager->errCode; PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); while( rc==SQLITE_OK && pList ){ PgHdr *pNext = pList->pDirty; if( pList->nRef==0 ){ @@ -6093,14 +6094,17 @@ int sqlite3PagerSync(Pager *pPager, const char *zMaster){ ** returned. */ int sqlite3PagerExclusiveLock(Pager *pPager){ - int rc = SQLITE_OK; - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - || pPager->eState==PAGER_WRITER_LOCKED - ); + int rc = pPager->errCode; assert( assert_pager_state(pPager) ); - if( 0==pagerUseWal(pPager) ){ - rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + if( rc==SQLITE_OK ){ + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED + ); + assert( assert_pager_state(pPager) ); + if( 0==pagerUseWal(pPager) ){ + rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); + } } return rc; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6c04ff5102..961c5169fc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7814,7 +7814,6 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); ** If any other error occurs while flushing dirty pages to disk (for ** example an IO error or out-of-memory condition), then processing is ** abandoned and an SQLite error code returned to the caller immediately. -** In this case the open transaction may be automatically rolled back. ** ** Otherwise, if no error occurs, SQLITE_OK is returned. ** diff --git a/test/cffault.test b/test/cffault.test index e90bbac55f..a89477b617 100644 --- a/test/cffault.test +++ b/test/cffault.test @@ -38,7 +38,7 @@ do_execsql_test 1.0 { } faultsim_save_and_close -do_faultsim_test 1 -prep { +do_faultsim_test 1.1 -prep { faultsim_restore_and_reopen db eval { BEGIN; @@ -47,11 +47,113 @@ do_faultsim_test 1 -prep { } -body { sqlite3_db_cacheflush db } -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } faultsim_test_result {0 {}} {1 {disk I/O error}} catch { db eval COMMIT } faultsim_integrity_check } +do_faultsim_test 1.2 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + set result [list] + db eval { SELECT * FROM t1 } { + if {$a==5} { catch { sqlite3_db_cacheflush db } } + lappend result $a $b + } + set result +} -test { + faultsim_test_result {0 {1 3 3 5 5 7 7 9}} {1 {disk I/O error}} + catch { db eval COMMIT } + faultsim_integrity_check +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c); + CREATE INDEX i1 ON t1(b); + CREATE INDEX i2 ON t1(c, b); + INSERT INTO t1 VALUES(1, 2, randomblob(600)); + INSERT INTO t1 VALUES(3, 4, randomblob(600)); + INSERT INTO t1 VALUES(5, 6, randomblob(600)); + INSERT INTO t1 VALUES(7, 8, randomblob(600)); + INSERT INTO t1 VALUES(9, 10, randomblob(600)); +} +faultsim_save_and_close + +do_faultsim_test 2.1 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + set result [list] + db eval { SELECT * FROM t1 } { + if {$a==5} { catch { sqlite3_db_cacheflush db } } + lappend result $a $b + } + set result +} -test { + faultsim_test_result {0 {1 3 3 5 5 7 7 9 9 11}} {1 {disk I/O error}} + catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.2 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b+1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval { SELECT * FROM t1 } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.3 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b-1; + } +} -body { + sqlite3_db_cacheflush db +} -test { + if {[sqlite3_get_autocommit db]} { error "Transaction rolled back!" } + faultsim_test_result {0 {}} {1 {disk I/O error}} + catch { db eval { INSERT INTO t1 VALUES(11, 12, randomblob(600)) } } + catch { db eval COMMIT } + faultsim_integrity_check +} + +do_faultsim_test 2.4 -prep { + faultsim_restore_and_reopen + db eval { + BEGIN; + UPDATE t1 SET b=b-1; + } +} -body { + catch { sqlite3_db_cacheflush db } + catch { sqlite3_db_release_memory db } + catch { sqlite3_db_cacheflush db } + execsql { SELECT a, b FROM t1 } +} -test { + faultsim_test_result {0 {1 1 3 3 5 5 7 7 9 9}} {1 {disk I/O error}} + catchsql ROLLBACK + faultsim_integrity_check +} finish_test From 4a6beac28b3d76f20147ab6a62c8445051fffd9a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Oct 2015 20:57:06 +0000 Subject: [PATCH 50/55] Add a test case that calls sqlite3_db_cacheflush() on an in-memory database. FossilOrigin-Name: f0cdfb547b0976e753e94958f29cb294edf31bed --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/cacheflush.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4ea95b624f..8aa65b5535 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sautomatically\srolling\sback\sthe\stransaction\sif\san\sSQLITE_IOERR\sor\sSQLITE_FULL\serror\soccurs\swithin\ssqlite3_db_cacheflush(). -D 2015-10-29T18:16:40.382 +C Add\sa\stest\scase\sthat\scalls\ssqlite3_db_cacheflush()\son\san\sin-memory\sdatabase. +D 2015-10-29T20:57:06.654 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -503,7 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de -F test/cacheflush.test 95944e4210100c525ec301c060721e82210c33a5 +F test/cacheflush.test 42855120d2b00ff75033b54ba7693927f1ce4de8 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 65b86dc1fa4a57cc3cde86a820d9f848aa288a15 -R a2eb49b0b44e5f6d387cfe5db61ab944 +P 370b5d520c6523526988d0db5299f1bd09567782 +R e469742ef6d00761a1fbbbbf9de3f4b1 U dan -Z 0108dff3f79bd94c840ccf22fb26067f +Z 9ba99da9a0f7b492a3cba8ddbf944bbf diff --git a/manifest.uuid b/manifest.uuid index 114b47522f..b806a0d731 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -370b5d520c6523526988d0db5299f1bd09567782 \ No newline at end of file +f0cdfb547b0976e753e94958f29cb294edf31bed \ No newline at end of file diff --git a/test/cacheflush.test b/test/cacheflush.test index a9ee672b9f..785bc0c77a 100644 --- a/test/cacheflush.test +++ b/test/cacheflush.test @@ -202,6 +202,34 @@ do_test 2.2.6 { } {1 2 3 4 5 6 7 8 9 10 11 12 13 14} do_execsql_test 2.2.7 { COMMIT } +#------------------------------------------------------------------------- +# Test that nothing terrible happens if sqlite3_db_cacheflush() is +# called on an in-memory database. +# +do_test 3.0 { + db close + sqlite3 db :memory: + db eval { + CREATE TABLE t1(x PRIMARY KEY); + CREATE TABLE t2(y PRIMARY KEY); + BEGIN; + INSERT INTO t1 VALUES(randomblob(100)); + INSERT INTO t2 VALUES(randomblob(100)); + INSERT INTO t1 VALUES(randomblob(100)); + INSERT INTO t2 VALUES(randomblob(100)); + } + sqlite3_db_cacheflush db +} {} + +do_execsql_test 3.1 { PRAGMA integrity_check } ok +do_execsql_test 3.2 { COMMIT } +do_execsql_test 3.3 { PRAGMA integrity_check } ok +do_execsql_test 3.4 { + SELECT count(*) FROM t1; + SELECT count(*) FROM t2; +} {2 2} + + test_restore_config_pagecache finish_test From 9fb13abc6ef9f1a02c99f173a586ed24922c4a46 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Oct 2015 21:11:22 +0000 Subject: [PATCH 51/55] Do not attempt to flush the pages of an in-memory database to disk if sqlite3_db_cacheflush() is called. FossilOrigin-Name: 9b79a390440a23542a370b591e567b31ebb35c42 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 17 +++++++++-------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 8aa65b5535..2b97b8e039 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sthat\scalls\ssqlite3_db_cacheflush()\son\san\sin-memory\sdatabase. -D 2015-10-29T20:57:06.654 +C Do\snot\sattempt\sto\sflush\sthe\spages\sof\san\sin-memory\sdatabase\sto\sdisk\sif\ssqlite3_db_cacheflush()\sis\scalled. +D 2015-10-29T21:11:22.422 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2f9de81ebc87f92814ffc1e34f478a6de7c869b0 +F src/pager.c b588107ee55ff4121c114949ff51a56aab21f3ac F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 370b5d520c6523526988d0db5299f1bd09567782 -R e469742ef6d00761a1fbbbbf9de3f4b1 +P f0cdfb547b0976e753e94958f29cb294edf31bed +R dcdd2b431259b301d28dfb5e7d9d6d5d U dan -Z 9ba99da9a0f7b492a3cba8ddbf944bbf +Z 1371a31e24aaed4ace229bd9de4453e9 diff --git a/manifest.uuid b/manifest.uuid index b806a0d731..8abded1106 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0cdfb547b0976e753e94958f29cb294edf31bed \ No newline at end of file +9b79a390440a23542a370b591e567b31ebb35c42 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 09d4935f27..ea867127e0 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4478,15 +4478,16 @@ static int pagerStress(void *p, PgHdr *pPg){ */ int sqlite3PagerFlush(Pager *pPager){ int rc = pPager->errCode; - PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); - - assert( assert_pager_state(pPager) ); - while( rc==SQLITE_OK && pList ){ - PgHdr *pNext = pList->pDirty; - if( pList->nRef==0 ){ - rc = pagerStress((void*)pPager, pList); + if( !MEMDB ){ + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); + assert( assert_pager_state(pPager) ); + while( rc==SQLITE_OK && pList ){ + PgHdr *pNext = pList->pDirty; + if( pList->nRef==0 ){ + rc = pagerStress((void*)pPager, pList); + } + pList = pNext; } - pList = pNext; } return rc; From e8e6657fa7c3f977afa4a9237a747e80b931bb43 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Oct 2015 09:13:29 +0000 Subject: [PATCH 52/55] Test that calling sqlite3_db_cacheflush() does not interfere with savepoints. FossilOrigin-Name: 0e09e4a26938cfe0f573449526a8f0f527cef921 --- manifest | 12 +++--- manifest.uuid | 2 +- test/cacheflush.test | 89 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 2b97b8e039..2da7a2f9cb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sto\sflush\sthe\spages\sof\san\sin-memory\sdatabase\sto\sdisk\sif\ssqlite3_db_cacheflush()\sis\scalled. -D 2015-10-29T21:11:22.422 +C Test\sthat\scalling\ssqlite3_db_cacheflush()\sdoes\snot\sinterfere\swith\ssavepoints. +D 2015-10-30T09:13:29.814 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -503,7 +503,7 @@ F test/btree02.test fe69453d474d8154d19b904157ff1db4812fed99 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de -F test/cacheflush.test 42855120d2b00ff75033b54ba7693927f1ce4de8 +F test/cacheflush.test a755c93482ce2e20c04825304bef27e7b7ea0111 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f0cdfb547b0976e753e94958f29cb294edf31bed -R dcdd2b431259b301d28dfb5e7d9d6d5d +P 9b79a390440a23542a370b591e567b31ebb35c42 +R b3b377e425858b0fc40d0f4a8e28ca4d U dan -Z 1371a31e24aaed4ace229bd9de4453e9 +Z 2687c0f7a67bbeeb26b2f80bb787cd41 diff --git a/manifest.uuid b/manifest.uuid index 8abded1106..6b4639c096 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b79a390440a23542a370b591e567b31ebb35c42 \ No newline at end of file +0e09e4a26938cfe0f573449526a8f0f527cef921 \ No newline at end of file diff --git a/test/cacheflush.test b/test/cacheflush.test index 785bc0c77a..007ee8a065 100644 --- a/test/cacheflush.test +++ b/test/cacheflush.test @@ -229,6 +229,95 @@ do_execsql_test 3.4 { SELECT count(*) FROM t2; } {2 2} +#------------------------------------------------------------------------- +# Test that calling sqlite3_db_cacheflush() does not interfere with +# savepoint transactions. +# +do_test 4.0 { + reset_db + execsql { + CREATE TABLE ta(a, aa); + CREATE TABLE tb(b, bb); + INSERT INTO ta VALUES('a', randomblob(500)); + INSERT INTO tb VALUES('b', randomblob(500)); + BEGIN; + UPDATE ta SET a = 'A'; + SAVEPOINT one; + UPDATE tb SET b = 'B'; + } + + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A B} + +do_test 4.1 { + execsql { + ROLLBACK TO one; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b} + +do_test 4.2 { + execsql { + INSERT INTO tb VALUES('c', randomblob(10)); + INSERT INTO tb VALUES('d', randomblob(10)); + INSERT INTO tb VALUES('e', randomblob(10)); + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b c d e} + +do_test 4.3 { + execsql { + SAVEPOINT two; + UPDATE tb SET b = upper(b); + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A B C D E} + +do_test 4.4 { + execsql { + ROLLBACK TO two; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b c d e} + +do_test 4.4 { + execsql { + ROLLBACK TO one; + } + sqlite3_db_cacheflush db + diskquery test.db { + SELECT a FROM ta; + SELECT b FROM tb; + } +} {A b} + +do_test 4.5 { + execsql { + ROLLBACK; + SELECT a FROM ta; + SELECT b FROM tb; + } +} {a b} test_restore_config_pagecache finish_test From e44b835e63ccad030158a52b3a21ecd4456ae49e Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Oct 2015 14:25:57 +0000 Subject: [PATCH 53/55] Add the --enable-editline option to various autoconf scripts. FossilOrigin-Name: 866f0277781dedf0db287ec5902a138406a172e3 --- Makefile.in | 1 + autoconf/configure.ac | 20 ++++++-- configure | 107 +++++++++++++++++++++++++++++++++++------ configure.ac | 16 +++++- manifest | 20 ++++---- manifest.uuid | 2 +- tool/mkautoconfamal.sh | 2 +- 7 files changed, 137 insertions(+), 31 deletions(-) diff --git a/Makefile.in b/Makefile.in index c6b090ba43..fe4dc197b9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -54,6 +54,7 @@ LIBTCL = @TCL_LIB_SPEC@ # Compiler options needed for programs that use the readline() library. # READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ +READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ # The library that programs using readline() must link against. # diff --git a/autoconf/configure.ac b/autoconf/configure.ac index 888b924e40..7812927557 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -18,7 +18,6 @@ AC_SYS_LARGEFILE # Check for required programs. AC_PROG_CC -AC_PROG_RANLIB AC_PROG_LIBTOOL AC_PROG_MKDIR_P @@ -30,12 +29,27 @@ AC_CONFIG_FILES([Makefile sqlite3.pc]) AC_SUBST(BUILD_CFLAGS) #----------------------------------------------------------------------- +# --enable-editline # --enable-readline # +AC_ARG_ENABLE(editline, [AS_HELP_STRING( + [--enable-editline], + [use BSD libedit])], + [], [enable_editline=yes]) AC_ARG_ENABLE(readline, [AS_HELP_STRING( [--enable-readline], - [use readline in shell tool (yes, no) [default=yes]])], - [], [enable_readline=yes]) + [use readline])], + [], [enable_readline=no]) +if test x"$enable_editline" != xno ; then + sLIBS=$LIBS + LIBS="" + AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no]) + READLINE_LIBS=$LIBS + if test x"$LIBS" != "x"; then + AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline) + fi + LIBS=$sLIBS +fi if test x"$enable_readline" != xno ; then sLIBS=$LIBS LIBS="" diff --git a/configure b/configure index 65591fa0c8..7f329c530e 100755 --- a/configure +++ b/configure @@ -774,6 +774,7 @@ USE_GCOV OPT_FEATURE_FLAGS USE_AMALGAMATION TARGET_DEBUG +TARGET_HAVE_EDITLINE TARGET_HAVE_READLINE TARGET_READLINE_INC TARGET_READLINE_LIBS @@ -895,6 +896,7 @@ enable_releasemode enable_tempstore enable_tcl with_tcl +enable_editline enable_readline with_readline_lib with_readline_inc @@ -1542,7 +1544,8 @@ Optional Features: --enable-tempstore Use an in-ram database for temporary tables (never,no,yes,always) --disable-tcl do not build TCL extension - --disable-readline disable readline support [default=detect] + --enable-editline enable BSD editline support + --disable-readline disable readline support --enable-debug enable debugging & verbose explain --disable-amalgamation Disable the amalgamation and instead build all files separately @@ -3920,13 +3923,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3923: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3926: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3926: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3929: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3929: output\"" >&5) + (eval echo "\"\$as_me:3932: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5132,7 +5135,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5135 "configure"' > conftest.$ac_ext + echo '#line 5138 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6657,11 +6660,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6660: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6663: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6664: \$? = $ac_status" >&5 + echo "$as_me:6667: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -6996,11 +6999,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6999: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7002: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7003: \$? = $ac_status" >&5 + echo "$as_me:7006: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7101,11 +7104,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7104: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7107: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7108: \$? = $ac_status" >&5 + echo "$as_me:7111: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7156,11 +7159,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7159: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7162: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7163: \$? = $ac_status" >&5 + echo "$as_me:7166: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9536,7 +9539,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9539 "configure" +#line 9542 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9632,7 +9635,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9635 "configure" +#line 9638 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10832,6 +10835,14 @@ fi TARGET_READLINE_LIBS="" TARGET_READLINE_INC="" TARGET_HAVE_READLINE=0 +TARGET_HAVE_EDITLINE=0 +# Check whether --enable-editline was given. +if test "${enable_editline+set}" = set; then : + enableval=$enable_editline; with_editline=$enableval +else + with_editline=auto +fi + # Check whether --enable-readline was given. if test "${enable_readline+set}" = set; then : enableval=$enable_readline; with_readline=$enableval @@ -10840,6 +10851,71 @@ else fi +if test x"$with_editline" != xno; then + sLIBS=$LIBS + LIBS="" + TARGET_HAVE_EDITLINE=1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readline" >&5 +$as_echo_n "checking for library containing readline... " >&6; } +if ${ac_cv_search_readline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char readline (); +int +main () +{ +return readline (); + ; + return 0; +} +_ACEOF +for ac_lib in '' edit; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_readline=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_readline+:} false; then : + break +fi +done +if ${ac_cv_search_readline+:} false; then : + +else + ac_cv_search_readline=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readline" >&5 +$as_echo "$ac_cv_search_readline" >&6; } +ac_res=$ac_cv_search_readline +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + with_readline=no +else + TARGET_HAVE_EDITLINE=0 +fi + + TARGET_READLINE_LIBS=$LIBS + LIBS=$sLIBS +fi if test x"$with_readline" != xno; then found="yes" @@ -11028,6 +11104,7 @@ fi + ########## # Figure out what C libraries are required to compile programs # that use "fdatasync()" function. diff --git a/configure.ac b/configure.ac index 11ab81d342..0b94d33930 100644 --- a/configure.ac +++ b/configure.ac @@ -460,11 +460,24 @@ AC_SUBST(HAVE_TCL) TARGET_READLINE_LIBS="" TARGET_READLINE_INC="" TARGET_HAVE_READLINE=0 +TARGET_HAVE_EDITLINE=0 +AC_ARG_ENABLE([editline], + [AC_HELP_STRING([--enable-editline],[enable BSD editline support])], + [with_editline=$enableval], + [with_editline=auto]) AC_ARG_ENABLE([readline], - [AC_HELP_STRING([--disable-readline],[disable readline support [default=detect]])], + [AC_HELP_STRING([--disable-readline],[disable readline support])], [with_readline=$enableval], [with_readline=auto]) +if test x"$with_editline" != xno; then + sLIBS=$LIBS + LIBS="" + TARGET_HAVE_EDITLINE=1 + AC_SEARCH_LIBS(readline,edit,[with_readline=no],[TARGET_HAVE_EDITLINE=0]) + TARGET_READLINE_LIBS=$LIBS + LIBS=$sLIBS +fi if test x"$with_readline" != xno; then found="yes" @@ -519,6 +532,7 @@ fi AC_SUBST(TARGET_READLINE_LIBS) AC_SUBST(TARGET_READLINE_INC) AC_SUBST(TARGET_HAVE_READLINE) +AC_SUBST(TARGET_HAVE_EDITLINE) ########## # Figure out what C libraries are required to compile programs diff --git a/manifest b/manifest index d4263de73a..befa28989a 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Fix\suses\sof\sctype\sfunctions\s(ex:\sisspace())\son\ssigned\scharacters\sin\stest\nprograms\sand\sin\ssome\sobscure\sextensions.\s\sNo\schanges\sto\sthe\score. -D 2015-10-29T13:48:15.235 -F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee +C Add\sthe\s--enable-editline\soption\sto\svarious\sautoconf\sscripts. +D 2015-10-30T14:25:57.043 +F Makefile.in 4469ed8b02a9934fea9503d791165367d19db2f7 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -15,7 +15,7 @@ F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/config.guess 94cc57e2a3fdb9c235b362ace86d77e89d188cad x F autoconf/config.sub 1efb390a8fb4bfafd74783a15a8fb5311c84300e x -F autoconf/configure.ac a1fe4eee429fd9d3170be41941514a2b7120ba4e +F autoconf/configure.ac bec3caf78cf1bdbaad903dcd5c6029292eda3d2d F autoconf/depcomp 0b26f101e3bc9fd1ff0be1da9fb4a82371142f92 x F autoconf/install-sh 06ee6336e63bb845c8439d777c32eb2eccc4fbf1 x F autoconf/ltmain.sh 7a658a24028f02331c1d2446562758083c5eadd1 @@ -35,8 +35,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 762a66c6eb9331f8af21f5d00b610bd61eaf8e14 x -F configure.ac f36bd4fb8c53eed8374c5a5ef319807c08c23fa9 +F configure 1d10fa35c71b5e830631bff0b8f94da164e0bc19 x +F configure.ac fcfc67b323d32daaa3e46cf7782d9465ed423a6d F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1353,7 +1353,7 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d F tool/lempar.c 3617143ddb9b176c3605defe6a9c798793280120 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 -F tool/mkautoconfamal.sh d1a2da0e15b2ed33d60af35c7e9d483f13a8eb9f +F tool/mkautoconfamal.sh 4bdf61548a143e5977bd86ab93d68b694d10c8fa F tool/mkkeywordhash.c dfff09dbbfaf950e89af294f48f902181b144670 F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e @@ -1395,7 +1395,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2964ce25864e8aec86272af741caf49c23c86590 -R 108548c0deac3f928b4d6bf600bf3b5a +P 34eb6911afee09e779318b79baf953f616200128 +R dbb213b8cdbb03dc8a86ed2fb8ef6538 U drh -Z 9e7ef25aa5af86f6161b757cd0b4f721 +Z 7c44c6fe415d9f529c3f15d0974f7632 diff --git a/manifest.uuid b/manifest.uuid index bb3991b901..a30f7468e3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34eb6911afee09e779318b79baf953f616200128 \ No newline at end of file +866f0277781dedf0db287ec5902a138406a172e3 \ No newline at end of file diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index 0c2668c8b7..d78d681816 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -56,7 +56,7 @@ mv $TMPSPACE/tmp $TMPSPACE/configure.ac cd $TMPSPACE aclocal autoconf -automake +automake --add-missing mkdir -p tea/generic echo "#ifdef USE_SYSTEM_SQLITE" > tea/generic/tclsqlite3.c From 5596eb30209450b22d9e61f038f9cf68d637a5b3 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Oct 2015 14:28:16 +0000 Subject: [PATCH 54/55] Return immediately if sqlite3PagerWrite() is called when the pager is in PAGER_ERROR state. FossilOrigin-Name: a6695b008487aeb7badf572fa32bfcba3c9fab03 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2da7a2f9cb..0497ff0353 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\sthat\scalling\ssqlite3_db_cacheflush()\sdoes\snot\sinterfere\swith\ssavepoints. -D 2015-10-30T09:13:29.814 +C Return\simmediately\sif\ssqlite3PagerWrite()\sis\scalled\swhen\sthe\spager\sis\sin\sPAGER_ERROR\sstate. +D 2015-10-30T14:28:16.049 F Makefile.in 2ea961bc09e441874eb3d1bf7398e04feb24f3ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 @@ -327,7 +327,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c fc93d55f96bb978f0b0168c6ea7d6fc60b0e172c F src/os_win.c 1716291e5ec2dbfc5a1fe0b32182030f1f7d8acf F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c b588107ee55ff4121c114949ff51a56aab21f3ac +F src/pager.c 9c1eec0d88133484b165fa0b5284a411c24b964c F src/pager.h 1c4fa826c330040c5659a384446c7cc6e8e4200c F src/parse.y 11078cd8e3af00f030505b6a86a06a4536cfdeaa F src/pcache.c 24be750c79272e0ca7b6e007bc94999700f3e5ef @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 9b79a390440a23542a370b591e567b31ebb35c42 -R b3b377e425858b0fc40d0f4a8e28ca4d +P 0e09e4a26938cfe0f573449526a8f0f527cef921 +R f396f7a1d6ed17b52257ec59a2b63902 U dan -Z 2687c0f7a67bbeeb26b2f80bb787cd41 +Z 76885908163af131d9fcc88a11feb178 diff --git a/manifest.uuid b/manifest.uuid index 6b4639c096..07944153ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e09e4a26938cfe0f573449526a8f0f527cef921 \ No newline at end of file +a6695b008487aeb7badf572fa32bfcba3c9fab03 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index ea867127e0..314f792aa0 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5915,9 +5915,10 @@ int sqlite3PagerWrite(PgHdr *pPg){ Pager *pPager = pPg->pPager; assert( (pPg->flags & PGHDR_MMAP)==0 ); assert( pPager->eState>=PAGER_WRITER_LOCKED ); - assert( pPager->eState!=PAGER_ERROR ); assert( assert_pager_state(pPager) ); - if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ + if( pPager->errCode ){ + return pPager->errCode; + }else if( (pPg->flags & PGHDR_WRITEABLE)!=0 && pPager->dbSize>=pPg->pgno ){ if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg); return SQLITE_OK; }else if( pPager->sectorSize > (u32)pPager->pageSize ){ From b457764d01a88021b70e9e13ec1e7f70ea8cb175 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Oct 2015 16:36:42 +0000 Subject: [PATCH 55/55] Increase the version number to 3.10.0, due to the addition of the sqlite3_db_cacheflush() interface. FossilOrigin-Name: 7565b046ff939e8310631397a4526fbd98b99aaf --- VERSION | 2 +- configure | 18 +++++++++--------- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/VERSION b/VERSION index 6bd10744ae..30291cba22 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.9.1 +3.10.0 diff --git a/configure b/configure index 7f329c530e..174f41ae24 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.9.1. +# Generated by GNU Autoconf 2.69 for sqlite 3.10.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.9.1' -PACKAGE_STRING='sqlite 3.9.1' +PACKAGE_VERSION='3.10.0' +PACKAGE_STRING='sqlite 3.10.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1460,7 +1460,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.9.1 to adapt to many kinds of systems. +\`configure' configures sqlite 3.10.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1525,7 +1525,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.9.1:";; + short | recursive ) echo "Configuration of sqlite 3.10.0:";; esac cat <<\_ACEOF @@ -1646,7 +1646,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.9.1 +sqlite configure 3.10.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2065,7 +2065,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.9.1, which was +It was created by sqlite $as_me 3.10.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -12023,7 +12023,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.9.1, which was +This file was extended by sqlite $as_me 3.10.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12089,7 +12089,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.9.1 +sqlite config.status 3.10.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 345e6cee83..f83dc922cc 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C Add\snew\sAPI\sfunction\ssqlite3_db_cacheflush(). -D 2015-10-30T16:14:03.663 +C Increase\sthe\sversion\snumber\sto\s3.10.0,\sdue\sto\sthe\saddition\sof\sthe\nsqlite3_db_cacheflush()\sinterface. +D 2015-10-30T16:36:42.626 F Makefile.in 4469ed8b02a9934fea9503d791165367d19db2f7 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 702d3e98f3afc6587a78481257f3c4c900efc3a4 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 -F VERSION a47917b59f38b632b3a8662d14fd20f94956bdd0 +F VERSION 8b9d3ac6f1962f94e06ba05462422a544f9c4e36 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -35,7 +35,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure 1d10fa35c71b5e830631bff0b8f94da164e0bc19 x +F configure e511ceefe595e35051933a90c848ab4fa1d48add x F configure.ac fcfc67b323d32daaa3e46cf7782d9465ed423a6d F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 @@ -1397,7 +1397,7 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 866f0277781dedf0db287ec5902a138406a172e3 a6695b008487aeb7badf572fa32bfcba3c9fab03 -R ef0d31ad874159721a762aa150025fb7 -U dan -Z 73ca07d4c2e56cd65bf8c1c2ed88c7c7 +P ad80d3073388c59f67171720efc6ef766e19886f +R 05540c814207efb67f7c8e8b3a47d3f0 +U drh +Z 14542ee53e71e033be97bac3859f7dcc diff --git a/manifest.uuid b/manifest.uuid index bef97ff6ba..3e10f9d11a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad80d3073388c59f67171720efc6ef766e19886f \ No newline at end of file +7565b046ff939e8310631397a4526fbd98b99aaf \ No newline at end of file