From 553818a0aaffdbf62fd038eb0a7d3dd3e830cf59 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 23 Jul 2014 18:36:55 +0000 Subject: [PATCH 01/11] Improve the performance of the ANALYZE command by taking advantage of the fact that every row of a UNIQUE index is distinct. FossilOrigin-Name: 3e1e79e1335f7ad33cd35f384f2a063c4aa2253b --- manifest | 12 ++--- manifest.uuid | 2 +- src/analyze.c | 124 +++++++++++++++++++++++++++++--------------------- 3 files changed, 79 insertions(+), 59 deletions(-) diff --git a/manifest b/manifest index 449ddf282d..f572551082 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updated\sdocumentation\son\ssqlite3_temp_directory.\s\sNo\schanges\sto\scode. -D 2014-07-23T15:51:29.276 +C Improve\sthe\sperformance\sof\sthe\sANALYZE\scommand\sby\staking\sadvantage\sof\sthe\nfact\sthat\severy\srow\sof\sa\sUNIQUE\sindex\sis\sdistinct. +D 2014-07-23T18:36:55.821 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c ab1e44158c25490bfda557f3d690217b2bb509e2 +F src/analyze.c c72bb66997ebdbc76936cfe96d7cc9da6ffe2b22 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -1183,7 +1183,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 48f40861db4fbd10725a2b8b606d44fe16d5bd27 -R c881f4a63c48850e8a9fb96aa00a5db1 +P e6225a7bf77a700b318563b1a854b4b3a9e031e1 +R fa098d0ebca9c403761ac8a7cdd64221 U drh -Z cd8aaf55159956edb23d2b840f6a6165 +Z 71590bde4580a255d675842a920968d0 diff --git a/manifest.uuid b/manifest.uuid index 470adaeeca..2ecff9239b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6225a7bf77a700b318563b1a854b4b3a9e031e1 \ No newline at end of file +3e1e79e1335f7ad33cd35f384f2a063c4aa2253b \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index c614350ae3..2c31f81f3a 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -371,15 +371,20 @@ static void stat4Destructor(void *pOld){ /* ** Implementation of the stat_init(N,K,C) SQL function. The three parameters ** are: -** N: The number of columns in the index including the rowid/pk -** K: The number of columns in the index excluding the rowid/pk -** C: The number of rows in the index +** N: The number of columns in the index including the rowid/pk (note 1) +** K: The number of columns in the index excluding the rowid/pk. +** C: The number of rows in the index (note 2) ** -** C is only used for STAT3 and STAT4. +** Note 1: In the special case of the covering index that implements a +** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the +** total number of columns in the table. ** -** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables, -** N=K+P where P is the number of columns in the primary key. For the -** covering index that implements the original WITHOUT ROWID table, N==K. +** Note 2: C is only used for STAT3 and STAT4. +** +** For indexes on ordinary rowid tables, N==K+1. But for indexes on +** WITHOUT ROWID tables, N=K+P where P is the number of columns in the +** PRIMARY KEY of the table. The covering index that implements the +** original WITHOUT ROWID table as N==K as a special case. ** ** This routine allocates the Stat4Accum object in heap memory. The return ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. @@ -689,7 +694,10 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){ ** R Rowid for the current row. Might be a key record for ** WITHOUT ROWID tables. ** -** The SQL function always returns NULL. +** This SQL function always returns NULL. It's purpose it to accumulate +** statistical data and/or samples in the Stat4Accum object about the +** index being analyzed. The stat_get() SQL function will later be used to +** extract relevant information for constructing the sqlite_statN tables. ** ** The R parameter is only used for STAT3 and STAT4 */ @@ -783,7 +791,10 @@ static const FuncDef statPushFuncdef = { /* ** Implementation of the stat_get(P,J) SQL function. This routine is -** used to query the results. Content is returned for parameter J +** used to query statistical information that has been gathered into +** the Stat4Accum object by prior calls to stat_push(). The P parameter +** is a BLOB which is decoded into a pointer to the Stat4Accum objects. +** The content to returned is determined by the parameter J ** which is one of the STAT_GET_xxxx values defined above. ** ** If neither STAT3 nor STAT4 are enabled, then J is always @@ -1002,23 +1013,25 @@ static void analyzeOneTable( sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int nCol; /* Number of columns indexed by pIdx */ + int nCol; /* Number of columns in pIdx. "N" */ int *aGotoChng; /* Array of jump instruction addresses */ int addrRewind; /* Address of "OP_Rewind iIdxCur" */ - int addrGotoChng0; /* Address of "Goto addr_chng_0" */ int addrNextRow; /* Address of "next_row:" */ const char *zIdxName; /* Name of the index */ + int nColTest; /* Number of columns to test for changes */ if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ nCol = pIdx->nKeyCol; zIdxName = pTab->zName; + nColTest = nCol - 1; }else{ nCol = pIdx->nColumn; zIdxName = pIdx->zName; + nColTest = pIdx->onError==OE_None ? nCol-1 : pIdx->nKeyCol-1; } - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nColTest+1)); if( aGotoChng==0 ) continue; /* Populate the register containing the index name. */ @@ -1061,7 +1074,7 @@ static void analyzeOneTable( ** the regPrev array and a trailing rowid (the rowid slot is required ** when building a record to insert into the sample column of ** the sqlite_stat4 table. */ - pParse->nMem = MAX(pParse->nMem, regPrev+nCol); + pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); /* Open a read-only cursor on the index being analyzed. */ assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); @@ -1071,10 +1084,13 @@ static void analyzeOneTable( /* Invoke the stat_init() function. The arguments are: ** - ** (1) the number of columns in the index including the rowid, - ** (2) the number of rows in the index, + ** (1) the number of columns in the index including the rowid + ** (or for a WITHOUT ROWID table, the number of PK columns), + ** (2) the number of columns in the key without the rowid/pk + ** (3) the number of rows in the index, ** - ** The second argument is only used for STAT3 and STAT4 + ** + ** The third argument is only used for STAT3 and STAT4 */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); @@ -1096,44 +1112,49 @@ static void analyzeOneTable( addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); - addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); - - /* - ** next_row: - ** regChng = 0 - ** if( idx(0) != regPrev(0) ) goto chng_addr_0 - ** regChng = 1 - ** if( idx(1) != regPrev(1) ) goto chng_addr_1 - ** ... - ** regChng = N - ** goto chng_addr_N - */ addrNextRow = sqlite3VdbeCurrentAddr(v); - for(i=0; iazColl[i]); - sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); - aGotoChng[i] = - sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); - sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); - VdbeCoverage(v); - } - sqlite3VdbeAddOp2(v, OP_Integer, nCol-1, regChng); - aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); - /* - ** chng_addr_0: - ** regPrev(0) = idx(0) - ** chng_addr_1: - ** regPrev(1) = idx(1) - ** ... - */ - sqlite3VdbeJumpHere(v, addrGotoChng0); - for(i=0; i0 ){ + /* + ** next_row: + ** regChng = 0 + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 + ** regChng = 1 + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 + ** ... + ** regChng = N + ** goto chng_addr_N + */ + sqlite3VdbeAddOp0(v, OP_Goto); + addrNextRow = sqlite3VdbeCurrentAddr(v); + for(i=0; iazColl[i]); + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); + aGotoChng[i] = + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + VdbeCoverage(v); + } + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); + aGotoChng[nColTest] = sqlite3VdbeAddOp0(v, OP_Goto); + + + /* + ** chng_addr_0: + ** regPrev(0) = idx(0) + ** chng_addr_1: + ** regPrev(1) = idx(1) + ** ... + */ + sqlite3VdbeJumpHere(v, addrNextRow-1); + for(i=0; i Date: Wed, 23 Jul 2014 19:37:21 +0000 Subject: [PATCH 02/11] Ugh. Consecutive UNIQUE index entries are only distinct if the index is on NOT NULL columns. So the previous version was not quite right. This check-in fixes the problem. FossilOrigin-Name: 30033f965030a015fad15e532bcaba1314c8cc0f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f572551082..c9cc80f306 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sthe\sANALYZE\scommand\sby\staking\sadvantage\sof\sthe\nfact\sthat\severy\srow\sof\sa\sUNIQUE\sindex\sis\sdistinct. -D 2014-07-23T18:36:55.821 +C Ugh.\s\sConsecutive\sUNIQUE\sindex\sentries\sare\sonly\sdistinct\sif\sthe\sindex\sis\non\sNOT\sNULL\scolumns.\s\sSo\sthe\sprevious\sversion\swas\snot\squite\sright.\s\sThis\ncheck-in\sfixes\sthe\sproblem. +D 2014-07-23T19:37:21.314 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c c72bb66997ebdbc76936cfe96d7cc9da6ffe2b22 +F src/analyze.c 7f893416d1e4375e31e497107e92b28c2f8f82d1 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -1183,7 +1183,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e6225a7bf77a700b318563b1a854b4b3a9e031e1 -R fa098d0ebca9c403761ac8a7cdd64221 +P 3e1e79e1335f7ad33cd35f384f2a063c4aa2253b +R 8df862d446d339da769e0f44096b055d U drh -Z 71590bde4580a255d675842a920968d0 +Z cc08889d86841af01a0687614b9dbde8 diff --git a/manifest.uuid b/manifest.uuid index 2ecff9239b..b9ae50e83b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e1e79e1335f7ad33cd35f384f2a063c4aa2253b \ No newline at end of file +30033f965030a015fad15e532bcaba1314c8cc0f \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 2c31f81f3a..e235389e2d 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1029,7 +1029,7 @@ static void analyzeOneTable( }else{ nCol = pIdx->nColumn; zIdxName = pIdx->zName; - nColTest = pIdx->onError==OE_None ? nCol-1 : pIdx->nKeyCol-1; + nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; } aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nColTest+1)); if( aGotoChng==0 ) continue; From 9d793325b0efb94a4a2395087959e3147aa9c339 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Jul 2014 19:54:20 +0000 Subject: [PATCH 03/11] Avoid change tests when analyzing single-column unique indexes after getting past the initial NULL entries. FossilOrigin-Name: 4690e99c07024f40fafba1db8e4487b287b788a9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c9cc80f306..f33fbbea51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ugh.\s\sConsecutive\sUNIQUE\sindex\sentries\sare\sonly\sdistinct\sif\sthe\sindex\sis\non\sNOT\sNULL\scolumns.\s\sSo\sthe\sprevious\sversion\swas\snot\squite\sright.\s\sThis\ncheck-in\sfixes\sthe\sproblem. -D 2014-07-23T19:37:21.314 +C Avoid\schange\stests\swhen\sanalyzing\ssingle-column\sunique\sindexes\safter\ngetting\spast\sthe\sinitial\sNULL\sentries. +D 2014-07-24T19:54:20.150 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c 7f893416d1e4375e31e497107e92b28c2f8f82d1 +F src/analyze.c 45216a14e7e71084859d2899cd323b2f597f8527 F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -1183,7 +1183,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 3e1e79e1335f7ad33cd35f384f2a063c4aa2253b -R 8df862d446d339da769e0f44096b055d +P 30033f965030a015fad15e532bcaba1314c8cc0f +R e98a107e1f5891c465c70c3fe5e38f27 U drh -Z cc08889d86841af01a0687614b9dbde8 +Z 7cfd64b5f36044a7bdee3831c72ee79f diff --git a/manifest.uuid b/manifest.uuid index b9ae50e83b..bfe6770cbb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30033f965030a015fad15e532bcaba1314c8cc0f \ No newline at end of file +4690e99c07024f40fafba1db8e4487b287b788a9 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index e235389e2d..9a64108384 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1031,7 +1031,7 @@ static void analyzeOneTable( zIdxName = pIdx->zName; nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; } - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nColTest+1)); + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); if( aGotoChng==0 ) continue; /* Populate the register containing the index name. */ @@ -1061,7 +1061,7 @@ static void analyzeOneTable( ** regPrev(1) = idx(1) ** ... ** - ** chng_addr_N: + ** endDistinctTest: ** regRowid = idx(rowid) ** stat_push(P, regChng, regRowid) ** Next csr @@ -1115,6 +1115,7 @@ static void analyzeOneTable( addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ + int endDistinctTest = sqlite3VdbeMakeLabel(v); /* ** next_row: ** regChng = 0 @@ -1123,10 +1124,17 @@ static void analyzeOneTable( ** if( idx(1) != regPrev(1) ) goto chng_addr_1 ** ... ** regChng = N - ** goto chng_addr_N + ** goto endDistinctTest */ sqlite3VdbeAddOp0(v, OP_Goto); addrNextRow = sqlite3VdbeCurrentAddr(v); + if( nColTest==1 && pIdx->nKeyCol==1 && pIdx->onError!=OE_None ){ + /* For a single-column UNIQUE index, once we have found a non-NULL + ** row, we know that all the rest will be distinct, so skip + ** subsequent distinctness tests. */ + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); + VdbeCoverage(v); + } for(i=0; iazColl[i]); sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); @@ -1137,7 +1145,7 @@ static void analyzeOneTable( VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); - aGotoChng[nColTest] = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); /* @@ -1152,7 +1160,7 @@ static void analyzeOneTable( sqlite3VdbeJumpHere(v, aGotoChng[i]); sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); } - sqlite3VdbeJumpHere(v, aGotoChng[nColTest]); + sqlite3VdbeResolveLabel(v, endDistinctTest); } /* From b12879fd1af673bcb41eec70c50ca3726196f693 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Jul 2014 20:25:16 +0000 Subject: [PATCH 04/11] Avoid trying to allocation zero bytes when analyzing a unique non-null index. FossilOrigin-Name: 85e2badeeb7f7599eb6fd35512f9bd524f0b1b3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/analyze.c | 9 +++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f33fbbea51..6c8e62a3ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\schange\stests\swhen\sanalyzing\ssingle-column\sunique\sindexes\safter\ngetting\spast\sthe\sinitial\sNULL\sentries. -D 2014-07-24T19:54:20.150 +C Avoid\strying\sto\sallocation\szero\sbytes\swhen\sanalyzing\sa\sunique\snon-null\sindex. +D 2014-07-24T20:25:16.037 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -161,7 +161,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 3d8b83c91651f53472ca17599dae3457b8b89494 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c b00900877f766f116f9e16116f1ccacdc21d82f1 -F src/analyze.c 45216a14e7e71084859d2899cd323b2f597f8527 +F src/analyze.c 9799a65d8e8892e6eb96d0094a1d4fa6d7aebd0e F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 @@ -1183,7 +1183,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 30033f965030a015fad15e532bcaba1314c8cc0f -R e98a107e1f5891c465c70c3fe5e38f27 +P 4690e99c07024f40fafba1db8e4487b287b788a9 +R 665515c1fc4ab29e7e80bbd8e675bbe2 U drh -Z 7cfd64b5f36044a7bdee3831c72ee79f +Z 06b30e9b7410b92f6a1122ec1ae06529 diff --git a/manifest.uuid b/manifest.uuid index bfe6770cbb..e165c09bcc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4690e99c07024f40fafba1db8e4487b287b788a9 \ No newline at end of file +85e2badeeb7f7599eb6fd35512f9bd524f0b1b3f \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 9a64108384..3931b2ff8c 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1014,7 +1014,6 @@ static void analyzeOneTable( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; /* Number of columns in pIdx. "N" */ - int *aGotoChng; /* Array of jump instruction addresses */ int addrRewind; /* Address of "OP_Rewind iIdxCur" */ int addrNextRow; /* Address of "next_row:" */ const char *zIdxName; /* Name of the index */ @@ -1031,8 +1030,6 @@ static void analyzeOneTable( zIdxName = pIdx->zName; nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; } - aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); - if( aGotoChng==0 ) continue; /* Populate the register containing the index name. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); @@ -1116,6 +1113,10 @@ static void analyzeOneTable( if( nColTest>0 ){ int endDistinctTest = sqlite3VdbeMakeLabel(v); + int *aGotoChng; /* Array of jump instruction addresses */ + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); + if( aGotoChng==0 ) continue; + /* ** next_row: ** regChng = 0 @@ -1161,6 +1162,7 @@ static void analyzeOneTable( sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); } sqlite3VdbeResolveLabel(v, endDistinctTest); + sqlite3DbFree(db, aGotoChng); } /* @@ -1247,7 +1249,6 @@ static void analyzeOneTable( /* End of analysis */ sqlite3VdbeJumpHere(v, addrRewind); - sqlite3DbFree(db, aGotoChng); } From d15f87ecfdf0f1bf12d58da5284c9792f966f4d4 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 24 Jul 2014 22:41:20 +0000 Subject: [PATCH 05/11] Fix a bug in the whereRangeSkipScanEst() procedure (added by check-in [d09ca6d5efad3e4cfa]) where it fails to consider the possibility of a ROWID column when computing the affinity of a table column. FossilOrigin-Name: 6aea2258dd7d3967900cefe4cd0af48a7ee7e169 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c9c66de972..87c15adf11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sreadfile(FILENAME)\sand\swritefile(FILENAME,CONTENT)\sSQL\sfunctions\sto\nthe\scommand-line\sshell. -D 2014-07-24T12:39:59.049 +C Fix\sa\sbug\sin\sthe\swhereRangeSkipScanEst()\sprocedure\s(added\sby\ncheck-in\s[d09ca6d5efad3e4cfa])\swhere\sit\sfails\sto\sconsider\sthe\spossibility\nof\sa\sROWID\scolumn\swhen\scomputing\sthe\saffinity\sof\sa\stable\scolumn. +D 2014-07-24T22:41:20.186 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -296,7 +296,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45 -F src/where.c 9454af8e5e18d6e91e5169eadfb61878e2cb42b1 +F src/where.c 4dfcd80380d154be434c4b51e890e17ce9754b3e F src/whereInt.h 929c1349b5355fd44f22cee5c14d72b3329c58a6 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f8f79f28785db716b10c3bc9d6652b98253fd125 -R 3cb7c1591be4171f813333f040f9142c +P fb1048cb2b613a0dbfe625a5df05e9dcd736a433 +R 7154486a7ce11d45d2aed19cdac8eb64 U drh -Z d6bf09c8f21a2381ecdf6b5a91f85057 +Z 3de5689fcbb67ba500bf3c297659c386 diff --git a/manifest.uuid b/manifest.uuid index c704a64b44..8f811c9bc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb1048cb2b613a0dbfe625a5df05e9dcd736a433 \ No newline at end of file +6aea2258dd7d3967900cefe4cd0af48a7ee7e169 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 3901dd468f..38d1014ac0 100644 --- a/src/where.c +++ b/src/where.c @@ -2047,7 +2047,8 @@ static int whereRangeSkipScanEst( int nLower = -1; int nUpper = p->nSample+1; int rc = SQLITE_OK; - u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity; + int iCol = p->aiColumn[nEq]; + u8 aff = iCol>=0 ? p->pTable->aCol[iCol].affinity : SQLITE_AFF_INTEGER; CollSeq *pColl; sqlite3_value *p1 = 0; /* Value extracted from pLower */ From 8af3f772c10e55d473e0cbe08e879101e66877ce Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Jul 2014 18:01:06 +0000 Subject: [PATCH 06/11] Add constraints (enforced only when SQLITE_DEBUG is enabled) on the use of OP_Next and OP_Prev. FossilOrigin-Name: 2230c74f1efa591770176c9b40e920724a3c39e1 --- manifest | 15 +++++---- manifest.uuid | 2 +- src/vdbe.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/vdbeInt.h | 3 ++ 4 files changed, 90 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a378b1468d..30ae97fa3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sthe\sANALYZE\scommand\sby\staking\sadvantage\sof\nUNIQUE\sconstraints\son\sindices. -D 2014-07-24T23:23:26.687 +C Add\sconstraints\s(enforced\sonly\swhen\sSQLITE_DEBUG\sis\senabled)\son\sthe\suse\sof\nOP_Next\sand\sOP_Prev. +D 2014-07-25T18:01:06.435 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,9 +283,9 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c fa74c6563486022920db4d73897bd9b837c7441d +F src/vdbe.c c6a9094a56b3dd4769243051a512f89763af7de5 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 -F src/vdbeInt.h f41a7cf5a40e7abd994d5fe3a04589ae3e1154e7 +F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 F src/vdbeaux.c 1ffe0bbc3a2c8aedd95622de9be6b6d07b3d3c6b F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac @@ -1184,8 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 6aea2258dd7d3967900cefe4cd0af48a7ee7e169 85e2badeeb7f7599eb6fd35512f9bd524f0b1b3f -R ac28d1873bd62cdf71787453262a0966 -T +closed 85e2badeeb7f7599eb6fd35512f9bd524f0b1b3f +P 114dcf33670fd98a1ebbac0e44f66b2d8bcccddf +R f27032fe9d592a52e4ec63c28d270176 U drh -Z 72b5de0db489041a156923cd906bfefb +Z 96714d48e7c72e5d439e8f51e5a0d88e diff --git a/manifest.uuid b/manifest.uuid index a9e63c9b42..9d6edd3229 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -114dcf33670fd98a1ebbac0e44f66b2d8bcccddf \ No newline at end of file +2230c74f1efa591770176c9b40e920724a3c39e1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 093669a82d..60d8ebf3e5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3481,7 +3481,7 @@ case OP_Close: { break; } -/* Opcode: SeekGe P1 P2 P3 P4 * +/* Opcode: SeekGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), @@ -3493,9 +3493,13 @@ case OP_Close: { ** is greater than or equal to the key value. If there are no records ** greater than or equal to the key and P2 is not zero, then jump to P2. ** +** This opcode leaves the cursor configured to move in forward order, +** from the begining toward the end. In other words, the cursor is +** configured to use OP_Next, not OP_Prev. +** ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe */ -/* Opcode: SeekGt P1 P2 P3 P4 * +/* Opcode: SeekGT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), @@ -3507,9 +3511,13 @@ case OP_Close: { ** is greater than the key value. If there are no records greater than ** the key and P2 is not zero, then jump to P2. ** +** This opcode leaves the cursor configured to move in forward order, +** from the begining toward the end. In other words, the cursor is +** configured to use OP_Next, not OP_Prev. +** ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe */ -/* Opcode: SeekLt P1 P2 P3 P4 * +/* Opcode: SeekLT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), @@ -3521,9 +3529,13 @@ case OP_Close: { ** is less than the key value. If there are no records less than ** the key and P2 is not zero, then jump to P2. ** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use OP_Prev, not OP_Next. +** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe */ -/* Opcode: SeekLe P1 P2 P3 P4 * +/* Opcode: SeekLE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), @@ -3535,6 +3547,10 @@ case OP_Close: { ** is less than or equal to the key value. If there are no records ** less than or equal to the key and P2 is not zero, then jump to P2. ** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use OP_Prev, not OP_Next. +** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ case OP_SeekLT: /* jump, in3 */ @@ -3560,6 +3576,9 @@ case OP_SeekGT: { /* jump, in3 */ assert( pC->pCursor!=0 ); oc = pOp->opcode; pC->nullRow = 0; +#ifdef SQLITE_DEBUG + pC->seekOp = pOp->opcode; +#endif if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do @@ -3715,6 +3734,10 @@ case OP_Seek: { /* in2 */ ** is a prefix of any entry in P1 then a jump is made to P2 and ** P1 is left pointing at the matching entry. ** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** ** See also: NotFound, NoConflict, NotExists. SeekGe */ /* Opcode: NotFound P1 P2 P3 P4 * @@ -3730,6 +3753,10 @@ case OP_Seek: { /* in2 */ ** falls through to the next instruction and P1 is left pointing at the ** matching entry. ** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** ** See also: Found, NotExists, NoConflict */ /* Opcode: NoConflict P1 P2 P3 P4 * @@ -3749,6 +3776,10 @@ case OP_Seek: { /* in2 */ ** This opcode is similar to OP_NotFound with the exceptions that the ** branch is always taken if any part of the search key input is NULL. ** +** This operation leaves the cursor in a state where it cannot be +** advanced in either direction. In other words, the Next and Prev +** opcodes do not work after this operation. +** ** See also: NotFound, Found, NotExists */ case OP_NoConflict: /* jump, in3 */ @@ -3771,6 +3802,9 @@ case OP_Found: { /* jump, in3 */ assert( pOp->p4type==P4_INT32 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = 0; +#endif pIn3 = &aMem[pOp->p3]; assert( pC->pCursor!=0 ); assert( pC->isTable==0 ); @@ -3842,6 +3876,10 @@ case OP_Found: { /* jump, in3 */ ** The OP_NotFound opcode performs the same operation on index btrees ** (with arbitrary multi-value keys). ** +** This opcode leaves the cursor in a state where it cannot be advanced +** in either direction. In other words, the Next and Prev opcodes will +** not work following this opcode. +** ** See also: Found, NotFound, NoConflict */ case OP_NotExists: { /* jump, in3 */ @@ -3855,6 +3893,9 @@ case OP_NotExists: { /* jump, in3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); +#ifdef SQLITE_DEBUG + pC->seekOp = 0; +#endif assert( pC->isTable ); assert( pC->pseudoTableReg==0 ); pCrsr = pC->pCursor; @@ -4421,11 +4462,15 @@ case OP_NullRow: { /* Opcode: Last P1 P2 * * * ** -** The next use of the Rowid or Column or Next instruction for P1 +** The next use of the Rowid or Column or Prev instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. +** +** This opcode leaves the cursor configured to move in reverse order, +** from the end toward the beginning. In other words, the cursor is +** configured to use OP_Prev, not OP_Next. */ case OP_Last: { /* jump */ VdbeCursor *pC; @@ -4443,6 +4488,9 @@ case OP_Last: { /* jump */ pC->deferredMoveto = 0; pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Last; +#endif if( pOp->p2>0 ){ VdbeBranchTaken(res!=0,2); if( res ) pc = pOp->p2 - 1; @@ -4479,6 +4527,10 @@ case OP_Sort: { /* jump */ ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. +** +** This opcode leaves the cursor configured to move in forward order, +** from the begining toward the end. In other words, the cursor is +** configured to use OP_Next, not OP_Prev. */ case OP_Rewind: { /* jump */ VdbeCursor *pC; @@ -4490,6 +4542,9 @@ case OP_Rewind: { /* jump */ assert( pC!=0 ); assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); res = 1; +#ifdef SQLITE_DEBUG + pC->seekOp = OP_Rewind; +#endif if( isSorter(pC) ){ rc = sqlite3VdbeSorterRewind(db, pC, &res); }else{ @@ -4516,6 +4571,10 @@ case OP_Rewind: { /* jump */ ** to the following instruction. But if the cursor advance was successful, ** jump immediately to P2. ** +** The OP_Next opcode is only valid following an OP_SeekGT, OP_SeekGE, or +** OP_Rewind opcode used to position the cursor. OP_Next is not allowed +** to follow OP_SeekLT, OP_SeekLE, or OP_Last. +** ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have ** been opened prior to this opcode or the program will segfault. ** @@ -4544,6 +4603,11 @@ case OP_Rewind: { /* jump */ ** to the following instruction. But if the cursor backup was successful, ** jump immediately to P2. ** +** +** The OP_Prev opcode is only valid following an OP_SeekLT, OP_SeekLE, or +** OP_Last opcode used to position the cursor. OP_Prev is not allowed +** to follow OP_SeekGT, OP_SeekGE, or OP_Rewind. +** ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. ** @@ -4591,6 +4655,16 @@ case OP_Next: /* jump */ assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); assert( pOp->opcode!=OP_NextIfOpen || pOp->p4.xAdvance==sqlite3BtreeNext ); assert( pOp->opcode!=OP_PrevIfOpen || pOp->p4.xAdvance==sqlite3BtreePrevious); + + /* The Next opcode is only used after SeekGT, SeekGE, and Rewind. + ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ + assert( pOp->opcode!=OP_Next || pOp->opcode!=OP_NextIfOpen + || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE + || pC->seekOp==OP_Rewind ); + assert( pOp->opcode!=OP_Prev || pOp->opcode!=OP_PrevIfOpen + || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE + || pC->seekOp==OP_Last ); + rc = pOp->p4.xAdvance(pC->pCursor, &res); next_tail: pC->cacheStatus = CACHE_STALE; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index f541aa7170..141573eef4 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -68,6 +68,9 @@ struct VdbeCursor { int pseudoTableReg; /* Register holding pseudotable content. */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ +#ifdef SQLITE_DEBUG + u8 seekOp; /* Most recent seek operation on this cursor */ +#endif i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ u8 nullRow; /* True if pointing to a row with no data */ u8 rowidIsValid; /* True if lastRowid is valid */ From 5dad9a3497f47f9277c8d1562b814e9292371d0c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Jul 2014 18:37:42 +0000 Subject: [PATCH 07/11] Improved comments on VDBE opcodes, for better documentation. No code or logic changes. FossilOrigin-Name: 2d32e4876e0b162730f81e5c2658be12d64a9a99 --- manifest | 12 ++++---- manifest.uuid | 2 +- src/vdbe.c | 76 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 53 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index 30ae97fa3c..34fbf9cae2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sconstraints\s(enforced\sonly\swhen\sSQLITE_DEBUG\sis\senabled)\son\sthe\suse\sof\nOP_Next\sand\sOP_Prev. -D 2014-07-25T18:01:06.435 +C Improved\scomments\son\sVDBE\sopcodes,\sfor\sbetter\sdocumentation.\s\sNo\scode\nor\slogic\schanges. +D 2014-07-25T18:37:42.754 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,7 +283,7 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c c6a9094a56b3dd4769243051a512f89763af7de5 +F src/vdbe.c b7af861342a215c7f27d3f20d92fe0b70f54fb3e F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 114dcf33670fd98a1ebbac0e44f66b2d8bcccddf -R f27032fe9d592a52e4ec63c28d270176 +P 2230c74f1efa591770176c9b40e920724a3c39e1 +R 29600123a95daa5177cd67bf8abb597c U drh -Z 96714d48e7c72e5d439e8f51e5a0d88e +Z 36e2e79e107a063c258f47507608b039 diff --git a/manifest.uuid b/manifest.uuid index 9d6edd3229..a16837f979 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2230c74f1efa591770176c9b40e920724a3c39e1 \ No newline at end of file +2d32e4876e0b162730f81e5c2658be12d64a9a99 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 60d8ebf3e5..e53b9251a3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -767,12 +767,14 @@ case OP_Return: { /* in1 */ /* Opcode: InitCoroutine P1 P2 P3 * * ** -** Set up register P1 so that it will OP_Yield to the co-routine +** Set up register P1 so that it will Yield to the coroutine ** located at address P3. ** -** If P2!=0 then the co-routine implementation immediately follows -** this opcode. So jump over the co-routine implementation to +** If P2!=0 then the coroutine implementation immediately follows +** this opcode. So jump over the coroutine implementation to ** address P2. +** +** See also: EndCoroutine */ case OP_InitCoroutine: { /* jump */ assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); @@ -788,9 +790,11 @@ case OP_InitCoroutine: { /* jump */ /* Opcode: EndCoroutine P1 * * * * ** -** The instruction at the address in register P1 is an OP_Yield. -** Jump to the P2 parameter of that OP_Yield. +** The instruction at the address in register P1 is an Yield. +** Jump to the P2 parameter of that Yield. ** After the jump, register P1 becomes undefined. +** +** See also: InitCoroutine */ case OP_EndCoroutine: { /* in1 */ VdbeOp *pCaller; @@ -807,11 +811,16 @@ case OP_EndCoroutine: { /* in1 */ /* Opcode: Yield P1 P2 * * * ** -** Swap the program counter with the value in register P1. +** Swap the program counter with the value in register P1. This +** has the effect of yielding to a coroutine. ** -** If the co-routine ends with OP_Yield or OP_Return then continue -** to the next instruction. But if the co-routine ends with -** OP_EndCoroutine, jump immediately to P2. +** If the coroutine that is launched by this instruction ends with +** Yield or Return then continue to the next instruction. But if +** the coroutine launched by this instruction ends with +** EndCoroutine, then jump to P2 rather than continuing with the +** next instruction. +** +** See also: InitCoroutine */ case OP_Yield: { /* in1, jump */ int pcDest; @@ -2196,10 +2205,14 @@ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ /* Opcode: Once P1 P2 * * * ** -** Check if OP_Once flag P1 is set. If so, jump to instruction P2. Otherwise, -** set the flag and fall through to the next instruction. In other words, -** this opcode causes all following opcodes up through P2 (but not including -** P2) to run just once and to be skipped on subsequent times through the loop. +** Check the "once" flag number P1. If it is set, jump to instruction P2. +** Otherwise, set the flag and fall through to the next instruction. +** In other words, this opcode causes all following opcodes up through P2 +** (but not including P2) to run just once and to be skipped on subsequent +** times through the loop. +** +** All "once" flags are initially cleared whenever a prepared statement +** first begins to run. */ case OP_Once: { /* jump */ assert( pOp->p1nOnceFlag ); @@ -3495,7 +3508,7 @@ case OP_Close: { ** ** This opcode leaves the cursor configured to move in forward order, ** from the begining toward the end. In other words, the cursor is -** configured to use OP_Next, not OP_Prev. +** configured to use Next, not Prev. ** ** See also: Found, NotFound, SeekLt, SeekGt, SeekLe */ @@ -3513,7 +3526,7 @@ case OP_Close: { ** ** This opcode leaves the cursor configured to move in forward order, ** from the begining toward the end. In other words, the cursor is -** configured to use OP_Next, not OP_Prev. +** configured to use Next, not Prev. ** ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe */ @@ -3531,7 +3544,7 @@ case OP_Close: { ** ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is -** configured to use OP_Prev, not OP_Next. +** configured to use Prev, not Next. ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLe */ @@ -3549,7 +3562,7 @@ case OP_Close: { ** ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is -** configured to use OP_Prev, not OP_Next. +** configured to use Prev, not Next. ** ** See also: Found, NotFound, SeekGt, SeekGe, SeekLt */ @@ -4470,7 +4483,7 @@ case OP_NullRow: { ** ** This opcode leaves the cursor configured to move in reverse order, ** from the end toward the beginning. In other words, the cursor is -** configured to use OP_Prev, not OP_Next. +** configured to use Prev, not Next. */ case OP_Last: { /* jump */ VdbeCursor *pC; @@ -4530,7 +4543,7 @@ case OP_Sort: { /* jump */ ** ** This opcode leaves the cursor configured to move in forward order, ** from the begining toward the end. In other words, the cursor is -** configured to use OP_Next, not OP_Prev. +** configured to use Next, not Prev. */ case OP_Rewind: { /* jump */ VdbeCursor *pC; @@ -4571,9 +4584,9 @@ case OP_Rewind: { /* jump */ ** to the following instruction. But if the cursor advance was successful, ** jump immediately to P2. ** -** The OP_Next opcode is only valid following an OP_SeekGT, OP_SeekGE, or -** OP_Rewind opcode used to position the cursor. OP_Next is not allowed -** to follow OP_SeekLT, OP_SeekLE, or OP_Last. +** The Next opcode is only valid following an SeekGT, SeekGE, or +** OP_Rewind opcode used to position the cursor. Next is not allowed +** to follow SeekLT, SeekLE, or OP_Last. ** ** The P1 cursor must be for a real table, not a pseudo-table. P1 must have ** been opened prior to this opcode or the program will segfault. @@ -4593,7 +4606,7 @@ case OP_Rewind: { /* jump */ */ /* Opcode: NextIfOpen P1 P2 P3 P4 P5 ** -** This opcode works just like OP_Next except that if cursor P1 is not +** This opcode works just like Next except that if cursor P1 is not ** open it behaves a no-op. */ /* Opcode: Prev P1 P2 P3 P4 P5 @@ -4604,9 +4617,9 @@ case OP_Rewind: { /* jump */ ** jump immediately to P2. ** ** -** The OP_Prev opcode is only valid following an OP_SeekLT, OP_SeekLE, or -** OP_Last opcode used to position the cursor. OP_Prev is not allowed -** to follow OP_SeekGT, OP_SeekGE, or OP_Rewind. +** The Prev opcode is only valid following an SeekLT, SeekLE, or +** OP_Last opcode used to position the cursor. Prev is not allowed +** to follow SeekGT, SeekGE, or OP_Rewind. ** ** The P1 cursor must be for a real table, not a pseudo-table. If P1 is ** not open then the behavior is undefined. @@ -4624,7 +4637,7 @@ case OP_Rewind: { /* jump */ */ /* Opcode: PrevIfOpen P1 P2 P3 P4 P5 ** -** This opcode works just like OP_Prev except that if cursor P1 is not +** This opcode works just like Prev except that if cursor P1 is not ** open it behaves a no-op. */ case OP_SorterNext: { /* jump */ @@ -5145,7 +5158,8 @@ case OP_LoadAnalysis: { ** ** Remove the internal (in-memory) data structures that describe ** the table named P4 in database P1. This is called after a table -** is dropped in order to keep the internal representation of the +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the ** schema consistent with what is on disk. */ case OP_DropTable: { @@ -5157,7 +5171,8 @@ case OP_DropTable: { ** ** Remove the internal (in-memory) data structures that describe ** the index named P4 in database P1. This is called after an index -** is dropped in order to keep the internal representation of the +** is dropped from disk (using the Destroy opcode) +** in order to keep the internal representation of the ** schema consistent with what is on disk. */ case OP_DropIndex: { @@ -5169,7 +5184,8 @@ case OP_DropIndex: { ** ** Remove the internal (in-memory) data structures that describe ** the trigger named P4 in database P1. This is called after a trigger -** is dropped in order to keep the internal representation of the +** is dropped from disk (using the Destroy opcode) in order to keep +** the internal representation of the ** schema consistent with what is on disk. */ case OP_DropTrigger: { From eac5bd78704006937a9bb5bee2dd724c7682b5e9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 25 Jul 2014 21:35:39 +0000 Subject: [PATCH 08/11] Try to fix harmless compiler warnings reported by Fortify. FossilOrigin-Name: e0fa6fdc14ac5458f9200cbae124f8025ea534ea --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.c | 2 +- src/pragma.c | 4 ++-- src/sqliteInt.h | 2 +- src/vdbeaux.c | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 34fbf9cae2..1097f4e5de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sVDBE\sopcodes,\sfor\sbetter\sdocumentation.\s\sNo\scode\nor\slogic\schanges. -D 2014-07-25T18:37:42.754 +C Try\sto\sfix\sharmless\scompiler\swarnings\sreported\sby\sFortify. +D 2014-07-25T21:35:39.767 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -167,7 +167,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c +F src/btree.c b5531339cd826af46b9621e4a9323971a9380e12 F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/build.c 48f400fa14fd6add244b954ce7e223ce7ccacf0b @@ -216,7 +216,7 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c e17c5ea1cb9eb9d93c41bbb7c3a17e747d5e0335 +F src/pragma.c 30f3b2ac09fef58320375d78e0e18b976198fc69 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c af06f66927919730f03479fed6ae9854f73419f4 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -227,7 +227,7 @@ F src/shell.c 191129c3f7a9cf241aea90ff6a6be3e74d3767f0 F src/sqlite.h.in ac4451c9da2771d2f4d702ef89722407242906d9 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 152134c6223369e2e1acb7b9cc2c0db052dae28a +F src/sqliteInt.h 068e42f41a09ce6b9edbe194ac8a470ab53145df F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -287,7 +287,7 @@ F src/vdbe.c b7af861342a215c7f27d3f20d92fe0b70f54fb3e F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 -F src/vdbeaux.c 1ffe0bbc3a2c8aedd95622de9be6b6d07b3d3c6b +F src/vdbeaux.c ac063f36c929f88bf6cecdbcc413000e272265bb F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394 F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2230c74f1efa591770176c9b40e920724a3c39e1 -R 29600123a95daa5177cd67bf8abb597c +P 2d32e4876e0b162730f81e5c2658be12d64a9a99 +R 863e6abd5a7272b515477418397f96e6 U drh -Z 36e2e79e107a063c258f47507608b039 +Z f462357bfa110cd51b2e07287181f811 diff --git a/manifest.uuid b/manifest.uuid index a16837f979..908cd7712f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2d32e4876e0b162730f81e5c2658be12d64a9a99 \ No newline at end of file +e0fa6fdc14ac5458f9200cbae124f8025ea534ea \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9032a9304c..b72a2ab01d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1632,7 +1632,7 @@ static Pgno btreePagecount(BtShared *pBt){ u32 sqlite3BtreeLastPage(Btree *p){ assert( sqlite3BtreeHoldsMutex(p) ); assert( ((p->pBt->nPage)&0x8000000)==0 ); - return (int)btreePagecount(p->pBt); + return btreePagecount(p->pBt); } /* diff --git a/src/pragma.c b/src/pragma.c index 709662c989..c4374cc71c 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -480,7 +480,7 @@ static const struct sPragmaNames { ** to support legacy SQL code. The safety level used to be boolean ** and older scripts may have used numbers 0 for OFF and 1 for ON. */ -static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ +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}; @@ -502,7 +502,7 @@ static u8 getSafetyLevel(const char *z, int omitFull, int dflt){ /* ** Interpret the given string as a boolean value. */ -u8 sqlite3GetBoolean(const char *z, int dflt){ +u8 sqlite3GetBoolean(const char *z, u8 dflt){ return getSafetyLevel(z,1,dflt)!=0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7a5d225b84..5d72295d66 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3364,7 +3364,7 @@ void sqlite3FileSuffix3(const char*, char*); #else # define sqlite3FileSuffix3(X,Y) #endif -u8 sqlite3GetBoolean(const char *z,int); +u8 sqlite3GetBoolean(const char *z,u8); const void *sqlite3ValueText(sqlite3_value*, u8); int sqlite3ValueBytes(sqlite3_value*, u8); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ac945df59e..240085bfbf 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2786,7 +2786,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ */ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ int flags = pMem->flags; - int n; + u32 n; if( flags&MEM_Null ){ return 0; @@ -2816,11 +2816,11 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){ return 7; } assert( pMem->db->mallocFailed || flags&(MEM_Str|MEM_Blob) ); - n = pMem->n; + assert( pMem->n>=0 ); + n = (u32)pMem->n; if( flags & MEM_Zero ){ n += pMem->u.nZero; } - assert( n>=0 ); return ((n*2) + 12 + ((flags&MEM_Str)!=0)); } From 975b4c6e8bc70bfb0d8f29107d393f692d162a69 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Jul 2014 16:47:23 +0000 Subject: [PATCH 09/11] Avoid unnecessary no-op calls to applyNumericAffinity() for a small performance improvement. FossilOrigin-Name: 413d7287977702fa651c0140bd5cf29021fe3e79 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 32 ++++++++++++++++---------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 1097f4e5de..480568c8f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Try\sto\sfix\sharmless\scompiler\swarnings\sreported\sby\sFortify. -D 2014-07-25T21:35:39.767 +C Avoid\sunnecessary\sno-op\scalls\sto\sapplyNumericAffinity()\sfor\sa\ssmall\nperformance\simprovement. +D 2014-07-26T16:47:23.387 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,7 +283,7 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c b7af861342a215c7f27d3f20d92fe0b70f54fb3e +F src/vdbe.c 145f909c1c7b16b0899bcab8b241b811e4af9534 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 2d32e4876e0b162730f81e5c2658be12d64a9a99 -R 863e6abd5a7272b515477418397f96e6 +P e0fa6fdc14ac5458f9200cbae124f8025ea534ea +R 497e2677c499db4d4a797e5c1acd577b U drh -Z f462357bfa110cd51b2e07287181f811 +Z ee817a86e8cc0ab5547d2241830d36e2 diff --git a/manifest.uuid b/manifest.uuid index 908cd7712f..06b44f1d10 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0fa6fdc14ac5458f9200cbae124f8025ea534ea \ No newline at end of file +413d7287977702fa651c0140bd5cf29021fe3e79 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e53b9251a3..49183129aa 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -224,21 +224,21 @@ static VdbeCursor *allocateCursor( ** look like a number, leave it alone. */ static void applyNumericAffinity(Mem *pRec){ - if( (pRec->flags & (MEM_Real|MEM_Int))==0 ){ - double rValue; - i64 iValue; - u8 enc = pRec->enc; - if( (pRec->flags&MEM_Str)==0 ) return; - if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; - if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ - pRec->u.i = iValue; - pRec->flags |= MEM_Int; - }else{ - pRec->r = rValue; - pRec->flags |= MEM_Real; - } + double rValue; + i64 iValue; + u8 enc = pRec->enc; + if( (pRec->flags&MEM_Str)==0 ) return; + if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; + if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ + pRec->u.i = iValue; + pRec->flags |= MEM_Int; + }else{ + pRec->r = rValue; + pRec->flags |= MEM_Real; } } +#define ApplyNumericAffinity(X) \ + if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);} /* ** Processing is determine by the affinity parameter: @@ -275,7 +275,7 @@ static void applyAffinity( }else if( affinity!=SQLITE_AFF_NONE ){ assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL || affinity==SQLITE_AFF_NUMERIC ); - applyNumericAffinity(pRec); + ApplyNumericAffinity(pRec); if( pRec->flags & MEM_Real ){ sqlite3VdbeIntegerAffinity(pRec); } @@ -292,7 +292,7 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){ int eType = sqlite3_value_type(pVal); if( eType==SQLITE_TEXT ){ Mem *pMem = (Mem*)pVal; - applyNumericAffinity(pMem); + ApplyNumericAffinity(pMem); eType = sqlite3_value_type(pVal); } return eType; @@ -3597,7 +3597,7 @@ case OP_SeekGT: { /* jump, in3 */ ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ pIn3 = &aMem[pOp->p3]; - applyNumericAffinity(pIn3); + ApplyNumericAffinity(pIn3); iKey = sqlite3VdbeIntValue(pIn3); pC->rowidIsValid = 0; From e6bc1ef68f17e438e91169d4c97cc03cb03aac2e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Jul 2014 20:12:56 +0000 Subject: [PATCH 10/11] Remove an unreachable branch from the sqlite3_value_numeric_type() interface. FossilOrigin-Name: 5350229b52b18a4961858a30538c5c75e5bd3048 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 480568c8f0..4de9f86a27 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sno-op\scalls\sto\sapplyNumericAffinity()\sfor\sa\ssmall\nperformance\simprovement. -D 2014-07-26T16:47:23.387 +C Remove\san\sunreachable\sbranch\sfrom\sthe\ssqlite3_value_numeric_type()\sinterface. +D 2014-07-26T20:12:56.006 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -283,7 +283,7 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 145f909c1c7b16b0899bcab8b241b811e4af9534 +F src/vdbe.c b127f05ff110c1f640b5aff98fa57d5028c8f2ee F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbeInt.h f5513f2b5ac1e2c5128996c7ea23add256a301df F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P e0fa6fdc14ac5458f9200cbae124f8025ea534ea -R 497e2677c499db4d4a797e5c1acd577b +P 413d7287977702fa651c0140bd5cf29021fe3e79 +R 882befeb8b61995267c9bc4311daa690 U drh -Z ee817a86e8cc0ab5547d2241830d36e2 +Z 28fa8e103cbfa69958d1f03600e24fde diff --git a/manifest.uuid b/manifest.uuid index 06b44f1d10..58f6f007db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -413d7287977702fa651c0140bd5cf29021fe3e79 \ No newline at end of file +5350229b52b18a4961858a30538c5c75e5bd3048 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 49183129aa..a00a1da836 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -292,7 +292,7 @@ int sqlite3_value_numeric_type(sqlite3_value *pVal){ int eType = sqlite3_value_type(pVal); if( eType==SQLITE_TEXT ){ Mem *pMem = (Mem*)pVal; - ApplyNumericAffinity(pMem); + applyNumericAffinity(pMem); eType = sqlite3_value_type(pVal); } return eType; From 57ff60b19b7596ad8259694d77f7861a314a5189 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 29 Jul 2014 11:54:18 +0000 Subject: [PATCH 11/11] Have calls to the xFilter() method of rtree virtual tables ensure that cursor is initialized before proceeding. Fix for [d2889096e7bdeac]. FossilOrigin-Name: 8cc41b0bf365af47c2061ffe44c86018945dd239 --- ext/rtree/rtree.c | 6 +++++- ext/rtree/rtree1.test | 22 ++++++++++++++++++++++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 7b540b4be1..8150538d45 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1533,9 +1533,13 @@ static int rtreeFilter( rtreeReference(pRtree); + /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ freeCursorConstraints(pCsr); - pCsr->iStrategy = idxNum; + sqlite3_free(pCsr->aPoint); + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->iStrategy = idxNum; if( idxNum==1 ){ /* Special case - lookup by rowid. */ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index 9de5362781..0beb16cc94 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -33,6 +33,7 @@ set testprefix rtree1 # rtree-8.*: Test constrained scans of r-tree data. # # rtree-12.*: Test that on-conflict clauses are supported. +# rtree-13.*: Test that bug [d2889096e7bdeac6d] has been fixed. # ifcapable !rtree { @@ -513,4 +514,25 @@ foreach {tn sql_template testdata} { db close } } + +#------------------------------------------------------------------------- +# Test that bug [d2889096e7bdeac6d] has been fixed. +# +reset_db +do_execsql_test 13.1 { + CREATE VIRTUAL TABLE t9 USING rtree(id, xmin, xmax); + INSERT INTO t9 VALUES(1,0,0); + INSERT INTO t9 VALUES(2,0,0); + SELECT * FROM t9 WHERE id IN (1, 2); +} {1 0.0 0.0 2 0.0 0.0} + +do_execsql_test 13.2 { + WITH r(x) AS ( + SELECT 1 UNION ALL + SELECT 2 UNION ALL + SELECT 3 + ) + SELECT * FROM r CROSS JOIN t9 WHERE id=x; +} {1 1 0.0 0.0 2 2 0.0 0.0} + finish_test diff --git a/manifest b/manifest index 4de9f86a27..d1716a2069 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sfrom\sthe\ssqlite3_value_numeric_type()\sinterface. -D 2014-07-26T20:12:56.006 +C Have\scalls\sto\sthe\sxFilter()\smethod\sof\srtree\svirtual\stables\sensure\sthat\scursor\sis\sinitialized\sbefore\sproceeding.\sFix\sfor\s[d2889096e7bdeac]. +D 2014-07-29T11:54:18.063 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -122,9 +122,9 @@ F ext/misc/vfslog.c fe40fab5c077a40477f7e5eba994309ecac6cc95 F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/rtree.c 6f70db93e0e42c369325c5cddcf2024c5a87ca43 +F ext/rtree/rtree.c 57bec53e1a677ab74217fe1f20a58c3a47261d6b F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e -F ext/rtree/rtree1.test e2da4aaa426918d27122d1a1066c6ecf8409a514 +F ext/rtree/rtree1.test 541bbcab74613907fea08b2ecdcdd5b7aa724cc9 F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree3.test a494da55c30ee0bc9b01a91c80c81b387b22d2dc F ext/rtree/rtree4.test c8fe384f60ebd49540a5fecc990041bf452eb6e0 @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 413d7287977702fa651c0140bd5cf29021fe3e79 -R 882befeb8b61995267c9bc4311daa690 -U drh -Z 28fa8e103cbfa69958d1f03600e24fde +P 5350229b52b18a4961858a30538c5c75e5bd3048 +R 0da0b70a772b464fda61490d5328a931 +U dan +Z f2b0f473c1ab5a411c1b4bc1349722f0 diff --git a/manifest.uuid b/manifest.uuid index 58f6f007db..b934c9dde5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5350229b52b18a4961858a30538c5c75e5bd3048 \ No newline at end of file +8cc41b0bf365af47c2061ffe44c86018945dd239 \ No newline at end of file