From e807bdba86b39f5996683c14842c705e3f6e25d6 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Jan 2016 17:06:33 +0000 Subject: [PATCH 001/107] Add a new hint bit on the flags parameter of sqlite3BtreeDelete(). The new BTREE_IDXDELETE bit indicates that the call is to delete an index entry corresponding to a table row that has already been deleted. FossilOrigin-Name: ac2cbadd8000947c097da5b00c00090fe58fdcff --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/btree.c | 41 +++++++++++++++++++++++++++++------------ src/btree.h | 7 ++++++- src/delete.c | 5 ++++- src/sqliteInt.h | 5 ++++- src/vdbe.c | 23 ++++++++++++++++------- 7 files changed, 73 insertions(+), 33 deletions(-) diff --git a/manifest b/manifest index d459ef1f26..084be630fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\sFORDELETE\shint.\s\sNo\slogic\schanges. -D 2016-01-21T15:55:37.704 +C Add\sa\snew\shint\sbit\son\sthe\sflags\sparameter\sof\ssqlite3BtreeDelete().\s\sThe\snew\nBTREE_IDXDELETE\sbit\sindicates\sthat\sthe\scall\sis\sto\sdelete\san\sindex\sentry\s\ncorresponding\sto\sa\stable\srow\sthat\shas\salready\sbeen\sdeleted. +D 2016-01-21T17:06:33.267 F Makefile.in 7be88f5b473891e3a8c07245ed60535fcda4f9ee F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc c5ead4aa22ff6f528c755b07ed1e31184ac5b3d2 @@ -288,8 +288,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c f224ae877fde69d1a9d430f502edaf8502752dbe -F src/btree.h 526137361963e746949ab966a910c7f455ac6b04 +F src/btree.c 97cf881292e085ee71faf44f7167b6312965b562 +F src/btree.h c5dfbbc59226fa5fcc2b03befa85fe10ef23c1b5 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 @@ -297,7 +297,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 -F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da +F src/delete.c f02e46234c5fc86f6c03ae34dc0ba48e93cd5029 F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44 @@ -350,7 +350,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 0403328581127bc8ad2f9cc7af2c3bb23d5316da +F src/sqliteInt.h 46e0bac7a3cdab96e8b5afd1436accc25d2c3d6a F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -410,7 +410,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 +F src/vdbe.c e21a506d17a7397cba16c162d8c9c96e9769c68e F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1419,7 +1419,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 f60f025027ab3acdbc97701f81ff9c11c8463022 -R 58c662ebb54c7087fe70ba0b9b653627 +P a3cec529f0238e4ca1196fec420f2de80d28db78 +R 76198b2176fddd32b1fb9b7a5f18b4c8 +T *branch * btree-fordelete-flag +T *sym-btree-fordelete-flag * +T -sym-trunk * U drh -Z 656e64b9ebb4ed29ac85ca9fad2e65b0 +Z c987d8ca8053309611f1f75e6c6acde5 diff --git a/manifest.uuid b/manifest.uuid index 80d0db3e83..57018fb84b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3cec529f0238e4ca1196fec420f2de80d28db78 \ No newline at end of file +ac2cbadd8000947c097da5b00c00090fe58fdcff \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4e6f6478af..89144e7a84 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4049,13 +4049,13 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ ** on the database already. If a write-cursor is requested, then ** the caller is assumed to have an open write transaction. ** -** If wrFlag==0, then the cursor can only be used for reading. -** If wrFlag==1, then the cursor can be used for reading or for -** writing if other conditions for writing are also met. These -** are the conditions that must be met in order for writing to -** be allowed: +** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only +** be used for reading. If the BTREE_WRCSR bit is set, then the cursor +** can be used for reading or for writing if other conditions for writing +** are also met. These are the conditions that must be met in order +** for writing to be allowed: ** -** 1: The cursor must have been opened with wrFlag==1 +** 1: The cursor must have been opened with wrFlag containing BTREE_WRCSR ** ** 2: Other database connections that share the same pager cache ** but which are not in the READ_UNCOMMITTED state may not have @@ -4067,6 +4067,16 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ ** ** 4: There must be an active transaction. ** +** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR +** is set. If FORDELETE is set, that is a hint to the implementation that +** this cursor will only be used to seek to and delete entries of an index +** as part of a larger DELETE statement. The FORDELETE hint is not used by +** this implementation. But in a hypothetical alternative storage engine +** in which index entries are automatically deleted when corresponding table +** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE +** operations on this cursor can be no-ops and all READ operations can +** return a null row (2-bytes: 0x01 0x00). +** ** No checking is done to make sure that page iTable really is the ** root page of a b-tree. If it is not, then the cursor acquired ** will not work correctly. @@ -8082,13 +8092,18 @@ end_insert: /* ** Delete the entry that the cursor is pointing to. ** -** If the second parameter is zero, then the cursor is left pointing at an -** arbitrary location after the delete. If it is non-zero, then the cursor -** is left in a state such that the next call to BtreeNext() or BtreePrev() -** moves it to the same row as it would if the call to BtreeDelete() had -** been omitted. +** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then +** the cursor is left pointing at an arbitrary location after the delete. +** But if that bit is set, then the cursor is left in a state such that +** the next call to BtreeNext() or BtreePrev() moves it to the same row +** as it would have been on if the call to BtreeDelete() had been omitted. +** +** The BTREE_IDXDELETE bit of flags indicates that this is a delete of +** an index entry where the corresponding table row has already been deleted. +** The BTREE_IDXDELETE bit is a hint that is not used by this implementation, +** but which might be used by alternative storage engines. */ -int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){ +int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; int rc; /* Return code */ @@ -8098,6 +8113,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){ int iCellDepth; /* Depth of node containing pCell */ u16 szCell; /* Size of the cell being deleted */ int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ + u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ assert( cursorOwnsBtShared(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -8107,6 +8123,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){ assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); assert( pCur->eState==CURSOR_VALID ); + assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_IDXDELETE))==0 ); iCellDepth = pCur->iPage; iCellIdx = pCur->aiIdx[iCellDepth]; diff --git a/src/btree.h b/src/btree.h index 37a9915eda..416faca651 100644 --- a/src/btree.h +++ b/src/btree.h @@ -245,7 +245,12 @@ int sqlite3BtreeMovetoUnpacked( ); int sqlite3BtreeCursorHasMoved(BtCursor*); int sqlite3BtreeCursorRestore(BtCursor*, int*); -int sqlite3BtreeDelete(BtCursor*, int); +int sqlite3BtreeDelete(BtCursor*, u8 flags); + +/* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */ +#define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ +#define BTREE_IDXDELETE 0x04 /* this is index, table row already deleted */ + int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, int nZero, int bias, int seekResult); diff --git a/src/delete.c b/src/delete.c index ed273bde81..98c49c9930 100644 --- a/src/delete.c +++ b/src/delete.c @@ -718,6 +718,7 @@ void sqlite3GenerateRowDelete( ** a view (in which case the only effect of the DELETE statement is to ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ + u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); if( count ){ @@ -725,8 +726,10 @@ void sqlite3GenerateRowDelete( } if( iIdxNoSeek>=0 ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); + if( eMode!=ONEPASS_OFF ) p5 = OPFLAG_IDXDELETE; } - sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI); + if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; + sqlite3VdbeChangeP5(v, p5); } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b536b8ab28..25aff00151 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2847,7 +2847,8 @@ struct AuthContext { /* ** Bitfield flags for P5 value in various opcodes. */ -#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */ +#define OPFLAG_NCHANGE 0x01 /* OP_Insert: Set to update db->nChange */ + /* Also used in P2 (not P5) of OP_Delete */ #define OPFLAG_EPHEM 0x01 /* OP_Column: Ephemeral output is ok */ #define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ #define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ @@ -2860,6 +2861,8 @@ struct AuthContext { #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ +#define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */ +#define OPFLAG_IDXDELETE 0x04 /* OP_Delete: index in a DELETE op */ /* * Each trigger present in the database schema is stored as an instance of diff --git a/src/vdbe.c b/src/vdbe.c index c6d5f7b0cc..c290097da2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4341,14 +4341,20 @@ case OP_InsertInt: { ** ** Delete the record at which the P1 cursor is currently pointing. ** -** If the P5 parameter is non-zero, the cursor will be left pointing at -** either the next or the previous record in the table. If it is left -** pointing at the next record, then the next Next instruction will be a -** no-op. As a result, in this case it is OK to delete a record from within a -** Next loop. If P5 is zero, then the cursor is left in an undefined state. +** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then +** the cursor will be left pointing at either the next or the previous +** record in the table. If it is left pointing at the next record, then +** the next Next instruction will be a no-op. As a result, in this case +** it is ok to delete a record from within a Next loop. If +** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be +** left in an undefined state. ** -** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is -** incremented (otherwise not). +** If the OPFLAG_IDXDELETE bit is set on P5, that indicates that this +** delete is on an index cursor where the corresponding table row has +** already been deleted. +** +** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row +** change count is incremented (otherwise not). ** ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. @@ -4385,6 +4391,9 @@ case OP_Delete: { } #endif + assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_IDXDELETE))==0 ); + assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); + assert( OPFLAG_IDXDELETE==BTREE_IDXDELETE ); rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; From b5c557b87e0e54f39ade09a73dc0b7cb13d2c93d Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 22 Jan 2016 15:44:07 +0000 Subject: [PATCH 002/107] Have the dbstat module dequote any argument passed to the CREATE VIRTUAL TABLE statement before attempting to match it against the names of attached databases. FossilOrigin-Name: e60461e984b8df09256bb0d733dbfae52568a145 --- manifest | 16 ++++++------ manifest.uuid | 2 +- src/dbstat.c | 6 ++++- test/stat.test | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5d0ee23cca..c4697a9a83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sFTS4\swhen\sbuilding\sthe\sshell\swith\sthe\sMSVC\smakefile. -D 2016-01-22T04:22:36.961 +C Have\sthe\sdbstat\smodule\sdequote\sany\sargument\spassed\sto\sthe\sCREATE\sVIRTUAL\sTABLE\sstatement\sbefore\sattempting\sto\smatch\sit\sagainst\sthe\snames\sof\sattached\sdatabases. +D 2016-01-22T15:44:07.317 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 @@ -296,7 +296,7 @@ F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 -F src/dbstat.c ffd63fc8ba7541476ced189b95e95d7f2bc63f78 +F src/dbstat.c d33af6b426449d7bfd5b3d9f77911c20d1c8abdc F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb @@ -1052,7 +1052,7 @@ F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953 -F test/stat.test 8de91498c99f5298b303f70f1d1f3b9557af91bf +F test/stat.test fafe6e82dfdb97d8c8be31cd83e36e973079ce0f F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1419,7 +1419,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 67625b963a6f5a0c6dff1a04a323e693569c2d94 -R a9194694e295a05f59bbd77f1c470bc0 -U mistachkin -Z bf1c280948a8257fdbbacb5c97da93b0 +P e4c07df557cd50786b05eecf011bf94708e6e31b +R ccbd95b5668f9b5a41b204404932d800 +U dan +Z ad5fc4f27f7e976928da8b4460d48d82 diff --git a/manifest.uuid b/manifest.uuid index 533751ec8a..800a36102e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4c07df557cd50786b05eecf011bf94708e6e31b \ No newline at end of file +e60461e984b8df09256bb0d733dbfae52568a145 \ No newline at end of file diff --git a/src/dbstat.c b/src/dbstat.c index ae55d6b803..e404c71dd3 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -149,7 +149,11 @@ static int statConnect( int iDb; if( argc>=4 ){ - iDb = sqlite3FindDbName(db, argv[3]); + char *zDb = sqlite3DbStrDup(db, argv[3]); + if( zDb==0 ) return SQLITE_NOMEM; + sqlite3Dequote(zDb); + iDb = sqlite3FindDbName(db, zDb); + sqlite3DbFree(db, zDb); if( iDb<0 ){ *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); return SQLITE_ERROR; diff --git a/test/stat.test b/test/stat.test index 57c1b9eae1..14751bd6ff 100644 --- a/test/stat.test +++ b/test/stat.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix stat ifcapable !vtab||!compound { finish_test @@ -184,4 +185,69 @@ do_catchsql_test stat-6.1 { CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx); } {1 {no such database: mainx}} +#------------------------------------------------------------------------- +# Test that the argument passed to the dbstat constructor is dequoted +# before it is matched against the names of attached databases. +# +forcedelete test.db2 +do_execsql_test 7.1 { + ATTACH 'test.db2' AS '123'; + CREATE TABLE "123".x1(a, b); + INSERT INTO x1 VALUES(1, 2); +} + +do_execsql_test 7.1.1 { + SELECT * FROM dbstat('123'); +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} +do_execsql_test 7.1.2 { + SELECT * FROM dbstat(123); +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} +do_execsql_test 7.1.3 { + CREATE VIRTUAL TABLE x2 USING dbstat('123'); + SELECT * FROM x2; +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} +do_execsql_test 7.1.4 { + CREATE VIRTUAL TABLE x3 USING dbstat(123); + SELECT * FROM x3; +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} + +do_execsql_test 7.2 { + DETACH 123; + DROP TABLE x2; + DROP TABLE x3; + ATTACH 'test.db2' AS '123corp'; +} +do_execsql_test 7.2.1 { + SELECT * FROM dbstat('123corp'); +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} +do_catchsql_test 7.2.2 { + SELECT * FROM dbstat(123corp); +} {1 {unrecognized token: "123corp"}} +do_execsql_test 7.2.3 { + CREATE VIRTUAL TABLE x2 USING dbstat('123corp'); + SELECT * FROM x2; +} { + sqlite_master / 1 leaf 1 37 875 37 0 1024 + x1 / 2 leaf 1 4 1008 4 1024 1024 +} +do_catchsql_test 7.2.4 { + CREATE VIRTUAL TABLE x3 USING dbstat(123corp); + SELECT * FROM x3; +} {1 {unrecognized token: "123corp"}} + finish_test From 40aced5c654a3f3322f49fa9e4b2116f43167790 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 22 Jan 2016 17:48:09 +0000 Subject: [PATCH 003/107] Add the sqlite3TokenInit() utility function. FossilOrigin-Name: 7323175337b7ba85ac932ca892b28860f6a5b688 --- manifest | 28 ++++++++++++++-------------- manifest.uuid | 2 +- src/build.c | 6 ++---- src/dbstat.c | 8 +++----- src/expr.c | 3 +-- src/fkey.c | 8 +++----- src/select.c | 3 +-- src/sqliteInt.h | 1 + src/trigger.c | 3 +-- src/util.c | 8 ++++++++ 10 files changed, 35 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index c4697a9a83..6c3814c3d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\sdbstat\smodule\sdequote\sany\sargument\spassed\sto\sthe\sCREATE\sVIRTUAL\sTABLE\sstatement\sbefore\sattempting\sto\smatch\sit\sagainst\sthe\snames\sof\sattached\sdatabases. -D 2016-01-22T15:44:07.317 +C Add\sthe\ssqlite3TokenInit()\sutility\sfunction. +D 2016-01-22T17:48:09.470 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 @@ -291,16 +291,16 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c f224ae877fde69d1a9d430f502edaf8502752dbe F src/btree.h 526137361963e746949ab966a910c7f455ac6b04 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 31af80bba31ac159967951ef58f3144cc7db9d70 +F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 -F src/dbstat.c d33af6b426449d7bfd5b3d9f77911c20d1c8abdc +F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da -F src/expr.c df0d7c3230d59abd679da22ff5ce4cfd0e3a0e63 +F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c e18b3dff7d47c7bcac5ac4fc178a89b9fd322b44 +F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504 F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 @@ -345,12 +345,12 @@ F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 718954db86277d696c520fe671148db1e9c4ed3c +F src/select.c 1db9a902e89201a0ae3ff5243a7a3f37842a3937 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 0403328581127bc8ad2f9cc7af2c3bb23d5316da +F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -405,10 +405,10 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66 -F src/trigger.c 056e51182a3677434423e3be0c74e61b90b4a663 +F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 -F src/util.c e802e8e311a0d6c48cd1b3e89db164f6f0248d70 +F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 @@ -1419,7 +1419,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 e4c07df557cd50786b05eecf011bf94708e6e31b -R ccbd95b5668f9b5a41b204404932d800 -U dan -Z ad5fc4f27f7e976928da8b4460d48d82 +P e60461e984b8df09256bb0d733dbfae52568a145 +R 03ab6310cefadc63b5c7c7da966c2348 +U drh +Z 0c42ba520d71deaa3e0a21b23ff67f9d diff --git a/manifest.uuid b/manifest.uuid index 800a36102e..e9fd60917b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e60461e984b8df09256bb0d733dbfae52568a145 \ No newline at end of file +7323175337b7ba85ac932ca892b28860f6a5b688 \ No newline at end of file diff --git a/src/build.c b/src/build.c index f7074ab417..06f5433e37 100644 --- a/src/build.c +++ b/src/build.c @@ -1708,8 +1708,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; - ipkToken.z = pTab->aCol[pTab->iPKey].zName; - ipkToken.n = sqlite3Strlen30(ipkToken.z); + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; @@ -3057,8 +3056,7 @@ Index *sqlite3CreateIndex( */ if( pList==0 ){ Token prevCol; - prevCol.z = pTab->aCol[pTab->nCol-1].zName; - prevCol.n = sqlite3Strlen30(prevCol.z); + sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; diff --git a/src/dbstat.c b/src/dbstat.c index e404c71dd3..5e42cdfe38 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -149,11 +149,9 @@ static int statConnect( int iDb; if( argc>=4 ){ - char *zDb = sqlite3DbStrDup(db, argv[3]); - if( zDb==0 ) return SQLITE_NOMEM; - sqlite3Dequote(zDb); - iDb = sqlite3FindDbName(db, zDb); - sqlite3DbFree(db, zDb); + Token nm; + sqlite3TokenInit(&nm, (char*)argv[3]); + iDb = sqlite3FindDb(db, &nm); if( iDb<0 ){ *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); return SQLITE_ERROR; diff --git a/src/expr.c b/src/expr.c index 403e81cf34..c91db2834f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -85,8 +85,7 @@ Expr *sqlite3ExprAddCollateToken( Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ Token s; assert( zC!=0 ); - s.z = zC; - s.n = sqlite3Strlen30(s.z); + sqlite3TokenInit(&s, (char*)zC); return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } diff --git a/src/fkey.c b/src/fkey.c index 2abd06c693..7eb188924d 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1192,11 +1192,9 @@ static Trigger *fkActionTrigger( assert( iFromCol>=0 ); assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); - tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName; - tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; - - tToCol.n = sqlite3Strlen30(tToCol.z); - tFromCol.n = sqlite3Strlen30(tFromCol.z); + sqlite3TokenInit(&tToCol, + pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); /* Create the expression "OLD.zToCol = zFromCol". It is important ** that the "OLD.zToCol" term is on the LHS of the = operator, so diff --git a/src/select.c b/src/select.c index 9eb6279c10..ffc0ec2415 100644 --- a/src/select.c +++ b/src/select.c @@ -4438,8 +4438,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); - sColname.z = zColname; - sColname.n = sqlite3Strlen30(zColname); + sqlite3TokenInit(&sColname, zColname); sqlite3ExprListSetName(pParse, pNew, &sColname, 0); if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b536b8ab28..1a8a5d3a5b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3322,6 +3322,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3SetString(char **, sqlite3*, const char*); void sqlite3ErrorMsg(Parse*, const char*, ...); int sqlite3Dequote(char*); +void sqlite3TokenInit(Token*,char*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*, char **); void sqlite3FinishCoding(Parse*); diff --git a/src/trigger.c b/src/trigger.c index 48d6772992..4bfb55af69 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -287,8 +287,7 @@ void sqlite3FinishTrigger( pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } - nameToken.z = pTrig->zName; - nameToken.n = sqlite3Strlen30(nameToken.z); + sqlite3TokenInit(&nameToken, pTrig->zName); sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) || sqlite3FixExpr(&sFix, pTrig->pWhen) diff --git a/src/util.c b/src/util.c index b4c5e62bb3..96f7c7f3dc 100644 --- a/src/util.c +++ b/src/util.c @@ -234,6 +234,14 @@ int sqlite3Dequote(char *z){ return j; } +/* +** Generate a Token object from a string +*/ +void sqlite3TokenInit(Token *p, char *z){ + p->z = z; + p->n = sqlite3Strlen30(z); +} + /* Convenient short-hand */ #define UpperToLower sqlite3UpperToLower From c3dfa5eba74db8eae0dddff1424b24e7f5873dbe Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 22 Jan 2016 19:44:03 +0000 Subject: [PATCH 004/107] Reenable the xCurrentTime and xGetLastError methods on the unix VFSes as long as SQLITE_OMIT_DEPRECATED is not defined. FossilOrigin-Name: c11c85fdb6514cae54bb44945cc197dcaba72307 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/os_unix.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6c3814c3d9..566db8de82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3TokenInit()\sutility\sfunction. -D 2016-01-22T17:48:09.470 +C Reenable\sthe\sxCurrentTime\sand\sxGetLastError\smethods\son\sthe\sunix\sVFSes\sas\slong\nas\sSQLITE_OMIT_DEPRECATED\sis\snot\sdefined. +D 2016-01-22T19:44:03.065 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c b509b49b40a269e7b75ab511b6e92b2dc9444359 +F src/os_unix.c 0eb7f469fcd4e1fbedf30060438e26b839ec5486 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c f4e9ac39fbb1e0fde97af85c0f4e00eb90764b67 @@ -1419,7 +1419,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 e60461e984b8df09256bb0d733dbfae52568a145 -R 03ab6310cefadc63b5c7c7da966c2348 +P 7323175337b7ba85ac932ca892b28860f6a5b688 +R 4fcfc780a1da751b6f90e6d6f3ced841 U drh -Z 0c42ba520d71deaa3e0a21b23ff67f9d +Z 703592c4495d8a71fd67fbd54e7f3927 diff --git a/manifest.uuid b/manifest.uuid index e9fd60917b..a853332581 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7323175337b7ba85ac932ca892b28860f6a5b688 \ No newline at end of file +c11c85fdb6514cae54bb44945cc197dcaba72307 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 5bd6116945..ee9b55674b 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -6187,7 +6187,7 @@ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ return rc; } -#if 0 /* Not used */ +#ifndef SQLITE_OMIT_DEPRECATED /* ** Find the current time (in Universal Coordinated Time). Write the ** current time and date as a Julian Day number into *prNow and @@ -6205,7 +6205,7 @@ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ # define unixCurrentTime 0 #endif -#if 0 /* Not used */ +#ifndef SQLITE_OMIT_DEPRECATED /* ** We added the xGetLastError() method with the intention of providing ** better low-level error messages when operating-system problems come up From 795502d26c770c06b1d8d586fd316a6e374ed1d6 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 22 Jan 2016 19:48:34 +0000 Subject: [PATCH 005/107] Experimental performance enhancements for fts5. FossilOrigin-Name: b5a57b812fd6a734cf2a342bf0b730ae18912d73 --- ext/fts5/fts5Int.h | 10 +- ext/fts5/fts5_expr.c | 42 ++-- ext/fts5/fts5_index.c | 389 +++++++++++++++++++++++++++----------- ext/fts5/fts5_vocab.c | 56 +++--- ext/fts5/test/fts5ac.test | 1 - manifest | 25 +-- manifest.uuid | 2 +- 7 files changed, 355 insertions(+), 170 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index b2f0d6c34e..7c50da9656 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -315,6 +315,12 @@ void sqlite3Fts5TermsetFree(Fts5Termset*); typedef struct Fts5Index Fts5Index; typedef struct Fts5IndexIter Fts5IndexIter; +struct Fts5IndexIter { + i64 iRowid; + const u8 *pData; + int nData; +}; + /* ** Values used as part of the flags argument passed to IndexQuery(). */ @@ -396,6 +402,8 @@ void sqlite3Fts5IterClose(Fts5IndexIter*); const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*); int sqlite3Fts5IterNextScan(Fts5IndexIter*); +int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*); + /* ** Insert or remove data to or from the index. Each time a document is @@ -469,8 +477,6 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); int sqlite3Fts5IndexLoadConfig(Fts5Index *p); -int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*); - /* ** End of interface to code in fts5_index.c. **************************************************************************/ diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index c51ed7939c..290baf4e2c 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -323,11 +323,15 @@ static int fts5ExprSynonymList( const u8 *a; int n; - if( bCollist ){ + if( 0 && bCollist ){ rc = sqlite3Fts5IterCollist(pIter, &a, &n); }else{ i64 dummy; +#if 0 rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy); +#endif + a = pIter->pData; + n = pIter->nData; } if( rc!=SQLITE_OK ) goto synonym_poslist_out; @@ -436,7 +440,12 @@ static int fts5ExprPhraseIsMatch( pTerm, 0, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n ); }else{ + Fts5IndexIter *pIter = pTerm->pIter; +#if 0 rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy); +#endif + a = pIter->pData; + n = pIter->nData; } if( rc!=SQLITE_OK ) goto ismatch_out; sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); @@ -775,6 +784,7 @@ static int fts5ExprNearTest( for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ Fts5IndexIter *pIter = pTerm->pIter; if( sqlite3Fts5IterEof(pIter)==0 ){ +#if 0 int n; i64 iRowid; rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid); @@ -784,6 +794,10 @@ static int fts5ExprNearTest( }else if( iRowid==pNode->iRowid && n>0 ){ pPhrase->poslist.n = 1; } +#endif + if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){ + pPhrase->poslist.n = 1; + } } } return pPhrase->poslist.n; @@ -800,9 +814,13 @@ static int fts5ExprNearTest( rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch); if( bMatch==0 ) break; }else{ + Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; + fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData); +#if 0 rc = sqlite3Fts5IterPoslistBuffer( pPhrase->aTerm[0].pIter, &pPhrase->poslist ); +#endif } } @@ -823,21 +841,20 @@ static int fts5ExprTokenTest( ** fts5_index.c iterator object. This is much faster than synthesizing ** a new poslist the way we have to for more complicated phrase or NEAR ** expressions. */ - Fts5ExprNearset *pNear = pNode->pNear; - Fts5ExprPhrase *pPhrase = pNear->apPhrase[0]; + Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0]; Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; - Fts5Colset *pColset = pNear->pColset; - int rc; assert( pNode->eType==FTS5_TERM ); - assert( pNear->nPhrase==1 && pPhrase->nTerm==1 ); + assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 ); assert( pPhrase->aTerm[0].pSynonym==0 ); - rc = sqlite3Fts5IterPoslist(pIter, pColset, - (const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid - ); + pPhrase->poslist.n = pIter->nData; + if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){ + pPhrase->poslist.p = (u8*)pIter->pData; + } + pNode->iRowid = pIter->iRowid; pNode->bNomatch = (pPhrase->poslist.n==0); - return rc; + return SQLITE_OK; } /* @@ -2484,6 +2501,8 @@ int sqlite3Fts5ExprPhraseCollist( int rc = SQLITE_OK; assert( iPhrase>=0 && iPhrasenPhrase ); + assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + if( pNode->bEof==0 && pNode->iRowid==pExpr->pRoot->iRowid && pPhrase->poslist.n>0 @@ -2503,7 +2522,8 @@ int sqlite3Fts5ExprPhraseCollist( *ppCollist = a; } }else{ - sqlite3Fts5IterCollist(pPhrase->aTerm[0].pIter, ppCollist, pnCollist); + *ppCollist = pPhrase->aTerm[0].pIter->pData; + *pnCollist = pPhrase->aTerm[0].pIter->nData; } }else{ *ppCollist = 0; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index fc11a23413..2ea57b04f9 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -261,6 +261,7 @@ typedef struct Fts5Data Fts5Data; typedef struct Fts5DlidxIter Fts5DlidxIter; typedef struct Fts5DlidxLvl Fts5DlidxLvl; typedef struct Fts5DlidxWriter Fts5DlidxWriter; +typedef struct Fts5Iter Fts5Iter; typedef struct Fts5PageWriter Fts5PageWriter; typedef struct Fts5SegIter Fts5SegIter; typedef struct Fts5DoclistIter Fts5DoclistIter; @@ -503,10 +504,16 @@ struct Fts5SegIter { ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. */ -struct Fts5IndexIter { +struct Fts5Iter { + Fts5IndexIter base; /* Base class containing output vars */ + Fts5Index *pIndex; /* Index that owns this iterator */ Fts5Structure *pStruct; /* Database structure for this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ + Fts5Colset *pColset; /* Restrict matches to these columns */ + + /* Invoked to set output variables. */ + void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*); int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ @@ -1752,7 +1759,7 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ ** points to a delete marker. A delete marker is an entry with a 0 byte ** position-list. */ -static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5IndexIter *pIter){ +static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){ Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0); } @@ -2406,7 +2413,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){ ** two iterators. */ static void fts5AssertComparisonResult( - Fts5IndexIter *pIter, + Fts5Iter *pIter, Fts5SegIter *p1, Fts5SegIter *p2, Fts5CResult *pRes @@ -2447,7 +2454,7 @@ static void fts5AssertComparisonResult( ** statement used to verify that the contents of the pIter->aFirst[] array ** are correct. */ -static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){ +static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){ if( p->rc==SQLITE_OK ){ Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int i; @@ -2492,7 +2499,7 @@ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){ ** to a key that is a duplicate of another, higher priority, ** segment-iterator in the pSeg->aSeg[] array. */ -static int fts5MultiIterDoCompare(Fts5IndexIter *pIter, int iOut){ +static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){ int i1; /* Index of left-hand Fts5SegIter */ int i2; /* Index of right-hand Fts5SegIter */ int iRes; @@ -2638,7 +2645,7 @@ static void fts5SegIterNextFrom( /* ** Free the iterator object passed as the second argument. */ -static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){ +static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){ if( pIter ){ int i; for(i=0; inSeg; i++){ @@ -2652,7 +2659,7 @@ static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){ static void fts5MultiIterAdvanced( Fts5Index *p, /* FTS5 backend to iterate within */ - Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */ + Fts5Iter *pIter, /* Iterator to update aFirst[] array for */ int iChanged, /* Index of sub-iterator just advanced */ int iMinset /* Minimum entry in aFirst[] to set */ ){ @@ -2680,8 +2687,9 @@ static void fts5MultiIterAdvanced( */ static int fts5MultiIterAdvanceRowid( Fts5Index *p, /* FTS5 backend to iterate within */ - Fts5IndexIter *pIter, /* Iterator to update aFirst[] array for */ - int iChanged /* Index of sub-iterator just advanced */ + Fts5Iter *pIter, /* Iterator to update aFirst[] array for */ + int iChanged, /* Index of sub-iterator just advanced */ + Fts5SegIter **ppFirst ){ Fts5SegIter *pNew = &pIter->aSeg[iChanged]; @@ -2714,13 +2722,14 @@ static int fts5MultiIterAdvanceRowid( } } + *ppFirst = pNew; return 0; } /* ** Set the pIter->bEof variable based on the state of the sub-iterators. */ -static void fts5MultiIterSetEof(Fts5IndexIter *pIter){ +static void fts5MultiIterSetEof(Fts5Iter *pIter){ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; pIter->bEof = pSeg->pLeaf==0; pIter->iSwitchRowid = pSeg->iRowid; @@ -2735,39 +2744,44 @@ static void fts5MultiIterSetEof(Fts5IndexIter *pIter){ */ static void fts5MultiIterNext( Fts5Index *p, - Fts5IndexIter *pIter, + Fts5Iter *pIter, int bFrom, /* True if argument iFrom is valid */ i64 iFrom /* Advance at least as far as this */ ){ - if( p->rc==SQLITE_OK ){ - int bUseFrom = bFrom; - do { - int iFirst = pIter->aFirst[1].iFirst; - int bNewTerm = 0; - Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; - assert( p->rc==SQLITE_OK ); - if( bUseFrom && pSeg->pDlidx ){ - fts5SegIterNextFrom(p, pSeg, iFrom); - }else{ - pSeg->xNext(p, pSeg, &bNewTerm); - } + int bUseFrom = bFrom; + while( p->rc==SQLITE_OK ){ + int iFirst = pIter->aFirst[1].iFirst; + int bNewTerm = 0; + Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + assert( p->rc==SQLITE_OK ); + if( bUseFrom && pSeg->pDlidx ){ + fts5SegIterNextFrom(p, pSeg, iFrom); + }else{ + pSeg->xNext(p, pSeg, &bNewTerm); + } - if( pSeg->pLeaf==0 || bNewTerm - || fts5MultiIterAdvanceRowid(p, pIter, iFirst) - ){ - fts5MultiIterAdvanced(p, pIter, iFirst, 1); - fts5MultiIterSetEof(pIter); - } - fts5AssertMultiIterSetup(p, pIter); + if( pSeg->pLeaf==0 || bNewTerm + || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg) + ){ + fts5MultiIterAdvanced(p, pIter, iFirst, 1); + fts5MultiIterSetEof(pIter); + pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; + if( pSeg->pLeaf==0 ) return; + } - bUseFrom = 0; - }while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) ); + fts5AssertMultiIterSetup(p, pIter); + assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); + if( pIter->bSkipEmpty==0 || pSeg->nPos ){ + pIter->xSetOutputs(pIter, pSeg); + return; + } + bUseFrom = 0; } } static void fts5MultiIterNext2( Fts5Index *p, - Fts5IndexIter *pIter, + Fts5Iter *pIter, int *pbNewTerm /* OUT: True if *might* be new term */ ){ assert( pIter->bSkipEmpty ); @@ -2780,7 +2794,7 @@ static void fts5MultiIterNext2( assert( p->rc==SQLITE_OK ); pSeg->xNext(p, pSeg, &bNewTerm); if( pSeg->pLeaf==0 || bNewTerm - || fts5MultiIterAdvanceRowid(p, pIter, iFirst) + || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg) ){ fts5MultiIterAdvanced(p, pIter, iFirst, 1); fts5MultiIterSetEof(pIter); @@ -2794,17 +2808,19 @@ static void fts5MultiIterNext2( } } +static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){ +} -static Fts5IndexIter *fts5MultiIterAlloc( +static Fts5Iter *fts5MultiIterAlloc( Fts5Index *p, /* FTS5 backend to iterate within */ int nSeg ){ - Fts5IndexIter *pNew; + Fts5Iter *pNew; int nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlotaSeg[] */ sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */ ); @@ -2812,12 +2828,13 @@ static Fts5IndexIter *fts5MultiIterAlloc( pNew->nSeg = nSlot; pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot]; pNew->pIndex = p; + pNew->xSetOutputs = fts5IterSetOutputs_Noop; } return pNew; } /* -** Allocate a new Fts5IndexIter object. +** Allocate a new Fts5Iter object. ** ** The new object will be used to iterate through data in structure pStruct. ** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel @@ -2835,14 +2852,14 @@ static void fts5MultiIterNew( const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */ int iLevel, /* Level to iterate (-1 for all) */ int nSegment, /* Number of segments to merge (iLevel>=0) */ - Fts5IndexIter **ppOut /* New object */ + Fts5Iter **ppOut /* New object */ ){ int nSeg = 0; /* Number of segment-iters in use */ int iIter = 0; /* */ int iSeg; /* Used to iterate through segments */ Fts5Buffer buf = {0,0,0}; /* Buffer used by fts5SegIterSeekInit() */ Fts5StructureLevel *pLvl; - Fts5IndexIter *pNew; + Fts5Iter *pNew; assert( (pTerm==0 && nTerm==0) || iLevel<0 ); @@ -2917,16 +2934,16 @@ static void fts5MultiIterNew( } /* -** Create an Fts5IndexIter that iterates through the doclist provided +** Create an Fts5Iter that iterates through the doclist provided ** as the second argument. */ static void fts5MultiIterNew2( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Data *pData, /* Doclist to iterate through */ int bDesc, /* True for descending rowid order */ - Fts5IndexIter **ppOut /* New object */ + Fts5Iter **ppOut /* New object */ ){ - Fts5IndexIter *pNew; + Fts5Iter *pNew; pNew = fts5MultiIterAlloc(p, 2); if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; @@ -2961,7 +2978,7 @@ static void fts5MultiIterNew2( ** Return true if the iterator is at EOF or if an error has occurred. ** False otherwise. */ -static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){ +static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){ assert( p->rc || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof ); @@ -2973,7 +2990,7 @@ static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){ ** to. If the iterator points to EOF when this function is called the ** results are undefined. */ -static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){ +static i64 fts5MultiIterRowid(Fts5Iter *pIter){ assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf ); return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid; } @@ -2983,7 +3000,7 @@ static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){ */ static void fts5MultiIterNextFrom( Fts5Index *p, - Fts5IndexIter *pIter, + Fts5Iter *pIter, i64 iMatch ){ while( 1 ){ @@ -3000,7 +3017,7 @@ static void fts5MultiIterNextFrom( ** Return a pointer to a buffer containing the term associated with the ** entry that the iterator currently points to. */ -static const u8 *fts5MultiIterTerm(Fts5IndexIter *pIter, int *pn){ +static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){ Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; *pn = p->term.n; return p->term.p; @@ -3582,7 +3599,7 @@ static void fts5WriteInit( ** incremental merge operation. This function is called if the incremental ** merge step has finished but the input has not been completely exhausted. */ -static void fts5TrimSegments(Fts5Index *p, Fts5IndexIter *pIter){ +static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){ int i; Fts5Buffer buf; memset(&buf, 0, sizeof(Fts5Buffer)); @@ -3660,7 +3677,7 @@ static void fts5IndexMergeLevel( Fts5Structure *pStruct = *ppStruct; Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureLevel *pLvlOut; - Fts5IndexIter *pIter = 0; /* Iterator to read input data */ + Fts5Iter *pIter = 0; /* Iterator to read input data */ int nRem = pnRem ? *pnRem : 0; /* Output leaf pages left to write */ int nInput; /* Number of input segments */ Fts5SegWriter writer; /* Writer object */ @@ -4342,7 +4359,7 @@ static int fts5IndexExtractCol( static int fts5AppendRowid( Fts5Index *p, i64 iDelta, - Fts5IndexIter *pMulti, + Fts5Iter *pMulti, Fts5Colset *pColset, Fts5Buffer *pBuf ){ @@ -4367,7 +4384,7 @@ static int fts5AppendRowid( static int fts5AppendPoslist( Fts5Index *p, i64 iDelta, - Fts5IndexIter *pMulti, + Fts5Iter *pMulti, Fts5Colset *pColset, Fts5Buffer *pBuf ){ @@ -4645,14 +4662,14 @@ static void fts5SetupPrefixIter( const u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ - Fts5IndexIter **ppIter /* OUT: New iterator */ + Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; const int nBuf = 32; void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); - int (*xAppend)(Fts5Index*, i64, Fts5IndexIter*, Fts5Colset*, Fts5Buffer*); + int (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Colset*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; @@ -4668,7 +4685,7 @@ static void fts5SetupPrefixIter( const int flags = FTS5INDEX_QUERY_SCAN; int i; i64 iLastRowid = 0; - Fts5IndexIter *p1 = 0; /* Iterator used to gather data from index */ + Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ Fts5Data *pData; Fts5Buffer doclist; int bNewTerm = 1; @@ -4932,6 +4949,154 @@ int sqlite3Fts5IndexWrite( return rc; } + +static int fts5IndexExtractColset ( + Fts5Colset *pColset, /* Colset to filter on */ + const u8 *pPos, int nPos, /* Position list */ + Fts5Buffer *pBuf /* Output buffer */ +){ + int rc = SQLITE_OK; + int i; + + fts5BufferZero(pBuf); + for(i=0; inCol; i++){ + const u8 *pSub = pPos; + int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); + if( nSub ){ + fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); + } + } + return rc; +} + +/* +** xSetOutputs callback used by detail=none tables. +*/ +static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){ + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE ); + pIter->base.iRowid = pSeg->iRowid; + pIter->base.nData = pSeg->nPos; +} + +/* +** xSetOutputs callback used by detail=full and detail=col tables when no +** column filters are specified. +*/ +static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ + pIter->base.iRowid = pSeg->iRowid; + pIter->base.nData = pSeg->nPos; + + assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE ); + assert( pIter->pColset==0 || pIter->bFiltered ); + + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ + /* All data is stored on the current page. Populate the output + ** variables to point into the body of the page object. */ + pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + }else{ + /* The data is distributed over two or more pages. Copy it into the + ** Fts5Iter.poslist buffer and then set the output pointer to point + ** to this buffer. */ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + } +} + +/* +** xSetOutputs callback used by detail=col when there is a column filter. +*/ +static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ + Fts5Colset *pColset = pIter->pColset; + pIter->base.iRowid = pSeg->iRowid; + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + assert( pColset ); + + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf && 0 ){ + /* All data is stored on the current page. Populate the output + ** variables to point into the body of the page object. */ + Fts5PoslistWriter writer = {0}; + const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + int n = pSeg->nPos; + int iCol = 0; + i64 iPos = 0; + int iOff = 0; + + fts5BufferZero(&pIter->poslist); + while( 0==sqlite3Fts5PoslistNext64(a, n, &iOff, &iPos) ){ + if( iPos==pColset->aiCol[iCol] ){ + sqlite3Fts5PoslistWriterAppend(&pIter->poslist, &writer, iPos); + if( ++iCol>=pColset->nCol ) break; + } + } + + }else{ + /* The data is distributed over two or more pages. Copy it into the + ** Fts5Iter.poslist buffer and then set the output pointer to point + ** to this buffer. */ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); + } + + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; +} + +/* +** xSetOutputs callback used by detail=full when there is a column filter. +*/ +static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ + Fts5Colset *pColset = pIter->pColset; + pIter->base.iRowid = pSeg->iRowid; + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL ); + assert( pColset ); + + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ + /* All data is stored on the current page. Populate the output + ** variables to point into the body of the page object. */ + const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + if( pColset->nCol==1 ){ + pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); + pIter->base.pData = a; + }else{ + fts5BufferZero(&pIter->poslist); + fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } + }else{ + /* The data is distributed over two or more pages. Copy it into the + ** Fts5Iter.poslist buffer and then set the output pointer to point + ** to this buffer. */ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } +} + +static void fts5IterSetOutputCb(Fts5Iter *pIter){ + int eDetail = pIter->pIndex->pConfig->eDetail; + if( eDetail==FTS5_DETAIL_NONE ){ + pIter->xSetOutputs = fts5IterSetOutputs_None; + } + + else if( pIter->pColset==0 || pIter->bFiltered ){ + pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; + } + + else if( eDetail==FTS5_DETAIL_FULL ){ + pIter->xSetOutputs = fts5IterSetOutputs_Full; + } + + else{ + assert( eDetail==FTS5_DETAIL_COLUMNS ); + pIter->xSetOutputs = fts5IterSetOutputs_Col; + } +} + /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -4944,22 +5109,27 @@ int sqlite3Fts5IndexQuery( Fts5IndexIter **ppIter /* OUT: New iterator object */ ){ Fts5Config *pConfig = p->pConfig; - Fts5IndexIter *pRet = 0; - int iIdx = 0; + Fts5Iter *pRet = 0; 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 ); if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ + int iIdx = 0; /* Index to search */ memcpy(&buf.p[1], pToken, nToken); -#ifdef SQLITE_DEBUG - /* If the QUERY_TEST_NOIDX flag was specified, then this must be a + /* Figure out which index to search and set iIdx accordingly. If this + ** is a prefix query for which there is no prefix index, set iIdx to + ** greater than pConfig->nPrefix to indicate that the query will be + ** satisfied by scanning multiple terms in the main index. + ** + ** If the QUERY_TEST_NOIDX flag was specified, then this must be a ** prefix-query. Instead of using a prefix-index (if one exists), ** evaluate the prefix query using the main FTS index. This is used ** for internal sanity checking by the integrity-check in debug ** mode only. */ +#ifdef SQLITE_DEBUG if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){ assert( flags & FTS5INDEX_QUERY_PREFIX ); iIdx = 1+pConfig->nPrefix; @@ -4973,6 +5143,7 @@ int sqlite3Fts5IndexQuery( } if( iIdx<=pConfig->nPrefix ){ + /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); if( pStruct ){ @@ -4980,17 +5151,25 @@ int sqlite3Fts5IndexQuery( fts5StructureRelease(pStruct); } }else{ + /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; buf.p[0] = FTS5_MAIN_PREFIX; fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); } + if( p->rc==SQLITE_OK ){ + Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; + pRet->pColset = pColset; + fts5IterSetOutputCb(pRet); + if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + } if( p->rc ){ - sqlite3Fts5IterClose(pRet); + sqlite3Fts5IterClose(&pRet->base); pRet = 0; fts5CloseReader(p); } - *ppIter = pRet; + + *ppIter = &pRet->base; sqlite3Fts5BufferFree(&buf); } return fts5IndexReturn(p); @@ -5000,14 +5179,15 @@ int sqlite3Fts5IndexQuery( ** Return true if the iterator passed as the only argument is at EOF. */ int sqlite3Fts5IterEof(Fts5IndexIter *pIter){ - assert( pIter->pIndex->rc==SQLITE_OK ); - return pIter->bEof; + assert( ((Fts5Iter*)pIter)->pIndex->rc==SQLITE_OK ); + return ((Fts5Iter*)pIter)->bEof; } /* ** Move to the next matching rowid. */ -int sqlite3Fts5IterNext(Fts5IndexIter *pIter){ +int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); return fts5IndexReturn(pIter->pIndex); @@ -5016,7 +5196,8 @@ int sqlite3Fts5IterNext(Fts5IndexIter *pIter){ /* ** Move to the next matching term/rowid. Used by the fts5vocab module. */ -int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){ +int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *p = pIter->pIndex; assert( pIter->pIndex->rc==SQLITE_OK ); @@ -5039,7 +5220,8 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){ ** definition of "at or after" depends on whether this iterator iterates ** in ascending or descending rowid order. */ -int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){ +int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); return fts5IndexReturn(pIter->pIndex); } @@ -5047,41 +5229,21 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){ /* ** Return the current rowid. */ -i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIter){ - return fts5MultiIterRowid(pIter); +i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIndexIter){ + return fts5MultiIterRowid((Fts5Iter*)pIndexIter); } /* ** Return the current term. */ -const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){ +const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ int n; - const char *z = (const char*)fts5MultiIterTerm(pIter, &n); + const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n); *pn = n-1; return &z[1]; } -static int fts5IndexExtractColset ( - Fts5Colset *pColset, /* Colset to filter on */ - const u8 *pPos, int nPos, /* Position list */ - Fts5Buffer *pBuf /* Output buffer */ -){ - int rc = SQLITE_OK; - int i; - - fts5BufferZero(pBuf); - for(i=0; inCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); - } - } - return rc; -} - - /* ** Return a pointer to a buffer containing a copy of the position list for ** the current entry. Output variable *pn is set to the size of the buffer @@ -5091,12 +5253,13 @@ static int fts5IndexExtractColset ( ** field that starts the position list on disk. */ int sqlite3Fts5IterPoslist( - Fts5IndexIter *pIter, + Fts5IndexIter *pIndexIter, Fts5Colset *pColset, /* Column filter (or NULL) */ const u8 **pp, /* OUT: Pointer to position-list data */ int *pn, /* OUT: Size of position-list in bytes */ i64 *piRowid /* OUT: Current rowid */ ){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int eDetail = pIter->pIndex->pConfig->eDetail; @@ -5133,10 +5296,11 @@ int sqlite3Fts5IterPoslist( } int sqlite3Fts5IterCollist( - Fts5IndexIter *pIter, + Fts5IndexIter *pIndexIter, const u8 **pp, /* OUT: Pointer to position-list data */ int *pn /* OUT: Size of position-list in bytes */ ){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); *pp = pIter->poslist.p; *pn = pIter->poslist.n; @@ -5148,7 +5312,8 @@ int sqlite3Fts5IterCollist( ** copies the position list into the buffer supplied as the second ** argument. */ -int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){ +int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIndexIter, Fts5Buffer *pBuf){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *p = pIter->pIndex; Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; assert( p->rc==SQLITE_OK ); @@ -5160,8 +5325,9 @@ int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){ /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ -void sqlite3Fts5IterClose(Fts5IndexIter *pIter){ - if( pIter ){ +void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ + if( pIndexIter ){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5MultiIterFree(pIter->pIndex, pIter); fts5CloseReader(pIndex); @@ -5328,35 +5494,30 @@ static int fts5QueryCksum( ){ int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; - Fts5IndexIter *pIdxIter = 0; - Fts5Buffer buf = {0, 0, 0}; - int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter); + Fts5IndexIter *pIter = 0; + int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); - while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){ - i64 rowid = sqlite3Fts5IterRowid(pIdxIter); + while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ + i64 rowid = sqlite3Fts5IterRowid(pIter); if( eDetail==FTS5_DETAIL_NONE ){ cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); }else{ - rc = sqlite3Fts5IterPoslistBuffer(pIdxIter, &buf); - if( rc==SQLITE_OK ){ - Fts5PoslistReader sReader; - for(sqlite3Fts5PoslistReaderInit(buf.p, buf.n, &sReader); - sReader.bEof==0; - sqlite3Fts5PoslistReaderNext(&sReader) - ){ - int iCol = FTS5_POS2COLUMN(sReader.iPos); - int iOff = FTS5_POS2OFFSET(sReader.iPos); - cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); - } + Fts5PoslistReader sReader; + for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader); + sReader.bEof==0; + sqlite3Fts5PoslistReaderNext(&sReader) + ){ + int iCol = FTS5_POS2COLUMN(sReader.iPos); + int iOff = FTS5_POS2OFFSET(sReader.iPos); + cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); } } if( rc==SQLITE_OK ){ - rc = sqlite3Fts5IterNext(pIdxIter); + rc = sqlite3Fts5IterNext(pIter); } } - sqlite3Fts5IterClose(pIdxIter); - fts5BufferFree(&buf); + sqlite3Fts5IterClose(pIter); *pCksum = cksum; return rc; @@ -5661,7 +5822,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ - Fts5IndexIter *pIter; /* Used to iterate through entire index */ + Fts5Iter *pIter; /* Used to iterate through entire index */ Fts5Structure *pStruct; /* Index structure */ #ifdef SQLITE_DEBUG diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index ddc5576c5d..17aa5816c4 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -412,28 +412,29 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ i64 iPos = 0; /* 64-bit position read from poslist */ int iOff = 0; /* Current offset within position list */ + pPos = pCsr->pIter->pData; + nPos = pCsr->pIter->nData; switch( pCsr->pConfig->eDetail ){ case FTS5_DETAIL_FULL: - rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy); - if( rc==SQLITE_OK ){ - if( pTab->eType==FTS5_VOCAB_ROW ){ - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - pCsr->aCnt[0]++; - } - pCsr->aDoc[0]++; - }else{ - int iCol = -1; - while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ - int ii = FTS5_POS2COLUMN(iPos); - pCsr->aCnt[ii]++; - if( iCol!=ii ){ - if( ii>=nCol ){ - rc = FTS5_CORRUPT; - break; - } - pCsr->aDoc[ii]++; - iCol = ii; + pPos = pCsr->pIter->pData; + nPos = pCsr->pIter->nData; + if( pTab->eType==FTS5_VOCAB_ROW ){ + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ + pCsr->aCnt[0]++; + } + pCsr->aDoc[0]++; + }else{ + int iCol = -1; + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ + int ii = FTS5_POS2COLUMN(iPos); + pCsr->aCnt[ii]++; + if( iCol!=ii ){ + if( ii>=nCol ){ + rc = FTS5_CORRUPT; + break; } + pCsr->aDoc[ii]++; + iCol = ii; } } } @@ -443,19 +444,14 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ if( pTab->eType==FTS5_VOCAB_ROW ){ pCsr->aDoc[0]++; }else{ - Fts5Buffer buf = {0, 0, 0}; - rc = sqlite3Fts5IterPoslistBuffer(pCsr->pIter, &buf); - if( rc==SQLITE_OK ){ - while( 0==sqlite3Fts5PoslistNext64(buf.p, buf.n, &iOff,&iPos) ){ - assert_nc( iPos>=0 && iPos=nCol ){ - rc = FTS5_CORRUPT; - break; - } - pCsr->aDoc[iPos]++; + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ + assert_nc( iPos>=0 && iPos=nCol ){ + rc = FTS5_CORRUPT; + break; } + pCsr->aDoc[iPos]++; } - sqlite3Fts5BufferFree(&buf); } break; diff --git a/ext/fts5/test/fts5ac.test b/ext/fts5/test/fts5ac.test index 00b1328867..a5a522a466 100644 --- a/ext/fts5/test/fts5ac.test +++ b/ext/fts5/test/fts5ac.test @@ -250,7 +250,6 @@ foreach {tn2 sql} { FROM xx WHERE xx match $expr } $res - set res [fts5_query_data $expr xx DESC] do_execsql_test 1.$tn2.$tn.[llength $res].desc { SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx) diff --git a/manifest b/manifest index 6c3814c3d9..99a9a8b139 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3TokenInit()\sutility\sfunction. -D 2016-01-22T17:48:09.470 +C Experimental\sperformance\senhancements\sfor\sfts5. +D 2016-01-22T19:48:34.825 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 @@ -97,13 +97,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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 5599703af9c13512900a9f22fec39d48078d619d +F ext/fts5/fts5Int.h f93aed3d05d1b3686c4dccf70544bcfc7aa117f1 F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e F ext/fts5/fts5_buffer.c 7d3f6f01f8fdc45204e6a33925ef8478a67d28dd F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 -F ext/fts5/fts5_expr.c 4ab4504c54bbe24689c83411d8588f4ec99136e9 +F ext/fts5/fts5_expr.c 48b9131b74c8d3b8c12ba0f7995e2d60eecce9f2 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 716c301835a122ba36910b4f821c87d26ae9a5d9 +F ext/fts5/fts5_index.c 19062d1f40ba6d88d786a986d1c20f9d741799d0 F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3 F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -112,13 +112,13 @@ F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c ee6df1a3be103414d7b7af833ae1885c7b83a9d0 +F ext/fts5/fts5_vocab.c f1b4308b9b7ec8e659d0c9b39ddc8f1aeee47a1a F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 6d0d74b695c4be055a8ba1dd807f22a2abc95b5e F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b -F ext/fts5/test/fts5ac.test d5073ca7bd2d9fe8aab0c82c6c75a7e4b0d70ced +F ext/fts5/test/fts5ac.test dec95549e007dd9be52aa435cdcd0f08e14e64d0 F ext/fts5/test/fts5ad.test 0ddaa5b692ff220100ee396228838f4331399eaa F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c @@ -1419,7 +1419,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 e60461e984b8df09256bb0d733dbfae52568a145 -R 03ab6310cefadc63b5c7c7da966c2348 -U drh -Z 0c42ba520d71deaa3e0a21b23ff67f9d +P 7323175337b7ba85ac932ca892b28860f6a5b688 +R bc65520844365f59e43048a22901b688 +T *branch * fts5-perf +T *sym-fts5-perf * +T -sym-trunk * +U dan +Z 20f25a74d681d80924173ee060583d9e diff --git a/manifest.uuid b/manifest.uuid index e9fd60917b..fc3a1227d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7323175337b7ba85ac932ca892b28860f6a5b688 \ No newline at end of file +b5a57b812fd6a734cf2a342bf0b730ae18912d73 \ No newline at end of file From a8a18734857f3ad96403acecc201effaab473fb7 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 22 Jan 2016 22:16:50 +0000 Subject: [PATCH 006/107] More MSVC makefile cleanup. FossilOrigin-Name: df22556fd75997111e52f96572da8379dfe948be --- Makefile.msc | 36 ++++++++++++++++++------------------ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 3621d4f92b..504b2893ba 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1326,12 +1326,29 @@ TESTOPTS = --verbose=file --output=test-out.txt # all: dll libsqlite3.lib shell libtclsqlite3.lib +# Dynamic link library section. +# +dll: $(SQLITE3DLL) + +# Shell executable. +# +shell: $(SQLITE3EXE) + libsqlite3.lib: $(LIBOBJ) $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS) libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib $(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS) +$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) + $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) + +sqlite3.def: libsqlite3.lib + echo EXPORTS > sqlite3.def + dumpbin /all libsqlite3.lib \ + | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \ + | sort >> sqlite3.def + $(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \ /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) @@ -1419,7 +1436,7 @@ opcodes.lo: opcodes.c # Rule to build the Win32 resources object file. # !IF $(USE_RC)!=0 -$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(HDR) +$(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h for /F %%V in ('type "$(TOP)\VERSION"') do ( \ echo #define SQLITE_RESOURCE_VERSION %%V \ @@ -1957,20 +1974,3 @@ clean: del /Q sqlite-*-output.vsix 2>NUL del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL - -# Shell executable. -# -shell: $(SQLITE3EXE) - -# Dynamic link library section. -# -dll: $(SQLITE3DLL) - -sqlite3.def: libsqlite3.lib - echo EXPORTS > sqlite3.def - dumpbin /all libsqlite3.lib \ - | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \ - | sort >> sqlite3.def - -$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) - $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) diff --git a/manifest b/manifest index 566db8de82..2e197ef017 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Reenable\sthe\sxCurrentTime\sand\sxGetLastError\smethods\son\sthe\sunix\sVFSes\sas\slong\nas\sSQLITE_OMIT_DEPRECATED\sis\snot\sdefined. -D 2016-01-22T19:44:03.065 +C More\sMSVC\smakefile\scleanup. +D 2016-01-22T22:16:50.346 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 +F Makefile.msc bf507c4168b28d0ba47ac29d53fd6244289f10b8 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1419,7 +1419,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 7323175337b7ba85ac932ca892b28860f6a5b688 -R 4fcfc780a1da751b6f90e6d6f3ced841 -U drh -Z 703592c4495d8a71fd67fbd54e7f3927 +P c11c85fdb6514cae54bb44945cc197dcaba72307 +R 7e2bc2233b486c9642759e292a9803ed +U mistachkin +Z f537116bba79cbb015eb60c46b78af4d diff --git a/manifest.uuid b/manifest.uuid index a853332581..289f7591c2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c11c85fdb6514cae54bb44945cc197dcaba72307 \ No newline at end of file +df22556fd75997111e52f96572da8379dfe948be \ No newline at end of file From 147ef3948622234303ef6d38c38e6ee9fe325928 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 22 Jan 2016 23:17:51 +0000 Subject: [PATCH 007/107] In the TCL interface, if a database connection object was opened with the -uri 1 option, then also honor URI filenames for the "backup" and "restore" commands. FossilOrigin-Name: a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tclsqlite.c | 8 ++++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2e197ef017..ffb98b2734 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sMSVC\smakefile\scleanup. -D 2016-01-22T22:16:50.346 +C In\sthe\sTCL\sinterface,\sif\sa\sdatabase\sconnection\sobject\swas\sopened\swith\nthe\s-uri\s1\soption,\sthen\salso\shonor\sURI\sfilenames\sfor\sthe\s"backup"\sand\n"restore"\scommands. +D 2016-01-22T23:17:51.219 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc bf507c4168b28d0ba47ac29d53fd6244289f10b8 @@ -354,7 +354,7 @@ F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e -F src/tclsqlite.c 82979239a896992f9b78efec81cfda05d316a7d0 +F src/tclsqlite.c 94ef6e2794220c5b6064d4c78ec7169a8c5cc45d F src/test1.c 4f1b42699068b7806af3111786f5ad760c2c1ff7 F src/test2.c 5586f43fcd9a1be0830793cf9d354082c261b25b F src/test3.c a8887dabbbee3059af338f20d290084a63ed1b0f @@ -1419,7 +1419,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 c11c85fdb6514cae54bb44945cc197dcaba72307 -R 7e2bc2233b486c9642759e292a9803ed -U mistachkin -Z f537116bba79cbb015eb60c46b78af4d +P df22556fd75997111e52f96572da8379dfe948be +R 14f009751ec343de1132abf0a7bfa01f +U drh +Z 3618240e30f243f2df7ae3a3ace24b2d diff --git a/manifest.uuid b/manifest.uuid index 289f7591c2..5a178d2571 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -df22556fd75997111e52f96572da8379dfe948be \ No newline at end of file +a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 604e898265..aa913ca7c7 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -153,6 +153,7 @@ struct SqliteDb { IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ int nStep, nSort, nIndex; /* Statistics for most recent operation */ int nTransaction; /* Number of nested [transaction] methods */ + int openFlags; /* Flags used to open. (SQLITE_OPEN_URI) */ #ifdef SQLITE_TEST int bLegacyPrepare; /* True to use sqlite3_prepare() */ #endif @@ -1750,7 +1751,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); return TCL_ERROR; } - rc = sqlite3_open(zDestFile, &pDest); + rc = sqlite3_open_v2(zDestFile, &pDest, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "cannot open target database: ", sqlite3_errmsg(pDest), (char*)0); @@ -2613,7 +2615,8 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME"); return TCL_ERROR; } - rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0); + rc = sqlite3_open_v2(zSrcFile, &pSrc, + SQLITE_OPEN_READONLY | pDb->openFlags, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, "cannot open source database: ", sqlite3_errmsg(pSrc), (char*)0); @@ -3088,6 +3091,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ return TCL_ERROR; } p->maxStmt = NUM_PREPARED_STMTS; + p->openFlags = flags & SQLITE_OPEN_URI; p->interp = interp; zArg = Tcl_GetStringFromObj(objv[1], 0); if( DbUseNre() ){ From 4cfea5c794983b03bc7fcf7b43b91b83d27b945c Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 00:07:51 +0000 Subject: [PATCH 008/107] More work on the MSVC build. FossilOrigin-Name: a79c46bc61a35edbaf6112c26e8052314b0eb16a --- Makefile.msc | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/sqlite3.rc | 2 ++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 504b2893ba..5921e9375a 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1948,7 +1948,7 @@ rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL - del /Q *.bsc *.cod *.da *.bb *.bbg gmon.out 2>NUL + del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL del /Q lemon.* lempar.c parse.* 2>NUL del /Q mkkeywordhash.* keywordhash.h 2>NUL diff --git a/manifest b/manifest index ffb98b2734..61cf5d66ed 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C In\sthe\sTCL\sinterface,\sif\sa\sdatabase\sconnection\sobject\swas\sopened\swith\nthe\s-uri\s1\soption,\sthen\salso\shonor\sURI\sfilenames\sfor\sthe\s"backup"\sand\n"restore"\scommands. -D 2016-01-22T23:17:51.219 +C More\swork\son\sthe\sMSVC\sbuild. +D 2016-01-23T00:07:51.151 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc bf507c4168b28d0ba47ac29d53fd6244289f10b8 +F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -348,7 +348,7 @@ F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c 1db9a902e89201a0ae3ff5243a7a3f37842a3937 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 -F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad +F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 @@ -1419,7 +1419,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 df22556fd75997111e52f96572da8379dfe948be -R 14f009751ec343de1132abf0a7bfa01f -U drh -Z 3618240e30f243f2df7ae3a3ace24b2d +P a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 +R b34246fa017fc0ae2e7bf7cb484e3eeb +U mistachkin +Z ba075ff448ff99fa520b3503324fe6e9 diff --git a/manifest.uuid b/manifest.uuid index 5a178d2571..d1ea2b33a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 \ No newline at end of file +a79c46bc61a35edbaf6112c26e8052314b0eb16a \ No newline at end of file diff --git a/src/sqlite3.rc b/src/sqlite3.rc index 04dd086488..5a856490d6 100644 --- a/src/sqlite3.rc +++ b/src/sqlite3.rc @@ -39,9 +39,11 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US * Icon */ +#if !defined(RC_VERONLY) #define IDI_SQLITE 101 IDI_SQLITE ICON "..\\art\\sqlite370.ico" +#endif /* !defined(RC_VERONLY) */ /* * Version From 3e7860938b58cae4388007a2bc6506679f13ddff Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 07:53:04 +0000 Subject: [PATCH 009/107] Add tooling to create an MSVC Makefile capable of building the core library and shell only, using a pre-built amalgamation. FossilOrigin-Name: c46f1a13cb00264d1164399059250884c7be4ea0 --- Makefile.min.msc | 885 +++++++++++++++++++++++++++++++++++++++++++++ Makefile.msc | 38 ++ manifest | 17 +- manifest.uuid | 2 +- tool/mkmsvcmin.tcl | 88 +++++ 5 files changed, 1023 insertions(+), 7 deletions(-) create mode 100644 Makefile.min.msc create mode 100644 tool/mkmsvcmin.tcl diff --git a/Makefile.min.msc b/Makefile.min.msc new file mode 100644 index 0000000000..2ec986fa4b --- /dev/null +++ b/Makefile.min.msc @@ -0,0 +1,885 @@ +# +# nmake Makefile for SQLite +# +############################################################################### +############################## START OF OPTIONS ############################### +############################################################################### + +# The toplevel directory of the source tree. This is the directory +# that contains this "Makefile.msc". +# +TOP = . + + +# Set this non-0 to enable full warnings (-W4, etc) when compiling. +# +!IFNDEF USE_FULLWARN +USE_FULLWARN = 0 +!ENDIF + +# Set this non-0 to use "stdcall" calling convention for the core library +# and shell executable. +# +!IFNDEF USE_STDCALL +USE_STDCALL = 0 +!ENDIF + +# Set this non-0 to have the shell executable link against the core dynamic +# link library. +# +!IFNDEF DYNAMIC_SHELL +DYNAMIC_SHELL = 0 +!ENDIF + +# Set this non-0 to enable extra code that attempts to detect misuse of the +# SQLite API. +# +!IFNDEF API_ARMOR +API_ARMOR = 0 +!ENDIF + +# If necessary, create a list of harmless compiler warnings to disable when +# compiling the various tools. For the SQLite source code itself, warnings, +# if any, will be disabled from within it. +# +!IFNDEF NO_WARN +!IF $(USE_FULLWARN)!=0 +NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206 +NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706 +!ENDIF +!ENDIF + +# Set this non-0 to use the library paths and other options necessary for +# Windows Phone 8.1. +# +!IFNDEF USE_WP81_OPTS +USE_WP81_OPTS = 0 +!ENDIF + +# Set this non-0 to split the SQLite amalgamation file into chunks to +# be used for debugging with Visual Studio. +# +!IFNDEF SPLIT_AMALGAMATION +SPLIT_AMALGAMATION = 0 +!ENDIF + + +# Set this non-0 to dynamically link to the MSVC runtime library. +# +!IFNDEF USE_CRT_DLL +USE_CRT_DLL = 0 +!ENDIF + +# Set this non-0 to link to the RPCRT4 library. +# +!IFNDEF USE_RPCRT4_LIB +USE_RPCRT4_LIB = 0 +!ENDIF + +# Set this non-0 to generate assembly code listings for the source code +# files. +# +!IFNDEF USE_LISTINGS +USE_LISTINGS = 0 +!ENDIF + +# Set this non-0 to attempt setting the native compiler automatically +# for cross-compiling the command line tools needed during the compilation +# process. +# +!IFNDEF XCOMPILE +XCOMPILE = 0 +!ENDIF + +# Set this non-0 to use the native libraries paths for cross-compiling +# the command line tools needed during the compilation process. +# +!IFNDEF USE_NATIVE_LIBPATHS +USE_NATIVE_LIBPATHS = 0 +!ENDIF + +# Set this 0 to skip the compiling and embedding of version resources. +# +!IFNDEF USE_RC +USE_RC = 1 +!ENDIF + +# Set this non-0 to compile binaries suitable for the WinRT environment. +# This setting does not apply to any binaries that require Tcl to operate +# properly (i.e. the text fixture, etc). +# +!IFNDEF FOR_WINRT +FOR_WINRT = 0 +!ENDIF + +# Set this non-0 to compile binaries suitable for the UAP environment. +# This setting does not apply to any binaries that require Tcl to operate +# properly (i.e. the text fixture, etc). +# +!IFNDEF FOR_UAP +FOR_UAP = 0 +!ENDIF + +# Set this non-0 to compile binaries suitable for the Windows 10 platform. +# +!IFNDEF FOR_WIN10 +FOR_WIN10 = 0 +!ENDIF + + +# Set this to non-0 to create and use PDBs. +# +!IFNDEF SYMBOLS +SYMBOLS = 1 +!ENDIF + +# Set this to non-0 to use the SQLite debugging heap subsystem. +# +!IFNDEF MEMDEBUG +MEMDEBUG = 0 +!ENDIF + +# Set this to non-0 to use the Win32 native heap subsystem. +# +!IFNDEF WIN32HEAP +WIN32HEAP = 0 +!ENDIF + +# Set this to non-0 to enable OSTRACE() macros, which can be useful when +# debugging. +# +!IFNDEF OSTRACE +OSTRACE = 0 +!ENDIF + +# Set this to one of the following values to enable various debugging +# features. Each level includes the debugging options from the previous +# levels. Currently, the recognized values for DEBUG are: +# +# 0 == NDEBUG: Disables assert() and other runtime diagnostics. +# 1 == SQLITE_ENABLE_API_ARMOR: extra attempts to detect misuse of the API. +# 2 == Disables NDEBUG and all optimizations and then enables PDBs. +# 3 == SQLITE_DEBUG: Enables various diagnostics messages and code. +# 4 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call. +# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros. +# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros. +# +!IFNDEF DEBUG +DEBUG = 0 +!ENDIF + +# Enable use of available compiler optimizations? Normally, this should be +# non-zero. Setting this to zero, thus disabling all compiler optimizations, +# can be useful for testing. +# +!IFNDEF OPTIMIZATIONS +OPTIMIZATIONS = 2 +!ENDIF + +# Set the source code file to be used by executables and libraries when +# they need the amalgamation. +# +!IFNDEF SQLITE3C +!IF $(SPLIT_AMALGAMATION)!=0 +SQLITE3C = sqlite3-all.c +!ELSE +SQLITE3C = sqlite3.c +!ENDIF +!ENDIF + +# Set the include code file to be used by executables and libraries when +# they need SQLite. +# +!IFNDEF SQLITE3H +SQLITE3H = sqlite3.h +!ENDIF + +# This is the name to use for the SQLite dynamic link library (DLL). +# +!IFNDEF SQLITE3DLL +SQLITE3DLL = sqlite3.dll +!ENDIF + +# This is the name to use for the SQLite import library (LIB). +# +!IFNDEF SQLITE3LIB +SQLITE3LIB = sqlite3.lib +!ENDIF + +# This is the name to use for the SQLite shell executable (EXE). +# +!IFNDEF SQLITE3EXE +SQLITE3EXE = sqlite3.exe +!ENDIF + +# This is the argument used to set the program database (PDB) file for the +# SQLite shell executable (EXE). +# +!IFNDEF SQLITE3EXEPDB +SQLITE3EXEPDB = /pdb:sqlite3sh.pdb +!ENDIF + +# These are the "standard" SQLite compilation options used when compiling for +# the Windows platform. +# +!IFNDEF OPT_FEATURE_FLAGS +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 +!ENDIF + +# These are the "extended" SQLite compilation options used when compiling for +# the Windows 10 platform. +# +!IFNDEF EXT_FEATURE_FLAGS +!IF $(FOR_WIN10)!=0 +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1 +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1 +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1 +!ELSE +EXT_FEATURE_FLAGS = +!ENDIF +!ENDIF + +############################################################################### +############################### END OF OPTIONS ################################ +############################################################################### + +# This assumes that MSVC is always installed in 32-bit Program Files directory +# and sets the variable for use in locating other 32-bit installs accordingly. +# +PROGRAMFILES_X86 = $(VCINSTALLDIR)\..\.. +PROGRAMFILES_X86 = $(PROGRAMFILES_X86:\\=\) + +# Check for the predefined command macro CC. This should point to the compiler +# binary for the target platform. If it is not defined, simply define it to +# the legacy default value 'cl.exe'. +# +!IFNDEF CC +CC = cl.exe +!ENDIF + +# Check for the command macro LD. This should point to the linker binary for +# the target platform. If it is not defined, simply define it to the legacy +# default value 'link.exe'. +# +!IFNDEF LD +LD = link.exe +!ENDIF + +# Check for the predefined command macro RC. This should point to the resource +# compiler binary for the target platform. If it is not defined, simply define +# it to the legacy default value 'rc.exe'. +# +!IFNDEF RC +RC = rc.exe +!ENDIF + +# Check for the MSVC runtime library path macro. Othertise, this value will +# default to the 'lib' directory underneath the MSVC installation directory. +# +!IFNDEF CRTLIBPATH +CRTLIBPATH = $(VCINSTALLDIR)\lib +!ENDIF + +CRTLIBPATH = $(CRTLIBPATH:\\=\) + +# Check for the command macro NCC. This should point to the compiler binary +# for the platform the compilation process is taking place on. If it is not +# defined, simply define it to have the same value as the CC macro. When +# cross-compiling, it is suggested that this macro be modified via the command +# line (since nmake itself does not provide a built-in method to guess it). +# For example, to use the x86 compiler when cross-compiling for x64, a command +# line similar to the following could be used (all on one line): +# +# nmake /f Makefile.msc sqlite3.dll +# XCOMPILE=1 USE_NATIVE_LIBPATHS=1 +# +# Alternatively, the full path and file name to the compiler binary for the +# platform the compilation process is taking place may be specified (all on +# one line): +# +# nmake /f Makefile.msc sqlite3.dll +# "NCC=""%VCINSTALLDIR%\bin\cl.exe""" +# USE_NATIVE_LIBPATHS=1 +# +!IFDEF NCC +NCC = $(NCC:\\=\) +!ELSEIF $(XCOMPILE)!=0 +NCC = "$(VCINSTALLDIR)\bin\$(CC)" +NCC = $(NCC:\\=\) +!ELSE +NCC = $(CC) +!ENDIF + +# Check for the MSVC native runtime library path macro. Othertise, +# this value will default to the 'lib' directory underneath the MSVC +# installation directory. +# +!IFNDEF NCRTLIBPATH +NCRTLIBPATH = $(VCINSTALLDIR)\lib +!ENDIF + +NCRTLIBPATH = $(NCRTLIBPATH:\\=\) + +# Check for the Platform SDK library path macro. Othertise, this +# value will default to the 'lib' directory underneath the Windows +# SDK installation directory (the environment variable used appears +# to be available when using Visual C++ 2008 or later via the +# command line). +# +!IFNDEF NSDKLIBPATH +NSDKLIBPATH = $(WINDOWSSDKDIR)\lib +!ENDIF + +NSDKLIBPATH = $(NSDKLIBPATH:\\=\) + +# C compiler and options for use in building executables that +# will run on the platform that is doing the build. +# +!IF $(USE_FULLWARN)!=0 +BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS) +!ELSE +BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS) +!ENDIF + +# Check if assembly code listings should be generated for the source +# code files to be compiled. +# +!IF $(USE_LISTINGS)!=0 +BCC = $(BCC) -FAcs +!ENDIF + +# Check if the native library paths should be used when compiling +# the command line tools used during the compilation process. If +# so, set the necessary macro now. +# +!IF $(USE_NATIVE_LIBPATHS)!=0 +NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)" + +!IFDEF NUCRTLIBPATH +NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\) +NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)" +!ENDIF +!ENDIF + +# C compiler and options for use in building executables that +# will run on the target platform. (BCC and TCC are usually the +# same unless your are cross-compiling.) +# +!IF $(USE_FULLWARN)!=0 +TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS) +!ELSE +TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS) +!ENDIF + +TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -fp:precise +RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) $(RCOPTS) $(RCCOPTS) + +# Adjust the names of the primary targets for use with Windows 10. +# +!IF $(FOR_WIN10)!=0 +SQLITE3DLL = winsqlite3.dll +SQLITE3LIB = winsqlite3.lib +SQLITE3EXE = winsqlite3shell.exe +SQLITE3EXEPDB = +!ENDIF + +# Check if we want to use the "stdcall" calling convention when compiling. +# This is not supported by the compilers for non-x86 platforms. It should +# also be noted here that building any target with these "stdcall" options +# will most likely fail if the Tcl library is also required. This is due +# to how the Tcl library functions are declared and exported (i.e. without +# an explicit calling convention, which results in "cdecl"). +# +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 +!IF "$(PLATFORM)"=="x86" +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +!ELSE +!IFNDEF PLATFORM +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall +!ELSE +CORE_CCONV_OPTS = +SHELL_CCONV_OPTS = +!ENDIF +!ENDIF +!ELSE +CORE_CCONV_OPTS = +SHELL_CCONV_OPTS = +!ENDIF + +# These are additional compiler options used for the core library. +# +!IFNDEF CORE_COMPILE_OPTS +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport) +!ELSE +CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) +!ENDIF +!ENDIF + +# These are the additional targets that the core library should depend on +# when linking. +# +!IFNDEF CORE_LINK_DEP +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +CORE_LINK_DEP = +!ELSE +CORE_LINK_DEP = +!ENDIF +!ENDIF + +# These are additional linker options used for the core library. +# +!IFNDEF CORE_LINK_OPTS +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +CORE_LINK_OPTS = +!ELSE +CORE_LINK_OPTS = +!ENDIF +!ENDIF + +# These are additional compiler options used for the shell executable. +# +!IFNDEF SHELL_COMPILE_OPTS +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport) +!ELSE +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) +!ENDIF +!ENDIF + +# This is the source code that the shell executable should be compiled +# with. +# +!IFNDEF SHELL_CORE_SRC +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +SHELL_CORE_SRC = +!ELSE +SHELL_CORE_SRC = $(SQLITE3C) +!ENDIF +!ENDIF + +# This is the core library that the shell executable should depend on. +# +!IFNDEF SHELL_CORE_DEP +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +SHELL_CORE_DEP = $(SQLITE3DLL) +!ELSE +SHELL_CORE_DEP = +!ENDIF +!ENDIF + +# This is the core library that the shell executable should link with. +# +!IFNDEF SHELL_CORE_LIB +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0 +SHELL_CORE_LIB = $(SQLITE3LIB) +!ELSE +SHELL_CORE_LIB = +!ENDIF +!ENDIF + +# These are additional linker options used for the shell executable. +# +!IFNDEF SHELL_LINK_OPTS +SHELL_LINK_OPTS = $(SHELL_CORE_LIB) +!ENDIF + +# Check if assembly code listings should be generated for the source +# code files to be compiled. +# +!IF $(USE_LISTINGS)!=0 +TCC = $(TCC) -FAcs +!ENDIF + +# When compiling the library for use in the WinRT environment, +# the following compile-time options must be used as well to +# disable use of Win32 APIs that are not available and to enable +# use of Win32 APIs that are specific to Windows 8 and/or WinRT. +# +!IF $(FOR_WINRT)!=0 +TCC = $(TCC) -DSQLITE_OS_WINRT=1 +RCC = $(RCC) -DSQLITE_OS_WINRT=1 +TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP +RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP +!ENDIF + +# C compiler options for the Windows 10 platform (needs MSVC 2015). +# +!IF $(FOR_WIN10)!=0 +TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE +BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE +!ENDIF + +# Also, we need to dynamically link to the correct MSVC runtime +# when compiling for WinRT (e.g. debug or release) OR if the +# USE_CRT_DLL option is set to force dynamically linking to the +# MSVC runtime library. +# +!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0 +!IF $(DEBUG)>1 +TCC = $(TCC) -MDd +BCC = $(BCC) -MDd +!ELSE +TCC = $(TCC) -MD +BCC = $(BCC) -MD +!ENDIF +!ELSE +!IF $(DEBUG)>1 +TCC = $(TCC) -MTd +BCC = $(BCC) -MTd +!ELSE +TCC = $(TCC) -MT +BCC = $(BCC) -MT +!ENDIF +!ENDIF + + +# Define -DNDEBUG to compile without debugging (i.e., for production usage) +# Omitting the define will cause extra debugging code to be inserted and +# includes extra comments when "EXPLAIN stmt" is used. +# +!IF $(DEBUG)==0 +TCC = $(TCC) -DNDEBUG +BCC = $(BCC) -DNDEBUG +RCC = $(RCC) -DNDEBUG +!ENDIF + +!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0 +TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1 +RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1 +!ENDIF + +!IF $(DEBUG)>2 +TCC = $(TCC) -DSQLITE_DEBUG=1 +RCC = $(RCC) -DSQLITE_DEBUG=1 +!ENDIF + +!IF $(DEBUG)>4 || $(OSTRACE)!=0 +TCC = $(TCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1 +RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1 +!ENDIF + +!IF $(DEBUG)>5 +TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1 +RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1 +!ENDIF + +# Prevent warnings about "insecure" MSVC runtime library functions +# being used. +# +TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS +BCC = $(BCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS +RCC = $(RCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS + +# Prevent warnings about "deprecated" POSIX functions being used. +# +TCC = $(TCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS +BCC = $(BCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS +RCC = $(RCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS + +# Use the SQLite debugging heap subsystem? +# +!IF $(MEMDEBUG)!=0 +TCC = $(TCC) -DSQLITE_MEMDEBUG=1 +RCC = $(RCC) -DSQLITE_MEMDEBUG=1 + +# Use native Win32 heap subsystem instead of malloc/free? +# +!ELSEIF $(WIN32HEAP)!=0 +TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1 +RCC = $(RCC) -DSQLITE_WIN32_MALLOC=1 + +# Validate the heap on every call into the native Win32 heap subsystem? +# +!IF $(DEBUG)>3 +TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 +RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 +!ENDIF +!ENDIF + + +# Compiler options needed for programs that use the readline() library. +# +!IFNDEF READLINE_FLAGS +READLINE_FLAGS = -DHAVE_READLINE=0 +!ENDIF + +# The library that programs using readline() must link against. +# +!IFNDEF LIBREADLINE +LIBREADLINE = +!ENDIF + +# Should the database engine be compiled threadsafe +# +TCC = $(TCC) -DSQLITE_THREADSAFE=1 +RCC = $(RCC) -DSQLITE_THREADSAFE=1 + +# Do threads override each others locks by default (1), or do we test (-1) +# +TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 +RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1 + +# Any target libraries which libsqlite must be linked against +# +!IFNDEF TLIBS +TLIBS = +!ENDIF + +# Flags controlling use of the in memory btree implementation +# +# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to +# default to file, 2 to default to memory, and 3 to force temporary +# tables to always be in memory. +# +TCC = $(TCC) -DSQLITE_TEMP_STORE=1 +RCC = $(RCC) -DSQLITE_TEMP_STORE=1 + +# Enable/disable loadable extensions, and other optional features +# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*). +# The same set of OMIT and ENABLE flags should be passed to the +# LEMON parser generator and the mkkeywordhash tool as well. + +# These are the required SQLite compilation options used when compiling for +# the Windows platform. +# +REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100 + +# If we are linking to the RPCRT4 library, enable features that need it. +# +!IF $(USE_RPCRT4_LIB)!=0 +REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1 +!ENDIF + +# Add the required and optional SQLite compilation options into the command +# lines used to invoke the MSVC code and resource compilers. +# +TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) +RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) + +# Add in any optional parameters specified on the commane line, e.g. +# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1" +# +TCC = $(TCC) $(OPTS) +RCC = $(RCC) $(OPTS) + +# If compiling for debugging, add some defines. +# +!IF $(DEBUG)>1 +TCC = $(TCC) -D_DEBUG +BCC = $(BCC) -D_DEBUG +RCC = $(RCC) -D_DEBUG +!ENDIF + +# If optimizations are enabled or disabled (either implicitly or +# explicitly), add the necessary flags. +# +!IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0 +TCC = $(TCC) -Od +BCC = $(BCC) -Od +!ELSEIF $(OPTIMIZATIONS)>=3 +TCC = $(TCC) -Ox +BCC = $(BCC) -Ox +!ELSEIF $(OPTIMIZATIONS)==2 +TCC = $(TCC) -O2 +BCC = $(BCC) -O2 +!ELSEIF $(OPTIMIZATIONS)==1 +TCC = $(TCC) -O1 +BCC = $(BCC) -O1 +!ENDIF + +# If symbols are enabled (or compiling for debugging), enable PDBs. +# +!IF $(DEBUG)>1 || $(SYMBOLS)!=0 +TCC = $(TCC) -Zi +BCC = $(BCC) -Zi +!ENDIF + + +# Command line prefixes for compiling code, compiling resources, +# linking, etc. +# +LTCOMPILE = $(TCC) -Fo$@ +LTRCOMPILE = $(RCC) -r +LTLIB = lib.exe +LTLINK = $(TCC) -Fe$@ + +# If requested, link to the RPCRT4 library. +# +!IF $(USE_RPCRT4_LIB)!=0 +LTLINK = $(LTLINK) rpcrt4.lib +!ENDIF + +# If a platform was set, force the linker to target that. +# Note that the vcvars*.bat family of batch files typically +# set this for you. Otherwise, the linker will attempt +# to deduce the binary type based on the object files. +!IFDEF PLATFORM +LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM) +LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM) +!ELSE +LTLINKOPTS = /NOLOGO +LTLIBOPTS = /NOLOGO +!ENDIF + +# When compiling for use in the WinRT environment, the following +# linker option must be used to mark the executable as runnable +# only in the context of an application container. +# +!IF $(FOR_WINRT)!=0 +LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER +!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0" +!IFNDEF STORELIBPATH +!IF "$(PLATFORM)"=="x86" +STORELIBPATH = $(CRTLIBPATH)\store +!ELSEIF "$(PLATFORM)"=="x64" +STORELIBPATH = $(CRTLIBPATH)\store\amd64 +!ELSEIF "$(PLATFORM)"=="ARM" +STORELIBPATH = $(CRTLIBPATH)\store\arm +!ELSE +STORELIBPATH = $(CRTLIBPATH)\store +!ENDIF +!ENDIF +STORELIBPATH = $(STORELIBPATH:\\=\) +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)" +!ENDIF +!ENDIF + +# When compiling for Windows Phone 8.1, an extra library path is +# required. +# +!IF $(USE_WP81_OPTS)!=0 +!IFNDEF WP81LIBPATH +!IF "$(PLATFORM)"=="x86" +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86 +!ELSEIF "$(PLATFORM)"=="ARM" +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM +!ELSE +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86 +!ENDIF +!ENDIF +!ENDIF + +# When compiling for Windows Phone 8.1, some extra linker options +# are also required. +# +!IF $(USE_WP81_OPTS)!=0 +!IFDEF WP81LIBPATH +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)" +!ENDIF +LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE +LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib +LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib +!ENDIF + +# When compiling for UAP, some extra linker options are also required. +# +!IF $(FOR_UAP)!=0 +LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib +LTLINKOPTS = $(LTLINKOPTS) mincore.lib +!IFDEF PSDKLIBPATH +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)" +!ENDIF +!ENDIF + +# If either debugging or symbols are enabled, enable PDBs. +# +!IF $(DEBUG)>1 || $(SYMBOLS)!=0 +LDFLAGS = /DEBUG $(LDOPTS) +!ELSE +LDFLAGS = $(LDOPTS) +!ENDIF + + +# You should not have to change anything below this line +############################################################################### + + +# Object files for the amalgamation. +# +LIBOBJS1 = sqlite3.lo + +# Determine the real value of LIBOBJ based on the 'configure' script +# +LIBOBJ = $(LIBOBJS1) + +# Determine if embedded resource compilation and usage are enabled. +# +!IF $(USE_RC)!=0 +LIBRESOBJS = sqlite3res.lo +!ELSE +LIBRESOBJS = +!ENDIF + + +# Additional compiler options for the shell. These are only effective +# when the shell is not being dynamically linked. +# +!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 +!ENDIF + + +# This is the default Makefile target. The objects listed here +# are what get build when you type just "make" with no arguments. +# +all: dll libsqlite3.lib shell + +# Dynamic link library section. +# +dll: $(SQLITE3DLL) + +# Shell executable. +# +shell: $(SQLITE3EXE) + +libsqlite3.lib: $(LIBOBJ) + $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS) + + +$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) + $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) + + +$(SQLITE3EXE): $(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) + $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \ + /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) + + +# Rule to build the amalgamation +# +sqlite3.lo: $(SQLITE3C) + $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C) + + +# Rule to build the Win32 resources object file. +# +!IF $(USE_RC)!=0 +_HASHCHAR=^# +!IF ![echo !IFNDEF VERSION > rcver.vc] && \ + ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \ + ![echo !ENDIF >> rcver.vc] +!INCLUDE rcver.vc +!ENDIF + +RESOURCE_VERSION = $(VERSION:^#=) +RESOURCE_VERSION = $(RESOURCE_VERSION:define=) +RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=) +RESOURCE_VERSION = $(RESOURCE_VERSION:"=) +RESOURCE_VERSION = $(RESOURCE_VERSION:.=,) + +$(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H) + echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h + echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h + echo #endif >> sqlite3rc.h + $(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc +!ENDIF + + +clean: + del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL + del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL diff --git a/Makefile.msc b/Makefile.msc index 5921e9375a..ab0ba95d53 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -10,11 +10,13 @@ # TOP = . +# <> # Set this non-0 to create and use the SQLite amalgamation file. # !IFNDEF USE_AMALGAMATION USE_AMALGAMATION = 1 !ENDIF +# <> # Set this non-0 to enable full warnings (-W4, etc) when compiling. # @@ -68,11 +70,13 @@ USE_WP81_OPTS = 0 SPLIT_AMALGAMATION = 0 !ENDIF +# <> # Set this non-0 to use the International Components for Unicode (ICU). # !IFNDEF USE_ICU USE_ICU = 0 !ENDIF +# <> # Set this non-0 to dynamically link to the MSVC runtime library. # @@ -136,12 +140,14 @@ FOR_UAP = 0 FOR_WIN10 = 0 !ENDIF +# <> # Set this non-0 to skip attempting to look for and/or link with the Tcl # runtime library. # !IFNDEF NO_TCL NO_TCL = 0 !ENDIF +# <> # Set this to non-0 to create and use PDBs. # @@ -553,6 +559,7 @@ BCC = $(BCC) -MT !ENDIF !ENDIF +# <> # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in # any extension header files by default. For non-amalgamation # builds, we need to make sure the compiler can find these. @@ -576,6 +583,7 @@ MKSQLITE3C_ARGS = --linemacros MKSQLITE3C_ARGS = !ENDIF !ENDIF +# <> # Define -DNDEBUG to compile without debugging (i.e., for production usage) # Omitting the define will cause extra debugging code to be inserted and @@ -640,6 +648,7 @@ RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1 !ENDIF !ENDIF +# <> # The locations of the Tcl header and library files. Also, the library that # non-stubs enabled programs using Tcl must link against. These variables # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment @@ -691,6 +700,7 @@ LIBICU = icuuc.lib icuin.lib !IFNDEF TCLSH_CMD TCLSH_CMD = tclsh85 !ENDIF +# <> # Compiler options needed for programs that use the readline() library. # @@ -789,6 +799,7 @@ TCC = $(TCC) -Zi BCC = $(BCC) -Zi !ENDIF +# <> # If ICU support is enabled, add the compiler options for it. # !IF $(USE_ICU)!=0 @@ -799,6 +810,7 @@ RCC = $(RCC) -I$(TOP)\ext\icu TCC = $(TCC) -I$(ICUINCDIR) RCC = $(RCC) -I$(ICUINCDIR) !ENDIF +# <> # Command line prefixes for compiling code, compiling resources, # linking, etc. @@ -894,6 +906,7 @@ LDFLAGS = /DEBUG $(LDOPTS) LDFLAGS = $(LDOPTS) !ENDIF +# <> # Start with the Tcl related linker options. # !IF $(NO_TCL)==0 @@ -907,10 +920,12 @@ LTLIBS = $(LIBTCL) LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR) LTLIBS = $(LTLIBS) $(LIBICU) !ENDIF +# <> # You should not have to change anything below this line ############################################################################### +# <> # Object files for the SQLite library (non-amalgamation). # LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \ @@ -934,6 +949,7 @@ LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \ vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \ vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \ utf.lo vtab.lo +# <> # Object files for the amalgamation. # @@ -941,11 +957,15 @@ LIBOBJS1 = sqlite3.lo # Determine the real value of LIBOBJ based on the 'configure' script # +# <> !IF $(USE_AMALGAMATION)==0 LIBOBJ = $(LIBOBJS0) !ELSE +# <> LIBOBJ = $(LIBOBJS1) +# <> !ENDIF +# <> # Determine if embedded resource compilation and usage are enabled. # @@ -955,6 +975,7 @@ LIBRESOBJS = sqlite3res.lo LIBRESOBJS = !ENDIF +# <> # All of the source code files. # SRC1 = \ @@ -1303,6 +1324,7 @@ FUZZDATA = \ $(TOP)\test\fuzzdata2.db \ $(TOP)\test\fuzzdata3.db \ $(TOP)\test\fuzzdata4.db +# <> # Additional compiler options for the shell. These are only effective # when the shell is not being dynamically linked. @@ -1311,6 +1333,7 @@ FUZZDATA = \ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 !ENDIF +# <> # Extra compiler options for various test tools. # MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5 @@ -1320,6 +1343,7 @@ FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 # Standard options to testfixture. # TESTOPTS = --verbose=file --output=test-out.txt +# <> # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. @@ -1337,22 +1361,27 @@ shell: $(SQLITE3EXE) libsqlite3.lib: $(LIBOBJ) $(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS) +# <> libtclsqlite3.lib: tclsqlite.lo libsqlite3.lib $(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS) +# <> $(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP) $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) +# <> sqlite3.def: libsqlite3.lib echo EXPORTS > sqlite3.def dumpbin /all libsqlite3.lib \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \ | sort >> sqlite3.def +# <> $(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H) $(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \ /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) +# <> sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1406,12 +1435,14 @@ sqlite3.c: .target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl +# <> # Rule to build the amalgamation # sqlite3.lo: $(SQLITE3C) $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C) +# <> # Rules to build the LEMON compiler generator # lempar.c: $(TOP)\tool\lempar.c @@ -1432,10 +1463,12 @@ parse.lo: parse.c $(HDR) opcodes.lo: opcodes.c $(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c +# <> # Rule to build the Win32 resources object file. # !IF $(USE_RC)!=0 +# <> $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h for /F %%V in ('type "$(TOP)\VERSION"') do ( \ @@ -1444,8 +1477,10 @@ $(LIBRESOBJS): $(TOP)\src\sqlite3.rc $(SQLITE3H) ) echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc +# <> !ENDIF +# <> # Rules to build individual *.lo files from files in the src directory. # alter.lo: $(TOP)\src\alter.c $(HDR) @@ -1945,10 +1980,12 @@ speedtest1.exe: $(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H) rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +# <> clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL +# <> del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL del /Q lemon.* lempar.c parse.* 2>NUL del /Q mkkeywordhash.* keywordhash.h 2>NUL @@ -1974,3 +2011,4 @@ clean: del /Q sqlite-*-output.vsix 2>NUL del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL +# <> diff --git a/manifest b/manifest index 61cf5d66ed..12db615b93 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,9 @@ -C More\swork\son\sthe\sMSVC\sbuild. -D 2016-01-23T00:07:51.151 +C Add\stooling\sto\screate\san\sMSVC\sMakefile\scapable\sof\sbuilding\sthe\score\slibrary\sand\sshell\sonly,\susing\sa\spre-built\samalgamation. +D 2016-01-23T07:53:04.796 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 +F Makefile.min.msc c805e4a474fc7610d4f0cd0b6a9f56334a14c6ad +F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1378,6 +1379,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 +F tool/mkmsvcmin.tcl 859737ff14668827738a3f7ca17ba643a88bcecc F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1419,7 +1421,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 a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 -R b34246fa017fc0ae2e7bf7cb484e3eeb +P a79c46bc61a35edbaf6112c26e8052314b0eb16a +R bd00cfb25453f633191b5f1755909575 +T *branch * msvcMakeMin +T *sym-msvcMakeMin * +T -sym-trunk * U mistachkin -Z ba075ff448ff99fa520b3503324fe6e9 +Z 18f99743dd26f3a3f31830457ad1b4ef diff --git a/manifest.uuid b/manifest.uuid index d1ea2b33a4..06bbe8845c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a79c46bc61a35edbaf6112c26e8052314b0eb16a \ No newline at end of file +c46f1a13cb00264d1164399059250884c7be4ea0 \ No newline at end of file diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl new file mode 100644 index 0000000000..56c9d52811 --- /dev/null +++ b/tool/mkmsvcmin.tcl @@ -0,0 +1,88 @@ +#!/usr/bin/tcl +# +# Removes and/or replaces specially marked sections from the Makefile +# for MSVC, writing the resulting output to another (different) file. +# In addition, some other strings are also removed and/or replaced if +# they are present in the Makefile. +# +set fromFileName [lindex $argv 0] + +if {![file exists $fromFileName]} then { + error "input file \"$fromFileName\" does not exist" +} + +set toFileName [lindex $argv 1] + +if {[file exists $toFileName]} then { + error "output file \"$toFileName\" already exists" +} + +proc readFile { fileName } { + set file_id [open $fileName RDONLY] + fconfigure $file_id -encoding binary -translation binary + set result [read $file_id] + close $file_id + return $result +} + +proc writeFile { fileName data } { + set file_id [open $fileName {WRONLY CREAT TRUNC}] + fconfigure $file_id -encoding binary -translation binary + puts -nonewline $file_id $data + close $file_id + return "" +} + +proc escapeSubSpec { data } { + regsub -all -- {&} $data {\\\&} data + regsub -all -- {\\(\d+)} $data {\\\\\1} data + return $data +} + +proc substVars { data } { + return [uplevel 1 [list subst -nocommands -nobackslashes $data]] +} + +# +# NOTE: This block is used to replace the section marked <> in +# the Makefile, if it exists. +# +set blocks(1) [string trimleft [string map [list \\\\ \\] { +_HASHCHAR=^# +!IF ![echo !IFNDEF VERSION > rcver.vc] && \\ + ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\ + ![echo !ENDIF >> rcver.vc] +!INCLUDE rcver.vc +!ENDIF + +RESOURCE_VERSION = $(VERSION:^#=) +RESOURCE_VERSION = $(RESOURCE_VERSION:define=) +RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=) +RESOURCE_VERSION = $(RESOURCE_VERSION:"=) +RESOURCE_VERSION = $(RESOURCE_VERSION:.=,) + +$(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H) + echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h + echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h + echo #endif >> sqlite3rc.h + $(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc +}]] + +set data [readFile $fromFileName] + +regsub -all -- {# <>\n.*?# <>\n} \ + $data "" data + +foreach i [lsort [array names blocks]] { + regsub -all -- [substVars \ + {# <>\n.*?# <>\n}] \ + $data [escapeSubSpec $blocks($i)] data +} + +set data [string map [list " -I\$(TOP)\\src" ""] $data] +set data [string map [list " /DEF:sqlite3.def" ""] $data] +set data [string map [list " sqlite3.def" ""] $data] +set data [string map [list " libtclsqlite3.lib" ""] $data] +set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data] + +writeFile $toFileName $data From c615097d3d9140f9ea2d23faf2dd4ed58475a6ad Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 14:05:27 +0000 Subject: [PATCH 010/107] Remove an assert() that can be false if compiled with SQLITE_USE_ALLOCA. FossilOrigin-Name: f0a551edf87ef061deae34d88b02c3b484ae9adc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/prepare.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 61cf5d66ed..7b54ea0ab0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\swork\son\sthe\sMSVC\sbuild. -D 2016-01-23T00:07:51.151 +C Remove\san\sassert()\sthat\scan\sbe\sfalse\sif\scompiled\swith\sSQLITE_USE_ALLOCA. +D 2016-01-23T14:05:27.109 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -340,7 +340,7 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 74855ddbdfad6a1c4a4d5c4b0913ebb01174ba19 +F src/prepare.c 8ca7237428f372a04717d558555ea67ee1c5df93 F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c @@ -1419,7 +1419,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 a1c8116ced62d81f3f5ca26bbe0877e829d4cc56 -R b34246fa017fc0ae2e7bf7cb484e3eeb -U mistachkin -Z ba075ff448ff99fa520b3503324fe6e9 +P a79c46bc61a35edbaf6112c26e8052314b0eb16a +R 78c84a447f1adb3672b2aa032cc33ea6 +U drh +Z 2d3baf83036e6553ecd28fa4c13c4bc2 diff --git a/manifest.uuid b/manifest.uuid index d1ea2b33a4..d11f7b73ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a79c46bc61a35edbaf6112c26e8052314b0eb16a \ No newline at end of file +f0a551edf87ef061deae34d88b02c3b484ae9adc \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index acc70dd2d5..acd50fcaf7 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -525,7 +525,7 @@ static int sqlite3Prepare( } pParse->pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); - assert( !db->mallocFailed ); + /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ assert( sqlite3_mutex_held(db->mutex) ); /* Check to verify that it is possible to get a read lock on all From 8498f387be1e02e4053c4bf5dcf4ded8a7103484 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Jan 2016 14:45:36 +0000 Subject: [PATCH 011/107] Fix a problem involving detail=col and column filters. FossilOrigin-Name: 7558a0ad2276e91f2faced8ea405d9fdb4fa0c6e --- ext/fts5/fts5_index.c | 14 ++++++++++---- manifest | 15 ++++++--------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2ea57b04f9..8323842dc6 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5013,21 +5013,26 @@ static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); assert( pColset ); - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf && 0 ){ + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ Fts5PoslistWriter writer = {0}; const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; int n = pSeg->nPos; int iCol = 0; + int iCVal = pColset->aiCol[0]; i64 iPos = 0; int iOff = 0; fts5BufferZero(&pIter->poslist); while( 0==sqlite3Fts5PoslistNext64(a, n, &iOff, &iPos) ){ - if( iPos==pColset->aiCol[iCol] ){ - sqlite3Fts5PoslistWriterAppend(&pIter->poslist, &writer, iPos); - if( ++iCol>=pColset->nCol ) break; + while( iPos>=iCVal ){ + if( iPos==iCVal ){ + sqlite3Fts5PoslistWriterAppend(&pIter->poslist, &writer, iPos); + } + if( ++iCol>=pColset->nCol ) goto setoutputs_col_out; + assert( pColset->aiCol[iCol]>iCVal ); + iCVal = pColset->aiCol[iCol]; } } @@ -5039,6 +5044,7 @@ static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); } +setoutputs_col_out: pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } diff --git a/manifest b/manifest index 99a9a8b139..0168850d28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\sperformance\senhancements\sfor\sfts5. -D 2016-01-22T19:48:34.825 +C Fix\sa\sproblem\sinvolving\sdetail=col\sand\scolumn\sfilters. +D 2016-01-23T14:45:36.706 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc d2b93511a969c0c8fcf52aeb5e426571e8c610d2 @@ -103,7 +103,7 @@ F ext/fts5/fts5_buffer.c 7d3f6f01f8fdc45204e6a33925ef8478a67d28dd F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c 48b9131b74c8d3b8c12ba0f7995e2d60eecce9f2 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 19062d1f40ba6d88d786a986d1c20f9d741799d0 +F ext/fts5/fts5_index.c bd5476edd4d6ef37fc389794a78f47f29f521634 F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3 F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1419,10 +1419,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 7323175337b7ba85ac932ca892b28860f6a5b688 -R bc65520844365f59e43048a22901b688 -T *branch * fts5-perf -T *sym-fts5-perf * -T -sym-trunk * +P b5a57b812fd6a734cf2a342bf0b730ae18912d73 +R 20bdd3799e5ba562672d44f9df7f8c2a U dan -Z 20f25a74d681d80924173ee060583d9e +Z fc938fd5a5718db0c9c10bacac344b80 diff --git a/manifest.uuid b/manifest.uuid index fc3a1227d6..7a9fdf27eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5a57b812fd6a734cf2a342bf0b730ae18912d73 \ No newline at end of file +7558a0ad2276e91f2faced8ea405d9fdb4fa0c6e \ No newline at end of file From c66d03f1e13e8f1746e063d642480cd951d4ca44 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 23 Jan 2016 15:57:06 +0000 Subject: [PATCH 012/107] Fix some signed/unsigned comparison compiler warnings in fts5. FossilOrigin-Name: 3be336aa893f9eb0837d7d66c83bab1489792b9a --- ext/fts5/fts5Int.h | 6 +++--- ext/fts5/fts5_buffer.c | 2 +- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index b2f0d6c34e..5d7facc948 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -225,8 +225,8 @@ int sqlite3Fts5ConfigParseRank(const char*, char**, char**); typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; - u32 n; - u32 nSpace; + int n; + int nSpace; }; int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); @@ -247,7 +247,7 @@ char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); #define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferGrow(pRc,pBuf,nn) ( \ - (pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \ + (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \ sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \ ) diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 94591188d3..9bd4fddb82 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -363,7 +363,7 @@ int sqlite3Fts5TermsetAdd( void sqlite3Fts5TermsetFree(Fts5Termset *p){ if( p ){ - int i; + u32 i; for(i=0; iapHash); i++){ Fts5TermsetEntry *pEntry = p->apHash[i]; while( pEntry ){ diff --git a/manifest b/manifest index 7b54ea0ab0..9f8ab447a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sassert()\sthat\scan\sbe\sfalse\sif\scompiled\swith\sSQLITE_USE_ALLOCA. -D 2016-01-23T14:05:27.109 +C Fix\ssome\ssigned/unsigned\scomparison\scompiler\swarnings\sin\sfts5. +D 2016-01-23T15:57:06.186 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -97,9 +97,9 @@ 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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 5599703af9c13512900a9f22fec39d48078d619d +F ext/fts5/fts5Int.h e4c7ca41a7841f180d78a24850757e0ffcb20f27 F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e -F ext/fts5/fts5_buffer.c 7d3f6f01f8fdc45204e6a33925ef8478a67d28dd +F ext/fts5/fts5_buffer.c 0b8e1f84fec3ec01f7e17f8d4f17c46856b31e10 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c 4ab4504c54bbe24689c83411d8588f4ec99136e9 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 @@ -1419,7 +1419,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 a79c46bc61a35edbaf6112c26e8052314b0eb16a -R 78c84a447f1adb3672b2aa032cc33ea6 -U drh -Z 2d3baf83036e6553ecd28fa4c13c4bc2 +P f0a551edf87ef061deae34d88b02c3b484ae9adc +R 962289f1674397e1ac71fafb409f527f +U dan +Z 5f630552e065d9e5a5f7f6919a0222d3 diff --git a/manifest.uuid b/manifest.uuid index d11f7b73ef..e3c087f5fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f0a551edf87ef061deae34d88b02c3b484ae9adc \ No newline at end of file +3be336aa893f9eb0837d7d66c83bab1489792b9a \ No newline at end of file From c6aab321441e0ce3eefa2a2ace0864cbca116231 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 18:24:52 +0000 Subject: [PATCH 013/107] Changes to spellfix to try to get it to use stack space instead of heap space in cases where that makes sense. FossilOrigin-Name: dfcebc7393a3a780ee9c4f257723c303bb633064 --- ext/misc/spellfix.c | 17 +++++++++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index c0da6b339b..d17a05a3cd 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -365,8 +365,8 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ int *m; /* The cost matrix */ char *cx; /* Corresponding character values */ int *toFree = 0; /* Malloced space */ - int mStack[60+15]; /* Stack space to use if not too much is needed */ int nMatch = 0; + int mStack[60+15]; /* Stack space to use if not too much is needed */ /* Early out if either input is NULL */ if( zA==0 || zB==0 ) return -1; @@ -899,15 +899,24 @@ static int editDist3Core( EditDist3FromString f = *pFrom; EditDist3To *a2; unsigned int *m; + unsigned int *pToFree; int szRow; EditDist3Cost *p; int res; + sqlite3_uint64 nByte; + unsigned int stackSpace[16*1024]; /* allocate the Wagner matrix and the aTo[] array for the TO string */ n = (f.n+1)*(n2+1); n = (n+1)&~1; - m = sqlite3_malloc( n*sizeof(m[0]) + sizeof(a2[0])*n2 ); - if( m==0 ) return -1; /* Out of memory */ + nByte = n*sizeof(m[0]) + sizeof(a2[0])*n2; + if( nByte<=sizeof(stackSpace) ){ + m = stackSpace; + pToFree = 0; + }else{ + m = pToFree = sqlite3_malloc( nByte ); + if( m==0 ) return -1; /* Out of memory */ + } a2 = (EditDist3To*)&m[n]; memset(a2, 0, sizeof(a2[0])*n2); @@ -1029,7 +1038,7 @@ static int editDist3Core( editDist3Abort: for(i2=0; i2 Date: Sat, 23 Jan 2016 18:51:59 +0000 Subject: [PATCH 014/107] Fix an fts5 problem with using both xPhraseFirst() and xPhraseFirstColumn() within a single statement in detail=col mode. FossilOrigin-Name: 72d53699bf0dcdb9d2a22e229989d7435f061399 --- ext/fts5/fts5Int.h | 6 +-- ext/fts5/fts5_aux.c | 2 +- ext/fts5/fts5_buffer.c | 4 +- ext/fts5/fts5_expr.c | 79 +++++++++++---------------------- ext/fts5/fts5_index.c | 79 --------------------------------- ext/fts5/fts5_main.c | 4 +- ext/fts5/fts5_storage.c | 2 +- ext/fts5/fts5_tokenize.c | 2 +- ext/fts5/fts5_vocab.c | 3 +- ext/fts5/test/fts5_common.tcl | 3 +- ext/fts5/test/fts5synonym2.test | 37 ++++++++++++++- manifest | 32 ++++++------- manifest.uuid | 2 +- 13 files changed, 90 insertions(+), 165 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index b8486dfdfb..48ab980921 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -29,7 +29,7 @@ typedef unsigned short u16; typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; -#define ArraySize(x) (sizeof(x) / sizeof(x[0])) +#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) #define testcase(x) #define ALWAYS(x) 1 @@ -388,8 +388,6 @@ int sqlite3Fts5IterEof(Fts5IndexIter*); int sqlite3Fts5IterNext(Fts5IndexIter*); int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); i64 sqlite3Fts5IterRowid(Fts5IndexIter*); -int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*); -int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf); /* ** Close an iterator opened by sqlite3Fts5IndexQuery(). @@ -402,8 +400,6 @@ void sqlite3Fts5IterClose(Fts5IndexIter*); const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*); int sqlite3Fts5IterNextScan(Fts5IndexIter*); -int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*); - /* ** Insert or remove data to or from the index. Each time a document is diff --git a/ext/fts5/fts5_aux.c b/ext/fts5/fts5_aux.c index 011064d405..79bed1c8f7 100644 --- a/ext/fts5/fts5_aux.c +++ b/ext/fts5/fts5_aux.c @@ -544,7 +544,7 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){ int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ - for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){ + for(i=0; rc==SQLITE_OK && ixCreateFunction(pApi, aBuiltin[i].zFunc, aBuiltin[i].pUserData, diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 9bd4fddb82..d69adf7d24 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -322,7 +322,7 @@ int sqlite3Fts5TermsetAdd( *pbPresent = 0; if( p ){ int i; - int hash = 13; + u32 hash = 13; Fts5TermsetEntry *pEntry; /* Calculate a hash value for this term. This is the same hash checksum @@ -339,7 +339,7 @@ int sqlite3Fts5TermsetAdd( if( pEntry->iIdx==iIdx && pEntry->nTerm==nTerm && memcmp(pEntry->pTerm, pTerm, nTerm)==0 - ){ + ){ *pbPresent = 1; break; } diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 290baf4e2c..3a1497f05d 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -306,7 +306,7 @@ static int fts5ExprSynonymList( int bCollist, Fts5Colset *pColset, i64 iRowid, - int *pbDel, /* OUT: Caller should sqlite3_free(*pa) */ + Fts5Buffer *pBuf, /* Use this buffer for space if required */ u8 **pa, int *pn ){ Fts5PoslistReader aStatic[4]; @@ -320,22 +320,7 @@ static int fts5ExprSynonymList( for(p=pTerm; p; p=p->pSynonym){ Fts5IndexIter *pIter = p->pIter; if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){ - const u8 *a; - int n; - - if( 0 && bCollist ){ - rc = sqlite3Fts5IterCollist(pIter, &a, &n); - }else{ - i64 dummy; -#if 0 - rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy); -#endif - a = pIter->pData; - n = pIter->nData; - } - - if( rc!=SQLITE_OK ) goto synonym_poslist_out; - if( n==0 ) continue; + if( pIter->nData==0 ) continue; if( nIter==nAlloc ){ int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte); @@ -348,20 +333,19 @@ static int fts5ExprSynonymList( if( aIter!=aStatic ) sqlite3_free(aIter); aIter = aNew; } - sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]); + sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]); assert( aIter[nIter].bEof==0 ); nIter++; } } - assert( *pbDel==0 ); if( nIter==1 ){ *pa = (u8*)aIter[0].a; *pn = aIter[0].n; }else{ Fts5PoslistWriter writer = {0}; - Fts5Buffer buf = {0,0,0}; i64 iPrev = -1; + fts5BufferZero(pBuf); while( 1 ){ int i; i64 iMin = FTS5_LARGEST_INT64; @@ -376,15 +360,12 @@ static int fts5ExprSynonymList( } } if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break; - rc = sqlite3Fts5PoslistWriterAppend(&buf, &writer, iMin); + rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin); iPrev = iMin; } - if( rc ){ - sqlite3_free(buf.p); - }else{ - *pa = buf.p; - *pn = buf.n; - *pbDel = 1; + if( rc==SQLITE_OK ){ + *pa = pBuf->p; + *pn = pBuf->n; } } @@ -421,7 +402,7 @@ static int fts5ExprPhraseIsMatch( /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ - if( pPhrase->nTerm>(int)ArraySize(aStatic) ){ + if( pPhrase->nTerm>ArraySize(aStatic) ){ int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte); if( !aIter ) return SQLITE_NOMEM; @@ -431,23 +412,23 @@ static int fts5ExprPhraseIsMatch( /* Initialize a term iterator for each term in the phrase */ for(i=0; inTerm; i++){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; - i64 dummy; int n = 0; int bFlag = 0; - const u8 *a = 0; + u8 *a = 0; if( pTerm->pSynonym ){ + Fts5Buffer buf = {0, 0, 0}; rc = fts5ExprSynonymList( - pTerm, 0, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n + pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n ); + if( rc ){ + sqlite3_free(a); + goto ismatch_out; + } + if( a==buf.p ) bFlag = 1; }else{ - Fts5IndexIter *pIter = pTerm->pIter; -#if 0 - rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy); -#endif - a = pIter->pData; - n = pIter->nData; + a = (u8*)pTerm->pIter->pData; + n = pTerm->pIter->nData; } - if( rc!=SQLITE_OK ) goto ismatch_out; sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); aIter[i].bFlag = (u8)bFlag; if( aIter[i].bEof ) goto ismatch_out; @@ -562,7 +543,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ /* If the aStatic[] array is not large enough, allocate a large array ** using sqlite3_malloc(). This approach could be improved upon. */ - if( pNear->nPhrase>(int)ArraySize(aStatic) ){ + if( pNear->nPhrase>ArraySize(aStatic) ){ int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte); }else{ @@ -1387,10 +1368,10 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; sqlite3_free(pTerm->zTerm); sqlite3Fts5IterClose(pTerm->pIter); - for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; sqlite3Fts5IterClose(pSyn->pIter); + fts5BufferFree((Fts5Buffer*)&pSyn[1]); sqlite3_free(pSyn); } } @@ -1478,13 +1459,13 @@ static int fts5ParseTokenize( assert( pPhrase==0 || pPhrase->nTerm>0 ); if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; - int nByte = sizeof(Fts5ExprTerm) + nToken+1; + int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; }else{ memset(pSyn, 0, nByte); - pSyn->zTerm = (char*)&pSyn[1]; + pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); memcpy(pSyn->zTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; @@ -2263,7 +2244,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ int rc = SQLITE_OK; void *pCtx = (void*)pGlobal; - for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){ + for(i=0; rc==SQLITE_OK && iz, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } @@ -2509,18 +2490,10 @@ int sqlite3Fts5ExprPhraseCollist( ){ Fts5ExprTerm *pTerm = &pPhrase->aTerm[0]; if( pTerm->pSynonym ){ - int bDel = 0; - u8 *a; + Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1]; rc = fts5ExprSynonymList( - pTerm, 1, 0, pNode->iRowid, &bDel, &a, pnCollist + pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist ); - if( bDel ){ - sqlite3Fts5BufferSet(&rc, &pPhrase->poslist, *pnCollist, a); - *ppCollist = pPhrase->poslist.p; - sqlite3_free(a); - }else{ - *ppCollist = a; - } }else{ *ppCollist = pPhrase->aTerm[0].pIter->pData; *pnCollist = pPhrase->aTerm[0].pIter->nData; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 8323842dc6..e147199ef8 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5249,85 +5249,6 @@ const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return &z[1]; } - -/* -** Return a pointer to a buffer containing a copy of the position list for -** the current entry. Output variable *pn is set to the size of the buffer -** in bytes before returning. -** -** The returned position list does not include the "number of bytes" varint -** field that starts the position list on disk. -*/ -int sqlite3Fts5IterPoslist( - Fts5IndexIter *pIndexIter, - Fts5Colset *pColset, /* Column filter (or NULL) */ - const u8 **pp, /* OUT: Pointer to position-list data */ - int *pn, /* OUT: Size of position-list in bytes */ - i64 *piRowid /* OUT: Current rowid */ -){ - Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; - int eDetail = pIter->pIndex->pConfig->eDetail; - - assert( pIter->pIndex->rc==SQLITE_OK ); - *piRowid = pSeg->iRowid; - if( eDetail==FTS5_DETAIL_NONE ){ - *pn = pSeg->nPos; - }else - if( eDetail==FTS5_DETAIL_FULL - && pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf - ){ - u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - if( pColset==0 || pIter->bFiltered ){ - *pn = pSeg->nPos; - *pp = pPos; - }else if( pColset->nCol==1 ){ - *pp = pPos; - *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]); - }else{ - fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist); - *pp = pIter->poslist.p; - *pn = pIter->poslist.n; - } - }else{ - fts5BufferZero(&pIter->poslist); - fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); - if( eDetail==FTS5_DETAIL_FULL ){ - *pp = pIter->poslist.p; - } - *pn = pIter->poslist.n; - } - return fts5IndexReturn(pIter->pIndex); -} - -int sqlite3Fts5IterCollist( - Fts5IndexIter *pIndexIter, - const u8 **pp, /* OUT: Pointer to position-list data */ - int *pn /* OUT: Size of position-list in bytes */ -){ - Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - *pp = pIter->poslist.p; - *pn = pIter->poslist.n; - return SQLITE_OK; -} - -/* -** This function is similar to sqlite3Fts5IterPoslist(), except that it -** copies the position list into the buffer supplied as the second -** argument. -*/ -int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIndexIter, Fts5Buffer *pBuf){ - Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - Fts5Index *p = pIter->pIndex; - Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; - assert( p->rc==SQLITE_OK ); - fts5BufferZero(pBuf); - fts5SegiterPoslist(p, pSeg, 0, pBuf); - return fts5IndexReturn(p); -} - /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 7447f9b5e1..ec045da6bf 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -538,7 +538,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int j; - for(j=0; j<(int)ArraySize(aConstraint); j++){ + for(j=0; jiColumn==aColMap[pC->iCol] && p->op & pC->op ){ if( p->usable ){ @@ -585,7 +585,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* Assign argvIndex values to each constraint in use. */ iNext = 1; - for(i=0; i<(int)ArraySize(aConstraint); i++){ + for(i=0; iiConsIndex>=0 ){ pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++; diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index 56383619d1..da9524dea3 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -338,7 +338,7 @@ int sqlite3Fts5StorageClose(Fts5Storage *p){ int i; /* Finalize all SQL statements */ - for(i=0; i<(int)ArraySize(p->aStmt); i++){ + for(i=0; iaStmt); i++){ sqlite3_finalize(p->aStmt[i]); } diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c index e60183c095..790adaae47 100644 --- a/ext/fts5/fts5_tokenize.c +++ b/ext/fts5/fts5_tokenize.c @@ -1220,7 +1220,7 @@ int sqlite3Fts5TokenizerInit(fts5_api *pApi){ int rc = SQLITE_OK; /* Return code */ int i; /* To iterate through builtin functions */ - for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){ + for(i=0; rc==SQLITE_OK && ixCreateTokenizer(pApi, aBuiltin[i].zName, (void*)pApi, diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 17aa5816c4..b17e8974fb 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -184,7 +184,7 @@ static int fts5VocabInitVtab( rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ - assert( eType>=0 && eType=0 && eTypeeType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); while( rc==SQLITE_OK ){ - i64 dummy; const u8 *pPos; int nPos; /* Position list */ i64 iPos = 0; /* 64-bit position read from poslist */ int iOff = 0; /* Current offset within position list */ diff --git a/ext/fts5/test/fts5_common.tcl b/ext/fts5/test/fts5_common.tcl index e7c61af00c..cf688dcc0d 100644 --- a/ext/fts5/test/fts5_common.tcl +++ b/ext/fts5/test/fts5_common.tcl @@ -48,7 +48,8 @@ proc fts5_test_poslist2 {cmd} { } } - set res + #set res + sort_poslist $res } proc fts5_test_collist {cmd} { diff --git a/ext/fts5/test/fts5synonym2.test b/ext/fts5/test/fts5synonym2.test index dddaa17af8..7e92822c33 100644 --- a/ext/fts5/test/fts5synonym2.test +++ b/ext/fts5/test/fts5synonym2.test @@ -27,6 +27,21 @@ foreach_detail_mode $testprefix { fts5_tclnum_register db fts5_aux_test_functions db +proc fts5_test_bothlist {cmd} { + + for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} { + set bFirst 1 + $cmd xPhraseColumnForeach $i c { + lappend CL $i.$c + if {$bFirst} { $cmd xPhraseForeach $i c o { lappend PL $i.$c.$o } } + set bFirst 0 + } + } + + list [sort_poslist $PL] $CL +} +sqlite3_fts5_create_function db fts5_test_bothlist fts5_test_bothlist + proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] } sqlite3_fts5_create_function db fts5_rowid fts5_rowid @@ -89,6 +104,8 @@ do_execsql_test 1.$tok.0.2 { } foreach {tn expr} { + 2.1 "one OR two OR three OR four" + 1.1 "one" 1.2 "two" 1.3 "three" 1.4 "four" 1.5 "v" 1.6 "vi" 1.7 "vii" 1.8 "viii" 1.9 "9" 1.10 "0" 1.11 "1" 1.12 "2" @@ -113,13 +130,31 @@ foreach {tn expr} { set res [fts5_query_data $expr ss ASC ::tclnum_syn] do_execsql_test 1.$tok.$tn.[llength $res].asc.1 { - SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr) + SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr) } $res do_execsql_test 1.$tok.$tn.[llength $res].asc.2 { SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr) + } $res + + do_execsql_test 1.$tok.$tn.[llength $res].asc.2 { + SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr) ORDER BY rank ASC } $res + + set res2 [list] + foreach {a b c} $res { lappend res2 $a $c $b } + do_execsql_test 1.$tok.$tn.[llength $res].asc.3 { + SELECT rowid, fts5_test_collist(ss), fts5_test_poslist2(ss) FROM ss($expr) + } $res2 + + set res3 [list] + foreach {a b c} $res { lappend res3 $a [list $b $c] } + do_execsql_test 1.$tok.$tn.[llength $res].asc.3 { + SELECT rowid, fts5_test_bothlist(ss) FROM ss($expr) + } $res3 + + } } diff --git a/manifest b/manifest index e3a6b78f3f..fbcb4d2d1b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\s(including\sfixes\sfor\swarnings\sin\sfts5)\swith\sthis\sbranch. -D 2016-01-23T16:20:16.389 +C Fix\san\sfts5\sproblem\swith\susing\sboth\sxPhraseFirst()\sand\sxPhraseFirstColumn()\swithin\sa\ssingle\sstatement\sin\sdetail=col\smode. +D 2016-01-23T18:51:59.865 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -97,25 +97,25 @@ 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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h a810589cf2fedd7dcfc9ba7871d2a5a09e850ace -F ext/fts5/fts5_aux.c 2dafc3aee0c70d643140c77d8d70daffa51a9e9e -F ext/fts5/fts5_buffer.c 0b8e1f84fec3ec01f7e17f8d4f17c46856b31e10 +F ext/fts5/fts5Int.h 6e0f90eb4872654a5b98130dec16965716525c9a +F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d +F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 -F ext/fts5/fts5_expr.c 48b9131b74c8d3b8c12ba0f7995e2d60eecce9f2 +F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c bd5476edd4d6ef37fc389794a78f47f29f521634 -F ext/fts5/fts5_main.c 833db0a3df10ab26e0221a9baa40cf871c450df3 -F ext/fts5/fts5_storage.c fb2eaec3aa954b680d43096dc539f8270bd6390e +F ext/fts5/fts5_index.c 722d8717e3167dd05fa48af970352932052da318 +F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e +F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be -F ext/fts5/fts5_tokenize.c 504984ac6993323247221eebe3cd55bead01b5f8 +F ext/fts5/fts5_tokenize.c 4d5c4f183c7d07d144bc219b92da1ea0e962fae3 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 -F ext/fts5/fts5_vocab.c f1b4308b9b7ec8e659d0c9b39ddc8f1aeee47a1a +F ext/fts5/fts5_vocab.c 3ef401a8d6932db56368de32f446eb9fe73aa623 F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba -F ext/fts5/test/fts5_common.tcl 6d0d74b695c4be055a8ba1dd807f22a2abc95b5e +F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9 F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test dec95549e007dd9be52aa435cdcd0f08e14e64d0 @@ -177,7 +177,7 @@ F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 -F ext/fts5/test/fts5synonym2.test eadb00c73ef0653258873e756b7e9102e0687539 +F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ea4df698b35cc427ebf2ba22829d0e28386d8c89 @@ -1419,7 +1419,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 7558a0ad2276e91f2faced8ea405d9fdb4fa0c6e 3be336aa893f9eb0837d7d66c83bab1489792b9a -R 27b07c29574081bf2a6f1649bb5e2393 +P ceccc9ad788fb4da9120915741995b9f088f85ff +R e7d7753020b6f70b109a92a8ac037ba7 U dan -Z 165b70c16fc218fdaf7b93acd8863bd2 +Z 648645363fb131dd10e5d7321a173b9d diff --git a/manifest.uuid b/manifest.uuid index 3e212691ce..1891619c18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ceccc9ad788fb4da9120915741995b9f088f85ff \ No newline at end of file +72d53699bf0dcdb9d2a22e229989d7435f061399 \ No newline at end of file From 408273e722fbff04e6f02960060529cd85ba772e Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 19:24:19 +0000 Subject: [PATCH 015/107] Use the -integer option when sorting list elements. FossilOrigin-Name: 949aa614e1401f6ab61cbb2e0469c60d764e6880 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- tool/mkmsvcmin.tcl | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 12db615b93..d24047ded1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stooling\sto\screate\san\sMSVC\sMakefile\scapable\sof\sbuilding\sthe\score\slibrary\sand\sshell\sonly,\susing\sa\spre-built\samalgamation. -D 2016-01-23T07:53:04.796 +C Use\sthe\s-integer\soption\swhen\ssorting\slist\selements. +D 2016-01-23T19:24:19.182 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.min.msc c805e4a474fc7610d4f0cd0b6a9f56334a14c6ad @@ -1379,7 +1379,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 -F tool/mkmsvcmin.tcl 859737ff14668827738a3f7ca17ba643a88bcecc +F tool/mkmsvcmin.tcl a0217f49042ec8160ff8665db638e9b5edc17964 F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1421,10 +1421,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 a79c46bc61a35edbaf6112c26e8052314b0eb16a -R bd00cfb25453f633191b5f1755909575 -T *branch * msvcMakeMin -T *sym-msvcMakeMin * -T -sym-trunk * +P c46f1a13cb00264d1164399059250884c7be4ea0 +R ce47a7131ea57ef586dba1d328c21253 U mistachkin -Z 18f99743dd26f3a3f31830457ad1b4ef +Z c9f6cfce5ff80db91258ef2b40e34be6 diff --git a/manifest.uuid b/manifest.uuid index 06bbe8845c..0c60eb81fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c46f1a13cb00264d1164399059250884c7be4ea0 \ No newline at end of file +949aa614e1401f6ab61cbb2e0469c60d764e6880 \ No newline at end of file diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 56c9d52811..188b73a18e 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -73,7 +73,7 @@ set data [readFile $fromFileName] regsub -all -- {# <>\n.*?# <>\n} \ $data "" data -foreach i [lsort [array names blocks]] { +foreach i [lsort -integer [array names blocks]] { regsub -all -- [substVars \ {# <>\n.*?# <>\n}] \ $data [escapeSubSpec $blocks($i)] data From 06cee48728424701260e2f3215ad75c257bace44 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 19:47:00 +0000 Subject: [PATCH 016/107] Improved comments on the transformation script and on the generated Makefile. FossilOrigin-Name: c6e633ab73812fe38f3e969f1652f1b5759096e4 --- Makefile.min.msc | 6 ++++++ manifest | 16 +++++++-------- manifest.uuid | 2 +- tool/mkmsvcmin.tcl | 51 +++++++++++++++++++++++++++------------------- 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Makefile.min.msc b/Makefile.min.msc index 2ec986fa4b..e2187efad3 100644 --- a/Makefile.min.msc +++ b/Makefile.min.msc @@ -1,3 +1,9 @@ +#### DO NOT EDIT #### +# This makefile is automatically generated from the Makefile.msc at +# the root of the canonical SQLite source tree using the +# tool/mkmsvcmin.tcl script. +# + # # nmake Makefile for SQLite # diff --git a/manifest b/manifest index d24047ded1..504f2ebbaf 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Use\sthe\s-integer\soption\swhen\ssorting\slist\selements. -D 2016-01-23T19:24:19.182 +C Improved\scomments\son\sthe\stransformation\sscript\sand\son\sthe\sgenerated\sMakefile. +D 2016-01-23T19:47:00.459 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.min.msc c805e4a474fc7610d4f0cd0b6a9f56334a14c6ad +F Makefile.min.msc cbbc5e37bfe74583cce7c2585319620b7516e6ed F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 @@ -1379,7 +1379,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 -F tool/mkmsvcmin.tcl a0217f49042ec8160ff8665db638e9b5edc17964 +F tool/mkmsvcmin.tcl a62d398d1304b36dd41b69e655d875728fd9d509 F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1421,7 +1421,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 c46f1a13cb00264d1164399059250884c7be4ea0 -R ce47a7131ea57ef586dba1d328c21253 -U mistachkin -Z c9f6cfce5ff80db91258ef2b40e34be6 +P 949aa614e1401f6ab61cbb2e0469c60d764e6880 +R 52e20c37d886e0ca572199fede1eb984 +U drh +Z 5f79d302a18d7c201b23ed73e75ff6ef diff --git a/manifest.uuid b/manifest.uuid index 0c60eb81fc..876d304c70 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -949aa614e1401f6ab61cbb2e0469c60d764e6880 \ No newline at end of file +c6e633ab73812fe38f3e969f1652f1b5759096e4 \ No newline at end of file diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 188b73a18e..7414f53000 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -1,22 +1,26 @@ #!/usr/bin/tcl # -# Removes and/or replaces specially marked sections from the Makefile -# for MSVC, writing the resulting output to another (different) file. -# In addition, some other strings are also removed and/or replaced if -# they are present in the Makefile. -# -set fromFileName [lindex $argv 0] - -if {![file exists $fromFileName]} then { - error "input file \"$fromFileName\" does not exist" +# This script reads the regular MSVC makefile (../Makefile.msc) and outputs +# a revised version of that Makefile that is "minimal" in the sense that +# it uses the sqlite3.c amalgamation as input and does not require tclsh. +# The resulting "../Makefile.min.msc" is suitable for use in the amalgamation +# tarballs. +# +if {$argc==0} { + set basedir [file dir [file dir [file normalize $argv0]]] + set fromFileName [file join $basedir Makefile.msc] + set toFileName [file join $basedir Makefile.min.msc] +} else { + set fromFileName [lindex $argv 0] + if {![file exists $fromFileName]} then { + error "input file \"$fromFileName\" does not exist" + } + set toFileName [lindex $argv 1] + if {[file exists $toFileName]} then { + error "output file \"$toFileName\" already exists" + } } - -set toFileName [lindex $argv 1] -if {[file exists $toFileName]} then { - error "output file \"$toFileName\" already exists" -} - proc readFile { fileName } { set file_id [open $fileName RDONLY] fconfigure $file_id -encoding binary -translation binary @@ -24,7 +28,7 @@ proc readFile { fileName } { close $file_id return $result } - + proc writeFile { fileName data } { set file_id [open $fileName {WRONLY CREAT TRUNC}] fconfigure $file_id -encoding binary -translation binary @@ -32,17 +36,17 @@ proc writeFile { fileName data } { close $file_id return "" } - + proc escapeSubSpec { data } { regsub -all -- {&} $data {\\\&} data regsub -all -- {\\(\d+)} $data {\\\\\1} data return $data } - + proc substVars { data } { return [uplevel 1 [list subst -nocommands -nobackslashes $data]] } - + # # NOTE: This block is used to replace the section marked <> in # the Makefile, if it exists. @@ -67,8 +71,13 @@ $(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H) echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc }]] - -set data [readFile $fromFileName] + +set data "#### DO NOT EDIT ####\n" +append data "# This makefile is automatically " +append data "generated from the [file tail $fromFileName] at\n" +append data "# the root of the canonical SQLite source tree using the\n" +append data "# tool/[file tail $argv0] script.\n#\n\n" +append data [readFile $fromFileName] regsub -all -- {# <>\n.*?# <>\n} \ $data "" data From ac779bcbe964611322cc9ad4e056e8220784b84a Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 20:09:30 +0000 Subject: [PATCH 017/107] Adjust the amalgamation-tarball build process so that it includes the MSVC makefile and the sqlite3.rc resource file. FossilOrigin-Name: e420f3dc93a0e3364f0773950b7a125f5221a109 --- autoconf/Makefile.am | 2 +- autoconf/{README => README.txt} | 5 ++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mkautoconfamal.sh | 17 +++++++++-------- 5 files changed, 23 insertions(+), 19 deletions(-) rename autoconf/{README => README.txt} (88%) diff --git a/autoconf/Makefile.am b/autoconf/Makefile.am index eed3ba41cb..03424a606b 100644 --- a/autoconf/Makefile.am +++ b/autoconf/Makefile.am @@ -14,7 +14,7 @@ sqlite3_CFLAGS = $(AM_CFLAGS) include_HEADERS = sqlite3.h sqlite3ext.h -EXTRA_DIST = sqlite3.1 tea +EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt pkgconfigdir = ${libdir}/pkgconfig pkgconfig_DATA = sqlite3.pc diff --git a/autoconf/README b/autoconf/README.txt similarity index 88% rename from autoconf/README rename to autoconf/README.txt index dd8cca24bd..731158a883 100644 --- a/autoconf/README +++ b/autoconf/README.txt @@ -1,4 +1,3 @@ - This package contains: * the SQLite library amalgamation (single file) source code distribution, @@ -6,6 +5,7 @@ This package contains: * the sqlite3.h and sqlite3ext.h header files required to link programs and sqlite extensions against the installed libary. * autoconf/automake installation infrastucture. + * a Makefile.msc and sqlite3.rc for Microsoft Visual C++ The generic installation instructions for autoconf/automake are found in the INSTALL file. @@ -30,3 +30,6 @@ example: $ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure +To compile for Windows using Microsoft Visual C++: + + $ nmake /f Makefile.msc FOR_WIN10=1 diff --git a/manifest b/manifest index 504f2ebbaf..a6797b77e5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\stransformation\sscript\sand\son\sthe\sgenerated\sMakefile. -D 2016-01-23T19:47:00.459 +C Adjust\sthe\samalgamation-tarball\sbuild\sprocess\sso\sthat\sit\sincludes\sthe\nMSVC\smakefile\sand\sthe\ssqlite3.rc\sresource\sfile. +D 2016-01-23T20:09:30.205 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.min.msc cbbc5e37bfe74583cce7c2585319620b7516e6ed @@ -11,9 +11,9 @@ F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 -F autoconf/Makefile.am 089e5ecdb5761e64ea1013ded02feb4d8b29927d -F autoconf/README 14458f1046c118efa721aadec5f227e876d3cd38 +F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 +F autoconf/README.txt c9265657b6ca8c4de1e148e8c0c4c29d60ec860c w autoconf/README F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -1377,7 +1377,7 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 -F tool/mkautoconfamal.sh 5a5441280b509d2bb3bdc71bfb63781b0d570373 +F tool/mkautoconfamal.sh add1d703074e7edb2d8423441c7e245271c5c8cb F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 F tool/mkmsvcmin.tcl a62d398d1304b36dd41b69e655d875728fd9d509 F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b @@ -1421,7 +1421,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 949aa614e1401f6ab61cbb2e0469c60d764e6880 -R 52e20c37d886e0ca572199fede1eb984 +P c6e633ab73812fe38f3e969f1652f1b5759096e4 +R d5543de9eede26dd90664aa004eef406 U drh -Z 5f79d302a18d7c201b23ed73e75ff6ef +Z 98c1051b769380596fbf89ccef90cc39 diff --git a/manifest.uuid b/manifest.uuid index 876d304c70..c32f479829 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6e633ab73812fe38f3e969f1652f1b5759096e4 \ No newline at end of file +e420f3dc93a0e3364f0773950b7a125f5221a109 \ No newline at end of file diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index 9f44152e36..d368cd226b 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -34,14 +34,15 @@ set -e ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz` rm -rf $TMPSPACE -cp -R $TOP/autoconf $TMPSPACE - -cp sqlite3.c $TMPSPACE -cp sqlite3.h $TMPSPACE -cp sqlite3ext.h $TMPSPACE -cp $TOP/sqlite3.1 $TMPSPACE -cp $TOP/sqlite3.pc.in $TMPSPACE -cp $TOP/src/shell.c $TMPSPACE +cp -R $TOP/autoconf $TMPSPACE +cp sqlite3.c $TMPSPACE +cp sqlite3.h $TMPSPACE +cp sqlite3ext.h $TMPSPACE +cp $TOP/sqlite3.1 $TMPSPACE +cp $TOP/sqlite3.pc.in $TMPSPACE +cp $TOP/src/shell.c $TMPSPACE +cp $TOP/Makefile.min.msc $TMPSPACE/Makefile.msc +cp $TOP/src/sqlite3.rc $TMPSPACE cat $TMPSPACE/configure.ac | sed "s/--SQLITE-VERSION--/$VERSION/" > $TMPSPACE/tmp From 4a25549b087bd576ac413f88f5e2d654cd59e0b4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 20:16:40 +0000 Subject: [PATCH 018/107] Minor coding style tweaks for the mkmsvcmin tool. FossilOrigin-Name: c15e0fc4be08b92547bea1f1cac65581ef497409 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- tool/mkmsvcmin.tcl | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a6797b77e5..2076ff35e1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\samalgamation-tarball\sbuild\sprocess\sso\sthat\sit\sincludes\sthe\nMSVC\smakefile\sand\sthe\ssqlite3.rc\sresource\sfile. -D 2016-01-23T20:09:30.205 +C Minor\scoding\sstyle\stweaks\sfor\sthe\smkmsvcmin\stool. +D 2016-01-23T20:16:40.624 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.min.msc cbbc5e37bfe74583cce7c2585319620b7516e6ed @@ -13,7 +13,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt c9265657b6ca8c4de1e148e8c0c4c29d60ec860c w autoconf/README +F autoconf/README.txt c9265657b6ca8c4de1e148e8c0c4c29d60ec860c F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -1379,7 +1379,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh add1d703074e7edb2d8423441c7e245271c5c8cb F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 -F tool/mkmsvcmin.tcl a62d398d1304b36dd41b69e655d875728fd9d509 +F tool/mkmsvcmin.tcl c1f92b52505fe4a026e7b57fffe49b439b11b71b F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1421,7 +1421,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 c6e633ab73812fe38f3e969f1652f1b5759096e4 -R d5543de9eede26dd90664aa004eef406 -U drh -Z 98c1051b769380596fbf89ccef90cc39 +P e420f3dc93a0e3364f0773950b7a125f5221a109 +R 0e64448b1af0ccd7100284f6f222657e +U mistachkin +Z 38e3fbc9582e760d49d364916a96f186 diff --git a/manifest.uuid b/manifest.uuid index c32f479829..6bcba645b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e420f3dc93a0e3364f0773950b7a125f5221a109 \ No newline at end of file +c15e0fc4be08b92547bea1f1cac65581ef497409 \ No newline at end of file diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index 7414f53000..d0143ddd86 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -5,18 +5,18 @@ # it uses the sqlite3.c amalgamation as input and does not require tclsh. # The resulting "../Makefile.min.msc" is suitable for use in the amalgamation # tarballs. -# +# if {$argc==0} { set basedir [file dir [file dir [file normalize $argv0]]] set fromFileName [file join $basedir Makefile.msc] set toFileName [file join $basedir Makefile.min.msc] } else { set fromFileName [lindex $argv 0] - if {![file exists $fromFileName]} then { + if {![file exists $fromFileName]} { error "input file \"$fromFileName\" does not exist" } set toFileName [lindex $argv 1] - if {[file exists $toFileName]} then { + if {[file exists $toFileName]} { error "output file \"$toFileName\" already exists" } } From 021f9a6605c2c1af96db9fd144c64749c5224751 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 20:34:27 +0000 Subject: [PATCH 019/107] Move Makefile.min.msc into the autoconf subdir where it belongs and change its name to Makefile.msc. Adjust build scripts accordingly. FossilOrigin-Name: 12eb8db79697ef55228c78011d275f36f58271e1 --- Makefile.min.msc => autoconf/Makefile.msc | 5 +++-- manifest | 18 +++++++++--------- manifest.uuid | 2 +- tool/mkautoconfamal.sh | 1 - tool/mkmsvcmin.tcl | 7 ++++--- 5 files changed, 17 insertions(+), 16 deletions(-) rename Makefile.min.msc => autoconf/Makefile.msc (99%) diff --git a/Makefile.min.msc b/autoconf/Makefile.msc similarity index 99% rename from Makefile.min.msc rename to autoconf/Makefile.msc index e2187efad3..fce62b2b8a 100644 --- a/Makefile.min.msc +++ b/autoconf/Makefile.msc @@ -1,7 +1,8 @@ #### DO NOT EDIT #### # This makefile is automatically generated from the Makefile.msc at -# the root of the canonical SQLite source tree using the -# tool/mkmsvcmin.tcl script. +# the root of the canonical SQLite source tree (not the +# amalgamation tarball) using the tool/mkmsvcmin.tcl +# script. # # diff --git a/manifest b/manifest index 2076ff35e1..9a914fa3d3 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,7 @@ -C Minor\scoding\sstyle\stweaks\sfor\sthe\smkmsvcmin\stool. -D 2016-01-23T20:16:40.624 +C Move\sMakefile.min.msc\sinto\sthe\sautoconf\ssubdir\swhere\sit\sbelongs\sand\schange\nits\sname\sto\sMakefile.msc.\s\sAdjust\sbuild\sscripts\saccordingly. +D 2016-01-23T20:34:27.088 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.min.msc cbbc5e37bfe74583cce7c2585319620b7516e6ed F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 @@ -12,6 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 +F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 w Makefile.min.msc F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt c9265657b6ca8c4de1e148e8c0c4c29d60ec860c F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 @@ -1377,9 +1377,9 @@ F tool/lemon.c 799e73e19a33b8dd7767a7fa34618ed2a9c2397d F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 -F tool/mkautoconfamal.sh add1d703074e7edb2d8423441c7e245271c5c8cb +F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 -F tool/mkmsvcmin.tcl c1f92b52505fe4a026e7b57fffe49b439b11b71b +F tool/mkmsvcmin.tcl 93167a9e73383465b5716aa8dfa407409fccef1d F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1421,7 +1421,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 e420f3dc93a0e3364f0773950b7a125f5221a109 -R 0e64448b1af0ccd7100284f6f222657e -U mistachkin -Z 38e3fbc9582e760d49d364916a96f186 +P c15e0fc4be08b92547bea1f1cac65581ef497409 +R ffa1a98b2b7806021300568489ac1126 +U drh +Z ba6195ff75ad05f3ae39571f4a1714e5 diff --git a/manifest.uuid b/manifest.uuid index 6bcba645b0..e3e08e4e7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c15e0fc4be08b92547bea1f1cac65581ef497409 \ No newline at end of file +12eb8db79697ef55228c78011d275f36f58271e1 \ No newline at end of file diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index d368cd226b..6081a7b0ec 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -41,7 +41,6 @@ cp sqlite3ext.h $TMPSPACE cp $TOP/sqlite3.1 $TMPSPACE cp $TOP/sqlite3.pc.in $TMPSPACE cp $TOP/src/shell.c $TMPSPACE -cp $TOP/Makefile.min.msc $TMPSPACE/Makefile.msc cp $TOP/src/sqlite3.rc $TMPSPACE cat $TMPSPACE/configure.ac | diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index d0143ddd86..de01490c97 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -9,7 +9,7 @@ if {$argc==0} { set basedir [file dir [file dir [file normalize $argv0]]] set fromFileName [file join $basedir Makefile.msc] - set toFileName [file join $basedir Makefile.min.msc] + set toFileName [file join $basedir autoconf Makefile.msc] } else { set fromFileName [lindex $argv 0] if {![file exists $fromFileName]} { @@ -75,8 +75,9 @@ $(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H) set data "#### DO NOT EDIT ####\n" append data "# This makefile is automatically " append data "generated from the [file tail $fromFileName] at\n" -append data "# the root of the canonical SQLite source tree using the\n" -append data "# tool/[file tail $argv0] script.\n#\n\n" +append data "# the root of the canonical SQLite source tree (not the\n" +append data "# amalgamation tarball) using the tool/[file tail $argv0]\n" +append data "# script.\n#\n\n" append data [readFile $fromFileName] regsub -all -- {# <>\n.*?# <>\n} \ From 74f6e6ccf877fd3154eff2fabaa0c55e188bb019 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 20:43:48 +0000 Subject: [PATCH 020/107] Updates to the autoconf README file. FossilOrigin-Name: 4ce60fa42d8486d219d40d25d785d7f2cabe5e06 --- autoconf/README.txt | 11 +++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/autoconf/README.txt b/autoconf/README.txt index 731158a883..575e0a8dd8 100644 --- a/autoconf/README.txt +++ b/autoconf/README.txt @@ -4,8 +4,11 @@ This package contains: * the shell.c file used to build the sqlite3 shell too, and * the sqlite3.h and sqlite3ext.h header files required to link programs and sqlite extensions against the installed libary. - * autoconf/automake installation infrastucture. - * a Makefile.msc and sqlite3.rc for Microsoft Visual C++ + * autoconf/automake installation infrastucture for building on posix systems. + * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ + +BUILDING ON POSIX +================= The generic installation instructions for autoconf/automake are found in the INSTALL file. @@ -30,6 +33,10 @@ example: $ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure + +BUILDING WITH MICROSOFT VISUAL C++: +=================================== + To compile for Windows using Microsoft Visual C++: $ nmake /f Makefile.msc FOR_WIN10=1 diff --git a/manifest b/manifest index 9a914fa3d3..e41fae053e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sMakefile.min.msc\sinto\sthe\sautoconf\ssubdir\swhere\sit\sbelongs\sand\schange\nits\sname\sto\sMakefile.msc.\s\sAdjust\sbuild\sscripts\saccordingly. -D 2016-01-23T20:34:27.088 +C Updates\sto\sthe\sautoconf\sREADME\sfile. +D 2016-01-23T20:43:48.995 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -11,9 +11,9 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 -F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 w Makefile.min.msc +F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt c9265657b6ca8c4de1e148e8c0c4c29d60ec860c +F autoconf/README.txt ebf930270b2d6258f4d2c62c8c5a5dcc7cff5293 F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -1421,7 +1421,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 c15e0fc4be08b92547bea1f1cac65581ef497409 -R ffa1a98b2b7806021300568489ac1126 +P 12eb8db79697ef55228c78011d275f36f58271e1 +R f077ea8ac49bb767871086d72cc4aac2 U drh -Z ba6195ff75ad05f3ae39571f4a1714e5 +Z 47e598e0236f733ea03c00ba7b81ee9b diff --git a/manifest.uuid b/manifest.uuid index e3e08e4e7c..ea84af834d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12eb8db79697ef55228c78011d275f36f58271e1 \ No newline at end of file +4ce60fa42d8486d219d40d25d785d7f2cabe5e06 \ No newline at end of file From 76d4b1b835be68f6164042e34efb4c31e3dc11c3 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Jan 2016 21:57:46 +0000 Subject: [PATCH 021/107] More updates to the README. FossilOrigin-Name: 9f02868df71d902a2b9118d0b06df18ee92b666b --- autoconf/README.txt | 77 +++++++++++++++++++++++++++++++++++++++++---- manifest | 14 ++++----- manifest.uuid | 2 +- 3 files changed, 79 insertions(+), 14 deletions(-) diff --git a/autoconf/README.txt b/autoconf/README.txt index 575e0a8dd8..a581c39dea 100644 --- a/autoconf/README.txt +++ b/autoconf/README.txt @@ -4,8 +4,10 @@ This package contains: * the shell.c file used to build the sqlite3 shell too, and * the sqlite3.h and sqlite3ext.h header files required to link programs and sqlite extensions against the installed libary. - * autoconf/automake installation infrastucture for building on posix systems. - * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ + * autoconf/automake installation infrastucture for building on POSIX + compliant systems. + * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on + Windows. BUILDING ON POSIX ================= @@ -19,7 +21,7 @@ The following SQLite specific boolean options are supported: --enable-threadsafe build a thread-safe library [default=yes] --enable-dynamic-extensions support loadable extensions [default=yes] -The default value for the CFLAGS variable (options passed to the C +The default value for the CFLAGS variable (options passed to the C compiler) includes debugging symbols in the build, resulting in larger binaries than are necessary. Override it on the configure command line like this: @@ -34,9 +36,72 @@ example: $ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure -BUILDING WITH MICROSOFT VISUAL C++: -=================================== +BUILDING WITH MICROSOFT VISUAL C++ +================================== To compile for Windows using Microsoft Visual C++: - $ nmake /f Makefile.msc FOR_WIN10=1 + $ nmake /f Makefile.msc + +Using Microsoft Visual C++ 2005 (or later) is recommended. Several Windows +platform variants may be built by adding additional macros to the NMAKE +command line. + +BUILDING FOR WINRT 8.0 +---------------------- + + FOR_WINRT=1 + +Using Microsoft Visual C++ 2012 (or later) is required. When using the +above, something like the following macro will need to be added to the +NMAKE command line as well: + + "NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86" + +BUILDING FOR WINRT 8.1 +---------------------- + + FOR_WINRT=1 + +Using Microsoft Visual C++ 2013 (or later) is required. When using the +above, something like the following macro will need to be added to the +NMAKE command line as well: + + "NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86" + +BUILDING FOR UAP 10.0 +--------------------- + + FOR_WINRT=1 FOR_UAP=1 + +Using Microsoft Visual C++ 2015 (or later) is required. When using the +above, something like the following macros will need to be added to the +NMAKE command line as well: + + "NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86" + "PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86" + "NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86" + +BUILDING FOR THE WINDOWS 10 SDK +------------------------------- + + FOR_WIN10=1 + +Using Microsoft Visual C++ 2015 (or later) is required. When using the +above, no other macros should be needed on the NMAKE command line. + +USING PREPROCESSOR DEFINES +-------------------------- + +Additionally, preprocessor defines may be specified by using the OPTS macro +on the NMAKE command line. However, not all possible preprocessor defines +may be specified in this manner as some require the amalgamation to be built +with them enabled (see http://www.sqlite.org/compile.html). For example, the +following will work: + + "OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1" + +However, the following will not compile unless the amalgamation was built +with it enabled: + + "OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1" diff --git a/manifest b/manifest index e41fae053e..0f3e8b7b8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\sautoconf\sREADME\sfile. -D 2016-01-23T20:43:48.995 +C More\supdates\sto\sthe\sREADME. +D 2016-01-23T21:57:46.170 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -13,7 +13,7 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt ebf930270b2d6258f4d2c62c8c5a5dcc7cff5293 +F autoconf/README.txt fc86867528c500dfd691620e623bfe6799c98d14 F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -1421,7 +1421,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 12eb8db79697ef55228c78011d275f36f58271e1 -R f077ea8ac49bb767871086d72cc4aac2 -U drh -Z 47e598e0236f733ea03c00ba7b81ee9b +P 4ce60fa42d8486d219d40d25d785d7f2cabe5e06 +R 9ddb76e24748b77caceaf34a8b255b23 +U mistachkin +Z 8a8dd4db0d2ee1de0599573a5cb1355c diff --git a/manifest.uuid b/manifest.uuid index ea84af834d..c53057578b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ce60fa42d8486d219d40d25d785d7f2cabe5e06 \ No newline at end of file +9f02868df71d902a2b9118d0b06df18ee92b666b \ No newline at end of file From 9084ec1d962388a219d32fbed684f15e44de11d8 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Jan 2016 22:55:53 +0000 Subject: [PATCH 022/107] Add the SQLITE_SPELLFIX_STACKALLOC_SZ compile-time option to control how much stack space is available for use as the Wagner matrix in editDest3 of the spellfix extension. FossilOrigin-Name: dd0100dd87e2c7c70fabb2d3188f0906e605583d --- ext/misc/spellfix.c | 13 ++++++++++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index d17a05a3cd..68bd2afbb2 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -875,6 +875,17 @@ static void updateCost( } } +/* +** How much stack space (int bytes) to use for Wagner matrix in +** editDist3Core(). If more space than this is required, the entire +** matrix is taken from the heap. To reduce the load on the memory +** allocator, make this value as large as practical for the +** architecture in use. +*/ +#ifndef SQLITE_SPELLFIX_STACKALLOC_SZ +# define SQLITE_SPELLFIX_STACKALLOC_SZ (1024) +#endif + /* Compute the edit distance between two strings. ** ** If an error occurs, return a negative number which is the error code. @@ -904,7 +915,7 @@ static int editDist3Core( EditDist3Cost *p; int res; sqlite3_uint64 nByte; - unsigned int stackSpace[16*1024]; + unsigned int stackSpace[SQLITE_SPELLFIX_STACKALLOC_SZ/sizeof(unsigned int)]; /* allocate the Wagner matrix and the aTo[] array for the TO string */ n = (f.n+1)*(n2+1); diff --git a/manifest b/manifest index 8a5302c683..d6adb98190 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sspellfix\sto\stry\sto\sget\sit\sto\suse\sstack\sspace\sinstead\sof\sheap\sspace\nin\scases\swhere\sthat\smakes\ssense. -D 2016-01-23T18:24:52.238 +C Add\sthe\sSQLITE_SPELLFIX_STACKALLOC_SZ\scompile-time\soption\sto\scontrol\show\smuch\nstack\sspace\sis\savailable\sfor\suse\sas\sthe\sWagner\smatrix\sin\seditDest3\sof\sthe\nspellfix\sextension. +D 2016-01-23T22:55:53.451 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -210,7 +210,7 @@ F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c 5850a0e05ae1eacd48a3d80991c63b58d41e2d27 +F ext/misc/spellfix.c db4cc4b7aa12384e6c19a289a39cd232d355413d F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e @@ -1419,7 +1419,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 3be336aa893f9eb0837d7d66c83bab1489792b9a -R e0cc5654cf9d372268674d3acd0d1178 +P dfcebc7393a3a780ee9c4f257723c303bb633064 +R f2b384711e45db4261b5ef34d3e09d67 U drh -Z 5f4045218ee81aac454594c9cbaf4e94 +Z 57efa8447e9c944d8afed12c4b4dd5da diff --git a/manifest.uuid b/manifest.uuid index ff35bf94f1..dfbb1735b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfcebc7393a3a780ee9c4f257723c303bb633064 \ No newline at end of file +dd0100dd87e2c7c70fabb2d3188f0906e605583d \ No newline at end of file From d0d0f8dc67725287d31be219314e839594a4278f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 01:07:59 +0000 Subject: [PATCH 023/107] Small simplification and performance improvement in memsys5Free(). FossilOrigin-Name: 0a9cff5c4822874b74e90bfca3963bc7e5c753a5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem5.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d6adb98190..1cbb37b406 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_SPELLFIX_STACKALLOC_SZ\scompile-time\soption\sto\scontrol\show\smuch\nstack\sspace\sis\savailable\sfor\suse\sas\sthe\sWagner\smatrix\sin\seditDest3\sof\sthe\nspellfix\sextension. -D 2016-01-23T22:55:53.451 +C Small\ssimplification\sand\sperformance\simprovement\sin\smemsys5Free(). +D 2016-01-25T01:07:59.493 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -316,7 +316,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a -F src/mem5.c 71f81a11fc5e29a57428761ab38a7bf2ef4ee19d +F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memjournal.c 3eb2c0b51adbd869cb6a44780323f05fa904dc85 F src/msvc.h d9ba56c6851227ab44b3f228a35f3f5772296495 F src/mutex.c 8e45800ee78e0cd1f1f3fe8e398853307f4a085c @@ -1419,7 +1419,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 dfcebc7393a3a780ee9c4f257723c303bb633064 -R f2b384711e45db4261b5ef34d3e09d67 +P dd0100dd87e2c7c70fabb2d3188f0906e605583d +R a179bcf25d5e17fae98e7434f7b5c754 U drh -Z 57efa8447e9c944d8afed12c4b4dd5da +Z 6a3ae2a8bc97ab052cdf4e5d8140159f diff --git a/manifest.uuid b/manifest.uuid index dfbb1735b4..fed0f2a557 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd0100dd87e2c7c70fabb2d3188f0906e605583d \ No newline at end of file +0a9cff5c4822874b74e90bfca3963bc7e5c753a5 \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index 7316a630a6..c194a6b778 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -322,11 +322,11 @@ static void memsys5FreeUnsafe(void *pOld){ int iBuddy; if( (iBlock>>iLogsize) & 1 ){ iBuddy = iBlock - size; + assert( iBuddy>=0 ); }else{ iBuddy = iBlock + size; + if( iBuddy>=mem5.nBlock ) break; } - assert( iBuddy>=0 ); - if( (iBuddy+(1<mem5.nBlock ) break; if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break; memsys5Unlink(iBuddy, iLogsize); iLogsize++; From a7dc4a321d8f537d9257b20634f93dccfabd03cd Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 02:15:02 +0000 Subject: [PATCH 024/107] Small simplification to the prepare statement opcode memory reuse logic. Easier to read, and slightly smaller and faster. FossilOrigin-Name: 8a1deae497edf3fa43fa96152d140405398c5ed6 --- manifest | 12 ++--- manifest.uuid | 2 +- src/vdbeaux.c | 119 ++++++++++++++++++++++++-------------------------- 3 files changed, 64 insertions(+), 69 deletions(-) diff --git a/manifest b/manifest index 1cbb37b406..e1fe265cc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssimplification\sand\sperformance\simprovement\sin\smemsys5Free(). -D 2016-01-25T01:07:59.493 +C Small\ssimplification\sto\sthe\sprepare\sstatement\sopcode\smemory\sreuse\slogic.\nEasier\sto\sread,\sand\sslightly\ssmaller\sand\sfaster. +D 2016-01-25T02:15:02.255 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -414,7 +414,7 @@ F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 07f8f485a6cbc0a62da660f14e303061d45d5cb6 +F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 @@ -1419,7 +1419,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 dd0100dd87e2c7c70fabb2d3188f0906e605583d -R a179bcf25d5e17fae98e7434f7b5c754 +P 0a9cff5c4822874b74e90bfca3963bc7e5c753a5 +R 5ad29c29cc49b0c7f9cd0947deba5a80 U drh -Z 6a3ae2a8bc97ab052cdf4e5d8140159f +Z 5c673e5ee459b55b04084dc37cebc110 diff --git a/manifest.uuid b/manifest.uuid index fed0f2a557..f04ce16d0b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a9cff5c4822874b74e90bfca3963bc7e5c753a5 \ No newline at end of file +8a1deae497edf3fa43fa96152d140405398c5ed6 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 17f1cb7dc4..e9be081a20 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1721,41 +1721,43 @@ void sqlite3VdbeIOTraceSql(Vdbe *p){ } #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ -/* -** Allocate space from a fixed size buffer and return a pointer to -** that space. If insufficient space is available, return NULL. +/* An instance of this object describes bulk memory available for use +** by subcomponents of a prepared statement. Space is allocated out +** of a ReusableSpace object by the allocSpace() routine below. +*/ +struct ReusableSpace { + u8 *pSpace; /* Available memory */ + int nFree; /* Bytes of available memory */ + int nNeeded; /* Total bytes that could not be allocated */ +}; + +/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf +** from the ReusableSpace object. Return a pointer to the allocated +** memory on success. If insufficient memory is available in the +** ReusableSpace object, increase the ReusableSpace.nNeeded +** value by the amount needed and return NULL. ** -** The pBuf parameter is the initial value of a pointer which will -** receive the new memory. pBuf is normally NULL. If pBuf is not -** NULL, it means that memory space has already been allocated and that -** this routine should not allocate any new memory. When pBuf is not -** NULL simply return pBuf. Only allocate new memory space when pBuf -** is NULL. +** If pBuf is not initially NULL, that means that the memory has already +** been allocated by a prior call to this routine, so just return a copy +** of pBuf and leave ReusableSpace unchanged. ** -** nByte is the number of bytes of space needed. -** -** pFrom points to *pnFrom bytes of available space. New space is allocated -** from the end of the pFrom buffer and *pnFrom is decremented. -** -** *pnNeeded is a counter of the number of bytes of space that have failed -** to allocate. If there is insufficient space in pFrom to satisfy the -** request, then increment *pnNeeded by the amount of the request. +** This allocator is employed to repurpose unused slots at the end of the +** opcode array of prepared state for other memory needs of the prepared +** statement. */ static void *allocSpace( - void *pBuf, /* Where return pointer will be stored */ - int nByte, /* Number of bytes to allocate */ - u8 *pFrom, /* Memory available for allocation */ - int *pnFrom, /* IN/OUT: Space available at pFrom */ - int *pnNeeded /* If allocation cannot be made, increment *pnByte */ + struct ReusableSpace *p, /* Bulk memory available for allocation */ + void *pBuf, /* Pointer to a prior allocation */ + int nByte /* Bytes of memory needed */ ){ - assert( EIGHT_BYTE_ALIGNMENT(pFrom) ); + assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); if( pBuf==0 ){ nByte = ROUND8(nByte); - if( nByte <= *pnFrom ){ - *pnFrom -= nByte; - pBuf = &pFrom[*pnFrom]; + if( nByte <= p->nFree ){ + p->nFree -= nByte; + pBuf = &p->pSpace[p->nFree]; }else{ - *pnNeeded += nByte; + p->nNeeded += nByte; } } assert( EIGHT_BYTE_ALIGNMENT(pBuf) ); @@ -1831,9 +1833,7 @@ void sqlite3VdbeMakeReady( int nArg; /* Number of arguments in subprograms */ int nOnce; /* Number of OP_Once instructions */ int n; /* Loop counter */ - int nFree; /* Available free space */ - u8 *zCsr; /* Memory available for allocation */ - int nByte; /* How much extra memory is needed */ + struct ReusableSpace x; /* Reusable bulk memory */ assert( p!=0 ); assert( p->nOp>0 ); @@ -1851,7 +1851,7 @@ void sqlite3VdbeMakeReady( /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by - ** the vdbe program. Instead they are used to allocate space for + ** the vdbe program. Instead they are used to allocate memory for ** VdbeCursor/BtCursor structures. The blob of memory associated with ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) ** stores the blob of memory associated with cursor 1, etc. @@ -1860,20 +1860,18 @@ void sqlite3VdbeMakeReady( */ nMem += nCursor; - /* zCsr will initially point to nFree bytes of unused space at the - ** end of the opcode array, p->aOp. The computation of nFree is - ** conservative - it might be smaller than the true number of free - ** bytes, but never larger. nFree must be a multiple of 8 - it is - ** rounded down if is not. + /* Figure out how much reusable memory is available at the end of the + ** opcode array. This extra memory will be reallocated for other elements + ** of the prepared statement. */ - n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode space used */ - zCsr = &((u8*)p->aOp)[n]; /* Unused opcode space */ - assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); - nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused space */ - assert( nFree>=0 ); - if( nFree>0 ){ - memset(zCsr, 0, nFree); - assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) ); + n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ + x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ + assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); + x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ + assert( x.nFree>=0 ); + if( x.nFree>0 ){ + memset(x.pSpace, 0, x.nFree); + assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) ); } resolveP2Values(p, &nArg); @@ -1883,33 +1881,30 @@ void sqlite3VdbeMakeReady( } p->expired = 0; - /* Memory for registers, parameters, cursor, etc, is allocated in two - ** passes. On the first pass, we try to reuse unused space at the + /* Memory for registers, parameters, cursor, etc, is allocated in one or two + ** passes. On the first pass, we try to reuse unused memory at the ** end of the opcode array. If we are unable to satisfy all memory ** requirements by reusing the opcode array tail, then the second - ** pass will fill in the rest using a fresh allocation. + ** pass will fill in the remainder using a fresh memory allocation. ** ** This two-pass approach that reuses as much memory as possible from - ** the leftover space at the end of the opcode array can significantly + ** the leftover memory at the end of the opcode array. This can significantly ** reduce the amount of memory held by a prepared statement. */ do { - nByte = 0; - p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte); - p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte); - p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte); - p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), - zCsr, &nFree, &nByte); - p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte); + x.nNeeded = 0; + p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); + p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem)); + p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*)); + p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*)); + p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte); + p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64)); #endif - if( nByte ){ - p->pFree = sqlite3DbMallocZero(db, nByte); - } - zCsr = p->pFree; - nFree = nByte; - }while( nByte && !db->mallocFailed ); + if( x.nNeeded==0 ) break; + x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded); + x.nFree = x.nNeeded; + }while( !db->mallocFailed ); p->nCursor = nCursor; p->nOnceFlag = nOnce; From 164c957b091ed8fb0b875481556e9e7d882d11a2 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 13:55:47 +0000 Subject: [PATCH 025/107] Add the SQLITE_EXTRA_DURABLE compile-time option. FossilOrigin-Name: 30671345b1c1ee55a2d1aa17273213f1849efd81 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pager.c | 17 ++++++++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e1fe265cc4..69e58459fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssimplification\sto\sthe\sprepare\sstatement\sopcode\smemory\sreuse\slogic.\nEasier\sto\sread,\sand\sslightly\ssmaller\sand\sfaster. -D 2016-01-25T02:15:02.255 +C Add\sthe\sSQLITE_EXTRA_DURABLE\scompile-time\soption. +D 2016-01-25T13:55:47.049 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -332,7 +332,7 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 0eb7f469fcd4e1fbedf30060438e26b839ec5486 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c f4e9ac39fbb1e0fde97af85c0f4e00eb90764b67 +F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 @@ -1419,7 +1419,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 0a9cff5c4822874b74e90bfca3963bc7e5c753a5 -R 5ad29c29cc49b0c7f9cd0947deba5a80 +P 8a1deae497edf3fa43fa96152d140405398c5ed6 +R ae4ccddaf3c593cdf1ed2beb484cfd15 U drh -Z 5c673e5ee459b55b04084dc37cebc110 +Z 297086babbdf85e61ae58e42a437c1ec diff --git a/manifest.uuid b/manifest.uuid index f04ce16d0b..439be2e5fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a1deae497edf3fa43fa96152d140405398c5ed6 \ No newline at end of file +30671345b1c1ee55a2d1aa17273213f1849efd81 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 2c904d2df1..0afbe215c6 100644 --- a/src/pager.c +++ b/src/pager.c @@ -428,6 +428,20 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ */ #define MAX_SECTOR_SIZE 0x10000 +/* +** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then +** SQLite will do extra fsync() operations when synchronous==FULL to help +** ensure that transactions are durable across a power failure. Most +** applications are happy as long as transactions are consistent across +** a power failure, and are perfectly willing to lose the last transaction +** in exchange for the extra performance of avoiding directory syncs. +** And so the default SQLITE_EXTRA_DURABLE setting is off. +*/ +#ifndef SQLITE_EXTRA_DURABLE +# define SQLITE_EXTRA_DURABLE 0 +#endif + + /* ** An instance of the following structure is allocated for each active ** savepoint and statement transaction in the system. All such structures @@ -1983,7 +1997,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ ); sqlite3OsClose(pPager->jfd); if( bDelete ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, + pPager->fullSync && SQLITE_EXTRA_DURABLE); } } } From cc2fa4cf5599637bdb8f5a2cc64f0805243e04e4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 15:57:29 +0000 Subject: [PATCH 026/107] Replace the OP_SetIfNotPos operator with OP_OffsetLimit in the VDBE, for simpler and smaller code. FossilOrigin-Name: 7ac017a498b6fb28343eef2d24e400c7800660d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 9 +++------ src/vdbe.c | 33 ++++++++++++++++++++++----------- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 69e58459fa..827a3d5126 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_EXTRA_DURABLE\scompile-time\soption. -D 2016-01-25T13:55:47.049 +C Replace\sthe\sOP_SetIfNotPos\soperator\swith\sOP_OffsetLimit\sin\sthe\sVDBE,\sfor\nsimpler\sand\ssmaller\scode. +D 2016-01-25T15:57:29.060 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -345,7 +345,7 @@ F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 1db9a902e89201a0ae3ff5243a7a3f37842a3937 +F src/select.c c34292c8ce7fe69c7cf890d933834a22572bd301 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -410,7 +410,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c b90d9d38e5e0260c2eafa3cb4c2274d8ea94da27 +F src/vdbe.c 3ffbcc413bf793e3f0b95b79ef2f4bd449a5b5a3 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1419,7 +1419,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 8a1deae497edf3fa43fa96152d140405398c5ed6 -R ae4ccddaf3c593cdf1ed2beb484cfd15 +P 30671345b1c1ee55a2d1aa17273213f1849efd81 +R f342889ba3409bd63b1cf54d88bfe0e2 U drh -Z 297086babbdf85e61ae58e42a437c1ec +Z e7c5fc86067d4269675714897cec0b51 diff --git a/manifest.uuid b/manifest.uuid index 439be2e5fa..276ef7a03f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30671345b1c1ee55a2d1aa17273213f1849efd81 \ No newline at end of file +7ac017a498b6fb28343eef2d24e400c7800660d6 \ No newline at end of file diff --git a/src/select.c b/src/select.c index ffc0ec2415..ea4298e677 100644 --- a/src/select.c +++ b/src/select.c @@ -1860,10 +1860,8 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ sqlite3ExprCode(pParse, p->pOffset, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); - sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0); - sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); + sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); VdbeComment((v, "LIMIT+OFFSET")); - sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1); } } } @@ -2280,9 +2278,8 @@ static int multiSelect( addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); if( p->iOffset ){ - sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0); - sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1); - sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1); + sqlite3VdbeAddOp3(v, OP_OffsetLimit, + p->iLimit, p->iOffset+1, p->iOffset); } } explainSetInteger(iSub2, pParse->iNextSelectId); diff --git a/src/vdbe.c b/src/vdbe.c index c6d5f7b0cc..cfff895c30 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5757,20 +5757,31 @@ case OP_IfPos: { /* jump, in1 */ break; } -/* Opcode: SetIfNotPos P1 P2 P3 * * -** Synopsis: if r[P1]<=0 then r[P2]=P3 +/* Opcode: OffsetLimit P1 P2 P3 * * +** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) ** -** Register P1 must contain an integer. -** If the value of register P1 is not positive (if it is less than 1) then -** set the value of register P2 to be the integer P3. +** This opcode performs a commonly used computation associated with +** LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] +** holds the offset counter. The opcode computes the combined value +** of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] +** value computed is the total number of rows that will need to be +** visited in order to complete the query. +** +** If r[P3] is zero or negative, that means there is no OFFSET +** and r[P2] is set to be the value of the LIMIT, r[P1]. +** +** if r[P1] is zero or negative, that means there is no LIMIT +** and r[P2] is set to -1. +** +** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. */ -case OP_SetIfNotPos: { /* in1, in2 */ +case OP_OffsetLimit: { /* in1, out2, in3 */ pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags&MEM_Int ); - if( pIn1->u.i<=0 ){ - pOut = out2Prerelease(p, pOp); - pOut->u.i = pOp->p3; - } + pIn3 = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + assert( pIn1->flags & MEM_Int ); + assert( pIn3->flags & MEM_Int ); + pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0); break; } From e88ec187cdd590f7b9155cef3ee276c268a4a522 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 25 Jan 2016 17:04:48 +0000 Subject: [PATCH 027/107] Fix issues on unix with opening database files via symlinks that are not in the current working directory. And with nested symlinks. FossilOrigin-Name: 80398fd44fb232193450103808e1854e0eba5652 --- manifest | 19 +++--- manifest.uuid | 2 +- src/os_unix.c | 154 +++++++++++++++++++++++++++++++++------------- test/symlink.test | 119 ++++++++++++++++++++++++++--------- 4 files changed, 215 insertions(+), 79 deletions(-) diff --git a/manifest b/manifest index 827a3d5126..0b395a1661 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sthe\sOP_SetIfNotPos\soperator\swith\sOP_OffsetLimit\sin\sthe\sVDBE,\sfor\nsimpler\sand\ssmaller\scode. -D 2016-01-25T15:57:29.060 +C Fix\sissues\son\sunix\swith\sopening\sdatabase\sfiles\svia\ssymlinks\sthat\sare\snot\sin\sthe\scurrent\sworking\sdirectory.\sAnd\swith\snested\ssymlinks. +D 2016-01-25T17:04:48.546 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 0eb7f469fcd4e1fbedf30060438e26b839ec5486 +F src/os_unix.c cf524029242b4f878d6b97bad25cc2c0b66c2b31 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 @@ -1061,7 +1061,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 -F test/symlink.test cbf6cb8c6c4b63a39e9f0f6b0d5c99e249dbc102 +F test/symlink.test 511db82662446bb0d3619002422760ef8e4b1122 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 @@ -1419,7 +1419,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 30671345b1c1ee55a2d1aa17273213f1849efd81 -R f342889ba3409bd63b1cf54d88bfe0e2 -U drh -Z e7c5fc86067d4269675714897cec0b51 +P 7ac017a498b6fb28343eef2d24e400c7800660d6 +R 0289127606d03bb3b649ecbd39bb14a5 +T *branch * follow-symlinks +T *sym-follow-symlinks * +T -sym-trunk * +U dan +Z 3e18b3d01ba737d3635110839e378935 diff --git a/manifest.uuid b/manifest.uuid index 276ef7a03f..6dda1af216 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac017a498b6fb28343eef2d24e400c7800660d6 \ No newline at end of file +80398fd44fb232193450103808e1854e0eba5652 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index ee9b55674b..9cd1fa19ad 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -149,6 +149,11 @@ */ #define MAX_PATHNAME 512 +/* +** Maximum supported symbolic links +*/ +#define SQLITE_MAX_SYMLINKS 100 + /* Always cast the getpid() return type for compatibility with ** kernel modules in VxWorks. */ #define osGetpid(X) (pid_t)getpid() @@ -5927,52 +5932,22 @@ static int unixAccess( return SQLITE_OK; } - /* -** Turn a relative pathname into a full pathname. The relative path -** is stored as a nul-terminated string in the buffer pointed to by -** zPath. +** Buffer zOut contains a (possibly) relative pathname. Overwrite it with +** the corresponding full pathname. ** -** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes -** (in this case, MAX_PATHNAME bytes). The full-path is written to -** this buffer before returning. +** Parameter nOut is the allocated size of buffer zOut. nByte is the number +** of bytes in the nul-terminated string that it contains (not including +** the nul-terminator itself). +** +** Return SQLITE_OK if successful, or an SQLite error code otherwise. */ -static int unixFullPathname( - sqlite3_vfs *pVfs, /* Pointer to vfs object */ - const char *zPath, /* Possibly relative input path */ - int nOut, /* Size of output buffer in bytes */ - char *zOut /* Output buffer */ +static int mkFullPathname( + const char *zPath, /* Use this path to log any errors */ + char *zOut, /* IN/OUT: Buffer to modify */ + int nByte, /* size of nul-terminated zOut in bytes */ + int nOut /* Allocated size of buffer zOut */ ){ - int nByte; - - /* It's odd to simulate an io-error here, but really this is just - ** using the io-error infrastructure to test that SQLite handles this - ** function failing. This function could fail if, for example, the - ** current working directory has been unlinked. - */ - SimulateIOError( return SQLITE_ERROR ); - - assert( pVfs->mxPathname==MAX_PATHNAME ); - UNUSED_PARAMETER(pVfs); - -#if defined(HAVE_READLINK) - /* Attempt to resolve the path as if it were a symbolic link. If it is - ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if - ** the identified file is not a symbolic link or does not exist, then - ** zPath is copied directly into zOut. Either way, nByte is left set to - ** the size of the string copied into zOut[] in bytes. */ - nByte = osReadlink(zPath, zOut, nOut-1); - if( nByte<0 ){ - if( errno!=EINVAL && errno!=ENOENT ){ - return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath); - } - sqlite3_snprintf(nOut, zOut, "%s", zPath); - nByte = sqlite3Strlen30(zOut); - }else{ - zOut[nByte] = '\0'; - } -#endif - /* If buffer zOut[] now contains an absolute path there is nothing more ** to do. If it contains a relative path, do the following: ** @@ -5989,6 +5964,7 @@ static int unixFullPathname( ** truncated to make it fit. This is Ok, as SQLite refuses to open any ** file for which this function returns a full path larger than (nOut-8) ** bytes in size. */ + assert( nBytemxPathname==MAX_PATHNAME ); + UNUSED_PARAMETER(pVfs); + + /* It's odd to simulate an io-error here, but really this is just + ** using the io-error infrastructure to test that SQLite handles this + ** function failing. This function could fail if, for example, the + ** current working directory has been unlinked. + */ + SimulateIOError( return SQLITE_ERROR ); + + do { + + /* Attempt to resolve the path as if it were a symbolic link. If it is + ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if + ** the identified file is not a symbolic link or does not exist, then + ** zPath is copied directly into zOut. Either way, nByte is left set to + ** the size of the string copied into zOut[] in bytes. */ + assert( (zDel==0 && zIn==zPath) || (zDel!=0 && zIn==zDel) ); + if( zDel ){ + assert( zIn==zDel ); + sqlite3_snprintf(nOut, zDel, "%s", zOut); + } + nByte = osReadlink(zIn, zOut, nOut-1); + if( nByte<0 ){ + if( errno!=EINVAL && errno!=ENOENT ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath); + }else{ + sqlite3_snprintf(nOut, zOut, "%s", zIn); + nByte = sqlite3Strlen30(zOut); + } + bLink = 0; + }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ + sqlite3_log(SQLITE_CANTOPEN, + "too many symbolic links (max=%d)", SQLITE_MAX_SYMLINKS + ); + rc = SQLITE_CANTOPEN_BKPT; + }else{ + zOut[nByte] = '\0'; + if( zOut[0]!='/' ){ + int n; + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + if( nByte+n+1>nOut ){ + rc = SQLITE_CANTOPEN_BKPT; + }else{ + memmove(&zOut[n], zOut, nByte+1); + memcpy(zOut, zIn, n); + nByte += n; + } + } + if( zDel==0 ){ + zDel = sqlite3_malloc(nOut); + if( zDel==0 ) rc = SQLITE_NOMEM; + zIn = (const char*)zDel; + } + bLink = 1; + } + + if( rc==SQLITE_OK ){ + rc = mkFullPathname(zPath, zOut, nByte, nOut); + } + }while( bLink && rc==SQLITE_OK ); + + sqlite3_free(zDel); + return rc; +#endif /* HAVE_READLINK */ +} + #ifndef SQLITE_OMIT_LOAD_EXTENSION /* diff --git a/test/symlink.test b/test/symlink.test index 790624161f..e9e5f3c305 100644 --- a/test/symlink.test +++ b/test/symlink.test @@ -83,38 +83,49 @@ do_test 1.5 { do_test 2.0 { catch { db close } catch { db2 close } - forcedelete test.db test.db2 + forcedelete test.db test.db2 test.db3 sqlite3 db test.db execsql { CREATE TABLE t1(x) } file link test.db2 test.db - sqlite3 db2 test.db2 - file exists test.db-journal -} 0 + file link test.db3 test.db2 + set {} {} +} {} -do_test 2.1 { - execsql { - BEGIN; - INSERT INTO t1 VALUES(1); - } db2 - file exists test.db-journal -} 1 -do_test 2.2 { - file exists test.db2-journal -} 0 -do_test 2.3 { - execsql { - COMMIT; - PRAGMA journal_mode = wal; - INSERT INTO t1 VALUES(2); - } db2 - file exists test.db-wal -} 1 -do_test 2.4 { - file exists test.db2-wal -} 0 -do_execsql_test 2.5 { - SELECT * FROM t1; -} {1 2} +foreach {tn f} {1 test.db2 2 test.db3} { + do_test 2.$tn.1 { + sqlite3 db2 $f + file exists test.db-journal + } 0 + do_test 2.$tn.2 { + execsql { + BEGIN; + INSERT INTO t1 VALUES(1); + } db2 + file exists test.db-journal + } 1 + do_test 2.$tn.3 { + list [file exists test2.db-journal] [file exists test3.db-journal] + } {0 0} + do_test 2.$tn.4 { + execsql { + COMMIT; + PRAGMA journal_mode = wal; + INSERT INTO t1 VALUES(2); + } db2 + file exists test.db-wal + } 1 + do_test 2.$tn.5 { + list [file exists test2.db-wal] [file exists test3.db-wal] + } {0 0} + do_execsql_test 2.$tn.6 { + SELECT * FROM t1; + } {1 2} + db2 close + do_execsql_test 2.$tn.7 { + DELETE FROM t1; + PRAGMA journal_mode = delete; + } delete +} # Try to open a ridiculously long pathname. Bug found by # Kostya Serebryany using libFuzzer on 2015-11-30. @@ -125,5 +136,57 @@ do_test 3.1 { set res } {unable to open database file} +#------------------------------------------------------------------------- +# Test that relative symlinks that are not located in the cwd work. +# +do_test 4.1 { + forcedelete x y z + file mkdir x + file mkdir y + file mkdir z + sqlite3 db x/test.db + file link y/test.db ../x/test.db + file link z/test.db ../y/test.db + execsql { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES('hello', 'world'); + } +} {wal} + +do_test 4.2.1 { + db close + sqlite3 db y/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.2.2 { + list [file exists x/test.db-wal] [file exists y/test.db-wal] +} {1 0} + +do_test 4.3.1 { + db close + sqlite3 db z/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.3.2 { + list [file exists x/test.db-wal] [file exists y/test.db-wal] \ + [file exists z/test.db-wal] +} {1 0 0} + +do_test 4.4.0 { + forcedelete w + file mkdir w + file link w/test.db [file join [pwd] x/test.db] + set {} {} +} {} +do_test 4.4.1 { + db close + breakpoint + sqlite3 db w/test.db + db eval { SELECT * FROM t1 } +} {hello world} +do_test 4.4.2 { + list [file exists x/test.db-wal] [file exists w/test.db-wal] +} {1 0} finish_test From caf6b150a1077f2d4293b4091247c7e932da3927 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 25 Jan 2016 18:05:49 +0000 Subject: [PATCH 028/107] Simplify the unixFullpathname() function. This adds a dependency on lstat(). FossilOrigin-Name: f71249d3db9242b8f38955db51a7a5789d002803 --- manifest | 15 +++--- manifest.uuid | 2 +- src/os_unix.c | 137 +++++++++++++++++++------------------------------- 3 files changed, 60 insertions(+), 94 deletions(-) diff --git a/manifest b/manifest index 0b395a1661..27188d419f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sissues\son\sunix\swith\sopening\sdatabase\sfiles\svia\ssymlinks\sthat\sare\snot\sin\sthe\scurrent\sworking\sdirectory.\sAnd\swith\snested\ssymlinks. -D 2016-01-25T17:04:48.546 +C Simplify\sthe\sunixFullpathname()\sfunction.\sThis\sadds\sa\sdependency\son\slstat(). +D 2016-01-25T18:05:49.964 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c cf524029242b4f878d6b97bad25cc2c0b66c2b31 +F src/os_unix.c 6604e7f9e5298b615f729b6bb3c22bd3545cdca6 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 @@ -1419,10 +1419,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 7ac017a498b6fb28343eef2d24e400c7800660d6 -R 0289127606d03bb3b649ecbd39bb14a5 -T *branch * follow-symlinks -T *sym-follow-symlinks * -T -sym-trunk * +P 80398fd44fb232193450103808e1854e0eba5652 +R 084dee05e1353887f6af0d88670b22d0 U dan -Z 3e18b3d01ba737d3635110839e378935 +Z 72572e009a3ce3b7747f3257ebf7dfc7 diff --git a/manifest.uuid b/manifest.uuid index 6dda1af216..b66c39a6ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80398fd44fb232193450103808e1854e0eba5652 \ No newline at end of file +f71249d3db9242b8f38955db51a7a5789d002803 \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 9cd1fa19ad..3d113301b8 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -480,6 +480,8 @@ static struct unix_syscall { #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) + { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, +#define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) }; /* End of the overrideable system calls */ @@ -5933,54 +5935,24 @@ static int unixAccess( } /* -** Buffer zOut contains a (possibly) relative pathname. Overwrite it with -** the corresponding full pathname. ** -** Parameter nOut is the allocated size of buffer zOut. nByte is the number -** of bytes in the nul-terminated string that it contains (not including -** the nul-terminator itself). -** -** Return SQLITE_OK if successful, or an SQLite error code otherwise. */ static int mkFullPathname( - const char *zPath, /* Use this path to log any errors */ - char *zOut, /* IN/OUT: Buffer to modify */ - int nByte, /* size of nul-terminated zOut in bytes */ + const char *zPath, /* Input path */ + char *zOut, /* Output buffer */ int nOut /* Allocated size of buffer zOut */ ){ - /* If buffer zOut[] now contains an absolute path there is nothing more - ** to do. If it contains a relative path, do the following: - ** - ** * move the relative path string so that it is at the end of th - ** zOut[] buffer. - ** * Call getcwd() to read the path of the current working directory - ** into the start of the zOut[] buffer. - ** * Append a '/' character to the cwd string and move the - ** relative path back within the buffer so that it immediately - ** follows the '/'. - ** - ** This code is written so that if the combination of the CWD and relative - ** path are larger than the allocated size of zOut[] the CWD is silently - ** truncated to make it fit. This is Ok, as SQLite refuses to open any - ** file for which this function returns a full path larger than (nOut-8) - ** bytes in size. */ - assert( nBytenOut ) return SQLITE_CANTOPEN_BKPT; + sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); return SQLITE_OK; } @@ -6000,13 +5972,11 @@ static int unixFullPathname( char *zOut /* Output buffer */ ){ #if !defined(HAVE_READLINK) - sqlite3_snprintf(nOut, zOut, "%s", zIn); - nByte = sqlite3Strlen30(zOut); - return mkFullPathname(zPath, zOut, sqlite3Strlen30(zOut), nOut); + return mkFullPathname(zPath, zOut, nOut); #else int rc = SQLITE_OK; int nByte; - int nLink = 0; /* Number of symbolic links followed so far */ + int nLink = 1; /* Number of symbolic links followed so far */ int bLink; /* True for a symbolic link */ const char *zIn = zPath; /* Input path for each iteration of loop */ char *zDel = 0; @@ -6023,55 +5993,54 @@ static int unixFullPathname( do { - /* Attempt to resolve the path as if it were a symbolic link. If it is - ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if - ** the identified file is not a symbolic link or does not exist, then - ** zPath is copied directly into zOut. Either way, nByte is left set to - ** the size of the string copied into zOut[] in bytes. */ - assert( (zDel==0 && zIn==zPath) || (zDel!=0 && zIn==zDel) ); - if( zDel ){ - assert( zIn==zDel ); - sqlite3_snprintf(nOut, zDel, "%s", zOut); - } - nByte = osReadlink(zIn, zOut, nOut-1); - if( nByte<0 ){ - if( errno!=EINVAL && errno!=ENOENT ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath); - }else{ - sqlite3_snprintf(nOut, zOut, "%s", zIn); - nByte = sqlite3Strlen30(zOut); + /* Call stat() on path zIn. Set bLink to true if the path is a symbolic + ** link, or false otherwise. */ + int bLink = 0; + struct stat buf; + if( osLstat(zIn, &buf)!=0 ){ + if( errno!=ENOENT ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "stat", zIn); } - bLink = 0; - }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ - sqlite3_log(SQLITE_CANTOPEN, - "too many symbolic links (max=%d)", SQLITE_MAX_SYMLINKS - ); - rc = SQLITE_CANTOPEN_BKPT; }else{ - zOut[nByte] = '\0'; - if( zOut[0]!='/' ){ - int n; - for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); - if( nByte+n+1>nOut ){ - rc = SQLITE_CANTOPEN_BKPT; - }else{ - memmove(&zOut[n], zOut, nByte+1); - memcpy(zOut, zIn, n); - nByte += n; - } - } + bLink = S_ISLNK(buf.st_mode); + } + + if( bLink ){ if( zDel==0 ){ zDel = sqlite3_malloc(nOut); if( zDel==0 ) rc = SQLITE_NOMEM; - zIn = (const char*)zDel; + }else if( ++nLink>SQLITE_MAX_SYMLINKS ){ + rc = SQLITE_CANTOPEN_BKPT; } - bLink = 1; + + if( rc==SQLITE_OK ){ + nByte = osReadlink(zIn, zDel, nOut-1); + if( nByte<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); + }else if( zDel[0]!='/' ){ + int n; + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + if( nByte+n+1>nOut ){ + rc = SQLITE_CANTOPEN_BKPT; + }else{ + memmove(&zDel[n], zDel, nByte+1); + memcpy(zDel, zIn, n); + nByte += n; + } + zDel[nByte] = '\0'; + } + } + + zIn = zDel; } if( rc==SQLITE_OK ){ - rc = mkFullPathname(zPath, zOut, nByte, nOut); + assert( zIn!=zOut || zIn[0]=='/' ); + rc = mkFullPathname(zIn, zOut, nOut); } - }while( bLink && rc==SQLITE_OK ); + if( bLink==0 ) break; + zIn = zOut; + }while( rc==SQLITE_OK ); sqlite3_free(zDel); return rc; @@ -7574,7 +7543,7 @@ int sqlite3_os_init(void){ /* Double-check that the aSyscall[] array has been constructed ** correctly. See ticket [bb3a86e890c8e96ab] */ - assert( ArraySize(aSyscall)==27 ); + assert( ArraySize(aSyscall)==28 ); /* Register all VFSes defined in the aVfs[] array */ for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ From af1b36b1df592aa8ecf1fd8799db7e415688ed6e Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 25 Jan 2016 18:43:05 +0000 Subject: [PATCH 029/107] Only use lstat() if the HAVE_LSTAT macro is defined. Fix some test file issues. FossilOrigin-Name: 8a6e4147a680ad6c5fdd588468b6daac82349d2c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/os_unix.c | 12 ++++++++---- src/vxworks.h | 1 + test/oserror.test | 2 +- test/syscall.test | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 27188d419f..33b8dc8b5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sunixFullpathname()\sfunction.\sThis\sadds\sa\sdependency\son\slstat(). -D 2016-01-25T18:05:49.964 +C Only\suse\slstat()\sif\sthe\sHAVE_LSTAT\smacro\sis\sdefined.\sFix\ssome\stest\sfile\sissues. +D 2016-01-25T18:43:05.007 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 6604e7f9e5298b615f729b6bb3c22bd3545cdca6 +F src/os_unix.c 4c217111d7bdebbd7a9b47cf11f434420da432e7 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 @@ -420,7 +420,7 @@ F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde -F src/vxworks.h 974e7d9a98f602d6310d563e1dc4e08f9fc48e47 +F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 @@ -924,7 +924,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 -F test/oserror.test 361346396ae18462c7393c1ac5c3f17237bd89b2 +F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799 F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 @@ -1063,7 +1063,7 @@ F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/symlink.test 511db82662446bb0d3619002422760ef8e4b1122 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 -F test/syscall.test 2aa9e111b79fb385681ff8940124def6f8faab87 +F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc F test/table.test b708f3e5fa2542fa51dfab21fc07b36ea445cb2f @@ -1419,7 +1419,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 80398fd44fb232193450103808e1854e0eba5652 -R 084dee05e1353887f6af0d88670b22d0 +P f71249d3db9242b8f38955db51a7a5789d002803 +R 31817b68212f6684c4e9fbfebdae658d U dan -Z 72572e009a3ce3b7747f3257ebf7dfc7 +Z 17d90a7cade21886dca3e4bdfc08ed4c diff --git a/manifest.uuid b/manifest.uuid index b66c39a6ae..35202dd686 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f71249d3db9242b8f38955db51a7a5789d002803 \ No newline at end of file +8a6e4147a680ad6c5fdd588468b6daac82349d2c \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 3d113301b8..a3bb45bdb9 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -480,7 +480,11 @@ static struct unix_syscall { #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) - { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, +#if defined(HAVE_LSTAT) + { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, +#else + { "lstat", (sqlite3_syscall_ptr)0, 0 }, +#endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) }; /* End of the overrideable system calls */ @@ -5971,7 +5975,7 @@ static int unixFullPathname( int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ ){ -#if !defined(HAVE_READLINK) +#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT) return mkFullPathname(zPath, zOut, nOut); #else int rc = SQLITE_OK; @@ -5999,7 +6003,7 @@ static int unixFullPathname( struct stat buf; if( osLstat(zIn, &buf)!=0 ){ if( errno!=ENOENT ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "stat", zIn); + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn); } }else{ bLink = S_ISLNK(buf.st_mode); @@ -6044,7 +6048,7 @@ static int unixFullPathname( sqlite3_free(zDel); return rc; -#endif /* HAVE_READLINK */ +#endif /* HAVE_READLINK && HAVE_LSTAT */ } diff --git a/src/vxworks.h b/src/vxworks.h index 60c41a19b8..e7013c3f66 100644 --- a/src/vxworks.h +++ b/src/vxworks.h @@ -28,4 +28,5 @@ #define OS_VXWORKS 0 #define HAVE_FCHOWN 1 #define HAVE_READLINK 1 +#define HAVE_LSTAT 1 #endif /* defined(_WRS_KERNEL) */ diff --git a/test/oserror.test b/test/oserror.test index 5fa7f98eb5..246a9d4023 100644 --- a/test/oserror.test +++ b/test/oserror.test @@ -95,7 +95,7 @@ do_test 1.4.1 { do_re_test 1.4.2 { lindex $::log 0 -} {^os_unix.c:\d*: \(\d+\) (open|readlink)\(.*test.db\) - } +} {^os_unix.c:\d*: \(\d+\) (open|readlink|lstat)\(.*test.db\) - } #-------------------------------------------------------------------------- # Tests oserror-1.* test failures in the unlink() system call. diff --git a/test/syscall.test b/test/syscall.test index a935957d39..5716b35a6e 100644 --- a/test/syscall.test +++ b/test/syscall.test @@ -61,7 +61,7 @@ foreach s { fcntl read pread write pwrite fchmod fallocate pread64 pwrite64 unlink openDirectory mkdir rmdir statvfs fchown geteuid umask mmap munmap mremap - getpagesize readlink + getpagesize readlink lstat } { if {[test_syscall exists $s]} {lappend syscall_list $s} } From 2aac8c7ba1e84a90b36906926336a4558360a02e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 22:08:11 +0000 Subject: [PATCH 030/107] Fix a compiler warning about doing pointer arithmetic involving a NULL pointer even though the result of computation is never used. FossilOrigin-Name: 7c49a9478bd36564e81d33458ca1f4063ddaca83 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 827a3d5126..5a7fe0a637 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Replace\sthe\sOP_SetIfNotPos\soperator\swith\sOP_OffsetLimit\sin\sthe\sVDBE,\sfor\nsimpler\sand\ssmaller\scode. -D 2016-01-25T15:57:29.060 +C Fix\sa\scompiler\swarning\sabout\sdoing\spointer\sarithmetic\sinvolving\sa\sNULL\spointer\neven\sthough\sthe\sresult\sof\scomputation\sis\snever\sused. +D 2016-01-25T22:08:11.961 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -417,7 +417,7 @@ F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 -F src/vdbesort.c 0971557e5d3c289e46f56a52aed2197c13251de7 +F src/vdbesort.c 3bb1f1f03162e6d223da623714d8e93fcaeac658 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde F src/vxworks.h 974e7d9a98f602d6310d563e1dc4e08f9fc48e47 @@ -1419,7 +1419,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 30671345b1c1ee55a2d1aa17273213f1849efd81 -R f342889ba3409bd63b1cf54d88bfe0e2 +P 7ac017a498b6fb28343eef2d24e400c7800660d6 +R aa5d51a793ca6d0a7613986a1affa54a U drh -Z e7c5fc86067d4269675714897cec0b51 +Z 142832d114ade2d8f5ff5fab3faed40b diff --git a/manifest.uuid b/manifest.uuid index 276ef7a03f..d34f9b48c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac017a498b6fb28343eef2d24e400c7800660d6 \ No newline at end of file +7c49a9478bd36564e81d33458ca1f4063ddaca83 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index e095f80912..22029aa6bf 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1837,7 +1837,9 @@ int sqlite3VdbeSorterWrite( pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory]; pSorter->iMemory += ROUND8(nReq); - pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); + if( pSorter->list.pList ){ + pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); + } }else{ pNew = (SorterRecord *)sqlite3Malloc(nReq); if( pNew==0 ){ From a72d15b5f0bbc0d67eb117624df7f005ad89c443 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Jan 2016 23:19:58 +0000 Subject: [PATCH 031/107] Minor changes to the autoconf/README.txt file. FossilOrigin-Name: 6df8a9c00a9d067f67d492da7a4617908070c6c0 --- autoconf/README.txt | 16 +++++++++++----- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/autoconf/README.txt b/autoconf/README.txt index a581c39dea..114831ec5e 100644 --- a/autoconf/README.txt +++ b/autoconf/README.txt @@ -9,6 +9,12 @@ This package contains: * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on Windows. +SUMMARY OF HOW TO BUILD +======================= + + unix: ./configure; make + windows: nmake /f Makefile.msc + BUILDING ON POSIX ================= @@ -47,7 +53,7 @@ Using Microsoft Visual C++ 2005 (or later) is recommended. Several Windows platform variants may be built by adding additional macros to the NMAKE command line. -BUILDING FOR WINRT 8.0 +Building for WinRT 8.0 ---------------------- FOR_WINRT=1 @@ -58,7 +64,7 @@ NMAKE command line as well: "NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86" -BUILDING FOR WINRT 8.1 +Building for WinRT 8.1 ---------------------- FOR_WINRT=1 @@ -69,7 +75,7 @@ NMAKE command line as well: "NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86" -BUILDING FOR UAP 10.0 +Building for UAP 10.0 --------------------- FOR_WINRT=1 FOR_UAP=1 @@ -82,7 +88,7 @@ NMAKE command line as well: "PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86" "NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86" -BUILDING FOR THE WINDOWS 10 SDK +Building for the Windows 10 SDK ------------------------------- FOR_WIN10=1 @@ -90,7 +96,7 @@ BUILDING FOR THE WINDOWS 10 SDK Using Microsoft Visual C++ 2015 (or later) is required. When using the above, no other macros should be needed on the NMAKE command line. -USING PREPROCESSOR DEFINES +Other preprocessor defines -------------------------- Additionally, preprocessor defines may be specified by using the OPTS macro diff --git a/manifest b/manifest index 0f3e8b7b8d..48622ea281 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\supdates\sto\sthe\sREADME. -D 2016-01-23T21:57:46.170 +C Minor\schanges\sto\sthe\sautoconf/README.txt\sfile. +D 2016-01-25T23:19:58.651 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -13,7 +13,7 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt fc86867528c500dfd691620e623bfe6799c98d14 +F autoconf/README.txt e3a5cf0ba2d8944c71ca1eb7c06c15f52bfca131 F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -1421,7 +1421,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 4ce60fa42d8486d219d40d25d785d7f2cabe5e06 -R 9ddb76e24748b77caceaf34a8b255b23 -U mistachkin -Z 8a8dd4db0d2ee1de0599573a5cb1355c +P 9f02868df71d902a2b9118d0b06df18ee92b666b +R 9aeab9bcdca09d2b8e9198ca7dec65cb +U drh +Z 1be43b84d3a6e7c2425c5f0806c1fce0 diff --git a/manifest.uuid b/manifest.uuid index c53057578b..4cab521d6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f02868df71d902a2b9118d0b06df18ee92b666b \ No newline at end of file +6df8a9c00a9d067f67d492da7a4617908070c6c0 \ No newline at end of file From f0fc9929369cda0c7416174d43a299188b8beabf Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Jan 2016 00:12:42 +0000 Subject: [PATCH 032/107] Remove an unused variable. FossilOrigin-Name: 1c2656c1d37906230edc142d3a4253b16b6e925f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/os_unix.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 33b8dc8b5c..ea40dd333f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\suse\slstat()\sif\sthe\sHAVE_LSTAT\smacro\sis\sdefined.\sFix\ssome\stest\sfile\sissues. -D 2016-01-25T18:43:05.007 +C Remove\san\sunused\svariable. +D 2016-01-26T00:12:42.634 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 4c217111d7bdebbd7a9b47cf11f434420da432e7 +F src/os_unix.c e9e1e6a49892a76fe1fd167b1d475eeddaf1ccb3 F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 @@ -1419,7 +1419,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 f71249d3db9242b8f38955db51a7a5789d002803 -R 31817b68212f6684c4e9fbfebdae658d -U dan -Z 17d90a7cade21886dca3e4bdfc08ed4c +P 8a6e4147a680ad6c5fdd588468b6daac82349d2c +R d2cf53f7b50c768b631d5f18bba143b9 +U drh +Z 592370e14c792642f017f87ac074cb77 diff --git a/manifest.uuid b/manifest.uuid index 35202dd686..78b51cd18f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a6e4147a680ad6c5fdd588468b6daac82349d2c \ No newline at end of file +1c2656c1d37906230edc142d3a4253b16b6e925f \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index a3bb45bdb9..cdbcd2c8e0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5981,7 +5981,6 @@ static int unixFullPathname( int rc = SQLITE_OK; int nByte; int nLink = 1; /* Number of symbolic links followed so far */ - int bLink; /* True for a symbolic link */ const char *zIn = zPath; /* Input path for each iteration of loop */ char *zDel = 0; From 23496702622549d23f22639b7e2f5c47cfeba9a6 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jan 2016 13:56:42 +0000 Subject: [PATCH 033/107] Ensure that unixFullpathname() always nul-terminates its output buffer, even when returning an error. FossilOrigin-Name: 4a4385564dd3887a7953820b60c99d6ce289f96a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/os_unix.c | 31 +++++++++++++++++++------------ test/symlink.test | 1 - 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index ea40dd333f..2765e104fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\svariable. -D 2016-01-26T00:12:42.634 +C Ensure\sthat\sunixFullpathname()\salways\snul-terminates\sits\soutput\sbuffer,\seven\swhen\sreturning\san\serror. +D 2016-01-26T13:56:42.494 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -329,7 +329,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c e9e1e6a49892a76fe1fd167b1d475eeddaf1ccb3 +F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 @@ -1061,7 +1061,7 @@ F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 -F test/symlink.test 511db82662446bb0d3619002422760ef8e4b1122 +F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 @@ -1419,7 +1419,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 8a6e4147a680ad6c5fdd588468b6daac82349d2c -R d2cf53f7b50c768b631d5f18bba143b9 -U drh -Z 592370e14c792642f017f87ac074cb77 +P 1c2656c1d37906230edc142d3a4253b16b6e925f +R 6c0824142ba46339a29c32338146479b +U dan +Z e95289d1bfc22539e02b85ec76fd69c7 diff --git a/manifest.uuid b/manifest.uuid index 78b51cd18f..72144560be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1c2656c1d37906230edc142d3a4253b16b6e925f \ No newline at end of file +4a4385564dd3887a7953820b60c99d6ce289f96a \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index cdbcd2c8e0..81422f215d 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5955,7 +5955,12 @@ static int mkFullPathname( iOff = sqlite3Strlen30(zOut); zOut[iOff++] = '/'; } - if( (iOff+nPath+1)>nOut ) return SQLITE_CANTOPEN_BKPT; + if( (iOff+nPath+1)>nOut ){ + /* SQLite assumes that xFullPathname() nul-terminates the output buffer + ** even if it returns an error. */ + zOut[iOff] = '\0'; + return SQLITE_CANTOPEN_BKPT; + } sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); return SQLITE_OK; } @@ -6020,15 +6025,17 @@ static int unixFullPathname( nByte = osReadlink(zIn, zDel, nOut-1); if( nByte<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn); - }else if( zDel[0]!='/' ){ - int n; - for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); - if( nByte+n+1>nOut ){ - rc = SQLITE_CANTOPEN_BKPT; - }else{ - memmove(&zDel[n], zDel, nByte+1); - memcpy(zDel, zIn, n); - nByte += n; + }else{ + if( zDel[0]!='/' ){ + int n; + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + if( nByte+n+1>nOut ){ + rc = SQLITE_CANTOPEN_BKPT; + }else{ + memmove(&zDel[n], zDel, nByte+1); + memcpy(zDel, zIn, n); + nByte += n; + } } zDel[nByte] = '\0'; } @@ -6037,8 +6044,8 @@ static int unixFullPathname( zIn = zDel; } - if( rc==SQLITE_OK ){ - assert( zIn!=zOut || zIn[0]=='/' ); + assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' ); + if( rc==SQLITE_OK && zIn!=zOut ){ rc = mkFullPathname(zIn, zOut, nOut); } if( bLink==0 ) break; diff --git a/test/symlink.test b/test/symlink.test index e9e5f3c305..949102cf8a 100644 --- a/test/symlink.test +++ b/test/symlink.test @@ -181,7 +181,6 @@ do_test 4.4.0 { } {} do_test 4.4.1 { db close - breakpoint sqlite3 db w/test.db db eval { SELECT * FROM t1 } } {hello world} From fee981e5b97a79b26308c2dc3f946264e4ee8028 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jan 2016 17:08:22 +0000 Subject: [PATCH 034/107] Enhance fts5txt2db.tcl, a script used to generate fts5/fts4 databases for performance testing. FossilOrigin-Name: c646e40350e5aa91abcf52de61fb31275bad38f9 --- ext/fts5/tool/fts5txt2db.tcl | 200 +++++++++++++++++++++++++---------- manifest | 12 +-- manifest.uuid | 2 +- 3 files changed, 152 insertions(+), 62 deletions(-) diff --git a/ext/fts5/tool/fts5txt2db.tcl b/ext/fts5/tool/fts5txt2db.tcl index c22c5dae72..c6a58e6edd 100644 --- a/ext/fts5/tool/fts5txt2db.tcl +++ b/ext/fts5/tool/fts5txt2db.tcl @@ -1,13 +1,127 @@ -proc usage {} { - puts stderr "$::argv0 ?OPTIONS? DATABASE FILE1..." +#------------------------------------------------------------------------- +# Command line options processor. +# +proc command_line_error {O E {msg ""}} { + if {$msg != ""} { + puts stderr "Error: $msg" + puts stderr "" + } + + set L [list] + foreach o $O { + if {[llength $o]==1} { + lappend L [string toupper $o] + } + } + + puts stderr "Usage: $::argv0 ?SWITCHES? $L" puts stderr "" - puts stderr "Options are" - puts stderr " -fts5" - puts stderr " -fts4" - puts stderr " -colsize " - puts stderr { + puts stderr "Switches are:" + foreach o $O { + if {[llength $o]==3} { + foreach {a b c} $o {} + puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b] + } elseif {[llength $o]==2} { + foreach {a b} $o {} + puts stderr [format " -%-15s %s" $a $b] + } + } + puts stderr "" + puts stderr $E + exit -1 +} + +proc process_command_line {avar lArgs O E} { + + upvar $avar A + set zTrailing "" ;# True if ... is present in $O + set lPosargs [list] + + # Populate A() with default values. Also, for each switch in the command + # line spec, set an entry in the idx() array as follows: + # + # {tblname t1 "table name to use"} + # -> [set idx(-tblname) {tblname t1 "table name to use"} + # + # For each position parameter, append its name to $lPosargs. If the ... + # specifier is present, set $zTrailing to the name of the prefix. + # + foreach o $O { + set nm [lindex $o 0] + set nArg [llength $o] + switch -- $nArg { + 1 { + if {[string range $nm end-2 end]=="..."} { + set zTrailing [string range $nm 0 end-3] + } else { + lappend lPosargs $nm + } + } + 2 { + set A($nm) 0 + set idx(-$nm) $o + } + 3 { + set A($nm) [lindex $o 1] + set idx(-$nm) $o + } + default { + error "Error in command line specification" + } + } + } + + # Set explicitly specified option values + # + set nArg [llength $lArgs] + for {set i 0} {$i < $nArg} {incr i} { + set opt [lindex $lArgs $i] + if {[string range $opt 0 0]!="-" || $opt=="--"} break + set c [array names idx "${opt}*"] + if {[llength $c]==0} { command_line_error $O $E "Unrecognized option: $opt"} + if {[llength $c]>1} { command_line_error $O $E "Ambiguous option: $opt"} + + if {[llength $idx($c)]==3} { + if {$i==[llength $lArgs]-1} { + command_line_error $O $E "Option requires argument: $c" + } + incr i + set A([lindex $idx($c) 0]) [lindex $lArgs $i] + } else { + set A([lindex $idx($c) 0]) 1 + } + } + + # Deal with position arguments. + # + set nPosarg [llength $lPosargs] + set nRem [expr $nArg - $i] + if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} { + command_line_error $O $E + } + for {set j 0} {$j < $nPosarg} {incr j} { + set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]] + } + if {$zTrailing!=""} { + set A($zTrailing) [lrange $lArgs [expr $j+$i] end] + } +} +# End of command line options processor. +#------------------------------------------------------------------------- + + +process_command_line A $argv { + {fts5 "use fts5"} + {fts4 "use fts4"} + {colsize "10 10 10" "list of column sizes"} + {tblname "t1" "table name to create"} + {detail "full" "Fts5 detail mode to use"} + {repeat 1 "Load each file this many times"} + database + file... +} { This script is designed to create fts4/5 tables with more than one column. The -colsize option should be set to a Tcl list of integer values, one for each column in the table. Each value is the number of tokens that will be @@ -22,59 +136,27 @@ of the -colsize list. The next N2 are used for the second column of the first row, and so on. Rows are added to the table until the entire list of tokens is exhausted. } - exit -1 + +if {$A(fts4)} { + set A(fts) fts4 +} else { + set A(fts) fts5 } -set O(aColSize) [list 10 10 10] -set O(tblname) t1 -set O(fts) fts5 - - -set options_with_values {-colsize} - -for {set i 0} {$i < [llength $argv]} {incr i} { - set opt [lindex $argv $i] - if {[string range $opt 0 0]!="-"} break - - if {[lsearch $options_with_values $opt]>=0} { - incr i - if {$i==[llength $argv]} usage - set val [lindex $argv $i] - } - - switch -- $opt { - -colsize { - set O(aColSize) $val - } - - -fts4 { - set O(fts) fts4 - } - - -fts5 { - set O(fts) fts5 - } - } -} - -if {$i > [llength $argv]-2} usage -set O(db) [lindex $argv $i] -set O(files) [lrange $argv [expr $i+1] end] - -sqlite3 db $O(db) +sqlite3 db $A(database) # Create the FTS table in the db. Return a list of the table columns. # proc create_table {} { - global O + global A 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 $A(colsize)] set cols [lrange $cols 0 [expr $nCol-1]] - set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) (" + set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) (" append sql [join $cols ,] - append sql ");" + if {$A(fts)=="fts5"} { append sql ",detail=$A(detail));" } db eval $sql return $cols @@ -89,27 +171,35 @@ proc readfile {file} { split $data } +proc repeat {L n} { + set res [list] + for {set i 0} {$i < $n} {incr i} { + set res [concat $res $L] + } + set res +} + # Load all the data into a big list of tokens. # set tokens [list] -foreach f $O(files) { - set tokens [concat $tokens [readfile $f]] +foreach f $A(file) { + set tokens [concat $tokens [repeat [readfile $f] $A(repeat)]] } set N [llength $tokens] set i 0 set cols [create_table] -set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]" +set sql "INSERT INTO $A(tblname) VALUES(\$R([lindex $cols 0])" foreach c [lrange $cols 1 end] { - append sql ", \$A($c)" + append sql ", \$R($c)" } append sql ")" db eval BEGIN while {$i < $N} { - foreach c $cols s $O(aColSize) { - set A($c) [lrange $tokens $i [expr $i+$s-1]] + foreach c $cols s $A(colsize) { + set R($c) [lrange $tokens $i [expr $i+$s-1]] incr i $s } db eval $sql diff --git a/manifest b/manifest index fbcb4d2d1b..32c610bbaf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sfts5\sproblem\swith\susing\sboth\sxPhraseFirst()\sand\sxPhraseFirstColumn()\swithin\sa\ssingle\sstatement\sin\sdetail=col\smode. -D 2016-01-23T18:51:59.865 +C Enhance\sfts5txt2db.tcl,\sa\sscript\sused\sto\sgenerate\sfts5/fts4\sdatabases\sfor\sperformance\stesting. +D 2016-01-26T17:08:22.193 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -189,7 +189,7 @@ F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221 -F ext/fts5/tool/fts5txt2db.tcl c374c4c4797e8cdfadabdfaeeb5412dcd6686e84 +F ext/fts5/tool/fts5txt2db.tcl ae308338b2da1646dea456ab66706acdde8c714e F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c @@ -1419,7 +1419,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 ceccc9ad788fb4da9120915741995b9f088f85ff -R e7d7753020b6f70b109a92a8ac037ba7 +P 72d53699bf0dcdb9d2a22e229989d7435f061399 +R e572f7330a1bdca73a606e620f2735b9 U dan -Z 648645363fb131dd10e5d7321a173b9d +Z 9f71d918f9bd09bf4fa550347b1ed369 diff --git a/manifest.uuid b/manifest.uuid index 1891619c18..0db14bcc12 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72d53699bf0dcdb9d2a22e229989d7435f061399 \ No newline at end of file +c646e40350e5aa91abcf52de61fb31275bad38f9 \ No newline at end of file From 1c16bccb79888f775b4e1fbdca00d8f272afed17 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jan 2016 19:30:49 +0000 Subject: [PATCH 035/107] Improve the performance of fts5 column filters on detail=col tables. FossilOrigin-Name: 249a2d070c34bf884a04cb248b9691e239f2871c --- ext/fts5/fts5_index.c | 68 ++++++++++++++++++++++++++++++---- ext/fts5/test/fts5ac.test | 2 +- ext/fts5/test/fts5simple3.test | 44 ++++++++++++++++++++++ ext/fts5/tool/fts5speed.tcl | 2 + manifest | 17 +++++---- manifest.uuid | 2 +- 6 files changed, 117 insertions(+), 18 deletions(-) create mode 100644 ext/fts5/test/fts5simple3.test diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index e147199ef8..6d442de799 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5003,6 +5003,53 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ } } +/* +** xSetOutputs callback used when: detail=col when there is a column filter. +** +** * detail=col, +** * there is a column filter, and +** * the table contains 32 or fewer columns. +*/ +static void fts5IterSetOutputs_Col32(Fts5Iter *pIter, Fts5SegIter *pSeg){ + Fts5Colset *pColset = pIter->pColset; + pIter->base.iRowid = pSeg->iRowid; + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + assert( pColset ); + + fts5BufferZero(&pIter->poslist); + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ + int i; + int iPrev = 0; + u32 m = 0; + u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; + u8 *pEnd = (u8*)&a[pSeg->nPos]; + + while( aposlist.p; + for(i=0; inCol; i++){ + int iCol = pColset->aiCol[i]; + if( m & (1 << iCol) ){ + *a++ = (iCol - iPrev) + 2; + iPrev = iCol; + } + } + pIter->poslist.n = a - pIter->poslist.p; + + }else{ + fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); + } + + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; +} + /* ** xSetOutputs callback used by detail=col when there is a column filter. */ @@ -5083,9 +5130,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ } } -static void fts5IterSetOutputCb(Fts5Iter *pIter){ - int eDetail = pIter->pIndex->pConfig->eDetail; - if( eDetail==FTS5_DETAIL_NONE ){ +static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ + Fts5Config *pConfig = pIter->pIndex->pConfig; + if( pConfig->eDetail==FTS5_DETAIL_NONE ){ pIter->xSetOutputs = fts5IterSetOutputs_None; } @@ -5093,13 +5140,18 @@ static void fts5IterSetOutputCb(Fts5Iter *pIter){ pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; } - else if( eDetail==FTS5_DETAIL_FULL ){ + else if( pConfig->eDetail==FTS5_DETAIL_FULL ){ pIter->xSetOutputs = fts5IterSetOutputs_Full; } else{ - assert( eDetail==FTS5_DETAIL_COLUMNS ); - pIter->xSetOutputs = fts5IterSetOutputs_Col; + assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + if( pConfig->nCol<=32 ){ + pIter->xSetOutputs = fts5IterSetOutputs_Col32; + sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); + }else{ + pIter->xSetOutputs = fts5IterSetOutputs_Col; + } } } @@ -5166,8 +5218,8 @@ int sqlite3Fts5IndexQuery( if( p->rc==SQLITE_OK ){ Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; pRet->pColset = pColset; - fts5IterSetOutputCb(pRet); - if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + fts5IterSetOutputCb(&p->rc, pRet); + if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } if( p->rc ){ sqlite3Fts5IterClose(&pRet->base); diff --git a/ext/fts5/test/fts5ac.test b/ext/fts5/test/fts5ac.test index a5a522a466..61b3230772 100644 --- a/ext/fts5/test/fts5ac.test +++ b/ext/fts5/test/fts5ac.test @@ -158,8 +158,8 @@ foreach {tn2 sql} { #------------------------------------------------------------------------- # foreach {tn expr} { - 1.2 "a OR b" 1.1 "a AND b" + 1.2 "a OR b" 1.3 "o" 1.4 "b q" 1.5 "e a e" diff --git a/ext/fts5/test/fts5simple3.test b/ext/fts5/test/fts5simple3.test new file mode 100644 index 0000000000..b84a3e56dd --- /dev/null +++ b/ext/fts5/test/fts5simple3.test @@ -0,0 +1,44 @@ +# 2015 September 05 +# +# 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. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5simple3 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +fts5_aux_test_functions db + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col); + INSERT INTO t1 VALUES('a', 'b', 'c'); + INSERT INTO t1 VALUES('x', 'x', 'x'); +} + +do_execsql_test 1.1 { + SELECT rowid, fts5_test_collist(t1) FROM t1('a:a'); +} {1 0.0} + +do_execsql_test 1.2 { + SELECT rowid, fts5_test_collist(t1) FROM t1('b:x'); +} {2 0.1} + +do_execsql_test 1.3 { + SELECT rowid, fts5_test_collist(t1) FROM t1('b:a'); +} {} + + +finish_test + diff --git a/ext/fts5/tool/fts5speed.tcl b/ext/fts5/tool/fts5speed.tcl index 1b060ea759..8e1c7f3899 100644 --- a/ext/fts5/tool/fts5speed.tcl +++ b/ext/fts5/tool/fts5speed.tcl @@ -11,6 +11,8 @@ set Q { {1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:t*'"} {1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"} {1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"} + + {2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"} } proc usage {} { diff --git a/manifest b/manifest index 32c610bbaf..2e90cb8536 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sfts5txt2db.tcl,\sa\sscript\sused\sto\sgenerate\sfts5/fts4\sdatabases\sfor\sperformance\stesting. -D 2016-01-26T17:08:22.193 +C Improve\sthe\sperformance\sof\sfts5\scolumn\sfilters\son\sdetail=col\stables. +D 2016-01-26T19:30:49.768 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -103,7 +103,7 @@ F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 722d8717e3167dd05fa48af970352932052da318 +F ext/fts5/fts5_index.c b34b7257f73929dc1b25c420aad2453dcbe36128 F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -118,7 +118,7 @@ F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9 F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b -F ext/fts5/test/fts5ac.test dec95549e007dd9be52aa435cdcd0f08e14e64d0 +F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f F ext/fts5/test/fts5ad.test 0ddaa5b692ff220100ee396228838f4331399eaa F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c @@ -176,6 +176,7 @@ F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 +F ext/fts5/test/fts5simple3.test e671b36bc4dbd4f5095e66cb04473cba9f680f53 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 @@ -188,7 +189,7 @@ F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 -F ext/fts5/tool/fts5speed.tcl aaee41894b552df8fbf8616aad003b2ea9ba3221 +F ext/fts5/tool/fts5speed.tcl 47f0031e6ac564964f4f4805e439ea665e848df2 F ext/fts5/tool/fts5txt2db.tcl ae308338b2da1646dea456ab66706acdde8c714e F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 @@ -1419,7 +1420,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 72d53699bf0dcdb9d2a22e229989d7435f061399 -R e572f7330a1bdca73a606e620f2735b9 +P c646e40350e5aa91abcf52de61fb31275bad38f9 +R a44979856d96ea38951595ad6e15598a U dan -Z 9f71d918f9bd09bf4fa550347b1ed369 +Z a6d46df0ea079f8f36131bee8e2cf5b7 diff --git a/manifest.uuid b/manifest.uuid index 0db14bcc12..54ccb7acb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c646e40350e5aa91abcf52de61fb31275bad38f9 \ No newline at end of file +249a2d070c34bf884a04cb248b9691e239f2871c \ No newline at end of file From 18205c781d4bb15d5a26801844212f231a4aed9d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Jan 2016 20:08:50 +0000 Subject: [PATCH 036/107] Further minor performance improvements and code-size reductions related to fts5 column filters on detail=col tables. FossilOrigin-Name: b4ac61aeee976296e7719949cd4fb496147a29e8 --- ext/fts5/fts5_index.c | 119 +++++++++++++++--------------------------- manifest | 12 ++--- manifest.uuid | 2 +- 3 files changed, 50 insertions(+), 83 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 6d442de799..ca3feb86f7 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5004,96 +5004,63 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ } /* -** xSetOutputs callback used when: detail=col when there is a column filter. -** -** * detail=col, -** * there is a column filter, and -** * the table contains 32 or fewer columns. +** xSetOutputs callback used by detail=col when there is a column filter +** and there are 100 or more columns. Also called as a fallback from +** fts5IterSetOutputs_Col100 if the column-list spans more than one page. */ -static void fts5IterSetOutputs_Col32(Fts5Iter *pIter, Fts5SegIter *pSeg){ - Fts5Colset *pColset = pIter->pColset; - pIter->base.iRowid = pSeg->iRowid; - - assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - assert( pColset ); - +static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ fts5BufferZero(&pIter->poslist); - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ - int i; - int iPrev = 0; - u32 m = 0; - u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; - u8 *pEnd = (u8*)&a[pSeg->nPos]; - - while( aposlist.p; - for(i=0; inCol; i++){ - int iCol = pColset->aiCol[i]; - if( m & (1 << iCol) ){ - *a++ = (iCol - iPrev) + 2; - iPrev = iCol; - } - } - pIter->poslist.n = a - pIter->poslist.p; - - }else{ - fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); - } - + fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist); + pIter->base.iRowid = pSeg->iRowid; pIter->base.pData = pIter->poslist.p; pIter->base.nData = pIter->poslist.n; } /* -** xSetOutputs callback used by detail=col when there is a column filter. +** xSetOutputs callback used when: +** +** * detail=col, +** * there is a column filter, and +** * the table contains 100 or fewer columns. +** +** The last point is to ensure all column numbers are stored as +** single-byte varints. */ -static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ - Fts5Colset *pColset = pIter->pColset; - pIter->base.iRowid = pSeg->iRowid; +static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - assert( pColset ); + assert( pIter->pColset ); - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ - /* All data is stored on the current page. Populate the output - ** variables to point into the body of the page object. */ - Fts5PoslistWriter writer = {0}; - const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - int n = pSeg->nPos; - int iCol = 0; - int iCVal = pColset->aiCol[0]; - i64 iPos = 0; - int iOff = 0; + if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ + fts5IterSetOutputs_Col(pIter, pSeg); + }else{ + u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; + u8 *pEnd = (u8*)&a[pSeg->nPos]; + int iPrev = 0; + int *aiCol = pIter->pColset->aiCol; + int *aiColEnd = &aiCol[pIter->pColset->nCol]; - fts5BufferZero(&pIter->poslist); - while( 0==sqlite3Fts5PoslistNext64(a, n, &iOff, &iPos) ){ - while( iPos>=iCVal ){ - if( iPos==iCVal ){ - sqlite3Fts5PoslistWriterAppend(&pIter->poslist, &writer, iPos); - } - if( ++iCol>=pColset->nCol ) goto setoutputs_col_out; - assert( pColset->aiCol[iCol]>iCVal ); - iCVal = pColset->aiCol[iCol]; + u8 *aOut = pIter->poslist.p; + int iPrevOut = 0; + + pIter->base.iRowid = pSeg->iRowid; + + while( aposlist); - fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); - } - setoutputs_col_out: - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = aOut - pIter->poslist.p; + } } /* @@ -5146,8 +5113,8 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ else{ assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - if( pConfig->nCol<=32 ){ - pIter->xSetOutputs = fts5IterSetOutputs_Col32; + if( pConfig->nCol<=100 ){ + pIter->xSetOutputs = fts5IterSetOutputs_Col100; sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); }else{ pIter->xSetOutputs = fts5IterSetOutputs_Col; diff --git a/manifest b/manifest index 2e90cb8536..173bd3a03a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sfts5\scolumn\sfilters\son\sdetail=col\stables. -D 2016-01-26T19:30:49.768 +C Further\sminor\sperformance\simprovements\sand\scode-size\sreductions\srelated\sto\sfts5\scolumn\sfilters\son\sdetail=col\stables. +D 2016-01-26T20:08:50.348 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 1708a78eda223b6daa302b140037fcc214a779f9 @@ -103,7 +103,7 @@ F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c b34b7257f73929dc1b25c420aad2453dcbe36128 +F ext/fts5/fts5_index.c 5558bfbeaf364cc67f937e25753ceed8757cb6d1 F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1420,7 +1420,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 c646e40350e5aa91abcf52de61fb31275bad38f9 -R a44979856d96ea38951595ad6e15598a +P 249a2d070c34bf884a04cb248b9691e239f2871c +R a28f5f4bedd812396ab85ff0aefd35c4 U dan -Z a6d46df0ea079f8f36131bee8e2cf5b7 +Z 56fb7a3fddaab518f0c4eb551a124662 diff --git a/manifest.uuid b/manifest.uuid index 54ccb7acb1..708359e9ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -249a2d070c34bf884a04cb248b9691e239f2871c \ No newline at end of file +b4ac61aeee976296e7719949cd4fb496147a29e8 \ No newline at end of file From d5be6f01cd7aa0aaa10334c6df01fd8118126d42 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 27 Jan 2016 07:28:33 +0000 Subject: [PATCH 037/107] Support building for Windows 10 desktop using 'MinCore.lib'. FossilOrigin-Name: 4bf89891fbb076364dc45a6bf3246efa6bc33d5d --- Makefile.msc | 12 ++++++++++-- autoconf/Makefile.msc | 2 +- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/os_win.c | 35 ++++++++++++++++++++++++++--------- tool/mkmsvcmin.tcl | 2 +- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index ab0ba95d53..3427b8177a 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -890,7 +890,7 @@ LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib # When compiling for UAP, some extra linker options are also required. # -!IF $(FOR_UAP)!=0 +!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0 LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib LTLINKOPTS = $(LTLINKOPTS) mincore.lib !IFDEF PSDKLIBPATH @@ -1343,12 +1343,20 @@ FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 # Standard options to testfixture. # TESTOPTS = --verbose=file --output=test-out.txt + +# Extra targets for the "all" target that require Tcl. +# +!IF $(NO_TCL)==0 +ALL_TCL_TARGETS = libtclsqlite3.lib +!ELSE +ALL_TCL_TARGETS = +!ENDIF # <> # This is the default Makefile target. The objects listed here # are what get build when you type just "make" with no arguments. # -all: dll libsqlite3.lib shell libtclsqlite3.lib +all: dll libsqlite3.lib shell $(ALL_TCL_TARGETS) # Dynamic link library section. # diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index fce62b2b8a..598e6517ae 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -785,7 +785,7 @@ LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib # When compiling for UAP, some extra linker options are also required. # -!IF $(FOR_UAP)!=0 +!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0 LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib LTLINKOPTS = $(LTLINKOPTS) mincore.lib !IFDEF PSDKLIBPATH diff --git a/manifest b/manifest index a5a0c52194..07acca6779 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Performance\simprovements\sfor\sfts5,\sparticularly\sdetail=col\smode. -D 2016-01-26T20:19:55.225 +C Support\sbuilding\sfor\sWindows\s10\sdesktop\susing\s'MinCore.lib'. +D 2016-01-27T07:28:33.525 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 +F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 -F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 +F autoconf/Makefile.msc 2ce3b1565a52d7083a1dbf57a1706fd14cc1ee0c F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 @@ -332,7 +332,7 @@ F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d -F src/os_win.c 386fba30419e8458b13209781c2af5590eab2811 +F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b @@ -1380,7 +1380,7 @@ F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 -F tool/mkmsvcmin.tcl 93167a9e73383465b5716aa8dfa407409fccef1d +F tool/mkmsvcmin.tcl d57e6efc9428605f5418d0b235721ddf7b5d9c0b F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e @@ -1422,7 +1422,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 4003db4a49c6b623750e56f626fa492c8402067f b4ac61aeee976296e7719949cd4fb496147a29e8 -R 3b6b6d60ef77e3cea10b7a0c2c39f1b3 -U dan -Z 0416f9e7e1e3c46e17637bea5d350927 +P a3d7b8ac53f94d29a11362f193fd1967f30583df +R 626d84a8bdebb7b947f7c1e376ac97c5 +U mistachkin +Z 136b0599f548728406750a73608ec6f4 diff --git a/manifest.uuid b/manifest.uuid index 915fae58ae..20f348c1ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3d7b8ac53f94d29a11362f193fd1967f30583df \ No newline at end of file +4bf89891fbb076364dc45a6bf3246efa6bc33d5d \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index c54bfd6a90..eda6cf59fb 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -76,6 +76,10 @@ # define NTDDI_WINBLUE 0x06030000 #endif +#ifndef NTDDI_WINTHRESHOLD +# define NTDDI_WINTHRESHOLD 0x06040000 +#endif + /* ** Check to see if the GetVersionEx[AW] functions are deprecated on the ** target system. GetVersionEx was first deprecated in Win8.1. @@ -88,6 +92,19 @@ # endif #endif +/* +** Check to see if the CreateFileMappingA function is supported on the +** target system. It is unavailable when using "mincore.lib" on Win10. +** When compiling for Windows 10, always assume "mincore.lib" is in use. +*/ +#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD +# define SQLITE_WIN32_CREATEFILEMAPPINGA 0 +# else +# define SQLITE_WIN32_CREATEFILEMAPPINGA 1 +# endif +#endif + /* ** This constant should already be defined (in the "WinDef.h" SDK file). */ @@ -494,8 +511,9 @@ static struct win_syscall { #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) -#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ - (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)) +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \ + (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \ + SQLITE_WIN32_CREATEFILEMAPPINGA { "CreateFileMappingA", (SYSCALL)CreateFileMappingA, 0 }, #else { "CreateFileMappingA", (SYSCALL)0, 0 }, @@ -725,8 +743,7 @@ static struct win_syscall { #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) -#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ - SQLITE_WIN32_GETVERSIONEX +#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, #else { "GetVersionExA", (SYSCALL)0, 0 }, @@ -736,7 +753,7 @@ static struct win_syscall { LPOSVERSIONINFOA))aSyscall[34].pCurrent) #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ - defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX + SQLITE_WIN32_GETVERSIONEX { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, #else { "GetVersionExW", (SYSCALL)0, 0 }, @@ -1347,7 +1364,7 @@ DWORD sqlite3Win32Wait(HANDLE hObject){ ** the LockFileEx() API. */ -#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX +#if !SQLITE_WIN32_GETVERSIONEX # define osIsNT() (1) #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) # define osIsNT() (1) @@ -1368,7 +1385,7 @@ int sqlite3_win32_is_nt(void){ ** kernel. */ return 1; -#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX +#elif SQLITE_WIN32_GETVERSIONEX if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ #if defined(SQLITE_WIN32_HAS_ANSI) OSVERSIONINFOA sInfo; @@ -3952,7 +3969,7 @@ static int winShmMap( hMap = osCreateFileMappingW(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); -#elif defined(SQLITE_WIN32_HAS_ANSI) +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA hMap = osCreateFileMappingA(pShmNode->hFile.h, NULL, PAGE_READWRITE, 0, nByte, NULL ); @@ -4108,7 +4125,7 @@ static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); -#elif defined(SQLITE_WIN32_HAS_ANSI) +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect, (DWORD)((nMap>>32) & 0xffffffff), (DWORD)(nMap & 0xffffffff), NULL); diff --git a/tool/mkmsvcmin.tcl b/tool/mkmsvcmin.tcl index de01490c97..da0cd6283c 100644 --- a/tool/mkmsvcmin.tcl +++ b/tool/mkmsvcmin.tcl @@ -92,7 +92,7 @@ foreach i [lsort -integer [array names blocks]] { set data [string map [list " -I\$(TOP)\\src" ""] $data] set data [string map [list " /DEF:sqlite3.def" ""] $data] set data [string map [list " sqlite3.def" ""] $data] -set data [string map [list " libtclsqlite3.lib" ""] $data] +set data [string map [list " \$(ALL_TCL_TARGETS)" ""] $data] set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data] writeFile $toFileName $data From b89aeb6aa2cacdb57ef4bd73f980eb4f16ec52e4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Jan 2016 15:49:32 +0000 Subject: [PATCH 038/107] Add assert() statements on the nExtraDelete variable in vdbe.c to try to verify that the FORDELETE and IDXDELETE flags are being generated correctly. Those flags are not currently generated correctly, and so the assert()s trip on this check-in. FossilOrigin-Name: dde1db0dd2e2cf04706117629756c352b178ebb8 --- manifest | 25 ++++++++++++++----------- manifest.uuid | 2 +- src/delete.c | 11 +++++++---- src/insert.c | 11 ++++++----- src/vdbe.c | 34 ++++++++++++++++++++++++++++++++-- src/vdbeInt.h | 1 + test/e_changes.test | 1 + 7 files changed, 62 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 101db20db8..bf4b14906c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\srecent\strunk\senhancements. -D 2016-01-26T23:32:55.750 +C Add\sassert()\sstatements\son\sthe\snExtraDelete\svariable\sin\svdbe.c\sto\stry\sto\sverify\nthat\sthe\sFORDELETE\sand\sIDXDELETE\sflags\sare\sbeing\sgenerated\scorrectly.\s\sThose\nflags\sare\snot\scurrently\sgenerated\scorrectly,\sand\sso\sthe\sassert()s\strip\son\sthis\ncheck-in. +D 2016-01-27T15:49:32.327 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -13,7 +13,7 @@ F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/Makefile.msc 68ed752a809b611d97b95d8572a34fe6fd1196f1 F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 -F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa w autoconf/README +F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 @@ -299,7 +299,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c -F src/delete.c f02e46234c5fc86f6c03ae34dc0ba48e93cd5029 +F src/delete.c db231a9895681efed007c0887e38b49f4d1291a5 F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 @@ -308,7 +308,7 @@ F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c a00e6d8a843dc22e2c136df04e6300c4528d9b9f +F src/insert.c 410f52b9ef4603dc0aebb169b7cb6b3c60eda07e F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b @@ -412,9 +412,9 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 6039096edea4ed25f7b1e28aa5d46b0ee3ba73ef +F src/vdbe.c a27a3fdc65f5728c6e9bff49b6753fbf9d73c8c0 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 -F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 +F src/vdbeInt.h 40c728712a2975855a2ac6aac44bf02dfd4a4c30 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 @@ -595,7 +595,7 @@ F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716 F test/e_blobopen.test 234f960d90235a9b51ec3ca1e062e8541dd558d8 F test/e_blobwrite.test 615b405f29feb2cfb5a1f03dab7933258294fa26 -F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 +F test/e_changes.test d66e8c1e33f5ec61af32eda729c8a2475404e49b F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 @@ -1422,7 +1422,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 ac2cbadd8000947c097da5b00c00090fe58fdcff a3d7b8ac53f94d29a11362f193fd1967f30583df -R 7855243eb7d1aae3e5a98345ca05c333 +P 9a71d56dcea953cb965f1fdda9a8b8f158cdeff6 +R 3af2d64e2a860c6e0d1b5193b911b983 +T *branch * fordelete-assert +T *sym-fordelete-assert * +T -sym-btree-fordelete-flag * U drh -Z 6eda54656ca87ef44dc31ff7472a92ee +Z f5e1f3160ce620e13f32c1dda67a1107 diff --git a/manifest.uuid b/manifest.uuid index 7255a707a7..beafd3f9d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9a71d56dcea953cb965f1fdda9a8b8f158cdeff6 \ No newline at end of file +dde1db0dd2e2cf04706117629756c352b178ebb8 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 98c49c9930..b3143c5f72 100644 --- a/src/delete.c +++ b/src/delete.c @@ -479,13 +479,12 @@ 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, p5, iTabCur, - aToOpen, &iDataCur, &iIdxCur); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, + iTabCur, aToOpen, &iDataCur, &iIdxCur); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); @@ -724,9 +723,13 @@ void sqlite3GenerateRowDelete( if( count ){ sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } + if( eMode!=ONEPASS_OFF ){ + sqlite3VdbeChangeP5(v, OPFLAG_IDXDELETE); + p5 = OPFLAG_IDXDELETE; + } if( iIdxNoSeek>=0 ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); - if( eMode!=ONEPASS_OFF ) p5 = OPFLAG_IDXDELETE; + p5 = 0; } if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; sqlite3VdbeChangeP5(v, p5); diff --git a/src/insert.c b/src/insert.c index 8082bcb459..cbe933c221 100644 --- a/src/insert.c +++ b/src/insert.c @@ -1647,7 +1647,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 */ + u8 p5, /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */ 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 */ @@ -1682,15 +1682,16 @@ int sqlite3OpenTableAndIndices( for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); - if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){ - *piDataCur = iIdxCur; - } if( aToOpen==0 || aToOpen[i+1] ){ sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - sqlite3VdbeChangeP5(v, p5); VdbeComment((v, "%s", pIdx->zName)); } + if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ + if( piDataCur ) *piDataCur = iIdxCur; + }else{ + sqlite3VdbeChangeP5(v, p5); + } } if( iBase>pParse->nTab ) pParse->nTab = iBase; return i; diff --git a/src/vdbe.c b/src/vdbe.c index adbdab0652..8583bcd4ba 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -551,6 +551,9 @@ int sqlite3VdbeExec( Op *pOp = aOp; /* Current operation */ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) Op *pOrigOp; /* Value of pOp at the top of the loop */ +#endif +#ifdef SQLITE_DEBUG + int nExtraDelete = 0; /* Verifies FORDELETE and IDXDELETE flags */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ @@ -3392,6 +3395,9 @@ case OP_OpenWrite: pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; +#ifdef SQLITE_DEBUG + pCur->wrFlag = wrFlag; +#endif rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); pCur->pKeyInfo = pKeyInfo; /* Set the VdbeCursor.isTable variable. Previous versions of @@ -4390,10 +4396,24 @@ case OP_Delete: { assert( pC->movetoTarget==iKey ); } #endif - + + /* Only flags that can be set are SAVEPOISTION and IDXDELETE */ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_IDXDELETE))==0 ); assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); assert( OPFLAG_IDXDELETE==BTREE_IDXDELETE ); + +#ifdef SQLITE_DEBUG + if( pC->isEphemeral==0 + && (pOp->p5 & OPFLAG_IDXDELETE)==0 + && (pC->wrFlag & OPFLAG_FORDELETE)==0 + ){ + nExtraDelete++; + } + if( pOp->p2 & OPFLAG_NCHANGE ){ + nExtraDelete--; + } +#endif + rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; @@ -4939,7 +4959,16 @@ case OP_IdxDelete: { r.default_rc = 0; r.aMem = &aMem[pOp->p2]; #ifdef SQLITE_DEBUG - { int i; for(i=0; iisEphemeral==0 + && (pOp->p5 & OPFLAG_IDXDELETE)==0 + && (pC->wrFlag & OPFLAG_FORDELETE)==0 + ){ + nExtraDelete++; + } + } #endif rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ @@ -6762,6 +6791,7 @@ vdbe_return: testcase( nVmStep>0 ); p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; sqlite3VdbeLeave(p); + assert( nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b231cf908e..646cf31fed 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -82,6 +82,7 @@ struct VdbeCursor { u8 isTable; /* True for rowid tables. False for indexes */ #ifdef SQLITE_DEBUG u8 seekOp; /* Most recent seek operation on this cursor */ + u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ diff --git a/test/e_changes.test b/test/e_changes.test index a77e22a2ee..c4b4406f7b 100644 --- a/test/e_changes.test +++ b/test/e_changes.test @@ -65,6 +65,7 @@ foreach {tn schema} { UPDATE t1 SET b=b+1 WHERE a<5; } 5 +exit # Delete 4 rows do_changes_test 1.$tn.4 { DELETE FROM t1 WHERE a>6 From 127f720240d07433276e0ce98cb8426a23266467 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Jan 2016 16:17:41 +0000 Subject: [PATCH 039/107] Fix tests in fordelete.test to test for the BTREE_AUXDELETE flag. FossilOrigin-Name: bbd25cf179df5bda1fe729928d6746248f06e46f --- manifest | 17 ++++++------- manifest.uuid | 2 +- test/fordelete.test | 58 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index bf4b14906c..dfebd3f6ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sassert()\sstatements\son\sthe\snExtraDelete\svariable\sin\svdbe.c\sto\stry\sto\sverify\nthat\sthe\sFORDELETE\sand\sIDXDELETE\sflags\sare\sbeing\sgenerated\scorrectly.\s\sThose\nflags\sare\snot\scurrently\sgenerated\scorrectly,\sand\sso\sthe\sassert()s\strip\son\sthis\ncheck-in. -D 2016-01-27T15:49:32.327 +C Fix\stests\sin\sfordelete.test\sto\stest\sfor\sthe\sBTREE_AUXDELETE\sflag. +D 2016-01-27T16:17:41.726 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -642,7 +642,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 ba12ec1d27cc34a4c23db4446029126d773f3849 +F test/fordelete.test f794392f1768584609fa439f7528484dc04d3a03 F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -1422,10 +1422,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 9a71d56dcea953cb965f1fdda9a8b8f158cdeff6 -R 3af2d64e2a860c6e0d1b5193b911b983 -T *branch * fordelete-assert -T *sym-fordelete-assert * -T -sym-btree-fordelete-flag * -U drh -Z f5e1f3160ce620e13f32c1dda67a1107 +P dde1db0dd2e2cf04706117629756c352b178ebb8 +R 112344660260002964aa8c335bb07305 +U dan +Z e0043c886092534757bb67db359c02f9 diff --git a/manifest.uuid b/manifest.uuid index beafd3f9d6..2b4460a277 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dde1db0dd2e2cf04706117629756c352b178ebb8 \ No newline at end of file +bbd25cf179df5bda1fe729928d6746248f06e46f \ No newline at end of file diff --git a/test/fordelete.test b/test/fordelete.test index 1e860e8867..7a49b5cbfd 100644 --- a/test/fordelete.test +++ b/test/fordelete.test @@ -30,17 +30,49 @@ proc analyze_delete_program {sql} { } { set T($rootpage) $name } - - # Calculate the results. - set res [list] + + # For each OpenWrite instruction generated for the proposed DELETE + # statement, add the following array entries: + # + # $M() -> + # $O() -> "*" | "" + # + # The O() entry is set to "*" if the BTREE_FORDELETE flag is specified, + # or "" otherwise. + # db eval "EXPLAIN $sql" R { - if {$R(opcode) == "OpenWrite"} { - set obj $T($R(p2)) - if {"0x$R(p5)" & 0x08} { append obj *} - lappend res $obj + if {$R(opcode)=="OpenWrite"} { + set root $R(p2) + set csr $R(p1) + if {[info exists T($root)]} { set M($csr) $T($root) } + + set obj $T($root) + set O($obj) "" + if {"0x$R(p5)" & 0x08} { + set O($obj) * + } else { + set O($obj) "" + } } } + db eval "EXPLAIN $sql" R { + if {$R(opcode) == "Delete"} { + set csr $R(p1) + if {[info exists M($csr)]} { + set idxdelete [expr {("0x$R(p5)" & 0x04) ? 1 : 0}] + if {$idxdelete} { + append O($M($csr)) "+" + } + } + } + } + + set res [list] + foreach {k v} [array get O] { + lappend res "${k}${v}" + } + lsort $res } @@ -53,10 +85,10 @@ do_execsql_test 1.0 { } 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 } + 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 } @@ -68,8 +100,8 @@ do_execsql_test 2.0 { 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* } + 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* } From def19e3b48c4064f38e6c701469f5365962f1481 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 27 Jan 2016 16:26:25 +0000 Subject: [PATCH 040/107] Change the name of the BTREE_IDXDELETE flag to BTREE_AUXDELETE, to better reflect its purpose. FossilOrigin-Name: 1d3bf6bebdda9f96734bc139601e9b05344ea0b4 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/btree.c | 11 +++++++---- src/btree.h | 2 +- src/delete.c | 4 +--- src/sqliteInt.h | 2 +- src/vdbe.c | 20 +++++++++++--------- 7 files changed, 33 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index dfebd3f6ae..9790c25453 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stests\sin\sfordelete.test\sto\stest\sfor\sthe\sBTREE_AUXDELETE\sflag. -D 2016-01-27T16:17:41.726 +C Change\sthe\sname\sof\sthe\sBTREE_IDXDELETE\sflag\sto\sBTREE_AUXDELETE,\sto\sbetter\nreflect\sits\spurpose. +D 2016-01-27T16:26:25.226 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -290,8 +290,8 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 97cf881292e085ee71faf44f7167b6312965b562 -F src/btree.h c5dfbbc59226fa5fcc2b03befa85fe10ef23c1b5 +F src/btree.c 16edaf415a54a2fc9058e3bc47d0c894cd59635e +F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 @@ -299,7 +299,7 @@ F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c -F src/delete.c db231a9895681efed007c0887e38b49f4d1291a5 +F src/delete.c 33ed87dc0746b1f8ce186f62b608bf40801af9c0 F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 @@ -352,7 +352,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 0faffdeed20201bedb202cf6ec07f14b29158c66 +F src/sqliteInt.h 12ec54454fc0f1c25f5c7057423ada1a363b6db0 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c a27a3fdc65f5728c6e9bff49b6753fbf9d73c8c0 +F src/vdbe.c c367615fecb5fae8a39113ee2b6ecbab94e4bcd3 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 40c728712a2975855a2ac6aac44bf02dfd4a4c30 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1422,7 +1422,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 dde1db0dd2e2cf04706117629756c352b178ebb8 -R 112344660260002964aa8c335bb07305 -U dan -Z e0043c886092534757bb67db359c02f9 +P bbd25cf179df5bda1fe729928d6746248f06e46f +R 21474325914b9893f106ce3a1694990c +U drh +Z 6ce2f1bf15f4f84bace517d6cc10a5ac diff --git a/manifest.uuid b/manifest.uuid index 2b4460a277..d16254398c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bbd25cf179df5bda1fe729928d6746248f06e46f \ No newline at end of file +1d3bf6bebdda9f96734bc139601e9b05344ea0b4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 89144e7a84..04748e1b37 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8098,9 +8098,12 @@ end_insert: ** the next call to BtreeNext() or BtreePrev() moves it to the same row ** as it would have been on if the call to BtreeDelete() had been omitted. ** -** The BTREE_IDXDELETE bit of flags indicates that this is a delete of -** an index entry where the corresponding table row has already been deleted. -** The BTREE_IDXDELETE bit is a hint that is not used by this implementation, +** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes +** associated with a single table entry and its indexes. Only one of those +** deletes is considered the "primary" delete. The primary delete occurs +** on a cursor that is not a BTREE_FORDELETE cursor. All but one delete +** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag. +** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, ** but which might be used by alternative storage engines. */ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ @@ -8123,7 +8126,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); assert( pCur->eState==CURSOR_VALID ); - assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_IDXDELETE))==0 ); + assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); iCellDepth = pCur->iPage; iCellIdx = pCur->aiIdx[iCellDepth]; diff --git a/src/btree.h b/src/btree.h index 416faca651..30522e99e1 100644 --- a/src/btree.h +++ b/src/btree.h @@ -249,7 +249,7 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags); /* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ -#define BTREE_IDXDELETE 0x04 /* this is index, table row already deleted */ +#define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, diff --git a/src/delete.c b/src/delete.c index b3143c5f72..5b5a5e3cb1 100644 --- a/src/delete.c +++ b/src/delete.c @@ -724,12 +724,10 @@ void sqlite3GenerateRowDelete( sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } if( eMode!=ONEPASS_OFF ){ - sqlite3VdbeChangeP5(v, OPFLAG_IDXDELETE); - p5 = OPFLAG_IDXDELETE; + sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } if( iIdxNoSeek>=0 ){ sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); - p5 = 0; } if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; sqlite3VdbeChangeP5(v, p5); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9aeffe216c..364b7a352e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2862,7 +2862,7 @@ struct AuthContext { #define OPFLAG_P2ISREG 0x10 /* P2 to OP_Open** is a register number */ #define OPFLAG_PERMUTE 0x01 /* OP_Compare: use the permutation */ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete: keep cursor position */ -#define OPFLAG_IDXDELETE 0x04 /* OP_Delete: index in a DELETE op */ +#define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ /* * Each trigger present in the database schema is stored as an instance of diff --git a/src/vdbe.c b/src/vdbe.c index 8583bcd4ba..f6a7946e6f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -553,7 +553,7 @@ int sqlite3VdbeExec( Op *pOrigOp; /* Value of pOp at the top of the loop */ #endif #ifdef SQLITE_DEBUG - int nExtraDelete = 0; /* Verifies FORDELETE and IDXDELETE flags */ + int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ #endif int rc = SQLITE_OK; /* Value to return */ sqlite3 *db = p->db; /* The database */ @@ -4355,9 +4355,11 @@ case OP_InsertInt: { ** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be ** left in an undefined state. ** -** If the OPFLAG_IDXDELETE bit is set on P5, that indicates that this -** delete is on an index cursor where the corresponding table row has -** already been deleted. +** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this +** delete one of several associated with deleting a table row and all its +** associated index entries. Exactly one of those deletes is the "primary" +** delete. The others are all on OPFLAG_FORDELETE cursors or else are +** marked with the AUXDELETE flag. ** ** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row ** change count is incremented (otherwise not). @@ -4397,14 +4399,14 @@ case OP_Delete: { } #endif - /* Only flags that can be set are SAVEPOISTION and IDXDELETE */ - assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_IDXDELETE))==0 ); + /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ + assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); - assert( OPFLAG_IDXDELETE==BTREE_IDXDELETE ); + assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); #ifdef SQLITE_DEBUG if( pC->isEphemeral==0 - && (pOp->p5 & OPFLAG_IDXDELETE)==0 + && (pOp->p5 & OPFLAG_AUXDELETE)==0 && (pC->wrFlag & OPFLAG_FORDELETE)==0 ){ nExtraDelete++; @@ -4963,7 +4965,7 @@ case OP_IdxDelete: { int i; for(i=0; iisEphemeral==0 - && (pOp->p5 & OPFLAG_IDXDELETE)==0 + && (pOp->p5 & OPFLAG_AUXDELETE)==0 && (pC->wrFlag & OPFLAG_FORDELETE)==0 ){ nExtraDelete++; From 5a2412f418bf96767fb5bc9979ca678811f8d94d Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 27 Jan 2016 23:50:14 +0000 Subject: [PATCH 041/107] Match the MSVC batch build tool sub-routine 'fn_UnsetVariable' a bit more robust. FossilOrigin-Name: 1edd5f31b9e6f91bb5434055a539428c000f1084 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/build-all-msvc.bat | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 07acca6779..7bd8b070a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Support\sbuilding\sfor\sWindows\s10\sdesktop\susing\s'MinCore.lib'. -D 2016-01-27T07:28:33.525 +C Match\sthe\sMSVC\sbatch\sbuild\stool\ssub-routine\s'fn_UnsetVariable'\sa\sbit\smore\srobust. +D 2016-01-27T23:50:14.931 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1363,7 +1363,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633 -F tool/build-all-msvc.bat 204a039f985d5a4f4f9df3a3aa594fd17848c37e x +F tool/build-all-msvc.bat 6def0b5cebba36db69da8a92a9a31daf92714b4f x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1422,7 +1422,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 a3d7b8ac53f94d29a11362f193fd1967f30583df -R 626d84a8bdebb7b947f7c1e376ac97c5 +P 4bf89891fbb076364dc45a6bf3246efa6bc33d5d +R 9e8aa43303c9d43f019b8eceec782e78 U mistachkin -Z 136b0599f548728406750a73608ec6f4 +Z 8662626dcb0cb6b59115e089abf15292 diff --git a/manifest.uuid b/manifest.uuid index 20f348c1ae..60bd1f672e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4bf89891fbb076364dc45a6bf3246efa6bc33d5d \ No newline at end of file +1edd5f31b9e6f91bb5434055a539428c000f1084 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 87794132b6..30371177db 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -729,8 +729,9 @@ GOTO no_errors GOTO :EOF :fn_UnsetVariable - IF NOT "%1" == "" ( - SET %1= + SET VALUE=%1 + IF DEFINED VALUE ( + SET %VALUE%= CALL :fn_ResetErrorLevel ) GOTO :EOF From 00029a1add0f6e19b134b585bade4cbfefe1afa4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 28 Jan 2016 00:04:32 +0000 Subject: [PATCH 042/107] Minor correction to the batch tool changes in the previous check-in. FossilOrigin-Name: 7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/build-all-msvc.bat | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 7bd8b070a6..8dd79dc815 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Match\sthe\sMSVC\sbatch\sbuild\stool\ssub-routine\s'fn_UnsetVariable'\sa\sbit\smore\srobust. -D 2016-01-27T23:50:14.931 +C Minor\scorrection\sto\sthe\sbatch\stool\schanges\sin\sthe\sprevious\scheck-in. +D 2016-01-28T00:04:32.165 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1363,7 +1363,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633 -F tool/build-all-msvc.bat 6def0b5cebba36db69da8a92a9a31daf92714b4f x +F tool/build-all-msvc.bat 77f85f4268c2711d637c629610d0cf3df5338638 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1422,7 +1422,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 4bf89891fbb076364dc45a6bf3246efa6bc33d5d -R 9e8aa43303c9d43f019b8eceec782e78 +P 1edd5f31b9e6f91bb5434055a539428c000f1084 +R dd88757d0a47522dcabe5cdbe4d1c234 U mistachkin -Z 8662626dcb0cb6b59115e089abf15292 +Z b852cd61a6ae9681850058c67e7066b1 diff --git a/manifest.uuid b/manifest.uuid index 60bd1f672e..3c05b7f8a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1edd5f31b9e6f91bb5434055a539428c000f1084 \ No newline at end of file +7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 30371177db..2dd01004d5 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -732,6 +732,7 @@ GOTO no_errors SET VALUE=%1 IF DEFINED VALUE ( SET %VALUE%= + SET VALUE= CALL :fn_ResetErrorLevel ) GOTO :EOF From ba60fbb6216f1b0dd5625429b8c8d12de965c65a Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 28 Jan 2016 02:47:32 +0000 Subject: [PATCH 043/107] Fix for pthread detection in the configure scripts. FossilOrigin-Name: 47633ffdbfead3ce7b1f6560660df99f950d24f8 --- autoconf/configure.ac | 1 + configure | 56 +++++++++++++++++++++++++++++++++++++++++++ configure.ac | 1 + manifest | 18 +++++++------- manifest.uuid | 2 +- 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/autoconf/configure.ac b/autoconf/configure.ac index fcca148aea..9492530680 100644 --- a/autoconf/configure.ac +++ b/autoconf/configure.ac @@ -75,6 +75,7 @@ AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING( THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0 if test x"$enable_threadsafe" != "xno"; then THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1" + AC_SEARCH_LIBS(pthread_create, pthread) AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) fi AC_SUBST(THREADSAFE_FLAGS) diff --git a/configure b/configure index 951b719ed5..b2cb4d1308 100755 --- a/configure +++ b/configure @@ -10464,6 +10464,62 @@ fi if test "$SQLITE_THREADSAFE" = "1"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +$as_echo_n "checking for library containing pthread_create... " >&6; } +if ${ac_cv_search_pthread_create+:} 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 pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +for ac_lib in '' pthread; 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_pthread_create=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_pthread_create+:} false; then : + break +fi +done +if ${ac_cv_search_pthread_create+:} false; then : + +else + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +$as_echo "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutexattr_init" >&5 $as_echo_n "checking for library containing pthread_mutexattr_init... " >&6; } if ${ac_cv_search_pthread_mutexattr_init+:} false; then : diff --git a/configure.ac b/configure.ac index 26a60147dd..19f85dc875 100644 --- a/configure.ac +++ b/configure.ac @@ -194,6 +194,7 @@ fi AC_SUBST(SQLITE_THREADSAFE) if test "$SQLITE_THREADSAFE" = "1"; then + AC_SEARCH_LIBS(pthread_create, pthread) AC_SEARCH_LIBS(pthread_mutexattr_init, pthread) fi diff --git a/manifest b/manifest index 8dd79dc815..c2a27c575e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scorrection\sto\sthe\sbatch\stool\schanges\sin\sthe\sprevious\scheck-in. -D 2016-01-28T00:04:32.165 +C Fix\sfor\spthread\sdetection\sin\sthe\sconfigure\sscripts. +D 2016-01-28T02:47:32.836 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -14,7 +14,7 @@ F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 F autoconf/Makefile.msc 2ce3b1565a52d7083a1dbf57a1706fd14cc1ee0c F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa -F autoconf/configure.ac 7b1ea0dcaf49fafba262ce4b0ee8cb3281b555d1 +F autoconf/configure.ac 72a5e42beb090b32bca580285dc0ab3c4670adb8 F autoconf/tea/Makefile.in b438a7020446c8a8156e8d97c8914a04833da6fd F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 @@ -30,8 +30,8 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 42b71ad3fe21c9e88fa59e8458ca1a6bc72eb0c0 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure d57d3b9d5c66549e54a4a2960de9813142d30a5a x -F configure.ac c59513d560b3107995c73b9cc1e55bfd086c4764 +F configure 12d96e3798e612e0ffa53a7a8c4d7fb1090df80e x +F configure.ac a2224b1162f79848982d3618ac1deffcd94e88ec F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/lemon.html 334dbf6621b8fb8790297ec1abf3cfa4621709d1 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 @@ -1422,7 +1422,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 1edd5f31b9e6f91bb5434055a539428c000f1084 -R dd88757d0a47522dcabe5cdbe4d1c234 -U mistachkin -Z b852cd61a6ae9681850058c67e7066b1 +P 7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8 +R aa8b5eab35ce807961f68c0e84ef93a7 +U drh +Z c7a8f0aff80d4c386e53fd4da40e1b68 diff --git a/manifest.uuid b/manifest.uuid index 3c05b7f8a9..a8cb6444e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8 \ No newline at end of file +47633ffdbfead3ce7b1f6560660df99f950d24f8 \ No newline at end of file From d5cafb380e588ac0b2f18bfaa2008c9a90fb5996 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Jan 2016 08:58:45 +0000 Subject: [PATCH 044/107] Remove a duplicate "p->magic = VDBE_MAGIC_RUN;" line from vdbeaux.c. FossilOrigin-Name: 688eb3b400a3f2f8005c341e8259f4c1485cb0ed --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c2a27c575e..2864c79773 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\spthread\sdetection\sin\sthe\sconfigure\sscripts. -D 2016-01-28T02:47:32.836 +C Remove\sa\sduplicate\s"p->magic\s=\sVDBE_MAGIC_RUN;"\sline\sfrom\svdbeaux.c. +D 2016-01-28T08:58:45.702 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -416,7 +416,7 @@ F src/vdbe.c 3ffbcc413bf793e3f0b95b79ef2f4bd449a5b5a3 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 757f86e6fef8efb3dd4226cb31e2e82b9c44c883 +F src/vdbeaux.c fc8926c4232cd5c982f36197b1443212f265d927 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c 3bb1f1f03162e6d223da623714d8e93fcaeac658 @@ -1422,7 +1422,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 7c89d75de1e8d44d7ebd8eac1320b50dd6c221a8 -R aa8b5eab35ce807961f68c0e84ef93a7 -U drh -Z c7a8f0aff80d4c386e53fd4da40e1b68 +P 47633ffdbfead3ce7b1f6560660df99f950d24f8 +R cfc22f0fb66c12a8ff66ff6486e44028 +U dan +Z 6ad2591078bc40cf96572d242da40773 diff --git a/manifest.uuid b/manifest.uuid index a8cb6444e4..a99478065f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47633ffdbfead3ce7b1f6560660df99f950d24f8 \ No newline at end of file +688eb3b400a3f2f8005c341e8259f4c1485cb0ed \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e9be081a20..3bbc5aad53 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1790,7 +1790,6 @@ void sqlite3VdbeRewind(Vdbe *p){ p->pc = -1; p->rc = SQLITE_OK; p->errorAction = OE_Abort; - p->magic = VDBE_MAGIC_RUN; p->nChange = 0; p->cacheCtr = 1; p->minWriteFileFormat = 255; From e61bbf441746d6129c9bfb09ab70ccdd6bfc421f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Jan 2016 17:06:17 +0000 Subject: [PATCH 045/107] Modifications to ensure the nExtraDelete-related assert() statement does not fail. FossilOrigin-Name: f43ff8f82d6c1239e6f9a32e7716421c1180ac74 --- manifest | 16 +++++++-------- manifest.uuid | 2 +- src/vdbe.c | 32 +++++++++++------------------- test/fordelete.test | 48 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index 9790c25453..dc719b86ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sname\sof\sthe\sBTREE_IDXDELETE\sflag\sto\sBTREE_AUXDELETE,\sto\sbetter\nreflect\sits\spurpose. -D 2016-01-27T16:26:25.226 +C Modifications\sto\sensure\sthe\snExtraDelete-related\sassert()\sstatement\sdoes\snot\sfail. +D 2016-01-28T17:06:17.501 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c c367615fecb5fae8a39113ee2b6ecbab94e4bcd3 +F src/vdbe.c 66c429896ce44ebcbe199f1c7a592c12095158f0 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 40c728712a2975855a2ac6aac44bf02dfd4a4c30 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -642,7 +642,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 f794392f1768584609fa439f7528484dc04d3a03 +F test/fordelete.test 57ed9b953eeace09dd2eac3251b40bf9d6990aec F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -1422,7 +1422,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 bbd25cf179df5bda1fe729928d6746248f06e46f -R 21474325914b9893f106ce3a1694990c -U drh -Z 6ce2f1bf15f4f84bace517d6cc10a5ac +P 1d3bf6bebdda9f96734bc139601e9b05344ea0b4 +R 8c4c31e27c8a082a17d0a49af9f3ce1b +U dan +Z 9dc5d2517a8a4fb456754e0a3cfe77cf diff --git a/manifest.uuid b/manifest.uuid index d16254398c..b83d35e772 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d3bf6bebdda9f96734bc139601e9b05344ea0b4 \ No newline at end of file +f43ff8f82d6c1239e6f9a32e7716421c1180ac74 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f6a7946e6f..c2e70ea8b2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4405,14 +4405,16 @@ case OP_Delete: { assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); #ifdef SQLITE_DEBUG - if( pC->isEphemeral==0 - && (pOp->p5 & OPFLAG_AUXDELETE)==0 - && (pC->wrFlag & OPFLAG_FORDELETE)==0 - ){ - nExtraDelete++; - } - if( pOp->p2 & OPFLAG_NCHANGE ){ - nExtraDelete--; + if( p->pFrame==0 ){ + if( pC->isEphemeral==0 + && (pOp->p5 & OPFLAG_AUXDELETE)==0 + && (pC->wrFlag & OPFLAG_FORDELETE)==0 + ){ + nExtraDelete++; + } + if( pOp->p2 & OPFLAG_NCHANGE ){ + nExtraDelete--; + } } #endif @@ -4960,21 +4962,9 @@ case OP_IdxDelete: { r.nField = (u16)pOp->p3; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; -#ifdef SQLITE_DEBUG - { - int i; - for(i=0; iisEphemeral==0 - && (pOp->p5 & OPFLAG_AUXDELETE)==0 - && (pC->wrFlag & OPFLAG_FORDELETE)==0 - ){ - nExtraDelete++; - } - } -#endif rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ - rc = sqlite3BtreeDelete(pCrsr, 0); + rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); } assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; diff --git a/test/fordelete.test b/test/fordelete.test index 7a49b5cbfd..bc38a4c5e3 100644 --- a/test/fordelete.test +++ b/test/fordelete.test @@ -158,5 +158,53 @@ do_test 3.2 { } } {6 {} {} {}} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 4.0 { + CREATE TABLE log(x); + CREATE TABLE p1(one PRIMARY KEY, two); + + CREATE TRIGGER tr_bd BEFORE DELETE ON p1 BEGIN + INSERT INTO log VALUES('delete'); + END; + INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C'); + DELETE FROM p1 WHERE one = 'a'; +} + +reset_db +do_execsql_test 4.1 { + BEGIN TRANSACTION; + CREATE TABLE tbl(a PRIMARY KEY, b, c); + CREATE TABLE log(a, b, c); + INSERT INTO "tbl" VALUES(1,2,3); + CREATE TRIGGER the_trigger BEFORE DELETE ON tbl BEGIN + INSERT INTO log VALUES(1, 2,3); + END; + COMMIT; + DELETE FROM tbl WHERE a=1; +} + +reset_db +do_execsql_test 5.1 { + PRAGMA foreign_keys = 1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + CREATE TABLE t2( + c INTEGER PRIMARY KEY, + d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT + ); +} {} +do_execsql_test 5.2 { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t2 VALUES(1, 2); + SELECT * FROM t2; +} {1 2} +do_execsql_test 5.3 { + DELETE FROM t1 WHERE a = 2; +} {} + + finish_test From 895c00e16a0308b0e0fc9fb49c1c6fdc8713af46 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Jan 2016 18:22:46 +0000 Subject: [PATCH 046/107] Modify the order of terms in an "if" condition to avoid implicitly comparing a dangling pointer to NULL following an OOM error. FossilOrigin-Name: 5372f800835da61736a64dcee8b476bbe7ee2e46 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2864c79773..771dba7fa8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sduplicate\s"p->magic\s=\sVDBE_MAGIC_RUN;"\sline\sfrom\svdbeaux.c. -D 2016-01-28T08:58:45.702 +C Modify\sthe\sorder\sof\sterms\sin\san\s"if"\scondition\sto\savoid\simplicitly\scomparing\sa\sdangling\spointer\sto\sNULL\sfollowing\san\sOOM\serror. +D 2016-01-28T18:22:46.091 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -336,7 +336,7 @@ F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b -F src/parse.y caad1e98edeca6960493d0c60d31b76820dd7776 +F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 @@ -1422,7 +1422,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 47633ffdbfead3ce7b1f6560660df99f950d24f8 -R cfc22f0fb66c12a8ff66ff6486e44028 +P 688eb3b400a3f2f8005c341e8259f4c1485cb0ed +R e0b38fbf138d8fe5067019d9b4797980 U dan -Z 6ad2591078bc40cf96572d242da40773 +Z 338551eead62c92e7c871564cd38e428 diff --git a/manifest.uuid b/manifest.uuid index a99478065f..9de4b4f3bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -688eb3b400a3f2f8005c341e8259f4c1485cb0ed \ No newline at end of file +5372f800835da61736a64dcee8b476bbe7ee2e46 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index d6a587a2c8..846c2504b7 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1010,7 +1010,7 @@ expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);} ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ sqlite3 *db = pParse->db; - if( pY && pA && pY->op==TK_NULL ){ + if( pA && pY && pY->op==TK_NULL ){ pA->op = (u8)op; sqlite3ExprDelete(db, pA->pRight); pA->pRight = 0; From 98a4d5a7fa997ddabe04c1352acedfb080d0b506 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jan 2016 08:38:35 +0000 Subject: [PATCH 047/107] Avoid two more instances of pointer arithmetic on freed pointers. FossilOrigin-Name: 2910ef64097b890c9f8929bf609ea2827db7ac97 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/prepare.c | 2 +- src/vdbesort.c | 5 ++--- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 771dba7fa8..04ba39cdd8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sthe\sorder\sof\sterms\sin\san\s"if"\scondition\sto\savoid\simplicitly\scomparing\sa\sdangling\spointer\sto\sNULL\sfollowing\san\sOOM\serror. -D 2016-01-28T18:22:46.091 +C Avoid\stwo\smore\sinstances\sof\spointer\sarithmetic\son\sfreed\spointers. +D 2016-01-29T08:38:35.193 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -342,7 +342,7 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c 8ca7237428f372a04717d558555ea67ee1c5df93 +F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c @@ -419,7 +419,7 @@ F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c fc8926c4232cd5c982f36197b1443212f265d927 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 -F src/vdbesort.c 3bb1f1f03162e6d223da623714d8e93fcaeac658 +F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1422,7 +1422,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 688eb3b400a3f2f8005c341e8259f4c1485cb0ed -R e0b38fbf138d8fe5067019d9b4797980 +P 5372f800835da61736a64dcee8b476bbe7ee2e46 +R 3b0a4b2b0654f088a973292429d2f71d U dan -Z 338551eead62c92e7c871564cd38e428 +Z daf578eb367bf673fc68218c1dc6fe42 diff --git a/manifest.uuid b/manifest.uuid index 9de4b4f3bf..32fa4e2607 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5372f800835da61736a64dcee8b476bbe7ee2e46 \ No newline at end of file +2910ef64097b890c9f8929bf609ea2827db7ac97 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index acd50fcaf7..f8ad54665a 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -582,8 +582,8 @@ static int sqlite3Prepare( zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ sqlite3RunParser(pParse, zSqlCopy, &zErrMsg); - sqlite3DbFree(db, zSqlCopy); pParse->zTail = &zSql[pParse->zTail-zSqlCopy]; + sqlite3DbFree(db, zSqlCopy); }else{ pParse->zTail = &zSql[nBytes]; } diff --git a/src/vdbesort.c b/src/vdbesort.c index 22029aa6bf..380772ee16 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1821,6 +1821,7 @@ int sqlite3VdbeSorterWrite( if( nMin>pSorter->nMemory ){ u8 *aNew; + int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; int nNew = pSorter->nMemory * 2; while( nNew < nMin ) nNew = nNew*2; if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; @@ -1828,9 +1829,7 @@ int sqlite3VdbeSorterWrite( aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); if( !aNew ) return SQLITE_NOMEM; - pSorter->list.pList = (SorterRecord*)( - aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory) - ); + pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; pSorter->list.aMemory = aNew; pSorter->nMemory = nNew; } From 3b83f0cd8f8525672a2631c57cea897f95a13a10 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Jan 2016 16:57:06 +0000 Subject: [PATCH 048/107] Avoid unnecessary WHERE clause term tests when coding a join where one of the tables contains a OR constraint. FossilOrigin-Name: ab94603974a0ad5342e5aee27603162652e70492 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 4 +++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 04ba39cdd8..4caab7f68f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\stwo\smore\sinstances\sof\spointer\sarithmetic\son\sfreed\spointers. -D 2016-01-29T08:38:35.193 +C Avoid\sunnecessary\sWHERE\sclause\sterm\stests\swhen\scoding\sa\sjoin\swhere\sone\nof\sthe\stables\scontains\sa\sOR\sconstraint. +D 2016-01-29T16:57:06.008 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 8dee26eb181ea9daa8b1a4d96f34c0860aaf99bd +F src/wherecode.c 22a7fee2360c738533ce12615f487594849adc78 F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1422,7 +1422,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 5372f800835da61736a64dcee8b476bbe7ee2e46 -R 3b0a4b2b0654f088a973292429d2f71d -U dan -Z daf578eb367bf673fc68218c1dc6fe42 +P 2910ef64097b890c9f8929bf609ea2827db7ac97 +R a5e195d58a480f7623421e36c529b8b4 +U drh +Z 416f01dc8ffa44ad767f5afe8de92edc diff --git a/manifest.uuid b/manifest.uuid index 32fa4e2607..87b521ed65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2910ef64097b890c9f8929bf609ea2827db7ac97 \ No newline at end of file +ab94603974a0ad5342e5aee27603162652e70492 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 9d53a20a67..4fd7399efd 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1401,7 +1401,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( Expr *pExpr = pWC->a[iTerm].pExpr; if( &pWC->a[iTerm] == pTerm ) continue; if( ExprHasProperty(pExpr, EP_FromJoin) ) continue; - if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); + testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); + if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); pExpr = sqlite3ExprDup(db, pExpr, 0); From 83f0ab8087a16eadb29b74a7849a52230ac731b4 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jan 2016 18:04:31 +0000 Subject: [PATCH 049/107] Prepend "rc!=SQLITE_OK || " to the nExtraDelete assert() condition. FossilOrigin-Name: 2a055ed0afd56e8c6b17cfc31e7808debe9ec765 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dc719b86ce..8ccd1f3c1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modifications\sto\sensure\sthe\snExtraDelete-related\sassert()\sstatement\sdoes\snot\sfail. -D 2016-01-28T17:06:17.501 +C Prepend\s"rc!=SQLITE_OK\s||\s"\sto\sthe\snExtraDelete\sassert()\scondition. +D 2016-01-29T18:04:31.311 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 66c429896ce44ebcbe199f1c7a592c12095158f0 +F src/vdbe.c e86e100a3f90a861f28a5bda9c9abf1bca119a54 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 40c728712a2975855a2ac6aac44bf02dfd4a4c30 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1422,7 +1422,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 1d3bf6bebdda9f96734bc139601e9b05344ea0b4 -R 8c4c31e27c8a082a17d0a49af9f3ce1b +P f43ff8f82d6c1239e6f9a32e7716421c1180ac74 +R 089a2135f4238760de692cbeaf9edaeb U dan -Z 9dc5d2517a8a4fb456754e0a3cfe77cf +Z f28c932cf1fbf9988a116d4b713a0ec7 diff --git a/manifest.uuid b/manifest.uuid index b83d35e772..3bf3d8a23c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f43ff8f82d6c1239e6f9a32e7716421c1180ac74 \ No newline at end of file +2a055ed0afd56e8c6b17cfc31e7808debe9ec765 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c2e70ea8b2..c36802c300 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6783,7 +6783,9 @@ vdbe_return: testcase( nVmStep>0 ); p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; sqlite3VdbeLeave(p); - assert( nExtraDelete==0 || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); + assert( rc!=SQLITE_OK || nExtraDelete==0 + || sqlite3_strlike("DELETE%",p->zSql,0)!=0 + ); return rc; /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH From 47ab455c2bb5e8256181e46fadc53979943075c7 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Jan 2016 18:48:08 +0000 Subject: [PATCH 050/107] Remove a stray "exit" in a test script. FossilOrigin-Name: 10c88bf9f2c238abbbb54797ee2327ab72713e6f --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/e_changes.test | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8ccd1f3c1a..26f3353966 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prepend\s"rc!=SQLITE_OK\s||\s"\sto\sthe\snExtraDelete\sassert()\scondition. -D 2016-01-29T18:04:31.311 +C Remove\sa\sstray\s"exit"\sin\sa\stest\sscript. +D 2016-01-29T18:48:08.448 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 6fca5455aaecbd14479f33f091aa19df2d3d2969 @@ -595,7 +595,7 @@ F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716 F test/e_blobopen.test 234f960d90235a9b51ec3ca1e062e8541dd558d8 F test/e_blobwrite.test 615b405f29feb2cfb5a1f03dab7933258294fa26 -F test/e_changes.test d66e8c1e33f5ec61af32eda729c8a2475404e49b +F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 @@ -1422,7 +1422,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 f43ff8f82d6c1239e6f9a32e7716421c1180ac74 -R 089a2135f4238760de692cbeaf9edaeb -U dan -Z f28c932cf1fbf9988a116d4b713a0ec7 +P 2a055ed0afd56e8c6b17cfc31e7808debe9ec765 +R 4fbaa01893d53f4580e8296002d14aff +U drh +Z dbc978af0b86d437c82a817aee2df876 diff --git a/manifest.uuid b/manifest.uuid index 3bf3d8a23c..79ac026d59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a055ed0afd56e8c6b17cfc31e7808debe9ec765 \ No newline at end of file +10c88bf9f2c238abbbb54797ee2327ab72713e6f \ No newline at end of file diff --git a/test/e_changes.test b/test/e_changes.test index c4b4406f7b..a77e22a2ee 100644 --- a/test/e_changes.test +++ b/test/e_changes.test @@ -65,7 +65,6 @@ foreach {tn schema} { UPDATE t1 SET b=b+1 WHERE a<5; } 5 -exit # Delete 4 rows do_changes_test 1.$tn.4 { DELETE FROM t1 WHERE a>6 From de892d96604b09cf959cd317243a2176b3d9531a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jan 2016 19:29:45 +0000 Subject: [PATCH 051/107] Experimental attempt to make better use of covering indexes within OR queries. FossilOrigin-Name: a323ac3a9d42bd5cb38d724c7e1180584b91054c --- manifest | 26 +++++++++++++------------ manifest.uuid | 2 +- src/vdbe.c | 20 +++++++++++++++---- src/vdbeInt.h | 6 ++++-- src/vdbeaux.c | 8 +++++++- src/wherecode.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++- test/whereD.test | 31 +++++++++++++++++++++++++++++- 7 files changed, 121 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index abb80cb617..4025b2f01a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sWHERE\sclause\sterm\stests\swhen\scoding\sa\sjoin\swhere\sone\sof\sthe\stables\scontains\sa\sOR\sconstraint. -D 2016-01-29T18:11:04.923 +C Experimental\sattempt\sto\smake\sbetter\suse\sof\scovering\sindexes\swithin\sOR\squeries. +D 2016-01-29T19:29:45.658 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -412,11 +412,11 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 3ffbcc413bf793e3f0b95b79ef2f4bd449a5b5a3 +F src/vdbe.c 2e0c42bba0aee55b06b636feb5ad41d77c75abe3 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 -F src/vdbeInt.h 42eefa4f9e7432b9968d321b44e48821ec13b189 +F src/vdbeInt.h 91f22c4d54a2540fa0da64f04dd9d96969c0f0e0 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c fc8926c4232cd5c982f36197b1443212f265d927 +F src/vdbeaux.c 657402ba7d253963e3fca323c6ad9f7b29a9efb9 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 22a7fee2360c738533ce12615f487594849adc78 +F src/wherecode.c 1b2a96c425048bf96eb97ba49235c71f54917b1d F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1334,7 +1334,7 @@ F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 -F test/whereD.test 9eba1f9b18e5b19a0b0bcaae5e8c037260195f2b +F test/whereD.test 4b648b4a75911474b7b4dde08a7411b165e3fa39 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501 @@ -1422,8 +1422,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 2910ef64097b890c9f8929bf609ea2827db7ac97 ab94603974a0ad5342e5aee27603162652e70492 -R a5e195d58a480f7623421e36c529b8b4 -T +closed ab94603974a0ad5342e5aee27603162652e70492 -U drh -Z e540fd89ce55e7aa63a8bd5d9b52b2c8 +P 512caa1ad30e6f699e2d006d5ab7674d55d2c746 +R 7c9589ab5b77780aed167682522067f5 +T *branch * covering-or +T *sym-covering-or * +T -sym-trunk * +U dan +Z 8b3097dd603cdb6f18b5a640e7f1b04b diff --git a/manifest.uuid b/manifest.uuid index ebf0893a75..afc72f756f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -512caa1ad30e6f699e2d006d5ab7674d55d2c746 \ No newline at end of file +a323ac3a9d42bd5cb38d724c7e1180584b91054c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cfff895c30..8ad1a17c39 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2376,12 +2376,16 @@ case OP_Column: { u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ + pC = p->apCsr[pOp->p1]; p2 = pOp->p2; + + /* If the cursor cache is stale, bring it up-to-date */ + rc = sqlite3VdbeCursorMoveto(&pC, &p2); + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( p2nField ); aOffset = pC->aOffset; @@ -2390,8 +2394,6 @@ case OP_Column: { assert( pC->eCurType!=CURTYPE_SORTER ); pCrsr = pC->uc.pCursor; - /* If the cursor cache is stale, bring it up-to-date */ - rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; if( pC->cacheStatus!=p->cacheCtr ){ if( pC->nullRow ){ @@ -3846,7 +3848,7 @@ seek_not_found: break; } -/* Opcode: Seek P1 P2 * * * +/* Opcode: Seek P1 P2 P3 P4 * ** Synopsis: intkey=r[P2] ** ** P1 is an open table cursor and P2 is a rowid integer. Arrange @@ -3855,6 +3857,13 @@ seek_not_found: ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. +** +** P4 may contain an array of integers (type P4_INTARRAY) containing +** one entry for each column in the table P1 is open on. If so, then +** parameter P3 is a cursor open on a database index. If array entry +** a[i] is non-zero, then reading column (a[i]-1) from cursor P3 is +** equivalent to performing the deferred seek and then reading column i +** from P1. */ case OP_Seek: { /* in2 */ VdbeCursor *pC; @@ -3869,6 +3878,9 @@ case OP_Seek: { /* in2 */ pIn2 = &aMem[pOp->p2]; pC->movetoTarget = sqlite3VdbeIntValue(pIn2); pC->deferredMoveto = 1; + assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); + pC->aAltMap = pOp->p4.ai; + pC->pAltCursor = p->apCsr[pOp->p3]; break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b231cf908e..e1c6d06567 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -74,6 +74,7 @@ typedef struct AuxData AuxData; ** * A virtual table ** * A one-row "pseudotable" stored in a single register */ +typedef struct VdbeCursor VdbeCursor; struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ @@ -100,6 +101,8 @@ struct VdbeCursor { int seekResult; /* Result of previous sqlite3BtreeMoveto() */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ + VdbeCursor *pAltCursor; /* Set by OP_Seek */ + int *aAltMap; /* Set by OP_Seek */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif @@ -124,7 +127,6 @@ struct VdbeCursor { ** static element declared in the structure. nField total array slots for ** aType[] and nField+1 array slots for aOffset[] */ }; -typedef struct VdbeCursor VdbeCursor; /* ** When a sub-program is executed (OP_Program), a structure of this type @@ -423,7 +425,7 @@ struct Vdbe { void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); -int sqlite3VdbeCursorMoveto(VdbeCursor*); +int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); int sqlite3VdbeCursorRestore(VdbeCursor*); #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) void sqlite3VdbePrintOp(FILE*, int, Op*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3bbc5aad53..6e368cfdbd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3008,9 +3008,15 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ ** If the cursor is already pointing to the correct row and that row has ** not been deleted out from under the cursor, then this routine is a no-op. */ -int sqlite3VdbeCursorMoveto(VdbeCursor *p){ +int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ + VdbeCursor *p = *pp; if( p->eCurType==CURTYPE_BTREE ){ if( p->deferredMoveto ){ + if( p->aAltMap && p->aAltMap[*piCol] ){ + *pp = p->pAltCursor; + *piCol = p->aAltMap[*piCol] - 1; + return SQLITE_OK; + } return handleDeferredMoveto(p); } if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ diff --git a/src/wherecode.c b/src/wherecode.c index 4fd7399efd..eacd6d08d1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -746,6 +746,54 @@ static void codeCursorHint( # define codeCursorHint(A,B,C) /* No-op */ #endif /* SQLITE_ENABLE_CURSOR_HINTS */ +/* +** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains +** a rowid value just read from cursor iIdxCur, open on index pIdx. This +** function generates code to do a deferred seek of cursor iCur to the +** rowid stored in register iRowid. +** +** Normally, this is just: +** +** OP_Seek $iCur $iRowid +** +** However, if the scan currently being coded is a branch of an OR-loop and +** the statement currently being coded is a SELECT, then P3 of the OP_Seek +** is set to iIdxCur and P4 is set to point to an array of integers +** containing one entry for each column of the table cursor iCur is open +** on. For each table column, if the column is the i'th column of the +** index, then the corresponding array entry is set to (i+1). If the column +** does not appear in the index at all, the array entry is set to 0. +*/ +static void codeDeferredSeek( + WhereInfo *pWInfo, /* Where clause context */ + Index *pIdx, /* Index scan is using */ + int iCur, /* Cursor for IPK b-tree */ + int iRowid, /* Register containing rowid to seek to */ + int iIdxCur /* Index cursor */ +){ + Parse *pParse = pWInfo->pParse; /* Parse context */ + Vdbe *v = pParse->pVdbe; /* Vdbe to generate code within */ + + assert( iIdxCur>0 ); + assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); + + sqlite3VdbeAddOp3(v, OP_Seek, iCur, iRowid, iIdxCur); + if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE) + && sqlite3ParseToplevel(pParse)->writeMask==0 + ){ + int i; + Table *pTab = pIdx->pTable; + int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * pTab->nCol); + if( ai ){ + for(i=0; inColumn-1; i++){ + assert( pIdx->aiColumn[i]nCol ); + if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]] = i+1; + } + sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); + } + } +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -1232,7 +1280,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ - sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg); /* Deferred seek */ + codeDeferredSeek(pWInfo, pIdx, iCur, iRowidReg, iIdxCur); } }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); diff --git a/test/whereD.test b/test/whereD.test index 17fdac7017..1d70103a70 100644 --- a/test/whereD.test +++ b/test/whereD.test @@ -156,7 +156,7 @@ do_searchcount_test 3.4.4 { do_searchcount_test 3.5.1 { SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR rowid=4 -} {1 one 2 two search 3} +} {1 one 2 two search 2} do_searchcount_test 3.5.2 { SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR rowid=4 } {1 i 2 ii search 3} @@ -271,5 +271,34 @@ do_execsql_test 5.3 { c16=1 or c17=1; } {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {}} +#------------------------------------------------------------------------- +do_execsql_test 6.1 { + CREATE TABLE x1(a, b, c, d, e); + CREATE INDEX x1a ON x1(a); + CREATE INDEX x1bc ON x1(b, c); + CREATE INDEX x1cd ON x1(c, d); + + INSERT INTO x1 VALUES(1, 2, 3, 4, 'A'); + INSERT INTO x1 VALUES(5, 6, 7, 8, 'B'); + INSERT INTO x1 VALUES(9, 10, 11, 12, 'C'); + INSERT INTO x1 VALUES(13, 14, 15, 16, 'D'); +} + +do_searchcount_test 6.2.1 { + SELECT e FROM x1 WHERE b=2 OR c=7; +} {A B search 6} +do_searchcount_test 6.2.2 { + SELECT c FROM x1 WHERE b=2 OR c=7; +} {3 7 search 4} + +do_searchcount_test 6.3.1 { + SELECT e FROM x1 WHERE a=1 OR b=10; +} {A C search 6} +do_searchcount_test 6.3.2 { + SELECT c FROM x1 WHERE a=1 OR b=10; +} {3 11 search 5} +do_searchcount_test 6.3.3 { + SELECT rowid FROM x1 WHERE a=1 OR b=10; +} {1 3 search 4} finish_test From 945d302215abf771fd9f32e16aae6235e9663d61 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 29 Jan 2016 20:58:40 +0000 Subject: [PATCH 052/107] Different comment on the alternative cursor fields of VdbeCursor. FossilOrigin-Name: 6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/vdbeInt.h | 4 ++-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 4025b2f01a..48234554f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\sattempt\sto\smake\sbetter\suse\sof\scovering\sindexes\swithin\sOR\squeries. -D 2016-01-29T19:29:45.658 +C Different\scomment\son\sthe\salternative\scursor\sfields\sof\sVdbeCursor. +D 2016-01-29T20:58:40.189 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -414,7 +414,7 @@ F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c 2e0c42bba0aee55b06b636feb5ad41d77c75abe3 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 -F src/vdbeInt.h 91f22c4d54a2540fa0da64f04dd9d96969c0f0e0 +F src/vdbeInt.h 171fdc5f6af4eeb0ff0559dbf0a71244d726a670 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e F src/vdbeaux.c 657402ba7d253963e3fca323c6ad9f7b29a9efb9 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 @@ -1422,10 +1422,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 512caa1ad30e6f699e2d006d5ab7674d55d2c746 -R 7c9589ab5b77780aed167682522067f5 -T *branch * covering-or -T *sym-covering-or * -T -sym-trunk * -U dan -Z 8b3097dd603cdb6f18b5a640e7f1b04b +P a323ac3a9d42bd5cb38d724c7e1180584b91054c +R 2723ccd4873b2c7d653d59caf129ff2b +U drh +Z c70856a82eab5a5a2e181cbd70b2aa42 diff --git a/manifest.uuid b/manifest.uuid index afc72f756f..5612aca8d6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a323ac3a9d42bd5cb38d724c7e1180584b91054c \ No newline at end of file +6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index e1c6d06567..85c1a54512 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -101,8 +101,8 @@ struct VdbeCursor { int seekResult; /* Result of previous sqlite3BtreeMoveto() */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - VdbeCursor *pAltCursor; /* Set by OP_Seek */ - int *aAltMap; /* Set by OP_Seek */ + VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ + int *aAltMap; /* Mapping from table to index column numbers */ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif From eaa6cd87e8f81fa7dfdaa7dfc3c195f86cc9f096 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 29 Jan 2016 21:16:13 +0000 Subject: [PATCH 053/107] Add tests for the change on this branch. FossilOrigin-Name: 7cb697f82932a2581af69350117a29c9c8a2544f --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/whereD.test | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 48234554f0..b6defac38e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Different\scomment\son\sthe\salternative\scursor\sfields\sof\sVdbeCursor. -D 2016-01-29T20:58:40.189 +C Add\stests\sfor\sthe\schange\son\sthis\sbranch. +D 2016-01-29T21:16:13.360 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1334,7 +1334,7 @@ F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 -F test/whereD.test 4b648b4a75911474b7b4dde08a7411b165e3fa39 +F test/whereD.test 51366b07cb6f546cd30cc803f7e754f063b940de F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501 @@ -1422,7 +1422,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 a323ac3a9d42bd5cb38d724c7e1180584b91054c -R 2723ccd4873b2c7d653d59caf129ff2b -U drh -Z c70856a82eab5a5a2e181cbd70b2aa42 +P 6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686 +R 56d45fd4fdb64a9d12152455ff1bc2b7 +U dan +Z 8c3eb3de3f58e27647eefba9e15f6f8b diff --git a/manifest.uuid b/manifest.uuid index 5612aca8d6..c7e676919d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686 \ No newline at end of file +7cb697f82932a2581af69350117a29c9c8a2544f \ No newline at end of file diff --git a/test/whereD.test b/test/whereD.test index 1d70103a70..de0f9618d2 100644 --- a/test/whereD.test +++ b/test/whereD.test @@ -301,4 +301,40 @@ do_searchcount_test 6.3.3 { SELECT rowid FROM x1 WHERE a=1 OR b=10; } {1 3 search 4} +do_searchcount_test 6.4.1 { + SELECT a FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12 +} {1 9 search 6} +do_searchcount_test 6.4.2 { + SELECT b, c FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12 +} {2 3 10 11 search 5} +do_searchcount_test 6.4.3 { + SELECT rowid, c FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12 +} {1 3 3 11 search 4} + +do_searchcount_test 6.5.1 { + SELECT a FROM x1 WHERE rowid = 2 OR c=11 +} {5 9 search 3} +do_searchcount_test 6.5.2 { + SELECT d FROM x1 WHERE rowid = 2 OR c=11 +} {8 12 search 2} +do_searchcount_test 6.5.3 { + SELECT d FROM x1 WHERE c=11 OR rowid = 2 +} {12 8 search 2} +do_searchcount_test 6.5.4 { + SELECT a FROM x1 WHERE c=11 OR rowid = 2 +} {9 5 search 3} + +do_searchcount_test 6.6.1 { + SELECT rowid FROM x1 WHERE a=1 OR b=6 OR c=11 +} {1 2 3 search 6} +do_searchcount_test 6.6.2 { + SELECT c FROM x1 WHERE a=1 OR b=6 OR c=11 +} {3 7 11 search 7} +do_searchcount_test 6.6.3 { + SELECT c FROM x1 WHERE c=11 OR a=1 OR b=6 +} {11 3 7 search 7} +do_searchcount_test 6.6.4 { + SELECT c FROM x1 WHERE b=6 OR c=11 OR a=1 +} {7 11 3 search 7} + finish_test From b17020265b4f9ff369845e0fe1adc92c5858b975 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Jan 2016 00:45:18 +0000 Subject: [PATCH 054/107] Change the P4_INTARRAY so that always begins with a length integer. Print the content of the INTARRAY on EXPLAIN output. FossilOrigin-Name: 6c520d5726e80b4251338c43c405270d150ea81e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/select.c | 5 +++-- src/vdbe.c | 5 ++++- src/vdbeaux.c | 21 ++++++++++++++++++--- src/wherecode.c | 5 +++-- 6 files changed, 39 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index b6defac38e..6b3a40d3f9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sthe\schange\son\sthis\sbranch. -D 2016-01-29T21:16:13.360 +C Change\sthe\sP4_INTARRAY\sso\sthat\salways\sbegins\swith\sa\slength\sinteger.\s\sPrint\nthe\scontent\sof\sthe\sINTARRAY\son\sEXPLAIN\soutput. +D 2016-01-30T00:45:18.967 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -347,7 +347,7 @@ F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c c34292c8ce7fe69c7cf890d933834a22572bd301 +F src/select.c ea6f3b0c279aa37eb3701792d094673a7ad1bf88 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -412,11 +412,11 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 2e0c42bba0aee55b06b636feb5ad41d77c75abe3 +F src/vdbe.c 0686ef5ee103935548d1aa2c0c28e52f1ae6e5a8 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 171fdc5f6af4eeb0ff0559dbf0a71244d726a670 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 657402ba7d253963e3fca323c6ad9f7b29a9efb9 +F src/vdbeaux.c 108124021ed02fa4fc6f90a53dcaf58ac3bab941 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 1b2a96c425048bf96eb97ba49235c71f54917b1d +F src/wherecode.c 3c4757ae85e8237808a4ec1a25c513d83e1395e0 F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1422,7 +1422,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 6e3dcb6d7d960bb513d9a4a002b6cf5ab7159686 -R 56d45fd4fdb64a9d12152455ff1bc2b7 -U dan -Z 8c3eb3de3f58e27647eefba9e15f6f8b +P 7cb697f82932a2581af69350117a29c9c8a2544f +R e4149e0b983ab1835709b124e27b8f90 +U drh +Z 9c9e55627bd1b33e50ca6caf5cedf1b5 diff --git a/manifest.uuid b/manifest.uuid index c7e676919d..95c87154e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7cb697f82932a2581af69350117a29c9c8a2544f \ No newline at end of file +6c520d5726e80b4251338c43c405270d150ea81e \ No newline at end of file diff --git a/src/select.c b/src/select.c index ea4298e677..891b123543 100644 --- a/src/select.c +++ b/src/select.c @@ -2870,10 +2870,11 @@ static int multiSelectOrderBy( ** to the right and the left are evaluated, they use the correct ** collation. */ - aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy); + aPermute = sqlite3DbMallocRaw(db, sizeof(int)*(nOrderBy + 1)); if( aPermute ){ struct ExprList_item *pItem; - for(i=0, pItem=pOrderBy->a; ia; i<=nOrderBy; i++, pItem++){ assert( pItem->u.x.iOrderByCol>0 ); assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; diff --git a/src/vdbe.c b/src/vdbe.c index 8ad1a17c39..b7c0258ce6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2067,11 +2067,14 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** The permutation is only valid until the next OP_Compare that has ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should ** occur immediately prior to the OP_Compare. +** +** The first integer in the P4 integer array is the length of the array +** and does not become part of the permutation. */ case OP_Permutation: { assert( pOp->p4type==P4_INTARRAY ); assert( pOp->p4.ai ); - aPermute = pOp->p4.ai; + aPermute = pOp->p4.ai + 1; break; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6e368cfdbd..aaba2d3d0c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1288,7 +1288,21 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } #endif case P4_INTARRAY: { - sqlite3_snprintf(nTemp, zTemp, "intarray"); + int i, j; + int *ai = pOp->p4.ai; + int n = ai[0]; /* The first element of an INTARRAY is always the + ** count of the number of elements to follow */ + zTemp[0] = '['; + for(i=j=1; i1 ) zTemp[j++] = ','; + sqlite3_snprintf(nTemp-j, zTemp+j, "%d", ai[i]); + j += sqlite3Strlen30(zTemp+j); + } + if( ieCurType==CURTYPE_BTREE ){ if( p->deferredMoveto ){ - if( p->aAltMap && p->aAltMap[*piCol] ){ + int iMap; + if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){ *pp = p->pAltCursor; - *piCol = p->aAltMap[*piCol] - 1; + *piCol = iMap - 1; return SQLITE_OK; } return handleDeferredMoveto(p); diff --git a/src/wherecode.c b/src/wherecode.c index eacd6d08d1..fea397c543 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -783,11 +783,12 @@ static void codeDeferredSeek( ){ int i; Table *pTab = pIdx->pTable; - int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int) * pTab->nCol); + int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1)); if( ai ){ + ai[0] = pTab->nCol; for(i=0; inColumn-1; i++){ assert( pIdx->aiColumn[i]nCol ); - if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]] = i+1; + if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1; } sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); } From 5f4a686f8c5f0fa206418ab5970b61beb49aca7c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Jan 2016 12:50:25 +0000 Subject: [PATCH 055/107] Simplification and size reduction to the printf logic. Remove the bFlags parameter from sqlite3VXPrintf() and sqlite3XPrintf(). Use sqlite3XPrintf() instead of sqlite3_snprintf() for rendering P4 values in EXPLAIN output. FossilOrigin-Name: 0bdb41c45aa1cc8e5c136aaa6605d54b401483bd --- manifest | 29 +++++++------- manifest.uuid | 2 +- src/btree.c | 5 ++- src/build.c | 4 +- src/func.c | 3 +- src/printf.c | 48 +++++++++++----------- src/sqliteInt.h | 14 ++++--- src/treeview.c | 22 +++++------ src/vdbeaux.c | 103 +++++++++++++++++++----------------------------- src/vdbetrace.c | 14 +++---- src/wherecode.c | 16 ++++---- 11 files changed, 121 insertions(+), 139 deletions(-) diff --git a/manifest b/manifest index 9e56090535..d6048a60fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\suse\sof\scovering\sindexes\sin\sthe\sOR\soptimization. -D 2016-01-30T02:10:38.644 +C Simplification\sand\ssize\sreduction\sto\sthe\sprintf\slogic.\s\sRemove\sthe\sbFlags\nparameter\sfrom\ssqlite3VXPrintf()\sand\ssqlite3XPrintf().\s\sUse\ssqlite3XPrintf()\ninstead\sof\ssqlite3_snprintf()\sfor\srendering\sP4\svalues\sin\sEXPLAIN\soutput. +D 2016-01-30T12:50:25.204 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -290,10 +290,10 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c f224ae877fde69d1a9d430f502edaf8502752dbe +F src/btree.c 5e3435a31afbe9d839c5ee2630b8390712847415 F src/btree.h 526137361963e746949ab966a910c7f455ac6b04 F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c b4eba1e84752ec9cae7ff3dacd5a8b6d1ab8deb9 +F src/build.c 0510844c48d80732aead74b5727403b493dd1cd5 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -303,7 +303,7 @@ F src/delete.c 00af9f08a15ddc5cba5962d3d3e5bf2d67b2e7da F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 -F src/func.c ba6c03f9e440f5693086c08ee88e6e60212b3504 +F src/func.c 42b24923328f65849f52f1659efb2a0907ad78fd F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 @@ -343,7 +343,7 @@ F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead -F src/printf.c af589a27b7d40f6f4f704e9eea99f02f18ad6d32 +F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e @@ -352,7 +352,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 74e10a74116df0aec9d4a3e134f1a86cc34c2f14 +F src/sqliteInt.h 5b552cc0eee50d519e2e020f16abbc68947b0e59 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -406,7 +406,7 @@ F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 -F src/treeview.c 78842e90c1f71269e7a73a1d4221b6fe360bab66 +F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 @@ -416,11 +416,11 @@ F src/vdbe.c 0686ef5ee103935548d1aa2c0c28e52f1ae6e5a8 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 171fdc5f6af4eeb0ff0559dbf0a71244d726a670 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e -F src/vdbeaux.c 108124021ed02fa4fc6f90a53dcaf58ac3bab941 +F src/vdbeaux.c 221631e40111b5efa96ea557c6e2e7f62fd32b2a F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 -F src/vdbetrace.c 8befe829faff6d9e6f6e4dee5a7d3f85cc85f1a0 +F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 3c4757ae85e8237808a4ec1a25c513d83e1395e0 +F src/wherecode.c ef0d7019029624625416cdf32cc86604c970416f F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1422,8 +1422,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 512caa1ad30e6f699e2d006d5ab7674d55d2c746 6c520d5726e80b4251338c43c405270d150ea81e -R e4149e0b983ab1835709b124e27b8f90 -T +closed 6c520d5726e80b4251338c43c405270d150ea81e +P 9de3d7123007636aa97da1c70bc34344b0391078 +R 821c09620afbfbde9b9d6d9359867747 U drh -Z 625eb895cdbe3aba3d382c8d078d5321 +Z e57134af984dbdd8b3338eb2a295687a diff --git a/manifest.uuid b/manifest.uuid index a752c98cea..0454e6289a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9de3d7123007636aa97da1c70bc34344b0391078 \ No newline at end of file +0bdb41c45aa1cc8e5c136aaa6605d54b401483bd \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 4e6f6478af..481418a3dc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8805,9 +8805,9 @@ static void checkAppendMsg( sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ - sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2); + sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } - sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap); + sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap); va_end(ap); if( pCheck->errMsg.accError==STRACCUM_NOMEM ){ pCheck->mallocFailed = 1; @@ -9321,6 +9321,7 @@ char *sqlite3BtreeIntegrityCheck( sCheck.aPgRef = 0; sCheck.heap = 0; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); + sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } diff --git a/src/build.c b/src/build.c index 06f5433e37..be320b9c5a 100644 --- a/src/build.c +++ b/src/build.c @@ -4132,14 +4132,14 @@ void sqlite3UniqueConstraint( sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200); if( pIdx->aColExpr ){ - sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName); + sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName); }else{ for(j=0; jnKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); zCol = pTab->aCol[pIdx->aiColumn[j]].zName; if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2); - sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol); + sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol); } } zErr = sqlite3StrAccumFinish(&errMsg); diff --git a/src/func.c b/src/func.c index b927296782..982a8c2caa 100644 --- a/src/func.c +++ b/src/func.c @@ -239,7 +239,8 @@ static void printfFunc( x.nUsed = 0; x.apArg = argv+1; sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); - sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x); + str.printfFlags = SQLITE_PRINTF_SQLFUNC; + sqlite3XPrintf(&str, zFormat, &x); n = str.nChar; sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, SQLITE_DYNAMIC); diff --git a/src/printf.c b/src/printf.c index 969950c154..946161f64c 100644 --- a/src/printf.c +++ b/src/printf.c @@ -171,7 +171,6 @@ static char *getTextArg(PrintfArguments *p){ */ void sqlite3VXPrintf( StrAccum *pAccum, /* Accumulate results here */ - u32 bFlags, /* SQLITE_PRINTF_* flags */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ @@ -211,11 +210,11 @@ void sqlite3VXPrintf( char buf[etBUFSIZE]; /* Conversion buffer */ bufpt = 0; - if( bFlags ){ - if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ + if( pAccum->printfFlags ){ + if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){ pArgList = va_arg(ap, PrintfArguments*); } - useIntern = bFlags & SQLITE_PRINTF_INTERNAL; + useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL; }else{ bArgList = useIntern = 0; } @@ -766,9 +765,9 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ setStrAccumError(p, STRACCUM_TOOBIG); return N; }else{ - char *zOld = p->bMalloced ? p->zText : 0; + char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; - assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); + assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); szNew += N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, @@ -789,10 +788,10 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ } if( zNew ){ assert( p->zText!=0 || p->nChar==0 ); - if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); + if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); p->zText = zNew; p->nAlloc = sqlite3DbMallocSize(p->db, zNew); - p->bMalloced = 1; + p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ sqlite3StrAccumReset(p); setStrAccumError(p, STRACCUM_NOMEM); @@ -810,7 +809,7 @@ void sqlite3AppendChar(StrAccum *p, int N, char c){ if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } - assert( (p->zText==p->zBase)==(p->bMalloced==0) ); + assert( (p->zText==p->zBase)==!isMalloced(p) ); while( (N--)>0 ) p->zText[p->nChar++] = c; } @@ -828,7 +827,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; } - assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); + assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); } /* @@ -864,13 +863,13 @@ void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){ */ char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ - assert( (p->zText==p->zBase)==(p->bMalloced==0) ); + assert( (p->zText==p->zBase)==!isMalloced(p) ); p->zText[p->nChar] = 0; - if( p->mxAlloc>0 && p->bMalloced==0 ){ + if( p->mxAlloc>0 && !isMalloced(p) ){ p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( p->zText ){ memcpy(p->zText, p->zBase, p->nChar+1); - p->bMalloced = 1; + p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ setStrAccumError(p, STRACCUM_NOMEM); } @@ -883,10 +882,10 @@ char *sqlite3StrAccumFinish(StrAccum *p){ ** Reset an StrAccum string. Reclaim all malloced memory. */ void sqlite3StrAccumReset(StrAccum *p){ - assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) ); - if( p->bMalloced ){ + assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) ); + if( isMalloced(p) ){ sqlite3DbFree(p->db, p->zText); - p->bMalloced = 0; + p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; } p->zText = 0; } @@ -912,7 +911,7 @@ void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->nAlloc = n; p->mxAlloc = mx; p->accError = 0; - p->bMalloced = 0; + p->printfFlags = 0; } /* @@ -926,7 +925,8 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ assert( db!=0 ); sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); - sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap); + acc.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ db->mallocFailed = 1; @@ -966,7 +966,7 @@ char *sqlite3_vmprintf(const char *zFormat, va_list ap){ if( sqlite3_initialize() ) return 0; #endif sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); - sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); return z; } @@ -1011,7 +1011,7 @@ char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ } #endif sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); - sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3VXPrintf(&acc, zFormat, ap); return sqlite3StrAccumFinish(&acc); } char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ @@ -1042,7 +1042,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); - sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3VXPrintf(&acc, zFormat, ap); sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, sqlite3StrAccumFinish(&acc)); } @@ -1071,7 +1071,7 @@ void sqlite3DebugPrintf(const char *zFormat, ...){ char zBuf[500]; sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); - sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3VXPrintf(&acc, zFormat, ap); va_end(ap); sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); @@ -1084,9 +1084,9 @@ void sqlite3DebugPrintf(const char *zFormat, ...){ ** variable-argument wrapper around sqlite3VXPrintf(). The bFlags argument ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. */ -void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){ +void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - sqlite3VXPrintf(p, bFlags, zFormat, ap); + sqlite3VXPrintf(p, zFormat, ap); va_end(ap); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1a8a5d3a5b..b851399c59 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2978,10 +2978,16 @@ struct StrAccum { u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ u8 accError; /* STRACCUM_NOMEM or STRACCUM_TOOBIG */ - u8 bMalloced; /* zText points to allocated space */ + u8 printfFlags; /* SQLITE_PRINTF flags below */ }; #define STRACCUM_NOMEM 1 #define STRACCUM_TOOBIG 2 +#define SQLITE_PRINTF_INTERNAL 0x01 /* Internal-use-only converters allowed */ +#define SQLITE_PRINTF_SQLFUNC 0x02 /* SQL function arguments to VXPrintf */ +#define SQLITE_PRINTF_MALLOCED 0x04 /* True if xText is allocated space */ + +#define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) + /* ** A pointer to this structure is used to communicate information @@ -3298,10 +3304,8 @@ struct PrintfArguments { sqlite3_value **apArg; /* The argument values */ }; -#define SQLITE_PRINTF_INTERNAL 0x01 -#define SQLITE_PRINTF_SQLFUNC 0x02 -void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list); -void sqlite3XPrintf(StrAccum*, u32, const char*, ...); +void sqlite3VXPrintf(StrAccum*, const char*, va_list); +void sqlite3XPrintf(StrAccum*, const char*, ...); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) diff --git a/src/treeview.c b/src/treeview.c index a26e9e2b9f..2985804314 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -63,7 +63,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); } va_start(ap, zFormat); - sqlite3VXPrintf(&acc, 0, zFormat, ap); + sqlite3VXPrintf(&acc, zFormat, ap); va_end(ap); if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1); sqlite3StrAccumFinish(&acc); @@ -98,17 +98,17 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, 0, "%s", pCte->zName); + sqlite3XPrintf(&x, "%s", pCte->zName); if( pCte->pCols && pCte->pCols->nExpr>0 ){ char cSep = '('; int j; for(j=0; jpCols->nExpr; j++){ - sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName); + sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName); cSep = ','; } - sqlite3XPrintf(&x, 0, ")"); + sqlite3XPrintf(&x, ")"); } - sqlite3XPrintf(&x, 0, " AS"); + sqlite3XPrintf(&x, " AS"); sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -159,20 +159,20 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor); + sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor); if( pItem->zDatabase ){ - sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName); + sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName); }else if( pItem->zName ){ - sqlite3XPrintf(&x, 0, " %s", pItem->zName); + sqlite3XPrintf(&x, " %s", pItem->zName); } if( pItem->pTab ){ - sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName); + sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName); } if( pItem->zAlias ){ - sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias); + sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias); } if( pItem->fg.jointype & JT_LEFT ){ - sqlite3XPrintf(&x, 0, " LEFT-JOIN"); + sqlite3XPrintf(&x, " LEFT-JOIN"); } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, ipSrc->nSrc-1); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index aaba2d3d0c..619aada030 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1117,28 +1117,27 @@ static int displayComment( ** 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){ +static void displayP4Expr(StrAccum *p, Expr *pExpr){ const char *zOp = 0; - int n; switch( pExpr->op ){ case TK_STRING: - sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken); + sqlite3XPrintf(p, "%Q", pExpr->u.zToken); break; case TK_INTEGER: - sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue); + sqlite3XPrintf(p, "%d", pExpr->u.iValue); break; case TK_NULL: - sqlite3_snprintf(nTemp, zTemp, "NULL"); + sqlite3XPrintf(p, "NULL"); break; case TK_REGISTER: { - sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable); + sqlite3XPrintf(p, "r[%d]", pExpr->iTable); break; } case TK_COLUMN: { if( pExpr->iColumn<0 ){ - sqlite3_snprintf(nTemp, zTemp, "rowid"); + sqlite3XPrintf(p, "rowid"); }else{ - sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn); + sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn); } break; } @@ -1170,21 +1169,19 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ case TK_NOTNULL: zOp = "NOTNULL"; break; default: - sqlite3_snprintf(nTemp, zTemp, "%s", "expr"); + sqlite3XPrintf(p, "%s", "expr"); break; } if( zOp ){ - sqlite3_snprintf(nTemp, zTemp, "%s(", zOp); - n = sqlite3Strlen30(zTemp); - n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft); - if( npRight ){ - zTemp[n++] = ','; - n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight); + sqlite3XPrintf(p, "%s(", zOp); + displayP4Expr(p, pExpr->pLeft); + if( pExpr->pRight ){ + sqlite3StrAccumAppend(p, ",", 1); + displayP4Expr(p, pExpr->pRight); } - sqlite3_snprintf(nTemp-n, zTemp+n, ")"); + sqlite3StrAccumAppend(p, ")", 1); } - return sqlite3Strlen30(zTemp); } #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ @@ -1196,72 +1193,57 @@ static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){ */ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ char *zP4 = zTemp; + StrAccum x; assert( nTemp>=20 ); + sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); switch( pOp->p4type ){ case P4_KEYINFO: { - int i, j; + int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->aSortOrder!=0 ); - sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField); - i = sqlite3Strlen30(zTemp); + sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField); for(j=0; jnField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; - const char *zColl = pColl ? pColl->zName : "nil"; - int n = sqlite3Strlen30(zColl); - if( n==6 && memcmp(zColl,"BINARY",6)==0 ){ - zColl = "B"; - n = 1; - } - if( i+n>nTemp-7 ){ - memcpy(&zTemp[i],",...",4); - i += 4; - break; - } - zTemp[i++] = ','; - if( pKeyInfo->aSortOrder[j] ){ - zTemp[i++] = '-'; - } - memcpy(&zTemp[i], zColl, n+1); - i += n; + const char *zColl = pColl ? pColl->zName : ""; + if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; + sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl); } - zTemp[i++] = ')'; - zTemp[i] = 0; - assert( ip4.pExpr); + displayP4Expr(&x, pOp->p4.pExpr); break; } #endif case P4_COLLSEQ: { CollSeq *pColl = pOp->p4.pColl; - sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName); + sqlite3XPrintf(&x, "(%.20s)", pColl->zName); break; } case P4_FUNCDEF: { FuncDef *pDef = pOp->p4.pFunc; - sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #ifdef SQLITE_DEBUG case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; - sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } #endif case P4_INT64: { - sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64); + sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64); break; } case P4_INT32: { - sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i); + sqlite3XPrintf(&x, "%d", pOp->p4.i); break; } case P4_REAL: { - sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal); + sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { @@ -1269,11 +1251,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & MEM_Int ){ - sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); + sqlite3XPrintf(&x, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ - sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r); + sqlite3XPrintf(&x, "%.16g", pMem->u.r); }else if( pMem->flags & MEM_Null ){ - sqlite3_snprintf(nTemp, zTemp, "NULL"); + zP4 = "NULL"; }else{ assert( pMem->flags & MEM_Blob ); zP4 = "(blob)"; @@ -1283,30 +1265,24 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; - sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab); + sqlite3XPrintf(&x, "vtab:%p", pVtab); break; } #endif case P4_INTARRAY: { - int i, j; + int i; int *ai = pOp->p4.ai; int n = ai[0]; /* The first element of an INTARRAY is always the ** count of the number of elements to follow */ + for(i=1; i1 ) zTemp[j++] = ','; - sqlite3_snprintf(nTemp-j, zTemp+j, "%d", ai[i]); - j += sqlite3Strlen30(zTemp+j); - } - if( iflags & MEM_Null ){ sqlite3StrAccumAppend(&out, "NULL", 4); }else if( pVar->flags & MEM_Int ){ - sqlite3XPrintf(&out, 0, "%lld", pVar->u.i); + sqlite3XPrintf(&out, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ - sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r); + sqlite3XPrintf(&out, "%!.15g", pVar->u.r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 @@ -151,17 +151,17 @@ char *sqlite3VdbeExpandSql( while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif - sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z); + sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); + sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif #ifndef SQLITE_OMIT_UTF16 if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); #endif }else if( pVar->flags & MEM_Zero ){ - sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero); + sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); @@ -171,12 +171,12 @@ char *sqlite3VdbeExpandSql( if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; iz[i]&0xff); + sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff); } sqlite3StrAccumAppend(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut); + sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif } diff --git a/src/wherecode.c b/src/wherecode.c index fea397c543..d590203155 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -76,7 +76,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); + sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); } j = i; @@ -135,13 +135,13 @@ int sqlite3WhereExplainOneScan( sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ - sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId); + sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId); }else{ - sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName); + sqlite3XPrintf(&str, " TABLE %s", pItem->zName); } if( pItem->zAlias ){ - sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias); + sqlite3XPrintf(&str, " AS %s", pItem->zAlias); } if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; @@ -165,7 +165,7 @@ int sqlite3WhereExplainOneScan( } if( zFmt ){ sqlite3StrAccumAppend(&str, " USING ", 7); - sqlite3XPrintf(&str, 0, zFmt, pIdx->zName); + sqlite3XPrintf(&str, zFmt, pIdx->zName); explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ @@ -180,17 +180,17 @@ int sqlite3WhereExplainOneScan( assert( flags&WHERE_TOP_LIMIT); zRangeOp = "<"; } - sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); + sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s", + sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ - sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); + sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut)); }else{ sqlite3StrAccumAppend(&str, " (~1 row)", 9); } From af30fdf6ed259cd1b32b93b571eebe2836beae18 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Jan 2016 14:17:10 +0000 Subject: [PATCH 056/107] Output subtype information on register traces for PRAGMA vdbe_trace. FossilOrigin-Name: 96b780209cc95c3f3769bb880591380d94bfe38d --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbe.c | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ee7ea0da28..c42504832e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sBTREE_FORDELETE\sand\sBTREE_AUXDELETE\sflags\sto\sthe\sb-tree\slayer\sinterface\nand\suse\sthem.\s\sAdd\sassert()\sstatement\sto\sverify\sthat\sthey\sare\scorrect. -D 2016-01-30T13:32:30.291 +C Output\ssubtype\sinformation\son\sregister\straces\sfor\sPRAGMA\svdbe_trace. +D 2016-01-30T14:17:10.486 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c d9d2406d8a3baca537d2b05a2354afaa25e1ca84 +F src/vdbe.c bd4d2cabbafe49bd8e04d7bf57d8e480393268d9 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 716df83ac45b70ff000b515040ea606d0cb5d0f3 F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e @@ -1422,8 +1422,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 0bdb41c45aa1cc8e5c136aaa6605d54b401483bd 46080b0474363ca6594d2e5c249a280e2b4fc67a -R 54437ffc6525e4a6d93d7714d1fd6e2f -T +closed 46080b0474363ca6594d2e5c249a280e2b4fc67a +P 85c467041c9378cae3038756da815e9117ee8c7d +R 694b551c33162b646e920ddc57abdc60 U drh -Z 640a4b96ac8cc992fda6dcd328c886fd +Z fd54d0de297ea145965f78cad2cde9ad diff --git a/manifest.uuid b/manifest.uuid index 32d73b4945..6041e7c246 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -85c467041c9378cae3038756da815e9117ee8c7d \ No newline at end of file +96b780209cc95c3f3769bb880591380d94bfe38d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5ad8b11a46..ebb7e046fe 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -471,6 +471,7 @@ static void memTracePrint(Mem *p){ sqlite3VdbeMemPrettyPrint(p, zBuf); printf(" %s", zBuf); } + if( p->eSubtype ) printf(" subtype=0x%02x", p->eSubtype); } static void registerTrace(int iReg, Mem *p){ printf("REG[%d] = ", iReg); From 5b6c8e4e1d988c5e980106bb7c39aa969004de24 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Jan 2016 15:46:03 +0000 Subject: [PATCH 057/107] A different way to clear the subtype on VDBE registers when the value of the register is overwritten with new content. To fix [[f45ac567eaa9f93]. FossilOrigin-Name: 2e9fb1295cd31fc29c97444c3dec82fef68e939f --- manifest | 25 ++++++++++++++----------- manifest.uuid | 2 +- src/utf.c | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 11 ++++++++--- src/vdbeapi.c | 9 ++++++--- test/json103.test | 15 ++++++++++++++- 7 files changed, 45 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index c42504832e..16ab0b16b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Output\ssubtype\sinformation\son\sregister\straces\sfor\sPRAGMA\svdbe_trace. -D 2016-01-30T14:17:10.486 +C A\sdifferent\sway\sto\sclear\sthe\ssubtype\son\sVDBE\sregisters\swhen\sthe\svalue\sof\sthe\sregister\sis\soverwritten\swith\snew\scontent.\sTo\sfix\s[[f45ac567eaa9f93]. +D 2016-01-30T15:46:03.527 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -409,13 +409,13 @@ F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 -F src/utf.c 32d7f82aa921322f3e1c956f4b58f019ebd2c6b3 +F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c bd4d2cabbafe49bd8e04d7bf57d8e480393268d9 +F src/vdbe.c 49e0a224526f4307ab80e9d3a63697b28cf0cb21 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 -F src/vdbeInt.h 716df83ac45b70ff000b515040ea606d0cb5d0f3 -F src/vdbeapi.c ffae8f5af4570fbd548504e815e9fb7227f0822e +F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 +F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 F src/vdbeaux.c 221631e40111b5efa96ea557c6e2e7f62fd32b2a F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 @@ -834,7 +834,7 @@ F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863 F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a -F test/json103.test 923b288a0610ec86c0951778f7db19cbcca36ad1 +F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 @@ -1422,7 +1422,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 85c467041c9378cae3038756da815e9117ee8c7d -R 694b551c33162b646e920ddc57abdc60 -U drh -Z fd54d0de297ea145965f78cad2cde9ad +P 96b780209cc95c3f3769bb880591380d94bfe38d +R bd3d63263e82ae4209cc8f920c59f1ec +T *branch * clear-subtype-flag +T *sym-clear-subtype-flag * +T -sym-trunk * +U dan +Z b20671d59699e15a0872203a064b7cf5 diff --git a/manifest.uuid b/manifest.uuid index 6041e7c246..5e49703813 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96b780209cc95c3f3769bb880591380d94bfe38d \ No newline at end of file +2e9fb1295cd31fc29c97444c3dec82fef68e939f \ No newline at end of file diff --git a/src/utf.c b/src/utf.c index ee367c1399..e42ab418ad 100644 --- a/src/utf.c +++ b/src/utf.c @@ -316,7 +316,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ c = pMem->flags; sqlite3VdbeMemRelease(pMem); - pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask); + pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype)); pMem->enc = desiredEnc; pMem->z = (char*)zOut; pMem->zMalloc = pMem->z; diff --git a/src/vdbe.c b/src/vdbe.c index ebb7e046fe..c6ae836a28 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -471,7 +471,7 @@ static void memTracePrint(Mem *p){ sqlite3VdbeMemPrettyPrint(p, zBuf); printf(" %s", zBuf); } - if( p->eSubtype ) printf(" subtype=0x%02x", p->eSubtype); + if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); } static void registerTrace(int iReg, Mem *p){ printf("REG[%d] = ", iReg); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 497beb87d5..839c2039be 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -238,7 +238,7 @@ struct Mem { #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ -#define MEM_TypeMask 0x01ff /* Mask of type bits */ +#define MEM_TypeMask 0x81ff /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of @@ -252,11 +252,18 @@ struct Mem { #define MEM_Ephem 0x1000 /* Mem.z points to an ephemeral string */ #define MEM_Agg 0x2000 /* Mem.z points to an agg function context */ #define MEM_Zero 0x4000 /* Mem.i contains count of 0s appended to blob */ +#define MEM_Subtype 0x8000 /* Mem.eSubtype is valid */ #ifdef SQLITE_OMIT_INCRBLOB #undef MEM_Zero #define MEM_Zero 0x0000 #endif +/* Return TRUE if Mem X contains dynamically allocated content - anything +** that needs to be deallocated to avoid a leak. +*/ +#define VdbeMemDynamic(X) \ + (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) + /* ** Clear any existing type flags from a Mem and replace them with f */ @@ -472,8 +479,6 @@ int sqlite3VdbeMemNumerify(Mem*); void sqlite3VdbeMemCast(Mem*,u8,u8); int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); -#define VdbeMemDynamic(X) \ - (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0) int sqlite3VdbeMemFinalize(Mem*, FuncDef*); const char *sqlite3OpcodeName(int); int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 4bc912b940..0a15633ddf 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -188,7 +188,8 @@ sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ return sqlite3VdbeIntValue((Mem*)pVal); } unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ - return ((Mem*)pVal)->eSubtype; + Mem *pMem = (Mem*)pVal; + return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); @@ -369,8 +370,10 @@ void sqlite3_result_null(sqlite3_context *pCtx){ sqlite3VdbeMemSetNull(pCtx->pOut); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - pCtx->pOut->eSubtype = eSubtype & 0xff; + Mem *pOut = pCtx->pOut; + assert( sqlite3_mutex_held(pOut->db->mutex) ); + pOut->eSubtype = eSubtype & 0xff; + pOut->flags |= MEM_Subtype; } void sqlite3_result_text( sqlite3_context *pCtx, diff --git a/test/json103.test b/test/json103.test index 0f0241e6fc..d7d12e3378 100644 --- a/test/json103.test +++ b/test/json103.test @@ -60,6 +60,19 @@ do_execsql_test json103-220 { WHERE rowid<7 GROUP BY b ORDER BY b; } {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}} - +# ticket https://www.sqlite.org/src/info/f45ac567eaa9f93c 2016-01-30 +# Invalid JSON generated by json_group_array() +# +# The underlying problem is a failure to reset Mem.eSubtype +# +do_execsql_test json103-300 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1 VALUES(1),('abc'); + SELECT + json_group_array(x), + json_group_array(json_object('x',x)) + FROM t1; +} {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}} finish_test From 784c1b93fbf5f206878d9fec62dd3d418b0e678d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 30 Jan 2016 16:59:56 +0000 Subject: [PATCH 058/107] Merge the implementation of OP_IdxRowid and OP_Seek so that OP_Seek no longer requires the rowid register and a separate OP_IdxRowid call. Shorter and faster prepared statements result. FossilOrigin-Name: 9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74 --- manifest | 15 ++++--- manifest.uuid | 2 +- src/vdbe.c | 103 +++++++++++++++++++++++++----------------------- src/wherecode.c | 11 +++--- 4 files changed, 66 insertions(+), 65 deletions(-) diff --git a/manifest b/manifest index df7711094d..d850d9282e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\shonor\sthe\sregister\ssubtype\svalue\sif\sthe\sMEM_Subtype\sflag\sis\sset.\nRevised\sand\simproved\sfix\sfor\sticket\s[f45ac567eaa9f9]. -D 2016-01-30T15:52:39.136 +C Merge\sthe\simplementation\sof\sOP_IdxRowid\sand\sOP_Seek\sso\sthat\sOP_Seek\sno\slonger\nrequires\sthe\srowid\sregister\sand\sa\sseparate\sOP_IdxRowid\scall.\s\sShorter\sand\nfaster\sprepared\sstatements\sresult. +D 2016-01-30T16:59:56.592 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 49e0a224526f4307ab80e9d3a63697b28cf0cb21 +F src/vdbe.c 73f0f61eb5556e430487671a557d032ecac52240 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c ef0d7019029624625416cdf32cc86604c970416f +F src/wherecode.c 7ea737b14e7a35d7f55cbad589a29aa49dfe3f7a F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1422,8 +1422,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 96b780209cc95c3f3769bb880591380d94bfe38d 2e9fb1295cd31fc29c97444c3dec82fef68e939f -R bd3d63263e82ae4209cc8f920c59f1ec -T +closed 2e9fb1295cd31fc29c97444c3dec82fef68e939f +P 1f4c667f37d63fc3ef2e8f2581ecd3a66c054426 +R c807c9436e91d8aabdffdea0ecd68c4e U drh -Z 5703eae66c478a55119b68d54c8bb9ef +Z a3f05d9c2a4721d817f24f533822e83f diff --git a/manifest.uuid b/manifest.uuid index f4551f775a..01040f34b0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1f4c667f37d63fc3ef2e8f2581ecd3a66c054426 \ No newline at end of file +9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c6ae836a28..a1e59e1170 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3857,42 +3857,6 @@ seek_not_found: } break; } - -/* Opcode: Seek P1 P2 P3 P4 * -** Synopsis: intkey=r[P2] -** -** P1 is an open table cursor and P2 is a rowid integer. Arrange -** for P1 to move so that it points to the rowid given by P2. -** -** This is actually a deferred seek. Nothing actually happens until -** the cursor is used to read a record. That way, if no reads -** occur, no unnecessary I/O happens. -** -** P4 may contain an array of integers (type P4_INTARRAY) containing -** one entry for each column in the table P1 is open on. If so, then -** parameter P3 is a cursor open on a database index. If array entry -** a[i] is non-zero, then reading column (a[i]-1) from cursor P3 is -** equivalent to performing the deferred seek and then reading column i -** from P1. -*/ -case OP_Seek: { /* in2 */ - VdbeCursor *pC; - - assert( pOp->p1>=0 && pOp->p1nCursor ); - pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); - assert( pC->uc.pCursor!=0 ); - assert( pC->isTable ); - pC->nullRow = 0; - pIn2 = &aMem[pOp->p2]; - pC->movetoTarget = sqlite3VdbeIntValue(pIn2); - pC->deferredMoveto = 1; - assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); - pC->aAltMap = pOp->p4.ai; - pC->pAltCursor = p->apCsr[pOp->p3]; - break; -} /* Opcode: Found P1 P2 P3 P4 * @@ -4987,6 +4951,25 @@ case OP_IdxDelete: { break; } +/* Opcode: Seek P1 * P3 P4 * +** Synopsis: Move P3 to P1.rowid +** +** P1 is an open index cursor and P3 is a cursor on the corresponding +** table. This opcode does a deferred seek of the P3 table cursor +** to the row that corresponds to the current row of P1. +** +** This is a deferred seek. Nothing actually happens until +** the cursor is used to read a record. That way, if no reads +** occur, no unnecessary I/O happens. +** +** P4 may be an array of integers (type P4_INTARRAY) containing +** one entry for each column in the P3 table. If array entry a[i] +** is non-zero, then reading column (a[i]-1) from cursor P3 is +** equivalent to performing the deferred seek and then reading column i +** from P1. This information is stored in P3 and used to redirect +** reads against P3 over to P1, thus possibly avoiding the need to +** seek and read cursor P3. +*/ /* Opcode: IdxRowid P1 P2 * * * ** Synopsis: r[P2]=rowid ** @@ -4996,37 +4979,57 @@ case OP_IdxDelete: { ** ** See also: Rowid, MakeRecord. */ +case OP_Seek: case OP_IdxRowid: { /* out2 */ - BtCursor *pCrsr; - VdbeCursor *pC; - i64 rowid; + VdbeCursor *pC; /* The P1 index cursor */ + VdbeCursor *pTabCur; /* The P2 table cursor (OP_Seek only) */ + i64 rowid; /* Rowid that P1 current points to */ - pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); - pCrsr = pC->uc.pCursor; - assert( pCrsr!=0 ); - pOut->flags = MEM_Null; + assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); assert( pC->deferredMoveto==0 ); + assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); + + /* The IdxRowid and Seek opcodes are combined because of the commonality + ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ + rc = sqlite3VdbeCursorRestore(pC); /* sqlite3VbeCursorRestore() can only fail if the record has been deleted - ** out from under the cursor. That will never happend for an IdxRowid - ** opcode, hence the NEVER() arround the check of the return value. - */ - rc = sqlite3VdbeCursorRestore(pC); + ** out from under the cursor. That will never happens for an IdxRowid + ** or Seek opcode */ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ - rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid); + rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pOut->u.i = rowid; - pOut->flags = MEM_Int; + if( pOp->opcode==OP_Seek ){ + assert( pOp->p3>=0 && pOp->p3nCursor ); + pTabCur = p->apCsr[pOp->p3]; + assert( pTabCur!=0 ); + assert( pTabCur->eCurType==CURTYPE_BTREE ); + assert( pTabCur->uc.pCursor!=0 ); + assert( pTabCur->isTable ); + pTabCur->nullRow = 0; + pTabCur->movetoTarget = rowid; + pTabCur->deferredMoveto = 1; + assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); + pTabCur->aAltMap = pOp->p4.ai; + pTabCur->pAltCursor = pC; + }else{ + pOut = out2Prerelease(p, pOp); + pOut->u.i = rowid; + pOut->flags = MEM_Int; + } + }else{ + assert( pOp->opcode==OP_IdxRowid ); + sqlite3VdbeMemSetNull(&aMem[pOp->p2]); } break; } diff --git a/src/wherecode.c b/src/wherecode.c index d590203155..3fbd198e31 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -768,7 +768,6 @@ static void codeDeferredSeek( WhereInfo *pWInfo, /* Where clause context */ Index *pIdx, /* Index scan is using */ int iCur, /* Cursor for IPK b-tree */ - int iRowid, /* Register containing rowid to seek to */ int iIdxCur /* Index cursor */ ){ Parse *pParse = pWInfo->pParse; /* Parse context */ @@ -777,7 +776,7 @@ static void codeDeferredSeek( assert( iIdxCur>0 ); assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); - sqlite3VdbeAddOp3(v, OP_Seek, iCur, iRowid, iIdxCur); + sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE) && sqlite3ParseToplevel(pParse)->writeMask==0 ){ @@ -1274,14 +1273,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - iRowidReg = ++pParse->nMem; - sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); if( pWInfo->eOnePass!=ONEPASS_OFF ){ + iRowidReg = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); + sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ - codeDeferredSeek(pWInfo, pIdx, iCur, iRowidReg, iIdxCur); + codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); } }else if( iCur!=iIdxCur ){ Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); From 52f5d1ba6be88ca71cf8bda71ed519ebe84a93e0 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Jan 2016 19:16:11 +0000 Subject: [PATCH 059/107] Performance enhancement for fts5 column filter queries on detail=full tables. FossilOrigin-Name: 13fb4aa6a87c5c6258979953da82eedc1a7bf14f --- ext/fts5/fts5_index.c | 24 ++-- ext/fts5/tool/fts5speed.tcl | 1 - ext/fts5/tool/fts5txt2db.tcl | 272 +++++++++++++++++++---------------- manifest | 18 +-- manifest.uuid | 2 +- 5 files changed, 170 insertions(+), 147 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index ca3feb86f7..f30c38d91a 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4333,26 +4333,32 @@ static int fts5IndexExtractCol( int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ const u8 *p = *pa; const u8 *pEnd = &p[n]; /* One byte past end of position list */ - u8 prev = 0; 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 ){ - prev = *p++; - if( p==pEnd ) return 0; + ** not part of a varint. Note that it is not possible for a negative + ** or extremely large varint to occur within an uncorrupted position + ** list. So the last byte of each varint may be assumed to have a clear + ** 0x80 bit. */ + while( *p!=0x01 ){ + while( *p++ & 0x80 ); + if( p>=pEnd ) return 0; } *pa = p++; - p += fts5GetVarint32(p, iCurrent); + iCurrent = *p++; + if( iCurrent & 0x80 ){ + 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 */ - assert( (prev & 0x80)==0 ); - while( p [set idx(-tblname) {tblname t1 "table name to use"} - # - # For each position parameter, append its name to $lPosargs. If the ... - # specifier is present, set $zTrailing to the name of the prefix. - # - foreach o $O { - set nm [lindex $o 0] - set nArg [llength $o] - switch -- $nArg { - 1 { - if {[string range $nm end-2 end]=="..."} { - set zTrailing [string range $nm 0 end-3] - } else { - lappend lPosargs $nm +########################################################################### +########################################################################### +# Command line options processor. This is generic code that can be copied +# between scripts. +# +namespace eval cmdline { + proc cmdline_error {O E {msg ""}} { + if {$msg != ""} { + puts stderr "Error: $msg" + puts stderr "" + } + + set L [list] + foreach o $O { + if {[llength $o]==1} { + lappend L [string toupper $o] + } + } + + puts stderr "Usage: $::argv0 ?SWITCHES? $L" + puts stderr "" + puts stderr "Switches are:" + foreach o $O { + if {[llength $o]==3} { + foreach {a b c} $o {} + puts stderr [format " -%-15s %s (default \"%s\")" "$a VAL" $c $b] + } elseif {[llength $o]==2} { + foreach {a b} $o {} + puts stderr [format " -%-15s %s" $a $b] + } + } + puts stderr "" + puts stderr $E + exit -1 + } + + proc process {avar lArgs O E} { + upvar $avar A + set zTrailing "" ;# True if ... is present in $O + set lPosargs [list] + + # Populate A() with default values. Also, for each switch in the command + # line spec, set an entry in the idx() array as follows: + # + # {tblname t1 "table name to use"} + # -> [set idx(-tblname) {tblname t1 "table name to use"} + # + # For each position parameter, append its name to $lPosargs. If the ... + # specifier is present, set $zTrailing to the name of the prefix. + # + foreach o $O { + set nm [lindex $o 0] + set nArg [llength $o] + switch -- $nArg { + 1 { + if {[string range $nm end-2 end]=="..."} { + set zTrailing [string range $nm 0 end-3] + } else { + lappend lPosargs $nm + } + } + 2 { + set A($nm) 0 + set idx(-$nm) $o + } + 3 { + set A($nm) [lindex $o 1] + set idx(-$nm) $o + } + default { + error "Error in command line specification" } } - 2 { - set A($nm) 0 - set idx(-$nm) $o - } - 3 { - set A($nm) [lindex $o 1] - set idx(-$nm) $o - } - default { - error "Error in command line specification" + } + + # Set explicitly specified option values + # + set nArg [llength $lArgs] + for {set i 0} {$i < $nArg} {incr i} { + set opt [lindex $lArgs $i] + if {[string range $opt 0 0]!="-" || $opt=="--"} break + set c [array names idx "${opt}*"] + if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"} + if {[llength $c]>1} { cmdline_error $O $E "Ambiguous option: $opt"} + + if {[llength $idx($c)]==3} { + if {$i==[llength $lArgs]-1} { + cmdline_error $O $E "Option requires argument: $c" + } + incr i + set A([lindex $idx($c) 0]) [lindex $lArgs $i] + } else { + set A([lindex $idx($c) 0]) 1 } } - } - - # Set explicitly specified option values - # - set nArg [llength $lArgs] - for {set i 0} {$i < $nArg} {incr i} { - set opt [lindex $lArgs $i] - if {[string range $opt 0 0]!="-" || $opt=="--"} break - set c [array names idx "${opt}*"] - if {[llength $c]==0} { command_line_error $O $E "Unrecognized option: $opt"} - if {[llength $c]>1} { command_line_error $O $E "Ambiguous option: $opt"} - - if {[llength $idx($c)]==3} { - if {$i==[llength $lArgs]-1} { - command_line_error $O $E "Option requires argument: $c" - } - incr i - set A([lindex $idx($c) 0]) [lindex $lArgs $i] - } else { - set A([lindex $idx($c) 0]) 1 + + # Deal with position arguments. + # + set nPosarg [llength $lPosargs] + set nRem [expr $nArg - $i] + if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} { + cmdline_error $O $E + } + for {set j 0} {$j < $nPosarg} {incr j} { + set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]] + } + if {$zTrailing!=""} { + set A($zTrailing) [lrange $lArgs [expr $j+$i] end] } } - - # Deal with position arguments. - # - set nPosarg [llength $lPosargs] - set nRem [expr $nArg - $i] - if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} { - command_line_error $O $E - } - for {set j 0} {$j < $nPosarg} {incr j} { - set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]] - } - if {$zTrailing!=""} { - set A($zTrailing) [lrange $lArgs [expr $j+$i] end] - } -} +} ;# namespace eval cmdline # End of command line options processor. -#------------------------------------------------------------------------- +########################################################################### +########################################################################### +process_cmdline -process_command_line A $argv { - {fts5 "use fts5"} - {fts4 "use fts4"} - {colsize "10 10 10" "list of column sizes"} - {tblname "t1" "table name to create"} - {detail "full" "Fts5 detail mode to use"} - {repeat 1 "Load each file this many times"} - database - file... -} { -This script is designed to create fts4/5 tables with more than one column. -The -colsize option should be set to a Tcl list of integer values, one for -each column in the table. Each value is the number of tokens that will be -inserted into the column value for each row. For example, setting the -colsize -option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10 -tokens per row in each, respectively. - -Each "FILE" argument should be a text file. The contents of these text files is -split on whitespace characters to form a list of tokens. The first N1 tokens -are used for the first column of the first row, where N1 is the first element -of the -colsize list. The next N2 are used for the second column of the first -row, and so on. Rows are added to the table until the entire list of tokens -is exhausted. -} - +# If -fts4 was specified, use fts4. Otherwise, fts5. if {$A(fts4)} { set A(fts) fts4 } else { @@ -156,7 +173,8 @@ proc create_table {} { set sql "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) (" append sql [join $cols ,] - if {$A(fts)=="fts5"} { append sql ",detail=$A(detail));" } + if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" } + append sql ", prefix='$A(prefix)');" db eval $sql return $cols diff --git a/manifest b/manifest index d850d9282e..75f2023494 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\simplementation\sof\sOP_IdxRowid\sand\sOP_Seek\sso\sthat\sOP_Seek\sno\slonger\nrequires\sthe\srowid\sregister\sand\sa\sseparate\sOP_IdxRowid\scall.\s\sShorter\sand\nfaster\sprepared\sstatements\sresult. -D 2016-01-30T16:59:56.592 +C Performance\senhancement\sfor\sfts5\scolumn\sfilter\squeries\son\sdetail=full\stables. +D 2016-01-30T19:16:11.820 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 5558bfbeaf364cc67f937e25753ceed8757cb6d1 +F ext/fts5/fts5_index.c cd1e4faca8b9adc2d89b367075bf93a7f50c406b F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -190,8 +190,8 @@ F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 -F ext/fts5/tool/fts5speed.tcl 47f0031e6ac564964f4f4805e439ea665e848df2 -F ext/fts5/tool/fts5txt2db.tcl ae308338b2da1646dea456ab66706acdde8c714e +F ext/fts5/tool/fts5speed.tcl f9944a9abb9b7685cfbee8101a3dd772ededca66 +F ext/fts5/tool/fts5txt2db.tcl 1343745b89ca2a1e975c23f836d0cee410052975 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c @@ -1422,7 +1422,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 1f4c667f37d63fc3ef2e8f2581ecd3a66c054426 -R c807c9436e91d8aabdffdea0ecd68c4e -U drh -Z a3f05d9c2a4721d817f24f533822e83f +P 9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74 +R bc0069e7525e32617bb065c15a24c73f +U dan +Z 0739ff39c83f4f590353add9c7d562e8 diff --git a/manifest.uuid b/manifest.uuid index 01040f34b0..6f555b4e1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74 \ No newline at end of file +13fb4aa6a87c5c6258979953da82eedc1a7bf14f \ No newline at end of file From 482721ab7571338de32932d6d9c221a0445bb421 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 30 Jan 2016 21:09:02 +0000 Subject: [PATCH 060/107] Fix new test cases in stat.test so that they work with -DSQLITE_DEFAULT_AUTOVACUUM=1 builds. FossilOrigin-Name: a2810cf65db13479e2ab255c37abac7841ee985d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/stat.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 75f2023494..6eedebcb19 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\senhancement\sfor\sfts5\scolumn\sfilter\squeries\son\sdetail=full\stables. -D 2016-01-30T19:16:11.820 +C Fix\snew\stest\scases\sin\sstat.test\sso\sthat\sthey\swork\swith\s-DSQLITE_DEFAULT_AUTOVACUUM=1\sbuilds. +D 2016-01-30T21:09:02.039 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1054,7 +1054,7 @@ F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953 -F test/stat.test fafe6e82dfdb97d8c8be31cd83e36e973079ce0f +F test/stat.test acc91e80517fff447ae8adcfd953cfdaa5efc0af F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/subquery.test d7268d193dd33d5505df965399d3a594e76ae13f @@ -1422,7 +1422,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 9bec50a1e7796a6e038db9b1cc7cc1e7e350bf74 -R bc0069e7525e32617bb065c15a24c73f +P 13fb4aa6a87c5c6258979953da82eedc1a7bf14f +R 47a5bd805bca8e3bfa57e533079ecc85 U dan -Z 0739ff39c83f4f590353add9c7d562e8 +Z 77da8baba44508a2b8a7ef85c127b8a0 diff --git a/manifest.uuid b/manifest.uuid index 6f555b4e1d..480ce59513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13fb4aa6a87c5c6258979953da82eedc1a7bf14f \ No newline at end of file +a2810cf65db13479e2ab255c37abac7841ee985d \ No newline at end of file diff --git a/test/stat.test b/test/stat.test index 14751bd6ff..288153dbb3 100644 --- a/test/stat.test +++ b/test/stat.test @@ -192,6 +192,7 @@ do_catchsql_test stat-6.1 { forcedelete test.db2 do_execsql_test 7.1 { ATTACH 'test.db2' AS '123'; + PRAGMA "123".auto_vacuum = OFF; CREATE TABLE "123".x1(a, b); INSERT INTO x1 VALUES(1, 2); } From 38bace84cdc2d654097a89ce1ffb2521eb8dbd04 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Feb 2016 00:21:08 +0000 Subject: [PATCH 061/107] Fix an assert() that might fail on a corrupt database. FossilOrigin-Name: 22eaced7274764eaf7ab4b5fc52cc2fcfc285708 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6eedebcb19..adf078c951 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\snew\stest\scases\sin\sstat.test\sso\sthat\sthey\swork\swith\s-DSQLITE_DEFAULT_AUTOVACUUM=1\sbuilds. -D 2016-01-30T21:09:02.039 +C Fix\san\sassert()\sthat\smight\sfail\son\sa\scorrupt\sdatabase. +D 2016-02-01T00:21:08.846 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -290,7 +290,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c e3929afb9bfbaa6b39685b5e5a207036ac862a75 +F src/btree.c a2a0244ea3f0b3f57f75019c2f229c744ca5d202 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 0510844c48d80732aead74b5727403b493dd1cd5 @@ -1422,7 +1422,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 13fb4aa6a87c5c6258979953da82eedc1a7bf14f -R 47a5bd805bca8e3bfa57e533079ecc85 -U dan -Z 77da8baba44508a2b8a7ef85c127b8a0 +P a2810cf65db13479e2ab255c37abac7841ee985d +R 188fdebacf7930560dd1bef6de7f142e +U drh +Z 4925a52dc50a180b6685bbcef3b9e085 diff --git a/manifest.uuid b/manifest.uuid index 480ce59513..85c92e6bfd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2810cf65db13479e2ab255c37abac7841ee985d \ No newline at end of file +22eaced7274764eaf7ab4b5fc52cc2fcfc285708 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b08367cbd7..d5acaf3669 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8239,7 +8239,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ if( rc==SQLITE_OK ){ if( bSkipnext ){ assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); - assert( pPage==pCur->apPage[pCur->iPage] ); + assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; if( iCellIdx>=pPage->nCell ){ From b0c886510f9f691ab382c5af82644ba48684a9f3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Feb 2016 13:21:13 +0000 Subject: [PATCH 062/107] Minor simplification to the OP_AutoCommit opcode. Fix some code comments related to transaction control. FossilOrigin-Name: a9b6a0672f84dd205f9333951e4c2a608d027d71 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 11 +++++------ src/vdbe.c | 19 +++++++++---------- src/vdbeaux.c | 2 +- 5 files changed, 24 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index adf078c951..fbe4e529cf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sthat\smight\sfail\son\sa\scorrupt\sdatabase. -D 2016-02-01T00:21:08.846 +C Minor\ssimplification\sto\sthe\sOP_AutoCommit\sopcode.\s\sFix\ssome\scode\scomments\nrelated\sto\stransaction\scontrol. +D 2016-02-01T13:21:13.072 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -293,7 +293,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c a2a0244ea3f0b3f57f75019c2f229c744ca5d202 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 0510844c48d80732aead74b5727403b493dd1cd5 +F src/build.c c177ca703d7a3ac6ea6bba3a6c396d67ce79bc69 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -412,11 +412,11 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 73f0f61eb5556e430487671a557d032ecac52240 +F src/vdbe.c 755b1e2117214549b768efb6e552fcd12a9d859b F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 -F src/vdbeaux.c 221631e40111b5efa96ea557c6e2e7f62fd32b2a +F src/vdbeaux.c b8ba8e6d48732fb7a735a23e3040a01f4848498e F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -1422,7 +1422,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 a2810cf65db13479e2ab255c37abac7841ee985d -R 188fdebacf7930560dd1bef6de7f142e +P 22eaced7274764eaf7ab4b5fc52cc2fcfc285708 +R 48595a32d50edde169d3b975cd1cf3f9 U drh -Z 4925a52dc50a180b6685bbcef3b9e085 +Z 4ace4ad684d082250fc68f1cbbc590b5 diff --git a/manifest.uuid b/manifest.uuid index 85c92e6bfd..f7adbd19c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22eaced7274764eaf7ab4b5fc52cc2fcfc285708 \ No newline at end of file +a9b6a0672f84dd205f9333951e4c2a608d027d71 \ No newline at end of file diff --git a/src/build.c b/src/build.c index be320b9c5a..88ddf406e6 100644 --- a/src/build.c +++ b/src/build.c @@ -3892,7 +3892,7 @@ void sqlite3SrcListShiftJoinType(SrcList *p){ } /* -** Begin a transaction +** Generate VDBE code for a BEGIN statement. */ void sqlite3BeginTransaction(Parse *pParse, int type){ sqlite3 *db; @@ -3902,7 +3902,6 @@ void sqlite3BeginTransaction(Parse *pParse, int type){ assert( pParse!=0 ); db = pParse->db; assert( db!=0 ); -/* if( db->aDb[0].pBt==0 ) return; */ if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ return; } @@ -3914,11 +3913,11 @@ void sqlite3BeginTransaction(Parse *pParse, int type){ sqlite3VdbeUsesBtree(v, i); } } - sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0); + sqlite3VdbeAddOp0(v, OP_AutoCommit); } /* -** Commit a transaction +** Generate VDBE code for a COMMIT statement. */ void sqlite3CommitTransaction(Parse *pParse){ Vdbe *v; @@ -3930,12 +3929,12 @@ void sqlite3CommitTransaction(Parse *pParse){ } v = sqlite3GetVdbe(pParse); if( v ){ - sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0); + sqlite3VdbeAddOp1(v, OP_AutoCommit, 1); } } /* -** Rollback a transaction +** Generate VDBE code for a ROLLBACK statement. */ void sqlite3RollbackTransaction(Parse *pParse){ Vdbe *v; diff --git a/src/vdbe.c b/src/vdbe.c index a1e59e1170..2bb39c85bf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3008,28 +3008,27 @@ case OP_Savepoint: { case OP_AutoCommit: { int desiredAutoCommit; int iRollback; - int turnOnAC; desiredAutoCommit = pOp->p1; iRollback = pOp->p2; - turnOnAC = desiredAutoCommit && !db->autoCommit; assert( desiredAutoCommit==1 || desiredAutoCommit==0 ); assert( desiredAutoCommit==1 || iRollback==0 ); assert( db->nVdbeActive>0 ); /* At least this one VM is active */ assert( p->bIsReader ); - if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){ - /* If this instruction implements a COMMIT and other VMs are writing - ** return an error indicating that the other VMs must complete first. - */ - sqlite3VdbeError(p, "cannot commit transaction - " - "SQL statements in progress"); - rc = SQLITE_BUSY; - }else if( desiredAutoCommit!=db->autoCommit ){ + if( desiredAutoCommit!=db->autoCommit ){ if( iRollback ){ assert( desiredAutoCommit==1 ); sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; + }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ + /* If this instruction implements a COMMIT and other VMs are writing + ** return an error indicating that the other VMs must complete first. + */ + sqlite3VdbeError(p, "cannot commit transaction - " + "SQL statements in progress"); + rc = SQLITE_BUSY; + break; }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 619aada030..d6cf451af4 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -534,7 +534,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; - /* NOTE: Be sure to update mkopcodeh.awk when adding or removing + /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing ** cases from this switch! */ switch( opcode ){ case OP_Transaction: { From cddb6ba03bdbe25cd0c466c3189a226adc4462ee Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 1 Feb 2016 13:58:56 +0000 Subject: [PATCH 063/107] Fix a problem causing the OR/covering-index optimization to be disabled if compile time parameter SQLITE_MAX_ATTACHED were set to greater than 30. FossilOrigin-Name: a17712bf8d98dd485560f434a5350e6381cf1411 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fbe4e529cf..ebebee2b6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sto\sthe\sOP_AutoCommit\sopcode.\s\sFix\ssome\scode\scomments\nrelated\sto\stransaction\scontrol. -D 2016-02-01T13:21:13.072 +C Fix\sa\sproblem\scausing\sthe\sOR/covering-index\soptimization\sto\sbe\sdisabled\sif\scompile\stime\sparameter\sSQLITE_MAX_ATTACHED\swere\sset\sto\sgreater\sthan\s30. +D 2016-02-01T13:58:56.691 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -428,7 +428,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 7ea737b14e7a35d7f55cbad589a29aa49dfe3f7a +F src/wherecode.c 923f5d04b379b7417bc29f3b86b5eae9d1923d72 F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1422,7 +1422,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 22eaced7274764eaf7ab4b5fc52cc2fcfc285708 -R 48595a32d50edde169d3b975cd1cf3f9 -U drh -Z 4ace4ad684d082250fc68f1cbbc590b5 +P a9b6a0672f84dd205f9333951e4c2a608d027d71 +R 2464227ee70c33ffde6d518be2a20c9c +U dan +Z 281424deda7a5f64a5e9ae761e185dda diff --git a/manifest.uuid b/manifest.uuid index f7adbd19c9..ec7821b682 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9b6a0672f84dd205f9333951e4c2a608d027d71 \ No newline at end of file +a17712bf8d98dd485560f434a5350e6381cf1411 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 3fbd198e31..f5f45da397 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -778,7 +778,7 @@ static void codeDeferredSeek( sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE) - && sqlite3ParseToplevel(pParse)->writeMask==0 + && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; Table *pTab = pIdx->pTable; From 3b37bc4206898dd93b5280d3aae4ee3fd8293e77 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 1 Feb 2016 16:36:47 +0000 Subject: [PATCH 064/107] Update walcrash.test to ensure that, during a particular test, enough data is written to cause SQLite to sync the wal file 14 times. FossilOrigin-Name: 5d7c092869137a0ba69f93324fe4ed56a05b5985 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/walcrash.test | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ebebee2b6a..115a4bbaf2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\scausing\sthe\sOR/covering-index\soptimization\sto\sbe\sdisabled\sif\scompile\stime\sparameter\sSQLITE_MAX_ATTACHED\swere\sset\sto\sgreater\sthan\s30. -D 2016-02-01T13:58:56.691 +C Update\swalcrash.test\sto\sensure\sthat,\sduring\sa\sparticular\stest,\senough\sdata\sis\swritten\sto\scause\sSQLite\sto\ssync\sthe\swal\sfile\s14\stimes. +D 2016-02-01T16:36:47.969 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1308,7 +1308,7 @@ F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa -F test/walcrash.test 451d79e528add5c42764cea74aa2750754171b25 +F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b @@ -1422,7 +1422,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 a9b6a0672f84dd205f9333951e4c2a608d027d71 -R 2464227ee70c33ffde6d518be2a20c9c +P a17712bf8d98dd485560f434a5350e6381cf1411 +R 9c14b59494afeacd043f7754f1a985e1 U dan -Z 281424deda7a5f64a5e9ae761e185dda +Z ecc144871fca92cc0fc68693a6e08d49 diff --git a/manifest.uuid b/manifest.uuid index ec7821b682..af8a34f793 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a17712bf8d98dd485560f434a5350e6381cf1411 \ No newline at end of file +5d7c092869137a0ba69f93324fe4ed56a05b5985 \ No newline at end of file diff --git a/test/walcrash.test b/test/walcrash.test index 2a647188b0..b8ca7fbf34 100644 --- a/test/walcrash.test +++ b/test/walcrash.test @@ -237,12 +237,13 @@ for {set i 1} {$i < $REPEATS} {incr i} { INSERT INTO t1 VALUES(randomblob(9000)); INSERT INTO t1 VALUES(randomblob(9000)); INSERT INTO t1 VALUES(randomblob(9000)); + INSERT INTO t1 VALUES(randomblob(9000)); } } {1 {child process exited abnormally}} do_test walcrash-6.$i.2 { sqlite3 db test.db - execsql { SELECT count(*)==34 OR count(*)==35 FROM t1 WHERE x != 1 } + execsql { SELECT count(*) BETWEEN 34 AND 36 FROM t1 WHERE x != 1 } } {1} do_test walcrash-6.$i.3 { execsql { PRAGMA main.integrity_check } } {ok} do_test walcrash-6.$i.4 { execsql { PRAGMA main.journal_mode } } {wal} From ed94af5eb9b75dc1ad6f3d462a14271b5386396b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Feb 2016 17:20:08 +0000 Subject: [PATCH 065/107] Number VDBE opcodes starting with 0 instead of 1, as this obviates the lower-bound test on "switch(opcode){...}", making the code smaller and faster. FossilOrigin-Name: 4c9222f75bfac47f5422fff86b2d69a61933b3a2 --- manifest | 18 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- tool/mkopcodec.tcl | 4 ++-- tool/mkopcodeh.tcl | 54 +++++++++++++++++++++++++--------------------- 5 files changed, 42 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 115a4bbaf2..5ae7fd9d24 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\swalcrash.test\sto\sensure\sthat,\sduring\sa\sparticular\stest,\senough\sdata\sis\swritten\sto\scause\sSQLite\sto\ssync\sthe\swal\sfile\s14\stimes. -D 2016-02-01T16:36:47.969 +C Number\sVDBE\sopcodes\sstarting\swith\s0\sinstead\sof\s1,\sas\sthis\sobviates\sthe\nlower-bound\stest\son\s"switch(opcode){...}",\smaking\sthe\scode\ssmaller\sand\sfaster. +D 2016-02-01T17:20:08.707 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -416,7 +416,7 @@ F src/vdbe.c 755b1e2117214549b768efb6e552fcd12a9d859b F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 -F src/vdbeaux.c b8ba8e6d48732fb7a735a23e3040a01f4848498e +F src/vdbeaux.c f0e7cfa04f7ac44d69866868531dbaf20659d0a2 F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -1381,8 +1381,8 @@ F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45 F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 F tool/mkmsvcmin.tcl d57e6efc9428605f5418d0b235721ddf7b5d9c0b -F tool/mkopcodec.tcl edde8adc42621b5e598127f8cdc6d52cfe21f52b -F tool/mkopcodeh.tcl e04177031532b7aa9379ded50e820231ac4abd6e +F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c +F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkpragmatab.tcl f0d5bb266d1d388cf86fce5ba01a891e95d72d41 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1422,7 +1422,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 a17712bf8d98dd485560f434a5350e6381cf1411 -R 9c14b59494afeacd043f7754f1a985e1 -U dan -Z ecc144871fca92cc0fc68693a6e08d49 +P 5d7c092869137a0ba69f93324fe4ed56a05b5985 +R c689c18fc524ba4b0a7bb357f3467ad8 +U drh +Z 4a66c8beaa1a93ec6bbf8e1c0f940158 diff --git a/manifest.uuid b/manifest.uuid index af8a34f793..cc32153f40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d7c092869137a0ba69f93324fe4ed56a05b5985 \ No newline at end of file +4c9222f75bfac47f5422fff86b2d69a61933b3a2 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d6cf451af4..13aef0d7fd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -171,7 +171,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ i = p->nOp; assert( p->magic==VDBE_MAGIC_INIT ); - assert( op>0 && op<0xff ); + assert( op>=0 && op<0xff ); if( p->pParse->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } diff --git a/tool/mkopcodec.tcl b/tool/mkopcodec.tcl index 55d828b14d..abdeaaeb32 100644 --- a/tool/mkopcodec.tcl +++ b/tool/mkopcodec.tcl @@ -19,7 +19,7 @@ puts "#else" puts "# define OpHelp(X)" puts "#endif" puts "const char *sqlite3OpcodeName(int i)\173" -puts " static const char *const azName\[\] = \173 \"?\"," +puts " static const char *const azName\[\] = \173" set mx 0 set in [open [lindex $argv 0] rb] @@ -40,7 +40,7 @@ while {![eof $in]} { } close $in -for {set i 1} {$i<=$mx} {incr i} { +for {set i 0} {$i<=$mx} {incr i} { puts [format " /* %3d */ %-18s OpHelp(\"%s\")," \ $i \"$label($i)\" $synopsis($i)] } diff --git a/tool/mkopcodeh.tcl b/tool/mkopcodeh.tcl index 4c36f24ba4..053c7f8984 100644 --- a/tool/mkopcodeh.tcl +++ b/tool/mkopcodeh.tcl @@ -81,8 +81,8 @@ while {![eof $in]} { set in1($name) 0 set in2($name) 0 set in3($name) 0 - set out1($name) 0 set out2($name) 0 + set out3($name) 0 for {set i 3} {$i<[llength $line]-1} {incr i} { switch [string trim [lindex $line $i] ,] { same { @@ -112,16 +112,19 @@ while {![eof $in]} { # Assign numbers to all opcodes and output the result. # -set cnt 0 -set max 0 puts "/* Automatically generated. Do not edit */" puts "/* See the tool/mkopcodeh.tcl script for details */" -set op(OP_Noop) -1 -set order($nOp) OP_Noop -incr nOp -set op(OP_Explain) -1 -set order($nOp) OP_Explain -incr nOp +foreach name {OP_Noop OP_Explain} { + set jump($name) 0 + set in1($name) 0 + set in2($name) 0 + set in3($name) 0 + set out2($name) 0 + set out3($name) 0 + set op($name) -1 + set order($nOp) $name + incr nOp +} # The following are the opcodes that are processed by resolveP2Values() # @@ -144,7 +147,7 @@ set rp2v_ops { # Assign small values to opcodes that are processed by resolveP2Values() # to make code generation for the switch() statement smaller and faster. # -set cnt 0 +set cnt -1 for {set i 0} {$i<$nOp} {incr i} { set name $order($i) if {[lsearch $rp2v_ops $name]>=0} { @@ -169,7 +172,7 @@ for {set i 0} {$i<$nOp} {incr i} { } } set max $cnt -for {set i 1} {$i<=$nOp} {incr i} { +for {set i 0} {$i<$nOp} {incr i} { if {![info exists used($i)]} { set def($i) "OP_NotUsed_$i" } @@ -196,27 +199,28 @@ for {set i 1} {$i<=$nOp} {incr i} { # Generate the bitvectors: # set bv(0) 0 -for {set i 1} {$i<=$max} {incr i} { +for {set i 0} {$i<=$max} {incr i} { set name $def($i) - if {[info exists jump($name)] && $jump($name)} {set a0 1} {set a0 0} - if {[info exists in1($name)] && $in1($name)} {set a1 2} {set a1 0} - if {[info exists in2($name)] && $in2($name)} {set a2 4} {set a2 0} - if {[info exists in3($name)] && $in3($name)} {set a3 8} {set a3 0} - if {[info exists out2($name)] && $out2($name)} {set a4 16} {set a4 0} - if {[info exists out3($name)] && $out3($name)} {set a5 32} {set a5 0} - set bv($i) [expr {$a0+$a1+$a2+$a3+$a4+$a5}] + set x 0 + if {$jump($name)} {incr x 1} + if {$in1($name)} {incr x 2} + if {$in2($name)} {incr x 4} + if {$in3($name)} {incr x 8} + if {$out2($name)} {incr x 16} + if {$out3($name)} {incr x 32} + set bv($i) $x } puts "" puts "/* Properties such as \"out2\" or \"jump\" that are specified in" puts "** comments following the \"case\" for each opcode in the vdbe.c" puts "** are encoded into bitvectors as follows:" puts "*/" -puts "#define OPFLG_JUMP 0x0001 /* jump: P2 holds jmp target */" -puts "#define OPFLG_IN1 0x0002 /* in1: P1 is an input */" -puts "#define OPFLG_IN2 0x0004 /* in2: P2 is an input */" -puts "#define OPFLG_IN3 0x0008 /* in3: P3 is an input */" -puts "#define OPFLG_OUT2 0x0010 /* out2: P2 is an output */" -puts "#define OPFLG_OUT3 0x0020 /* out3: P3 is an output */" +puts "#define OPFLG_JUMP 0x01 /* jump: P2 holds jmp target */" +puts "#define OPFLG_IN1 0x02 /* in1: P1 is an input */" +puts "#define OPFLG_IN2 0x04 /* in2: P2 is an input */" +puts "#define OPFLG_IN3 0x08 /* in3: P3 is an input */" +puts "#define OPFLG_OUT2 0x10 /* out2: P2 is an output */" +puts "#define OPFLG_OUT3 0x20 /* out3: P3 is an output */" puts "#define OPFLG_INITIALIZER \173\\" for {set i 0} {$i<=$max} {incr i} { if {$i%8==0} { From df015945e3fdca65b4bc4b7ef5f431610f405bf0 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 1 Feb 2016 20:12:41 +0000 Subject: [PATCH 066/107] Improve performance of fts5 queries. FossilOrigin-Name: 2334e88244afe6387208be5d527aba9b5ddf4e4c --- ext/fts5/fts5_expr.c | 115 +++++++++++++++++++++++++--------- ext/fts5/fts5_main.c | 16 ++--- ext/fts5/test/fts5simple.test | 23 ++++++- manifest | 18 +++--- manifest.uuid | 2 +- 5 files changed, 122 insertions(+), 52 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 3a1497f05d..7c8e3c87c1 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -62,6 +62,9 @@ struct Fts5ExprNode { int bEof; /* True at EOF */ int bNomatch; /* True if entry is not a match */ + /* Next method for this node. */ + int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64); + i64 iRowid; /* Current rowid */ Fts5ExprNearset *pNear; /* For FTS5_STRING - cluster of phrases */ @@ -73,6 +76,12 @@ struct Fts5ExprNode { #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING) +/* +** Invoke the xNext method of an Fts5ExprNode object. This macro should be +** used as if it has the same signature as the xNext() methods themselves. +*/ +#define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d)) + /* ** An instance of the following structure represents a single search term ** or term prefix. @@ -234,7 +243,15 @@ int sqlite3Fts5ExprNew( sParse.rc = SQLITE_NOMEM; sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ - pNew->pRoot = sParse.pExpr; + if( !sParse.pExpr ){ + const int nByte = sizeof(Fts5ExprNode); + pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); + if( pNew->pRoot ){ + pNew->pRoot->bEof = 1; + } + }else{ + pNew->pRoot = sParse.pExpr; + } pNew->pIndex = 0; pNew->pConfig = pConfig; pNew->apExprPhrase = sParse.apPhrase; @@ -500,12 +517,6 @@ static int fts5LookaheadReaderInit( return fts5LookaheadReaderNext(p); } -#if 0 -static int fts5LookaheadReaderEof(Fts5LookaheadReader *p){ - return (p->iPos==FTS5_LOOKAHEAD_EOF); -} -#endif - typedef struct Fts5NearTrimmer Fts5NearTrimmer; struct Fts5NearTrimmer { Fts5LookaheadReader reader; /* Input iterator */ @@ -636,6 +647,7 @@ static int fts5ExprNearAdvanceFirst( Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0]; int rc = SQLITE_OK; + pNode->bNomatch = 0; if( pTerm->pSynonym ){ int bEof = 1; Fts5ExprTerm *p; @@ -765,17 +777,6 @@ static int fts5ExprNearTest( for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ Fts5IndexIter *pIter = pTerm->pIter; if( sqlite3Fts5IterEof(pIter)==0 ){ -#if 0 - int n; - i64 iRowid; - rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid); - if( rc!=SQLITE_OK ){ - *pRc = rc; - return 0; - }else if( iRowid==pNode->iRowid && n>0 ){ - pPhrase->poslist.n = 1; - } -#endif if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){ pPhrase->poslist.n = 1; } @@ -797,11 +798,6 @@ static int fts5ExprNearTest( }else{ Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData); -#if 0 - rc = sqlite3Fts5IterPoslistBuffer( - pPhrase->aTerm[0].pIter, &pPhrase->poslist - ); -#endif } } @@ -888,6 +884,7 @@ static int fts5ExprNearNextMatch( if( iRowid==iLast ) continue; bMatch = 0; if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ + pNode->bNomatch = 0; pNode->bEof = 1; return rc; } @@ -905,7 +902,8 @@ static int fts5ExprNearNextMatch( }while( bMatch==0 ); pNode->iRowid = iLast; - pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode)); + pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK); + assert( pNode->bEof==0 || pNode->bNomatch==0 ); return rc; } @@ -923,6 +921,7 @@ static int fts5ExprNearInitAll( int i, j; int rc = SQLITE_OK; + assert( pNode->bNomatch==0 ); for(i=0; rc==SQLITE_OK && inPhrase; i++){ Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; for(j=0; jnTerm; j++){ @@ -990,6 +989,7 @@ static int fts5RowidCmp( static void fts5ExprSetEof(Fts5ExprNode *pNode){ int i; pNode->bEof = 1; + pNode->bNomatch = 0; for(i=0; inChild; i++){ fts5ExprSetEof(pNode->apChild[i]); } @@ -1012,8 +1012,6 @@ static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){ } -static int fts5ExprNodeNext(Fts5Expr*, Fts5ExprNode*, int, i64); - /* ** Argument pNode is an FTS5_AND node. */ @@ -1093,6 +1091,33 @@ static int fts5NodeCompare( return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid); } +/* +** xNext() method for a node of type FTS5_TERM. +*/ +static int fts5ExprNodeNext_Term( + Fts5Expr *pExpr, + Fts5ExprNode *pNode, + int bFromValid, + i64 iFrom +){ + int rc; + Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter; + + assert( pNode->bEof==0 ); + if( bFromValid ){ + rc = sqlite3Fts5IterNextFrom(pIter, iFrom); + }else{ + rc = sqlite3Fts5IterNext(pIter); + } + if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ + rc = fts5ExprTokenTest(pExpr, pNode); + }else{ + pNode->bEof = 1; + pNode->bNomatch = 0; + } + return rc; +} + /* ** Advance node iterator pNode, part of expression pExpr. If argument ** bFromValid is zero, then pNode is advanced exactly once. Or, if argument @@ -1100,7 +1125,7 @@ static int fts5NodeCompare( ** rowid value iFrom. Whether "past" means "less than" or "greater than" ** depends on whether this is an ASC or DESC iterator. */ -static int fts5ExprNodeNext( +static int fts5ExprNodeNext_Fallback( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, @@ -1127,6 +1152,7 @@ static int fts5ExprNodeNext( rc = fts5ExprTokenTest(pExpr, pNode); }else{ pNode->bEof = 1; + pNode->bNomatch = 0; } return rc; }; @@ -1180,6 +1206,7 @@ static int fts5ExprNodeNext( || pNode->iRowid==iFrom || pExpr->bDesc==(pNode->iRowidbNomatch==0 || rc==SQLITE_OK ); return rc; } @@ -1246,6 +1273,7 @@ static int fts5ExprNodeNextMatch( rc = fts5ExprNodeNext(pExpr, p1, 0, 0); } pNode->bEof = p1->bEof; + pNode->bNomatch = p1->bNomatch; pNode->iRowid = p1->iRowid; if( p1->bEof ){ fts5ExprNodeZeroPoslist(p2); @@ -1268,16 +1296,36 @@ static int fts5ExprNodeNextMatch( static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){ int rc = SQLITE_OK; pNode->bEof = 0; + pNode->bNomatch = 0; if( Fts5NodeIsString(pNode) ){ /* Initialize all term iterators in the NEAR object. */ rc = fts5ExprNearInitAll(pExpr, pNode); }else{ int i; + int nEof = 0; for(i=0; inChild && rc==SQLITE_OK; i++){ + Fts5ExprNode *pChild = pNode->apChild[i]; rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]); + assert( pChild->bEof==0 || pChild->bEof==1 ); + nEof += pChild->bEof; } pNode->iRowid = pNode->apChild[0]->iRowid; + + switch( pNode->eType ){ + case FTS5_AND: + if( nEof>0 ) fts5ExprSetEof(pNode); + break; + + case FTS5_OR: + if( pNode->nChild==nEof ) fts5ExprSetEof(pNode); + break; + + default: + assert( pNode->eType==FTS5_NOT ); + pNode->bEof = pNode->apChild[0]->bEof; + break; + } } if( rc==SQLITE_OK ){ @@ -1305,7 +1353,7 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ Fts5ExprNode *pRoot = p->pRoot; int rc = SQLITE_OK; - if( pRoot ){ + if( pRoot->xNext ){ p->pIndex = pIdx; p->bDesc = bDesc; rc = fts5ExprNodeFirst(p, pRoot); @@ -1333,9 +1381,11 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ int rc; Fts5ExprNode *pRoot = p->pRoot; + assert( pRoot->bEof==0 && pRoot->bNomatch==0 ); do { rc = fts5ExprNodeNext(p, pRoot, 0, 0); - }while( pRoot->bNomatch && pRoot->bEof==0 && rc==SQLITE_OK ); + assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) ); + }while( pRoot->bNomatch ); if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){ pRoot->bEof = 1; } @@ -1343,7 +1393,7 @@ int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ } int sqlite3Fts5ExprEof(Fts5Expr *p){ - return (p->pRoot==0 || p->pRoot->bEof); + return p->pRoot->bEof; } i64 sqlite3Fts5ExprRowid(Fts5Expr *p){ @@ -1640,6 +1690,7 @@ int sqlite3Fts5ExprClonePhrase( pNew->apExprPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->nPhrase = 1; + pNew->pRoot->xNext = fts5ExprNodeNext_Fallback; sCtx.pPhrase->pNode = pNew->pRoot; if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ @@ -1840,6 +1891,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode( pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ + pRet->xNext = fts5ExprNodeNext_Fallback; pRet->eType = eType; pRet->pNear = pNear; if( eType==FTS5_STRING ){ @@ -1850,6 +1902,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode( if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 ){ if( pNear->apPhrase[0]->aTerm[0].pSynonym==0 ){ pRet->eType = FTS5_TERM; + pRet->xNext = fts5ExprNodeNext_Term; } }else if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ assert( pParse->rc==SQLITE_OK ); @@ -2144,7 +2197,7 @@ static void fts5ExprFunction( } if( rc==SQLITE_OK ){ char *zText; - if( pExpr->pRoot==0 ){ + if( pExpr->pRoot->xNext==0 ){ zText = sqlite3_mprintf(""); }else if( bTcl ){ zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index ec045da6bf..9ef8d9a01a 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -220,10 +220,10 @@ struct Fts5Cursor { /* ** Values for Fts5Cursor.csrflags */ -#define FTS5CSR_REQUIRE_CONTENT 0x01 -#define FTS5CSR_REQUIRE_DOCSIZE 0x02 -#define FTS5CSR_REQUIRE_INST 0x04 -#define FTS5CSR_EOF 0x08 +#define FTS5CSR_EOF 0x01 +#define FTS5CSR_REQUIRE_CONTENT 0x02 +#define FTS5CSR_REQUIRE_DOCSIZE 0x04 +#define FTS5CSR_REQUIRE_INST 0x08 #define FTS5CSR_FREE_ZRANK 0x10 #define FTS5CSR_REQUIRE_RESEEK 0x20 #define FTS5CSR_REQUIRE_POSLIST 0x40 @@ -778,7 +778,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr); rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc); - if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){ + if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){ *pbSkip = 1; } @@ -786,6 +786,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ fts5CsrNewrow(pCsr); if( sqlite3Fts5ExprEof(pCsr->pExpr) ){ CsrFlagSet(pCsr, FTS5CSR_EOF); + *pbSkip = 1; } } return rc; @@ -807,14 +808,13 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ assert( (pCsr->ePlan<3)== (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) ); + assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid); - if( sqlite3Fts5ExprEof(pCsr->pExpr) ){ - CsrFlagSet(pCsr, FTS5CSR_EOF); - } + CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr)); fts5CsrNewrow(pCsr); }else{ switch( pCsr->ePlan ){ diff --git a/ext/fts5/test/fts5simple.test b/ext/fts5/test/fts5simple.test index e29c13117c..b6563fd9d0 100644 --- a/ext/fts5/test/fts5simple.test +++ b/ext/fts5/test/fts5simple.test @@ -19,7 +19,7 @@ ifcapable !fts5 { return } - if 1 { +if 1 { #------------------------------------------------------------------------- # @@ -363,8 +363,6 @@ do_execsql_test 15.1 { INSERT INTO x2(x2) VALUES('integrity-check'); } -} - #------------------------------------------------------------------------- foreach_detail_mode $testprefix { reset_db @@ -382,5 +380,24 @@ foreach_detail_mode $testprefix { } {{0.0.0 1.0.2}} } +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 17.0 { + CREATE VIRTUAL TABLE x3 USING fts5(x); + INSERT INTO x3 VALUES('a b c'); +} + +do_execsql_test 17.1 { + SELECT rowid FROM x3('b AND d'); +} + +#------------------------------------------------------------------------- +do_execsql_test 18.1 { + CREATE VIRTUAL TABLE x4 USING fts5(x); + SELECT rowid FROM x4('""'); +} + finish_test diff --git a/manifest b/manifest index 5ae7fd9d24..f5e3ab6b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Number\sVDBE\sopcodes\sstarting\swith\s0\sinstead\sof\s1,\sas\sthis\sobviates\sthe\nlower-bound\stest\son\s"switch(opcode){...}",\smaking\sthe\scode\ssmaller\sand\sfaster. -D 2016-02-01T17:20:08.707 +C Improve\sperformance\sof\sfts5\squeries. +D 2016-02-01T20:12:41.276 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -102,10 +102,10 @@ F ext/fts5/fts5Int.h 6e0f90eb4872654a5b98130dec16965716525c9a F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 -F ext/fts5/fts5_expr.c a66b9694519d9c336d9bdbd46ea22e7e14aef412 +F ext/fts5/fts5_expr.c 768d221e592df03b26f46da56aa0a561f00fa4e0 F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 F ext/fts5/fts5_index.c cd1e4faca8b9adc2d89b367075bf93a7f50c406b -F ext/fts5/fts5_main.c 3886bbfc5ac1d9df29979823ddf2b68241e1127e +F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 @@ -175,7 +175,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 -F ext/fts5/test/fts5simple.test 2bc6451cbe887a9215f5b14ae307c70d850344c9 +F ext/fts5/test/fts5simple.test 7fcacfa473a37355af2e60096650c87b5ba8f3ba F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 F ext/fts5/test/fts5simple3.test e671b36bc4dbd4f5095e66cb04473cba9f680f53 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 @@ -1422,7 +1422,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 5d7c092869137a0ba69f93324fe4ed56a05b5985 -R c689c18fc524ba4b0a7bb357f3467ad8 -U drh -Z 4a66c8beaa1a93ec6bbf8e1c0f940158 +P 4c9222f75bfac47f5422fff86b2d69a61933b3a2 +R 267ad0dad7a7346f85182e52086f7b51 +U dan +Z ee79d8b7c590b68c4d6e9bbdc4c83095 diff --git a/manifest.uuid b/manifest.uuid index cc32153f40..3b468df8c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c9222f75bfac47f5422fff86b2d69a61933b3a2 \ No newline at end of file +2334e88244afe6387208be5d527aba9b5ddf4e4c \ No newline at end of file From 1861afcdbb48d4e2cb1f6ec491aeaee51bf15774 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 1 Feb 2016 21:48:34 +0000 Subject: [PATCH 067/107] Change the OP_SetCookie instruction to write the literal P3 value, not the value in register P3. FossilOrigin-Name: 6d7d4703ebf3754bec74123d5ba7e861a705f90f --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/alter.c | 2 +- src/build.c | 12 ++++-------- src/pragma.c | 19 ++++++++----------- src/vdbe.c | 16 +++++++--------- 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/manifest b/manifest index f5e3ab6b6d..391305ff38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sperformance\sof\sfts5\squeries. -D 2016-02-01T20:12:41.276 +C Change\sthe\sOP_SetCookie\sinstruction\sto\swrite\sthe\sliteral\sP3\svalue,\snot\sthe\nvalue\sin\sregister\sP3. +D 2016-02-01T21:48:34.880 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -283,7 +283,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 9d649e46c780166e416fb11dbd23f8d49aab8267 +F src/alter.c 3fe13e97ab38317b092e2f3ae11267b40c9b5cbd F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 F src/attach.c 07b3a34a1702dce92a7f1d3888c0c06222b63760 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 @@ -293,7 +293,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c a2a0244ea3f0b3f57f75019c2f229c744ca5d202 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c c177ca703d7a3ac6ea6bba3a6c396d67ce79bc69 +F src/build.c 33dea2cef04c16a902c55f9d83b1a2065f213979 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -340,7 +340,7 @@ F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c ea290193369faa0a26ae2f924e7b86289b4a7987 +F src/pragma.c 2ac26ac45eedbed3cc8a9a320ad6d2fc299e69a6 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 @@ -412,7 +412,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 755b1e2117214549b768efb6e552fcd12a9d859b +F src/vdbe.c a0a0ada4b51161d3950fe30fc696b6c8235a841f F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 @@ -1422,7 +1422,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 4c9222f75bfac47f5422fff86b2d69a61933b3a2 -R 267ad0dad7a7346f85182e52086f7b51 -U dan -Z ee79d8b7c590b68c4d6e9bbdc4c83095 +P 2334e88244afe6387208be5d527aba9b5ddf4e4c +R 249f75933f6fe25a197c05fa835262de +U drh +Z 56e6b1659de31a547fab736bcf3cb22f diff --git a/manifest.uuid b/manifest.uuid index 3b468df8c8..54e6aa4e9f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2334e88244afe6387208be5d527aba9b5ddf4e4c \ No newline at end of file +6d7d4703ebf3754bec74123d5ba7e861a705f90f \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 2b043ef158..c8102c55d2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -608,7 +608,7 @@ void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){ sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, minFormat); sqlite3VdbeJumpHere(v, addr1); sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); diff --git a/src/build.c b/src/build.c index 88ddf406e6..3ca4c99947 100644 --- a/src/build.c +++ b/src/build.c @@ -983,10 +983,8 @@ void sqlite3StartTable( addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; - sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3); - sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); sqlite3VdbeJumpHere(v, addr1); /* This just creates a place-holder record in the sqlite_master table. @@ -1471,13 +1469,11 @@ CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ ** 1 chance in 2^32. So we're safe enough. */ void sqlite3ChangeCookie(Parse *pParse, int iDb){ - int r1 = sqlite3GetTempReg(pParse); sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1); - sqlite3ReleaseTempReg(pParse, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, + db->aDb[iDb].pSchema->schema_cookie+1); } /* diff --git a/src/pragma.c b/src/pragma.c index 15f0eecce3..1d827d7b70 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -444,8 +444,7 @@ void sqlite3Pragma( }else{ int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); sqlite3BeginWriteOperation(pParse, 0, iDb); - sqlite3VdbeAddOp2(v, OP_Integer, size, 1); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); @@ -683,8 +682,7 @@ void sqlite3Pragma( { OP_ReadCookie, 0, 1, BTREE_LARGEST_ROOT_PAGE}, { OP_If, 1, 0, 0}, /* 2 */ { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ - { OP_Integer, 0, 1, 0}, /* 4 */ - { OP_SetCookie, 0, BTREE_INCR_VACUUM, 1}, /* 5 */ + { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ }; VdbeOp *aOp; int iAddr = sqlite3VdbeCurrentAddr(v); @@ -694,8 +692,8 @@ void sqlite3Pragma( aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[2].p2 = iAddr+4; - aOp[4].p1 = eAuto - 1; - aOp[5].p1 = iDb; + aOp[4].p1 = iDb; + aOp[4].p3 = eAuto - 1; sqlite3VdbeUsesBtree(v, iDb); } } @@ -1728,17 +1726,16 @@ void sqlite3Pragma( /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { { OP_Transaction, 0, 1, 0}, /* 0 */ - { OP_Integer, 0, 1, 0}, /* 1 */ - { OP_SetCookie, 0, 0, 1}, /* 2 */ + { OP_SetCookie, 0, 0, 0}, /* 1 */ }; VdbeOp *aOp; sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; - aOp[1].p1 = sqlite3Atoi(zRight); - aOp[2].p1 = iDb; - aOp[2].p2 = iCookie; + aOp[1].p1 = iDb; + aOp[1].p2 = iCookie; + aOp[1].p3 = sqlite3Atoi(zRight); }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { diff --git a/src/vdbe.c b/src/vdbe.c index 2bb39c85bf..1cf4cb16a7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3213,15 +3213,15 @@ case OP_ReadCookie: { /* out2 */ /* Opcode: SetCookie P1 P2 P3 * * ** -** Write the content of register P3 (interpreted as an integer) -** into cookie number P2 of database P1. P2==1 is the schema version. -** P2==2 is the database format. P2==3 is the recommended pager cache +** Write the integer value P3 into cookie number P2 of database P1. +** P2==1 is the schema version. P2==2 is the database format. +** P2==3 is the recommended pager cache ** size, and so forth. P1==0 is the main database file and P1==1 is the ** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. */ -case OP_SetCookie: { /* in3 */ +case OP_SetCookie: { Db *pDb; assert( pOp->p2p1>=0 && pOp->p1nDb ); @@ -3230,17 +3230,15 @@ case OP_SetCookie: { /* in3 */ pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); - pIn3 = &aMem[pOp->p3]; - sqlite3VdbeMemIntegerify(pIn3); /* See note about index shifting on OP_ReadCookie */ - rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i); + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - pDb->pSchema->schema_cookie = (int)pIn3->u.i; + pDb->pSchema->schema_cookie = pOp->p3; db->flags |= SQLITE_InternChanges; }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ - pDb->pSchema->file_format = (u8)pIn3->u.i; + pDb->pSchema->file_format = pOp->p3; } if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database From b8db549832d2acc2fc30327e6fb5c0474820f122 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 2 Feb 2016 02:04:21 +0000 Subject: [PATCH 068/107] Enhance the comment on the sqlite3_index_constraint object to bring attention to the fact than iColumn field can be negative for a rowid. FossilOrigin-Name: d8b7b1996eefae7768bfcb82d4ff22c69392aa63 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 391305ff38..3952435799 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sOP_SetCookie\sinstruction\sto\swrite\sthe\sliteral\sP3\svalue,\snot\sthe\nvalue\sin\sregister\sP3. -D 2016-02-01T21:48:34.880 +C Enhance\sthe\scomment\son\sthe\ssqlite3_index_constraint\sobject\sto\sbring\sattention\s\nto\sthe\sfact\sthan\siColumn\sfield\scan\sbe\snegative\sfor\sa\srowid. +D 2016-02-02T02:04:21.840 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -349,7 +349,7 @@ F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e F src/select.c ea6f3b0c279aa37eb3701792d094673a7ad1bf88 F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 -F src/sqlite.h.in 214476a62012e578f42133a9a3b4f97a9aa421a3 +F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d F src/sqliteInt.h 2f80b9b1506a8d602b2a99f3f0bfae22df3e7d70 @@ -1422,7 +1422,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 2334e88244afe6387208be5d527aba9b5ddf4e4c -R 249f75933f6fe25a197c05fa835262de +P 6d7d4703ebf3754bec74123d5ba7e861a705f90f +R a0fd58918162f72722cea72a597641d9 U drh -Z 56e6b1659de31a547fab736bcf3cb22f +Z 8a77cde1543981fcb216eb719b02e019 diff --git a/manifest.uuid b/manifest.uuid index 54e6aa4e9f..dae04066fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d7d4703ebf3754bec74123d5ba7e861a705f90f \ No newline at end of file +d8b7b1996eefae7768bfcb82d4ff22c69392aa63 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 59b30cdd3a..fce396c0f6 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5697,7 +5697,7 @@ struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ struct sqlite3_index_constraint { - int iColumn; /* Column on left-hand side of constraint */ + int iColumn; /* Column constrained. -1 for ROWID */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ From 735ff4a80947404ab8960e2b6d6d23c0b163661f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Feb 2016 17:40:41 +0000 Subject: [PATCH 069/107] Enhance the performance of fts5 AND and OR queries. FossilOrigin-Name: 62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e --- ext/fts5/fts5Int.h | 4 +- ext/fts5/fts5_expr.c | 714 ++++++++++++++++++------------------ ext/fts5/fts5_index.c | 27 +- ext/fts5/tool/fts5speed.tcl | 4 + manifest | 20 +- manifest.uuid | 2 +- 6 files changed, 384 insertions(+), 387 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 48ab980921..9e5e52fa41 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -319,8 +319,11 @@ struct Fts5IndexIter { i64 iRowid; const u8 *pData; int nData; + u8 bEof; }; +#define sqlite3Fts5IterEof(x) ((x)->bEof) + /* ** Values used as part of the flags argument passed to IndexQuery(). */ @@ -384,7 +387,6 @@ int sqlite3Fts5IndexQuery( ** The various operations on open token or token prefix iterators opened ** using sqlite3Fts5IndexQuery(). */ -int sqlite3Fts5IterEof(Fts5IndexIter*); int sqlite3Fts5IterNext(Fts5IndexIter*); int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); i64 sqlite3Fts5IterRowid(Fts5IndexIter*); diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 7c8e3c87c1..1df173cfcc 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -303,7 +303,7 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ assert( bDesc==0 || bDesc==1 ); for(p=pTerm; p; p=p->pSynonym){ if( 0==sqlite3Fts5IterEof(p->pIter) ){ - i64 iRowid = sqlite3Fts5IterRowid(p->pIter); + i64 iRowid = p->pIter->iRowid; if( bRetValid==0 || (bDesc!=(iRowidpSynonym ); for(p=pTerm; p; p=p->pSynonym){ Fts5IndexIter *pIter = p->pIter; - if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){ + if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){ if( pIter->nData==0 ) continue; if( nIter==nAlloc ){ int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; @@ -631,72 +631,6 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ } } -/* -** Advance the first term iterator in the first phrase of pNear. Set output -** variable *pbEof to true if it reaches EOF or if an error occurs. -** -** Return SQLITE_OK if successful, or an SQLite error code if an error -** occurs. -*/ -static int fts5ExprNearAdvanceFirst( - Fts5Expr *pExpr, /* Expression pPhrase belongs to */ - Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */ - int bFromValid, - i64 iFrom -){ - Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0]; - int rc = SQLITE_OK; - - pNode->bNomatch = 0; - if( pTerm->pSynonym ){ - int bEof = 1; - Fts5ExprTerm *p; - - /* Find the firstest rowid any synonym points to. */ - i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0); - - /* Advance each iterator that currently points to iRowid. Or, if iFrom - ** is valid - each iterator that points to a rowid before iFrom. */ - for(p=pTerm; p; p=p->pSynonym){ - if( sqlite3Fts5IterEof(p->pIter)==0 ){ - i64 ii = sqlite3Fts5IterRowid(p->pIter); - if( ii==iRowid - || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc) - ){ - if( bFromValid ){ - rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom); - }else{ - rc = sqlite3Fts5IterNext(p->pIter); - } - if( rc!=SQLITE_OK ) break; - if( sqlite3Fts5IterEof(p->pIter)==0 ){ - bEof = 0; - } - }else{ - bEof = 0; - } - } - } - - /* Set the EOF flag if either all synonym iterators are at EOF or an - ** error has occurred. */ - pNode->bEof = (rc || bEof); - }else{ - Fts5IndexIter *pIter = pTerm->pIter; - - assert( Fts5NodeIsString(pNode) ); - if( bFromValid ){ - rc = sqlite3Fts5IterNextFrom(pIter, iFrom); - }else{ - rc = sqlite3Fts5IterNext(pIter); - } - - pNode->bEof = (rc || sqlite3Fts5IterEof(pIter)); - } - - return rc; -} - /* ** Advance iterator pIter until it points to a value equal to or laster ** than the initial value of *piLast. If this means the iterator points @@ -716,7 +650,7 @@ static int fts5ExprAdvanceto( i64 iLast = *piLast; i64 iRowid; - iRowid = sqlite3Fts5IterRowid(pIter); + iRowid = pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLastiRowid; assert( (bDesc==0 && iRowid>=iLast) || (bDesc==1 && iRowid<=iLast) ); } *piLast = iRowid; @@ -745,7 +679,7 @@ static int fts5ExprSynonymAdvanceto( for(p=pTerm; rc==SQLITE_OK && p; p=p->pSynonym){ if( sqlite3Fts5IterEof(p->pIter)==0 ){ - i64 iRowid = sqlite3Fts5IterRowid(p->pIter); + i64 iRowid = p->pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLastpIter, iLast); } @@ -809,104 +743,6 @@ static int fts5ExprNearTest( } } -static int fts5ExprTokenTest( - Fts5Expr *pExpr, /* Expression that pNear is a part of */ - Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */ -){ - /* As this "NEAR" object is actually a single phrase that consists - ** of a single term only, grab pointers into the poslist managed by the - ** fts5_index.c iterator object. This is much faster than synthesizing - ** a new poslist the way we have to for more complicated phrase or NEAR - ** expressions. */ - Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0]; - Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; - - assert( pNode->eType==FTS5_TERM ); - assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 ); - assert( pPhrase->aTerm[0].pSynonym==0 ); - - pPhrase->poslist.n = pIter->nData; - if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){ - pPhrase->poslist.p = (u8*)pIter->pData; - } - pNode->iRowid = pIter->iRowid; - pNode->bNomatch = (pPhrase->poslist.n==0); - return SQLITE_OK; -} - -/* -** All individual term iterators in pNear are guaranteed to be valid when -** this function is called. This function checks if all term iterators -** point to the same rowid, and if not, advances them until they do. -** If an EOF is reached before this happens, *pbEof is set to true before -** returning. -** -** SQLITE_OK is returned if an error occurs, or an SQLite error code -** otherwise. It is not considered an error code if an iterator reaches -** EOF. -*/ -static int fts5ExprNearNextMatch( - Fts5Expr *pExpr, /* Expression pPhrase belongs to */ - Fts5ExprNode *pNode -){ - Fts5ExprNearset *pNear = pNode->pNear; - Fts5ExprPhrase *pLeft = pNear->apPhrase[0]; - int rc = SQLITE_OK; - i64 iLast; /* Lastest rowid any iterator points to */ - int i, j; /* Phrase and token index, respectively */ - int bMatch; /* True if all terms are at the same rowid */ - const int bDesc = pExpr->bDesc; - - /* Check that this node should not be FTS5_TERM */ - assert( pNear->nPhrase>1 - || pNear->apPhrase[0]->nTerm>1 - || pNear->apPhrase[0]->aTerm[0].pSynonym - ); - - /* Initialize iLast, the "lastest" rowid any iterator points to. If the - ** iterator skips through rowids in the default ascending order, this means - ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it - ** means the minimum rowid. */ - if( pLeft->aTerm[0].pSynonym ){ - iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0); - }else{ - iLast = sqlite3Fts5IterRowid(pLeft->aTerm[0].pIter); - } - - do { - bMatch = 1; - for(i=0; inPhrase; i++){ - Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; - for(j=0; jnTerm; j++){ - Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; - if( pTerm->pSynonym ){ - i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0); - if( iRowid==iLast ) continue; - bMatch = 0; - if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ - pNode->bNomatch = 0; - pNode->bEof = 1; - return rc; - } - }else{ - Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; - i64 iRowid = sqlite3Fts5IterRowid(pIter); - if( iRowid==iLast ) continue; - bMatch = 0; - if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ - return rc; - } - } - } - } - }while( bMatch==0 ); - - pNode->iRowid = iLast; - pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK); - assert( pNode->bEof==0 || pNode->bNomatch==0 ); - - return rc; -} /* ** Initialize all term iterators in the pNear object. If any term is found @@ -957,10 +793,6 @@ static int fts5ExprNearInitAll( return rc; } -/* fts5ExprNodeNext() calls fts5ExprNodeNextMatch(). And vice-versa. */ -static int fts5ExprNodeNextMatch(Fts5Expr*, Fts5ExprNode*); - - /* ** If pExpr is an ASC iterator, this function returns a value with the ** same sign as: @@ -1012,10 +844,275 @@ static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){ } + +/* +** Compare the values currently indicated by the two nodes as follows: +** +** res = (*p1) - (*p2) +** +** Nodes that point to values that come later in the iteration order are +** considered to be larger. Nodes at EOF are the largest of all. +** +** This means that if the iteration order is ASC, then numerically larger +** rowids are considered larger. Or if it is the default DESC, numerically +** smaller rowids are larger. +*/ +static int fts5NodeCompare( + Fts5Expr *pExpr, + Fts5ExprNode *p1, + Fts5ExprNode *p2 +){ + if( p2->bEof ) return -1; + if( p1->bEof ) return +1; + return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid); +} + +/* +** All individual term iterators in pNear are guaranteed to be valid when +** this function is called. This function checks if all term iterators +** point to the same rowid, and if not, advances them until they do. +** If an EOF is reached before this happens, *pbEof is set to true before +** returning. +** +** SQLITE_OK is returned if an error occurs, or an SQLite error code +** otherwise. It is not considered an error code if an iterator reaches +** EOF. +*/ +static int fts5ExprNodeTest_STRING( + Fts5Expr *pExpr, /* Expression pPhrase belongs to */ + Fts5ExprNode *pNode +){ + Fts5ExprNearset *pNear = pNode->pNear; + Fts5ExprPhrase *pLeft = pNear->apPhrase[0]; + int rc = SQLITE_OK; + i64 iLast; /* Lastest rowid any iterator points to */ + int i, j; /* Phrase and token index, respectively */ + int bMatch; /* True if all terms are at the same rowid */ + const int bDesc = pExpr->bDesc; + + /* Check that this node should not be FTS5_TERM */ + assert( pNear->nPhrase>1 + || pNear->apPhrase[0]->nTerm>1 + || pNear->apPhrase[0]->aTerm[0].pSynonym + ); + + /* Initialize iLast, the "lastest" rowid any iterator points to. If the + ** iterator skips through rowids in the default ascending order, this means + ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it + ** means the minimum rowid. */ + if( pLeft->aTerm[0].pSynonym ){ + iLast = fts5ExprSynonymRowid(&pLeft->aTerm[0], bDesc, 0); + }else{ + iLast = pLeft->aTerm[0].pIter->iRowid; + } + + do { + bMatch = 1; + for(i=0; inPhrase; i++){ + Fts5ExprPhrase *pPhrase = pNear->apPhrase[i]; + for(j=0; jnTerm; j++){ + Fts5ExprTerm *pTerm = &pPhrase->aTerm[j]; + if( pTerm->pSynonym ){ + i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0); + if( iRowid==iLast ) continue; + bMatch = 0; + if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){ + pNode->bNomatch = 0; + pNode->bEof = 1; + return rc; + } + }else{ + Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter; + if( pIter->iRowid==iLast ) continue; + bMatch = 0; + if( fts5ExprAdvanceto(pIter, bDesc, &iLast, &rc, &pNode->bEof) ){ + return rc; + } + } + } + } + }while( bMatch==0 ); + + pNode->iRowid = iLast; + pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK); + assert( pNode->bEof==0 || pNode->bNomatch==0 ); + + return rc; +} + +/* +** Advance the first term iterator in the first phrase of pNear. Set output +** variable *pbEof to true if it reaches EOF or if an error occurs. +** +** Return SQLITE_OK if successful, or an SQLite error code if an error +** occurs. +*/ +static int fts5ExprNodeNext_STRING( + Fts5Expr *pExpr, /* Expression pPhrase belongs to */ + Fts5ExprNode *pNode, /* FTS5_STRING or FTS5_TERM node */ + int bFromValid, + i64 iFrom +){ + Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0]; + int rc = SQLITE_OK; + + pNode->bNomatch = 0; + if( pTerm->pSynonym ){ + int bEof = 1; + Fts5ExprTerm *p; + + /* Find the firstest rowid any synonym points to. */ + i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0); + + /* Advance each iterator that currently points to iRowid. Or, if iFrom + ** is valid - each iterator that points to a rowid before iFrom. */ + for(p=pTerm; p; p=p->pSynonym){ + if( sqlite3Fts5IterEof(p->pIter)==0 ){ + i64 ii = p->pIter->iRowid; + if( ii==iRowid + || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc) + ){ + if( bFromValid ){ + rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom); + }else{ + rc = sqlite3Fts5IterNext(p->pIter); + } + if( rc!=SQLITE_OK ) break; + if( sqlite3Fts5IterEof(p->pIter)==0 ){ + bEof = 0; + } + }else{ + bEof = 0; + } + } + } + + /* Set the EOF flag if either all synonym iterators are at EOF or an + ** error has occurred. */ + pNode->bEof = (rc || bEof); + }else{ + Fts5IndexIter *pIter = pTerm->pIter; + + assert( Fts5NodeIsString(pNode) ); + if( bFromValid ){ + rc = sqlite3Fts5IterNextFrom(pIter, iFrom); + }else{ + rc = sqlite3Fts5IterNext(pIter); + } + + pNode->bEof = (rc || sqlite3Fts5IterEof(pIter)); + } + + if( pNode->bEof==0 ){ + assert( rc==SQLITE_OK ); + rc = fts5ExprNodeTest_STRING(pExpr, pNode); + } + + return rc; +} + + +static int fts5ExprNodeTest_TERM( + Fts5Expr *pExpr, /* Expression that pNear is a part of */ + Fts5ExprNode *pNode /* The "NEAR" node (FTS5_TERM) */ +){ + /* As this "NEAR" object is actually a single phrase that consists + ** of a single term only, grab pointers into the poslist managed by the + ** fts5_index.c iterator object. This is much faster than synthesizing + ** a new poslist the way we have to for more complicated phrase or NEAR + ** expressions. */ + Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0]; + Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter; + + assert( pNode->eType==FTS5_TERM ); + assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 ); + assert( pPhrase->aTerm[0].pSynonym==0 ); + + pPhrase->poslist.n = pIter->nData; + if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){ + pPhrase->poslist.p = (u8*)pIter->pData; + } + pNode->iRowid = pIter->iRowid; + pNode->bNomatch = (pPhrase->poslist.n==0); + return SQLITE_OK; +} + +/* +** xNext() method for a node of type FTS5_TERM. +*/ +static int fts5ExprNodeNext_TERM( + Fts5Expr *pExpr, + Fts5ExprNode *pNode, + int bFromValid, + i64 iFrom +){ + int rc; + Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter; + + assert( pNode->bEof==0 ); + if( bFromValid ){ + rc = sqlite3Fts5IterNextFrom(pIter, iFrom); + }else{ + rc = sqlite3Fts5IterNext(pIter); + } + if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ + rc = fts5ExprNodeTest_TERM(pExpr, pNode); + }else{ + pNode->bEof = 1; + pNode->bNomatch = 0; + } + return rc; +} + +static void fts5ExprNodeTest_OR( + Fts5Expr *pExpr, /* Expression of which pNode is a part */ + Fts5ExprNode *pNode /* Expression node to test */ +){ + Fts5ExprNode *pNext = pNode->apChild[0]; + int i; + + for(i=1; inChild; i++){ + Fts5ExprNode *pChild = pNode->apChild[i]; + int cmp = fts5NodeCompare(pExpr, pNext, pChild); + if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){ + pNext = pChild; + } + } + pNode->iRowid = pNext->iRowid; + pNode->bEof = pNext->bEof; + pNode->bNomatch = pNext->bNomatch; +} + +static int fts5ExprNodeNext_OR( + Fts5Expr *pExpr, + Fts5ExprNode *pNode, + int bFromValid, + i64 iFrom +){ + int i; + i64 iLast = pNode->iRowid; + + for(i=0; inChild; i++){ + Fts5ExprNode *p1 = pNode->apChild[i]; + assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 ); + if( p1->bEof==0 ){ + if( (p1->iRowid==iLast) + || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0) + ){ + int rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom); + if( rc!=SQLITE_OK ) return rc; + } + } + } + + fts5ExprNodeTest_OR(pExpr, pNode); + return SQLITE_OK; +} + /* ** Argument pNode is an FTS5_AND node. */ -static int fts5ExprAndNextRowid( +static int fts5ExprNodeTest_AND( Fts5Expr *pExpr, /* Expression pPhrase belongs to */ Fts5ExprNode *pAnd /* FTS5_AND node to advance */ ){ @@ -1030,15 +1127,11 @@ static int fts5ExprAndNextRowid( bMatch = 1; for(iChild=0; iChildnChild; iChild++){ Fts5ExprNode *pChild = pAnd->apChild[iChild]; - if( 0 && pChild->eType==FTS5_STRING ){ - /* TODO */ - }else{ - int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid); - if( cmp>0 ){ - /* Advance pChild until it points to iLast or laster */ - rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast); - if( rc!=SQLITE_OK ) return rc; - } + int cmp = fts5RowidCmp(pExpr, iLast, pChild->iRowid); + if( cmp>0 ){ + /* Advance pChild until it points to iLast or laster */ + rc = fts5ExprNodeNext(pExpr, pChild, 1, iLast); + if( rc!=SQLITE_OK ) return rc; } /* If the child node is now at EOF, so is the parent AND node. Otherwise, @@ -1068,155 +1161,66 @@ static int fts5ExprAndNextRowid( return SQLITE_OK; } - -/* -** Compare the values currently indicated by the two nodes as follows: -** -** res = (*p1) - (*p2) -** -** Nodes that point to values that come later in the iteration order are -** considered to be larger. Nodes at EOF are the largest of all. -** -** This means that if the iteration order is ASC, then numerically larger -** rowids are considered larger. Or if it is the default DESC, numerically -** smaller rowids are larger. -*/ -static int fts5NodeCompare( - Fts5Expr *pExpr, - Fts5ExprNode *p1, - Fts5ExprNode *p2 -){ - if( p2->bEof ) return -1; - if( p1->bEof ) return +1; - return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid); -} - -/* -** xNext() method for a node of type FTS5_TERM. -*/ -static int fts5ExprNodeNext_Term( +static int fts5ExprNodeNext_AND( Fts5Expr *pExpr, Fts5ExprNode *pNode, int bFromValid, i64 iFrom ){ - int rc; - Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter; - - assert( pNode->bEof==0 ); - if( bFromValid ){ - rc = sqlite3Fts5IterNextFrom(pIter, iFrom); - }else{ - rc = sqlite3Fts5IterNext(pIter); - } - if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ - rc = fts5ExprTokenTest(pExpr, pNode); - }else{ - pNode->bEof = 1; - pNode->bNomatch = 0; + int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); + if( rc==SQLITE_OK ){ + rc = fts5ExprNodeTest_AND(pExpr, pNode); } return rc; } -/* -** Advance node iterator pNode, part of expression pExpr. If argument -** bFromValid is zero, then pNode is advanced exactly once. Or, if argument -** bFromValid is non-zero, then pNode is advanced until it is at or past -** rowid value iFrom. Whether "past" means "less than" or "greater than" -** depends on whether this is an ASC or DESC iterator. -*/ -static int fts5ExprNodeNext_Fallback( - Fts5Expr *pExpr, - Fts5ExprNode *pNode, - int bFromValid, - i64 iFrom +static int fts5ExprNodeTest_NOT( + Fts5Expr *pExpr, /* Expression pPhrase belongs to */ + Fts5ExprNode *pNode /* FTS5_NOT node to advance */ ){ int rc = SQLITE_OK; + Fts5ExprNode *p1 = pNode->apChild[0]; + Fts5ExprNode *p2 = pNode->apChild[1]; + assert( pNode->nChild==2 ); - if( pNode->bEof==0 ){ - switch( pNode->eType ){ - case FTS5_STRING: { - rc = fts5ExprNearAdvanceFirst(pExpr, pNode, bFromValid, iFrom); - break; - }; - - case FTS5_TERM: { - Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter; - if( bFromValid ){ - rc = sqlite3Fts5IterNextFrom(pIter, iFrom); - }else{ - rc = sqlite3Fts5IterNext(pIter); - } - if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ - assert( rc==SQLITE_OK ); - rc = fts5ExprTokenTest(pExpr, pNode); - }else{ - pNode->bEof = 1; - pNode->bNomatch = 0; - } - return rc; - }; - - case FTS5_AND: { - Fts5ExprNode *pLeft = pNode->apChild[0]; - rc = fts5ExprNodeNext(pExpr, pLeft, bFromValid, iFrom); - break; - } - - case FTS5_OR: { - int i; - i64 iLast = pNode->iRowid; - - for(i=0; rc==SQLITE_OK && inChild; i++){ - Fts5ExprNode *p1 = pNode->apChild[i]; - assert( p1->bEof || fts5RowidCmp(pExpr, p1->iRowid, iLast)>=0 ); - if( p1->bEof==0 ){ - if( (p1->iRowid==iLast) - || (bFromValid && fts5RowidCmp(pExpr, p1->iRowid, iFrom)<0) - ){ - rc = fts5ExprNodeNext(pExpr, p1, bFromValid, iFrom); - } - } - } - - break; - } - - default: assert( pNode->eType==FTS5_NOT ); { - assert( pNode->nChild==2 ); - rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); - break; - } - } - - if( rc==SQLITE_OK ){ - rc = fts5ExprNodeNextMatch(pExpr, pNode); + while( rc==SQLITE_OK && p1->bEof==0 ){ + int cmp = fts5NodeCompare(pExpr, p1, p2); + if( cmp>0 ){ + rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid); + cmp = fts5NodeCompare(pExpr, p1, p2); } + assert( rc!=SQLITE_OK || cmp<=0 ); + if( cmp || p2->bNomatch ) break; + rc = fts5ExprNodeNext(pExpr, p1, 0, 0); + } + pNode->bEof = p1->bEof; + pNode->bNomatch = p1->bNomatch; + pNode->iRowid = p1->iRowid; + if( p1->bEof ){ + fts5ExprNodeZeroPoslist(p2); } - - /* Assert that if bFromValid was true, either: - ** - ** a) an error occurred, or - ** b) the node is now at EOF, or - ** c) the node is now at or past rowid iFrom. - */ - assert( bFromValid==0 - || rc!=SQLITE_OK /* a */ - || pNode->bEof /* b */ - || pNode->iRowid==iFrom || pExpr->bDesc==(pNode->iRowidbNomatch==0 || rc==SQLITE_OK ); return rc; } +static int fts5ExprNodeNext_NOT( + Fts5Expr *pExpr, + Fts5ExprNode *pNode, + int bFromValid, + i64 iFrom +){ + int rc = fts5ExprNodeNext(pExpr, pNode->apChild[0], bFromValid, iFrom); + if( rc==SQLITE_OK ){ + rc = fts5ExprNodeTest_NOT(pExpr, pNode); + } + return rc; +} /* ** If pNode currently points to a match, this function returns SQLITE_OK ** without modifying it. Otherwise, pNode is advanced until it does point ** to a match or EOF is reached. */ -static int fts5ExprNodeNextMatch( +static int fts5ExprNodeTest( Fts5Expr *pExpr, /* Expression of which pNode is a part */ Fts5ExprNode *pNode /* Expression node to test */ ){ @@ -1225,59 +1229,27 @@ static int fts5ExprNodeNextMatch( switch( pNode->eType ){ case FTS5_STRING: { - /* Advance the iterators until they all point to the same rowid */ - rc = fts5ExprNearNextMatch(pExpr, pNode); + rc = fts5ExprNodeTest_STRING(pExpr, pNode); break; } case FTS5_TERM: { - rc = fts5ExprTokenTest(pExpr, pNode); + rc = fts5ExprNodeTest_TERM(pExpr, pNode); break; } case FTS5_AND: { - rc = fts5ExprAndNextRowid(pExpr, pNode); + rc = fts5ExprNodeTest_AND(pExpr, pNode); break; } case FTS5_OR: { - Fts5ExprNode *pNext = pNode->apChild[0]; - int i; - - for(i=1; inChild; i++){ - Fts5ExprNode *pChild = pNode->apChild[i]; - int cmp = fts5NodeCompare(pExpr, pNext, pChild); - if( cmp>0 || (cmp==0 && pChild->bNomatch==0) ){ - pNext = pChild; - } - } - pNode->iRowid = pNext->iRowid; - pNode->bEof = pNext->bEof; - pNode->bNomatch = pNext->bNomatch; + fts5ExprNodeTest_OR(pExpr, pNode); break; } default: assert( pNode->eType==FTS5_NOT ); { - Fts5ExprNode *p1 = pNode->apChild[0]; - Fts5ExprNode *p2 = pNode->apChild[1]; - assert( pNode->nChild==2 ); - - while( rc==SQLITE_OK && p1->bEof==0 ){ - int cmp = fts5NodeCompare(pExpr, p1, p2); - if( cmp>0 ){ - rc = fts5ExprNodeNext(pExpr, p2, 1, p1->iRowid); - cmp = fts5NodeCompare(pExpr, p1, p2); - } - assert( rc!=SQLITE_OK || cmp<=0 ); - if( cmp || p2->bNomatch ) break; - rc = fts5ExprNodeNext(pExpr, p1, 0, 0); - } - pNode->bEof = p1->bEof; - pNode->bNomatch = p1->bNomatch; - pNode->iRowid = p1->iRowid; - if( p1->bEof ){ - fts5ExprNodeZeroPoslist(p2); - } + rc = fts5ExprNodeTest_NOT(pExpr, pNode); break; } } @@ -1329,7 +1301,7 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){ } if( rc==SQLITE_OK ){ - rc = fts5ExprNodeNextMatch(pExpr, pNode); + rc = fts5ExprNodeTest(pExpr, pNode); } return rc; } @@ -1690,13 +1662,14 @@ int sqlite3Fts5ExprClonePhrase( pNew->apExprPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase; pNew->pRoot->pNear->nPhrase = 1; - pNew->pRoot->xNext = fts5ExprNodeNext_Fallback; sCtx.pPhrase->pNode = pNew->pRoot; if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){ pNew->pRoot->eType = FTS5_TERM; + pNew->pRoot->xNext = fts5ExprNodeNext_TERM; }else{ pNew->pRoot->eType = FTS5_STRING; + pNew->pRoot->xNext = fts5ExprNodeNext_STRING; } }else{ sqlite3Fts5ExprFree(pNew); @@ -1844,6 +1817,38 @@ void sqlite3Fts5ParseSetColset( } } +static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ + switch( pNode->eType ){ + case FTS5_STRING: { + Fts5ExprNearset *pNear = pNode->pNear; + if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 + && pNear->apPhrase[0]->aTerm[0].pSynonym==0 + ){ + pNode->eType = FTS5_TERM; + pNode->xNext = fts5ExprNodeNext_TERM; + }else{ + pNode->xNext = fts5ExprNodeNext_STRING; + } + break; + }; + + case FTS5_OR: { + pNode->xNext = fts5ExprNodeNext_OR; + break; + }; + + case FTS5_AND: { + pNode->xNext = fts5ExprNodeNext_AND; + break; + }; + + default: assert( pNode->eType==FTS5_NOT ); { + pNode->xNext = fts5ExprNodeNext_NOT; + break; + }; + } +} + static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ if( p->eType!=FTS5_NOT && pSub->eType==p->eType ){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; @@ -1891,20 +1896,18 @@ Fts5ExprNode *sqlite3Fts5ParseNode( pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ - pRet->xNext = fts5ExprNodeNext_Fallback; pRet->eType = eType; pRet->pNear = pNear; + fts5ExprAssignXNext(pRet); if( eType==FTS5_STRING ){ int iPhrase; for(iPhrase=0; iPhrasenPhrase; iPhrase++){ pNear->apPhrase[iPhrase]->pNode = pRet; } - if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 ){ - if( pNear->apPhrase[0]->aTerm[0].pSynonym==0 ){ - pRet->eType = FTS5_TERM; - pRet->xNext = fts5ExprNodeNext_Term; - } - }else if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){ + + if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL + && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm!=1) + ){ assert( pParse->rc==SQLITE_OK ); pParse->rc = SQLITE_ERROR; assert( pParse->zErr==0 ); @@ -1915,6 +1918,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode( sqlite3_free(pRet); pRet = 0; } + }else{ fts5ExprAddChildren(pRet, pLeft); fts5ExprAddChildren(pRet, pRight); diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index f30c38d91a..3b627dabad 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -518,7 +518,6 @@ struct Fts5Iter { int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ u8 bSkipEmpty; /* True to skip deleted entries */ - u8 bEof; /* True at EOF */ u8 bFiltered; /* True if column-filter already applied */ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ @@ -2459,7 +2458,7 @@ static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){ Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; int i; - assert( (pFirst->pLeaf==0)==pIter->bEof ); + assert( (pFirst->pLeaf==0)==pIter->base.bEof ); /* Check that pIter->iSwitchRowid is set correctly. */ for(i=0; inSeg; i++){ @@ -2731,7 +2730,7 @@ static int fts5MultiIterAdvanceRowid( */ static void fts5MultiIterSetEof(Fts5Iter *pIter){ Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ]; - pIter->bEof = pSeg->pLeaf==0; + pIter->base.bEof = pSeg->pLeaf==0; pIter->iSwitchRowid = pSeg->iRowid; } @@ -2964,7 +2963,7 @@ static void fts5MultiIterNew2( } pData = 0; }else{ - pNew->bEof = 1; + pNew->base.bEof = 1; } fts5SegIterSetNext(p, pIter); @@ -2980,9 +2979,9 @@ static void fts5MultiIterNew2( */ static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){ assert( p->rc - || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof + || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof ); - return (p->rc || pIter->bEof); + return (p->rc || pIter->base.bEof); } /* @@ -5209,11 +5208,6 @@ int sqlite3Fts5IndexQuery( /* ** Return true if the iterator passed as the only argument is at EOF. */ -int sqlite3Fts5IterEof(Fts5IndexIter *pIter){ - assert( ((Fts5Iter*)pIter)->pIndex->rc==SQLITE_OK ); - return ((Fts5Iter*)pIter)->bEof; -} - /* ** Move to the next matching rowid. */ @@ -5239,7 +5233,7 @@ int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ if( pSeg->pLeaf && pSeg->term.p[0]!=FTS5_MAIN_PREFIX ){ fts5DataRelease(pSeg->pLeaf); pSeg->pLeaf = 0; - pIter->bEof = 1; + pIter->base.bEof = 1; } } @@ -5257,13 +5251,6 @@ int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ return fts5IndexReturn(pIter->pIndex); } -/* -** Return the current rowid. -*/ -i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIndexIter){ - return fts5MultiIterRowid((Fts5Iter*)pIndexIter); -} - /* ** Return the current term. */ @@ -5450,7 +5437,7 @@ static int fts5QueryCksum( int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ - i64 rowid = sqlite3Fts5IterRowid(pIter); + i64 rowid = pIter->iRowid; if( eDetail==FTS5_DETAIL_NONE ){ cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); diff --git a/ext/fts5/tool/fts5speed.tcl b/ext/fts5/tool/fts5speed.tcl index f0e96e348d..0f38638c26 100644 --- a/ext/fts5/tool/fts5speed.tcl +++ b/ext/fts5/tool/fts5speed.tcl @@ -12,6 +12,10 @@ set Q { {1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"} {1 "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"} {2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"} + + {2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes OR e:holmes OR f:holmes OR g:holmes'" } + {2 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes AND e:holmes AND f:holmes AND g:holmes'" } + {4 "SELECT count(*) FROM t1 WHERE t1 MATCH 'd:holmes NOT e:holmes'" } } proc usage {} { diff --git a/manifest b/manifest index 3952435799..44101197f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\scomment\son\sthe\ssqlite3_index_constraint\sobject\sto\sbring\sattention\s\nto\sthe\sfact\sthan\siColumn\sfield\scan\sbe\snegative\sfor\sa\srowid. -D 2016-02-02T02:04:21.840 +C Enhance\sthe\sperformance\sof\sfts5\sAND\sand\sOR\squeries. +D 2016-02-02T17:40:41.411 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -98,13 +98,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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 6e0f90eb4872654a5b98130dec16965716525c9a +F ext/fts5/fts5Int.h 9505f3bc8d0b2ca4cd2b112e7e042e3c6a3222a7 F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 -F ext/fts5/fts5_expr.c 768d221e592df03b26f46da56aa0a561f00fa4e0 +F ext/fts5/fts5_expr.c 304b22448ee0c3056d4177e327ed62dc80cbe23a F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c cd1e4faca8b9adc2d89b367075bf93a7f50c406b +F ext/fts5/fts5_index.c 471ff6935068a4579830474249e1046b57137103 F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -190,7 +190,7 @@ F ext/fts5/test/fts5unindexed.test e9539d5b78c677315e7ed8ea911d4fd25437c680 F ext/fts5/test/fts5update.test 57c7012a7919889048947addae10e0613df45529 F ext/fts5/test/fts5version.test 978f59541d8cef7e8591f8be2115ec5ccb863e2e F ext/fts5/test/fts5vocab.test 480d780aa6b699816c5066225fbd86f3a0239477 -F ext/fts5/tool/fts5speed.tcl f9944a9abb9b7685cfbee8101a3dd772ededca66 +F ext/fts5/tool/fts5speed.tcl b0056f91a55b2d1a3684ec05729de92b042e2f85 F ext/fts5/tool/fts5txt2db.tcl 1343745b89ca2a1e975c23f836d0cee410052975 F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl d1c2a9ab8e0ec690a52316f33dd9b1d379942f45 @@ -1422,7 +1422,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 6d7d4703ebf3754bec74123d5ba7e861a705f90f -R a0fd58918162f72722cea72a597641d9 -U drh -Z 8a77cde1543981fcb216eb719b02e019 +P d8b7b1996eefae7768bfcb82d4ff22c69392aa63 +R e61034725c181be1c4702281e2c951bc +U dan +Z e59ee5dbb82eef632e47f5b2b9e1cde6 diff --git a/manifest.uuid b/manifest.uuid index dae04066fb..0a6e70dd4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8b7b1996eefae7768bfcb82d4ff22c69392aa63 \ No newline at end of file +62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e \ No newline at end of file From b06347a5dcab801ba317cbf36043f8f70df0deec Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 2 Feb 2016 21:19:21 +0000 Subject: [PATCH 070/107] Add tests to restore full coverage of fts5 code. FossilOrigin-Name: 063755c81574800e7db12a42e17d982a8c1e5181 --- ext/fts5/fts5_expr.c | 3 +- ext/fts5/test/fts5fault1.test | 3 +- ext/fts5/test/fts5fault2.test | 2 +- ext/fts5/test/fts5fault7.test | 9 ++++- ext/fts5/test/fts5fault8.test | 51 +++++++++++++++------------ ext/fts5/test/fts5faultA.test | 64 ++++++++++++++++++++++++++++++++++ ext/fts5/test/fts5simple3.test | 41 ++++++++++++++++++++++ manifest | 23 ++++++------ manifest.uuid | 2 +- 9 files changed, 159 insertions(+), 39 deletions(-) create mode 100644 ext/fts5/test/fts5faultA.test diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 1df173cfcc..5006d88d0f 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1337,7 +1337,8 @@ int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ } /* If the iterator is not at a real match, skip forward until it is. */ - while( pRoot->bNomatch && rc==SQLITE_OK && pRoot->bEof==0 ){ + while( pRoot->bNomatch ){ + assert( pRoot->bEof==0 && rc==SQLITE_OK ); rc = fts5ExprNodeNext(p, pRoot, 0, 0); } } diff --git a/ext/fts5/test/fts5fault1.test b/ext/fts5/test/fts5fault1.test index 429ea39af0..9d63a1175f 100644 --- a/ext/fts5/test/fts5fault1.test +++ b/ext/fts5/test/fts5fault1.test @@ -72,7 +72,7 @@ do_faultsim_test 3 -prep { reset_db do_execsql_test 4.0 { CREATE VIRTUAL TABLE t2 USING fts5(a, b); - INSERT INTO t2 VALUES('m f a jj th q jr ar', 'hj n h h sg j i m'); + INSERT INTO t2 VALUES('m f a jj th q gi ar', 'hj n h h sg j i m'); INSERT INTO t2 VALUES('nr s t g od j kf h', 'sb h aq rg op rb n nl'); INSERT INTO t2 VALUES('do h h pb p p q fr', 'c rj qs or cr a l i'); INSERT INTO t2 VALUES('lk gp t i lq mq qm p', 'h mr g f op ld aj h'); @@ -95,6 +95,7 @@ foreach {tn expr res} { 7 { NEAR(r a, 5) } {9} 8 { m* f* } {1 4 6 8 9 10} 9 { m* + f* } {1 8} + 10 { c NOT p } {5 6 7 10} } { do_faultsim_test 4.$tn -prep { faultsim_restore_and_reopen diff --git a/ext/fts5/test/fts5fault2.test b/ext/fts5/test/fts5fault2.test index ef1df8826a..43c7c7a3dd 100644 --- a/ext/fts5/test/fts5fault2.test +++ b/ext/fts5/test/fts5fault2.test @@ -16,7 +16,7 @@ source [file join [file dirname [info script]] fts5_common.tcl] source $testdir/malloc_common.tcl set testprefix fts5fault2 -# 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/fts5fault7.test b/ext/fts5/test/fts5fault7.test index bfe6420615..a35b19ade2 100644 --- a/ext/fts5/test/fts5fault7.test +++ b/ext/fts5/test/fts5fault7.test @@ -99,7 +99,7 @@ do_execsql_test 2.0 { } faultsim_save_and_close -do_faultsim_test 2 -faults oom-* -prep { +do_faultsim_test 2.1 -faults oom-* -prep { faultsim_restore_and_reopen } -body { db eval { UPDATE OR REPLACE xy SET rowid=3 WHERE rowid = 2 } @@ -107,6 +107,13 @@ do_faultsim_test 2 -faults oom-* -prep { faultsim_test_result {0 {}} } +# Test fault-injection when an empty expression is parsed. +# +do_faultsim_test 2.2 -faults oom-* -body { + db eval { SELECT * FROM xy('""') } +} -test { + faultsim_test_result {0 {}} +} finish_test diff --git a/ext/fts5/test/fts5fault8.test b/ext/fts5/test/fts5fault8.test index d93066c6c0..ae5849495b 100644 --- a/ext/fts5/test/fts5fault8.test +++ b/ext/fts5/test/fts5fault8.test @@ -24,32 +24,37 @@ ifcapable !fts5 { foreach_detail_mode $testprefix { -fts5_aux_test_functions db -do_execsql_test 1.0 { - CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); - INSERT INTO t1 VALUES('a b c d', '1 2 3 4'); - INSERT INTO t1 VALUES('a b a b', NULL); - INSERT INTO t1 VALUES(NULL, '1 2 1 2'); -} - -do_faultsim_test 1 -faults oom-* -body { - execsql { - SELECT rowid, fts5_test_poslist(t1) FROM t1 WHERE t1 MATCH 'b OR 2' + fts5_aux_test_functions db + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%); + INSERT INTO t1 VALUES('a b c d', '1 2 3 4'); + INSERT INTO t1 VALUES('a b a b', NULL); + INSERT INTO t1 VALUES(NULL, '1 2 1 2'); } -} -test { - faultsim_test_result {0 {1 {0.0.1 1.1.1} 2 {0.0.1 0.0.3} 3 {1.1.1 1.1.3}}} \ - {1 SQLITE_NOMEM} -} - -do_faultsim_test 2 -faults oom-* -body { - execsql { - INSERT INTO t1(t1) VALUES('integrity-check'); + + do_faultsim_test 1 -faults oom-* -body { + execsql { + SELECT rowid, fts5_test_poslist(t1) FROM t1 WHERE t1 MATCH 'b OR 2' + } + } -test { + faultsim_test_result {0 {1 {0.0.1 1.1.1} 2 {0.0.1 0.0.3} 3 {1.1.1 1.1.3}}} \ + {1 SQLITE_NOMEM} + } + + do_faultsim_test 2 -faults oom-* -body { + execsql { INSERT INTO t1(t1) VALUES('integrity-check') } + } -test { + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} } -} -test { - faultsim_test_result {0 {}} {1 SQLITE_NOMEM} -} -} + if {[detail_is_none]==0} { + do_faultsim_test 3 -faults oom-* -body { + execsql { SELECT rowid FROM t1('b:2') } + } -test { + faultsim_test_result {0 {1 3}} {1 SQLITE_NOMEM} + } + } +} ;# foreach_detail_mode... finish_test diff --git a/ext/fts5/test/fts5faultA.test b/ext/fts5/test/fts5faultA.test new file mode 100644 index 0000000000..817ccb4ee8 --- /dev/null +++ b/ext/fts5/test/fts5faultA.test @@ -0,0 +1,64 @@ +# 2016 February 2 +# +# 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 is focused on OOM errors. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultA + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +foreach_detail_mode $testprefix { + do_execsql_test 1.0 { + CREATE VIRTUAL TABLE o1 USING fts5(a, detail=%DETAIL%); + INSERT INTO o1(o1, rank) VALUES('pgsz', 32); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 ) + INSERT INTO o1 SELECT 'A B C' FROM s; + + INSERT INTO o1 VALUES('A X C'); + + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 ) + INSERT INTO o1 SELECT 'A B C' FROM s; + } + + do_faultsim_test 1 -faults oom* -prep { + sqlite3 db test.db + } -body { + execsql { SELECT rowid FROM o1('a NOT b') } + } -test { + faultsim_test_result {0 301} + } +} + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE o2 USING fts5(a); + + INSERT INTO o2 VALUES('A B C'); + WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<300 ) + INSERT INTO o2 SELECT group_concat('A B C ') FROM s; +} + +do_faultsim_test 2 -faults oom* -prep { + sqlite3 db test.db +} -body { + execsql { SELECT rowid FROM o2('a+b+c NOT xyz') } +} -test { + faultsim_test_result {0 {1 2}} +} +finish_test + diff --git a/ext/fts5/test/fts5simple3.test b/ext/fts5/test/fts5simple3.test index b84a3e56dd..b6922f84dd 100644 --- a/ext/fts5/test/fts5simple3.test +++ b/ext/fts5/test/fts5simple3.test @@ -39,6 +39,47 @@ do_execsql_test 1.3 { SELECT rowid, fts5_test_collist(t1) FROM t1('b:a'); } {} +#------------------------------------------------------------------------- +# Create detail=col and detail=full tables with 998 columns. +# +foreach_detail_mode $testprefix { + if {[detail_is_none]} continue + + do_test 2.1 { + execsql { DROP TABLE IF EXISTS t2 } + set cols [list] + set vals [list] + for {set i 1} {$i <= 998} {incr i} { + lappend cols "c$i" + lappend vals "'val$i'" + } + execsql "CREATE VIRTUAL TABLE t2 USING fts5(detail=%DETAIL%,[join $cols ,])" + } {} + + do_test 2.2 { + execsql "INSERT INTO t2 VALUES([join $vals ,])" + } {} + + foreach {tn q res} { + 1 { c1:val1 } 1 + 2 { c300:val300 } 1 + 3 { c300:val1 } {} + 4 { c1:val300 } {} + } { + do_execsql_test 2.3.$tn { + SELECT rowid FROM t2($q) + } $res + } +} + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE x3 USING fts5(one); + INSERT INTO x3 VALUES('a b c'); + INSERT INTO x3 VALUES('c b a'); + INSERT INTO x3 VALUES('o t t'); + SELECT * FROM x3('x OR y OR z'); +} + finish_test diff --git a/manifest b/manifest index 44101197f7..c1cd05951c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sperformance\sof\sfts5\sAND\sand\sOR\squeries. -D 2016-02-02T17:40:41.411 +C Add\stests\sto\srestore\sfull\scoverage\sof\sfts5\scode. +D 2016-02-02T21:19:21.156 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -102,7 +102,7 @@ F ext/fts5/fts5Int.h 9505f3bc8d0b2ca4cd2b112e7e042e3c6a3222a7 F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 -F ext/fts5/fts5_expr.c 304b22448ee0c3056d4177e327ed62dc80cbe23a +F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 F ext/fts5/fts5_index.c 471ff6935068a4579830474249e1046b57137103 F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d @@ -147,15 +147,16 @@ F ext/fts5/test/fts5dlidx.test 13871a14641017ae42f6f1055a8067bafd44cb3d F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 F ext/fts5/test/fts5eb.test 021aa80b7ac09b964249aa32ced9ee908703e4aa -F ext/fts5/test/fts5fault1.test 4b39c47ca3544615daa8a2f733b911fa08022c77 -F ext/fts5/test/fts5fault2.test 28c36c843bb39ae855ba79827417ecc37f114341 +F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7 +F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3 F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277 F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda -F ext/fts5/test/fts5fault7.test 01be274bfc8d9bf22451a3bf5892e9399d044f1b -F ext/fts5/test/fts5fault8.test f2d8a2b673a5f72ca1fa0e85bdbfb2041ffd347d +F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080 +F ext/fts5/test/fts5fault8.test 430837fe6dd0511fd3aea52bd602ac02441bcb58 F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08 +F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741 F ext/fts5/test/fts5hash.test 00668f6fa9b9bffbd7c1be29f408aa2bdade0451 F ext/fts5/test/fts5integrity.test f5e4f8d284385875068ad0f3e894ce43e9de835d @@ -177,7 +178,7 @@ F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6 F ext/fts5/test/fts5simple.test 7fcacfa473a37355af2e60096650c87b5ba8f3ba F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46 -F ext/fts5/test/fts5simple3.test e671b36bc4dbd4f5095e66cb04473cba9f680f53 +F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48 F ext/fts5/test/fts5synonym2.test aa4c43bd3b691ff80f658cb064f5ab40690e834e F ext/fts5/test/fts5tok1.test beb894c6f3468f10a574302f69ebe4436b0287c7 @@ -1422,7 +1423,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 d8b7b1996eefae7768bfcb82d4ff22c69392aa63 -R e61034725c181be1c4702281e2c951bc +P 62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e +R e3a290a62981c78902a14c3c2f0729a7 U dan -Z e59ee5dbb82eef632e47f5b2b9e1cde6 +Z 6792ae7332aab4430b100fd43f303a7d diff --git a/manifest.uuid b/manifest.uuid index 0a6e70dd4e..0d75e9b7c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e \ No newline at end of file +063755c81574800e7db12a42e17d982a8c1e5181 \ No newline at end of file From 1b32554b80cd84bbc93075e5b4dd803bdcf65748 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Feb 2016 01:55:44 +0000 Subject: [PATCH 071/107] Enhance the internal sqlite3VdbeAddOpList() interface to automatically update jump destinations. Use this feature to simplify the AUTOINCREMENT code generator. FossilOrigin-Name: ae8b9d2edf1b5aef6108e729754911db7682b6a3 --- manifest | 22 +++++++-------- manifest.uuid | 2 +- src/insert.c | 73 +++++++++++++++++++++++++++++++++---------------- src/pragma.c | 5 ++-- src/sqliteInt.h | 2 +- src/vdbeaux.c | 6 ++++ src/vdbeblob.c | 22 +++++++-------- 7 files changed, 80 insertions(+), 52 deletions(-) diff --git a/manifest b/manifest index c1cd05951c..1fd0c856ce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\srestore\sfull\scoverage\sof\sfts5\scode. -D 2016-02-02T21:19:21.156 +C Enhance\sthe\sinternal\ssqlite3VdbeAddOpList()\sinterface\sto\sautomatically\supdate\njump\sdestinations.\s\sUse\sthis\sfeature\sto\ssimplify\sthe\sAUTOINCREMENT\scode\ngenerator. +D 2016-02-03T01:55:44.089 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -309,7 +309,7 @@ F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 410f52b9ef4603dc0aebb169b7cb6b3c60eda07e +F src/insert.c 3e2462294fc8bc6e46f377ec824ff315e79fc36d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b @@ -341,7 +341,7 @@ F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c 2ac26ac45eedbed3cc8a9a320ad6d2fc299e69a6 +F src/pragma.c a973357ef2faded933725a6de2883133deb24029 F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 @@ -353,7 +353,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h 2f80b9b1506a8d602b2a99f3f0bfae22df3e7d70 +F src/sqliteInt.h ed6f75088781af7cbd0a6653c2fe16340faa0dd4 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -417,8 +417,8 @@ F src/vdbe.c a0a0ada4b51161d3950fe30fc696b6c8235a841f F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 -F src/vdbeaux.c f0e7cfa04f7ac44d69866868531dbaf20659d0a2 -F src/vdbeblob.c 37c3d11a753e403698c69e17383d282e1ae73e75 +F src/vdbeaux.c 23b38b447ebf5991de1d3d456003c58cf523a5da +F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 @@ -1423,7 +1423,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 62ea9e5ab8bc1a20245beebceb5ea62dcd7ec84e -R e3a290a62981c78902a14c3c2f0729a7 -U dan -Z 6792ae7332aab4430b100fd43f303a7d +P 063755c81574800e7db12a42e17d982a8c1e5181 +R 03bd7861865ae8f6fba63605b50d909b +U drh +Z 0f50d7954b5cdd37df3317e2f95eccf8 diff --git a/manifest.uuid b/manifest.uuid index 0d75e9b7c9..e0288532b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -063755c81574800e7db12a42e17d982a8c1e5181 \ No newline at end of file +ae8b9d2edf1b5aef6108e729754911db7682b6a3 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index cbe933c221..5f36c089f6 100644 --- a/src/insert.c +++ b/src/insert.c @@ -254,7 +254,6 @@ void sqlite3AutoincrementBegin(Parse *pParse){ sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* Database only autoinc table */ int memId; /* Register holding max rowid */ - int addr; /* A VDBE address */ Vdbe *v = pParse->pVdbe; /* VDBE under construction */ /* This routine is never called during trigger-generation. It is @@ -264,33 +263,46 @@ void sqlite3AutoincrementBegin(Parse *pParse){ assert( v ); /* We failed long ago if this is not so */ for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoInc[] = { + /* 0 */ {OP_Null, 0, 0, 0}, + /* 1 */ {OP_Rewind, 0, 9, 0}, + /* 2 */ {OP_Column, 0, 0, 0}, + /* 3 */ {OP_Ne, 0, 7, 0}, + /* 4 */ {OP_Rowid, 0, 0, 0}, + /* 5 */ {OP_Column, 0, 1, 0}, + /* 6 */ {OP_Goto, 0, 9, 0}, + /* 7 */ {OP_Next, 0, 2, 0}, + /* 8 */ {OP_Integer, 0, 0, 0}, + /* 9 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; pDb = &db->aDb[p->iDb]; memId = p->regCtr; assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_Null, 0, memId, memId+1); - addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); - sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); VdbeCoverage(v); - sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); - sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); VdbeCoverage(v); - sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); - sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); - sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId); - sqlite3VdbeGoto(v, addr+9); - sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); - sqlite3VdbeAddOp0(v, OP_Close); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); + if( aOp==0 ) break; + aOp[0].p2 = memId; + aOp[0].p3 = memId+1; + aOp[2].p3 = memId; + aOp[3].p1 = memId-1; + aOp[3].p3 = memId; + aOp[3].p5 = SQLITE_JUMPIFNULL; + aOp[4].p2 = memId+1; + aOp[5].p3 = memId; + aOp[8].p2 = memId; } } /* ** Update the maximum rowid for an autoincrement calculation. ** -** This routine should be called when the top of the stack holds a +** This routine should be called when the regRowid register holds a ** new rowid that is about to be inserted. If that new rowid is ** larger than the maximum rowid in the memId memory cell, then the -** memory cell is updated. The stack is unchanged. +** memory cell is updated. */ static void autoIncStep(Parse *pParse, int memId, int regRowid){ if( memId>0 ){ @@ -305,31 +317,44 @@ static void autoIncStep(Parse *pParse, int memId, int regRowid){ ** table (either directly or through triggers) needs to call this ** routine just before the "exit" code. */ -void sqlite3AutoincrementEnd(Parse *pParse){ +static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ AutoincInfo *p; Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; assert( v ); for(p = pParse->pAinc; p; p = p->pNext){ + static const int iLn = VDBE_OFFSET_LINENO(2); + static const VdbeOpList autoIncEnd[] = { + /* 0 */ {OP_NotNull, 0, 2, 0}, + /* 1 */ {OP_NewRowid, 0, 0, 0}, + /* 2 */ {OP_MakeRecord, 0, 2, 0}, + /* 3 */ {OP_Insert, 0, 0, 0}, + /* 4 */ {OP_Close, 0, 0, 0} + }; + VdbeOp *aOp; Db *pDb = &db->aDb[p->iDb]; - int addr1; int iRec; int memId = p->regCtr; iRec = sqlite3GetTempReg(pParse); assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); - sqlite3VdbeJumpHere(v, addr1); - sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); - sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3VdbeAddOp0(v, OP_Close); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); + if( aOp==0 ) break; + aOp[0].p1 = memId+1; + aOp[1].p2 = memId+1; + aOp[2].p1 = memId-1; + aOp[2].p3 = iRec; + aOp[3].p2 = iRec; + aOp[3].p3 = memId+1; + aOp[3].p5 = OPFLAG_APPEND; sqlite3ReleaseTempReg(pParse, iRec); } } +void sqlite3AutoincrementEnd(Parse *pParse){ + if( pParse->pAinc ) autoIncrementEnd(pParse); +} #else /* ** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines diff --git a/src/pragma.c b/src/pragma.c index 1d827d7b70..c62c8d2afd 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1599,16 +1599,15 @@ void sqlite3Pragma( static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList endCode[] = { { OP_AddImm, 1, 0, 0}, /* 0 */ - { OP_If, 1, 0, 0}, /* 1 */ + { OP_If, 1, 4, 0}, /* 1 */ { OP_String8, 0, 3, 0}, /* 2 */ - { OP_ResultRow, 3, 1, 0}, + { OP_ResultRow, 3, 1, 0}, /* 3 */ }; VdbeOp *aOp; aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); if( aOp ){ aOp[0].p2 = -mxErr; - aOp[1].p2 = sqlite3VdbeCurrentAddr(v); aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index dbe1595af9..c18e837263 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2641,7 +2641,7 @@ struct SelectDest { ** tables, the following information is attached to the Table.u.autoInc.p ** pointer of each autoincrement table to record some side information that ** the code generator needs. We have to keep per-table autoincrement -** information in case inserts are down within triggers. Triggers do not +** information in case inserts are done within triggers. Triggers do not ** normally coordinate their activities, but we do need to coordinate the ** loading and saving of autoincrement information. */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 13aef0d7fd..632c1231aa 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -646,6 +646,9 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ /* ** Add a whole list of operations to the operation stack. Return a ** pointer to the first operation inserted. +** +** Non-zero P2 arguments to jump instructions are automatically adjusted +** so that the jump target is relative to the first operation inserted. */ VdbeOp *sqlite3VdbeAddOpList( Vdbe *p, /* Add opcodes to the prepared statement */ @@ -666,6 +669,9 @@ VdbeOp *sqlite3VdbeAddOpList( pOut->p1 = aOp->p1; pOut->p2 = aOp->p2; assert( aOp->p2>=0 ); + if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ + pOut->p2 += p->nOp; + } pOut->p3 = aOp->p3; pOut->p4type = P4_NOTUSED; pOut->p4.p = 0; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index f9015ad6f4..2ba5301e7a 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -249,19 +249,17 @@ int sqlite3_blob_open( ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ - static const int iLn = VDBE_OFFSET_LINENO(4); + static const int iLn = VDBE_OFFSET_LINENO(2); static const VdbeOpList openBlob[] = { - /* addr/ofst */ - /* {OP_Transaction, 0, 0, 0}, // 0/ inserted separately */ - {OP_TableLock, 0, 0, 0}, /* 1/0: Acquire a read or write lock */ - {OP_OpenRead, 0, 0, 0}, /* 2/1: Open a cursor */ - {OP_Variable, 1, 1, 0}, /* 3/2: Move ?1 into reg[1] */ - {OP_NotExists, 0, 8, 1}, /* 4/3: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 5/4 */ - {OP_ResultRow, 1, 0, 0}, /* 6/5 */ - {OP_Goto, 0, 3, 0}, /* 7/6 */ - {OP_Close, 0, 0, 0}, /* 8/7 */ - {OP_Halt, 0, 0, 0}, /* 9/8 */ + {OP_TableLock, 0, 0, 0}, /* 0: Acquire a read or write lock */ + {OP_OpenRead, 0, 0, 0}, /* 1: Open a cursor */ + {OP_Variable, 1, 1, 0}, /* 2: Move ?1 into reg[1] */ + {OP_NotExists, 0, 7, 1}, /* 3: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 4 */ + {OP_ResultRow, 1, 0, 0}, /* 5 */ + {OP_Goto, 0, 2, 0}, /* 6 */ + {OP_Close, 0, 0, 0}, /* 7 */ + {OP_Halt, 0, 0, 0}, /* 8 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); From 6841b1cb3dfd12edbc1f147bdc08887199f11cce Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Feb 2016 19:20:15 +0000 Subject: [PATCH 072/107] Add "PRAGMA synchronous=EXTRA" which syncs the directory containing the rollback journal when the rollback journal is deleted in order to commit a transaction in DELETE mode. FossilOrigin-Name: af92401826f5cf49e62c278f344ab75252a18da2 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/pager.c | 22 +++++++++++++++++----- src/pager.h | 11 ++++++----- src/pragma.c | 23 +++++++++++++---------- src/sqliteInt.h | 8 ++++---- test/pragma.test | 20 +++++++++++++++++--- 7 files changed, 68 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 1fd0c856ce..19dbe602f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sinternal\ssqlite3VdbeAddOpList()\sinterface\sto\sautomatically\supdate\njump\sdestinations.\s\sUse\sthis\sfeature\sto\ssimplify\sthe\sAUTOINCREMENT\scode\ngenerator. -D 2016-02-03T01:55:44.089 +C Add\s"PRAGMA\ssynchronous=EXTRA"\swhich\ssyncs\sthe\sdirectory\scontaining\sthe\nrollback\sjournal\swhen\sthe\srollback\sjournal\sis\sdeleted\sin\sorder\sto\scommit\sa\s\ntransaction\sin\sDELETE\smode. +D 2016-02-03T19:20:15.585 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -335,13 +335,13 @@ F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 2916c66aee50f69d9ec56a7619b62d9c6a3bee61 -F src/pager.h 1c2a49143dfba9e69cc8159ef019f472ed8d260b +F src/pager.c 3e189231fc662710964b54862450bc7f69f313c2 +F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865 F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c a973357ef2faded933725a6de2883133deb24029 +F src/pragma.c 3c4f3fadf05893e289f2adf3a20c671a842cadec F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 @@ -353,7 +353,7 @@ F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h ed6f75088781af7cbd0a6653c2fe16340faa0dd4 +F src/sqliteInt.h bf8c17fb55d7cd09b477111212b19d661b134989 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -943,7 +943,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 4ea119731c62d2f7d0aa86dd5b184cbb61ca411b -F test/pragma.test a44253f911e7d50127d4a08f927f47c861a4c772 +F test/pragma.test 507ac7ef2ea5682241ea0ef041799ca70bb5e0bf F test/pragma2.test a9400a7289605280576098b97f5cde3f204075c0 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc @@ -1423,7 +1423,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 063755c81574800e7db12a42e17d982a8c1e5181 -R 03bd7861865ae8f6fba63605b50d909b +P ae8b9d2edf1b5aef6108e729754911db7682b6a3 +R 1a8761ef82294be8ac021b32cc3428ab U drh -Z 0f50d7954b5cdd37df3317e2f95eccf8 +Z 47031796dc00696c427dc7b231b9f896 diff --git a/manifest.uuid b/manifest.uuid index e0288532b8..4b62d72b22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ae8b9d2edf1b5aef6108e729754911db7682b6a3 \ No newline at end of file +af92401826f5cf49e62c278f344ab75252a18da2 \ No newline at end of file diff --git a/src/pager.c b/src/pager.c index 0afbe215c6..8f1635d9ee 100644 --- a/src/pager.c +++ b/src/pager.c @@ -637,6 +637,7 @@ struct Pager { u8 useJournal; /* Use a rollback journal on this file */ u8 noSync; /* Do not sync the journal if true */ u8 fullSync; /* Do extra syncs of the journal for robustness */ + u8 extraSync; /* sync directory after journal delete */ u8 ckptSyncFlags; /* SYNC_NORMAL or SYNC_FULL for checkpoint */ u8 walSyncFlags; /* SYNC_NORMAL or SYNC_FULL for wal writes */ u8 syncFlags; /* SYNC_NORMAL or SYNC_FULL otherwise */ @@ -1997,8 +1998,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ ); sqlite3OsClose(pPager->jfd); if( bDelete ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, - pPager->fullSync && SQLITE_EXTRA_DURABLE); + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); } } } @@ -3504,9 +3504,15 @@ void sqlite3PagerSetFlags( unsigned pgFlags /* Various flags */ ){ unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK; - assert( level>=1 && level<=3 ); - pPager->noSync = (level==1 || pPager->tempFile) ?1:0; - pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0; + if( pPager->tempFile ){ + pPager->noSync = 1; + pPager->fullSync = 0; + pPager->extraSync = 0; + }else{ + pPager->noSync = level==PAGER_SYNCHRONOUS_OFF ?1:0; + pPager->fullSync = level>=PAGER_SYNCHRONOUS_FULL ?1:0; + pPager->extraSync = level==PAGER_SYNCHRONOUS_EXTRA ?1:0; + } if( pPager->noSync ){ pPager->syncFlags = 0; pPager->ckptSyncFlags = 0; @@ -4811,11 +4817,17 @@ act_like_temp_file: pPager->noSync = pPager->tempFile; if( pPager->noSync ){ assert( pPager->fullSync==0 ); + assert( pPager->extraSync==0 ); assert( pPager->syncFlags==0 ); assert( pPager->walSyncFlags==0 ); assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; +#ifdef SQLITE_EXTRA_DURABLE + pPager->extraSync = 1; +#else + pPager->extraSync = 0; +#endif pPager->syncFlags = SQLITE_SYNC_NORMAL; pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS; pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL; diff --git a/src/pager.h b/src/pager.h index 3552a876e7..8d9f08108d 100644 --- a/src/pager.h +++ b/src/pager.h @@ -90,11 +90,12 @@ typedef struct PgHdr DbPage; #define PAGER_SYNCHRONOUS_OFF 0x01 /* PRAGMA synchronous=OFF */ #define PAGER_SYNCHRONOUS_NORMAL 0x02 /* PRAGMA synchronous=NORMAL */ #define PAGER_SYNCHRONOUS_FULL 0x03 /* PRAGMA synchronous=FULL */ -#define PAGER_SYNCHRONOUS_MASK 0x03 /* Mask for three values above */ -#define PAGER_FULLFSYNC 0x04 /* PRAGMA fullfsync=ON */ -#define PAGER_CKPT_FULLFSYNC 0x08 /* PRAGMA checkpoint_fullfsync=ON */ -#define PAGER_CACHESPILL 0x10 /* PRAGMA cache_spill=ON */ -#define PAGER_FLAGS_MASK 0x1c /* All above except SYNCHRONOUS */ +#define PAGER_SYNCHRONOUS_EXTRA 0x04 /* PRAGMA synchronous=EXTRA */ +#define PAGER_SYNCHRONOUS_MASK 0x07 /* Mask for four values above */ +#define PAGER_FULLFSYNC 0x08 /* PRAGMA fullfsync=ON */ +#define PAGER_CKPT_FULLFSYNC 0x10 /* PRAGMA checkpoint_fullfsync=ON */ +#define PAGER_CACHESPILL 0x20 /* PRAGMA cache_spill=ON */ +#define PAGER_FLAGS_MASK 0x38 /* All above except SYNCHRONOUS */ /* ** The remainder of this file contains the declarations of the functions diff --git a/src/pragma.c b/src/pragma.c index c62c8d2afd..bde17d1e86 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -32,8 +32,8 @@ /* ** Interpret the given string as a safety level. Return 0 for OFF, -** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or -** unrecognized string argument. The FULL option is disallowed +** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or +** unrecognized string argument. The FULL and EXTRA option is disallowed ** if the omitFull parameter it 1. ** ** Note that the values returned are one less that the values that @@ -42,18 +42,21 @@ ** and older scripts may have used numbers 0 for OFF and 1 for ON. */ static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ - /* 123456789 123456789 */ - static const char zText[] = "onoffalseyestruefull"; - static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 16}; - static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 4}; - static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 2}; + /* 123456789 123456789 123 */ + static const char zText[] = "onoffalseyestruextrafull"; + static const u8 iOffset[] = {0, 1, 2, 4, 9, 12, 15, 20}; + static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; + static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; + /* on no off false yes true extra full */ int i, n; if( sqlite3Isdigit(*z) ){ return (u8)sqlite3Atoi(z); } n = sqlite3Strlen30(z); - for(i=0; i Date: Wed, 3 Feb 2016 19:52:06 +0000 Subject: [PATCH 073/107] Fix markup errors in comments used to generate the documentation - specifically in the documentation on the OP_Seek opcode. FossilOrigin-Name: ef252bc4b59d272460aaebdc0d4b8e347b0d25a8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 19dbe602f6..b7ee931a14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s"PRAGMA\ssynchronous=EXTRA"\swhich\ssyncs\sthe\sdirectory\scontaining\sthe\nrollback\sjournal\swhen\sthe\srollback\sjournal\sis\sdeleted\sin\sorder\sto\scommit\sa\s\ntransaction\sin\sDELETE\smode. -D 2016-02-03T19:20:15.585 +C Fix\smarkup\serrors\sin\scomments\sused\sto\sgenerate\sthe\sdocumentation\s-\sspecifically\nin\sthe\sdocumentation\son\sthe\sOP_Seek\sopcode. +D 2016-02-03T19:52:06.161 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -413,7 +413,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c a0a0ada4b51161d3950fe30fc696b6c8235a841f +F src/vdbe.c 16ca0c1e2975fac04c3ea5c62b34dc24b13fea13 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 @@ -1423,7 +1423,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 ae8b9d2edf1b5aef6108e729754911db7682b6a3 -R 1a8761ef82294be8ac021b32cc3428ab +P af92401826f5cf49e62c278f344ab75252a18da2 +R f36c5f43b820b4830c00d3f3959d5c82 U drh -Z 47031796dc00696c427dc7b231b9f896 +Z cdc17003a87221b5f2cfde36f98aed07 diff --git a/manifest.uuid b/manifest.uuid index 4b62d72b22..6563093eae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af92401826f5cf49e62c278f344ab75252a18da2 \ No newline at end of file +ef252bc4b59d272460aaebdc0d4b8e347b0d25a8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1cf4cb16a7..62ad86d4f3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4960,8 +4960,8 @@ case OP_IdxDelete: { ** occur, no unnecessary I/O happens. ** ** P4 may be an array of integers (type P4_INTARRAY) containing -** one entry for each column in the P3 table. If array entry a[i] -** is non-zero, then reading column (a[i]-1) from cursor P3 is +** one entry for each column in the P3 table. If array entry a(i) +** is non-zero, then reading column a(i)-1 from cursor P3 is ** equivalent to performing the deferred seek and then reading column i ** from P1. This information is stored in P3 and used to redirect ** reads against P3 over to P1, thus possibly avoiding the need to From eb715c62f9367794b11cc9210a9e61a4a1943b04 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 3 Feb 2016 20:04:59 +0000 Subject: [PATCH 074/107] Improve performance of fts5 prefix queries on detail=col tables. FossilOrigin-Name: ca11f46db047e7f131cef3893f73824758a2076b --- ext/fts5/fts5Int.h | 6 + ext/fts5/fts5_index.c | 995 ++++++++++++++++++++---------------------- manifest | 16 +- manifest.uuid | 2 +- 4 files changed, 489 insertions(+), 530 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index 9e5e52fa41..fc71584909 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -332,6 +332,12 @@ struct Fts5IndexIter { #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ #define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ +/* The following are used internally by the fts5_index.c module. They are +** defined here only to make it easier to avoid clashes with the flags +** above. */ +#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 +#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 + /* ** Create/destroy an Fts5Index object. */ diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3b627dabad..1a8cc63dad 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -2264,9 +2264,6 @@ static void fts5SegIterSeekInit( int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ - static int nCall = 0; - nCall++; - assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); memset(pIter, 0, sizeof(*pIter)); @@ -2832,6 +2829,410 @@ static Fts5Iter *fts5MultiIterAlloc( return pNew; } +static void fts5PoslistCallback( + Fts5Index *p, + void *pContext, + const u8 *pChunk, int nChunk +){ + assert_nc( nChunk>=0 ); + if( nChunk>0 ){ + fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk); + } +} + +typedef struct PoslistCallbackCtx PoslistCallbackCtx; +struct PoslistCallbackCtx { + Fts5Buffer *pBuf; /* Append to this buffer */ + Fts5Colset *pColset; /* Restrict matches to this column */ + int eState; /* See above */ +}; + +typedef struct PoslistOffsetsCtx PoslistOffsetsCtx; +struct PoslistOffsetsCtx { + Fts5Buffer *pBuf; /* Append to this buffer */ + Fts5Colset *pColset; /* Restrict matches to this column */ + int iRead; + int iWrite; +}; + +/* +** TODO: Make this more efficient! +*/ +static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){ + int i; + for(i=0; inCol; i++){ + if( pColset->aiCol[i]==iCol ) return 1; + } + return 0; +} + +static void fts5PoslistOffsetsCallback( + Fts5Index *p, + void *pContext, + const u8 *pChunk, int nChunk +){ + PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext; + assert_nc( nChunk>=0 ); + if( nChunk>0 ){ + int i = 0; + while( iiRead - 2; + pCtx->iRead = iVal; + if( fts5IndexColsetTest(pCtx->pColset, iVal) ){ + fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite); + pCtx->iWrite = iVal; + } + } + } +} + +static void fts5PoslistFilterCallback( + Fts5Index *p, + void *pContext, + const u8 *pChunk, int nChunk +){ + PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext; + assert_nc( nChunk>=0 ); + if( nChunk>0 ){ + /* Search through to find the first varint with value 1. This is the + ** start of the next columns hits. */ + int i = 0; + int iStart = 0; + + if( pCtx->eState==2 ){ + int iCol; + fts5FastGetVarint32(pChunk, i, iCol); + if( fts5IndexColsetTest(pCtx->pColset, iCol) ){ + pCtx->eState = 1; + fts5BufferSafeAppendVarint(pCtx->pBuf, 1); + }else{ + pCtx->eState = 0; + } + } + + do { + while( ieState ){ + fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); + } + if( i=nChunk ){ + pCtx->eState = 2; + }else{ + fts5FastGetVarint32(pChunk, i, iCol); + pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol); + if( pCtx->eState ){ + fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); + iStart = i; + } + } + } + }while( inPos; /* Number of bytes still to come */ + Fts5Data *pData = 0; + u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset); + int pgno = pSeg->iLeafPgno; + int pgnoSave = 0; + + /* This function does notmwork with detail=none databases. */ + assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); + + if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){ + pgnoSave = pgno+1; + } + + while( 1 ){ + xChunk(p, pCtx, pChunk, nChunk); + nRem -= nChunk; + fts5DataRelease(pData); + if( nRem<=0 ){ + break; + }else{ + pgno++; + pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); + if( pData==0 ) break; + pChunk = &pData->p[4]; + nChunk = MIN(nRem, pData->szLeaf - 4); + if( pgno==pgnoSave ){ + assert( pSeg->pNextLeaf==0 ); + pSeg->pNextLeaf = pData; + pData = 0; + } + } + } +} + +/* +** Iterator pIter currently points to a valid entry (not EOF). This +** function appends the position list data for the current entry to +** buffer pBuf. It does not make a copy of the position-list size +** field. +*/ +static void fts5SegiterPoslist( + Fts5Index *p, + Fts5SegIter *pSeg, + Fts5Colset *pColset, + Fts5Buffer *pBuf +){ + if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){ + if( pColset==0 ){ + fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); + }else{ + if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){ + PoslistCallbackCtx sCtx; + sCtx.pBuf = pBuf; + sCtx.pColset = pColset; + sCtx.eState = fts5IndexColsetTest(pColset, 0); + assert( sCtx.eState==0 || sCtx.eState==1 ); + fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback); + }else{ + PoslistOffsetsCtx sCtx; + memset(&sCtx, 0, sizeof(sCtx)); + sCtx.pBuf = pBuf; + sCtx.pColset = pColset; + fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback); + } + } + } +} + +/* +** IN/OUT parameter (*pa) points to a position list n bytes in size. If +** the position list contains entries for column iCol, then (*pa) is set +** to point to the sub-position-list for that column and the number of +** bytes in it returned. Or, if the argument position list does not +** contain any entries for column iCol, return 0. +*/ +static int fts5IndexExtractCol( + const u8 **pa, /* IN/OUT: Pointer to poslist */ + int n, /* IN: Size of poslist in bytes */ + int iCol /* Column to extract from poslist */ +){ + int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ + const u8 *p = *pa; + const u8 *pEnd = &p[n]; /* One byte past end of position list */ + + while( iCol>iCurrent ){ + /* Advance pointer p until it points to pEnd or an 0x01 byte that is + ** not part of a varint. Note that it is not possible for a negative + ** or extremely large varint to occur within an uncorrupted position + ** list. So the last byte of each varint may be assumed to have a clear + ** 0x80 bit. */ + while( *p!=0x01 ){ + while( *p++ & 0x80 ); + if( p>=pEnd ) return 0; + } + *pa = p++; + iCurrent = *p++; + if( iCurrent & 0x80 ){ + 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 */ + while( pnCol; i++){ + const u8 *pSub = pPos; + int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); + if( nSub ){ + fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); + } + } + return rc; +} + +/* +** xSetOutputs callback used by detail=none tables. +*/ +static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){ + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE ); + pIter->base.iRowid = pSeg->iRowid; + pIter->base.nData = pSeg->nPos; +} + +/* +** xSetOutputs callback used by detail=full and detail=col tables when no +** column filters are specified. +*/ +static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ + pIter->base.iRowid = pSeg->iRowid; + pIter->base.nData = pSeg->nPos; + + assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE ); + assert( pIter->pColset==0 || pIter->bFiltered ); + + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ + /* All data is stored on the current page. Populate the output + ** variables to point into the body of the page object. */ + pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + }else{ + /* The data is distributed over two or more pages. Copy it into the + ** Fts5Iter.poslist buffer and then set the output pointer to point + ** to this buffer. */ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + } +} + +/* +** xSetOutputs callback used by detail=col when there is a column filter +** and there are 100 or more columns. Also called as a fallback from +** fts5IterSetOutputs_Col100 if the column-list spans more than one page. +*/ +static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist); + pIter->base.iRowid = pSeg->iRowid; + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; +} + +/* +** xSetOutputs callback used when: +** +** * detail=col, +** * there is a column filter, and +** * the table contains 100 or fewer columns. +** +** The last point is to ensure all column numbers are stored as +** single-byte varints. +*/ +static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + assert( pIter->pColset ); + + if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ + fts5IterSetOutputs_Col(pIter, pSeg); + }else{ + u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; + u8 *pEnd = (u8*)&a[pSeg->nPos]; + int iPrev = 0; + int *aiCol = pIter->pColset->aiCol; + int *aiColEnd = &aiCol[pIter->pColset->nCol]; + + u8 *aOut = pIter->poslist.p; + int iPrevOut = 0; + + pIter->base.iRowid = pSeg->iRowid; + + while( abase.pData = pIter->poslist.p; + pIter->base.nData = aOut - pIter->poslist.p; + } +} + +/* +** xSetOutputs callback used by detail=full when there is a column filter. +*/ +static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ + Fts5Colset *pColset = pIter->pColset; + pIter->base.iRowid = pSeg->iRowid; + + assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL ); + assert( pColset ); + + if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ + /* All data is stored on the current page. Populate the output + ** variables to point into the body of the page object. */ + const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; + if( pColset->nCol==1 ){ + pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); + pIter->base.pData = a; + }else{ + fts5BufferZero(&pIter->poslist); + fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } + }else{ + /* The data is distributed over two or more pages. Copy it into the + ** Fts5Iter.poslist buffer and then set the output pointer to point + ** to this buffer. */ + fts5BufferZero(&pIter->poslist); + fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } +} + +static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ + if( *pRc==SQLITE_OK ){ + Fts5Config *pConfig = pIter->pIndex->pConfig; + if( pConfig->eDetail==FTS5_DETAIL_NONE ){ + pIter->xSetOutputs = fts5IterSetOutputs_None; + } + + else if( pIter->pColset==0 || pIter->bFiltered ){ + pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; + } + + else if( pConfig->eDetail==FTS5_DETAIL_FULL ){ + pIter->xSetOutputs = fts5IterSetOutputs_Full; + } + + else{ + assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); + if( pConfig->nCol<=100 ){ + pIter->xSetOutputs = fts5IterSetOutputs_Col100; + sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); + }else{ + pIter->xSetOutputs = fts5IterSetOutputs_Col; + } + } + } +} + + /* ** Allocate a new Fts5Iter object. ** @@ -2846,8 +3247,8 @@ static Fts5Iter *fts5MultiIterAlloc( static void fts5MultiIterNew( Fts5Index *p, /* FTS5 backend to iterate within */ Fts5Structure *pStruct, /* Structure of specific index */ - int bSkipEmpty, /* True to ignore delete-keys */ int flags, /* FTS5INDEX_QUERY_XXX flags */ + Fts5Colset *pColset, /* Colset to filter on (or NULL) */ const u8 *pTerm, int nTerm, /* Term to seek to (or NULL/0) */ int iLevel, /* Level to iterate (-1 for all) */ int nSegment, /* Number of segments to merge (iLevel>=0) */ @@ -2875,36 +3276,42 @@ static void fts5MultiIterNew( *ppOut = pNew = fts5MultiIterAlloc(p, nSeg); if( pNew==0 ) return; pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC)); - pNew->bSkipEmpty = (u8)bSkipEmpty; + pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY)); pNew->pStruct = pStruct; + pNew->pColset = pColset; fts5StructureRef(pStruct); + if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){ + fts5IterSetOutputCb(&p->rc, pNew); + } /* Initialize each of the component segment iterators. */ - if( iLevel<0 ){ - Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; - if( p->pHash ){ - /* Add a segment iterator for the current contents of the hash table. */ - Fts5SegIter *pIter = &pNew->aSeg[iIter++]; - fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); - } - for(pLvl=&pStruct->aLevel[0]; pLvlnSeg-1; iSeg>=0; iSeg--){ - Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; + if( p->rc==SQLITE_OK ){ + if( iLevel<0 ){ + Fts5StructureLevel *pEnd = &pStruct->aLevel[pStruct->nLevel]; + if( p->pHash ){ + /* Add a segment iterator for the current contents of the hash table. */ Fts5SegIter *pIter = &pNew->aSeg[iIter++]; - if( pTerm==0 ){ - fts5SegIterInit(p, pSeg, pIter); - }else{ - fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter); + fts5SegIterHashInit(p, pTerm, nTerm, flags, pIter); + } + for(pLvl=&pStruct->aLevel[0]; pLvlnSeg-1; iSeg>=0; iSeg--){ + Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; + Fts5SegIter *pIter = &pNew->aSeg[iIter++]; + if( pTerm==0 ){ + fts5SegIterInit(p, pSeg, pIter); + }else{ + fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter); + } } } + }else{ + pLvl = &pStruct->aLevel[iLevel]; + for(iSeg=nSeg-1; iSeg>=0; iSeg--){ + fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]); + } } - }else{ - pLvl = &pStruct->aLevel[iLevel]; - for(iSeg=nSeg-1; iSeg>=0; iSeg--){ - fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]); - } + assert( iIter==nSeg ); } - assert( iIter==nSeg ); /* If the above was successful, each component iterators now points ** to the first entry in its segment. In this case initialize the @@ -2924,12 +3331,17 @@ static void fts5MultiIterNew( if( pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){ fts5MultiIterNext(p, pNew, 0, 0); + }else if( pNew->base.bEof==0 ){ + Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; + pNew->xSetOutputs(pNew, pSeg); } + }else{ fts5MultiIterFree(p, pNew); *ppOut = 0; } fts5BufferFree(&buf); + } /* @@ -3022,49 +3434,6 @@ static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){ return p->term.p; } -static void fts5ChunkIterate( - Fts5Index *p, /* Index object */ - Fts5SegIter *pSeg, /* Poslist of this iterator */ - void *pCtx, /* Context pointer for xChunk callback */ - void (*xChunk)(Fts5Index*, void*, const u8*, int) -){ - int nRem = pSeg->nPos; /* Number of bytes still to come */ - Fts5Data *pData = 0; - u8 *pChunk = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - int nChunk = MIN(nRem, pSeg->pLeaf->szLeaf - pSeg->iLeafOffset); - int pgno = pSeg->iLeafPgno; - int pgnoSave = 0; - - /* This function does notmwork with detail=none databases. */ - assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); - - if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){ - pgnoSave = pgno+1; - } - - while( 1 ){ - xChunk(p, pCtx, pChunk, nChunk); - nRem -= nChunk; - fts5DataRelease(pData); - if( nRem<=0 ){ - break; - }else{ - pgno++; - pData = fts5DataRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); - if( pData==0 ) break; - pChunk = &pData->p[4]; - nChunk = MIN(nRem, pData->szLeaf - 4); - if( pgno==pgnoSave ){ - assert( pSeg->pNextLeaf==0 ); - pSeg->pNextLeaf = pData; - pData = 0; - } - } - } -} - - - /* ** Allocate a new segment-id for the structure pStruct. The new segment ** id must be between 1 and 65335 inclusive, and must not be used by @@ -3684,6 +4053,7 @@ static void fts5IndexMergeLevel( Fts5Buffer term; int bOldest; /* True if the output segment is the oldest */ int eDetail = p->pConfig->eDetail; + const int flags = FTS5INDEX_QUERY_NOOUTPUT; assert( iLvlnLevel ); assert( pLvl->nMerge<=pLvl->nSeg ); @@ -3728,7 +4098,7 @@ static void fts5IndexMergeLevel( bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); assert( iLvl>=0 ); - for(fts5MultiIterNew(p, pStruct, 0, 0, 0, 0, iLvl, nInput, &pIter); + for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, iLvl, nInput, &pIter); fts5MultiIterEof(p, pIter)==0; fts5MultiIterNext(p, pIter, 0, 0) ){ @@ -4173,281 +4543,28 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ return fts5IndexReturn(p); } -static void fts5PoslistCallback( - Fts5Index *p, - void *pContext, - const u8 *pChunk, int nChunk -){ - assert_nc( nChunk>=0 ); - if( nChunk>0 ){ - fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk); - } -} - -typedef struct PoslistCallbackCtx PoslistCallbackCtx; -struct PoslistCallbackCtx { - Fts5Buffer *pBuf; /* Append to this buffer */ - Fts5Colset *pColset; /* Restrict matches to this column */ - int eState; /* See above */ -}; - -typedef struct PoslistOffsetsCtx PoslistOffsetsCtx; -struct PoslistOffsetsCtx { - Fts5Buffer *pBuf; /* Append to this buffer */ - Fts5Colset *pColset; /* Restrict matches to this column */ - int iRead; - int iWrite; -}; - -/* -** TODO: Make this more efficient! -*/ -static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){ - int i; - for(i=0; inCol; i++){ - if( pColset->aiCol[i]==iCol ) return 1; - } - return 0; -} - -static void fts5PoslistOffsetsCallback( - Fts5Index *p, - void *pContext, - const u8 *pChunk, int nChunk -){ - PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext; - assert_nc( nChunk>=0 ); - if( nChunk>0 ){ - int i = 0; - while( iiRead - 2; - pCtx->iRead = iVal; - if( fts5IndexColsetTest(pCtx->pColset, iVal) ){ - fts5BufferSafeAppendVarint(pCtx->pBuf, iVal + 2 - pCtx->iWrite); - pCtx->iWrite = iVal; - } - } - } -} - -static void fts5PoslistFilterCallback( - Fts5Index *p, - void *pContext, - const u8 *pChunk, int nChunk -){ - PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext; - assert_nc( nChunk>=0 ); - if( nChunk>0 ){ - /* Search through to find the first varint with value 1. This is the - ** start of the next columns hits. */ - int i = 0; - int iStart = 0; - - if( pCtx->eState==2 ){ - int iCol; - fts5FastGetVarint32(pChunk, i, iCol); - if( fts5IndexColsetTest(pCtx->pColset, iCol) ){ - pCtx->eState = 1; - fts5BufferSafeAppendVarint(pCtx->pBuf, 1); - }else{ - pCtx->eState = 0; - } - } - - do { - while( ieState ){ - fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); - } - if( i=nChunk ){ - pCtx->eState = 2; - }else{ - fts5FastGetVarint32(pChunk, i, iCol); - pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol); - if( pCtx->eState ){ - fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart); - iStart = i; - } - } - } - }while( irc, pBuf, pSeg->nPos) ){ - if( pColset==0 ){ - fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); - }else{ - if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){ - PoslistCallbackCtx sCtx; - sCtx.pBuf = pBuf; - sCtx.pColset = pColset; - sCtx.eState = fts5IndexColsetTest(pColset, 0); - assert( sCtx.eState==0 || sCtx.eState==1 ); - fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback); - }else{ - PoslistOffsetsCtx sCtx; - memset(&sCtx, 0, sizeof(sCtx)); - sCtx.pBuf = pBuf; - sCtx.pColset = pColset; - fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistOffsetsCallback); - } - } - } -} - -/* -** IN/OUT parameter (*pa) points to a position list n bytes in size. If -** the position list contains entries for column iCol, then (*pa) is set -** to point to the sub-position-list for that column and the number of -** bytes in it returned. Or, if the argument position list does not -** contain any entries for column iCol, return 0. -*/ -static int fts5IndexExtractCol( - const u8 **pa, /* IN/OUT: Pointer to poslist */ - int n, /* IN: Size of poslist in bytes */ - int iCol /* Column to extract from poslist */ -){ - int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ - const u8 *p = *pa; - const u8 *pEnd = &p[n]; /* One byte past end of position list */ - - while( iCol>iCurrent ){ - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint. Note that it is not possible for a negative - ** or extremely large varint to occur within an uncorrupted position - ** list. So the last byte of each varint may be assumed to have a clear - ** 0x80 bit. */ - while( *p!=0x01 ){ - while( *p++ & 0x80 ); - if( p>=pEnd ) return 0; - } - *pa = p++; - iCurrent = *p++; - if( iCurrent & 0x80 ){ - 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 */ - while( prc, pBuf, iDelta); - return 0; } -/* -** Iterator pMulti currently points to a valid entry (not EOF). This -** function appends the following to buffer pBuf: -** -** * The varint iDelta, and -** * the position list that currently points to, including the size field. -** -** If argument pColset is NULL, then the position list is filtered according -** to pColset before being appended to the buffer. If this means there are -** no entries in the position list, nothing is appended to the buffer (not -** even iDelta). -** -** If an error occurs, an error code is left in p->rc. -*/ -static int fts5AppendPoslist( +static void fts5AppendPoslist( Fts5Index *p, i64 iDelta, Fts5Iter *pMulti, - Fts5Colset *pColset, Fts5Buffer *pBuf ){ - if( p->rc==SQLITE_OK ){ - Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ]; - assert( fts5MultiIterEof(p, pMulti)==0 ); - assert( pSeg->nPos>0 ); - if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){ - if( p->pConfig->eDetail==FTS5_DETAIL_FULL - && pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf - && (pColset==0 || pColset->nCol==1) - ){ - const u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - 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{ - int iSv1; - int iSv2; - int iData; - - /* Append iDelta */ - iSv1 = pBuf->n; - fts5BufferSafeAppendVarint(pBuf, iDelta); - - /* 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); - } - } - } - } - } + int nData = pMulti->base.nData; + assert( nData>0 ); + if( p->rc==SQLITE_OK && 0==fts5BufferGrow(&p->rc, pBuf, nData+9+9) ){ + fts5BufferSafeAppendVarint(pBuf, iDelta); + fts5BufferSafeAppendVarint(pBuf, nData*2); + fts5BufferSafeAppendBlob(pBuf, pMulti->base.pData, nData); } - - return 0; } @@ -4674,7 +4791,7 @@ static void fts5SetupPrefixIter( const int nBuf = 32; void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); - int (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Colset*, Fts5Buffer*); + void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; @@ -4687,7 +4804,9 @@ static void fts5SetupPrefixIter( pStruct = fts5StructureRead(p); if( aBuf && pStruct ){ - const int flags = FTS5INDEX_QUERY_SCAN; + const int flags = FTS5INDEX_QUERY_SCAN + | FTS5INDEX_QUERY_SKIPEMPTY + | FTS5INDEX_QUERY_NOOUTPUT; int i; i64 iLastRowid = 0; Fts5Iter *p1 = 0; /* Iterator used to gather data from index */ @@ -4696,19 +4815,25 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); - for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1); + fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; fts5MultiIterEof(p, p1)==0; fts5MultiIterNext2(p, p1, &bNewTerm) ){ - i64 iRowid = fts5MultiIterRowid(p1); - int nTerm; - const u8 *pTerm = fts5MultiIterTerm(p1, &nTerm); + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + int nTerm = pSeg->term.n; + const u8 *pTerm = pSeg->term.p; + p1->xSetOutputs(p1, pSeg); + assert_nc( memcmp(pToken, pTerm, MIN(nToken, nTerm))<=0 ); if( bNewTerm ){ if( nTerm0 && iRowid<=iLastRowid ){ + if( p1->base.nData==0 ) continue; + + if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ assert( ibase.iRowid-iLastRowid, p1, &doclist); + iLastRowid = p1->base.iRowid; } for(i=0; inCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(&rc, pBuf, nSub, pSub); - } - } - return rc; -} - -/* -** xSetOutputs callback used by detail=none tables. -*/ -static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){ - assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE ); - pIter->base.iRowid = pSeg->iRowid; - pIter->base.nData = pSeg->nPos; -} - -/* -** xSetOutputs callback used by detail=full and detail=col tables when no -** column filters are specified. -*/ -static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ - pIter->base.iRowid = pSeg->iRowid; - pIter->base.nData = pSeg->nPos; - - assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE ); - assert( pIter->pColset==0 || pIter->bFiltered ); - - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ - /* All data is stored on the current page. Populate the output - ** variables to point into the body of the page object. */ - pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - }else{ - /* The data is distributed over two or more pages. Copy it into the - ** Fts5Iter.poslist buffer and then set the output pointer to point - ** to this buffer. */ - fts5BufferZero(&pIter->poslist); - fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - } -} - -/* -** xSetOutputs callback used by detail=col when there is a column filter -** and there are 100 or more columns. Also called as a fallback from -** fts5IterSetOutputs_Col100 if the column-list spans more than one page. -*/ -static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){ - fts5BufferZero(&pIter->poslist); - fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist); - pIter->base.iRowid = pSeg->iRowid; - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; -} - -/* -** xSetOutputs callback used when: -** -** * detail=col, -** * there is a column filter, and -** * the table contains 100 or fewer columns. -** -** The last point is to ensure all column numbers are stored as -** single-byte varints. -*/ -static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){ - - assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - assert( pIter->pColset ); - - if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){ - fts5IterSetOutputs_Col(pIter, pSeg); - }else{ - u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset]; - u8 *pEnd = (u8*)&a[pSeg->nPos]; - int iPrev = 0; - int *aiCol = pIter->pColset->aiCol; - int *aiColEnd = &aiCol[pIter->pColset->nCol]; - - u8 *aOut = pIter->poslist.p; - int iPrevOut = 0; - - pIter->base.iRowid = pSeg->iRowid; - - while( abase.pData = pIter->poslist.p; - pIter->base.nData = aOut - pIter->poslist.p; - } -} - -/* -** xSetOutputs callback used by detail=full when there is a column filter. -*/ -static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ - Fts5Colset *pColset = pIter->pColset; - pIter->base.iRowid = pSeg->iRowid; - - assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL ); - assert( pColset ); - - if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ - /* All data is stored on the current page. Populate the output - ** variables to point into the body of the page object. */ - const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - if( pColset->nCol==1 ){ - pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); - pIter->base.pData = a; - }else{ - fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; - } - }else{ - /* The data is distributed over two or more pages. Copy it into the - ** Fts5Iter.poslist buffer and then set the output pointer to point - ** to this buffer. */ - fts5BufferZero(&pIter->poslist); - fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; - } -} - -static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ - Fts5Config *pConfig = pIter->pIndex->pConfig; - if( pConfig->eDetail==FTS5_DETAIL_NONE ){ - pIter->xSetOutputs = fts5IterSetOutputs_None; - } - - else if( pIter->pColset==0 || pIter->bFiltered ){ - pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; - } - - else if( pConfig->eDetail==FTS5_DETAIL_FULL ){ - pIter->xSetOutputs = fts5IterSetOutputs_Full; - } - - else{ - assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); - if( pConfig->nCol<=100 ){ - pIter->xSetOutputs = fts5IterSetOutputs_Col100; - sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); - }else{ - pIter->xSetOutputs = fts5IterSetOutputs_Col; - } - } -} - /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -5177,7 +5128,9 @@ int sqlite3Fts5IndexQuery( Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); if( pStruct ){ - fts5MultiIterNew(p, pStruct, 1, flags, buf.p, nToken+1, -1, 0, &pRet); + fts5MultiIterNew(p, pStruct, flags | FTS5INDEX_QUERY_SKIPEMPTY, + pColset, buf.p, nToken+1, -1, 0, &pRet + ); fts5StructureRelease(pStruct); } }else{ @@ -5185,14 +5138,13 @@ int sqlite3Fts5IndexQuery( int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; buf.p[0] = FTS5_MAIN_PREFIX; fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); + fts5IterSetOutputCb(&p->rc, pRet); + if( p->rc==SQLITE_OK ){ + Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; + if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + } } - if( p->rc==SQLITE_OK ){ - Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; - pRet->pColset = pColset; - fts5IterSetOutputCb(&p->rc, pRet); - if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); - } if( p->rc ){ sqlite3Fts5IterClose(&pRet->base); pRet = 0; @@ -5769,6 +5721,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ u64 cksum3 = 0; /* Checksum based on contents of indexes */ Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */ #endif + const int flags = FTS5INDEX_QUERY_NOOUTPUT; /* Load the FTS index structure */ pStruct = fts5StructureRead(p); @@ -5797,7 +5750,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ ** same term is performed. cksum3 is calculated based on the entries ** extracted by these queries. */ - for(fts5MultiIterNew(p, pStruct, 0, 0, 0, 0, -1, 0, &pIter); + for(fts5MultiIterNew(p, pStruct, flags, 0, 0, 0, -1, 0, &pIter); fts5MultiIterEof(p, pIter)==0; fts5MultiIterNext(p, pIter, 0, 0) ){ diff --git a/manifest b/manifest index b7ee931a14..0efc8787a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\smarkup\serrors\sin\scomments\sused\sto\sgenerate\sthe\sdocumentation\s-\sspecifically\nin\sthe\sdocumentation\son\sthe\sOP_Seek\sopcode. -D 2016-02-03T19:52:06.161 +C Improve\sperformance\sof\sfts5\sprefix\squeries\son\sdetail=col\stables. +D 2016-02-03T20:04:59.805 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -98,13 +98,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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 9505f3bc8d0b2ca4cd2b112e7e042e3c6a3222a7 +F ext/fts5/fts5Int.h 2095cc38e776f19cc083ca90e00772ea0b204ab3 F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 471ff6935068a4579830474249e1046b57137103 +F ext/fts5/fts5_index.c e634a4a05b066f7122db93558c871148bd9893f2 F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -1423,7 +1423,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 af92401826f5cf49e62c278f344ab75252a18da2 -R f36c5f43b820b4830c00d3f3959d5c82 -U drh -Z cdc17003a87221b5f2cfde36f98aed07 +P ef252bc4b59d272460aaebdc0d4b8e347b0d25a8 +R 671ea22942ad2d2bcb9568b9e59d452e +U dan +Z 34c6688fd340fcbe0aee4e43e23acf72 diff --git a/manifest.uuid b/manifest.uuid index 6563093eae..06d0c2d828 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef252bc4b59d272460aaebdc0d4b8e347b0d25a8 \ No newline at end of file +ca11f46db047e7f131cef3893f73824758a2076b \ No newline at end of file From fabe393da8f09bee7f40781e2bae9edacebe8619 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 3 Feb 2016 22:14:38 +0000 Subject: [PATCH 075/107] In the VDBE loop, only check for OOM errors at jumps rather than after every opcode, for about a 0.5% performance increase. FossilOrigin-Name: 632071bac5ff324a74cec9bdbba2deb60c0945e9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 ++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0efc8787a5..63d7f994de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sperformance\sof\sfts5\sprefix\squeries\son\sdetail=col\stables. -D 2016-02-03T20:04:59.805 +C In\sthe\sVDBE\sloop,\sonly\scheck\sfor\sOOM\serrors\sat\sjumps\srather\sthan\safter\severy\nopcode,\sfor\sabout\sa\s0.5%\sperformance\sincrease. +D 2016-02-03T22:14:38.812 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -413,7 +413,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 16ca0c1e2975fac04c3ea5c62b34dc24b13fea13 +F src/vdbe.c f0c2e2fb8cbff761ea8602058406c151b9325e8d F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 @@ -1423,7 +1423,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 ef252bc4b59d272460aaebdc0d4b8e347b0d25a8 -R 671ea22942ad2d2bcb9568b9e59d452e -U dan -Z 34c6688fd340fcbe0aee4e43e23acf72 +P ca11f46db047e7f131cef3893f73824758a2076b +R 59ea01ed7c88b6674116d0bfaf73cf15 +U drh +Z 96f5f7409c64154023cc6759eed6c5b3 diff --git a/manifest.uuid b/manifest.uuid index 06d0c2d828..bfccf07dec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca11f46db047e7f131cef3893f73824758a2076b \ No newline at end of file +632071bac5ff324a74cec9bdbba2deb60c0945e9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 62ad86d4f3..fd90d3b0de 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -629,7 +629,6 @@ int sqlite3VdbeExec( #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); - if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif @@ -754,14 +753,16 @@ jump_to_p2_and_check_for_interrupt: /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon ** completion. Check to see if sqlite3_interrupt() has been called - ** or if the progress callback needs to be invoked. + ** or if the progress callback needs to be invoked. Also check for + ** OOM conditions and abort if seen. ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this ** way for performance, to avoid having to run the interrupt and progress - ** checks on every opcode. This helps sqlite3_step() to run about 1.5% + ** checks on every opcode. This helps sqlite3_step() to run over 2.0% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: + if( db->mallocFailed ) goto no_mem; if( db->u1.isInterrupted ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number From 6d258995e65e606f65b9189c409801c3da01f4ef Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Feb 2016 09:48:12 +0000 Subject: [PATCH 076/107] Refinements to synchronous logic: (1) Use PAGER_SYNCHRONOUS_FULL rather than the corresponding magic number. (2) Honor SQLITE_NO_SYNC on xDelete calls with sync (3) Count xDelete syncs during testing (4) Fix #ifs on SQLITE_EXTRA_DURABLE so that directory syncs on journal unlink are off by default. FossilOrigin-Name: e3157cb5ad0d22758e766a95fb1463a7810f7d7f --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/attach.c | 3 ++- src/os_unix.c | 9 ++------- src/pager.c | 2 +- test/sync.test | 11 +++++------ 6 files changed, 20 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 63d7f994de..b33b7f4352 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sVDBE\sloop,\sonly\scheck\sfor\sOOM\serrors\sat\sjumps\srather\sthan\safter\severy\nopcode,\sfor\sabout\sa\s0.5%\sperformance\sincrease. -D 2016-02-03T22:14:38.812 +C Refinements\sto\ssynchronous\slogic:\s\n(1)\sUse\sPAGER_SYNCHRONOUS_FULL\srather\sthan\sthe\scorresponding\smagic\snumber.\n(2)\sHonor\sSQLITE_NO_SYNC\son\sxDelete\scalls\swith\ssync\n(3)\sCount\sxDelete\ssyncs\sduring\stesting\n(4)\sFix\s#ifs\son\sSQLITE_EXTRA_DURABLE\sso\sthat\sdirectory\ssyncs\son\sjournal\nunlink\sare\soff\sby\sdefault. +D 2016-02-04T09:48:12.199 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -286,7 +286,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 3fe13e97ab38317b092e2f3ae11267b40c9b5cbd F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 -F src/attach.c 07b3a34a1702dce92a7f1d3888c0c06222b63760 +F src/attach.c 27743a694df17ca468eee3956126a5d28d2a29ea F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -332,10 +332,10 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8 F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf F src/os_common.h abdb9a191a367793268fe553d25bab894e986a0e F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa -F src/os_unix.c 5bb20172d0c9a6afcfa829a88c406970593c848d +F src/os_unix.c 821ed110197175165cf2f50b0930c7ff9a24504c F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca -F src/pager.c 3e189231fc662710964b54862450bc7f69f313c2 +F src/pager.c 67cd2fbab58d0e35fed5f81432856f4f0af9fc6d F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865 F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 @@ -1065,7 +1065,7 @@ F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/subtype1.test 7fe09496352f97053af1437150751be2d0a0cae8 F test/superlock.test 1cde669f68d2dd37d6c9bd35eee1d95491ae3fc2 F test/symlink.test c9ebe7330d228249e447038276bfc8a7b22f4849 -F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 +F test/sync.test 2f607e1821aa3af3c5c53b58835c05e511c95899 F test/syscall.test f59ba4e25f7ba4a4c031026cc2ef8b6e4b4c639c F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test cc33684f9480fcf1fd5ce287ac28d22971cad1cc @@ -1423,7 +1423,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 ca11f46db047e7f131cef3893f73824758a2076b -R 59ea01ed7c88b6674116d0bfaf73cf15 +P 632071bac5ff324a74cec9bdbba2deb60c0945e9 +R 3746b9c792f29a07d873215ad89cd62c U drh -Z 96f5f7409c64154023cc6759eed6c5b3 +Z 6297b2dadaa7144af31b30e87beaeee7 diff --git a/manifest.uuid b/manifest.uuid index bfccf07dec..2921dbef8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -632071bac5ff324a74cec9bdbba2deb60c0945e9 \ No newline at end of file +e3157cb5ad0d22758e766a95fb1463a7810f7d7f \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index fd5cc7c76c..12d3ac3ff6 100644 --- a/src/attach.c +++ b/src/attach.c @@ -156,7 +156,8 @@ static void attachFunc( sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS - sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); + sqlite3BtreeSetPagerFlags(aNew->pBt, + PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif sqlite3BtreeLeave(aNew->pBt); } diff --git a/src/os_unix.c b/src/os_unix.c index 81422f215d..fe1fc6af19 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -5887,12 +5887,7 @@ static int unixDelete( int fd; rc = osOpenDirectory(zPath, &fd); if( rc==SQLITE_OK ){ -#if OS_VXWORKS - if( fsync(fd)==-1 ) -#else - if( fsync(fd) ) -#endif - { + if( full_fsync(fd,0,0) ){ rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath); } robust_close(0, fd, __LINE__); @@ -6936,7 +6931,7 @@ static int proxyTakeConch(unixFile *pFile){ writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); - fsync(conchFile->h); + full_fsync(conchFile->h,0,0); /* If we created a new conch file (not just updated the contents of a ** valid conch file), try to match the permissions of the database */ diff --git a/src/pager.c b/src/pager.c index 8f1635d9ee..5c61968e36 100644 --- a/src/pager.c +++ b/src/pager.c @@ -4823,7 +4823,7 @@ act_like_temp_file: assert( pPager->ckptSyncFlags==0 ); }else{ pPager->fullSync = 1; -#ifdef SQLITE_EXTRA_DURABLE +#if SQLITE_EXTRA_DURABLE pPager->extraSync = 1; #else pPager->extraSync = 0; diff --git a/test/sync.test b/test/sync.test index 14252b5c08..2ee636a266 100644 --- a/test/sync.test +++ b/test/sync.test @@ -13,7 +13,6 @@ # This file implements tests to verify that fsync is disabled when # pragma synchronous=off even for multi-database commits. # -# $Id: sync.test,v 1.6 2007/10/09 08:29:33 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -33,7 +32,7 @@ proc cond_incr_sync_count {adj} { global sqlite_sync_count if {$::tcl_platform(platform) == "windows"} { incr sqlite_sync_count $adj - } { + } else { ifcapable !dirsync { incr sqlite_sync_count $adj } @@ -64,9 +63,9 @@ ifcapable pager_pragmas { INSERT INTO t2 VALUES(3,4); COMMIT; } - cond_incr_sync_count 3 + cond_incr_sync_count 4 set sqlite_sync_count - } 8 + } 9 } do_test sync-1.3 { set sqlite_sync_count 0 @@ -78,9 +77,9 @@ do_test sync-1.3 { INSERT INTO t2 VALUES(5,6); COMMIT; } - cond_incr_sync_count 3 + cond_incr_sync_count 4 set sqlite_sync_count -} 10 +} 11 ifcapable pager_pragmas { do_test sync-1.4 { set sqlite_sync_count 0 From 3b7f9a68d5172c215fe56dc5dc60378aec268820 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Feb 2016 10:28:57 +0000 Subject: [PATCH 077/107] Escape control characters in JSON. Fix for ticket [ad2559db380abf8]. FossilOrigin-Name: 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1 --- ext/misc/json1.c | 25 ++++++++++++++++++++++++- manifest | 14 +++++++------- manifest.uuid | 2 +- test/json101.test | 15 +++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 3707516660..e4ea4fb9f0 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -276,10 +276,33 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ if( (N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; for(i=0; inUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; + }else if( c<=0x1f ){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + if( aSpecial[c] ){ + c = aSpecial[c]; + goto json_simple_escape; + } + if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; } p->zBuf[p->nUsed++] = c; } diff --git a/manifest b/manifest index b33b7f4352..3bb584fd54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinements\sto\ssynchronous\slogic:\s\n(1)\sUse\sPAGER_SYNCHRONOUS_FULL\srather\sthan\sthe\scorresponding\smagic\snumber.\n(2)\sHonor\sSQLITE_NO_SYNC\son\sxDelete\scalls\swith\ssync\n(3)\sCount\sxDelete\ssyncs\sduring\stesting\n(4)\sFix\s#ifs\son\sSQLITE_EXTRA_DURABLE\sso\sthat\sdirectory\ssyncs\son\sjournal\nunlink\sare\soff\sby\sdefault. -D 2016-02-04T09:48:12.199 +C Escape\scontrol\scharacters\sin\sJSON.\nFix\sfor\sticket\s[ad2559db380abf8]. +D 2016-02-04T10:28:57.253 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -206,7 +206,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 7b1155f520d5e8ec1c005d978ac675e8a7f2688a +F ext/misc/json1.c 8698ea0ce24bda23bd8ad4a124620d758f92760b F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc @@ -833,7 +833,7 @@ F test/journal3.test ff8af941f9e06161d3db1b46bb9f965ff0e7f307 F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test f0178422b3a2418f423fd0d3caf3571c8d1b9863 +F test/json101.test ef42283f0b60d8bacbc2243448e7c84988578e52 F test/json102.test bf3fe7a706d30936a76a0f7a0375e1e8e73aff5a F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1423,7 +1423,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 632071bac5ff324a74cec9bdbba2deb60c0945e9 -R 3746b9c792f29a07d873215ad89cd62c +P e3157cb5ad0d22758e766a95fb1463a7810f7d7f +R b212639d5d48b990a29409ffb71a1dde U drh -Z 6297b2dadaa7144af31b30e87beaeee7 +Z b8b1a6316f2eff8be617256b6e3556cd diff --git a/manifest.uuid b/manifest.uuid index 2921dbef8e..8bc8215408 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3157cb5ad0d22758e766a95fb1463a7810f7d7f \ No newline at end of file +4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1 \ No newline at end of file diff --git a/test/json101.test b/test/json101.test index 8c62c8b16c..9b780a379b 100644 --- a/test/json101.test +++ b/test/json101.test @@ -342,4 +342,19 @@ foreach {tn isvalid ws} { $isvalid } +# Ticket https://www.sqlite.org/src/info/ad2559db380abf8e +# Control characters must be escaped in JSON strings. +# +do_execsql_test json-8.1 { + DROP TABLE IF EXISTS t8; + CREATE TABLE t8(a,b); + INSERT INTO t8(a) VALUES('abc' || char(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) || 'xyz'); + UPDATE t8 SET b=json_array(a); + SELECT b FROM t8; +} {{["abc\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#xyz"]}} +do_execsql_test json-8.2 { + SELECT a=json_extract(b,'$[0]') FROM t8; +} {1} + + finish_test From c4703eedab614f8b4e5e8173ac78e8507439a556 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Feb 2016 11:15:57 +0000 Subject: [PATCH 078/107] Use sqlite3_malloc64() instead of sqlite3_malloc() in the spellfix extension. FossilOrigin-Name: 634d008c34bd237fc9cfb88dc291394fc5d31efa --- ext/misc/spellfix.c | 30 +++++++++++++++--------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/ext/misc/spellfix.c b/ext/misc/spellfix.c index 68bd2afbb2..cac1edcff8 100644 --- a/ext/misc/spellfix.c +++ b/ext/misc/spellfix.c @@ -186,7 +186,7 @@ static const unsigned char className[] = ".ABCDHLRMY9 ?"; ** Return NULL if memory allocation fails. */ static unsigned char *phoneticHash(const unsigned char *zIn, int nIn){ - unsigned char *zOut = sqlite3_malloc( nIn + 1 ); + unsigned char *zOut = sqlite3_malloc64( nIn + 1 ); int i; int nOut = 0; char cPrev = 0x77; @@ -413,7 +413,7 @@ static int editdist1(const char *zA, const char *zB, int *pnMatch){ if( nB<(sizeof(mStack)*4)/(sizeof(mStack[0])*5) ){ m = mStack; }else{ - m = toFree = sqlite3_malloc( (nB+1)*5*sizeof(m[0])/4 ); + m = toFree = sqlite3_malloc64( (nB+1)*5*sizeof(m[0])/4 ); if( m==0 ) return -3; } cx = (char*)&m[nB+1]; @@ -687,7 +687,7 @@ static int editDist3ConfigLoad( if( iCost<0 ) continue; if( pLang==0 || iLang!=iLangPrev ){ EditDist3Lang *pNew; - pNew = sqlite3_realloc(p->a, (p->nLang+1)*sizeof(p->a[0])); + pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0])); if( pNew==0 ){ rc = SQLITE_NOMEM; break; } p->a = pNew; pLang = &p->a[p->nLang]; @@ -709,7 +709,7 @@ static int editDist3ConfigLoad( EditDist3Cost *pCost; int nExtra = nFrom + nTo - 4; if( nExtra<0 ) nExtra = 0; - pCost = sqlite3_malloc( sizeof(*pCost) + nExtra ); + pCost = sqlite3_malloc64( sizeof(*pCost) + nExtra ); if( pCost==0 ){ rc = SQLITE_NOMEM; break; } pCost->nFrom = nFrom; pCost->nTo = nTo; @@ -808,7 +808,7 @@ static EditDist3FromString *editDist3FromStringNew( if( z==0 ) return 0; if( n<0 ) n = (int)strlen(z); - pStr = sqlite3_malloc( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 ); + pStr = sqlite3_malloc64( sizeof(*pStr) + sizeof(pStr->a[0])*n + n + 1 ); if( pStr==0 ) return 0; pStr->a = (EditDist3From*)&pStr[1]; memset(pStr->a, 0, sizeof(pStr->a[0])*n); @@ -833,13 +833,13 @@ static EditDist3FromString *editDist3FromStringNew( if( i+p->nFrom>n ) continue; if( matchFrom(p, z+i, n-i)==0 ) continue; if( p->nTo==0 ){ - apNew = sqlite3_realloc(pFrom->apDel, + apNew = sqlite3_realloc64(pFrom->apDel, sizeof(*apNew)*(pFrom->nDel+1)); if( apNew==0 ) break; pFrom->apDel = apNew; apNew[pFrom->nDel++] = p; }else{ - apNew = sqlite3_realloc(pFrom->apSubst, + apNew = sqlite3_realloc64(pFrom->apSubst, sizeof(*apNew)*(pFrom->nSubst+1)); if( apNew==0 ) break; pFrom->apSubst = apNew; @@ -925,7 +925,7 @@ static int editDist3Core( m = stackSpace; pToFree = 0; }else{ - m = pToFree = sqlite3_malloc( nByte ); + m = pToFree = sqlite3_malloc64( nByte ); if( m==0 ) return -1; /* Out of memory */ } a2 = (EditDist3To*)&m[n]; @@ -940,7 +940,7 @@ static int editDist3Core( if( i2+p->nTo>n2 ) continue; if( matchTo(p, z2+i2, n2-i2)==0 ) continue; a2[i2].nIns++; - apNew = sqlite3_realloc(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns); + apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns); if( apNew==0 ){ res = -1; /* Out of memory */ goto editDist3Abort; @@ -1118,7 +1118,7 @@ static void editDist3SqlFunc( */ static int editDist3Install(sqlite3 *db){ int rc; - EditDist3Config *pConfig = sqlite3_malloc( sizeof(*pConfig) ); + EditDist3Config *pConfig = sqlite3_malloc64( sizeof(*pConfig) ); if( pConfig==0 ) return SQLITE_NOMEM; memset(pConfig, 0, sizeof(*pConfig)); rc = sqlite3_create_function_v2(db, "editdist3", @@ -1607,7 +1607,7 @@ static const struct { ** should be freed by the caller. */ static unsigned char *transliterate(const unsigned char *zIn, int nIn){ - unsigned char *zOut = sqlite3_malloc( nIn*4 + 1 ); + unsigned char *zOut = sqlite3_malloc64( nIn*4 + 1 ); int c, sz, nOut; if( zOut==0 ) return 0; nOut = 0; @@ -1930,7 +1930,7 @@ static int spellfix1Init( int i; nDbName = (int)strlen(zDbName); - pNew = sqlite3_malloc( sizeof(*pNew) + nDbName + 1); + pNew = sqlite3_malloc64( sizeof(*pNew) + nDbName + 1); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -2044,7 +2044,7 @@ static void spellfix1ResetCursor(spellfix1_cursor *pCur){ static void spellfix1ResizeCursor(spellfix1_cursor *pCur, int N){ struct spellfix1_row *aNew; assert( N>=pCur->nRow ); - aNew = sqlite3_realloc(pCur->a, sizeof(pCur->a[0])*N); + aNew = sqlite3_realloc64(pCur->a, sizeof(pCur->a[0])*N); if( aNew==0 && N>0 ){ spellfix1ResetCursor(pCur); sqlite3_free(pCur->a); @@ -2203,7 +2203,7 @@ static int spellfix1BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ static int spellfix1Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ spellfix1_vtab *p = (spellfix1_vtab*)pVTab; spellfix1_cursor *pCur; - pCur = sqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3_malloc64( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); pCur->pVTab = p; @@ -2417,7 +2417,7 @@ static int spellfix1FilterForMatch( /* Load the cost table if we have not already done so */ if( p->zCostTable!=0 && p->pConfig3==0 ){ - p->pConfig3 = sqlite3_malloc( sizeof(p->pConfig3[0]) ); + p->pConfig3 = sqlite3_malloc64( sizeof(p->pConfig3[0]) ); if( p->pConfig3==0 ) return SQLITE_NOMEM; memset(p->pConfig3, 0, sizeof(p->pConfig3[0])); rc = editDist3ConfigLoad(p->pConfig3, p->db, p->zCostTable); diff --git a/manifest b/manifest index 3bb584fd54..b43bff0440 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Escape\scontrol\scharacters\sin\sJSON.\nFix\sfor\sticket\s[ad2559db380abf8]. -D 2016-02-04T10:28:57.253 +C Use\ssqlite3_malloc64()\sinstead\sof\ssqlite3_malloc()\sin\sthe\sspellfix\sextension. +D 2016-02-04T11:15:57.924 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -213,7 +213,7 @@ F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc F ext/misc/rot13.c 1ac6f95f99b575907b9b09c81a349114cf9be45a F ext/misc/series.c b8fb7befd85b3a9b4a10e701b30b2b79ca92b6d4 F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c db4cc4b7aa12384e6c19a289a39cd232d355413d +F ext/misc/spellfix.c 525190484b7a9dbc6be646c4842274fff4f27d53 F ext/misc/totype.c 4a167594e791abeed95e0a8db028822b5e8fe512 F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e @@ -1423,7 +1423,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 e3157cb5ad0d22758e766a95fb1463a7810f7d7f -R b212639d5d48b990a29409ffb71a1dde +P 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1 +R cd8475786d59a53ccb02d1969d7db950 U drh -Z b8b1a6316f2eff8be617256b6e3556cd +Z 726ec290d2122a80c8fe5371e8b4749b diff --git a/manifest.uuid b/manifest.uuid index 8bc8215408..c28b7cc350 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1 \ No newline at end of file +634d008c34bd237fc9cfb88dc291394fc5d31efa \ No newline at end of file From 4df86af329e606e8c92d5d41a8874e30ebb226cb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Feb 2016 11:48:00 +0000 Subject: [PATCH 079/107] Remove unnecessary sets of db->mallocFailed. FossilOrigin-Name: b787165b25a240fd5b4a5c7f73b395f30213a1d7 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/alter.c | 2 +- src/btree.c | 1 - src/build.c | 2 +- src/wherecode.c | 4 +--- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index b43bff0440..194c646e6b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3_malloc64()\sinstead\sof\ssqlite3_malloc()\sin\sthe\sspellfix\sextension. -D 2016-02-04T11:15:57.924 +C Remove\sunnecessary\ssets\sof\sdb->mallocFailed. +D 2016-02-04T11:48:00.219 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -284,17 +284,17 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 3fe13e97ab38317b092e2f3ae11267b40c9b5cbd +F src/alter.c b6e0befc17d69b59c66f4b8a126c05b1ee7ef10a F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 F src/attach.c 27743a694df17ca468eee3956126a5d28d2a29ea F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c a2a0244ea3f0b3f57f75019c2f229c744ca5d202 +F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 33dea2cef04c16a902c55f9d83b1a2065f213979 +F src/build.c 88ee370118ff7f081f2060ad3fb6c170f9aed7d3 F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -429,7 +429,7 @@ F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a -F src/wherecode.c 923f5d04b379b7417bc29f3b86b5eae9d1923d72 +F src/wherecode.c 791a784bbf8749d560fdb0b990b607bc4f44a38d F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1423,7 +1423,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 4f1b5229a3bbc9d40b7433a5eb3139d59d31dcb1 -R cd8475786d59a53ccb02d1969d7db950 +P 634d008c34bd237fc9cfb88dc291394fc5d31efa +R 0723d194047e6276e554e1a515e620e8 U drh -Z 726ec290d2122a80c8fe5371e8b4749b +Z 4a87610dafa418a613875dd84903b4d5 diff --git a/manifest.uuid b/manifest.uuid index c28b7cc350..8a6b51b9d7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -634d008c34bd237fc9cfb88dc291394fc5d31efa \ No newline at end of file +b787165b25a240fd5b4a5c7f73b395f30213a1d7 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index c8102c55d2..16b7a9e192 100644 --- a/src/alter.c +++ b/src/alter.c @@ -803,7 +803,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ - db->mallocFailed = 1; + assert( db->mallocFailed ); goto exit_begin_add_column; } memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); diff --git a/src/btree.c b/src/btree.c index d5acaf3669..b99820ddbc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -2338,7 +2338,6 @@ int sqlite3BtreeOpen( pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM; - db->mallocFailed = 0; goto btree_open_out; } } diff --git a/src/build.c b/src/build.c index 3ca4c99947..cea05d51c7 100644 --- a/src/build.c +++ b/src/build.c @@ -926,7 +926,7 @@ void sqlite3StartTable( pTable = sqlite3DbMallocZero(db, sizeof(Table)); if( pTable==0 ){ - db->mallocFailed = 1; + assert( db->mallocFailed ); pParse->rc = SQLITE_NOMEM; pParse->nErr++; goto begin_table_error; diff --git a/src/wherecode.c b/src/wherecode.c index f5f45da397..bb48e5dc70 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -495,9 +495,7 @@ static int codeAllEqualityTerms( pParse->nMem += nReg; zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); - if( !zAff ){ - pParse->db->mallocFailed = 1; - } + assert( zAff!=0 || pParse->db->mallocFailed ); if( nSkip ){ int iIdxCur = pLevel->iIdxCur; From be7721d10339d31ffd0db5eddc45c8483f1a6fba Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 4 Feb 2016 17:31:03 +0000 Subject: [PATCH 080/107] Avoid running some particularly time-consuming tests as part of veryquick.test. FossilOrigin-Name: f465944b75a800ddc6920229ad32c2f39ff91e19 --- manifest | 41 ++-- manifest.uuid | 2 +- test/fuzzer1.test | 46 ----- test/fuzzer2.test | 72 +++++++ test/mmap1.test | 65 +------ test/mmap4.test | 104 ++++++++++ test/permutations.test | 20 +- test/{savepoint3.test => savepointfault.test} | 13 +- test/sort.test | 46 ----- test/sort2.test | 28 +-- test/sort3.test | 51 ++++- test/tester.tcl | 6 + test/wal.test | 85 --------- test/wal3.test | 143 +------------- test/walcksum.test | 54 ------ test/walprotocol.test | 177 ++++++++++++++++++ test/walslow.test | 158 ++++++++++++++++ test/{where8m.test => wherefault.test} | 12 +- 18 files changed, 639 insertions(+), 484 deletions(-) create mode 100644 test/fuzzer2.test create mode 100644 test/mmap4.test rename test/{savepoint3.test => savepointfault.test} (94%) create mode 100644 test/walprotocol.test rename test/{where8m.test => wherefault.test} (84%) diff --git a/manifest b/manifest index 194c646e6b..7b935898ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\ssets\sof\sdb->mallocFailed. -D 2016-02-04T11:48:00.219 +C Avoid\srunning\ssome\sparticularly\stime-consuming\stests\sas\spart\sof\sveryquick.test. +D 2016-02-04T17:31:03.368 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -769,7 +769,8 @@ F test/fuzzdata1.db 7ee3227bad0e7ccdeb08a9e6822916777073c664 F test/fuzzdata2.db f03a420d3b822cc82e4f894ca957618fbe9c4973 F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db 1882f0055fb63214d8407ddc7aca9b0b1c59af21 -F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 +F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 +F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/hexlit.test d7b0a5f41123df1e43985b91b8b2e70f95282d21 @@ -897,9 +898,10 @@ F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test edd0b63e2ee29a256900b0514f6fff27e19e9bb2 F test/misc8.test fc2754d38892f7dac30c22db3616c2764f117d66 F test/misuse.test 3c34719944ba045cc6c188a4852ba04680728912 -F test/mmap1.test 1bfd611b9841eafb44f7d83c0788e146d84a33c9 +F test/mmap1.test 44a5ff1c1bcc7dcf2de50227d1f997e75a8ef1ae F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e +F test/mmap4.test 2e2b4e32555b58da15176e6fe750f17c9dcf7f93 F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3 F test/multiplex.test efd015ca0b5b4a57dc9535b8feb1273eebeadb60 F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a @@ -942,7 +944,7 @@ F test/parser1.test 222b5cbf3e2e659fec1bf7d723488c8b9c94f1d0 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 4ea119731c62d2f7d0aa86dd5b184cbb61ca411b +F test/permutations.test 382a43c49f49bafe6fddffe904ea33d6bb3ff33e F test/pragma.test 507ac7ef2ea5682241ea0ef041799ca70bb5e0bf F test/pragma2.test a9400a7289605280576098b97f5cde3f204075c0 F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c @@ -974,11 +976,11 @@ F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test c671fdbd34cd3bfe1518a777526ada595180cf8d F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 -F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 +F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 w test/savepoint3.test F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 @@ -1034,9 +1036,9 @@ F test/snapshot.test efc6b4edc5d571161835f9dd8552e181ad1f0ac2 F test/snapshot_fault.test 25973aeb1b86a280800e0bcf1eb5ce70e9ef57ab F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 -F test/sort.test 3f492e5b7be1d3f756728d2ff6edf4f6091e84cb -F test/sort2.test 37afbc03f5559f2eb0f18940b55d38dfbb5172ac -F test/sort3.test 6178ade30810ac9166fcdf14b7065e49c0f534e2 +F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b +F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 +F test/sort3.test 1d831e95076b92985754a122e92ebc23bdf6f712 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 @@ -1076,7 +1078,7 @@ F test/tclsqlite.test 7fb866443c7deceed22b63948ccd6f76b52ad054 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1 -F test/tester.tcl af4749cf4abf04291710c5e73f40bc8f411bae86 +F test/tester.tcl 462376b478c1429030911b4cb7c8c517ef1fbd9b F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5 F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1294,9 +1296,9 @@ F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 -F test/wal.test 65bfc68f3f09dcbc62cee9f794e560428d96cec7 +F test/wal.test 0148c8b3421a25fdb4d9c160e84a681d0646371b F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada -F test/wal3.test b1d425f68a1f61d12563f0fa1ee6fca7d5afabf4 +F test/wal3.test 5dd734147f1f8f958c5261a1f2775d346d7013ce F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 88b5d9a6a3d1532497ee9f4296f010d66f07e33c F test/wal6.test 4421cd5a2fa99d29cc91ef12fb23bed171ed3a4c @@ -1308,7 +1310,7 @@ F test/wal_common.tcl a98f17fba96206122eff624db0ab13ec377be4fe F test/walbak.test b9f68e39646375c2b877be906babcc15d38b4877 F test/walbig.test f437473a16cfb314867c6b5d1dbcd519e73e3434 F test/walblock.test be48f3a75eff0b4456209f26b3ce186c2015497d -F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa +F test/walcksum.test bb234a1bb42248b3515d992b719708015c384278 F test/walcrash.test 21038858cc552077b0522f50b0fa87e38139306a F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af @@ -1318,9 +1320,10 @@ F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 F test/waloverwrite.test a0d2ae0783187374c1e6a9571e0916152977cb81 F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 +F test/walprotocol.test 059cb75484a1ecf6357a2c1b3324b8156749221e F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 -F test/walslow.test e7be6d9888f83aa5d3d3c7c08aa9b5c28b93609a +F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test de8dbaf6d9e41481c460ba31ca61e163d7348f8e F test/where.test 9902a3d84e9bc80357a2c54ed0e76c0d6d04a867 F test/where2.test af78c55589cbc82d793449493adba0dc3d659f23 @@ -1330,7 +1333,6 @@ F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test f520bcec2c3d12dc4615623b06b2aec7c2d67e94 F test/where8.test 98eedca0d375fb400b8377269c4b4686582dfb45 -F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739 F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2 F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 @@ -1343,6 +1345,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b +F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 w test/where8m.test F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1423,7 +1426,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 634d008c34bd237fc9cfb88dc291394fc5d31efa -R 0723d194047e6276e554e1a515e620e8 -U drh -Z 4a87610dafa418a613875dd84903b4d5 +P b787165b25a240fd5b4a5c7f73b395f30213a1d7 +R 2d9511ba502b30b0a28170783af34756 +U dan +Z 9311e6c3b97d9e579dd5eb1512f82842 diff --git a/manifest.uuid b/manifest.uuid index 8a6b51b9d7..81e89adc73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b787165b25a240fd5b4a5c7f73b395f30213a1d7 \ No newline at end of file +f465944b75a800ddc6920229ad32c2f39ff91e19 \ No newline at end of file diff --git a/test/fuzzer1.test b/test/fuzzer1.test index 4ee5730807..5e361e9df0 100644 --- a/test/fuzzer1.test +++ b/test/fuzzer1.test @@ -23,7 +23,6 @@ ifcapable !vtab { } set ::testprefix fuzzer1 - load_static_extension db fuzzer # Check configuration errors. @@ -1648,51 +1647,6 @@ do_catchsql_test 5.5.4 { CREATE VIRTUAL TABLE x USING fuzzer('fuzzer [x] rules table'); } {1 {fuzzer: ruleset must be between 0 and 2147483647}} -#------------------------------------------------------------------------- -# This test uses a fuzzer table with many rules. There is one rule to -# map each possible two character string, where characters are lower-case -# letters used in the English language, to all other possible two character -# strings. In total, (26^4)-(26^2) mappings (the subtracted term represents -# the no-op mappings discarded automatically by the fuzzer). -# -# -do_execsql_test 6.1.1 { - DROP TABLE IF EXISTS x1; - DROP TABLE IF EXISTS x1_rules; - CREATE TABLE x1_rules(ruleset, cFrom, cTo, cost); -} -puts "This test is slow - perhaps around 7 seconds on an average pc" -do_test 6.1.2 { - set LETTERS {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 cost 1 - db transaction { - foreach c1 $LETTERS { - foreach c2 $LETTERS { - foreach c3 $LETTERS { - foreach c4 $LETTERS { - db eval {INSERT INTO x1_rules VALUES(0, $c1||$c2, $c3||$c4, $cost)} - set cost [expr ($cost%1000) + 1] - } - } - } - } - db eval {UPDATE x1_rules SET cost = 20 WHERE cost<20 AND cFrom!='xx'} - } -} {} - -do_execsql_test 6.2 { - SELECT count(*) FROM x1_rules WHERE cTo!=cFrom; -} [expr 26*26*26*26 - 26*26] - -do_execsql_test 6.2.1 { - CREATE VIRTUAL TABLE x1 USING fuzzer(x1_rules); - SELECT word FROM x1 WHERE word MATCH 'xx' LIMIT 10; -} {xx hw hx hy hz ia ib ic id ie} -do_execsql_test 6.2.2 { - SELECT cTo FROM x1_rules WHERE cFrom='xx' - ORDER BY cost asc, rowid asc LIMIT 9; -} {hw hx hy hz ia ib ic id ie} - #------------------------------------------------------------------------- # Test using different types of quotes with CREATE VIRTUAL TABLE # arguments. diff --git a/test/fuzzer2.test b/test/fuzzer2.test new file mode 100644 index 0000000000..44ee9e312c --- /dev/null +++ b/test/fuzzer2.test @@ -0,0 +1,72 @@ +# 2016 February 4 +# +# 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. +# +#*********************************************************************** +# The focus of the tests is the word-fuzzer virtual table. The tests +# in this file are slower than those in fuzzer1.test. So this file does +# not run as part of veryquick.test etc. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !vtab { + finish_test + return +} + +set ::testprefix fuzzer2 +load_static_extension db fuzzer + +#------------------------------------------------------------------------- +# This test uses a fuzzer table with many rules. There is one rule to +# map each possible two character string, where characters are lower-case +# letters used in the English language, to all other possible two character +# strings. In total, (26^4)-(26^2) mappings (the subtracted term represents +# the no-op mappings discarded automatically by the fuzzer). +# +# +do_execsql_test 1.1.1 { + DROP TABLE IF EXISTS x1; + DROP TABLE IF EXISTS x1_rules; + CREATE TABLE x1_rules(ruleset, cFrom, cTo, cost); +} +puts "This test is slow - perhaps around 7 seconds on an average pc" +do_test 1.1.2 { + set LETTERS {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 cost 1 + db transaction { + foreach c1 $LETTERS { + foreach c2 $LETTERS { + foreach c3 $LETTERS { + foreach c4 $LETTERS { + db eval {INSERT INTO x1_rules VALUES(0, $c1||$c2, $c3||$c4, $cost)} + set cost [expr ($cost%1000) + 1] + } + } + } + } + db eval {UPDATE x1_rules SET cost = 20 WHERE cost<20 AND cFrom!='xx'} + } +} {} + +do_execsql_test 1.2 { + SELECT count(*) FROM x1_rules WHERE cTo!=cFrom; +} [expr 26*26*26*26 - 26*26] + +do_execsql_test 1.2.1 { + CREATE VIRTUAL TABLE x1 USING fuzzer(x1_rules); + SELECT word FROM x1 WHERE word MATCH 'xx' LIMIT 10; +} {xx hw hx hy hz ia ib ic id ie} +do_execsql_test 1.2.2 { + SELECT cTo FROM x1_rules WHERE cFrom='xx' + ORDER BY cost asc, rowid asc LIMIT 9; +} {hw hx hy hz ia ib ic id ie} + +finish_test diff --git a/test/mmap1.test b/test/mmap1.test index 18aec9f8fa..199a058754 100644 --- a/test/mmap1.test +++ b/test/mmap1.test @@ -28,6 +28,10 @@ proc nRead {db} { return $stats(read) } +# Return a Tcl script that registers a user-defined scalar function +# named rblob() with database handle $dbname. The function returns a +# sequence of pseudo-random blobs based on seed value $seed. +# proc register_rblob_code {dbname seed} { return [subst -nocommands { set ::rcnt $seed @@ -40,6 +44,7 @@ proc register_rblob_code {dbname seed} { }] } + # For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on # unix and 9 on windows. The difference is that windows only ever maps # an integer number of OS pages (i.e. creates mappings that are a multiple @@ -269,65 +274,5 @@ do_test 5.5 { sqlite3_finalize $::STMT } SQLITE_OK -#------------------------------------------------------------------------- -# Test various mmap_size settings. -# -foreach {tn1 mmap1 mmap2} { - 1 6144 167773 - 2 18432 140399 - 3 43008 401302 - 4 92160 253899 - 5 190464 2 - 6 387072 752431 - 7 780288 291143 - 8 1566720 594306 - 9 3139584 829137 - 10 6285312 793963 - 11 12576768 1015590 -} { - do_multiclient_test tn { - sql1 { - CREATE TABLE t1(a PRIMARY KEY); - CREATE TABLE t2(x); - INSERT INTO t2 VALUES(''); - } - - code1 [register_rblob_code db 0] - code2 [register_rblob_code db2 444] - - sql1 "PRAGMA mmap_size = $mmap1" - sql2 "PRAGMA mmap_size = $mmap2" - - do_test $tn1.$tn { - for {set i 1} {$i <= 100} {incr i} { - if {$i % 2} { - set c1 sql1 - set c2 sql2 - } else { - set c1 sql2 - set c2 sql1 - } - - $c1 { - INSERT INTO t1 VALUES( rblob(5000) ); - UPDATE t2 SET x = (SELECT md5sum(a) FROM t1); - } - - set res [$c2 { - SELECT count(*) FROM t1; - SELECT x == (SELECT md5sum(a) FROM t1) FROM t2; - PRAGMA integrity_check; - }] - if {$res != [list $i 1 ok]} { - do_test $tn1.$tn.$i { - set ::res - } [list $i 1 ok] - } - } - set res 1 - } {1} - } -} - finish_test diff --git a/test/mmap4.test b/test/mmap4.test new file mode 100644 index 0000000000..97015489cc --- /dev/null +++ b/test/mmap4.test @@ -0,0 +1,104 @@ +# 2016 February 04 +# +# 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 tests the effect of the mmap() or mremap() system calls +# returning an error on the library. +# +# If either mmap() or mremap() fails, SQLite should log an error +# message, then continue accessing the database using read() and +# write() exclusively. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +ifcapable !mmap { + finish_test + return +} +source $testdir/lock_common.tcl +set testprefix mmap4 + +# Return a Tcl script that registers a user-defined scalar function +# named rblob() with database handle $dbname. The function returns a +# sequence of pseudo-random blobs based on seed value $seed. +# +proc register_rblob_code {dbname seed} { + return [subst -nocommands { + set ::rcnt $seed + proc rblob {n} { + set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF] + set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] + string range [string repeat [set str] [expr [set n]/4]] 1 [set n] + } + $dbname func rblob rblob + }] +} + +#------------------------------------------------------------------------- +# Test various mmap_size settings. +# +foreach {tn1 mmap1 mmap2} { + 1 6144 167773 + 2 18432 140399 + 3 43008 401302 + 4 92160 253899 + 5 190464 2 + 6 387072 752431 + 7 780288 291143 + 8 1566720 594306 + 9 3139584 829137 + 10 6285312 793963 + 11 12576768 1015590 +} { + do_multiclient_test tn { + sql1 { + CREATE TABLE t1(a PRIMARY KEY); + CREATE TABLE t2(x); + INSERT INTO t2 VALUES(''); + } + + code1 [register_rblob_code db 0] + code2 [register_rblob_code db2 444] + + sql1 "PRAGMA mmap_size = $mmap1" + sql2 "PRAGMA mmap_size = $mmap2" + + do_test $tn1.$tn { + for {set i 1} {$i <= 100} {incr i} { + if {$i % 2} { + set c1 sql1 + set c2 sql2 + } else { + set c1 sql2 + set c2 sql1 + } + + $c1 { + INSERT INTO t1 VALUES( rblob(5000) ); + UPDATE t2 SET x = (SELECT md5sum(a) FROM t1); + } + + set res [$c2 { + SELECT count(*) FROM t1; + SELECT x == (SELECT md5sum(a) FROM t1) FROM t2; + PRAGMA integrity_check; + }] + if {$res != [list $i 1 ok]} { + do_test $tn1.$tn.$i { + set ::res + } [list $i 1 ok] + } + } + set res 1 + } {1} + } +} + +finish_test diff --git a/test/permutations.test b/test/permutations.test index 28bbd3017e..c099889067 100644 --- a/test/permutations.test +++ b/test/permutations.test @@ -113,7 +113,14 @@ set allquicktests [test_set $alltests -exclude { vtab_err.test walslow.test walcrash.test walcrash3.test walthread.test rtree3.test indexfault.test securedel2.test sort3.test sort4.test fts4growth.test fts4growth2.test - bigsort.test rbu.test + bigsort.test rbu.test walprotocol.test mmap4.test fuzzer2.test + walcrash2.test e_fkey.test backup.test + + fts4merge.test fts4merge2.test fts4merge4.test fts4check.test + fts3cov.test fts3snippet.test fts3corrupt2.test fts3an.test + fts3defer.test fts4langid.test fts3sort.test fts5unicode.test + + rtree4.test }] if {[info exists ::env(QUICKTEST_INCLUDE)]} { set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)] @@ -150,7 +157,7 @@ test_suite "veryquick" -prefix "" -description { This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* ] test_suite "extraquick" -prefix "" -description { @@ -158,7 +165,7 @@ test_suite "extraquick" -prefix "" -description { This test suite is the same as the "veryquick" tests, except that slower tests are omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* \ + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \ wal3.test fts4merge* sort2.test mmap1.test walcrash* \ percentile.test where8m.test walcksum.test savepoint3.test \ fuzzer1.test fuzzer3.test fts3expr3.test @@ -176,7 +183,7 @@ test_suite "valgrind" -prefix "" -description { Run the "veryquick" test suite with a couple of multi-process tests (that fail under valgrind) omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* wal.test \ + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \ shell*.test crash8.test atof1.test selectG.test \ tkt-fc62af4523.test numindex1.test ] -initialize { @@ -189,7 +196,8 @@ test_suite "valgrind-nolookaside" -prefix "" -description { Run the "veryquick" test suite with a couple of multi-process tests (that fail under valgrind) omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* wal.test atof1.test + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* \ + wal.test atof1.test ] -initialize { set ::G(valgrind) 1 catch {db close} @@ -266,7 +274,7 @@ test_suite "nofaultsim" -prefix "" -description { This test suite is the same as the "quick" tests, except that some files that test malloc and IO errors are omitted. } -files [ - test_set $allquicktests -exclude *malloc* *ioerr* *fault* + test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* ] -initialize { catch {db close} sqlite3_shutdown diff --git a/test/savepoint3.test b/test/savepointfault.test similarity index 94% rename from test/savepoint3.test rename to test/savepointfault.test index 0dcb0aceba..0329f8caa2 100644 --- a/test/savepoint3.test +++ b/test/savepointfault.test @@ -9,14 +9,15 @@ # #*********************************************************************** # -# $Id: savepoint3.test,v 1.5 2009/06/05 17:09:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl -do_malloc_test savepoint3-1 -sqlprep { +set testprefix savepointfault + +do_malloc_test 1 -sqlprep { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(1, 2, 3); } -sqlbody { @@ -28,7 +29,7 @@ do_malloc_test savepoint3-1 -sqlprep { RELEASE one; } -do_malloc_test savepoint3-2 -sqlprep { +do_malloc_test 2 -sqlprep { PRAGMA cache_size = 10; CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(randstr(400,400), randstr(400,400), randstr(400,400)); @@ -59,7 +60,7 @@ do_malloc_test savepoint3-2 -sqlprep { RELEASE one; } -do_ioerr_test savepoint3.3 -sqlprep { +do_ioerr_test 3 -sqlprep { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(1, randstr(1000,1000), randstr(1000,1000)); INSERT INTO t1 VALUES(2, randstr(1000,1000), randstr(1000,1000)); @@ -79,7 +80,7 @@ do_ioerr_test savepoint3.3 -sqlprep { # The following test does a really big savepoint rollback. One involving # more than 4000 pages. The idea is to get a specific sqlite3BitvecSet() # operation in pagerPlaybackSavepoint() to fail. -#do_malloc_test savepoint3-4 -sqlprep { +#do_malloc_test 4 -sqlprep { # BEGIN; # CREATE TABLE t1(a, b); # CREATE INDEX i1 ON t1(a); @@ -107,7 +108,7 @@ do_ioerr_test savepoint3.3 -sqlprep { # Cause a specific malloc in savepoint rollback code to fail. # -do_malloc_test savepoint3-4 -start 7 -sqlprep { +do_malloc_test 4 -start 7 -sqlprep { PRAGMA auto_vacuum = incremental; PRAGMA cache_size = 1000; diff --git a/test/sort.test b/test/sort.test index 21b11d6c88..d73ecea480 100644 --- a/test/sort.test +++ b/test/sort.test @@ -491,52 +491,6 @@ do_execsql_test sort-13.3 { SELECT a, b FROM t10 ORDER BY a; } [db eval {SELECT a, b FROM t10 ORDER BY a, b}] -#------------------------------------------------------------------------- -# Sort some large ( > 4KiB) records. -# -proc cksum {x} { - set i1 1 - set i2 2 - binary scan $x c* L - foreach {a b} $L { - set i1 [expr (($i2<<3) + $a) & 0x7FFFFFFF] - set i2 [expr (($i1<<3) + $b) & 0x7FFFFFFF] - } - list $i1 $i2 -} -db func cksum cksum - -do_execsql_test sort-14.0 { - PRAGMA cache_size = 5; - CREATE TABLE t11(a, b); - INSERT INTO t11 VALUES(randomblob(5000), NULL); - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --2 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --3 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --4 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --5 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --6 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --7 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --8 - INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --9 - UPDATE t11 SET b = cksum(a); -} - -foreach {tn mmap_limit} { - 1 0 - 2 1000000 -} { - do_test sort-14.$tn { - sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit - set prev "" - db eval { SELECT * FROM t11 ORDER BY b } { - if {$b != [cksum $a]} {error "checksum failed"} - if {[string compare $b $prev] < 0} {error "sort failed"} - set prev $b - } - set {} {} - } {} -} - #------------------------------------------------------------------------- # foreach {tn mmap_limit nWorker tmpstore coremutex fakeheap softheaplimit} { diff --git a/test/sort2.test b/test/sort2.test index 890025a5d0..f686654d53 100644 --- a/test/sort2.test +++ b/test/sort2.test @@ -31,7 +31,6 @@ foreach {tn script} { catch { db eval {PRAGMA threads=7} } } } { - eval $script do_execsql_test $tn.1 { @@ -67,17 +66,22 @@ foreach {tn script} { do_execsql_test $tn.2.4 { PRAGMA integrity_check } {ok} - do_execsql_test $tn.3 { - PRAGMA cache_size = 5; - WITH r(x,y) AS ( - SELECT 1, randomblob(100) - UNION ALL - SELECT x+1, randomblob(100) FROM r - LIMIT 1000000 - ) - SELECT count(x), length(y) FROM r GROUP BY (x%5) - } { - 200000 100 200000 100 200000 100 200000 100 200000 100 + # Because it uses so much data, this test can take 12-13 seconds even on + # a modern workstation. So it is omitted from "veryquick" and other + # permutations.test tests. + if {[isquick]==0} { + do_execsql_test $tn.3 { + PRAGMA cache_size = 5; + WITH r(x,y) AS ( + SELECT 1, randomblob(100) + UNION ALL + SELECT x+1, randomblob(100) FROM r + LIMIT 1000000 + ) + SELECT count(x), length(y) FROM r GROUP BY (x%5) + } { + 200000 100 200000 100 200000 100 200000 100 200000 100 + } } } diff --git a/test/sort3.test b/test/sort3.test index 80d8bbca3f..3aa6512a4b 100644 --- a/test/sort3.test +++ b/test/sort3.test @@ -19,6 +19,53 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix sort3 +#------------------------------------------------------------------------- +# Sort some large ( > 4KiB) records. +# +proc cksum {x} { + set i1 1 + set i2 2 + binary scan $x c* L + foreach {a b} $L { + set i1 [expr (($i2<<3) + $a) & 0x7FFFFFFF] + set i2 [expr (($i1<<3) + $b) & 0x7FFFFFFF] + } + list $i1 $i2 +} +db func cksum cksum + +do_execsql_test 1.0 { + PRAGMA cache_size = 5; + CREATE TABLE t11(a, b); + INSERT INTO t11 VALUES(randomblob(5000), NULL); + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --2 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --3 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --4 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --5 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --6 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --7 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --8 + INSERT INTO t11 SELECT randomblob(5000), NULL FROM t11; --9 + UPDATE t11 SET b = cksum(a); +} + +foreach {tn mmap_limit} { + 1 0 + 2 1000000 +} { + do_test 1.$tn { + sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $mmap_limit + set prev "" + db eval { SELECT * FROM t11 ORDER BY b } { + if {$b != [cksum $a]} {error "checksum failed"} + if {[string compare $b $prev] < 0} {error "sort failed"} + set prev $b + } + set {} {} + } {} +} + + # Sort roughly 20MB of data. Once with a mmap limit of 5MB and once without. # foreach {itest limit} { @@ -26,7 +73,7 @@ foreach {itest limit} { 2 0x7FFFFFFF } { sqlite3_test_control SQLITE_TESTCTRL_SORTER_MMAP db $limit - do_execsql_test 1.$itest { + do_execsql_test 2.$itest { WITH r(x,y) AS ( SELECT 1, randomblob(1000) UNION ALL @@ -46,7 +93,7 @@ foreach {itest limit} { # Sort more than 2GB of data. At one point this was causing a problem. # This test might take one minute or more to run. # -do_execsql_test 2 { +do_execsql_test 3 { PRAGMA cache_size = 20000; WITH r(x,y) AS ( SELECT 1, randomblob(1000) diff --git a/test/tester.tcl b/test/tester.tcl index 426808ea90..dc532c97fa 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1905,6 +1905,12 @@ proc presql {} { set presql } +proc isquick {} { + set ret 0 + catch {set ret $::G(isquick)} + set ret +} + #------------------------------------------------------------------------- # proc slave_test_script {script} { diff --git a/test/wal.test b/test/wal.test index abd3a3ce49..92b65e66ba 100644 --- a/test/wal.test +++ b/test/wal.test @@ -824,91 +824,6 @@ do_test wal-12.6 { db2 close db close -#------------------------------------------------------------------------- -# Test large log summaries. -# -# In this case "large" usually means a log file that requires a wal-index -# mapping larger than 64KB (the default initial allocation). A 64KB wal-index -# is large enough for a log file that contains approximately 13100 frames. -# So the following tests create logs containing at least this many frames. -# -# wal-13.1.*: This test case creates a very large log file within the -# file-system (around 200MB). The log file does not contain -# any valid frames. Test that the database file can still be -# opened and queried, and that the invalid log file causes no -# problems. -# -# wal-13.2.*: Test that a process may create a large log file and query -# the database (including the log file that it itself created). -# -# wal-13.3.*: Test that if a very large log file is created, and then a -# second connection is opened on the database file, it is possible -# to query the database (and the very large log) using the -# second connection. -# -# wal-13.4.*: Same test as wal-13.3.*. Except in this case the second -# connection is opened by an external process. -# -do_test wal-13.1.1 { - list [file exists test.db] [file exists test.db-wal] -} {1 0} -do_test wal-13.1.2 { - set fd [open test.db-wal w] - seek $fd [expr 200*1024*1024] - puts $fd "" - close $fd - sqlite3 db test.db - execsql { SELECT * FROM t2 } -} {B 2} -do_test wal-13.1.3 { - db close - file exists test.db-wal -} {0} - -do_test wal-13.2.1 { - sqlite3 db test.db - execsql { SELECT count(*) FROM t2 } -} {1} -do_test wal-13.2.2 { - db function blob blob - for {set i 0} {$i < 16} {incr i} { - execsql { INSERT INTO t2 SELECT blob(400), blob(400) FROM t2 } - } - execsql { SELECT count(*) FROM t2 } -} [expr int(pow(2, 16))] -do_test wal-13.2.3 { - expr [file size test.db-wal] > [wal_file_size 33000 1024] -} 1 - -do_multiclient_test tn { - incr tn 2 - - do_test wal-13.$tn.0 { - sql1 { - PRAGMA journal_mode = WAL; - CREATE TABLE t1(x); - INSERT INTO t1 SELECT randomblob(800); - } - sql1 { SELECT count(*) FROM t1 } - } {1} - - for {set ii 1} {$ii<16} {incr ii} { - do_test wal-13.$tn.$ii.a { - sql2 { INSERT INTO t1 SELECT randomblob(800) FROM t1 } - sql2 { SELECT count(*) FROM t1 } - } [expr (1<<$ii)] - do_test wal-13.$tn.$ii.b { - sql1 { SELECT count(*) FROM t1 } - } [expr (1<<$ii)] - do_test wal-13.$tn.$ii.c { - sql1 { SELECT count(*) FROM t1 } - } [expr (1<<$ii)] - do_test wal-13.$tn.$ii.d { - sql1 { PRAGMA integrity_check } - } {ok} - } -} - #------------------------------------------------------------------------- # Check a fun corruption case has been fixed. # diff --git a/test/wal3.test b/test/wal3.test index 9ee8a99458..da3d318773 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -61,7 +61,7 @@ do_test wal3-1.0 { PRAGMA cache_size = 10; } set x [wal_frame_count test.db-wal 1024] - if {$::G(perm:name)=="memsubsys1"} { + if {[permutation]=="memsubsys1"} { if {$x==4251 || $x==4290} {set x 4056} } set x @@ -238,67 +238,6 @@ foreach {tn syncmode synccount} { T delete } -#------------------------------------------------------------------------- -# When recovering the contents of a WAL file, a process obtains the WRITER -# lock, then locks all other bytes before commencing recovery. If it fails -# to lock all other bytes (because some other process is holding a read -# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the -# caller. Test this (test case wal3-4.3). -# -# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain -# the WRITER lock (should be the same). Test case wal3-4.4. -# -proc lock_callback {method filename handle lock} { - lappend ::locks $lock -} -do_test wal3-4.1 { - testvfs T - T filter xShmLock - T script lock_callback - set ::locks [list] - sqlite3 db test.db -vfs T - execsql { SELECT * FROM x } - lrange $::locks 0 3 -} [list {0 1 lock exclusive} {1 7 lock exclusive} \ - {1 7 unlock exclusive} {0 1 unlock exclusive} \ -] -do_test wal3-4.2 { - db close - set ::locks [list] - sqlite3 db test.db -vfs T - execsql { SELECT * FROM x } - lrange $::locks 0 3 -} [list {0 1 lock exclusive} {1 7 lock exclusive} \ - {1 7 unlock exclusive} {0 1 unlock exclusive} \ -] -proc lock_callback {method filename handle lock} { - if {$lock == "1 7 lock exclusive"} { return SQLITE_BUSY } - return SQLITE_OK -} -puts "# Warning: This next test case causes SQLite to call xSleep(1) 100 times." -puts "# Normally this equates to a 100ms delay, but if SQLite is built on unix" -puts "# without HAVE_USLEEP defined, it may be 100 seconds." -do_test wal3-4.3 { - db close - set ::locks [list] - sqlite3 db test.db -vfs T - catchsql { SELECT * FROM x } -} {1 {locking protocol}} - -puts "# Warning: Same again!" -proc lock_callback {method filename handle lock} { - if {$lock == "0 1 lock exclusive"} { return SQLITE_BUSY } - return SQLITE_OK -} -do_test wal3-4.4 { - db close - set ::locks [list] - sqlite3 db test.db -vfs T - catchsql { SELECT * FROM x } -} {1 {locking protocol}} -db close -T delete - #------------------------------------------------------------------------- # Only one client may run recovery at a time. Test this mechanism. @@ -617,86 +556,6 @@ db close db2 close T delete -#------------------------------------------------------------------------- -# -do_test wal3-8.1 { - forcedelete test.db test.db-journal test.db wal - sqlite3 db test.db - sqlite3 db2 test.db - execsql { - PRAGMA auto_vacuum = off; - PRAGMA journal_mode = WAL; - CREATE TABLE b(c); - INSERT INTO b VALUES('Tehran'); - INSERT INTO b VALUES('Qom'); - INSERT INTO b VALUES('Markazi'); - PRAGMA wal_checkpoint; - } -} {wal 0 5 5} -do_test wal3-8.2 { - execsql { SELECT * FROM b } -} {Tehran Qom Markazi} -do_test wal3-8.3 { - db eval { SELECT * FROM b } { - db eval { INSERT INTO b VALUES('Qazvin') } - set r [db2 eval { SELECT * FROM b }] - break - } - set r -} {Tehran Qom Markazi Qazvin} -do_test wal3-8.4 { - execsql { - INSERT INTO b VALUES('Gilan'); - INSERT INTO b VALUES('Ardabil'); - } -} {} -db2 close - -faultsim_save_and_close -testvfs T -default 1 -faultsim_restore_and_reopen -T filter xShmLock -T script lock_callback - -proc lock_callback {method file handle spec} { - if {$spec == "1 7 unlock exclusive"} { - T filter {} - set ::r [catchsql { SELECT * FROM b } db2] - } -} -sqlite3 db test.db -sqlite3 db2 test.db -do_test wal3-8.5 { - execsql { SELECT * FROM b } -} {Tehran Qom Markazi Qazvin Gilan Ardabil} -do_test wal3-8.6 { - set ::r -} {1 {locking protocol}} - -db close -db2 close - -faultsim_restore_and_reopen -sqlite3 db2 test.db -T filter xShmLock -T script lock_callback -proc lock_callback {method file handle spec} { - if {$spec == "1 7 unlock exclusive"} { - T filter {} - set ::r [catchsql { SELECT * FROM b } db2] - } -} -unset ::r -do_test wal3-8.5 { - execsql { SELECT * FROM b } -} {Tehran Qom Markazi Qazvin Gilan Ardabil} -do_test wal3-8.6 { - set ::r -} {1 {locking protocol}} - -db close -db2 close -T delete #------------------------------------------------------------------------- # When a connection opens a read-lock on the database, it searches for diff --git a/test/walcksum.test b/test/walcksum.test index 3005a758ac..f3fc427115 100644 --- a/test/walcksum.test +++ b/test/walcksum.test @@ -334,59 +334,5 @@ do_test walcksum-2.1 { catch { db close } catch { db2 close } -#------------------------------------------------------------------------- -# Test case walcksum-3.* tests that the checksum calculation detects single -# byte changes to frame or frame-header data and considers the frame -# invalid as a result. -# -do_test walcksum-3.1 { - forcedelete test.db test.db-wal test.db-journal - sqlite3 db test.db - - execsql { - PRAGMA synchronous = NORMAL; - PRAGMA page_size = 1024; - CREATE TABLE t1(a, b); - INSERT INTO t1 VALUES(1, randomblob(300)); - INSERT INTO t1 VALUES(2, randomblob(300)); - PRAGMA journal_mode = WAL; - INSERT INTO t1 VALUES(3, randomblob(300)); - } - - file size test.db-wal -} [wal_file_size 1 1024] -do_test walcksum-3.2 { - forcecopy test.db-wal test2.db-wal - forcecopy test.db test2.db - sqlite3 db2 test2.db - execsql { SELECT a FROM t1 } db2 -} {1 2 3} -db2 close -forcecopy test.db test2.db - - -foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { - do_test walcksum-3.3.$incr { - set FAIL 0 - for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { - - forcecopy test.db-wal test2.db-wal - set fd [open test2.db-wal r+] - fconfigure $fd -encoding binary - fconfigure $fd -translation binary - - seek $fd $iOff - binary scan [read $fd 1] c x - seek $fd $iOff - puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]] - close $fd - - sqlite3 db2 test2.db - if { [execsql { SELECT a FROM t1 } db2] != "1 2" } {set FAIL 1} - db2 close - } - set FAIL - } {0} -} finish_test diff --git a/test/walprotocol.test b/test/walprotocol.test new file mode 100644 index 0000000000..d658de9d7c --- /dev/null +++ b/test/walprotocol.test @@ -0,0 +1,177 @@ +# 2016 February 4 +# +# 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 operation of the library in +# "PRAGMA journal_mode=WAL" mode. +# +# More specifically, it tests "locking protocol" errors - errors that +# may be caused if one or more SQLite clients does not follow the expected +# locking protocol when accessing a wal-mode database. These tests take +# quite a while to run. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/lock_common.tcl +source $testdir/wal_common.tcl +ifcapable !wal {finish_test ; return } + +set testprefix walprotocol + +#------------------------------------------------------------------------- +# When recovering the contents of a WAL file, a process obtains the WRITER +# lock, then locks all other bytes before commencing recovery. If it fails +# to lock all other bytes (because some other process is holding a read +# lock) it should retry up to 100 times. Then return SQLITE_PROTOCOL to the +# caller. Test this (test case 1.3). +# +# Also test the effect of hitting an SQLITE_BUSY while attempting to obtain +# the WRITER lock (should be the same). Test case 1.4. +# +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE x(y); + INSERT INTO x VALUES('z'); +} {wal} + +proc lock_callback {method filename handle lock} { + lappend ::locks $lock +} +do_test 1.1 { + testvfs T + T filter xShmLock + T script lock_callback + set ::locks [list] + sqlite3 db test.db -vfs T + execsql { SELECT * FROM x } + lrange $::locks 0 3 +} [list {0 1 lock exclusive} {1 7 lock exclusive} \ + {1 7 unlock exclusive} {0 1 unlock exclusive} \ +] +do_test 1.2 { + db close + set ::locks [list] + sqlite3 db test.db -vfs T + execsql { SELECT * FROM x } + lrange $::locks 0 3 +} [list {0 1 lock exclusive} {1 7 lock exclusive} \ + {1 7 unlock exclusive} {0 1 unlock exclusive} \ +] +proc lock_callback {method filename handle lock} { + if {$lock == "1 7 lock exclusive"} { return SQLITE_BUSY } + return SQLITE_OK +} +puts "# Warning: This next test case causes SQLite to call xSlee(1) 100 times." +puts "# Normally this equates to a delay of roughly 10 seconds, but if SQLite" +puts "# is built on unix without HAVE_USLEEP defined, it may be much longer." +do_test 1.3 { + db close + set ::locks [list] + sqlite3 db test.db -vfs T + catchsql { SELECT * FROM x } +} {1 {locking protocol}} + +puts "# Warning: Same again!" +proc lock_callback {method filename handle lock} { + if {$lock == "0 1 lock exclusive"} { return SQLITE_BUSY } + return SQLITE_OK +} +do_test 1.4 { + db close + set ::locks [list] + sqlite3 db test.db -vfs T + catchsql { SELECT * FROM x } +} {1 {locking protocol}} +db close +T delete + +#------------------------------------------------------------------------- +# +do_test 2.1 { + forcedelete test.db test.db-journal test.db wal + sqlite3 db test.db + sqlite3 db2 test.db + execsql { + PRAGMA auto_vacuum = off; + PRAGMA journal_mode = WAL; + CREATE TABLE b(c); + INSERT INTO b VALUES('Tehran'); + INSERT INTO b VALUES('Qom'); + INSERT INTO b VALUES('Markazi'); + PRAGMA wal_checkpoint; + } +} {wal 0 5 5} +do_test 2.2 { + execsql { SELECT * FROM b } +} {Tehran Qom Markazi} +do_test 2.3 { + db eval { SELECT * FROM b } { + db eval { INSERT INTO b VALUES('Qazvin') } + set r [db2 eval { SELECT * FROM b }] + break + } + set r +} {Tehran Qom Markazi Qazvin} +do_test 2.4 { + execsql { + INSERT INTO b VALUES('Gilan'); + INSERT INTO b VALUES('Ardabil'); + } +} {} +db2 close + +faultsim_save_and_close +testvfs T -default 1 +faultsim_restore_and_reopen +T filter xShmLock +T script lock_callback + +proc lock_callback {method file handle spec} { + if {$spec == "1 7 unlock exclusive"} { + T filter {} + set ::r [catchsql { SELECT * FROM b } db2] + } +} +sqlite3 db test.db +sqlite3 db2 test.db +do_test 2.5 { + execsql { SELECT * FROM b } +} {Tehran Qom Markazi Qazvin Gilan Ardabil} +do_test 2.6 { + set ::r +} {1 {locking protocol}} + +db close +db2 close + +faultsim_restore_and_reopen +sqlite3 db2 test.db +T filter xShmLock +T script lock_callback +proc lock_callback {method file handle spec} { + if {$spec == "1 7 unlock exclusive"} { + T filter {} + set ::r [catchsql { SELECT * FROM b } db2] + } +} +unset ::r +do_test 2.7 { + execsql { SELECT * FROM b } +} {Tehran Qom Markazi Qazvin Gilan Ardabil} +do_test 2.8 { + set ::r +} {1 {locking protocol}} + +db close +db2 close +T delete + +finish_test diff --git a/test/walslow.test b/test/walslow.test index 83f292281a..2a52a225d8 100644 --- a/test/walslow.test +++ b/test/walslow.test @@ -16,9 +16,13 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +source $testdir/wal_common.tcl +source $testdir/lock_common.tcl ifcapable !wal {finish_test ; return } +set testprefix walslow + proc reopen_db {} { catch { db close } forcedelete test.db test.db-wal @@ -69,5 +73,159 @@ for {set seed 1} {$seed<10} {incr seed} { } } +#------------------------------------------------------------------------- +# Test case walslow-3.* tests that the checksum calculation detects single +# byte changes to frame or frame-header data and considers the frame +# invalid as a result. +# +reset_db +do_test 3.1 { + + execsql { + PRAGMA synchronous = NORMAL; + PRAGMA page_size = 1024; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, randomblob(300)); + INSERT INTO t1 VALUES(2, randomblob(300)); + PRAGMA journal_mode = WAL; + INSERT INTO t1 VALUES(3, randomblob(300)); + } + + file size test.db-wal +} [wal_file_size 1 1024] +do_test 3.2 { + forcecopy test.db-wal test2.db-wal + forcecopy test.db test2.db + sqlite3 db2 test2.db + execsql { SELECT a FROM t1 } db2 +} {1 2 3} +db2 close +forcecopy test.db test2.db + +foreach incr {1 2 3 20 40 60 80 100 120 140 160 180 200 220 240 253 254 255} { + do_test 3.3.$incr { + set FAIL 0 + for {set iOff 0} {$iOff < [wal_file_size 1 1024]} {incr iOff} { + + forcecopy test.db-wal test2.db-wal + set fd [open test2.db-wal r+] + fconfigure $fd -encoding binary + fconfigure $fd -translation binary + + seek $fd $iOff + binary scan [read $fd 1] c x + seek $fd $iOff + puts -nonewline $fd [binary format c [expr {($x+$incr)&0xFF}]] + close $fd + + sqlite3 db2 test2.db + if { [execsql { SELECT a FROM t1 } db2] != "1 2" } {set FAIL 1} + db2 close + } + set FAIL + } {0} +} + + +#------------------------------------------------------------------------- +# Test large log summaries. +# +# In this case "large" usually means a log file that requires a wal-index +# mapping larger than 64KB (the default initial allocation). A 64KB wal-index +# is large enough for a log file that contains approximately 13100 frames. +# So the following tests create logs containing at least this many frames. +# +# 4.1.*: This test case creates a very large log file within the +# file-system (around 200MB). The log file does not contain +# any valid frames. Test that the database file can still be +# opened and queried, and that the invalid log file causes no +# problems. +# +# 4.2.*: Test that a process may create a large log file and query +# the database (including the log file that it itself created). +# +# 4.3.*: Test that if a very large log file is created, and then a +# second connection is opened on the database file, it is possible +# to query the database (and the very large log) using the +# second connection. +# +# 4.4.*: Same test as wal-13.3.*. Except in this case the second +# connection is opened by an external process. +# +set ::blobcnt 0 +proc blob {nByte} { + incr ::blobcnt + return [string range [string repeat "${::blobcnt}x" $nByte] 1 $nByte] +} + +reset_db +do_execsql_test 4.1 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO "t1" VALUES('A',0); + CREATE TABLE t2(x, y); + INSERT INTO "t2" VALUES('B',2); +} {wal} +db close + +do_test 4.1.1 { + list [file exists test.db] [file exists test.db-wal] +} {1 0} +do_test 4.1.2 { + set fd [open test.db-wal w] + seek $fd [expr 200*1024*1024] + puts $fd "" + close $fd + sqlite3 db test.db + execsql { SELECT * FROM t2 } +} {B 2} +do_test 4.1.3 { + db close + file exists test.db-wal +} {0} + +do_test 4.2.1 { + sqlite3 db test.db + execsql { SELECT count(*) FROM t2 } +} {1} +do_test 4.2.2 { + db function blob blob + for {set i 0} {$i < 16} {incr i} { + execsql { INSERT INTO t2 SELECT blob(400), blob(400) FROM t2 } + } + execsql { SELECT count(*) FROM t2 } +} [expr int(pow(2, 16))] +do_test 4.2.3 { + expr [file size test.db-wal] > [wal_file_size 33000 1024] +} 1 + +do_multiclient_test tn { + incr tn 2 + + do_test 4.$tn.0 { + sql1 { + PRAGMA journal_mode = WAL; + CREATE TABLE t1(x); + INSERT INTO t1 SELECT randomblob(800); + } + sql1 { SELECT count(*) FROM t1 } + } {1} + + for {set ii 1} {$ii<16} {incr ii} { + do_test 4.$tn.$ii.a { + sql2 { INSERT INTO t1 SELECT randomblob(800) FROM t1 } + sql2 { SELECT count(*) FROM t1 } + } [expr (1<<$ii)] + do_test 4.$tn.$ii.b { + sql1 { SELECT count(*) FROM t1 } + } [expr (1<<$ii)] + do_test 4.$tn.$ii.c { + sql1 { SELECT count(*) FROM t1 } + } [expr (1<<$ii)] + do_test 4.$tn.$ii.d { + sql1 { PRAGMA integrity_check } + } {ok} + } +} finish_test diff --git a/test/where8m.test b/test/wherefault.test similarity index 84% rename from test/where8m.test rename to test/wherefault.test index 4fce3db7c3..60330a92dd 100644 --- a/test/where8m.test +++ b/test/wherefault.test @@ -9,17 +9,19 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The focus -# is testing of where.c. More specifically, the focus is the optimization -# of WHERE clauses that feature the OR operator. +# is testing of where.c. More specifically, the focus is on handling OOM +# errors within the code that optimizes WHERE clauses that feature the +# OR operator. # -# $Id: where8m.test,v 1.3 2009/06/05 17:09:12 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl -do_malloc_test where8m-1 -sqlprep { +set testprefix wherefault + +do_malloc_test 1 -sqlprep { CREATE TABLE t1(a, b, c); CREATE INDEX i1 ON t1(a); CREATE INDEX i2 ON t1(b); @@ -37,7 +39,7 @@ do_malloc_test where8m-1 -sqlprep { a BETWEEN 1 AND 3 AND b < 5 AND b > 2 AND c = 4; } -do_malloc_test where8m-2 -tclprep { +do_malloc_test 2 -tclprep { db eval { BEGIN; CREATE TABLE t1(a, b, c); From 4786cf5a20ded9637e487a9dd93ea104c8fb46ef Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 4 Feb 2016 19:45:19 +0000 Subject: [PATCH 081/107] Further improve performance of unindexed fts5 prefix queries. FossilOrigin-Name: c9c6457d8ea911f6cc63967127e58da3146fd3ef --- ext/fts5/fts5_index.c | 138 ++++++++++++++++++++++++------------------ manifest | 16 ++--- manifest.uuid | 2 +- 3 files changed, 87 insertions(+), 69 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 1a8cc63dad..0461f3a778 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4705,76 +4705,94 @@ static void fts5MergePrefixLists( Fts5Buffer *p2 /* Second list to merge */ ){ if( p2->n ){ - i64 iLastRowid = 0; - Fts5DoclistIter i1; - Fts5DoclistIter i2; - Fts5Buffer out; - Fts5Buffer tmp; - memset(&out, 0, sizeof(out)); - memset(&tmp, 0, sizeof(tmp)); + if( p1->n==0 ){ + fts5BufferSwap(p1, p2); + }else{ + i64 iLastRowid = 0; + Fts5DoclistIter i1; + Fts5DoclistIter i2; + Fts5Buffer out = {0, 0, 0}; + Fts5Buffer tmp = {0, 0, 0}; - 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) ){ - if( i2.aPoslist==0 || (i1.aPoslist && i1.iRowidrc, &out, p1->n + p2->n) ) return; + fts5DoclistIterInit(p1, &i1); + fts5DoclistIterInit(p2, &i2); - Fts5PoslistWriter writer; - memset(&writer, 0, sizeof(writer)); + while( 1 ){ - /* Merge the two position lists. */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferZero(&tmp); + if( i1.iRowidrc==SQLITE_OK && (iPos1>=0 || iPos2>=0) ){ - i64 iNew; - if( iPos2<0 || (iPos1>=0 && iPos1=0 || iPos2>=0 ){ + i64 iNew; + if( iPos2<0 || (iPos1>=0 && iPos1rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew); + if( p->rc ) goto error_out; } } - if( iNew!=writer.iPrev || tmp.n==0 ){ - p->rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew); - } + + /* WRITEPOSLISTSIZE */ + fts5BufferSafeAppendVarint(&out, tmp.n * 2); + fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); + fts5DoclistIterNext(&i1); + fts5DoclistIterNext(&i2); + if( i1.aPoslist==0 || i2.aPoslist==0 ) break; } - - /* WRITEPOSLISTSIZE */ - fts5BufferSafeAppendVarint(&out, tmp.n * 2); - fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); - fts5DoclistIterNext(&i1); - fts5DoclistIterNext(&i2); } - } - fts5BufferSet(&p->rc, p1, out.n, out.p); - fts5BufferFree(&tmp); - fts5BufferFree(&out); + if( i1.aPoslist ){ + fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); + fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); + } + else if( i2.aPoslist ){ + fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); + fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); + } + + error_out: + fts5BufferSet(&p->rc, p1, out.n, out.p); + fts5BufferFree(&tmp); + fts5BufferFree(&out); + } } } diff --git a/manifest b/manifest index 7b935898ba..b4349c77ff 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\srunning\ssome\sparticularly\stime-consuming\stests\sas\spart\sof\sveryquick.test. -D 2016-02-04T17:31:03.368 +C Further\simprove\sperformance\sof\sunindexed\sfts5\sprefix\squeries. +D 2016-02-04T19:45:19.673 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -104,7 +104,7 @@ F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c e634a4a05b066f7122db93558c871148bd9893f2 +F ext/fts5/fts5_index.c 614c54544f844387ba6728c613a884a1aa151f06 F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -980,7 +980,7 @@ F test/savepoint4.test c8f8159ade6d2acd9128be61e1230f1c1edc6cc0 F test/savepoint5.test 0735db177e0ebbaedc39812c8d065075d563c4fd F test/savepoint6.test f41279c5e137139fa5c21485773332c7adb98cd7 F test/savepoint7.test db3db281486c925095f305aad09fe806e5188ff3 -F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 w test/savepoint3.test +F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test 5253c219e331318a437f436268e0e82345700285 F test/schema.test 8f7999be894260f151adf15c2c7540f1c6d6a481 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 @@ -1345,7 +1345,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b -F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 w test/where8m.test +F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c @@ -1426,7 +1426,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 b787165b25a240fd5b4a5c7f73b395f30213a1d7 -R 2d9511ba502b30b0a28170783af34756 +P f465944b75a800ddc6920229ad32c2f39ff91e19 +R 50521888ffcbf123db65487e5572aad3 U dan -Z 9311e6c3b97d9e579dd5eb1512f82842 +Z 7367047abd1bd45b9cf9859d0571d183 diff --git a/manifest.uuid b/manifest.uuid index 81e89adc73..960087b4e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f465944b75a800ddc6920229ad32c2f39ff91e19 \ No newline at end of file +c9c6457d8ea911f6cc63967127e58da3146fd3ef \ No newline at end of file From e514f651d0fb5364e6495b9d6c4dd80ca51a227f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 4 Feb 2016 19:50:33 +0000 Subject: [PATCH 082/107] Temporarily back out the 0.5% performance improvement from check-in [632071bac5ff32]. Need a more elaborate solution that works with reentrant virtual tables and SQL functions. FossilOrigin-Name: 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index b4349c77ff..7d7eb20c87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprove\sperformance\sof\sunindexed\sfts5\sprefix\squeries. -D 2016-02-04T19:45:19.673 +C Temporarily\sback\sout\sthe\s0.5%\sperformance\simprovement\sfrom\ncheck-in\s[632071bac5ff32].\s\sNeed\sa\smore\selaborate\ssolution\sthat\sworks\nwith\sreentrant\svirtual\stables\sand\sSQL\sfunctions. +D 2016-02-04T19:50:33.284 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -413,7 +413,7 @@ F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c f0c2e2fb8cbff761ea8602058406c151b9325e8d +F src/vdbe.c 16ca0c1e2975fac04c3ea5c62b34dc24b13fea13 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 @@ -1426,7 +1426,8 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 48bd54594752d5be3337f12c72f28d2080cb630b F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f465944b75a800ddc6920229ad32c2f39ff91e19 -R 50521888ffcbf123db65487e5572aad3 -U dan -Z 7367047abd1bd45b9cf9859d0571d183 +P c9c6457d8ea911f6cc63967127e58da3146fd3ef +Q -632071bac5ff324a74cec9bdbba2deb60c0945e9 +R c2fbdbab2e50abda4a6e36464c2e90a7 +U drh +Z d787da74a7d8bd75c2afcf5547eaa172 diff --git a/manifest.uuid b/manifest.uuid index 960087b4e6..902f64f567 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9c6457d8ea911f6cc63967127e58da3146fd3ef \ No newline at end of file +42736fb0adc82a0fb692850ff3dd3f9b501cbf1f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index fd90d3b0de..62ad86d4f3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -629,6 +629,7 @@ int sqlite3VdbeExec( #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); + if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif @@ -753,16 +754,14 @@ jump_to_p2_and_check_for_interrupt: /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon ** completion. Check to see if sqlite3_interrupt() has been called - ** or if the progress callback needs to be invoked. Also check for - ** OOM conditions and abort if seen. + ** or if the progress callback needs to be invoked. ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this ** way for performance, to avoid having to run the interrupt and progress - ** checks on every opcode. This helps sqlite3_step() to run over 2.0% + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: - if( db->mallocFailed ) goto no_mem; if( db->u1.isInterrupted ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number From 4a642b60607e55a2c25f663b472af3609c76b214 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 01:55:27 +0000 Subject: [PATCH 083/107] Improvements to the way that OOM errors are processed. FossilOrigin-Name: c3ef03478a5788c855b3aef385d43ae7f494f440 --- ext/misc/json1.c | 6 ++--- manifest | 70 +++++++++++++++++++++++++----------------------- manifest.uuid | 2 +- src/alter.c | 2 +- src/analyze.c | 13 +++++---- src/attach.c | 4 +-- src/build.c | 21 +++++++-------- src/callback.c | 4 +-- src/expr.c | 5 +++- src/fkey.c | 6 ++--- src/func.c | 2 +- src/insert.c | 4 +-- src/legacy.c | 2 +- src/main.c | 8 +++--- src/malloc.c | 51 ++++++++++++++++++++++++++++------- src/parse.y | 13 +++++++-- src/pragma.c | 2 +- src/prepare.c | 18 +++++++------ src/printf.c | 2 +- src/select.c | 9 ++++--- src/sqliteInt.h | 6 ++++- src/tokenize.c | 7 +---- src/trigger.c | 2 +- src/vdbe.c | 7 +++-- src/vdbeapi.c | 4 +-- src/vdbeaux.c | 8 +++--- src/vdbemem.c | 2 +- src/vtab.c | 8 +++--- src/where.c | 2 +- src/whereexpr.c | 1 - 30 files changed, 166 insertions(+), 125 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index e4ea4fb9f0..3c63b6e946 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -343,7 +343,7 @@ static void jsonAppendValue( default: { if( p->bErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 1; + p->bErr = 2; jsonReset(p); } break; @@ -1571,7 +1571,7 @@ static void jsonArrayFinal(sqlite3_context *ctx){ pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); if( pStr->bErr ){ - sqlite3_result_error_nomem(ctx); + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, @@ -1619,7 +1619,7 @@ static void jsonObjectFinal(sqlite3_context *ctx){ if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ - sqlite3_result_error_nomem(ctx); + if( pStr->bErr==0 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else{ sqlite3_result_text(ctx, pStr->zBuf, pStr->nUsed, diff --git a/manifest b/manifest index 7d7eb20c87..d515b0a7f1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Temporarily\sback\sout\sthe\s0.5%\sperformance\simprovement\sfrom\ncheck-in\s[632071bac5ff32].\s\sNeed\sa\smore\selaborate\ssolution\sthat\sworks\nwith\sreentrant\svirtual\stables\sand\sSQL\sfunctions. -D 2016-02-04T19:50:33.284 +C Improvements\sto\sthe\sway\sthat\sOOM\serrors\sare\sprocessed. +D 2016-02-05T01:55:27.277 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -206,7 +206,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 4c84635c71c26cfa7c2e5848cf49fe2d2cfcd767 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 8698ea0ce24bda23bd8ad4a124620d758f92760b +F ext/misc/json1.c a27cf1eca6583f9b6e18abab5c2a9a82c4540ca9 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c bcbee3c061b884eccb80e21651daaae8e1e43c63 F ext/misc/regexp.c af92cdaa5058fcec1451e49becc7ba44dba023dc @@ -284,9 +284,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c b6e0befc17d69b59c66f4b8a126c05b1ee7ef10a -F src/analyze.c 0043d3e501f04297fed2bb50b488bc08d5c39f36 -F src/attach.c 27743a694df17ca468eee3956126a5d28d2a29ea +F src/alter.c e4a5132e6264e002ab87c268108f416df3f1fb10 +F src/analyze.c 5338dbbc9f12087b38d74234de00907bdf023a92 +F src/attach.c b943546856ac657c702e1a92fb7adcf67c1dc397 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -294,27 +294,27 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 88ee370118ff7f081f2060ad3fb6c170f9aed7d3 -F src/callback.c 29ae4faba226c7ebb9aee93016b5ce8a8f071261 +F src/build.c dcb55142c4c4293cbec181ef1ae1485ce0bc94d6 +F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c F src/delete.c 33ed87dc0746b1f8ce186f62b608bf40801af9c0 -F src/expr.c d10c1cdef5810cdbf73adc9f9b383684230b360a +F src/expr.c fddb1b19d77730d423ef2c219ae17e10087554ba F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c c66d3e5b35d4d95b5c1e2ee6c12f5df13a7f9ad6 -F src/func.c 42b24923328f65849f52f1659efb2a0907ad78fd +F src/fkey.c dc893ee37a21868fcf07e3d941c7663957807ad2 +F src/func.c 86e55fee35b9577e485f47d9dd5c1d34cd513288 F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 3e2462294fc8bc6e46f377ec824ff315e79fc36d +F src/insert.c e3e2811c69318ff62d8a764b01f5a5677d846b1e F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d -F src/legacy.c ba1863ea58c4c840335a84ec276fc2b25e22bc4e +F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b -F src/main.c b686dabe9a7ece9121da87120d5c7bf402d77eb3 -F src/malloc.c b67c26c359c13836d370350b3f43d228dff5b360 +F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 +F src/malloc.c 65168ef91884206bf3fa14a3070e79255561324b F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -337,23 +337,23 @@ F src/os_win.c ccf29ddded3e41e506b6bd98c1171aa0963b23f2 F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca F src/pager.c 67cd2fbab58d0e35fed5f81432856f4f0af9fc6d F src/pager.h f3eb324a3ff2408b28bab7e81c1c55c13720f865 -F src/parse.y 426a91fbbbf7cdde3fd4b8798de7317a8782bec5 +F src/parse.y d7bff41d460f2df96fb890f36700e85cb0fc5634 F src/pcache.c 73895411fa6b7bd6f0091212feabbe833b358d23 F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 -F src/pragma.c 3c4f3fadf05893e289f2adf3a20c671a842cadec +F src/pragma.c 80ee77226d0008d9188356a6cbbe6010866e1bee F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c db85f0451ba93ecb3c1e497c279abece5cb5aead -F src/printf.c 98a5cef7fc84577ab8a3098cfa48ecfa5a70b9f8 +F src/prepare.c db4ce553dd1f03909a01858a760fa293e0f32ca0 +F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c ea6f3b0c279aa37eb3701792d094673a7ad1bf88 +F src/select.c 07178f2ae1239404874492ba7e3b9a46361ebbbc F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h bf8c17fb55d7cd09b477111212b19d661b134989 +F src/sqliteInt.h e251b755c71c343434bce1e82c6593603c7af364 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -406,31 +406,31 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 -F src/tokenize.c 5606871a377f390af7040ec3c12e0d183512d785 +F src/tokenize.c 214b783d6138e9f9fbb6b225ce9a376db3b03d42 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b -F src/trigger.c 72d876b2d0c66604a112362bdae07dae9b104816 +F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 16ca0c1e2975fac04c3ea5c62b34dc24b13fea13 +F src/vdbe.c 2e49c5d1b8f2f24f91ddd6c6b003d8e7fbbc4e56 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 -F src/vdbeapi.c 9d640d5efd9a140a6bda8da53b220aa258167993 -F src/vdbeaux.c 23b38b447ebf5991de1d3d456003c58cf523a5da +F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459 +F src/vdbeaux.c 0e66330ac8ad473bdefde88278725202d0174ae5 F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db -F src/vdbemem.c b9181e77eca2a095929d46250daf85c8d2621fc0 +F src/vdbemem.c 9a6736339ca581f3b9503d5a1a40b7d718ca4635 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 320682cca733115b4cbe71320b5c5eeb1074ebde +F src/vtab.c 2cc0b7bb253851c8718b8850dfaed8592b6dc7f8 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c af9bf5dcec1a0e52726c550924aa91d837166251 +F src/where.c 8bdb43e09d4e7f20bb371154799da39c25b51dfd F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a F src/wherecode.c 791a784bbf8749d560fdb0b990b607bc4f44a38d -F src/whereexpr.c 197a448b52073aee43eca3a2233fc113369eb2d4 +F src/whereexpr.c 85ee2de9ff0fe40a4afaf2a477bd6c9a808548b3 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1426,8 +1426,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 c9c6457d8ea911f6cc63967127e58da3146fd3ef -Q -632071bac5ff324a74cec9bdbba2deb60c0945e9 -R c2fbdbab2e50abda4a6e36464c2e90a7 +P 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f +R 1d34f5ef33e19e0d2d7f06ad149ac201 +T *branch * oom-handling +T *sym-oom-handling * +T -sym-trunk * U drh -Z d787da74a7d8bd75c2afcf5547eaa172 +Z a95dbad943095aee523b449d4529a303 diff --git a/manifest.uuid b/manifest.uuid index 902f64f567..a42eab21cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42736fb0adc82a0fb692850ff3dd3f9b501cbf1f \ No newline at end of file +c3ef03478a5788c855b3aef385d43ae7f494f440 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 16b7a9e192..3419059fa2 100644 --- a/src/alter.c +++ b/src/alter.c @@ -695,7 +695,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ - db->mallocFailed = 1; + assert( db->mallocFailed = 1 ); return; } if( !pVal ){ diff --git a/src/analyze.c b/src/analyze.c index 4d777fa9f5..7a7d68f59a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1523,7 +1523,7 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); - if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; + if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); } aiRowEst = pIndex->aiRowEst; #endif @@ -1670,7 +1670,7 @@ static int loadStatTbl( Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); zSql = sqlite3MPrintf(db, zSql1, zDb); if( !zSql ){ return SQLITE_NOMEM; @@ -1784,7 +1784,7 @@ static int loadStatTbl( static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, 0, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", @@ -1866,10 +1866,9 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load the statistics from the sqlite_stat4 table. */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ - int lookasideEnabled = db->lookaside.bEnabled; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; rc = loadStat4(db, sInfo.zDatabase); - db->lookaside.bEnabled = lookasideEnabled; + db->lookaside.bDisable--; } for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); @@ -1879,7 +1878,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ #endif if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return rc; } diff --git a/src/attach.c b/src/attach.c index 12d3ac3ff6..e167951f68 100644 --- a/src/attach.c +++ b/src/attach.c @@ -127,7 +127,7 @@ static void attachFunc( flags = db->openFlags; rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); return; @@ -230,7 +230,7 @@ static void attachFunc( sqlite3ResetAllSchemasOfConnection(db); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, zErrDyn); zErrDyn = sqlite3MPrintf(db, "out of memory"); }else if( zErrDyn==0 ){ diff --git a/src/build.c b/src/build.c index cea05d51c7..097149fd4f 100644 --- a/src/build.c +++ b/src/build.c @@ -78,7 +78,7 @@ void sqlite3TableLock( p->zName = zName; }else{ pToplevel->nTableLock = 0; - pToplevel->db->mallocFailed = 1; + sqlite3OomFault(pToplevel->db); } } @@ -1555,7 +1555,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ n += 35 + 6*p->nCol; zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 0; } sqlite3_snprintf(n, zStmt, "CREATE TABLE "); @@ -2038,7 +2038,7 @@ void sqlite3EndTable( pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ - db->mallocFailed = 1; + sqlite3OomFault(db); return; } pParse->pNewTable = 0; @@ -2142,7 +2142,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ sqlite3_xauth xAuth; /* Saved xAuth pointer */ - u8 bEnabledLA; /* Saved db->lookaside.bEnabled state */ assert( pTable ); @@ -2188,18 +2187,18 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** statement that defines the view. */ assert( pTable->pSelect ); - bEnabledLA = db->lookaside.bEnabled; if( pTable->pCheck ){ - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); + db->lookaside.bDisable--; }else{ pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; @@ -2208,6 +2207,7 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel); #endif + db->lookaside.bDisable--; pParse->nTab = n; if( pSelTab ){ assert( pTable->aCol==0 ); @@ -2226,7 +2226,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ nErr++; } } - db->lookaside.bEnabled = bEnabledLA; pTable->pSchema->schemaFlags |= DB_UnresetViews; #endif /* SQLITE_OMIT_VIEW */ return nErr; @@ -2692,7 +2691,7 @@ void sqlite3CreateForeignKey( pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ - db->mallocFailed = 1; + sqlite3OomFault(db); goto fk_end; } if( pNextTo ){ @@ -3274,7 +3273,7 @@ Index *sqlite3CreateIndex( pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ - db->mallocFailed = 1; + sqlite3OomFault(db); goto exit_create_index; } db->flags |= SQLITE_InternChanges; @@ -3992,7 +3991,7 @@ int sqlite3OpenTempDatabase(Parse *pParse){ db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 1; } } diff --git a/src/callback.c b/src/callback.c index 2a9f5b802a..2b955fdcdb 100644 --- a/src/callback.c +++ b/src/callback.c @@ -177,7 +177,7 @@ static CollSeq *findCollSeqEntry( */ assert( pDel==0 || pDel==pColl ); if( pDel!=0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, pDel); pColl = 0; } @@ -465,7 +465,7 @@ Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if ( 0==p->file_format ){ sqlite3HashInit(&p->tblHash); sqlite3HashInit(&p->idxHash); diff --git a/src/expr.c b/src/expr.c index c91db2834f..5b134d6661 100644 --- a/src/expr.c +++ b/src/expr.c @@ -699,7 +699,10 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){ if( x>pParse->nzVar ){ char **a; a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); - if( a==0 ) return; /* Error reported through db->mallocFailed */ + if( a==0 ){ + assert( db->mallocFailed ); /* Error reported through mallocFailed */ + return; + } pParse->azVar = a; memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); pParse->nzVar = x; diff --git a/src/fkey.c b/src/fkey.c index 7eb188924d..fae25c4828 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -1165,7 +1165,6 @@ static Trigger *fkActionTrigger( pTrigger = pFKey->apTrigger[iAction]; if( action!=OE_None && !pTrigger ){ - u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ char const *zFrom; /* Name of child table */ int nFrom; /* Length in bytes of zFrom */ Index *pIdx = 0; /* Parent key index for this FK */ @@ -1274,8 +1273,7 @@ static Trigger *fkActionTrigger( } /* Disable lookaside memory allocation */ - enableLookaside = db->lookaside.bEnabled; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable++; pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ @@ -1297,7 +1295,7 @@ static Trigger *fkActionTrigger( } /* Re-enable the lookaside buffer, if it was disabled earlier. */ - db->lookaside.bEnabled = enableLookaside; + db->lookaside.bDisable--; sqlite3ExprDelete(db, pWhere); sqlite3ExprDelete(db, pWhen); diff --git a/src/func.c b/src/func.c index 982a8c2caa..d615cf90b1 100644 --- a/src/func.c +++ b/src/func.c @@ -1615,7 +1615,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ int rc = sqlite3_overload_function(db, "MATCH", 2); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } diff --git a/src/insert.c b/src/insert.c index 5f36c089f6..a8cde72954 100644 --- a/src/insert.c +++ b/src/insert.c @@ -83,7 +83,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ Table *pTab = pIdx->pTable; pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return 0; } for(n=0; nnColumn; n++){ @@ -134,7 +134,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return; } diff --git a/src/legacy.c b/src/legacy.c index a10006e558..1b5e518d43 100644 --- a/src/legacy.c +++ b/src/legacy.c @@ -90,7 +90,7 @@ int sqlite3_exec( for(i=0; imallocFailed = 1; + sqlite3OomFault(db); goto exec_out; } } diff --git a/src/main.c b/src/main.c index 63a105c3f0..588461b48a 100644 --- a/src/main.c +++ b/src/main.c @@ -698,12 +698,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ p = (LookasideSlot*)&((u8*)p)[sz]; } db->lookaside.pEnd = p; - db->lookaside.bEnabled = 1; + db->lookaside.bDisable = 0; db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; - db->lookaside.bEnabled = 0; + db->lookaside.bDisable = 1; db->lookaside.bMalloced = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ @@ -2208,7 +2208,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ ** be cleared before returning. Do this directly, instead of via ** sqlite3ApiExit(), to avoid setting the database handle error message. */ - db->mallocFailed = 0; + sqlite3OomClear(db); } sqlite3_mutex_leave(db->mutex); return z; @@ -2846,7 +2846,7 @@ static int openDatabase( db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; diff --git a/src/malloc.c b/src/malloc.c index c8a04128cf..057d36a4be 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -608,10 +608,8 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE if( db ){ LookasideSlot *pBuf; - if( db->mallocFailed ){ - return 0; - } - if( db->lookaside.bEnabled ){ + if( db->lookaside.bDisable==0 ){ + assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ db->lookaside.anStat[1]++; }else if( (pBuf = db->lookaside.pFree)==0 ){ @@ -625,7 +623,10 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ } return (void*)pBuf; } + }else if( db->mallocFailed ){ + return 0; } + } #else if( db && db->mallocFailed ){ @@ -637,10 +638,10 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ void *p = sqlite3Malloc(n); if( !p && db ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } sqlite3MemdebugSetType(p, - (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); + (db && db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); return p; } @@ -671,10 +672,10 @@ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ sqlite3MemdebugSetType(p, MEMTYPE_HEAP); pNew = sqlite3_realloc64(p, n); if( !pNew ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } sqlite3MemdebugSetType(pNew, - (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); + (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); } } return pNew; @@ -736,11 +737,43 @@ void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ *pz = sqlite3DbStrDup(db, zNew); } +/* +** Call this routine to record the fact that an OOM (out-of-memory) error +** has happened. This routine will set db->mallocFailed, and also +** temporarily disable the lookaside memory allocator and interrupt +** any running VDBEs. +*/ +void sqlite3OomFault(sqlite3 *db){ + if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ + db->mallocFailed = 1; + if( db->nVdbeExec>0 ){ + db->u1.isInterrupted = 1; + } + db->lookaside.bDisable++; + } +} + +/* +** This routine reactivates the memory allocator and clears the +** db->mallocFailed flag as necessary. +** +** The memory allocator is not restarted if there are running +** VDBEs. +*/ +void sqlite3OomClear(sqlite3 *db){ + if( db->mallocFailed && db->nVdbeExec==0 ){ + db->mallocFailed = 0; + db->u1.isInterrupted = 0; + assert( db->lookaside.bDisable>0 ); + db->lookaside.bDisable--; + } +} + /* ** Take actions at the end of an API call to indicate an OOM error */ static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ - db->mallocFailed = 0; + sqlite3OomClear(db); sqlite3Error(db, SQLITE_NOMEM); return SQLITE_NOMEM; } diff --git a/src/parse.y b/src/parse.y index 846c2504b7..0bfe4e473a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -106,6 +106,15 @@ struct TrigEvent { int a; IdList * b; }; */ struct AttachKey { int type; Token key; }; +/* +** Disable lookaside memory allocation for objects that might be +** shared across database connections. +*/ +static void disableLookaside(Parse *pParse){ + pParse->disableLookaside++; + pParse->db->lookaside.bDisable++; +} + } // end %include // Input is a single SQL command @@ -156,7 +165,7 @@ create_table ::= createkw temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). { sqlite3StartTable(pParse,&Y,&Z,T,0,0,E); } createkw(A) ::= CREATE(X). { - pParse->db->lookaside.bEnabled = 0; + disableLookaside(pParse); A = X; } %type ifnotexists {int} @@ -1507,7 +1516,7 @@ cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column(Y). { sqlite3AlterFinishAddColumn(pParse, &Y); } add_column_fullname ::= fullname(X). { - pParse->db->lookaside.bEnabled = 0; + disableLookaside(pParse); sqlite3AlterBeginAddColumn(pParse, X); } kwcolumn_opt ::= . diff --git a/src/pragma.c b/src/pragma.c index bde17d1e86..c34d5421c2 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -478,7 +478,7 @@ void sqlite3Pragma( */ db->nextPagesize = sqlite3Atoi(zRight); if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } break; diff --git a/src/prepare.c b/src/prepare.c index f8ad54665a..3fb71a770e 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -32,7 +32,7 @@ static void corruptSchema( if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra); sqlite3DbFree(db, *pData->pzErrMsg); *pData->pzErrMsg = z; - if( z==0 ) db->mallocFailed = 1; + if( z==0 ) sqlite3OomFault(db); } pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } @@ -91,7 +91,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ }else{ pData->rc = rc; if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ corruptSchema(pData, argv[0], sqlite3_errmsg(db)); } @@ -336,7 +336,7 @@ initone_error_out: error_out: if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return rc; } @@ -434,7 +434,7 @@ static void schemaIsValid(Parse *pParse){ if( !sqlite3BtreeIsInReadTrans(pBt) ){ rc = sqlite3BtreeBeginTrans(pBt, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } if( rc!=SQLITE_OK ) return; openedTransaction = 1; @@ -497,6 +497,11 @@ void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; sqlite3DbFree(db, pParse->aLabel); sqlite3ExprListDelete(db, pParse->pConstExpr); + if( db ){ + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + } + pParse->disableLookaside = 0; } } @@ -592,9 +597,6 @@ static int sqlite3Prepare( } assert( 0==pParse->nQueryLoop ); - if( db->mallocFailed ){ - pParse->rc = SQLITE_NOMEM; - } if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; if( pParse->checkSchema ){ schemaIsValid(pParse); @@ -716,7 +718,7 @@ int sqlite3Reprepare(Vdbe *p){ rc = sqlite3LockAndPrepare(db, zSql, -1, 0, p, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } assert( pNew==0 ); return rc; diff --git a/src/printf.c b/src/printf.c index 946161f64c..238997f37d 100644 --- a/src/printf.c +++ b/src/printf.c @@ -929,7 +929,7 @@ char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ sqlite3VXPrintf(&acc, zFormat, ap); z = sqlite3StrAccumFinish(&acc); if( acc.accError==STRACCUM_NOMEM ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } return z; } diff --git a/src/select.c b/src/select.c index 891b123543..84d5423de6 100644 --- a/src/select.c +++ b/src/select.c @@ -1016,7 +1016,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->nRef = 1; memset(&p[1], 0, nExtra); }else{ - db->mallocFailed = 1; + sqlite3OomFault(db); } return p; } @@ -1677,7 +1677,7 @@ int sqlite3ColumnsFromExprList( pCol->zName = zName; sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ - db->mallocFailed = 1; + sqlite3OomFault(db); } } sqlite3HashClear(&ht); @@ -1764,7 +1764,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){ } /* The sqlite3ResultSetOfSelect() is only used n contexts where lookaside ** is disabled */ - assert( db->lookaside.bEnabled==0 ); + assert( db->lookaside.bDisable ); pTab->nRef = 1; pTab->zName = 0; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); @@ -5562,7 +5562,8 @@ int sqlite3Select( if( flag ){ pMinMax = sqlite3ExprListDup(db, pMinMax, 0); pDel = pMinMax; - if( pMinMax && !db->mallocFailed ){ + assert( db->mallocFailed || pMinMax!=0 ); + if( !db->mallocFailed ){ pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN ?1:0; pMinMax->a[0].pExpr->op = TK_COLUMN; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 16d3ea9921..70f210c0a2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1094,8 +1094,8 @@ struct Schema { ** lookaside allocations are not used to construct the schema objects. */ struct Lookaside { + u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ - u8 bEnabled; /* False to disable new lookaside allocations */ u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ int nOut; /* Number of buffers currently checked out */ int mxOut; /* Highwater mark for nOut */ @@ -1178,6 +1178,7 @@ struct sqlite3 { u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ u8 mallocFailed; /* True if we have seen a malloc failure */ + u8 bBenignMalloc; /* Do not require OOMs if true */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ @@ -2733,6 +2734,7 @@ struct Parse { u8 mayAbort; /* True if statement may throw an ABORT exception */ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */ u8 okConstFactor; /* OK to factor out constants */ + u8 disableLookaside; /* Number of times lookaside has been disabled */ int aTempReg[8]; /* Holding area for temporary registers */ int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ @@ -3777,6 +3779,8 @@ int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), FuncDestructor *pDestructor ); +void sqlite3OomFault(sqlite3*); +void sqlite3OomClear(sqlite3*); int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); diff --git a/src/tokenize.c b/src/tokenize.c index b85e35dc10..5bee3d5a84 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -390,7 +390,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ void *pEngine; /* The LEMON-generated LALR(1) parser */ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ - u8 enableLookaside; /* Saved value of db->lookaside.bEnabled */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ @@ -406,7 +405,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ /* sqlite3ParserTrace(stdout, "parser: "); */ pEngine = sqlite3ParserAlloc(sqlite3Malloc); if( pEngine==0 ){ - db->mallocFailed = 1; + sqlite3OomFault(db); return SQLITE_NOMEM; } assert( pParse->pNewTable==0 ); @@ -414,8 +413,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ assert( pParse->nVar==0 ); assert( pParse->nzVar==0 ); assert( pParse->azVar==0 ); - enableLookaside = db->lookaside.bEnabled; - if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; @@ -428,7 +425,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ if( tokenType>=TK_SPACE ){ assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL ); if( db->u1.isInterrupted ){ - sqlite3ErrorMsg(pParse, "interrupt"); pParse->rc = SQLITE_INTERRUPT; break; } @@ -463,7 +459,6 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ sqlite3ParserFree(pEngine, sqlite3_free); - db->lookaside.bEnabled = enableLookaside; if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; } diff --git a/src/trigger.c b/src/trigger.c index 4bfb55af69..72c31eb2a3 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -323,7 +323,7 @@ void sqlite3FinishTrigger( assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ - db->mallocFailed = 1; + sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); diff --git a/src/vdbe.c b/src/vdbe.c index 62ad86d4f3..c0eff6a09f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -629,7 +629,6 @@ int sqlite3VdbeExec( #endif for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){ assert( pOp>=aOp && pOp<&aOp[p->nOp]); - if( db->mallocFailed ) goto no_mem; #ifdef VDBE_PROFILE start = sqlite3Hwtime(); #endif @@ -6785,7 +6784,7 @@ vdbe_error_halt: sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); - if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ sqlite3ResetOneSchema(db, resetSchemaOnFault-1); @@ -6815,7 +6814,7 @@ too_big: /* Jump to here if a malloc() fails. */ no_mem: - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3VdbeError(p, "out of memory"); rc = SQLITE_NOMEM; goto vdbe_error_halt; @@ -6836,7 +6835,7 @@ abort_due_to_error: */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); - rc = SQLITE_INTERRUPT; + rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_INTERRUPT; p->rc = rc; sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); goto vdbe_error_halt; diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 0a15633ddf..fce43630e7 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -473,7 +473,7 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM; pCtx->fErrorOrAux = 1; - pCtx->pOut->db->mallocFailed = 1; + sqlite3OomFault(pCtx->pOut->db); } /* @@ -1101,7 +1101,7 @@ static const void *columnName( ** is the case, clear the mallocFailed flag and return NULL. */ if( db->mallocFailed ){ - db->mallocFailed = 0; + sqlite3OomClear(db); ret = 0; } sqlite3_mutex_leave(db->mutex); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 632c1231aa..7d3a8c4293 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1423,7 +1423,6 @@ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; sqlite3 *db = p->db; - u8 malloc_failed = db->mallocFailed; if( db->pnBytesFreed ){ do{ if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); @@ -1459,7 +1458,6 @@ static void releaseMemArray(Mem *p, int N){ p->flags = MEM_Undefined; }while( (++p)mallocFailed = malloc_failed; } } @@ -1520,7 +1518,7 @@ int sqlite3VdbeList( if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ - db->mallocFailed = 1; + sqlite3OomFault(db); return SQLITE_ERROR; } @@ -2711,12 +2709,12 @@ int sqlite3VdbeTransferError(Vdbe *p){ sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ - u8 mallocFailed = db->mallocFailed; + db->bBenignMalloc++; sqlite3BeginBenignMalloc(); if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); sqlite3EndBenignMalloc(); - db->mallocFailed = mallocFailed; + db->bBenignMalloc--; db->errCode = rc; }else{ sqlite3Error(db, rc); diff --git a/src/vdbemem.c b/src/vdbemem.c index 0eeb59ef85..974b990747 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1381,7 +1381,7 @@ static int valueFromExpr( return rc; no_mem: - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 diff --git a/src/vtab.c b/src/vtab.c index ea79cd8cef..ca444944f4 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -62,7 +62,7 @@ static int createModule( pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); assert( pDel==0 || pDel==pMod ); if( pDel ){ - db->mallocFailed = 1; + sqlite3OomFault(db); sqlite3DbFree(db, pDel); } } @@ -439,7 +439,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ - db->mallocFailed = 1; + sqlite3OomFault(db); assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } @@ -530,7 +530,7 @@ static int vtabCallConstructor( db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = sCtx.pPrior; - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ @@ -1088,7 +1088,7 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ - pToplevel->db->mallocFailed = 1; + sqlite3OomFault(pToplevel->db); } } diff --git a/src/where.c b/src/where.c index 8c8dfbb7b6..d3a4ab87e4 100644 --- a/src/where.c +++ b/src/where.c @@ -943,7 +943,7 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ - pParse->db->mallocFailed = 1; + sqlite3OomFault(pParse->db); }else if( !pVtab->zErrMsg ){ sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); }else{ diff --git a/src/whereexpr.c b/src/whereexpr.c index e0b8bac1b7..ec244bcb46 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -563,7 +563,6 @@ static void exprAnalyzeOrTerm( sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); sqlite3WhereExprAnalyze(pSrc, pAndWC); pAndWC->pOuter = pWC; - testcase( db->mallocFailed ); if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); From b84e574c8923b5bcb0b50fbb5a36f4a12b4cde0d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 02:42:54 +0000 Subject: [PATCH 084/107] Further performance improvements that fall out of the mallocFailed changes. FossilOrigin-Name: d94416ddca8f7ed727dd335d38155ea5945a86b7 --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/build.c | 5 ++--- src/malloc.c | 18 +++++++++++------- src/vdbeaux.c | 4 ++-- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index d515b0a7f1..667cb055a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sthat\sOOM\serrors\sare\sprocessed. -D 2016-02-05T01:55:27.277 +C Further\sperformance\simprovements\sthat\sfall\sout\sof\sthe\smallocFailed\schanges. +D 2016-02-05T02:42:54.123 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -294,7 +294,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c dcb55142c4c4293cbec181ef1ae1485ce0bc94d6 +F src/build.c 784c61366e79092b16e116372e66930775d2e6dc F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -314,7 +314,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 -F src/malloc.c 65168ef91884206bf3fa14a3070e79255561324b +F src/malloc.c 92ca6e16c90fb10f97844c08061bd8381423eb89 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -417,7 +417,7 @@ F src/vdbe.c 2e49c5d1b8f2f24f91ddd6c6b003d8e7fbbc4e56 F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459 -F src/vdbeaux.c 0e66330ac8ad473bdefde88278725202d0174ae5 +F src/vdbeaux.c 777461529f862623e9164eb954fc53e54ddd650a F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c 9a6736339ca581f3b9503d5a1a40b7d718ca4635 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -1426,10 +1426,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 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f -R 1d34f5ef33e19e0d2d7f06ad149ac201 -T *branch * oom-handling -T *sym-oom-handling * -T -sym-trunk * +P c3ef03478a5788c855b3aef385d43ae7f494f440 +R 84df2aaa23afa82bffc643c1855a9e65 U drh -Z a95dbad943095aee523b449d4529a303 +Z 8d53cc14407430cf1880951ea3d679f2 diff --git a/manifest.uuid b/manifest.uuid index a42eab21cd..eedb6d9e7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3ef03478a5788c855b3aef385d43ae7f494f440 \ No newline at end of file +d94416ddca8f7ed727dd335d38155ea5945a86b7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 097149fd4f..4185f48e93 100644 --- a/src/build.c +++ b/src/build.c @@ -4366,10 +4366,9 @@ With *sqlite3WithAdd( }else{ pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } - assert( zName!=0 || pNew==0 ); - assert( db->mallocFailed==0 || pNew==0 ); + assert( (pNew!=0 && zName!=0) || db->mallocFailed ); - if( pNew==0 ){ + if( db->mallocFailed ){ sqlite3ExprListDelete(db, pArglist); sqlite3SelectDelete(db, pQuery); sqlite3DbFree(db, zName); diff --git a/src/malloc.c b/src/malloc.c index 057d36a4be..441b4cb67d 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -645,22 +645,26 @@ static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ return p; } +/* Forward declaration */ +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); + /* ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ + assert( db!=0 ); + if( p==0 ) return sqlite3DbMallocRaw(db, n); + assert( sqlite3_mutex_held(db->mutex) ); + if( isLookaside(db,p) && n<=db->lookaside.sz ) return p; + return dbReallocFinish(db, p, n); +} +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ void *pNew = 0; assert( db!=0 ); - assert( sqlite3_mutex_held(db->mutex) ); + assert( p!=0 ); if( db->mallocFailed==0 ){ - if( p==0 ){ - return sqlite3DbMallocRaw(db, n); - } if( isLookaside(db, p) ){ - if( n<=db->lookaside.sz ){ - return p; - } pNew = sqlite3DbMallocRaw(db, n); if( pNew ){ memcpy(pNew, p, db->lookaside.sz); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7d3a8c4293..334f54e414 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2511,7 +2511,7 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->db->mallocFailed ){ + if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; } if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag); @@ -2672,7 +2672,7 @@ int sqlite3VdbeHalt(Vdbe *p){ } p->magic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); - if( p->db->mallocFailed ){ + if( db->mallocFailed ){ p->rc = SQLITE_NOMEM; } From 17a936f84a656f3fba8e108758c822ec8f7b472b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 02:50:11 +0000 Subject: [PATCH 085/107] Minor simplification of schema error reporting. FossilOrigin-Name: a8846aeed9992c6c9f1c8bd6e996a4cbe891751e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 667cb055a4..b94b629c43 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sperformance\simprovements\sthat\sfall\sout\sof\sthe\smallocFailed\schanges. -D 2016-02-05T02:42:54.123 +C Minor\ssimplification\sof\sschema\serror\sreporting. +D 2016-02-05T02:50:11.825 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -343,7 +343,7 @@ F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545 F src/pcache1.c 72f644dc9e1468c72922eff5904048427b817051 F src/pragma.c 80ee77226d0008d9188356a6cbbe6010866e1bee F src/pragma.h 64c78a648751b9f4f297276c4eb7507b14b4628c -F src/prepare.c db4ce553dd1f03909a01858a760fa293e0f32ca0 +F src/prepare.c c12b786713df3e8270c0f85f988c5359d8b4d87c F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c @@ -1426,7 +1426,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 c3ef03478a5788c855b3aef385d43ae7f494f440 -R 84df2aaa23afa82bffc643c1855a9e65 +P d94416ddca8f7ed727dd335d38155ea5945a86b7 +R 93de80b6f41eca5b247f8cd43a03611d U drh -Z 8d53cc14407430cf1880951ea3d679f2 +Z 30d13b253cef6bc68465b8bc6d2bab02 diff --git a/manifest.uuid b/manifest.uuid index eedb6d9e7d..9d5db4dfbb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d94416ddca8f7ed727dd335d38155ea5945a86b7 \ No newline at end of file +a8846aeed9992c6c9f1c8bd6e996a4cbe891751e \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 3fb71a770e..f74aa52e0b 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -28,11 +28,10 @@ static void corruptSchema( if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ char *z; if( zObj==0 ) zObj = "?"; - z = sqlite3_mprintf("malformed database schema (%s)", zObj); - if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra); + z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); + if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); sqlite3DbFree(db, *pData->pzErrMsg); *pData->pzErrMsg = z; - if( z==0 ) sqlite3OomFault(db); } pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT; } From 02de84e56248309aa1c993d1e694f1ee4782c366 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 5 Feb 2016 04:39:11 +0000 Subject: [PATCH 086/107] Another small tweak to the MSVC batch build tool. FossilOrigin-Name: 76718bbce775e13a82893be519ddd98b2f3a4942 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- tool/build-all-msvc.bat | 6 +++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7d7eb20c87..3f7a991ee4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Temporarily\sback\sout\sthe\s0.5%\sperformance\simprovement\sfrom\ncheck-in\s[632071bac5ff32].\s\sNeed\sa\smore\selaborate\ssolution\sthat\sworks\nwith\sreentrant\svirtual\stables\sand\sSQL\sfunctions. -D 2016-02-04T19:50:33.284 +C Another\ssmall\stweak\sto\sthe\sMSVC\sbatch\sbuild\stool. +D 2016-02-05T04:39:11.238 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1367,7 +1367,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633 -F tool/build-all-msvc.bat 77f85f4268c2711d637c629610d0cf3df5338638 x +F tool/build-all-msvc.bat 8686ace11a70a2dcd25d8a32e594517040402f1d x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1426,8 +1426,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 c9c6457d8ea911f6cc63967127e58da3146fd3ef -Q -632071bac5ff324a74cec9bdbba2deb60c0945e9 -R c2fbdbab2e50abda4a6e36464c2e90a7 -U drh -Z d787da74a7d8bd75c2afcf5547eaa172 +P 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f +R 42b9a28037cad0e47b316fe911b23a4e +U mistachkin +Z 608fd16e3704c006125d3c0da336963e diff --git a/manifest.uuid b/manifest.uuid index 902f64f567..166eb03e68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42736fb0adc82a0fb692850ff3dd3f9b501cbf1f \ No newline at end of file +76718bbce775e13a82893be519ddd98b2f3a4942 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 2dd01004d5..059f3a1da2 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -729,11 +729,15 @@ GOTO no_errors GOTO :EOF :fn_UnsetVariable + SETLOCAL SET VALUE=%1 IF DEFINED VALUE ( - SET %VALUE%= SET VALUE= + ENDLOCAL + SET %VALUE%= CALL :fn_ResetErrorLevel + ) ELSE ( + ENDLOCAL ) GOTO :EOF From 98c7a12c003278d9332c25dc9782e491b7bb0845 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 04:50:27 +0000 Subject: [PATCH 087/107] OOM failures on sqlite3_errmsg16() in an app-defined function are no longer benign. FossilOrigin-Name: 9efb223f4ce8ccc00515f8f016f7c494c9ae5096 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_func.c | 2 -- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b94b629c43..be1bead349 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sof\sschema\serror\sreporting. -D 2016-02-05T02:50:11.825 +C OOM\sfailures\son\ssqlite3_errmsg16()\sin\san\sapp-defined\sfunction\sare\sno\slonger\nbenign. +D 2016-02-05T04:50:27.680 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -376,7 +376,7 @@ F src/test_config.c 0dee90328e3dedf8ba002ee94b6a7e7ea7726fe4 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c a61f54247fdb843761d709879c3bcd1989b2050c -F src/test_func.c 0d9c25956152adefee8881c6fadc8354793764d0 +F src/test_func.c 37453d346cfcf118774efd5bf6187f7e6a7e3254 F src/test_hexio.c abfdecb6fa58c354623978efceb088ca18e379cd F src/test_init.c 66b33120ffe9cd853b5a905ec850d51151337b32 F src/test_intarray.c 870124b95ec4c645d4eb84f15efb7133528fb1a5 @@ -1426,7 +1426,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 d94416ddca8f7ed727dd335d38155ea5945a86b7 -R 93de80b6f41eca5b247f8cd43a03611d +P a8846aeed9992c6c9f1c8bd6e996a4cbe891751e +R d0bf71e8097462f80d2341a6f602c53f U drh -Z 30d13b253cef6bc68465b8bc6d2bab02 +Z 1d703e36553aaf91d3187c59187314d2 diff --git a/manifest.uuid b/manifest.uuid index 9d5db4dfbb..72711c9e2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8846aeed9992c6c9f1c8bd6e996a4cbe891751e \ No newline at end of file +9efb223f4ce8ccc00515f8f016f7c494c9ae5096 \ No newline at end of file diff --git a/src/test_func.c b/src/test_func.c index 63cf18e3f7..579177b70c 100644 --- a/src/test_func.c +++ b/src/test_func.c @@ -166,9 +166,7 @@ static void test_agg_errmsg16_final(sqlite3_context *ctx){ const void *z; sqlite3 * db = sqlite3_context_db_handle(ctx); sqlite3_aggregate_context(ctx, 2048); - sqlite3BeginBenignMalloc(); z = sqlite3_errmsg16(db); - sqlite3EndBenignMalloc(); sqlite3_result_text16(ctx, z, -1, SQLITE_TRANSIENT); #endif } From b91d2214fe73133a320a0d63cea279d9316cf639 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 5 Feb 2016 04:55:01 +0000 Subject: [PATCH 088/107] Improve ERRORLEVEL handling in the MSVC batch build tool sub-routine 'fn_UnsetVariable'. FossilOrigin-Name: fe123ab4f17f97ba9d64a7e0589ac47fd9d43877 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/build-all-msvc.bat | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3f7a991ee4..35946a7421 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\ssmall\stweak\sto\sthe\sMSVC\sbatch\sbuild\stool. -D 2016-02-05T04:39:11.238 +C Improve\sERRORLEVEL\shandling\sin\sthe\sMSVC\sbatch\sbuild\stool\ssub-routine\s'fn_UnsetVariable'. +D 2016-02-05T04:55:01.668 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -1367,7 +1367,7 @@ F test/zerodamage.test cf6748bad89553cc1632be51a6f54e487e4039ac F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 629d87562e0487c386db630033931d12d62e6372 F tool/addopcodes.tcl 4ca9c3ef196f08da30add5d07ce0c9458dc8c633 -F tool/build-all-msvc.bat 8686ace11a70a2dcd25d8a32e594517040402f1d x +F tool/build-all-msvc.bat 31866578036cd1d962628059b0760d407c3ce4d8 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl 692ce4b8693d59e3a3de77ca97f4139ecfa641b0 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 @@ -1426,7 +1426,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 42736fb0adc82a0fb692850ff3dd3f9b501cbf1f -R 42b9a28037cad0e47b316fe911b23a4e +P 76718bbce775e13a82893be519ddd98b2f3a4942 +R 86ae75673aa5606b4c7ad2944af4b890 U mistachkin -Z 608fd16e3704c006125d3c0da336963e +Z b9861f56ee1885b232be909ed448816a diff --git a/manifest.uuid b/manifest.uuid index 166eb03e68..b114896ea4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -76718bbce775e13a82893be519ddd98b2f3a4942 \ No newline at end of file +fe123ab4f17f97ba9d64a7e0589ac47fd9d43877 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index 059f3a1da2..84528e37c2 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -735,10 +735,10 @@ GOTO no_errors SET VALUE= ENDLOCAL SET %VALUE%= - CALL :fn_ResetErrorLevel ) ELSE ( ENDLOCAL ) + CALL :fn_ResetErrorLevel GOTO :EOF :fn_AppendVariable From 575fad6500070ad7fc7f91a8906b0b285965f99a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 13:38:36 +0000 Subject: [PATCH 089/107] Add the slightly faster sqlite3DbMallocRawNN(db,n) routine for the majority cases where db is guaranteed to be not NULL. FossilOrigin-Name: 0a802e96ab06e2643834b83671fa8353da1a348d --- manifest | 50 +++++++++++++-------------- manifest.uuid | 2 +- src/analyze.c | 4 +-- src/attach.c | 2 +- src/build.c | 3 +- src/date.c | 2 +- src/delete.c | 2 +- src/expr.c | 27 +++++++++------ src/fkey.c | 2 +- src/insert.c | 4 +-- src/malloc.c | 91 ++++++++++++++++++++++++++++--------------------- src/rowset.c | 2 +- src/select.c | 4 +-- src/sqliteInt.h | 1 + src/update.c | 2 +- src/util.c | 2 +- src/vdbe.c | 8 ++--- src/vdbeaux.c | 2 +- src/vdbemem.c | 5 +-- src/vtab.c | 2 +- src/where.c | 6 ++-- src/whereexpr.c | 4 +-- 22 files changed, 125 insertions(+), 102 deletions(-) diff --git a/manifest b/manifest index be1bead349..9ea4a16054 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C OOM\sfailures\son\ssqlite3_errmsg16()\sin\san\sapp-defined\sfunction\sare\sno\slonger\nbenign. -D 2016-02-05T04:50:27.680 +C Add\sthe\sslightly\sfaster\ssqlite3DbMallocRawNN(db,n)\sroutine\sfor\sthe\smajority\ncases\swhere\sdb\sis\sguaranteed\sto\sbe\snot\sNULL. +D 2016-02-05T13:38:36.171 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -285,8 +285,8 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c e4a5132e6264e002ab87c268108f416df3f1fb10 -F src/analyze.c 5338dbbc9f12087b38d74234de00907bdf023a92 -F src/attach.c b943546856ac657c702e1a92fb7adcf67c1dc397 +F src/analyze.c fbf0e80d83cc893734e872f932f249a056b86e11 +F src/attach.c c16c2648a577fa3def2adfa48c28901376389bc5 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf @@ -294,27 +294,27 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 784c61366e79092b16e116372e66930775d2e6dc +F src/build.c 198eaa849c193f28b802ed135b2483c68ef7a35c F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 -F src/date.c 997651e3ee6c2818fbf7fcdb7156cef9eb3ece20 +F src/date.c ca17321bc17cca8f40e0843edea4fafff974998e F src/dbstat.c b2ec6793eef97aebb4d171d490a4ffdfa9f2475c -F src/delete.c 33ed87dc0746b1f8ce186f62b608bf40801af9c0 -F src/expr.c fddb1b19d77730d423ef2c219ae17e10087554ba +F src/delete.c 48802aa3ee6339f576d074336d3ae1b5f40e240f +F src/expr.c fbf0706199aea23c54efe36b6932d8307c4eb872 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c dc893ee37a21868fcf07e3d941c7663957807ad2 +F src/fkey.c 08edad1fce30f761f14b3997e89bad58f9f7f4e0 F src/func.c 86e55fee35b9577e485f47d9dd5c1d34cd513288 F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c e3e2811c69318ff62d8a764b01f5a5677d846b1e +F src/insert.c b84359365bace233919db550a15f131923190efc F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 -F src/malloc.c 92ca6e16c90fb10f97844c08061bd8381423eb89 +F src/malloc.c 55ebb1701ebd39985dbcc497aaecb09192b69682 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -347,13 +347,13 @@ F src/prepare.c c12b786713df3e8270c0f85f988c5359d8b4d87c F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c -F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e -F src/select.c 07178f2ae1239404874492ba7e3b9a46361ebbbc +F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e +F src/select.c 57646a44ba9a0bc4aa926ae9c79b8199c246844b F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h dfbe62ffd95b99afe2140d8c35b180d11924072d -F src/sqliteInt.h e251b755c71c343434bce1e82c6593603c7af364 +F src/sqliteInt.h 3aeaff9611acd790c8e76719b33db09ab885d537 F src/sqliteLimit.h 216557999cb45f2e3578ed53ebefe228d779cb46 F src/status.c 70912d7be68e9e2dbc4010c93d344af61d4c59ba F src/table.c 51b46b2a62d1b3a959633d593b89bab5e2c9155e @@ -409,28 +409,28 @@ F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 F src/tokenize.c 214b783d6138e9f9fbb6b225ce9a376db3b03d42 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 -F src/update.c 17332f9fe818cbc0444c36a811800af8498af4c3 +F src/update.c 310ca7adb86a7d1f2afae46905b21c83580f3e17 F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 -F src/util.c 72d40df0a52d3f30b462a15f0e094fcbade6dc82 +F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 -F src/vdbe.c 2e49c5d1b8f2f24f91ddd6c6b003d8e7fbbc4e56 +F src/vdbe.c c193299e595a13eba247738e22fce25c49346a6c F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459 -F src/vdbeaux.c 777461529f862623e9164eb954fc53e54ddd650a +F src/vdbeaux.c 49b536284c2b8a823dd342d653e18145ca2b393a F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db -F src/vdbemem.c 9a6736339ca581f3b9503d5a1a40b7d718ca4635 +F src/vdbemem.c 68fcfac37dc6601d98c32cc5adee4d39f2c1b7b4 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 F src/vdbetrace.c f75c5455d8cf389ef86a8bfdfd3177e0e3692484 -F src/vtab.c 2cc0b7bb253851c8718b8850dfaed8592b6dc7f8 +F src/vtab.c bef51b4f693d82b4b0184457faa8625654534091 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c d21b99fd1458159d0b1ecdccc8ee6ada4fdc4c54 F src/wal.h 2f7c831cf3b071fa548bf2d5cac640846a7ff19c F src/walker.c 0f142b5bd3ed2041fc52d773880748b212e63354 -F src/where.c 8bdb43e09d4e7f20bb371154799da39c25b51dfd +F src/where.c d89fd5cff448ab5c5ca492dd9793b35ffe31ab35 F src/whereInt.h 78b6b4de94db84aecbdc07fe3e38f648eb391e9a F src/wherecode.c 791a784bbf8749d560fdb0b990b607bc4f44a38d -F src/whereexpr.c 85ee2de9ff0fe40a4afaf2a477bd6c9a808548b3 +F src/whereexpr.c de117970b29471177a6901d60ad83a194671dc03 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1426,7 +1426,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 a8846aeed9992c6c9f1c8bd6e996a4cbe891751e -R d0bf71e8097462f80d2341a6f602c53f +P 9efb223f4ce8ccc00515f8f016f7c494c9ae5096 +R a3e65991654c830e3de734323ec006f3 U drh -Z 1d703e36553aaf91d3187c59187314d2 +Z 1d7c8b6479ccf726221b089b3d2b622f diff --git a/manifest.uuid b/manifest.uuid index 72711c9e2c..9543c6e779 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9efb223f4ce8ccc00515f8f016f7c494c9ae5096 \ No newline at end of file +0a802e96ab06e2643834b83671fa8353da1a348d \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 7a7d68f59a..1e026a7530 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -313,7 +313,7 @@ static void sampleClear(sqlite3 *db, Stat4Sample *p){ static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ assert( db!=0 ); if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); - p->u.aRowid = sqlite3DbMallocRaw(db, n); + p->u.aRowid = sqlite3DbMallocRawNN(db, n); if( p->u.aRowid ){ p->nRowid = n; memcpy(p->u.aRowid, pData, n); @@ -1115,7 +1115,7 @@ static void analyzeOneTable( if( nColTest>0 ){ int endDistinctTest = sqlite3VdbeMakeLabel(v); int *aGotoChng; /* Array of jump instruction addresses */ - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); + aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); if( aGotoChng==0 ) continue; /* diff --git a/src/attach.c b/src/attach.c index e167951f68..2288ac9b62 100644 --- a/src/attach.c +++ b/src/attach.c @@ -109,7 +109,7 @@ static void attachFunc( ** hash tables. */ if( db->aDb==db->aDbStatic ){ - aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 ); + aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ diff --git a/src/build.c b/src/build.c index 4185f48e93..476fc28c41 100644 --- a/src/build.c +++ b/src/build.c @@ -3702,8 +3702,9 @@ SrcList *sqlite3SrcListAppend( ){ struct SrcList_item *pItem; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ + assert( db!=0 ); if( pList==0 ){ - pList = sqlite3DbMallocRaw(db, sizeof(SrcList) ); + pList = sqlite3DbMallocRawNN(db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 0; diff --git a/src/date.c b/src/date.c index d78e83cf57..0a1d0e0798 100644 --- a/src/date.c +++ b/src/date.c @@ -967,7 +967,7 @@ static void strftimeFunc( sqlite3_result_error_toobig(context); return; }else{ - z = sqlite3DbMallocRaw(db, (int)n); + z = sqlite3DbMallocRawNN(db, (int)n); if( z==0 ){ sqlite3_result_error_nomem(context); return; diff --git a/src/delete.c b/src/delete.c index 5b5a5e3cb1..0fe064bc45 100644 --- a/src/delete.c +++ b/src/delete.c @@ -439,7 +439,7 @@ void sqlite3DeleteFrom( ** one, so just keep it in its register(s) and fall through to the ** delete code. */ nKey = nPk; /* OP_Found will use an unpacked key */ - aToOpen = sqlite3DbMallocRaw(db, nIdx+2); + aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); if( aToOpen==0 ){ sqlite3WhereEnd(pWInfo); goto delete_from_cleanup; diff --git a/src/expr.c b/src/expr.c index 5b134d6661..8d96ba10cd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -453,6 +453,7 @@ Expr *sqlite3ExprAlloc( int nExtra = 0; int iValue = 0; + assert( db!=0 ); if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 || sqlite3GetInt32(pToken->z, &iValue)==0 ){ @@ -460,7 +461,7 @@ Expr *sqlite3ExprAlloc( assert( iValue>=0 ); } } - pNew = sqlite3DbMallocRaw(db, sizeof(Expr)+nExtra); + pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); if( pNew ){ memset(pNew, 0, sizeof(Expr)); pNew->op = (u8)op; @@ -857,6 +858,7 @@ static int dupedExprSize(Expr *p, int flags){ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ Expr *pNew = 0; /* Value to return */ assert( flags==0 || flags==EXPRDUP_REDUCE ); + assert( db!=0 ); if( p ){ const int isReduced = (flags&EXPRDUP_REDUCE); u8 *zAlloc; @@ -869,7 +871,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){ zAlloc = *pzBuffer; staticFlag = EP_Static; }else{ - zAlloc = sqlite3DbMallocRaw(db, dupedExprSize(p, flags)); + zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, flags)); } pNew = (Expr *)zAlloc; @@ -992,12 +994,13 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; + assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nExpr = i = p->nExpr; if( (flags & EXPRDUP_REDUCE)==0 ) for(i=1; inExpr; i+=i){} - pNew->a = pItem = sqlite3DbMallocRaw(db, i*sizeof(p->a[0]) ); + pNew->a = pItem = sqlite3DbMallocRawNN(db, i*sizeof(p->a[0]) ); if( pItem==0 ){ sqlite3DbFree(db, pNew); return 0; @@ -1028,9 +1031,10 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ SrcList *pNew; int i; int nByte; + assert( db!=0 ); if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); - pNew = sqlite3DbMallocRaw(db, nByte ); + pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ @@ -1067,11 +1071,12 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; + assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = p->nId; - pNew->a = sqlite3DbMallocRaw(db, p->nId*sizeof(p->a[0]) ); + pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ sqlite3DbFree(db, pNew); return 0; @@ -1089,8 +1094,9 @@ IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ } Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ Select *pNew, *pPrior; + assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRaw(db, sizeof(*p) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); if( pNew==0 ) return 0; pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); @@ -1136,13 +1142,14 @@ ExprList *sqlite3ExprListAppend( Expr *pExpr /* Expression to be appended. Might be NULL */ ){ sqlite3 *db = pParse->db; + assert( db!=0 ); if( pList==0 ){ - pList = sqlite3DbMallocRaw(db, sizeof(ExprList) ); + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } pList->nExpr = 0; - pList->a = sqlite3DbMallocRaw(db, sizeof(pList->a[0])); + pList->a = sqlite3DbMallocRawNN(db, sizeof(pList->a[0])); if( pList->a==0 ) goto no_mem; }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ struct ExprList_item *a; diff --git a/src/fkey.c b/src/fkey.c index fae25c4828..38fd4f756b 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -219,7 +219,7 @@ int sqlite3FkLocateIndex( } }else if( paiCol ){ assert( nCol>1 ); - aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); + aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); if( !aiCol ) return 1; *paiCol = aiCol; } diff --git a/src/insert.c b/src/insert.c index a8cde72954..729e0fedce 100644 --- a/src/insert.c +++ b/src/insert.c @@ -230,7 +230,7 @@ static int autoIncBegin( pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ - pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo)); + pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); if( pInfo==0 ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; @@ -787,7 +787,7 @@ void sqlite3Insert( int nIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); - aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); + aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ goto insert_cleanup; } diff --git a/src/malloc.c b/src/malloc.c index 441b4cb67d..1ff0a5221d 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -575,10 +575,24 @@ void *sqlite3MallocZero(u64 n){ ** the mallocFailed flag in the connection pointer. */ void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ - void *p = sqlite3DbMallocRaw(db, n); - if( p ){ - memset(p, 0, (size_t)n); - } + void *p; + testcase( db==0 ); + p = sqlite3DbMallocRaw(db, n); + if( p ) memset(p, 0, (size_t)n); + return p; +} + + +/* Finish the work of sqlite3DbMallocRawNN for the unusual and +** slower case when the allocation cannot be fulfilled using lookaside. +*/ +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ + void *p; + assert( db!=0 ); + p = sqlite3Malloc(n); + if( !p ) sqlite3OomFault(db); + sqlite3MemdebugSetType(p, + (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); return p; } @@ -600,50 +614,48 @@ void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ ** ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. +** +** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is +** not a NULL pointer. */ -static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n); void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ - assert( db==0 || sqlite3_mutex_held(db->mutex) ); - assert( db==0 || db->pnBytesFreed==0 ); + void *p; + if( db ) return sqlite3DbMallocRawNN(db, n); + p = sqlite3Malloc(n); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + return p; +} +void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); #ifndef SQLITE_OMIT_LOOKASIDE - if( db ){ - LookasideSlot *pBuf; - if( db->lookaside.bDisable==0 ){ - assert( db->mallocFailed==0 ); - if( n>db->lookaside.sz ){ - db->lookaside.anStat[1]++; - }else if( (pBuf = db->lookaside.pFree)==0 ){ - db->lookaside.anStat[2]++; - }else{ - db->lookaside.pFree = pBuf->pNext; - db->lookaside.nOut++; - db->lookaside.anStat[0]++; - if( db->lookaside.nOut>db->lookaside.mxOut ){ - db->lookaside.mxOut = db->lookaside.nOut; - } - return (void*)pBuf; + LookasideSlot *pBuf; + if( db->lookaside.bDisable==0 ){ + assert( db->mallocFailed==0 ); + if( n>db->lookaside.sz ){ + db->lookaside.anStat[1]++; + }else if( (pBuf = db->lookaside.pFree)==0 ){ + db->lookaside.anStat[2]++; + }else{ + db->lookaside.pFree = pBuf->pNext; + db->lookaside.nOut++; + db->lookaside.anStat[0]++; + if( db->lookaside.nOut>db->lookaside.mxOut ){ + db->lookaside.mxOut = db->lookaside.nOut; } - }else if( db->mallocFailed ){ - return 0; + return (void*)pBuf; } - + }else if( db->mallocFailed ){ + return 0; } #else - if( db && db->mallocFailed ){ + if( db->mallocFailed ){ return 0; } #endif return dbMallocRawFinish(db, n); } -static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ - void *p = sqlite3Malloc(n); - if( !p && db ){ - sqlite3OomFault(db); - } - sqlite3MemdebugSetType(p, - (db && db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); - return p; -} /* Forward declaration */ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); @@ -654,7 +666,7 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); */ void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); - if( p==0 ) return sqlite3DbMallocRaw(db, n); + if( p==0 ) return sqlite3DbMallocRawNN(db, n); assert( sqlite3_mutex_held(db->mutex) ); if( isLookaside(db,p) && n<=db->lookaside.sz ) return p; return dbReallocFinish(db, p, n); @@ -665,7 +677,7 @@ static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ assert( p!=0 ); if( db->mallocFailed==0 ){ if( isLookaside(db, p) ){ - pNew = sqlite3DbMallocRaw(db, n); + pNew = sqlite3DbMallocRawNN(db, n); if( pNew ){ memcpy(pNew, p, db->lookaside.sz); sqlite3DbFree(db, p); @@ -721,11 +733,12 @@ char *sqlite3DbStrDup(sqlite3 *db, const char *z){ } char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ char *zNew; + assert( db!=0 ); if( z==0 ){ return 0; } assert( (n&0x7fffffff)==n ); - zNew = sqlite3DbMallocRaw(db, n+1); + zNew = sqlite3DbMallocRawNN(db, n+1); if( zNew ){ memcpy(zNew, z, (size_t)n); zNew[n] = 0; diff --git a/src/rowset.c b/src/rowset.c index ff5593892a..c2e73ed72e 100644 --- a/src/rowset.c +++ b/src/rowset.c @@ -181,7 +181,7 @@ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ assert( p!=0 ); if( p->nFresh==0 ){ struct RowSetChunk *pNew; - pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew)); + pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); if( pNew==0 ){ return 0; } diff --git a/src/select.c b/src/select.c index 84d5423de6..ea3e920b9f 100644 --- a/src/select.c +++ b/src/select.c @@ -112,7 +112,7 @@ Select *sqlite3SelectNew( Select *pNew; Select standin; sqlite3 *db = pParse->db; - pNew = sqlite3DbMallocRaw(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ){ assert( db->mallocFailed ); pNew = &standin; @@ -2870,7 +2870,7 @@ static int multiSelectOrderBy( ** to the right and the left are evaluated, they use the correct ** collation. */ - aPermute = sqlite3DbMallocRaw(db, sizeof(int)*(nOrderBy + 1)); + aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1)); if( aPermute ){ struct ExprList_item *pItem; aPermute[0] = nOrderBy; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 70f210c0a2..760c1f4d21 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3227,6 +3227,7 @@ void *sqlite3Malloc(u64); void *sqlite3MallocZero(u64); void *sqlite3DbMallocZero(sqlite3*, u64); void *sqlite3DbMallocRaw(sqlite3*, u64); +void *sqlite3DbMallocRawNN(sqlite3*, u64); char *sqlite3DbStrDup(sqlite3*,const char*); char *sqlite3DbStrNDup(sqlite3*,const char*, u64); void *sqlite3Realloc(void*, u64); diff --git a/src/update.c b/src/update.c index a9735cadca..20951aade9 100644 --- a/src/update.c +++ b/src/update.c @@ -197,7 +197,7 @@ void sqlite3Update( /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ - aXRef = sqlite3DbMallocRaw(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); + aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); if( aXRef==0 ) goto update_cleanup; aRegIdx = aXRef+pTab->nCol; aToOpen = (u8*)(aRegIdx+nIdx); diff --git a/src/util.c b/src/util.c index 96f7c7f3dc..37b585b2ea 100644 --- a/src/util.c +++ b/src/util.c @@ -1150,7 +1150,7 @@ void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ char *zBlob; int i; - zBlob = (char *)sqlite3DbMallocRaw(db, n/2 + 1); + zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); n--; if( zBlob ){ for(i=0; ip3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); + pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; pCtx->pOut = 0; pCtx->pFunc = pOp->p4.pFunc; @@ -2870,7 +2870,7 @@ case OP_Savepoint: { #endif /* Create a new savepoint structure. */ - pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+nName+1); + pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); if( pNew ){ pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, zName, nName+1); @@ -5420,7 +5420,7 @@ case OP_IntegrityCk: { assert( p->bIsReader ); nRoot = pOp->p2; assert( nRoot>0 ); - aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(nRoot+1) ); + aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(nRoot+1) ); if( aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pnErr = &aMem[pOp->p3]; @@ -5917,7 +5917,7 @@ case OP_AggStep0: { assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = sqlite3DbMallocRaw(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); + pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); if( pCtx==0 ) goto no_mem; pCtx->pMem = 0; pCtx->pFunc = pOp->p4.pFunc; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 334f54e414..8eb3141daf 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -289,7 +289,7 @@ int sqlite3VdbeAddOp4Dup8( const u8 *zP4, /* The P4 operand */ int p4type /* P4 operand type */ ){ - char *p4copy = sqlite3DbMallocRaw(sqlite3VdbeDb(p), 8); + char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); if( p4copy ) memcpy(p4copy, zP4, 8); return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); } diff --git a/src/vdbemem.c b/src/vdbemem.c index 974b990747..6fb7cebbcc 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -116,6 +116,7 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( sqlite3VdbeCheckMemInvariants(pMem) ); assert( (pMem->flags&MEM_RowSet)==0 ); + testcase( pMem->db==0 ); /* If the bPreserve flag is set to true, then the memory cell must already ** contain a valid string or blob value. */ @@ -719,7 +720,7 @@ void sqlite3VdbeMemSetRowSet(Mem *pMem){ assert( db!=0 ); assert( (pMem->flags & MEM_RowSet)==0 ); sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRaw(db, 64); + pMem->zMalloc = sqlite3DbMallocRawNN(db, 64); if( db->mallocFailed ){ pMem->flags = MEM_Null; pMem->szMalloc = 0; @@ -1440,7 +1441,7 @@ static void recordFunc( db = sqlite3_context_db_handle(context); nRet = 1 + nSerial + nVal; - aRet = sqlite3DbMallocRaw(db, nRet); + aRet = sqlite3DbMallocRawNN(db, nRet); if( aRet==0 ){ sqlite3_result_error_nomem(context); }else{ diff --git a/src/vtab.c b/src/vtab.c index ca444944f4..e8794e687d 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -49,7 +49,7 @@ static int createModule( rc = SQLITE_MISUSE_BKPT; }else{ Module *pMod; - pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); + pMod = (Module *)sqlite3DbMallocRawNN(db, sizeof(Module) + nName + 1); if( pMod ){ Module *pDel; char *zCopy = (char *)(&pMod[1]); diff --git a/src/where.c b/src/where.c index d3a4ab87e4..1bee2ca6fe 100644 --- a/src/where.c +++ b/src/where.c @@ -1735,7 +1735,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ WhereTerm **paNew; if( p->nLSlot>=n ) return SQLITE_OK; n = (n+7)&~7; - paNew = sqlite3DbMallocRaw(db, sizeof(p->aLTerm[0])*n); + paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); if( paNew==0 ) return SQLITE_NOMEM; memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFree(db, p->aLTerm); @@ -2032,7 +2032,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ #endif if( p==0 ){ /* Allocate a new WhereLoop to add to the end of the list */ - *ppPrev = p = sqlite3DbMallocRaw(db, sizeof(WhereLoop)); + *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); if( p==0 ) return SQLITE_NOMEM; whereLoopInit(p); p->pNextLoop = 0; @@ -3529,7 +3529,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; - pSpace = sqlite3DbMallocRaw(db, nSpace); + pSpace = sqlite3DbMallocRawNN(db, nSpace); if( pSpace==0 ) return SQLITE_NOMEM; aTo = (WherePath*)pSpace; aFrom = aTo+mxChoice; diff --git a/src/whereexpr.c b/src/whereexpr.c index ec244bcb46..c84d2f230a 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -64,7 +64,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pWInfo->pParse->db; - pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); + pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ if( wtFlags & TERM_DYNAMIC ){ sqlite3ExprDelete(db, p); @@ -549,7 +549,7 @@ static void exprAnalyzeOrTerm( WhereAndInfo *pAndInfo; assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); chngToIN = 0; - pAndInfo = sqlite3DbMallocRaw(db, sizeof(*pAndInfo)); + pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); if( pAndInfo ){ WhereClause *pAndWC; WhereTerm *pAndTerm; From a23bc8a345e9030c56808202d290c8ae0e4cbf6c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 16:46:09 +0000 Subject: [PATCH 090/107] From test scripts, remove stray "breakpoint" commands and blank lines at the ends of files. FossilOrigin-Name: a6b35273239669189f33402144f58328b133d182 --- manifest | 111 +++++++++++++++++++-------------------- manifest.uuid | 2 +- test/analyze9.test | 3 -- test/analyzeB.test | 1 - test/analyzeD.test | 1 - test/cacheflush.test | 1 - test/cffault.test | 1 - test/corruptH.test | 1 - test/corruptI.test | 1 - test/cost.test | 3 -- test/e_blobbytes.test | 2 - test/e_blobclose.test | 1 - test/e_blobopen.test | 1 - test/e_blobwrite.test | 1 - test/e_walckpt.test | 1 - test/fkey8.test | 1 - test/fordelete.test | 1 - test/fts3conf.test | 1 - test/fts3expr4.test | 1 - test/fts3join.test | 2 - test/fts3matchinfo.test | 2 - test/fts3offsets.test | 1 - test/fts3snippet.test | 1 - test/fts4check.test | 1 - test/fts4content.test | 1 - test/fts4growth.test | 1 - test/fts4growth2.test | 1 - test/fts4noti.test | 3 -- test/fts4onepass.test | 1 - test/fuzz3.test | 1 - test/incrcorrupt.test | 1 - test/mallocK.test | 1 - test/mallocL.test | 1 - test/ovfl.test | 2 - test/pragma2.test | 1 - test/rollback2.test | 1 - test/rollbackfault.test | 2 - test/select7.test | 2 - test/shared3.test | 1 - test/snapshot.test | 1 - test/sort3.test | 1 - test/sort5.test | 1 - test/spellfix.test | 1 - test/sqllog.test | 3 -- test/tkt-9f2eb3abac.test | 1 - test/tkt-ba7cbfaedc.test | 2 - test/triggerE.test | 2 - test/vtab_shared.test | 1 - test/wal6.test | 1 - test/waloverwrite.test | 2 - test/whereI.test | 1 - test/withM.test | 3 -- 52 files changed, 56 insertions(+), 126 deletions(-) diff --git a/manifest b/manifest index 8c2dfea1b7..ca42763a5e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sout-of-memory\sconditions\sare\shandled,\sresulting\nin\san\salmost\s1%\sperformance\sgain\sin\sthe\scommmon\scase\swhere\sOOM\serrors\sdo\nnot\soccur. -D 2016-02-05T14:11:12.413 +C From\stest\sscripts,\sremove\sstray\s"breakpoint"\scommands\sand\sblank\slines\nat\sthe\sends\sof\sfiles. +D 2016-02-05T16:46:09.824 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -450,11 +450,11 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze8.test c05a461d0a6b05991106467d0c47480f2e709c82 -F test/analyze9.test 3dd9e203fad353ec8027b18a6d9a92af59f4e727 +F test/analyze9.test 88c1f2aa20b614236f03e1cc38c3619e7e8a38b4 F test/analyzeA.test 3335697f6700c7052295cfd0067fc5b2aacddf9a -F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d +F test/analyzeB.test a4c1c3048f6d9e090eb76e83eecb18bcf6d31a70 F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 -F test/analyzeD.test 08f9d0bee4e118a66fff3a32d02dbe0ee0a2b594 +F test/analyzeD.test f3d77cd0fefe2849d784897d52df13beee19271d F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d F test/analyzeF.test 5d1fe1024ba2dfea3c18bede8c1ccef8aba1ab34 F test/analyzer1.test 498e2ff4b62740c2751c3a2f8b744fe26689fae9 @@ -513,7 +513,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 a755c93482ce2e20c04825304bef27e7b7ea0111 +F test/cacheflush.test af25bb1509df04c1da10e38d8f322d66eceedf61 F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738 F test/capi3.test bf6f0308bbbba1e770dac13aa08e5c2ac61c7324 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 @@ -521,7 +521,7 @@ F test/capi3c.test 06f6261f9e9b4ef6f76afcd9900f3665408af1c8 F test/capi3d.test 485048dc5cd07bc68011e4917ad035ad6047ab82 F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 -F test/cffault.test 1647eef45512817265c360ed4539538eed26ac69 +F test/cffault.test aadc1f61f8811cb600e3e069acbf8796f472a096 F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763 F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815 F test/closure01.test b1703ba40639cfc9b295cf478d70739415eec6a4 @@ -558,10 +558,10 @@ F test/corruptD.test b3c205fac7952b1de645ce44bb02335cd9e3e040 F test/corruptE.test be8e5088c369fc7979c662cd644efdaafc0f7f6d F test/corruptF.test be9fde98e4c93648f1ba52b74e5318edc8f59fe4 F test/corruptG.test 1ab3bf97ee7bdba70e0ff3ba2320657df55d1804 -F test/corruptH.test 5dd4fa98c6c1ed33b178f9e8a48c4fdd3cfc9067 -F test/corruptI.test f2b10e4fec2a4315bca2b936ffa52ccbffac3422 +F test/corruptH.test 99ad81a4bda7cc078c589ef7542ecbc64e453c80 +F test/corruptI.test 347babbf970e7947e3f91dccf7a1bec28a1bab04 F test/corruptJ.test 9e29e7a81ee3b6ac50f77ea7a9e2f3fa03f32d91 -F test/cost.test 19d314526616ce4473eb4e4e450fcb94499ce318 +F test/cost.test 1eedbfd868f806f3fa08ff072b04cf270dcf61c8 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c F test/coveridxscan.test cdb47d01acc4a634a34fd25abe85189e0d0f1e62 F test/crash.test fb9dc4a02dcba30d4aa5c2c226f98b220b2b959f @@ -592,10 +592,10 @@ F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 -F test/e_blobbytes.test 9bea1d3e2b20f3010b04abba58f6ba172301f49f -F test/e_blobclose.test df756753f571bc30e42e3a6cba2807576e49e716 -F test/e_blobopen.test 234f960d90235a9b51ec3ca1e062e8541dd558d8 -F test/e_blobwrite.test 615b405f29feb2cfb5a1f03dab7933258294fa26 +F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 +F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d +F test/e_blobopen.test e95e1d40f995056f6f322cd5e1a1b83a27e1a145 +F test/e_blobwrite.test 650ded42ee5e0c2dbf263583ce01adf280129599 F test/e_changes.test fd66105385153dbf21fdb35eb8ef6c3e1eade579 F test/e_createtable.test d4c6059d44dcd4b636de9aae322766062b471844 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e @@ -615,7 +615,7 @@ F test/e_uri.test eed3eb41b22d051a1164110dacdc778899126e14 F test/e_vacuum.test 5bfbdc21b65c0abf24398d0ba31dc88d93ca77a9 F test/e_wal.test ae9a593207a77d711443ee69ffe081fda9243625 F test/e_walauto.test 280714ddf14e1a47dcbc59d515cd0b026dfd5567 -F test/e_walckpt.test 65e29b6631e51f210f83e4ff11571e647ba93608 +F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test da3ea8b3483d1af72190337bda50155a91a4b664 F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc2.test 83437a79ba1545a55fb549309175c683fb334473 @@ -641,9 +641,9 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 5a373303f201ac03c22ba1ef17a733d3f56e611a F test/fkey6.test abb59f866c1b44926fd02d1fdd217d831fe04f48 F test/fkey7.test 72e915890ee4a005daaf3002cb208e8fe973ac13 -F test/fkey8.test 8f08203458321e6c19a263829de4cfc936274ab0 +F test/fkey8.test 7bd1dd0174a0e29a90c62c517b9e2a410a0b345d F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 -F test/fordelete.test 57ed9b953eeace09dd2eac3251b40bf9d6990aec +F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 @@ -704,7 +704,7 @@ F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba F test/fts3b.test e93bbb653e52afde110ad53bbd793f14fe7a8984 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c -F test/fts3conf.test ff90127b2462c788348c0dd7f6f8c573ef9cb5d9 +F test/fts3conf.test 1c8b8adb0ab28a41b68d1514df44380bd7353402 F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7 @@ -717,40 +717,40 @@ F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851 F test/fts3expr.test 3401d47b229c4504424caf362cc4ff704cad4162 F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr3.test c4d4a7d6327418428c96e0a3a1137c251b8dfbf8 -F test/fts3expr4.test e1be1248566f43c252d4404d52914f1fc4bfa065 +F test/fts3expr4.test c39a15d676b14fc439d9bf845aa7bddcf4a74dc3 F test/fts3expr5.test f9abfffbf5e53d48a33e12a1e8f8ba2c551c9b49 F test/fts3fault.test da49627b280b210ebc6657f76344c7851f10ce66 F test/fts3fault2.test f953bb3cf903988172270a9a0aafd5a890b0f98f F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 -F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499 +F test/fts3join.test 34750f3ce1e29b2749eaf0f1be2fa6301c5d50da F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 -F test/fts3matchinfo.test 07009313ad6c082f94d8c9c3228eb8940c93ac71 +F test/fts3matchinfo.test ce864e0bd92429df8008f31cf557269ba172482a F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905 -F test/fts3offsets.test 5b8ec5be27dd2070af3538b23c67f1ca8c822853 +F test/fts3offsets.test b85fd382abdc78ebce721d8117bd552dfb75094c F test/fts3prefix.test fa794eaab0bdae466494947b0b153d7844478ab2 F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce F test/fts3query.test f33eb71a1fe1084ea585eeb7ee76b390729f5170 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e -F test/fts3snippet.test 63dbd687d5bf5191f1b8e6a0977aa9c1e28a7004 +F test/fts3snippet.test 01a4231816e03a0660ae53ba2404fe69012fe0db F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test 178c050199af8c05299b1ad572514ce1c54b7827 F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e F test/fts4aa.test 10aac8e9d62c7357590acfabe3fad01e9a9ce1cb -F test/fts4check.test 9d9e818fd6cb29c0e007cd6d00447739d4fde430 -F test/fts4content.test 8707425b926663f8ca81de866c007900442b5ec0 +F test/fts4check.test c3056eab9524232e4c9bdcd119912947e07bcc1c +F test/fts4content.test 05716af19a899cd70d5cd916c580043c03f30db4 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 -F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53 -F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d +F test/fts4growth.test 60d6bb3f78e25b34f533797dd9f2f9402310a13a +F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7 F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b -F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849 -F test/fts4onepass.test bfca61f69c6ca74cd71e6dca12a0cdd47192fc24 +F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309 +F test/fts4onepass.test 7319d61a2ed1325fc54afd0c060a0513b462303a F test/fts4unicode.test 27378af76394542cf490cf001d8d1505fe55f6a9 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef @@ -761,7 +761,7 @@ F test/func5.test cdd224400bc3e48d891827cc913a57051a426fa4 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 F test/fuzz.test 96083052bf5765e4518c1ba686ce2bab785670d1 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 -F test/fuzz3.test 53fabcd5f0f430f8b221282f6c12c4d0903c21eb +F test/fuzz3.test b47377143f0c80f91ed29d722861077ff34415d5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzcheck.c 3309d793165ca61a9996271cb799694839348f9a @@ -790,7 +790,7 @@ F test/incrblob3.test d8d036fde015d4a159cd3cbae9d29003b37227a4 F test/incrblob4.test f26502a5697893e5acea268c910f16478c2f0fab F test/incrblob_err.test af1f12ba60d220c9752073ff2bda2ad59e88960d F test/incrblobfault.test 280474078f6da9e732cd2a215d3d854969014b6e -F test/incrcorrupt.test 9786cba68c5832f01887fde1c06b43c3904d86f6 +F test/incrcorrupt.test 6c567fbf870aa9e91866fe52ce6f200cd548939a F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 F test/incrvacuum2.test 676c41428765d58f1da7dbe659ef27726d3d30ac F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a @@ -876,8 +876,8 @@ F test/mallocG.test 0ff91b65c50bdaba680fb75d87fe4ad35bb7934f F test/mallocH.test 79b65aed612c9b3ed2dcdaa727c85895fd1bfbdb F test/mallocI.test a88c2b9627c8506bf4703d8397420043a786cdb6 F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e -F test/mallocK.test da01dcdd316767b8356741f8d33a23a06a23def5 -F test/mallocL.test 252ddc7eb4fbf75364eab17b938816085ff1fc17 +F test/mallocK.test 27cb5566a6e5f2d76f9d4aa2eca45524401fd61e +F test/mallocL.test fb311ff80afddf3b1a75e52289081f4754d901dc F test/malloc_common.tcl aac62499b76be719fac31e7a3e54a7fd53272e7f F test/manydb.test 28385ae2087967aa05c38624cec7d96ec74feb3e F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f @@ -930,7 +930,7 @@ F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 F test/oserror.test b32dc34f2363ef18532e3a0a7358e3e7e321974f -F test/ovfl.test 4f7ca651cba5c059a12d8c67dddd49bec5747799 +F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f F test/pager1.test 1acbdb14c5952a72dd43129cabdbf69aaa3ed1fa F test/pager2.test 67b8f40ae98112bcdba1f2b2d03ea83266418c71 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f @@ -946,7 +946,7 @@ F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 382a43c49f49bafe6fddffe904ea33d6bb3ff33e F test/pragma.test 507ac7ef2ea5682241ea0ef041799ca70bb5e0bf -F test/pragma2.test a9400a7289605280576098b97f5cde3f204075c0 +F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 6f849ccffeee7e496d2f2b5e74152306c0b8757c F test/printf.test b3ff34e73d59124140eaf89f7672e21bc2ca5fcc F test/printf2.test 0b61566dd1c0f0b802f59dffa228c5dc5aa6b054 @@ -967,8 +967,8 @@ F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 F test/releasetest.tcl 975449bf742b8bb9025208292208af816a1fcb58 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/rollback.test 458fe73eb3ffdfdf9f6ba3e9b7350a6220414dea -F test/rollback2.test fc14cf6d1a2b250d2735ef16124b971bce152f14 -F test/rollbackfault.test 6a004f71087cc399296cffbb5429ea6da655ae65 +F test/rollback2.test 8435d6ff0f13f51d2a4181c232e706005fa90fc5 +F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d @@ -995,7 +995,7 @@ F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650 F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 -F test/select7.test 71f06cd37cb6f65bb08ba1ccf8e2f5818c09329f +F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d F test/select9.test aebc2bb0c3bc44606125033cbcaac2c8d1f33a95 F test/selectA.test e452bdb975f488ea46d091382a9185b5853ed2c7 @@ -1008,7 +1008,7 @@ F test/selectG.test e8600e379589e85e9fefd2fe4d44a4cdd63f6982 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/shared.test 1da9dbad400cee0d93f252ccf76e1ae007a63746 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 -F test/shared3.test fcd65cb11d189eff5f5c85cc4fad246fb0933108 +F test/shared3.test ab693f9b6e156b8bfb2a0ad94f29fe69602a5d38 F test/shared4.test c75f476804e76e26bf6fa0e7b421fb0ca7d07558 F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9 F test/shared7.test a81e99f83e6c51b02ac99c96fb3a2a7b5978c956 @@ -1032,15 +1032,15 @@ F test/skipscan2.test d1d1450952b7275f0b0a3a981f0230532743951a F test/skipscan3.test ec5bab3f81c7038b43450e7b3062e04a198bdbb5 F test/skipscan5.test 67817a4b6857c47e0e33ba3e506da6f23ef68de2 F test/skipscan6.test 5866039d03a56f5bd0b3d172a012074a1d90a15b -F test/snapshot.test efc6b4edc5d571161835f9dd8552e181ad1f0ac2 +F test/snapshot.test 5ec4651d16c3d1eb6c010d102febe32b3614bf56 F test/snapshot_fault.test 25973aeb1b86a280800e0bcf1eb5ce70e9ef57ab F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test c2adc635c2564241fefec0b3a68391ef6868fd3b F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 -F test/sort3.test 1d831e95076b92985754a122e92ebc23bdf6f712 +F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test 5c34d9623a4ae5921d956dfa2b70e77ed0fc6e5c -F test/sort5.test a448240a42b49239edc00f85d6d7ac7a1b261e1f +F test/sort5.test d3041ce3c475aa04142a959ae56ef6593f98a99f F test/sortfault.test d4ccf606a0c77498e2beb542764fd9394acb4d66 F test/speed1.test f2974a91d79f58507ada01864c0e323093065452 F test/speed1p.explain d841e650a04728b39e6740296b852dccdca9b2cb @@ -1051,12 +1051,12 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/speedtest1.c f8bf04214e7b5f745feea99f7bde68b1c4870666 -F test/spellfix.test 0597065ff57042df1f138e6a2611ae19c2698135 +F test/spellfix.test f9c1f431e2c096c8775fec032952320c0e4700db F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test f7bf7b3482971473d32b6b00f6944c5c066cff97 F test/sqldiff1.test 8f6bc7c6a5b3585d350d779c6078869ba402f8f5 F test/sqllimits1.test a74ee2a3740b9f9c2437c246d8fb77354862a142 -F test/sqllog.test a8faa2df39610a037dd372ed872d124260d32953 +F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/stat.test acc91e80517fff447ae8adcfd953cfdaa5efc0af F test/statfault.test f525a7bf633e50afd027700e9a486090684b1ac1 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 @@ -1125,14 +1125,14 @@ F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5 F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223 F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67 -F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395 +F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 F test/tkt-a8a0d2996a.test eb597379dbcefa24765763d7f682c00cb5924fa9 F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 F test/tkt-b72787b1.test a95e8cdad0b98af1853ac7f0afd4ab27b77bf5f3 F test/tkt-b75a9ca6b0.test 97cc2d5eeaf82799eb42138c0a1ff64370238ce4 -F test/tkt-ba7cbfaedc.test e76d88e572e489ee0d64fe4caf4af18b3d1dc688 +F test/tkt-ba7cbfaedc.test b4c0deccc12aeb55cfdb57935b16b5d67c5a9877 F test/tkt-bd484a090c.test 60460bf946f79a79712b71f202eda501ca99b898 F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447 @@ -1252,7 +1252,7 @@ F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 -F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52 +F test/triggerE.test 15fa63f1097db1f83dd62d121616006978063d1f F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 @@ -1295,13 +1295,13 @@ F test/vtabH.test 5f5157a1501d9889ec35c1a1832f69612dd31444 F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8 -F test/vtab_shared.test ea8778d5b0df200adef2ca7c00c3c37d4375f772 +F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad F test/wal.test 0148c8b3421a25fdb4d9c160e84a681d0646371b F test/wal2.test 1f841d2048080d32f552942e333fd99ce541dada F test/wal3.test 5dd734147f1f8f958c5261a1f2775d346d7013ce F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c F test/wal5.test 88b5d9a6a3d1532497ee9f4296f010d66f07e33c -F test/wal6.test 4421cd5a2fa99d29cc91ef12fb23bed171ed3a4c +F test/wal6.test a9d6aa635b9d63607dabdc11406f5f96ca986635 F test/wal64k.test 163655ecd2cb8afef4737cac2a40fdd2eeaf20b8 F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd F test/wal8.test 75c42e1bc4545c277fed212f8fc9b7723cd02216 @@ -1318,7 +1318,7 @@ F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483 F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/waloverwrite.test a0d2ae0783187374c1e6a9571e0916152977cb81 +F test/waloverwrite.test dad2f26567f1b45174e54fbf9a8dc1cb876a7f03 F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 F test/walprotocol.test 059cb75484a1ecf6357a2c1b3324b8156749221e F test/walro.test 34422d1d95aaff0388f0791ec20edb34e2a3ed57 @@ -1342,7 +1342,7 @@ F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test dde4c52a97385a55be6a7cd46be8373f0cf35501 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 -F test/whereI.test 1d89199697919d4930be05a71e7fe620f114e622 +F test/whereI.test eab5b226bbc344ac70d7dc09b963a064860ae6d7 F test/whereJ.test 55a3221706a7ab706293f17cc8f96da563bf0767 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864 @@ -1354,7 +1354,7 @@ F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/with1.test cef099a491eac9874f2c28bd2dc86394fb3e47b3 F test/with2.test 2b40da883658eb74ad8ad06afabe11a408e7fb87 F test/with3.test 511bacdbe41c49cf34f9fd1bd3245fe1575bca98 -F test/withM.test e97f2a8c506ab3ea9eab94e6f6072f6cc924c991 +F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test 1a7b9bd51b899928d327052df9741d2fe8dbe701 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test aad4f9d383e199349b6c7e508a778f7dff5dff79 @@ -1426,8 +1426,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 fe123ab4f17f97ba9d64a7e0589ac47fd9d43877 0a802e96ab06e2643834b83671fa8353da1a348d -R 3749c59fe6fdfc59db76e85b115f2d1f -T +closed 0a802e96ab06e2643834b83671fa8353da1a348d +P b082538da774ac77f284fd7e22f9b1b9c2abc343 +R 2d1b67b182c9e99ebe80d7af9546dd2d U drh -Z 89e3d20f1d49685c430d339bf1d58063 +Z 796cfacaa9509982f1af1b696a2e58d2 diff --git a/manifest.uuid b/manifest.uuid index 96f1ef1f1f..e7a723dfc9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b082538da774ac77f284fd7e22f9b1b9c2abc343 \ No newline at end of file +a6b35273239669189f33402144f58328b133d182 \ No newline at end of file diff --git a/test/analyze9.test b/test/analyze9.test index 1ebd69c8d1..e24f3dd49d 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -1244,6 +1244,3 @@ do_eqp_test 26.2.2 { finish_test - - - diff --git a/test/analyzeB.test b/test/analyzeB.test index 2a78c18b3d..e91e7d585e 100644 --- a/test/analyzeB.test +++ b/test/analyzeB.test @@ -680,4 +680,3 @@ for {set i 0} {$i<16} {incr i} { } finish_test - diff --git a/test/analyzeD.test b/test/analyzeD.test index 4d46be6c64..7ef1094f82 100644 --- a/test/analyzeD.test +++ b/test/analyzeD.test @@ -114,4 +114,3 @@ do_eqp_test 1.8 { } finish_test - diff --git a/test/cacheflush.test b/test/cacheflush.test index 007ee8a065..50461893ef 100644 --- a/test/cacheflush.test +++ b/test/cacheflush.test @@ -321,4 +321,3 @@ do_test 4.5 { test_restore_config_pagecache finish_test - diff --git a/test/cffault.test b/test/cffault.test index a89477b617..79cefd24c4 100644 --- a/test/cffault.test +++ b/test/cffault.test @@ -156,4 +156,3 @@ do_faultsim_test 2.4 -prep { } finish_test - diff --git a/test/corruptH.test b/test/corruptH.test index 5c83cb3b90..0e1a1d4429 100644 --- a/test/corruptH.test +++ b/test/corruptH.test @@ -174,4 +174,3 @@ do_test 3.3 { } {1 {database disk image is malformed}} finish_test - diff --git a/test/corruptI.test b/test/corruptI.test index 64323d9608..9f46efb744 100644 --- a/test/corruptI.test +++ b/test/corruptI.test @@ -206,7 +206,6 @@ do_test 6.1 { db close hexio_write test.db 616 8FFFFFFF7F02 sqlite3 db test.db - breakpoint execsql { DELETE FROM t1 WHERE rowid=2 } } {} diff --git a/test/cost.test b/test/cost.test index 92fff9c888..9c10d821d9 100644 --- a/test/cost.test +++ b/test/cost.test @@ -287,6 +287,3 @@ ifcapable stat4 { } finish_test - - - diff --git a/test/e_blobbytes.test b/test/e_blobbytes.test index a6283ab852..d38f56bf34 100644 --- a/test/e_blobbytes.test +++ b/test/e_blobbytes.test @@ -72,5 +72,3 @@ do_test 2.1 { sqlite3_blob_close $B finish_test - - diff --git a/test/e_blobclose.test b/test/e_blobclose.test index a5d432d3b5..2683197854 100644 --- a/test/e_blobclose.test +++ b/test/e_blobclose.test @@ -168,4 +168,3 @@ do_execsql_test 3.5 { do_test 4.0 { sqlite3_blob_close 0 } {} finish_test - diff --git a/test/e_blobopen.test b/test/e_blobopen.test index 01f62cdd78..a6168042e9 100644 --- a/test/e_blobopen.test +++ b/test/e_blobopen.test @@ -546,4 +546,3 @@ do_test 13.5 { finish_test - diff --git a/test/e_blobwrite.test b/test/e_blobwrite.test index a0d33336de..7b2249c243 100644 --- a/test/e_blobwrite.test +++ b/test/e_blobwrite.test @@ -201,4 +201,3 @@ do_execsql_test 3.2.4 { finish_test - diff --git a/test/e_walckpt.test b/test/e_walckpt.test index e022f840cf..3b1f3b015a 100644 --- a/test/e_walckpt.test +++ b/test/e_walckpt.test @@ -751,4 +751,3 @@ do_test 6.5 { finish_test - diff --git a/test/fkey8.test b/test/fkey8.test index 60bb8e4640..b4b6bb75e7 100644 --- a/test/fkey8.test +++ b/test/fkey8.test @@ -103,4 +103,3 @@ foreach {tn use_stmt sql schema} { finish_test - diff --git a/test/fordelete.test b/test/fordelete.test index bc38a4c5e3..9a382d97f5 100644 --- a/test/fordelete.test +++ b/test/fordelete.test @@ -207,4 +207,3 @@ do_execsql_test 5.3 { finish_test - diff --git a/test/fts3conf.test b/test/fts3conf.test index e157c239ef..f9698770cc 100644 --- a/test/fts3conf.test +++ b/test/fts3conf.test @@ -212,4 +212,3 @@ do_execsql_test 4.2.2 { } {} finish_test - diff --git a/test/fts3expr4.test b/test/fts3expr4.test index 4bc62030d5..9fc22c1172 100644 --- a/test/fts3expr4.test +++ b/test/fts3expr4.test @@ -79,4 +79,3 @@ do_icu_expr_test 3.9 { "ab*c" } { PHRASE 3 0 ab+ * c } do_icu_expr_test 3.10 { ab*c } { AND {PHRASE 3 0 ab+} {PHRASE 3 0 c}} finish_test - diff --git a/test/fts3join.test b/test/fts3join.test index 64363639db..0fb8c62022 100644 --- a/test/fts3join.test +++ b/test/fts3join.test @@ -62,5 +62,3 @@ do_catchsql_test 2.5 { } {1 {unable to use function MATCH in the requested context}} finish_test - - diff --git a/test/fts3matchinfo.test b/test/fts3matchinfo.test index b17d7da0a5..8cbcd69041 100644 --- a/test/fts3matchinfo.test +++ b/test/fts3matchinfo.test @@ -524,7 +524,6 @@ foreach {tn expr res} { do_execsql_test 11.1.$tn.2 { SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr } $r2 - breakpoint do_execsql_test 11.1.$tn.2 { SELECT rowid, mit(matchinfo(tt, 'b')) FROM tt WHERE tt MATCH $expr @@ -552,4 +551,3 @@ do_execsql_test 12.1 { set sqlite_fts3_enable_parentheses 0 finish_test - diff --git a/test/fts3offsets.test b/test/fts3offsets.test index 184321ac01..4a1e63aa4c 100644 --- a/test/fts3offsets.test +++ b/test/fts3offsets.test @@ -121,4 +121,3 @@ do_execsql_test 1.4.1 { set sqlite_fts3_enable_parentheses 0 finish_test - diff --git a/test/fts3snippet.test b/test/fts3snippet.test index 4e1d123b2f..887011cd11 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -559,4 +559,3 @@ do_test 4.2 { set sqlite_fts3_enable_parentheses 0 finish_test - diff --git a/test/fts4check.test b/test/fts4check.test index 4ded053871..1e2f6b234f 100644 --- a/test/fts4check.test +++ b/test/fts4check.test @@ -210,4 +210,3 @@ do_execsql_test 5.4 { } {} finish_test - diff --git a/test/fts4content.test b/test/fts4content.test index 5a91987867..67642b6b8a 100644 --- a/test/fts4content.test +++ b/test/fts4content.test @@ -636,4 +636,3 @@ do_catchsql_test 11.1 { finish_test - diff --git a/test/fts4growth.test b/test/fts4growth.test index aa5f251f95..e4b5f19ecb 100644 --- a/test/fts4growth.test +++ b/test/fts4growth.test @@ -434,4 +434,3 @@ do_execsql_test 7.7 { finish_test - diff --git a/test/fts4growth2.test b/test/fts4growth2.test index af41d51c18..bcccf89c87 100644 --- a/test/fts4growth2.test +++ b/test/fts4growth2.test @@ -90,4 +90,3 @@ for {set tn 0} {$tn < 40} {incr tn} { finish_test - diff --git a/test/fts4noti.test b/test/fts4noti.test index c90999b4fa..6707203970 100644 --- a/test/fts4noti.test +++ b/test/fts4noti.test @@ -228,6 +228,3 @@ do_execsql_test 6.3.1 { } {0 1 1 0 1 1} finish_test - - - diff --git a/test/fts4onepass.test b/test/fts4onepass.test index d290980dc9..46cb4b794b 100644 --- a/test/fts4onepass.test +++ b/test/fts4onepass.test @@ -144,4 +144,3 @@ foreach {tn tcl1 tcl2} { } finish_test - diff --git a/test/fuzz3.test b/test/fuzz3.test index b432671822..6d2a01c7d3 100644 --- a/test/fuzz3.test +++ b/test/fuzz3.test @@ -173,4 +173,3 @@ for {set ii 0} {$ii < 5000} {incr ii} { test_restore_config_pagecache finish_test - diff --git a/test/incrcorrupt.test b/test/incrcorrupt.test index eda65e4035..2ea68c8c7c 100644 --- a/test/incrcorrupt.test +++ b/test/incrcorrupt.test @@ -124,4 +124,3 @@ do_test 2.16 { sqlite3_errcode db } {SQLITE_CORRUPT} do_test 2.17 { sqlite3_errmsg db } {database disk image is malformed} finish_test - diff --git a/test/mallocK.test b/test/mallocK.test index 65791e79ea..45ee7905c3 100644 --- a/test/mallocK.test +++ b/test/mallocK.test @@ -172,4 +172,3 @@ do_faultsim_test 8 -faults oom* -body { finish_test - diff --git a/test/mallocL.test b/test/mallocL.test index 6532ca5e14..5c2a4ec0b0 100644 --- a/test/mallocL.test +++ b/test/mallocL.test @@ -40,4 +40,3 @@ for {set j 1} {$j < 40} {incr j} { finish_test - diff --git a/test/ovfl.test b/test/ovfl.test index 075b1e43dd..4be7568546 100644 --- a/test/ovfl.test +++ b/test/ovfl.test @@ -45,5 +45,3 @@ do_execsql_test 1.2 { } [expr 2000 * 2000] finish_test - - diff --git a/test/pragma2.test b/test/pragma2.test index a4fb2ce657..5896e52687 100644 --- a/test/pragma2.test +++ b/test/pragma2.test @@ -255,7 +255,6 @@ db close forcedelete test.db sqlite3 db test.db -breakpoint do_execsql_test pragma2-5.1 { PRAGMA page_size=16384; CREATE TABLE t1(x); diff --git a/test/rollback2.test b/test/rollback2.test index 4d42dda5d6..3ba0f3f9fd 100644 --- a/test/rollback2.test +++ b/test/rollback2.test @@ -154,4 +154,3 @@ do_rollback_test 4.4 -setup { } finish_test - diff --git a/test/rollbackfault.test b/test/rollbackfault.test index f248d0758d..4d060b43c8 100644 --- a/test/rollbackfault.test +++ b/test/rollbackfault.test @@ -80,5 +80,3 @@ foreach f {oom ioerr} { finish_test - - diff --git a/test/select7.test b/test/select7.test index 9ed5357748..0df84e13d9 100644 --- a/test/select7.test +++ b/test/select7.test @@ -220,5 +220,3 @@ do_catchsql_test 8.2 { finish_test - - diff --git a/test/shared3.test b/test/shared3.test index acc86d2a07..1d09b69b82 100644 --- a/test/shared3.test +++ b/test/shared3.test @@ -139,4 +139,3 @@ do_test 3.5 { sqlite3_enable_shared_cache $::enable_shared_cache finish_test - diff --git a/test/snapshot.test b/test/snapshot.test index 6e160166c3..63a0e30175 100644 --- a/test/snapshot.test +++ b/test/snapshot.test @@ -55,7 +55,6 @@ do_execsql_test 2.1.0 { SELECT * FROM t1; } {1 2 3 4 5 6 7 8} -breakpoint do_test 2.1.1 { set snapshot [sqlite3_snapshot_get db main] execsql { diff --git a/test/sort3.test b/test/sort3.test index 3aa6512a4b..088ae1642d 100644 --- a/test/sort3.test +++ b/test/sort3.test @@ -111,4 +111,3 @@ do_execsql_test 3 { } finish_test - diff --git a/test/sort5.test b/test/sort5.test index a02b8f920f..5b1292bb48 100644 --- a/test/sort5.test +++ b/test/sort5.test @@ -42,4 +42,3 @@ do_execsql_test 1.2 { db close tvfs delete finish_test - diff --git a/test/spellfix.test b/test/spellfix.test index b47001ebd7..8128bb59d2 100644 --- a/test/spellfix.test +++ b/test/spellfix.test @@ -403,4 +403,3 @@ foreach {tn conflict err bRollback res} { } finish_test - diff --git a/test/sqllog.test b/test/sqllog.test index dca5781dbd..53d8d871d8 100644 --- a/test/sqllog.test +++ b/test/sqllog.test @@ -110,7 +110,4 @@ unset ::env(SQLITE_SQLLOG_DIR) unset ::env(SQLITE_SQLLOG_CONDITIONAL) sqlite3_config_sqllog sqlite3_initialize -breakpoint finish_test - - diff --git a/test/tkt-9f2eb3abac.test b/test/tkt-9f2eb3abac.test index 5b93733afe..8411654cdd 100644 --- a/test/tkt-9f2eb3abac.test +++ b/test/tkt-9f2eb3abac.test @@ -76,4 +76,3 @@ do_faultsim_test 3 -faults oom* -prep { } finish_test - diff --git a/test/tkt-ba7cbfaedc.test b/test/tkt-ba7cbfaedc.test index a558d4cec3..f83f8a3d17 100644 --- a/test/tkt-ba7cbfaedc.test +++ b/test/tkt-ba7cbfaedc.test @@ -61,5 +61,3 @@ do_execsql_test 2.0 { } finish_test - - diff --git a/test/triggerE.test b/test/triggerE.test index e2727bbdcb..a82ac9d2a5 100644 --- a/test/triggerE.test +++ b/test/triggerE.test @@ -108,5 +108,3 @@ do_execsql_test 2.3 { } {1 2 x y z z} finish_test - - diff --git a/test/vtab_shared.test b/test/vtab_shared.test index 3473992900..a9079eac04 100644 --- a/test/vtab_shared.test +++ b/test/vtab_shared.test @@ -276,4 +276,3 @@ ifcapable fts3 { sqlite3_enable_shared_cache 0 finish_test - diff --git a/test/wal6.test b/test/wal6.test index d96166ef59..2574a64a84 100644 --- a/test/wal6.test +++ b/test/wal6.test @@ -236,4 +236,3 @@ do_test 4.4.2 { finish_test - diff --git a/test/waloverwrite.test b/test/waloverwrite.test index aa1154fb97..ff8bc5ab55 100644 --- a/test/waloverwrite.test +++ b/test/waloverwrite.test @@ -131,7 +131,6 @@ foreach {tn xtra} { execsql { UPDATE t1 SET y = randomblob(797) WHERE x=$x } } } - breakpoint execsql {ROLLBACK TO abc} } @@ -161,4 +160,3 @@ foreach {tn xtra} { } finish_test - diff --git a/test/whereI.test b/test/whereI.test index 452e7f8f19..29b08549be 100644 --- a/test/whereI.test +++ b/test/whereI.test @@ -89,4 +89,3 @@ do_execsql_test 3.0 { } finish_test - diff --git a/test/withM.test b/test/withM.test index c1650d9576..78b757f422 100644 --- a/test/withM.test +++ b/test/withM.test @@ -72,6 +72,3 @@ do_faultsim_test withM-1.3 -prep { } finish_test - - - From 1cd0f054921f7fd552bf8711abbf31ba88c6908c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 5 Feb 2016 17:49:43 +0000 Subject: [PATCH 091/107] Make sure the "bak.db" database file does not actually exist before starting the "quota.test" testing. FossilOrigin-Name: 1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/quota.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ca42763a5e..35ca92466b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C From\stest\sscripts,\sremove\sstray\s"breakpoint"\scommands\sand\sblank\slines\nat\sthe\sends\sof\sfiles. -D 2016-02-05T16:46:09.824 +C Make\ssure\sthe\s"bak.db"\sdatabase\sfile\sdoes\snot\sactually\sexist\sbefore\nstarting\sthe\s"quota.test"\stesting. +D 2016-02-05T17:49:43.402 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -955,7 +955,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 -F test/quota.test 2379902c25e291eac5c12b4cf96946a3447e3744 +F test/quota.test 36cd78b178c4eb0401d4f25754ef410fbd9df2a7 F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 @@ -1426,7 +1426,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 b082538da774ac77f284fd7e22f9b1b9c2abc343 -R 2d1b67b182c9e99ebe80d7af9546dd2d +P a6b35273239669189f33402144f58328b133d182 +R a53abbe37c3df437dd159edcdce10b4b U drh -Z 796cfacaa9509982f1af1b696a2e58d2 +Z b28b558e8ce57b27d1473527e7eaafc5 diff --git a/manifest.uuid b/manifest.uuid index e7a723dfc9..25bc3f5bbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a6b35273239669189f33402144f58328b133d182 \ No newline at end of file +1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd \ No newline at end of file diff --git a/test/quota.test b/test/quota.test index f9655fb8c0..7af55a8330 100644 --- a/test/quota.test +++ b/test/quota.test @@ -21,6 +21,7 @@ ifcapable !curdir { source $testdir/malloc_common.tcl +forcedelete bak.db unset -nocomplain defaultVfs set defaultVfs [file_control_vfsname db] db close From b80b8f482c5ef4fe0159db8931995e191f52c95a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 5 Feb 2016 19:18:02 +0000 Subject: [PATCH 092/107] Further streamlining of fts5 prefix query code. FossilOrigin-Name: ca91bd8ac70a5b3fef127364f73ec675e58bb92c --- ext/fts5/fts5Int.h | 1 + ext/fts5/fts5_buffer.c | 62 ++++++++++++++++++++++------------- ext/fts5/fts5_index.c | 55 ++++++++++++++++++++++--------- ext/fts5/fts5_main.c | 3 +- ext/fts5/test/fts5ad.test | 2 ++ ext/fts5/test/fts5detail.test | 4 +++ manifest | 24 +++++++------- manifest.uuid | 2 +- 8 files changed, 101 insertions(+), 52 deletions(-) diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index fc71584909..6318af900f 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -282,6 +282,7 @@ struct Fts5PoslistWriter { i64 iPrev; }; int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64); +void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64); int sqlite3Fts5PoslistNext64( const u8 *a, int n, /* Buffer containing poslist */ diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index d69adf7d24..878240af4f 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -16,18 +16,20 @@ #include "fts5Int.h" int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ - u32 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; + if( pBuf->nSpacenSpace ? pBuf->nSpace : 64; + u8 *pNew; + while( nNewp, nNew); + if( pNew==0 ){ + *pRc = SQLITE_NOMEM; + return 1; + }else{ + pBuf->nSpace = nNew; + pBuf->p = pNew; + } } return 0; } @@ -208,23 +210,37 @@ int sqlite3Fts5PoslistReaderInit( return pIter->bEof; } +/* +** Append position iPos to the position list being accumulated in buffer +** pBuf, which must be already be large enough to hold the new data. +** The previous position written to this list is *piPrev. *piPrev is set +** to iPos before returning. +*/ +void sqlite3Fts5PoslistSafeAppend( + Fts5Buffer *pBuf, + i64 *piPrev, + i64 iPos +){ + static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; + if( (iPos & colmask) != (*piPrev & colmask) ){ + pBuf->p[pBuf->n++] = 1; + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); + *piPrev = (iPos & colmask); + } + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); + *piPrev = iPos; +} + int sqlite3Fts5PoslistWriterAppend( Fts5Buffer *pBuf, Fts5PoslistWriter *pWriter, i64 iPos ){ static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; - int rc = SQLITE_OK; - 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)); - pWriter->iPrev = (iPos & colmask); - } - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-pWriter->iPrev)+2); - pWriter->iPrev = iPos; - } - return rc; + int rc; + if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc; + sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos); + return SQLITE_OK; } void *sqlite3Fts5MallocZero(int *pRc, int nByte){ diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 0461f3a778..3dd9a9c92d 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4704,6 +4704,7 @@ static void fts5MergePrefixLists( Fts5Buffer *p1, /* First list to merge */ Fts5Buffer *p2 /* Second list to merge */ ){ + if( p2->n ){ if( p1->n==0 ){ fts5BufferSwap(p1, p2); @@ -4719,7 +4720,6 @@ static void fts5MergePrefixLists( fts5DoclistIterInit(p2, &i2); while( 1 ){ - if( i1.iRowidrc, &tmp, i1.nPoslist + i2.nPoslist); + if( p->rc ) break; sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); + assert( iPos1>=0 && iPos2>=0 ); - while( iPos1>=0 || iPos2>=0 ){ - i64 iNew; - if( iPos2<0 || (iPos1>=0 && iPos1=0 && iPos2>=0 ){ + while( 1 ){ + if( iPos1rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew); - if( p->rc ) goto error_out; + } + + if( iPos1>=0 ){ + if( iPos1!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); } + fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1); + } + else if( iPos2>=0 ){ + if( iPos2!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); + } + fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2); } /* WRITEPOSLISTSIZE */ @@ -4936,7 +4961,7 @@ int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){ int sqlite3Fts5IndexRollback(Fts5Index *p){ fts5CloseReader(p); fts5IndexDiscardData(p); - assert( p->rc==SQLITE_OK ); + /* assert( p->rc==SQLITE_OK ); */ return SQLITE_OK; } diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 9ef8d9a01a..4b798314c0 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -803,7 +803,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ */ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; - int rc = SQLITE_OK; + int rc; assert( (pCsr->ePlan<3)== (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) @@ -820,6 +820,7 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ switch( pCsr->ePlan ){ case FTS5_PLAN_SPECIAL: { CsrFlagSet(pCsr, FTS5CSR_EOF); + rc = SQLITE_OK; break; } diff --git a/ext/fts5/test/fts5ad.test b/ext/fts5/test/fts5ad.test index c6b09d8121..974aa781aa 100644 --- a/ext/fts5/test/fts5ad.test +++ b/ext/fts5/test/fts5ad.test @@ -11,6 +11,8 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing the FTS5 module. # +# More specifically, the focus is on testing prefix queries, both with and +# without prefix indexes. # source [file join [file dirname [info script]] fts5_common.tcl] diff --git a/ext/fts5/test/fts5detail.test b/ext/fts5/test/fts5detail.test index 5bdd14424e..58fda3e995 100644 --- a/ext/fts5/test/fts5detail.test +++ b/ext/fts5/test/fts5detail.test @@ -85,6 +85,10 @@ do_execsql_test 2.2 { SELECT fts5_test_poslist(t2) FROM t2('aa'); } {0.0.0} +do_execsql_test 2.3 { + SELECT fts5_test_collist(t2) FROM t2('aa'); +} {0.0} + set ::pc 0 #puts [nearset {{ax bx cx}} -pc ::pc -near 10 -- b*] #exit diff --git a/manifest b/manifest index 35ca92466b..76600b8190 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\s"bak.db"\sdatabase\sfile\sdoes\snot\sactually\sexist\sbefore\nstarting\sthe\s"quota.test"\stesting. -D 2016-02-05T17:49:43.402 +C Further\sstreamlining\sof\sfts5\sprefix\squery\scode. +D 2016-02-05T19:18:02.811 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -98,14 +98,14 @@ 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 ff9c2782e8ed890b0de2f697a8d63971939e70c7 -F ext/fts5/fts5Int.h 2095cc38e776f19cc083ca90e00772ea0b204ab3 +F ext/fts5/fts5Int.h efb02807dbe5a2bfb0ea592a472d1171cb553d53 F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d -F ext/fts5/fts5_buffer.c f6e0c6018ffc8e39fc0b333b5daa8b8d528ae6e4 +F ext/fts5/fts5_buffer.c ad4bb545c866eea6add1b0f84c2c5029cd689092 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 614c54544f844387ba6728c613a884a1aa151f06 -F ext/fts5/fts5_main.c 7e8a5f27d504bc04e3de7f1cba8867f0332aee9d +F ext/fts5/fts5_index.c 9706959f2188d97d72df750519fee7baccef9964 +F ext/fts5/fts5_main.c 6e23df904049edb498538bd3e22e53ec1ab6f4f7 F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 @@ -120,7 +120,7 @@ F ext/fts5/test/fts5_common.tcl 61ff0d1a29d98a91c4553b20b3f410d858834ee9 F ext/fts5/test/fts5aa.test 7e814df4a0e6c22a6fe2d84f210fdc0b5068a084 F ext/fts5/test/fts5ab.test 30325a89453280160106be411bba3acf138e6d1b F ext/fts5/test/fts5ac.test 55cad4275a1f5acabfe14d8442a8046b47e49e5f -F ext/fts5/test/fts5ad.test 0ddaa5b692ff220100ee396228838f4331399eaa +F ext/fts5/test/fts5ad.test 36995f0586f30f5602074e012b9224c71ec5171c F ext/fts5/test/fts5ae.test 612dcb51f4069226791ff14c17dbfb3138c56f20 F ext/fts5/test/fts5af.test be858a96b1f5de66ba6d64f0021bd8b2408e126c F ext/fts5/test/fts5ag.test 27180de76c03036be75ee80b93d8c5f540014071 @@ -142,7 +142,7 @@ F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 F ext/fts5/test/fts5corrupt2.test 26c0a39dd9ff73207e6229f83b50b21d37c7658c F ext/fts5/test/fts5corrupt3.test a2b537c120bdd43c79c42fe2438d7b8c81fe5599 -F ext/fts5/test/fts5detail.test 4e971d28e7336c61ab916fc287900355dab7054d +F ext/fts5/test/fts5detail.test ef5c690535a797413acaf5ad9b8ab5d49972df69 F ext/fts5/test/fts5dlidx.test 13871a14641017ae42f6f1055a8067bafd44cb3d F ext/fts5/test/fts5doclist.test 8edb5b57e5f144030ed74ec00ef6fa4294fed79b F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 @@ -1426,7 +1426,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 a6b35273239669189f33402144f58328b133d182 -R a53abbe37c3df437dd159edcdce10b4b -U drh -Z b28b558e8ce57b27d1473527e7eaafc5 +P 1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd +R 82ed27d217d52be944f2d4bee3dfe639 +U dan +Z ad1bc1867d7f59ff72d365283a40efbf diff --git a/manifest.uuid b/manifest.uuid index 25bc3f5bbc..8902cb7ad9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd \ No newline at end of file +ca91bd8ac70a5b3fef127364f73ec675e58bb92c \ No newline at end of file From a6f28893ed0066a06f03b2ea3f54a31582558ea2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 5 Feb 2016 19:40:23 +0000 Subject: [PATCH 093/107] More work on Windows 10 SDK integration. FossilOrigin-Name: ebace2c99b6af9230c4bbc31a764c7f397200148 --- Makefile.msc | 24 ++++++++++++++++++++++-- manifest | 17 ++++++++++------- manifest.uuid | 2 +- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 3427b8177a..a507825a20 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -356,6 +356,16 @@ NSDKLIBPATH = $(WINDOWSSDKDIR)\lib NSDKLIBPATH = $(NSDKLIBPATH:\\=\) +# Check for the UCRT library path macro. Othertise, this value will +# default to the version-specific, platform-specific 'lib' directory +# underneath the Windows SDK installation directory. +# +!IFNDEF UCRTLIBPATH +UCRTLIBPATH = $(WINDOWSSDKDIR)\lib\$(WINDOWSSDKLIBVERSION)\ucrt\$(PLATFORM) +!ENDIF + +UCRTLIBPATH = $(UCRTLIBPATH:\\=\) + # C compiler and options for use in building executables that # will run on the platform that is doing the build. # @@ -541,7 +551,7 @@ BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE # USE_CRT_DLL option is set to force dynamically linking to the # MSVC runtime library. # -!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0 +!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0 !IF $(DEBUG)>1 TCC = $(TCC) -MDd BCC = $(BCC) -MDd @@ -888,7 +898,8 @@ LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelH LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib !ENDIF -# When compiling for UAP, some extra linker options are also required. +# When compiling for UAP or the Windows 10 platform, some extra +# linker options are also required. # !IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0 LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib @@ -898,6 +909,15 @@ LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)" !ENDIF !ENDIF +!IF $(FOR_WIN10)!=0 +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(UCRTLIBPATH)" +!IF $(DEBUG)>1 +LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib +!ELSE +LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib +!ENDIF +!ENDIF + # If either debugging or symbols are enabled, enable PDBs. # !IF $(DEBUG)>1 || $(SYMBOLS)!=0 diff --git a/manifest b/manifest index 76600b8190..c8a0a95df0 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Further\sstreamlining\sof\sfts5\sprefix\squery\scode. -D 2016-02-05T19:18:02.811 +C More\swork\son\sWindows\s10\sSDK\sintegration. +D 2016-02-05T19:40:23.877 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 +F Makefile.msc 9eadde083c1ef0d0d2a253671c76e0b7e48a3dc6 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1426,7 +1426,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 1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd -R 82ed27d217d52be944f2d4bee3dfe639 -U dan -Z ad1bc1867d7f59ff72d365283a40efbf +P ca91bd8ac70a5b3fef127364f73ec675e58bb92c +R 1ddcbe680d5a6ea9a1dc01ec422c820c +T *branch * win10sdk +T *sym-win10sdk * +T -sym-trunk * +U mistachkin +Z 9a5014635472c911640e985821bf4dea diff --git a/manifest.uuid b/manifest.uuid index 8902cb7ad9..bf7c81653a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca91bd8ac70a5b3fef127364f73ec675e58bb92c \ No newline at end of file +ebace2c99b6af9230c4bbc31a764c7f397200148 \ No newline at end of file From d120a1e3ab9763ba9c39e08d2b4e6f5f2cfbf346 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 5 Feb 2016 21:09:26 +0000 Subject: [PATCH 094/107] Add tests for and remove unreachable branches from fts5 in order to restore test coverage. FossilOrigin-Name: 22589018ac3321f7bd89ce9fa69e57eae395e324 --- ext/fts5/fts5_buffer.c | 1 - ext/fts5/fts5_index.c | 213 ++++++++++++++++------------------ ext/fts5/fts5_varint.c | 3 + ext/fts5/test/fts5config.test | 4 + manifest | 18 +-- manifest.uuid | 2 +- 6 files changed, 117 insertions(+), 124 deletions(-) diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 878240af4f..c3d4101b8b 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -236,7 +236,6 @@ int sqlite3Fts5PoslistWriterAppend( Fts5PoslistWriter *pWriter, i64 iPos ){ - static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; int rc; if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc; sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos); diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3dd9a9c92d..12e18c6445 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -518,7 +518,6 @@ struct Fts5Iter { int nSeg; /* Size of aSeg[] array */ int bRev; /* True to iterate in reverse order */ u8 bSkipEmpty; /* True to skip deleted entries */ - u8 bFiltered; /* True if column-filter already applied */ i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */ Fts5CResult *aFirst; /* Current merge state (see above) */ @@ -2030,9 +2029,6 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ iPoslist = 4; } fts5IndexSkipVarint(pLeaf->p, iPoslist); - assert( p->pConfig->eDetail==FTS5_DETAIL_NONE || iPoslist==( - pIter->iLeafOffset - sqlite3Fts5GetVarintLen(pIter->nPos*2+pIter->bDel) - )); pIter->iLeafOffset = iPoslist; /* If this condition is true then the largest rowid for the current @@ -3095,7 +3091,7 @@ static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){ pIter->base.nData = pSeg->nPos; assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE ); - assert( pIter->pColset==0 || pIter->bFiltered ); + assert( pIter->pColset==0 ); if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){ /* All data is stored on the current page. Populate the output @@ -3212,7 +3208,7 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ pIter->xSetOutputs = fts5IterSetOutputs_None; } - else if( pIter->pColset==0 || pIter->bFiltered ){ + else if( pIter->pColset==0 ){ pIter->xSetOutputs = fts5IterSetOutputs_Nocolset; } @@ -3359,7 +3355,6 @@ static void fts5MultiIterNew2( if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; - pNew->bFiltered = 1; pIter->flags = FTS5_SEGITER_ONETERM; if( pData->szLeaf>0 ){ pIter->pLeaf = pData; @@ -4704,120 +4699,111 @@ static void fts5MergePrefixLists( Fts5Buffer *p1, /* First list to merge */ Fts5Buffer *p2 /* Second list to merge */ ){ - if( p2->n ){ - if( p1->n==0 ){ - fts5BufferSwap(p1, p2); - }else{ - i64 iLastRowid = 0; - Fts5DoclistIter i1; - Fts5DoclistIter i2; - Fts5Buffer out = {0, 0, 0}; - Fts5Buffer tmp = {0, 0, 0}; + i64 iLastRowid = 0; + Fts5DoclistIter i1; + Fts5DoclistIter i2; + Fts5Buffer out = {0, 0, 0}; + Fts5Buffer tmp = {0, 0, 0}; - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return; - fts5DoclistIterInit(p1, &i1); - fts5DoclistIterInit(p2, &i2); + if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return; + fts5DoclistIterInit(p1, &i1); + fts5DoclistIterInit(p2, &i2); - while( 1 ){ - if( i1.iRowidrc, &tmp, i1.nPoslist + i2.nPoslist); - if( p->rc ) break; - - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert( iPos1>=0 && iPos2>=0 ); - - if( iPos1=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1=0 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1); - } - else if( iPos2>=0 ){ - if( iPos2!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - } - fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2); - } - - /* WRITEPOSLISTSIZE */ - fts5BufferSafeAppendVarint(&out, tmp.n * 2); - fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); - fts5DoclistIterNext(&i1); - fts5DoclistIterNext(&i2); - if( i1.aPoslist==0 || i2.aPoslist==0 ) break; - } - } - - if( i1.aPoslist ){ + while( 1 ){ + if( i1.iRowidrc, p1, out.n, out.p); - fts5BufferFree(&tmp); - fts5BufferFree(&out); + i64 iPrev = 0; + Fts5PoslistWriter writer; + memset(&writer, 0, sizeof(writer)); + + fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); + fts5BufferZero(&tmp); + sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist); + if( p->rc ) break; + + sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); + sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); + assert( iPos1>=0 && iPos2>=0 ); + + if( iPos1=0 && iPos2>=0 ){ + while( 1 ){ + if( iPos1=0 ){ + if( iPos1!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); + } + fts5BufferSafeAppendBlob(&tmp, &a1[iOff1], i1.nPoslist-iOff1); + }else{ + assert( iPos2>=0 && iPos2!=iPrev ); + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); + fts5BufferSafeAppendBlob(&tmp, &a2[iOff2], i2.nPoslist-iOff2); + } + + /* WRITEPOSLISTSIZE */ + fts5BufferSafeAppendVarint(&out, tmp.n * 2); + fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); + fts5DoclistIterNext(&i1); + fts5DoclistIterNext(&i2); + if( i1.aPoslist==0 || i2.aPoslist==0 ) break; + } } + + if( i1.aPoslist ){ + fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); + fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); + } + else if( i2.aPoslist ){ + fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); + fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); + } + + fts5BufferSet(&p->rc, p1, out.n, out.p); + fts5BufferFree(&tmp); + fts5BufferFree(&out); } } @@ -5181,10 +5167,11 @@ int sqlite3Fts5IndexQuery( int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; buf.p[0] = FTS5_MAIN_PREFIX; fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); + assert( pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; - if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } diff --git a/ext/fts5/fts5_varint.c b/ext/fts5/fts5_varint.c index 21858506ac..bb212ab5a8 100644 --- a/ext/fts5/fts5_varint.c +++ b/ext/fts5/fts5_varint.c @@ -333,7 +333,10 @@ int sqlite3Fts5PutVarint(unsigned char *p, u64 v){ int sqlite3Fts5GetVarintLen(u32 iVal){ +#if 0 if( iVal<(1 << 7 ) ) return 1; +#endif + assert( iVal>=(1 << 7) ); if( iVal<(1 << 14) ) return 2; if( iVal<(1 << 21) ) return 3; if( iVal<(1 << 28) ) return 4; diff --git a/ext/fts5/test/fts5config.test b/ext/fts5/test/fts5config.test index 223e504a65..c30a597242 100644 --- a/ext/fts5/test/fts5config.test +++ b/ext/fts5/test/fts5config.test @@ -243,5 +243,9 @@ foreach {tn opt} { do_catchsql_test 11.$tn "CREATE VIRTUAL TABLE f1 USING fts5(x, $opt)" $res } +do_catchsql_test 12.1 { + INSERT INTO t1(t1, rank) VALUES('rank', NULL);; +} {1 {SQL logic error or missing database}} + finish_test diff --git a/manifest b/manifest index 76600b8190..15c459f19f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sstreamlining\sof\sfts5\sprefix\squery\scode. -D 2016-02-05T19:18:02.811 +C Add\stests\sfor\sand\sremove\sunreachable\sbranches\sfrom\sfts5\sin\sorder\sto\srestore\stest\scoverage. +D 2016-02-05T21:09:26.310 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -100,11 +100,11 @@ F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7 F ext/fts5/fts5Int.h efb02807dbe5a2bfb0ea592a472d1171cb553d53 F ext/fts5/fts5_aux.c b9bcce753ef5b451267b2232f0ca153ddeb3951d -F ext/fts5/fts5_buffer.c ad4bb545c866eea6add1b0f84c2c5029cd689092 +F ext/fts5/fts5_buffer.c 2dac8e23c5b77fccecc234f1a1f37d75113b4e46 F ext/fts5/fts5_config.c 0c384ebdd23fd055e2e50a93277b8d59da538238 F ext/fts5/fts5_expr.c ff5c451a6d025909639ac0f0d0af0cc595b50feb F ext/fts5/fts5_hash.c 1b113977296cf4212c6ec667d5e3f2bd18036955 -F ext/fts5/fts5_index.c 9706959f2188d97d72df750519fee7baccef9964 +F ext/fts5/fts5_index.c 28f72130400cb54d179a9a120b7232915e3e7a4e F ext/fts5/fts5_main.c 6e23df904049edb498538bd3e22e53ec1ab6f4f7 F ext/fts5/fts5_storage.c 2a1f44deae090cd711f02cec0c2af8e660360d24 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966 @@ -112,7 +112,7 @@ F ext/fts5/fts5_test_mi.c 1ec66ffdf7632077fbd773b7a6df5153272ec070 F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be F ext/fts5/fts5_tokenize.c 4d5c4f183c7d07d144bc219b92da1ea0e962fae3 F ext/fts5/fts5_unicode2.c 78273fbd588d1d9bd0a7e4e0ccc9207348bae33c -F ext/fts5/fts5_varint.c 3f86ce09cab152e3d45490d7586b7ed2e40c13f1 +F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738 F ext/fts5/fts5_vocab.c 3ef401a8d6932db56368de32f446eb9fe73aa623 F ext/fts5/fts5parse.y 1647eba089b9b3fc058b4dc989d9da87d15b9580 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba @@ -136,7 +136,7 @@ F ext/fts5/test/fts5auxdata.test 141a7cbffcceb1bd2799b4b29c183ff8780d586e F ext/fts5/test/fts5bigpl.test 04ee0d7eebbebf17c31f5a0b5c5f9494eac3a0cb F ext/fts5/test/fts5bigtok.test 981b2790f6fa02773c889bd35d42c6b97f80f0f4 F ext/fts5/test/fts5columnsize.test a8cfef21ffa1c264b9f670a7d94eeaccb5341c07 -F ext/fts5/test/fts5config.test 83941309b94d002ed6f55d9cd814e0353c9ae013 +F ext/fts5/test/fts5config.test 8b2bc6dcc0eb06fa2b7dd65b2ce2db09e829e873 F ext/fts5/test/fts5conflict.test 26f4e46c4d31e16221794832a990dc4e30e18de5 F ext/fts5/test/fts5content.test 9a952c95518a14182dc3b59e3c8fa71cda82a4e1 F ext/fts5/test/fts5corrupt.test c2ad090192708150d50d961278df10ae7a4b8b62 @@ -1426,7 +1426,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 1cac6c45eeb7dbbcda0c76ba7d3a2ca77bc725cd -R 82ed27d217d52be944f2d4bee3dfe639 +P ca91bd8ac70a5b3fef127364f73ec675e58bb92c +R bc449da6b3e9fd24816f80d5ebb5f8a2 U dan -Z ad1bc1867d7f59ff72d365283a40efbf +Z 6b9788cdb90c1d425a4100a494ea3da5 diff --git a/manifest.uuid b/manifest.uuid index 8902cb7ad9..3643624eee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca91bd8ac70a5b3fef127364f73ec675e58bb92c \ No newline at end of file +22589018ac3321f7bd89ce9fa69e57eae395e324 \ No newline at end of file From bb3da060e3d90da84944b1d75df74ce7697d8998 Mon Sep 17 00:00:00 2001 From: pdr Date: Sat, 6 Feb 2016 14:14:43 +0000 Subject: [PATCH 095/107] Fix an assert() to have a test instead of a side effect FossilOrigin-Name: a2952231ac7abe165ed070875728f752ae0be608 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 15c459f19f..d6e074a0b5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sand\sremove\sunreachable\sbranches\sfrom\sfts5\sin\sorder\sto\srestore\stest\scoverage. -D 2016-02-05T21:09:26.310 +C Fix\san\sassert()\sto\shave\sa\stest\sinstead\sof\sa\sside\seffect +D 2016-02-06T14:14:43.463 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -284,7 +284,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c e4a5132e6264e002ab87c268108f416df3f1fb10 +F src/alter.c d50b7dbb49a4affee951301afb76a008463e3625 F src/analyze.c fbf0e80d83cc893734e872f932f249a056b86e11 F src/attach.c c16c2648a577fa3def2adfa48c28901376389bc5 F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 @@ -1426,7 +1426,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 ca91bd8ac70a5b3fef127364f73ec675e58bb92c -R bc449da6b3e9fd24816f80d5ebb5f8a2 -U dan -Z 6b9788cdb90c1d425a4100a494ea3da5 +P 22589018ac3321f7bd89ce9fa69e57eae395e324 +R e3d82b169cbfebcfd4c4fb1447b3dcc4 +U pdr +Z 6e44ca05901e086eb71b8481afaf44d8 diff --git a/manifest.uuid b/manifest.uuid index 3643624eee..4f51f901e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22589018ac3321f7bd89ce9fa69e57eae395e324 \ No newline at end of file +a2952231ac7abe165ed070875728f752ae0be608 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 3419059fa2..34ca8abd2c 100644 --- a/src/alter.c +++ b/src/alter.c @@ -695,7 +695,7 @@ void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ - assert( db->mallocFailed = 1 ); + assert( db->mallocFailed == 1 ); return; } if( !pVal ){ From f5818aa560fc463e241bbeeaefba8cfacdd0131f Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Feb 2016 19:48:50 +0000 Subject: [PATCH 096/107] Make sure variable declarations occur at the beginning of blocks, even with SQLITE_DEBUG enabled. FossilOrigin-Name: 2f7778e64d93ef237e23ceac01ea9808df5cf2a1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/malloc.c | 7 +++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d6e074a0b5..098cff6d3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sto\shave\sa\stest\sinstead\sof\sa\sside\seffect -D 2016-02-06T14:14:43.463 +C Make\ssure\svariable\sdeclarations\soccur\sat\sthe\sbeginning\sof\sblocks,\seven\nwith\sSQLITE_DEBUG\senabled. +D 2016-02-06T19:48:50.321 F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 @@ -314,7 +314,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 -F src/malloc.c 55ebb1701ebd39985dbcc497aaecb09192b69682 +F src/malloc.c 337e9808b5231855fe28857950f4f60ae42c417f F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 @@ -1426,7 +1426,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 22589018ac3321f7bd89ce9fa69e57eae395e324 -R e3d82b169cbfebcfd4c4fb1447b3dcc4 -U pdr -Z 6e44ca05901e086eb71b8481afaf44d8 +P a2952231ac7abe165ed070875728f752ae0be608 +R da8a8c4dec6af3be8a6f4cff524d4f5f +U drh +Z f3b1e3c58e3e9ab1cb32cfa377da1181 diff --git a/manifest.uuid b/manifest.uuid index 4f51f901e5..c92bb840b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2952231ac7abe165ed070875728f752ae0be608 \ No newline at end of file +2f7778e64d93ef237e23ceac01ea9808df5cf2a1 \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 1ff0a5221d..ebe0440350 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -626,11 +626,11 @@ void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ return p; } void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ +#ifndef SQLITE_OMIT_LOOKASIDE + LookasideSlot *pBuf; assert( db!=0 ); assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); -#ifndef SQLITE_OMIT_LOOKASIDE - LookasideSlot *pBuf; if( db->lookaside.bDisable==0 ){ assert( db->mallocFailed==0 ); if( n>db->lookaside.sz ){ @@ -650,6 +650,9 @@ void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ return 0; } #else + assert( db!=0 ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( db->pnBytesFreed==0 ); if( db->mallocFailed ){ return 0; } From cc5f8a46b975d5afb86bfbe2da2ee7f2d85d7572 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 6 Feb 2016 22:32:06 +0000 Subject: [PATCH 097/107] Add a utility program that looks for assert(), NEVER(), ALWAYS(), and testcase() macros that have side-effects, and reports errors when they are found. Also fix a bug that this utility detected as it was being tested. FossilOrigin-Name: b0b4624fc5d53bb0cc9fae7dad51984837d946ac --- Makefile.in | 8 ++- main.mk | 8 ++- manifest | 19 +++--- manifest.uuid | 2 +- src/btree.c | 15 +++-- src/main.c | 2 +- tool/srcck1.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 192 insertions(+), 19 deletions(-) create mode 100644 tool/srcck1.c diff --git a/Makefile.in b/Makefile.in index a07279c3c9..f0c78a4ee7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -583,6 +583,12 @@ sqlite3$(TEXE): $(TOP)/src/shell.c libsqlite3.la sqlite3.h sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) +srcck1$(BEXE): $(TOP)/tool/srcck1.c + $(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c + +sourcetest: srcck1$(BEXE) sqlite3.c + ./srcck1 sqlite3.c + fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) @@ -1083,7 +1089,7 @@ quicktest: ./testfixture$(TEXE) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: $(TESTPROGS) fastfuzztest +test: $(TESTPROGS) sourcetest fastfuzztest ./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS) # Run a test using valgrind. This can take a really long time diff --git a/main.mk b/main.mk index 1dda2d153f..f4cbbdbb95 100644 --- a/main.mk +++ b/main.mk @@ -480,6 +480,12 @@ sqldiff$(EXE): $(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h $(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB) +srcck1$(EXE): $(TOP)/tool/srcck1.c + $(BCC) -o srcck1$(EXE) $(TOP)/tool/srcck1.c + +sourcetest: srcck1$(EXE) sqlite3.c + ./srcck1 sqlite3.c + fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \ @@ -768,7 +774,7 @@ quicktest: ./testfixture$(EXE) # The default test case. Runs most of the faster standard TCL tests, # and fuzz tests, and sqlite3_analyzer and sqldiff tests. # -test: $(TESTPROGS) fastfuzztest +test: $(TESTPROGS) sourcetest fastfuzztest ./testfixture$(EXE) $(TOP)/test/veryquick.test $(TESTOPTS) # Run a test using valgrind. This can take a really long time diff --git a/manifest b/manifest index 098cff6d3a..9220387b53 100644 --- a/manifest +++ b/manifest @@ -1,6 +1,6 @@ -C Make\ssure\svariable\sdeclarations\soccur\sat\sthe\sbeginning\sof\sblocks,\seven\nwith\sSQLITE_DEBUG\senabled. -D 2016-02-06T19:48:50.321 -F Makefile.in 027c1603f255390c43a426671055a31c0a65fdb4 +C Add\sa\sutility\sprogram\sthat\slooks\sfor\sassert(),\sNEVER(),\sALWAYS(),\sand\ntestcase()\smacros\sthat\shave\sside-effects,\sand\sreports\serrors\swhen\sthey\sare\nfound.\s\sAlso\sfix\sa\sbug\sthat\sthis\sutility\sdetected\sas\sit\swas\sbeing\stested. +D 2016-02-06T22:32:06.228 +F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 @@ -272,7 +272,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 960071a0bceb043bc5627573986154f507931f33 +F main.mk f51c0652d2a623160e90a758e01312a6a00f3454 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -291,7 +291,7 @@ F src/auth.c b56c78ebe40a2110fd361379f7e8162d23f92240 F src/backup.c 2869a76c03eb393ee795416e2387005553df72bc F src/bitvec.c 1a78d450a17c5016710eec900bedfc5729bf9bdf F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 -F src/btree.c 0b359bcc2316a57acf12f583253974ad22b4654f +F src/btree.c 4c8caaeed7878aafdb607c3d2bcbc365bb0d19a1 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 F src/build.c 198eaa849c193f28b802ed135b2483c68ef7a35c @@ -313,7 +313,7 @@ F src/insert.c b84359365bace233919db550a15f131923190efc F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b -F src/main.c 62b7fe3ed245757d1ff2e6268a7ec0bc30100308 +F src/main.c b67a45397b93b7ba8fbd6bfcb03423d245baed05 F src/malloc.c 337e9808b5231855fe28857950f4f60ae42c417f F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c 6919bcf12f221868ea066eec27e579fed95ce98b @@ -1416,6 +1416,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/sqldiff.c 5a26205111e6fa856d9b1535b1637744dcdb930b +F tool/srcck1.c 3119733530abcef14f1b0603c66207a342936263 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f @@ -1426,7 +1427,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 a2952231ac7abe165ed070875728f752ae0be608 -R da8a8c4dec6af3be8a6f4cff524d4f5f +P 2f7778e64d93ef237e23ceac01ea9808df5cf2a1 +R e75f025e263d6165f7cd0bcd65f5ad12 U drh -Z f3b1e3c58e3e9ab1cb32cfa377da1181 +Z 663376736f9ceb33b8ce1b1cb94df97c diff --git a/manifest.uuid b/manifest.uuid index c92bb840b3..20460304dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2f7778e64d93ef237e23ceac01ea9808df5cf2a1 \ No newline at end of file +b0b4624fc5d53bb0cc9fae7dad51984837d946ac \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b99820ddbc..c6f9c34f7b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6148,7 +6148,7 @@ static int fillInCell( { CellInfo info; pPage->xParseCell(pPage, pCell, &info); - assert( nHeader=(int)(info.pPayload - pCell) ); + assert( nHeader==(int)(info.pPayload - pCell) ); assert( info.nKey==nKey ); assert( *pnSize == info.nSize ); assert( spaceLeft == info.nLocal ); @@ -7807,8 +7807,8 @@ static int balance(BtCursor *pCur){ u8 aBalanceQuickSpace[13]; u8 *pFree = 0; - TESTONLY( int balance_quick_called = 0 ); - TESTONLY( int balance_deeper_called = 0 ); + VVA_ONLY( int balance_quick_called = 0 ); + VVA_ONLY( int balance_deeper_called = 0 ); do { int iPage = pCur->iPage; @@ -7821,7 +7821,8 @@ static int balance(BtCursor *pCur){ ** and copy the current contents of the root-page to it. The ** next iteration of the do-loop will balance the child page. */ - assert( (balance_deeper_called++)==0 ); + assert( balance_deeper_called==0 ); + VVA_ONLY( balance_deeper_called++ ); rc = balance_deeper(pPage, &pCur->apPage[1]); if( rc==SQLITE_OK ){ pCur->iPage = 1; @@ -7860,7 +7861,8 @@ static int balance(BtCursor *pCur){ ** function. If this were not verified, a subtle bug involving reuse ** of the aBalanceQuickSpace[] might sneak in. */ - assert( (balance_quick_called++)==0 ); + assert( balance_quick_called==0 ); + VVA_ONLY( balance_quick_called++ ); rc = balance_quick(pParent, pPage, aBalanceQuickSpace); }else #endif @@ -9327,7 +9329,8 @@ char *sqlite3BtreeIntegrityCheck( sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); - assert( (nRef = sqlite3PagerRefcount(pBt->pPager))>=0 ); + VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); + assert( nRef>=0 ); sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = btreePagecount(sCheck.pBt); diff --git a/src/main.c b/src/main.c index 588461b48a..922af1315a 100644 --- a/src/main.c +++ b/src/main.c @@ -3566,7 +3566,7 @@ int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_ASSERT: { volatile int x = 0; - assert( (x = va_arg(ap,int))!=0 ); + assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); rc = x; break; } diff --git a/tool/srcck1.c b/tool/srcck1.c new file mode 100644 index 0000000000..cd4b4990b9 --- /dev/null +++ b/tool/srcck1.c @@ -0,0 +1,157 @@ +/* +** The program does some simple static analysis of the sqlite3.c source +** file looking for mistakes. +** +** Usage: +** +** ./srcck1 sqlite3.c +** +** This program looks for instances of assert(), ALWAYS(), NEVER() or +** testcase() that contain side-effects and reports errors if any such +** instances are found. +** +** The aim of this utility is to prevent recurrences of errors such +** as the one fixed at: +** +** https://www.sqlite.org/src/info/a2952231ac7abe16 +** +** Note that another similar error was found by this utility when it was +** first written. That other error was fixed by the same check-in that +** committed the first version of this utility program. +*/ +#include +#include +#include + +/* Read the complete text of a file into memory. Return a pointer to +** the result. Panic if unable to read the file or allocate memory. +*/ +static char *readFile(const char *zFilename){ + FILE *in; + char *z; + long n; + size_t got; + + in = fopen(zFilename, "rb"); + if( in==0 ){ + fprintf(stderr, "unable to open '%s' for reading\n", zFilename); + exit(1); + } + fseek(in, 0, SEEK_END); + n = ftell(in); + rewind(in); + z = malloc( n+1 ); + if( z==0 ){ + fprintf(stderr, "cannot allocate %d bytes to store '%s'\n", + (int)(n+1), zFilename); + exit(1); + } + got = fread(z, 1, n, in); + fclose(in); + if( got!=(size_t)n ){ + fprintf(stderr, "only read %d of %d bytes from '%s'\n", + (int)got, (int)n, zFilename); + exit(1); + } + z[n] = 0; + return z; +} + +/* Change the C code in the argument to see if it might have +** side effects. The only accurate way to know this is to do a full +** parse of the C code, which this routine does not do. This routine +** uses a simple heuristic of looking for: +** +** * '=' not immediately after '>', '<', '!', or '='. +** * '++' +** * '--' +** +** If the code contains the phrase "side-effects-ok" is inside a +** comment, then always return false. This is used to disable checking +** for assert()s with deliberate side-effects, such as used by +** SQLITE_TESTCTRL_ASSERT - a facility that allows applications to +** determine at runtime whether or not assert()s are enabled. +** Obviously, that determination cannot be made unless the assert() +** has some side-effect. +** +** Return true if a side effect is seen. Return false if not. +*/ +static int hasSideEffect(const char *z, unsigned int n){ + unsigned int i; + for(i=0; i0 && z[i-1]!='=' && z[i-1]!='>' + && z[i-1]!='<' && z[i-1]!='!' && z[i+1]!='=' ) return 1; + if( z[i]=='+' && z[i+1]=='+' ) return 1; + if( z[i]=='-' && z[i+1]=='-' ) return 1; + } + return 0; +} + +/* Return the number of bytes in string z[] prior to the first unmatched ')' +** character. +*/ +static unsigned int findCloseParen(const char *z){ + unsigned int nOpen = 0; + unsigned i; + for(i=0; z[i]; i++){ + if( z[i]=='(' ) nOpen++; + if( z[i]==')' ){ + if( nOpen==0 ) break; + nOpen--; + } + } + return i; +} + +/* Search for instances of assert(...), ALWAYS(...), NEVER(...), and/or +** testcase(...) where the argument contains side effects. +** +** Print error messages whenever a side effect is found. Return the number +** of problems seen. +*/ +static unsigned int findAllSideEffects(const char *z){ + unsigned int lineno = 1; /* Line number */ + unsigned int i; + unsigned int nErr = 0; + char c, prevC = 0; + for(i=0; (c = z[i])!=0; prevC=c, i++){ + if( c=='\n' ){ lineno++; continue; } + if( isalpha(c) && !isalpha(prevC) ){ + if( strncmp(&z[i],"assert(",7)==0 + || strncmp(&z[i],"ALWAYS(",7)==0 + || strncmp(&z[i],"NEVER(",6)==0 + || strncmp(&z[i],"testcase(",9)==0 + ){ + unsigned int j, n; + const char *z2 = &z[i+5]; + while( z2[0]!='(' ){ z2++; } + z2++; + n = findCloseParen(z2); + if( hasSideEffect(z2, n) ){ + nErr++; + fprintf(stderr, "side-effect line %u: %.*s\n", lineno, + (int)(&z2[n+1] - &z[i]), &z[i]); + } + } + } + } + return nErr; +} + +int main(int argc, char **argv){ + char *z; + unsigned int nErr = 0; + if( argc!=2 ){ + fprintf(stderr, "Usage: %s FILENAME\n", argv[0]); + return 1; + } + z = readFile(argv[1]); + nErr = findAllSideEffects(z); + free(z); + if( nErr ){ + fprintf(stderr, "Found %u undesirable side-effects\n", nErr); + return 1; + } + return 0; +} From fd0d93fd71b2c9f1f889bb2e2022a1119a2b52bd Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 7 Feb 2016 00:08:08 +0000 Subject: [PATCH 098/107] Add the sourcetest target to Makefile.msc. FossilOrigin-Name: ab269e720552483c5617906837e294c1be3e0a57 --- Makefile.msc | 10 ++++++++-- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/srcck1.c | 1 + 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 3427b8177a..0ba00d89c7 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1393,6 +1393,12 @@ $(SQLITE3EXE): $(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_S sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +srcck1.exe: $(TOP)\tool\srcck1.c + $(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c + +sourcetest: srcck1.exe sqlite3.c + srcck1.exe sqlite3.c + fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1916,14 +1922,14 @@ fastfuzztest: fuzzcheck.exe # Minimal testing that runs in less than 3 minutes (on a fast machine) # -quicktest: testfixture.exe +quicktest: testfixture.exe sourcetest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\extraquick.test $(TESTOPTS) # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: $(TESTPROGS) fastfuzztest +test: $(TESTPROGS) sourcetest fastfuzztest @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS) diff --git a/manifest b/manifest index 9220387b53..3a81b43628 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sa\sutility\sprogram\sthat\slooks\sfor\sassert(),\sNEVER(),\sALWAYS(),\sand\ntestcase()\smacros\sthat\shave\sside-effects,\sand\sreports\serrors\swhen\sthey\sare\nfound.\s\sAlso\sfix\sa\sbug\sthat\sthis\sutility\sdetected\sas\sit\swas\sbeing\stested. -D 2016-02-06T22:32:06.228 +C Add\sthe\ssourcetest\starget\sto\sMakefile.msc. +D 2016-02-07T00:08:08.480 F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 72b7858f02017611c3ac1ddc965251017fed0845 +F Makefile.msc a3f8092763bb5d0057f0f4feb6b7fcc19713e107 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -1416,7 +1416,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/sqldiff.c 5a26205111e6fa856d9b1535b1637744dcdb930b -F tool/srcck1.c 3119733530abcef14f1b0603c66207a342936263 +F tool/srcck1.c 0522865656ed7f89a8acdcfa6ba2d4f898f4e55c F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f @@ -1427,7 +1427,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 2f7778e64d93ef237e23ceac01ea9808df5cf2a1 -R e75f025e263d6165f7cd0bcd65f5ad12 +P b0b4624fc5d53bb0cc9fae7dad51984837d946ac +R 08c9d9815def36a9ada11c24d7dc13cb U drh -Z 663376736f9ceb33b8ce1b1cb94df97c +Z 21cfff4994071e02bdb1eef8143a0ef4 diff --git a/manifest.uuid b/manifest.uuid index 20460304dd..16127e2758 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0b4624fc5d53bb0cc9fae7dad51984837d946ac \ No newline at end of file +ab269e720552483c5617906837e294c1be3e0a57 \ No newline at end of file diff --git a/tool/srcck1.c b/tool/srcck1.c index cd4b4990b9..ae19fbebaa 100644 --- a/tool/srcck1.c +++ b/tool/srcck1.c @@ -22,6 +22,7 @@ #include #include #include +#include /* Read the complete text of a file into memory. Return a pointer to ** the result. Panic if unable to read the file or allocate memory. From 27b6997e9cec6ef3a27e54925db1e377a2903e75 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 7 Feb 2016 20:39:27 +0000 Subject: [PATCH 099/107] Fix harmless compiler warning in 'srcck1' tool and add it to the clean targets. FossilOrigin-Name: 852a529a8b112049f67a3126f677c06ae4a22d73 --- Makefile.in | 1 + Makefile.msc | 2 +- main.mk | 1 + manifest | 20 ++++++++++---------- manifest.uuid | 2 +- tool/srcck1.c | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Makefile.in b/Makefile.in index f0c78a4ee7..54f7643327 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1225,6 +1225,7 @@ clean: rm -f sqlite-*-output.vsix rm -f mptester mptester.exe rm -f rbu rbu.exe + rm -f srcck1 srcck1.exe rm -f fuzzershell fuzzershell.exe rm -f fuzzcheck fuzzcheck.exe rm -f sqldiff sqldiff.exe diff --git a/Makefile.msc b/Makefile.msc index 0ba00d89c7..aacacbcec3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -2016,7 +2016,7 @@ clean: del /Q testfixture.exe test.db 2>NUL del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL - del /Q mptester.exe wordcount.exe rbu.exe 2>NUL + del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL del /Q $(SQLITE3EXE) $(SQLITE3DLL) sqlite3.def 2>NUL del /Q sqlite3.c sqlite3-*.c 2>NUL del /Q sqlite3rc.h 2>NUL diff --git a/main.mk b/main.mk index f4cbbdbb95..149f94e209 100644 --- a/main.mk +++ b/main.mk @@ -899,6 +899,7 @@ clean: rm -f speedtest1 speedtest1.exe rm -f wordcount wordcount.exe rm -f rbu rbu.exe + rm -f srcck1 srcck1.exe rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c rm -f sqlite3rc.h rm -f shell.c sqlite3ext.h diff --git a/manifest b/manifest index 3a81b43628..dbd577f123 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Add\sthe\ssourcetest\starget\sto\sMakefile.msc. -D 2016-02-07T00:08:08.480 -F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 +C Fix\sharmless\scompiler\swarning\sin\s'srcck1'\stool\sand\sadd\sit\sto\sthe\sclean\stargets. +D 2016-02-07T20:39:27.144 +F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc a3f8092763bb5d0057f0f4feb6b7fcc19713e107 +F Makefile.msc fcf377286d910b47e072da1ac7945976337c0925 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -272,7 +272,7 @@ F ext/userauth/userauth.c 5fa3bdb492f481bbc1709fc83c91ebd13460c69e F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk f51c0652d2a623160e90a758e01312a6a00f3454 +F main.mk 37497b06d3e3acb2c71675d76627a3b2639c6db0 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1416,7 +1416,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c F tool/sqldiff.c 5a26205111e6fa856d9b1535b1637744dcdb930b -F tool/srcck1.c 0522865656ed7f89a8acdcfa6ba2d4f898f4e55c +F tool/srcck1.c 4c39bdfa9a92edd20233ee720df84dbeb2417602 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f @@ -1427,7 +1427,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 b0b4624fc5d53bb0cc9fae7dad51984837d946ac -R 08c9d9815def36a9ada11c24d7dc13cb -U drh -Z 21cfff4994071e02bdb1eef8143a0ef4 +P ab269e720552483c5617906837e294c1be3e0a57 +R b0244c1b9f3d2cf89729e9f132d42a5e +U mistachkin +Z 9a8eb772a0a9cfffcb8487b60e9945a2 diff --git a/manifest.uuid b/manifest.uuid index 16127e2758..3f741fdf8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab269e720552483c5617906837e294c1be3e0a57 \ No newline at end of file +852a529a8b112049f67a3126f677c06ae4a22d73 \ No newline at end of file diff --git a/tool/srcck1.c b/tool/srcck1.c index ae19fbebaa..e95765185f 100644 --- a/tool/srcck1.c +++ b/tool/srcck1.c @@ -124,7 +124,7 @@ static unsigned int findAllSideEffects(const char *z){ || strncmp(&z[i],"NEVER(",6)==0 || strncmp(&z[i],"testcase(",9)==0 ){ - unsigned int j, n; + unsigned int n; const char *z2 = &z[i+5]; while( z2[0]!='(' ){ z2++; } z2++; From 8974331fc35a22b48ccf1ca2c709890646f10a3d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Feb 2016 02:30:50 +0000 Subject: [PATCH 100/107] Demonstrate a much faster sqlite3GetToken() routine by using a lookup table to map initial token characters into a character class. This check-in does not work for EBCDIC. More optimization needed. FossilOrigin-Name: 9115baa1919584dc8ca25bbff54d3b65748a9631 --- manifest | 15 +++--- manifest.uuid | 2 +- src/tokenize.c | 133 ++++++++++++++++++++++++++++++++++--------------- 3 files changed, 102 insertions(+), 48 deletions(-) diff --git a/manifest b/manifest index 3a81b43628..3badb22032 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssourcetest\starget\sto\sMakefile.msc. -D 2016-02-07T00:08:08.480 +C Demonstrate\sa\smuch\sfaster\ssqlite3GetToken()\sroutine\sby\susing\sa\slookup\stable\nto\smap\sinitial\stoken\scharacters\sinto\sa\scharacter\sclass.\s\sThis\scheck-in\sdoes\nnot\swork\sfor\sEBCDIC.\s\sMore\soptimization\sneeded. +D 2016-02-08T02:30:50.194 F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a3f8092763bb5d0057f0f4feb6b7fcc19713e107 @@ -406,7 +406,7 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 -F src/tokenize.c 214b783d6138e9f9fbb6b225ce9a376db3b03d42 +F src/tokenize.c b3cfc123d65a5bf7ba615f74f28737ae2135620a F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 310ca7adb86a7d1f2afae46905b21c83580f3e17 @@ -1427,7 +1427,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 b0b4624fc5d53bb0cc9fae7dad51984837d946ac -R 08c9d9815def36a9ada11c24d7dc13cb +P ab269e720552483c5617906837e294c1be3e0a57 +R de21eeb460827c84c88aec10967c3b1d +T *branch * tokenizer-char-class +T *sym-tokenizer-char-class * +T -sym-trunk * U drh -Z 21cfff4994071e02bdb1eef8143a0ef4 +Z 8982f608f7ca1f17154501e0dba47865 diff --git a/manifest.uuid b/manifest.uuid index 16127e2758..9b08cb07e9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab269e720552483c5617906837e294c1be3e0a57 \ No newline at end of file +9115baa1919584dc8ca25bbff54d3b65748a9631 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 5bee3d5a84..c4b36c4758 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -18,6 +18,56 @@ #include "sqliteInt.h" #include +/* Character classes for tokenizing */ +#define CC_X 0 /* The letter 'x' or 'X'. Start of x'01234fed' */ +#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ +#define CC_ID 2 /* unicode characters usable in IDs */ +#define CC_DIGIT 3 /* Digits */ +#define CC_DOLLAR 4 /* '$' */ +#define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ +#define CC_VARNUM 6 /* '?'. Numeric SQL variables */ +#define CC_SPACE 7 /* Space characters */ +#define CC_QUOTE 8 /* '"', '\'', or '`'. String literals, quoted ids */ +#define CC_QUOTE2 9 /* '['. [...] style quoted ids */ +#define CC_PIPE 10 /* '|'. Bitwise OR or concatenate */ +#define CC_MINUS 11 /* '-'. Minus or SQL-style comment */ +#define CC_LT 12 /* '<'. Part of < or <= or <> */ +#define CC_GT 13 /* '>'. Part of > or >= */ +#define CC_EQ 14 /* '='. Part of = or == */ +#define CC_BANG 15 /* '!'. Part of != */ +#define CC_SLASH 16 /* '/'. / or c-style comment */ +#define CC_LP 17 /* '(' */ +#define CC_RP 18 /* ')' */ +#define CC_SEMI 19 /* ';' */ +#define CC_PLUS 20 /* '+' */ +#define CC_STAR 21 /* '*' */ +#define CC_PERCENT 22 /* '%' */ +#define CC_COMMA 23 /* ',' */ +#define CC_AND 24 /* '&' */ +#define CC_TILDA 25 /* '~' */ +#define CC_DOT 26 /* '.' */ +#define CC_ILLEGAL 27 /* Illegal character */ + +static const unsigned char aiClass[] = { +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, +/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, +/* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, +/* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, +/* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, +/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +}; + /* ** The charMap() macro maps alphabetic characters into their ** lower-case ASCII equivalent. On ASCII machines, this is just @@ -115,8 +165,8 @@ int sqlite3IsIdChar(u8 c){ return IdChar(c); } */ int sqlite3GetToken(const unsigned char *z, int *tokenType){ int i, c; - switch( *z ){ - case ' ': case '\t': case '\n': case '\f': case '\r': { + switch( aiClass[*z] ){ + case CC_SPACE: { testcase( z[0]==' ' ); testcase( z[0]=='\t' ); testcase( z[0]=='\n' ); @@ -126,7 +176,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_SPACE; return i; } - case '-': { + case CC_MINUS: { if( z[1]=='-' ){ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ @@ -135,27 +185,27 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_MINUS; return 1; } - case '(': { + case CC_LP: { *tokenType = TK_LP; return 1; } - case ')': { + case CC_RP: { *tokenType = TK_RP; return 1; } - case ';': { + case CC_SEMI: { *tokenType = TK_SEMI; return 1; } - case '+': { + case CC_PLUS: { *tokenType = TK_PLUS; return 1; } - case '*': { + case CC_STAR: { *tokenType = TK_STAR; return 1; } - case '/': { + case CC_SLASH: { if( z[1]!='*' || z[2]==0 ){ *tokenType = TK_SLASH; return 1; @@ -165,15 +215,15 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; } - case '%': { + case CC_PERCENT: { *tokenType = TK_REM; return 1; } - case '=': { + case CC_EQ: { *tokenType = TK_EQ; return 1 + (z[1]=='='); } - case '<': { + case CC_LT: { if( (c=z[1])=='=' ){ *tokenType = TK_LE; return 2; @@ -188,7 +238,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return 1; } } - case '>': { + case CC_GT: { if( (c=z[1])=='=' ){ *tokenType = TK_GE; return 2; @@ -200,7 +250,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return 1; } } - case '!': { + case CC_BANG: { if( z[1]!='=' ){ *tokenType = TK_ILLEGAL; return 2; @@ -209,7 +259,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return 2; } } - case '|': { + case CC_PIPE: { if( z[1]!='|' ){ *tokenType = TK_BITOR; return 1; @@ -218,21 +268,19 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return 2; } } - case ',': { + case CC_COMMA: { *tokenType = TK_COMMA; return 1; } - case '&': { + case CC_AND: { *tokenType = TK_BITAND; return 1; } - case '~': { + case CC_TILDA: { *tokenType = TK_BITNOT; return 1; } - case '`': - case '\'': - case '"': { + case CC_QUOTE: { int delim = z[0]; testcase( delim=='`' ); testcase( delim=='\'' ); @@ -257,7 +305,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return i; } } - case '.': { + case CC_DOT: { #ifndef SQLITE_OMIT_FLOATING_POINT if( !sqlite3Isdigit(z[1]) ) #endif @@ -268,8 +316,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ /* If the next character is a digit, this is a floating point ** number that begins with ".". Fall thru into the next case */ } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { + case CC_DIGIT: { testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); @@ -304,22 +351,18 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ } return i; } - case '[': { + case CC_QUOTE2: { for(i=1, c=z[0]; c!=']' && (c=z[i])!=0; i++){} *tokenType = c==']' ? TK_ID : TK_ILLEGAL; return i; } - case '?': { + case CC_VARNUM: { *tokenType = TK_VARIABLE; for(i=1; sqlite3Isdigit(z[i]); i++){} return i; } -#ifndef SQLITE_OMIT_TCL_VARIABLE - case '$': -#endif - case '@': /* For compatibility with MS SQL Server */ - case '#': - case ':': { + case CC_DOLLAR: + case CC_VARALPHA: { int n = 0; testcase( z[0]=='$' ); testcase( z[0]=='@' ); testcase( z[0]==':' ); testcase( z[0]=='#' ); @@ -349,7 +392,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return i; } #ifndef SQLITE_OMIT_BLOB_LITERAL - case 'x': case 'X': { + case CC_X: { testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; @@ -361,20 +404,28 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( z[i] ) i++; return i; } - /* Otherwise fall through to the next case */ + i = 1; + break; } #endif - default: { - if( !IdChar(*z) ){ - break; - } - for(i=1; IdChar(z[i]); i++){} + case CC_KYWD: { + for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} + if( aiClass[z[i]]<=CC_DOLLAR ){ i++; break; } *tokenType = TK_ID; return keywordCode((char*)z, i, tokenType); } + case CC_ID: { + i = 1; + break; + } + default: { + *tokenType = TK_ILLEGAL; + return 1; + } } - *tokenType = TK_ILLEGAL; - return 1; + while( aiClass[z[i]]<=CC_DOLLAR ){ i++; } + *tokenType = TK_ID; + return i; } /* From 41aab89b3123f9b7ffcb59d3e57528c88d2f50eb Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Feb 2016 03:23:46 +0000 Subject: [PATCH 101/107] Faster keywordCode() implementation by taking advantage of the fact that the input is always pure ASCII alphabetic and underscore and that the keyword table is always upper-case. FossilOrigin-Name: ff406b9701ebe3a01834837f380641c6f0c495bc --- manifest | 15 ++++++--------- manifest.uuid | 2 +- tool/mkkeywordhash.c | 17 ++++++++++------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 3badb22032..a3d1184319 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Demonstrate\sa\smuch\sfaster\ssqlite3GetToken()\sroutine\sby\susing\sa\slookup\stable\nto\smap\sinitial\stoken\scharacters\sinto\sa\scharacter\sclass.\s\sThis\scheck-in\sdoes\nnot\swork\sfor\sEBCDIC.\s\sMore\soptimization\sneeded. -D 2016-02-08T02:30:50.194 +C Faster\skeywordCode()\simplementation\sby\staking\sadvantage\sof\sthe\sfact\sthat\nthe\sinput\sis\salways\spure\sASCII\salphabetic\sand\sunderscore\sand\sthat\sthe\skeyword\ntable\sis\salways\supper-case. +D 2016-02-08T03:23:46.173 F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a3f8092763bb5d0057f0f4feb6b7fcc19713e107 @@ -1383,7 +1383,7 @@ F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45 -F tool/mkkeywordhash.c 06ec0b78bd4fa68c12d90ef2bdfe76b039133ff8 +F tool/mkkeywordhash.c 4451824f4f68f8e8d89eba080e0c1a9cf83f7b62 F tool/mkmsvcmin.tcl d57e6efc9428605f5418d0b235721ddf7b5d9c0b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d @@ -1427,10 +1427,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 ab269e720552483c5617906837e294c1be3e0a57 -R de21eeb460827c84c88aec10967c3b1d -T *branch * tokenizer-char-class -T *sym-tokenizer-char-class * -T -sym-trunk * +P 9115baa1919584dc8ca25bbff54d3b65748a9631 +R b013689cd0826a67d194ddf9700064de U drh -Z 8982f608f7ca1f17154501e0dba47865 +Z b5dc027d5e497c867b371327464bbd96 diff --git a/manifest.uuid b/manifest.uuid index 9b08cb07e9..290fa630a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9115baa1919584dc8ca25bbff54d3b65748a9631 \ No newline at end of file +ff406b9701ebe3a01834837f380641c6f0c495bc \ No newline at end of file diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index 003ed7d66e..43455ef97c 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -565,20 +565,23 @@ int main(int argc, char **argv){ } printf("%s };\n", j==0 ? "" : "\n"); - printf(" int h, i;\n"); + printf(" int h, i, j;\n"); + printf(" const char *zKW;\n"); printf(" if( n>=2 ){\n"); printf(" h = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", bestSize); printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); - printf(" if( aLen[i]==n &&" - " sqlite3StrNICmp(&zText[aOffset[i]],z,n)==0 ){\n"); + printf(" if( aLen[i]!=n ) continue;\n"); + printf(" j = 0;\n"); + printf(" zKW = &zText[aOffset[i]];\n"); + printf(" while( j Date: Mon, 8 Feb 2016 19:15:48 +0000 Subject: [PATCH 102/107] Add code to get the tokenizer character-class logic working for EBCDIC. FossilOrigin-Name: 04f7da77c13925c1f1e287f4579bb85518297d81 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tokenize.c | 42 ++++++++++++++++++++++++++++++++++++------ tool/mkkeywordhash.c | 16 ++++++++++++---- 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index a3d1184319..180d6f2232 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\skeywordCode()\simplementation\sby\staking\sadvantage\sof\sthe\sfact\sthat\nthe\sinput\sis\salways\spure\sASCII\salphabetic\sand\sunderscore\sand\sthat\sthe\skeyword\ntable\sis\salways\supper-case. -D 2016-02-08T03:23:46.173 +C Add\scode\sto\sget\sthe\stokenizer\scharacter-class\slogic\sworking\sfor\sEBCDIC. +D 2016-02-08T19:15:48.295 F Makefile.in 0a957a57243a3d55e96b1514e22ffae5db9ea116 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a3f8092763bb5d0057f0f4feb6b7fcc19713e107 @@ -406,7 +406,7 @@ F src/test_windirent.c 8f5fada630348558d5745b334702f301da1ffc61 F src/test_windirent.h b12055cab6227f7be10f5c19296f67c60cc5e2a5 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c bbfb74450643cb5372a43ad4f6cffd7e9dfcecb0 -F src/tokenize.c b3cfc123d65a5bf7ba615f74f28737ae2135620a +F src/tokenize.c 5019666f8705e9f7135c6f1c1ffac95a1af76fa6 F src/treeview.c dc39ccf04e9331237388b9cb73289c9d87ea050b F src/trigger.c e14840ee0c3e549e758ec9bf3e4146e166002280 F src/update.c 310ca7adb86a7d1f2afae46905b21c83580f3e17 @@ -1383,7 +1383,7 @@ F tool/lempar.c 3ec1463a034b37d87d782be5f6b8b10a3b1ecbe7 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c eef612f8adf4d0993dafed0416064cf50d5d33c6 F tool/mkautoconfamal.sh a29b14d54302b33fd892958f6895582ea90e4a45 -F tool/mkkeywordhash.c 4451824f4f68f8e8d89eba080e0c1a9cf83f7b62 +F tool/mkkeywordhash.c f7f3b342211ac6a14258b9726d5b97cf4f548f22 F tool/mkmsvcmin.tcl d57e6efc9428605f5418d0b235721ddf7b5d9c0b F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 385c62d78c38b2d92146dcb5abd319dbbc33506d @@ -1427,7 +1427,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 9115baa1919584dc8ca25bbff54d3b65748a9631 -R b013689cd0826a67d194ddf9700064de +P ff406b9701ebe3a01834837f380641c6f0c495bc +R f322e625886c02a1fcd0df28b2c76f16 U drh -Z b5dc027d5e497c867b371327464bbd96 +Z 8351e730f91ff26fa5b93d74f8f175a3 diff --git a/manifest.uuid b/manifest.uuid index 290fa630a8..96aac98d14 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff406b9701ebe3a01834837f380641c6f0c495bc \ No newline at end of file +04f7da77c13925c1f1e287f4579bb85518297d81 \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index c4b36c4758..68e7b45172 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -18,7 +18,14 @@ #include "sqliteInt.h" #include -/* Character classes for tokenizing */ +/* Character classes for tokenizing +** +** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented +** using a lookup table, whereas a switch() directly on c uses a binary search. +** The lookup table is much faster. To maximize speed, and to ensure that +** a lookup table is used, all of the classes need to be small integers and +** all of them need to be used within the switch. +*/ #define CC_X 0 /* The letter 'x' or 'X'. Start of x'01234fed' */ #define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ #define CC_ID 2 /* unicode characters usable in IDs */ @@ -49,6 +56,7 @@ #define CC_ILLEGAL 27 /* Illegal character */ static const unsigned char aiClass[] = { +#ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ /* 0x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, /* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, @@ -66,14 +74,36 @@ static const unsigned char aiClass[] = { /* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +#endif +#ifdef SQLITE_EBCDIC +/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ +/* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, +/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 12, 17, 20, 10, +/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, +/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 7, +/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, +/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, +/* 9x */ 25, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, +/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, +/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, +/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, +/* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, +#endif }; /* -** The charMap() macro maps alphabetic characters into their +** The charMap() macro maps alphabetic characters (only) into their ** lower-case ASCII equivalent. On ASCII machines, this is just ** an upper-to-lower case map. On EBCDIC machines we also need -** to adjust the encoding. Only alphabetic characters and underscores -** need to be translated. +** to adjust the encoding. The mapping is only valid for alphabetics +** which are the only characters for which this feature is used. +** +** Used by keywordhash.h */ #ifdef SQLITE_ASCII # define charMap(X) sqlite3UpperToLower[(unsigned char)X] @@ -410,7 +440,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ #endif case CC_KYWD: { for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} - if( aiClass[z[i]]<=CC_DOLLAR ){ i++; break; } + if( IdChar(z[i]) ){ i++; break; } *tokenType = TK_ID; return keywordCode((char*)z, i, tokenType); } @@ -423,7 +453,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ return 1; } } - while( aiClass[z[i]]<=CC_DOLLAR ){ i++; } + while( IdChar(z[i]) ){ i++; } *tokenType = TK_ID; return i; } diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index 43455ef97c..7e5287ea54 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -277,7 +277,10 @@ static Keyword aKeywordTable[] = { /* Number of keywords */ static int nKeyword = (sizeof(aKeywordTable)/sizeof(aKeywordTable[0])); -/* Map all alphabetic characters into the same case */ +/* Map all alphabetic characters into lower-case for hashing. This is +** only valid for alphabetics. In particular it does not work for '_' +** and so the hash cannot be on a keyword position that might be an '_'. +*/ #define charMap(X) (0x20|(X)) /* @@ -565,16 +568,21 @@ int main(int argc, char **argv){ } printf("%s };\n", j==0 ? "" : "\n"); - printf(" int h, i, j;\n"); + printf(" int i, j;\n"); printf(" const char *zKW;\n"); printf(" if( n>=2 ){\n"); - printf(" h = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", + printf(" i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) %% %d;\n", bestSize); - printf(" for(i=((int)aHash[h])-1; i>=0; i=((int)aNext[i])-1){\n"); + printf(" for(i=((int)aHash[i])-1; i>=0; i=((int)aNext[i])-1){\n"); printf(" if( aLen[i]!=n ) continue;\n"); printf(" j = 0;\n"); printf(" zKW = &zText[aOffset[i]];\n"); + printf("#ifdef SQLITE_ASCII\n"); printf(" while( j Date: Mon, 8 Feb 2016 19:40:17 +0000 Subject: [PATCH 103/107] Disable the two-argument form of the fts3_tokenizer() SQL function unless the library is built with -DSQLITE_ENABLE_FTS3_TOKENIZER. FossilOrigin-Name: e0eb217aca7e4aadf9c44ed20822b78139f7c83c --- ext/fts3/fts3_tokenizer.c | 12 ++++- manifest | 21 ++++---- manifest.uuid | 2 +- src/test_config.c | 6 +++ test/fts3atoken.test | 110 ++++++++++++++++++++------------------ test/fts4langid.test | 46 ++++++++-------- 6 files changed, 111 insertions(+), 86 deletions(-) diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index 64cfe07aac..26bac57648 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -67,6 +67,7 @@ static void scalarFunc( nName = sqlite3_value_bytes(argv[0])+1; if( argc==2 ){ +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER void *pOld; int n = sqlite3_value_bytes(argv[1]); if( zName==0 || n!=sizeof(pPtr) ){ @@ -79,7 +80,14 @@ static void scalarFunc( sqlite3_result_error(context, "out of memory", -1); return; } - }else{ +#else + sqlite3_result_error(context, "fts3tokenize: " + "disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER", -1 + ); + return; +#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */ + }else + { if( zName ){ pPtr = sqlite3Fts3HashFind(pHash, zName, nName); } @@ -420,11 +428,13 @@ static void intTestFunc( assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); /* Test the storage function */ +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER rc = registerTokenizer(db, "nosuchtokenizer", p1); assert( rc==SQLITE_OK ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_OK ); assert( p2==p1 ); +#endif sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); } diff --git a/manifest b/manifest index 2902207223..2ad9b86f00 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\shelp\sthe\stokenizer\srun\sabout\s33%\sfaster. -D 2016-02-08T19:36:46.659 +C Disable\sthe\stwo-argument\sform\sof\sthe\sfts3_tokenizer()\sSQL\sfunction\sunless\sthe\slibrary\sis\sbuilt\swith\s-DSQLITE_ENABLE_FTS3_TOKENIZER. +D 2016-02-08T19:40:17.991 F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fcf377286d910b47e072da1ac7945976337c0925 @@ -83,7 +83,7 @@ F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7 F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038 F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 -F ext/fts3/fts3_tokenizer.c 50e7a69a549ac5882cc1971ee43f66aaabc11395 +F ext/fts3/fts3_tokenizer.c 0d3a77bbdc6f394d302f24980fa80667371c6e68 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145 @@ -372,7 +372,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 0dee90328e3dedf8ba002ee94b6a7e7ea7726fe4 +F src/test_config.c 7985332c806d1cece793475c75a6abcccde9d331 F src/test_demovfs.c 0de72c2c89551629f58486fde5734b7d90758852 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c a61f54247fdb843761d709879c3bcd1989b2050c @@ -697,7 +697,7 @@ F test/fts3al.test 07d64326e79bbdbab20ee87fc3328fbf01641c9f F test/fts3am.test 218aa6ba0dfc50c7c16b2022aac5c6be593d08d8 F test/fts3an.test a49ccadc07a2f7d646ec1b81bc09da2d85a85b18 F test/fts3ao.test 3e4e3d5e75c076520341d0bdf4eb17c00e8cbde2 -F test/fts3atoken.test e3a126365131a6db52efc20a9a6053cd44e5f289 +F test/fts3atoken.test 76262be798f23a390717d14266f0df551e52a7ee F test/fts3auto.test b981fea19b132b4e6878f50d7c1f369b28f68eb9 F test/fts3aux1.test f8f287a4a73f381f8fa15b6a70f36245f903d221 F test/fts3aux2.test 7ae2b2c13aefdf4169279a27a5f51780ce57f6ba @@ -744,7 +744,7 @@ F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4growth.test 60d6bb3f78e25b34f533797dd9f2f9402310a13a F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d -F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7 +F test/fts4langid.test 8bd8759e0d4b04d71771544b861193a6841fee84 F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 @@ -1427,8 +1427,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 852a529a8b112049f67a3126f677c06ae4a22d73 04f7da77c13925c1f1e287f4579bb85518297d81 -R 64edf86f87d772039cf70265114474cb -T +closed 04f7da77c13925c1f1e287f4579bb85518297d81 -U drh -Z feb6daf33d3b967be60d8c209f5e5987 +P a050e6f096d40aa5b6275797b96e62c228044f5a +R b09b6ba902e95153c88d724675282802 +U dan +Z a5b8919de2cf0c2997cac75a4e3c3a2c diff --git a/manifest.uuid b/manifest.uuid index dc1ddc7e40..fcaa3cc3b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a050e6f096d40aa5b6275797b96e62c228044f5a \ No newline at end of file +e0eb217aca7e4aadf9c44ed20822b78139f7c83c \ No newline at end of file diff --git a/src/test_config.c b/src/test_config.c index 30b421e00b..5db7117555 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -370,6 +370,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER + Tcl_SetVar2(interp, "sqlite_options", "fts3_tokenizer", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "fts3_tokenizer", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_ENABLE_FTS5 Tcl_SetVar2(interp, "sqlite_options", "fts5", "1", TCL_GLOBAL_ONLY); #else diff --git a/test/fts3atoken.test b/test/fts3atoken.test index 88e3d4f72b..2cdea79a98 100644 --- a/test/fts3atoken.test +++ b/test/fts3atoken.test @@ -24,7 +24,7 @@ ifcapable !fts3 { return } -set ::testprefix fts3token +set ::testprefix fts3atoken proc escape_string {str} { set out "" @@ -40,7 +40,7 @@ proc escape_string {str} { } #-------------------------------------------------------------------------- -# Test cases fts3token-1.* are the warm-body test for the SQL scalar +# Test cases fts3atoken-1.* are the warm-body test for the SQL scalar # function fts3_tokenizer(). The procedure is as follows: # # 1: Verify that there is no such fts3 tokenizer as 'blah'. @@ -56,62 +56,68 @@ proc escape_string {str} { # # 5: Test that the table created to use tokenizer 'blah' is usable. # -do_test fts3token-1.1 { - catchsql { - CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah); - } -} {1 {unknown tokenizer: blah}} -do_test fts3token-1.2 { - execsql { +ifcapable fts3_tokenizer { + do_test fts3atoken-1.1 { + catchsql { + CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah); + } + } {1 {unknown tokenizer: blah}} + do_test fts3atoken-1.2 { + execsql { + SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL; + } + } {0} + do_test fts3atoken-1.3 { + execsql { + SELECT fts3_tokenizer('blah') == fts3_tokenizer('simple'); + } + } {1} + do_test fts3atoken-1.4 { + catchsql { + CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah); + } + } {0 {}} + do_test fts3atoken-1.5 { + execsql { + INSERT INTO t1(content) VALUES('There was movement at the station'); + INSERT INTO t1(content) VALUES('For the word has passed around'); + INSERT INTO t1(content) VALUES('That the colt from ol regret had got'); + SELECT content FROM t1 WHERE content MATCH 'movement' + } + } {{There was movement at the station}} +} else { + do_catchsql_test 1.6 { SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL; - } -} {0} -do_test fts3token-1.3 { - execsql { - SELECT fts3_tokenizer('blah') == fts3_tokenizer('simple'); - } -} {1} -do_test fts3token-1.4 { - catchsql { - CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah); - } -} {0 {}} -do_test fts3token-1.5 { - execsql { - INSERT INTO t1(content) VALUES('There was movement at the station'); - INSERT INTO t1(content) VALUES('For the word has passed around'); - INSERT INTO t1(content) VALUES('That the colt from ol regret had got away'); - SELECT content FROM t1 WHERE content MATCH 'movement' - } -} {{There was movement at the station}} + } {1 {fts3tokenize: disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER}} +} #-------------------------------------------------------------------------- -# Test cases fts3token-2.* test error cases in the scalar function based +# Test cases fts3atoken-2.* test error cases in the scalar function based # API for getting and setting tokenizers. # -do_test fts3token-2.1 { +do_test fts3atoken-2.1 { catchsql { SELECT fts3_tokenizer('nosuchtokenizer'); } } {1 {unknown tokenizer: nosuchtokenizer}} #-------------------------------------------------------------------------- -# Test cases fts3token-3.* test the three built-in tokenizers with a +# Test cases fts3atoken-3.* test the three built-in tokenizers with a # simple input string via the built-in test function. This is as much # to test the test function as the tokenizer implementations. # -do_test fts3token-3.1 { +do_test fts3atoken-3.1 { execsql { SELECT fts3_tokenizer_test('simple', 'I don''t see how'); } } {{0 i I 1 don don 2 t t 3 see see 4 how how}} -do_test fts3token-3.2 { +do_test fts3atoken-3.2 { execsql { SELECT fts3_tokenizer_test('porter', 'I don''t see how'); } } {{0 i I 1 don don 2 t t 3 see see 4 how how}} ifcapable icu { - do_test fts3token-3.3 { + do_test fts3atoken-3.3 { execsql { SELECT fts3_tokenizer_test('icu', 'I don''t see how'); } @@ -119,7 +125,7 @@ ifcapable icu { } #-------------------------------------------------------------------------- -# Test cases fts3token-4.* test the ICU tokenizer. In practice, this +# Test cases fts3atoken-4.* test the ICU tokenizer. In practice, this # tokenizer only has two modes - "thai" and "everybody else". Some other # Asian languages (Lao, Khmer etc.) require the same special treatment as # Thai, but ICU doesn't support them yet. @@ -133,8 +139,8 @@ ifcapable icu { } $output } - do_icu_test fts3token-4.1 en_US {} {} - do_icu_test fts3token-4.2 en_US {Test cases fts3} [list \ + do_icu_test fts3atoken-4.1 en_US {} {} + do_icu_test fts3atoken-4.2 en_US {Test cases fts3} [list \ 0 test Test 1 cases cases 2 fts3 fts3 ] @@ -147,12 +153,12 @@ ifcapable icu { append output "1 \u0e19\u0e30 \u0e19\u0e30 " append output "2 \u0e04\u0e23\u0e31\u0e1a \u0e04\u0e23\u0e31\u0e1a" - do_icu_test fts3token-4.3 th_TH $input $output - do_icu_test fts3token-4.4 en_US $input $output + do_icu_test fts3atoken-4.3 th_TH $input $output + do_icu_test fts3atoken-4.4 en_US $input $output # ICU handles an unknown locale by falling back to the default. # So this is not an error. - do_icu_test fts3token-4.5 MiddleOfTheOcean $input $output + do_icu_test fts3atoken-4.5 MiddleOfTheOcean $input $output set longtoken "AReallyReallyLongTokenOneThatWillSurelyRequire" append longtoken "AReallocInTheIcuTokenizerCode" @@ -164,9 +170,9 @@ ifcapable icu { append output "2 then then " append output "3 [string tolower $longtoken] $longtoken" - do_icu_test fts3token-4.6 MiddleOfTheOcean $input $output - do_icu_test fts3token-4.7 th_TH $input $output - do_icu_test fts3token-4.8 en_US $input $output + do_icu_test fts3atoken-4.6 MiddleOfTheOcean $input $output + do_icu_test fts3atoken-4.7 th_TH $input $output + do_icu_test fts3atoken-4.8 en_US $input $output do_execsql_test 5.1 { CREATE VIRTUAL TABLE x1 USING fts3(name,TOKENIZE icu en_US); @@ -186,7 +192,7 @@ ifcapable icu { } {} } -do_test fts3token-internal { +do_test fts3atoken-internal { execsql { SELECT fts3_tokenizer_internal_test() } } {ok} @@ -206,12 +212,14 @@ do_catchsql_test 6.1.3 { do_catchsql_test 6.2.1 { SELECT fts3_tokenizer(NULL); } {1 {unknown tokenizer: }} -do_catchsql_test 6.2.2 { - SELECT fts3_tokenizer(NULL, X'1234567812345678'); -} {1 {argument type mismatch}} -do_catchsql_test 6.2.3 { - SELECT fts3_tokenizer(NULL, X'12345678'); -} {1 {argument type mismatch}} +ifcapable fts3_tokenizer { + do_catchsql_test 6.2.2 { + SELECT fts3_tokenizer(NULL, X'1234567812345678'); + } {1 {argument type mismatch}} + do_catchsql_test 6.2.3 { + SELECT fts3_tokenizer(NULL, X'12345678'); + } {1 {argument type mismatch}} +} finish_test diff --git a/test/fts4langid.test b/test/fts4langid.test index 843e11f9ab..a3059931e7 100644 --- a/test/fts4langid.test +++ b/test/fts4langid.test @@ -358,29 +358,31 @@ proc build_multilingual_db_2 {db} { } } -do_test 4.1.0 { - reset_db - set ptr [fts3_test_tokenizer] - execsql { SELECT fts3_tokenizer('testtokenizer', $ptr) } - build_multilingual_db_2 db -} {} -do_execsql_test 4.1.1 { - SELECT docid FROM t4 WHERE t4 MATCH 'quick'; -} {0} -do_execsql_test 4.1.2 { - SELECT docid FROM t4 WHERE t4 MATCH 'quick' AND lid=1; -} {} -do_execsql_test 4.1.3 { - SELECT docid FROM t4 WHERE t4 MATCH 'Quick' AND lid=1; -} {1} -for {set i 0} {$i < 50} {incr i} { - do_execsql_test 4.1.4.$i { - SELECT count(*) FROM t4 WHERE t4 MATCH 'fox' AND lid=$i; - } [expr 0==($i%2)] +ifcapable fts3_tokenizer { + do_test 4.1.0 { + reset_db + set ptr [fts3_test_tokenizer] + execsql { SELECT fts3_tokenizer('testtokenizer', $ptr) } + build_multilingual_db_2 db + } {} + do_execsql_test 4.1.1 { + SELECT docid FROM t4 WHERE t4 MATCH 'quick'; + } {0} + do_execsql_test 4.1.2 { + SELECT docid FROM t4 WHERE t4 MATCH 'quick' AND lid=1; + } {} + do_execsql_test 4.1.3 { + SELECT docid FROM t4 WHERE t4 MATCH 'Quick' AND lid=1; + } {1} + for {set i 0} {$i < 50} {incr i} { + do_execsql_test 4.1.4.$i { + SELECT count(*) FROM t4 WHERE t4 MATCH 'fox' AND lid=$i; + } [expr 0==($i%2)] + } + do_catchsql_test 4.1.5 { + INSERT INTO t4(content, lid) VALUES('hello world', 101) + } {1 {SQL logic error or missing database}} } -do_catchsql_test 4.1.5 { - INSERT INTO t4(content, lid) VALUES('hello world', 101) -} {1 {SQL logic error or missing database}} #------------------------------------------------------------------------- # Test cases 5.* From 83d7920e551c33cf93c8104cf44fc23117b5414b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 8 Feb 2016 20:06:52 +0000 Subject: [PATCH 104/107] Fix a compiler warning when compiling without SQLITE_ENABLE_FTS3_TOKENIZER. FossilOrigin-Name: 6926f28cd56bf61f7c92877baa54024bee7cbab5 --- ext/fts3/fts3_tokenizer.c | 3 +++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ext/fts3/fts3_tokenizer.c b/ext/fts3/fts3_tokenizer.c index 26bac57648..fcabe5cca2 100644 --- a/ext/fts3/fts3_tokenizer.c +++ b/ext/fts3/fts3_tokenizer.c @@ -336,6 +336,7 @@ finish: Tcl_DecrRefCount(pRet); } +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER static int registerTokenizer( sqlite3 *db, @@ -357,6 +358,8 @@ int registerTokenizer( return sqlite3_finalize(pStmt); } +#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */ + static int queryTokenizer( diff --git a/manifest b/manifest index 2ad9b86f00..7b991aaa7c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\stwo-argument\sform\sof\sthe\sfts3_tokenizer()\sSQL\sfunction\sunless\sthe\slibrary\sis\sbuilt\swith\s-DSQLITE_ENABLE_FTS3_TOKENIZER. -D 2016-02-08T19:40:17.991 +C Fix\sa\scompiler\swarning\swhen\scompiling\swithout\sSQLITE_ENABLE_FTS3_TOKENIZER. +D 2016-02-08T20:06:52.183 F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc fcf377286d910b47e072da1ac7945976337c0925 @@ -83,7 +83,7 @@ F ext/fts3/fts3_snippet.c 68ae118b0f834ea53d2b89e4087fc0f0b8c4ee4e F ext/fts3/fts3_term.c 88c55a6fa1a51ab494e33dced0401a6c28791fd7 F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038 F ext/fts3/fts3_tokenize_vtab.c a27593ab19657166f6fa5ec073b678cc29a75860 -F ext/fts3/fts3_tokenizer.c 0d3a77bbdc6f394d302f24980fa80667371c6e68 +F ext/fts3/fts3_tokenizer.c 4bd72f767f61c9ce5a7575c844e8d1ed2c3c561a F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c a93f5edc0aff44ef8b06d7cb55b52026541ca145 @@ -1427,7 +1427,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 a050e6f096d40aa5b6275797b96e62c228044f5a -R b09b6ba902e95153c88d724675282802 -U dan -Z a5b8919de2cf0c2997cac75a4e3c3a2c +P e0eb217aca7e4aadf9c44ed20822b78139f7c83c +R 3ba2bfd061690101a8667e8fadcc2696 +U drh +Z 2da14d7bb409b5abdcdd912d6af6bf8a diff --git a/manifest.uuid b/manifest.uuid index fcaa3cc3b9..116910222d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0eb217aca7e4aadf9c44ed20822b78139f7c83c \ No newline at end of file +6926f28cd56bf61f7c92877baa54024bee7cbab5 \ No newline at end of file From c2d0b56e6a7fd298113e857df6012e21189dfa13 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 8 Feb 2016 20:14:41 +0000 Subject: [PATCH 105/107] Fix a signed/unsigned comparison warning in fts5. FossilOrigin-Name: 85eb05ddbc3a7cff986af13c3dab6c0063e62171 --- ext/fts5/fts5_buffer.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index c3d4101b8b..c552e860eb 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -16,7 +16,7 @@ #include "fts5Int.h" int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ - if( pBuf->nSpacenSpacenSpace ? pBuf->nSpace : 64; u8 *pNew; while( nNew Date: Mon, 8 Feb 2016 20:45:37 +0000 Subject: [PATCH 106/107] Fix spelling error in MSVC makefile comments. FossilOrigin-Name: 6eab74c9ae57676044b5bc82fa14e92fd2448008 --- Makefile.msc | 8 ++++---- autoconf/Makefile.msc | 8 ++++---- manifest | 15 +++++++-------- manifest.uuid | 2 +- 4 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 8d416b77cb..9620ff6237 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -306,7 +306,7 @@ LD = link.exe RC = rc.exe !ENDIF -# Check for the MSVC runtime library path macro. Othertise, this value will +# Check for the MSVC runtime library path macro. Otherwise, this value will # default to the 'lib' directory underneath the MSVC installation directory. # !IFNDEF CRTLIBPATH @@ -343,7 +343,7 @@ NCC = $(NCC:\\=\) NCC = $(CC) !ENDIF -# Check for the MSVC native runtime library path macro. Othertise, +# Check for the MSVC native runtime library path macro. Otherwise, # this value will default to the 'lib' directory underneath the MSVC # installation directory. # @@ -353,7 +353,7 @@ NCRTLIBPATH = $(VCINSTALLDIR)\lib NCRTLIBPATH = $(NCRTLIBPATH:\\=\) -# Check for the Platform SDK library path macro. Othertise, this +# Check for the Platform SDK library path macro. Otherwise, this # value will default to the 'lib' directory underneath the Windows # SDK installation directory (the environment variable used appears # to be available when using Visual C++ 2008 or later via the @@ -365,7 +365,7 @@ NSDKLIBPATH = $(WINDOWSSDKDIR)\lib NSDKLIBPATH = $(NSDKLIBPATH:\\=\) -# Check for the UCRT library path macro. Othertise, this value will +# Check for the UCRT library path macro. Otherwise, this value will # default to the version-specific, platform-specific 'lib' directory # underneath the Windows SDK installation directory. # diff --git a/autoconf/Makefile.msc b/autoconf/Makefile.msc index a4f916f5a7..65f2396180 100644 --- a/autoconf/Makefile.msc +++ b/autoconf/Makefile.msc @@ -291,7 +291,7 @@ LD = link.exe RC = rc.exe !ENDIF -# Check for the MSVC runtime library path macro. Othertise, this value will +# Check for the MSVC runtime library path macro. Otherwise, this value will # default to the 'lib' directory underneath the MSVC installation directory. # !IFNDEF CRTLIBPATH @@ -328,7 +328,7 @@ NCC = $(NCC:\\=\) NCC = $(CC) !ENDIF -# Check for the MSVC native runtime library path macro. Othertise, +# Check for the MSVC native runtime library path macro. Otherwise, # this value will default to the 'lib' directory underneath the MSVC # installation directory. # @@ -338,7 +338,7 @@ NCRTLIBPATH = $(VCINSTALLDIR)\lib NCRTLIBPATH = $(NCRTLIBPATH:\\=\) -# Check for the Platform SDK library path macro. Othertise, this +# Check for the Platform SDK library path macro. Otherwise, this # value will default to the 'lib' directory underneath the Windows # SDK installation directory (the environment variable used appears # to be available when using Visual C++ 2008 or later via the @@ -350,7 +350,7 @@ NSDKLIBPATH = $(WINDOWSSDKDIR)\lib NSDKLIBPATH = $(NSDKLIBPATH:\\=\) -# Check for the UCRT library path macro. Othertise, this value will +# Check for the UCRT library path macro. Otherwise, this value will # default to the version-specific, platform-specific 'lib' directory # underneath the Windows SDK installation directory. # diff --git a/manifest b/manifest index 24eebb58a9..23d68d6a6c 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C More\swork\son\sWindows\s10\sSDK\sintegration. -D 2016-02-08T20:40:57.726 +C Fix\sspelling\serror\sin\sMSVC\smakefile\scomments. +D 2016-02-08T20:45:37.407 F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 8514a6d7c15fa179b45da902a4ddcf0a8e6748b2 +F Makefile.msc b0493f10caddb8adf992a4e6f1943141fc7c6816 F README.md 8ecc12493ff9f820cdea6520a9016001cb2e59b7 F VERSION 866588d1edf0ccb5b0d33896974338f97564f719 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -11,7 +11,7 @@ F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am 1c1657650775960804945dc392e14d9e43c5ed84 -F autoconf/Makefile.msc de6d40e0c495d761b9813ccb20a649841f6d6b72 +F autoconf/Makefile.msc a35b2aab24d1603f3f0ae65cf01686c2578d319c F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt e9757a381e5ce2553dbaa6247bb8ad00eb8d87aa F autoconf/configure.ac 72a5e42beb090b32bca580285dc0ab3c4670adb8 @@ -1427,8 +1427,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 85eb05ddbc3a7cff986af13c3dab6c0063e62171 ebace2c99b6af9230c4bbc31a764c7f397200148 -R 7f11f3c1dcb5601b2c82dcb73372e020 -T +closed ebace2c99b6af9230c4bbc31a764c7f397200148 +P 1e563c6ebbb02d2e89760c7a7f95aa69964629c6 +R 8450aebd4fe3e5df6689a15f6b4c74a5 U mistachkin -Z ac6553c79aaf86d7e04ebeafa308be17 +Z fa8db5a9236f4356c9f0e0ef9af9fdef diff --git a/manifest.uuid b/manifest.uuid index 583f181cdb..def0c6f083 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1e563c6ebbb02d2e89760c7a7f95aa69964629c6 \ No newline at end of file +6eab74c9ae57676044b5bc82fa14e92fd2448008 \ No newline at end of file From 2fade2f7913f948a6b2ad92e2e0e557de53937fe Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 9 Feb 2016 02:12:20 +0000 Subject: [PATCH 107/107] Make sure every co-routines has its own set of temporary registers and does not share temporaries, since a co-routine might expect the content of a temporary register to be preserved across an OP_Yield. Proposed fix for ticket [d06a25c84454a]. FossilOrigin-Name: ca72be8618e5d466d6f35819ca8bbd2b84269959 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/build.c | 2 +- src/insert.c | 2 +- src/select.c | 6 +++--- src/vdbe.h | 1 + src/vdbeaux.c | 15 +++++++++++++++ test/select4.test | 20 ++++++++++++++++++++ 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 23d68d6a6c..69b6e1ba9f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sspelling\serror\sin\sMSVC\smakefile\scomments. -D 2016-02-08T20:45:37.407 +C Make\ssure\severy\sco-routines\shas\sits\sown\sset\sof\stemporary\sregisters\sand\sdoes\nnot\sshare\stemporaries,\ssince\sa\sco-routine\smight\sexpect\sthe\scontent\sof\sa\ntemporary\sregister\sto\sbe\spreserved\sacross\san\sOP_Yield.\nProposed\sfix\sfor\sticket\s[d06a25c84454a]. +D 2016-02-09T02:12:20.490 F Makefile.in dac2776c84e0d533b158a9af6e57e05c4a6b19f3 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b0493f10caddb8adf992a4e6f1943141fc7c6816 @@ -294,7 +294,7 @@ F src/btmutex.c bc87dd3b062cc26edfe79918de2200ccb8d41e73 F src/btree.c 4c8caaeed7878aafdb607c3d2bcbc365bb0d19a1 F src/btree.h 368ceeb4bd9312dc8df2ffd64b4b7dbcf4db5f8e F src/btreeInt.h c18b7d2a3494695133e4e60ee36061d37f45d9a5 -F src/build.c 198eaa849c193f28b802ed135b2483c68ef7a35c +F src/build.c 54866fbafa09d494269bdefc79995eb7207003a6 F src/callback.c ed6c2a4a712eb7287ff64e20e3c23265dfb8a7ce F src/complete.c addcd8160b081131005d5bc2d34adf20c1c5c92f F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 @@ -309,7 +309,7 @@ F src/global.c bd5a0af3f30b0c01be6db756c626cd3c33a3d260 F src/hash.c 4263fbc955f26c2e8cdc0cf214bc42435aa4e4f5 F src/hash.h c8f3c31722cf3277d03713909761e152a5b81094 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c b84359365bace233919db550a15f131923190efc +F src/insert.c 046199e085e69e05af7bef197d53c5b4b402b6fa F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c b1b0880fc474abfab89e737b0ecfde0bd7a60902 F src/loadext.c 84996d7d70a605597d79c1f1d7b2012a5fd34f2b @@ -348,7 +348,7 @@ F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696 F src/resolve.c 9f7ce3a3c087afb7597b7c916c99126ff3f12f0c F src/rowset.c 9fe4b3ad7cc00944386bb600233d8f523de07a6e -F src/select.c 57646a44ba9a0bc4aa926ae9c79b8199c246844b +F src/select.c ff80004a9a6ece891a8d9327a88e7b6e2588ee6d F src/shell.c dcd7a83645ef2a58ee9c6d0ea4714d877d7835c4 F src/sqlite.h.in cf22ad1d52dca2c9862d63833e581028119aab7e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -414,10 +414,10 @@ F src/utf.c 10cc2519e82e3369344d0969ad4b1a333dc86d18 F src/util.c 49ce0a65306c1c51d61cb5bc214c71cb62452de6 F src/vacuum.c 2ddd5cad2a7b9cef7f9e431b8c7771634c6b1701 F src/vdbe.c c193299e595a13eba247738e22fce25c49346a6c -F src/vdbe.h 7a733ea8aac1b77305a67698e784fa3484ee3337 +F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512 F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79 F src/vdbeapi.c 9324f6baee1a1b2284c6543e98f916888a81e459 -F src/vdbeaux.c 49b536284c2b8a823dd342d653e18145ca2b393a +F src/vdbeaux.c deae5d3bd45da0e57c7d9e1d7436333d142dc3bb F src/vdbeblob.c 3b570b730109e8f653d9d2081649f6e7015113db F src/vdbemem.c 68fcfac37dc6601d98c32cc5adee4d39f2c1b7b4 F src/vdbesort.c ef3c6d1f1a7d44cf67bb2bee59ea3d1fe5bad174 @@ -992,7 +992,7 @@ F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test be62204d2bd9a5a8a149e9974cfddce893d8f686 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 -F test/select4.test 6d5bc6d178a367e8b48fa1c1d3ea12cae9c2d650 +F test/select4.test 453631158540e5f685b81cac5b7e8bd8c6b4c5fc F test/select5.test e758b8ef94f69b111df4cb819008856655dcd535 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 F test/select7.test 95e370c42d47c3c52377d05e9ffc01ccff7c1f61 @@ -1427,7 +1427,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 1e563c6ebbb02d2e89760c7a7f95aa69964629c6 -R 8450aebd4fe3e5df6689a15f6b4c74a5 -U mistachkin -Z fa8db5a9236f4356c9f0e0ef9af9fdef +P 6eab74c9ae57676044b5bc82fa14e92fd2448008 +R 28a5285fd29b59b5a769fa2b98c8137d +U drh +Z 50a93197f1857fe46bad3c49957d1f43 diff --git a/manifest.uuid b/manifest.uuid index def0c6f083..9e7ed6ea08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6eab74c9ae57676044b5bc82fa14e92fd2448008 \ No newline at end of file +ca72be8618e5d466d6f35819ca8bbd2b84269959 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 476fc28c41..250dc20d20 100644 --- a/src/build.c +++ b/src/build.c @@ -1954,7 +1954,7 @@ void sqlite3EndTable( sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); sqlite3Select(pParse, pSelect, &dest); - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); if( pParse->nErr ) return; pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect); diff --git a/src/insert.c b/src/insert.c index 729e0fedce..650f397de0 100644 --- a/src/insert.c +++ b/src/insert.c @@ -685,7 +685,7 @@ void sqlite3Insert( rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; diff --git a/src/select.c b/src/select.c index ea3e920b9f..c3132c2325 100644 --- a/src/select.c +++ b/src/select.c @@ -2952,7 +2952,7 @@ static int multiSelectOrderBy( pPrior->iLimit = regLimitA; explainSetInteger(iSub1, pParse->iNextSelectId); sqlite3Select(pParse, pPrior, &destA); - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA); + sqlite3VdbeEndCoroutine(v, regAddrA); sqlite3VdbeJumpHere(v, addr1); /* Generate a coroutine to evaluate the SELECT statement on @@ -2969,7 +2969,7 @@ static int multiSelectOrderBy( sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; - sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrB); + sqlite3VdbeEndCoroutine(v, regAddrB); /* Generate a subroutine that outputs the current row of the A ** select as the next output row of the compound select. @@ -4990,7 +4990,7 @@ int sqlite3Select( pItem->pTab->nRowLogEst = sqlite3LogEst(pSub->nSelectRow); pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; - sqlite3VdbeAddOp1(v, OP_EndCoroutine, pItem->regReturn); + sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); }else{ diff --git a/src/vdbe.h b/src/vdbe.h index f09997bf94..4c02f5844d 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -180,6 +180,7 @@ int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); #else diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8eb3141daf..ce98edd0a5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -324,6 +324,21 @@ int sqlite3VdbeAddOp4Int( return addr; } +/* Insert the end of a co-routine +*/ +void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); + + /* Clear the temporary register cache, thereby ensuring that each + ** co-routine has its own independent set of registers, because co-routines + ** might expect their registers to be preserved across an OP_Yield, and + ** that could cause problems if two or more co-routines are using the same + ** temporary register. + */ + v->pParse->nTempReg = 0; + v->pParse->nRangeReg = 0; +} + /* ** Create a new symbolic label for an instruction that has yet to be ** coded. The symbolic label is really just a negative number. The diff --git a/test/select4.test b/test/select4.test index a7b1af20a5..be8d0e0ab1 100644 --- a/test/select4.test +++ b/test/select4.test @@ -916,4 +916,24 @@ do_execsql_test select4-14.17 { VALUES(1),(2),(3),(4) UNION ALL SELECT 5 LIMIT 3; } {1 2 3} +# Ticket https://www.sqlite.org/src/info/d06a25c84454a372 +# Incorrect answer due to two co-routines using the same registers and expecting +# those register values to be preserved across a Yield. +# +do_execsql_test select4-15.1 { + DROP TABLE IF EXISTS tx; + CREATE TABLE tx(id INTEGER PRIMARY KEY, a, b); + INSERT INTO tx(a,b) VALUES(33,456); + INSERT INTO tx(a,b) VALUES(33,789); + + SELECT DISTINCT t0.id, t0.a, t0.b + FROM tx AS t0, tx AS t1 + WHERE t0.a=t1.a AND t1.a=33 AND t0.b=456 + UNION + SELECT DISTINCT t0.id, t0.a, t0.b + FROM tx AS t0, tx AS t1 + WHERE t0.a=t1.a AND t1.a=33 AND t0.b=789 + ORDER BY 1; +} {1 33 456 2 33 789} + finish_test