From 052e6a8a070165905197b523b880d439baecfe10 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Nov 2013 19:34:10 +0000 Subject: [PATCH 01/78] Remove an unused local variable. FossilOrigin-Name: 10d59226382adcb8016fc2d927e5a0c0b36f3980 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index efb3c6127d..0c330d29ec 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\sprogress\scallback\scheck.\sOn\sbranch\sremoved. -D 2013-11-14T00:09:48.126 +C Remove\san\sunused\slocal\svariable. +D 2013-11-14T19:34:10.694 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 2eb88f96a73d77bd61d6afd50c33ec5d63c15dd5 +F src/where.c 9d0b21b65b3d1c9f923b5c6bd0ba250dcd16b645 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 21f59b04f74738d08ebad693646bbaea24dc45ef -R 5afe90b6493eb21de1d0af561cfa69c0 +P 24ef16548eebcdb9d8b40308f6a16dabf8f8d474 +R 0c320313c4ba09b8dc172b3453c72ead U drh -Z d0339b99c91e151f95c1864799fb36e8 +Z bae383cbfc07908bca5c1197a0c507b6 diff --git a/manifest.uuid b/manifest.uuid index 56997654db..7086a9bfd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24ef16548eebcdb9d8b40308f6a16dabf8f8d474 \ No newline at end of file +10d59226382adcb8016fc2d927e5a0c0b36f3980 \ No newline at end of file diff --git a/src/where.c b/src/where.c index c4f25675c2..05d379fb89 100644 --- a/src/where.c +++ b/src/where.c @@ -2987,7 +2987,6 @@ static Bitmask codeOneLoopStart( OP_IdxLT /* 2: (end_constraints && bRev) */ }; u16 nEq = pLoop->u.btree.nEq; /* Number of == or IN terms */ - u16 nSkip = pLoop->u.btree.nSkip; /* Number of left index terms to skip */ int isMinQuery = 0; /* If this is an optimized SELECT min(x).. */ int regBase; /* Base register holding constraint values */ int r1; /* Temp register */ @@ -3006,7 +3005,7 @@ static Bitmask codeOneLoopStart( pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; - assert( nEq>=nSkip ); + assert( nEq>=pLoop->u.btree.nSkip ); /* If this loop satisfies a sort order (pOrderBy) request that ** was passed to this function to implement a "SELECT min(x) ..." @@ -3020,7 +3019,7 @@ static Bitmask codeOneLoopStart( && (pWInfo->bOBSat!=0) && (pIdx->nKeyCol>nEq) ){ - assert( nSkip==0 ); + assert( pLoop->u.btree.nSkip==0 ); isMinQuery = 1; nExtraReg = 1; } From 01752bc805d5e1b2da2951dd7b84bf1526e029ad Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 14 Nov 2013 23:59:33 +0000 Subject: [PATCH 02/78] Adjust the command-line shell EXPLAIN indentation logic to handle the second loop of an UPDATE that reads out a RowSet. FossilOrigin-Name: ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 9 +++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0c330d29ec..7db6c41970 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunused\slocal\svariable. -D 2013-11-14T19:34:10.694 +C Adjust\sthe\scommand-line\sshell\sEXPLAIN\sindentation\slogic\sto\shandle\sthe\nsecond\sloop\sof\san\sUPDATE\sthat\sreads\sout\sa\sRowSet. +D 2013-11-14T23:59:33.676 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c fc4673cc49b116e51e7f12de074c0acf8f2388f9 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 7317406831ecced390edba972818f3c5f82238c0 -F src/shell.c 6ccc22b717afe4f6d7d3c8b6baa02e3b99a5fdf0 +F src/shell.c 65a259d538b283e190708b43ece0d596563097f8 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 24ef16548eebcdb9d8b40308f6a16dabf8f8d474 -R 0c320313c4ba09b8dc172b3453c72ead +P 10d59226382adcb8016fc2d927e5a0c0b36f3980 +R e492370754f541158ba25713cf44bfcb U drh -Z bae383cbfc07908bca5c1197a0c507b6 +Z 035eb0414986ea339898609e92b31744 diff --git a/manifest.uuid b/manifest.uuid index 7086a9bfd6..57c65bfa2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10d59226382adcb8016fc2d927e5a0c0b36f3980 \ No newline at end of file +ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 61df7d6d52..6485fad7b9 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1173,9 +1173,10 @@ static int str_in_array(const char *zStr, const char **azArray){ ** all opcodes that occur between the p2 jump destination and the opcode ** itself by 2 spaces. ** -** * For each "Goto", if the jump destination is a "Yield", "SeekGt", -** or "SeekLt" instruction that occurs earlier in the program than -** the Goto itself, indent all opcodes between the earlier instruction +** * For each "Goto", if the jump destination is earlier in the program +** and ends on one of: +** Yield SeekGt SeekLt RowSetRead +** then indent all opcodes between the earlier instruction ** and "Goto" by 2 spaces. */ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ @@ -1186,7 +1187,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ int iOp; const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", 0 }; - const char *azYield[] = { "Yield", "SeekLt", "SeekGt", 0 }; + const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 }; const char *azGoto[] = { "Goto", 0 }; /* Try to figure out if this is really an EXPLAIN statement. If this From f30a969b80ec4f06c97a30cc7cd9471adcd52863 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 01:10:18 +0000 Subject: [PATCH 03/78] Rework the logic that factors constant expressions out of inner loops, making it both simpler and faster. FossilOrigin-Name: 8dc5c76c766828d7c28090bec30ff48227e7b140 --- manifest | 31 +++++---- manifest.uuid | 2 +- src/backup.c | 1 + src/build.c | 25 ++++--- src/expr.c | 175 ++++++++++-------------------------------------- src/prepare.c | 8 +++ src/sqliteInt.h | 3 +- src/trigger.c | 1 + src/vdbeblob.c | 1 + src/vtab.c | 1 + src/where.c | 1 - 11 files changed, 82 insertions(+), 167 deletions(-) diff --git a/manifest b/manifest index 7db6c41970..f7ec2db29b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\scommand-line\sshell\sEXPLAIN\sindentation\slogic\sto\shandle\sthe\nsecond\sloop\sof\san\sUPDATE\sthat\sreads\sout\sa\sRowSet. -D 2013-11-14T23:59:33.676 +C Rework\sthe\slogic\sthat\sfactors\sconstant\sexpressions\sout\sof\sinner\sloops,\smaking\nit\sboth\ssimpler\sand\sfaster. +D 2013-11-15T01:10:18.507 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,19 +163,19 @@ F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083 F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 -F src/backup.c 2f1987981139bd2f6d8c728d64bf09fb387443c3 +F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 260dedc13119e6fb7930380bd3d294b98362bf5a F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 2baeed38bdaa9f1199f101c63db41fdcc4b39ba5 +F src/build.c 5b744617019f6011ee35a88fe046f3fdf6f85c53 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef -F src/expr.c e7bbe3c6916e141f27a28655d3cf325b817695e4 +F src/expr.c b54ac7b5a77cf2967b4194aba95005544e8b705e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 @@ -214,7 +214,7 @@ F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 F src/pragma.c c8d70c47ec8d8ba93575d92e34d30ddff8e9b517 -F src/prepare.c fa6988589f39af8504a61731614cd4f6ae71554f +F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c fc4673cc49b116e51e7f12de074c0acf8f2388f9 @@ -224,7 +224,7 @@ F src/shell.c 65a259d538b283e190708b43ece0d596563097f8 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 2ec1d71220307fa5ee85a918a6240cf0b4635b0e +F src/sqliteInt.h c5dfd52fcc677725c750b1570b090f70a5cb60ec F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -275,7 +275,7 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9 F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 -F src/trigger.c 53d6b5d50b3b23d4fcd0a36504feb5cff9aed716 +F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c 3de7e657b98ac67338d775c114a4068faf732402 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 @@ -285,15 +285,15 @@ F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c dd0f6ab9dc159911facfc0a7a2164af44779bdda -F src/vdbeblob.c ff60adf2953e0ffc1d59541b3101c9886b03a3de +F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc -F src/vtab.c 5a423b042eb1402ef77697d03d6a67378d97bc8d +F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 9d0b21b65b3d1c9f923b5c6bd0ba250dcd16b645 +F src/where.c 9bff77c96e40bf472050bee6b2f7db8ed8e4402d F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1139,7 +1139,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 10d59226382adcb8016fc2d927e5a0c0b36f3980 -R e492370754f541158ba25713cf44bfcb +P ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 +R ea4290df34dfa387f06721fb8b8fabb6 +T *branch * expr-codegen-enhancement +T *sym-expr-codegen-enhancement * +T -sym-trunk * U drh -Z 035eb0414986ea339898609e92b31744 +Z 42026cbf90dc1d9e1d914e786ac618c6 diff --git a/manifest.uuid b/manifest.uuid index 57c65bfa2d..95628cd332 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 \ No newline at end of file +8dc5c76c766828d7c28090bec30ff48227e7b140 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index afbaeeb109..1bac821f3f 100644 --- a/src/backup.c +++ b/src/backup.c @@ -96,6 +96,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ rc = SQLITE_ERROR; } sqlite3DbFree(pErrorDb, pParse->zErrMsg); + sqlite3ParserReset(pParse); sqlite3StackFree(pErrorDb, pParse); } if( rc ){ diff --git a/src/build.c b/src/build.c index d1615a128d..68d71da4ee 100644 --- a/src/build.c +++ b/src/build.c @@ -150,7 +150,7 @@ void sqlite3FinishCoding(Parse *pParse){ */ if( pParse->cookieGoto>0 ){ yDbMask mask; - int iDb; + int iDb, i, addr; sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDbnDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; @@ -164,14 +164,11 @@ void sqlite3FinishCoding(Parse *pParse){ } } #ifndef SQLITE_OMIT_VIRTUALTABLE - { - int i; - for(i=0; inVtabLock; i++){ - char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); - sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); - } - pParse->nVtabLock = 0; + for(i=0; inVtabLock; i++){ + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); } + pParse->nVtabLock = 0; #endif /* Once all the cookies have been verified and transactions opened, @@ -184,8 +181,18 @@ void sqlite3FinishCoding(Parse *pParse){ */ sqlite3AutoincrementBegin(pParse); + /* Code constant expressions that where factored out of inner loops */ + addr = pParse->cookieGoto; + if( pParse->pConstExpr ){ + ExprList *pEL = pParse->pConstExpr; + pParse->cookieGoto = 0; + for(i=0; inExpr; i++){ + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].iAlias); + } + } + /* Finally, jump back to the beginning of the executable code. */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); } } diff --git a/src/expr.c b/src/expr.c index 7e72b44f96..524f24cbb3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2989,15 +2989,42 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ** If the register is a temporary register that can be deallocated, ** then write its number into *pReg. If the result register is not ** a temporary, then set *pReg to zero. +** +** If pExpr is a constant, then this routine might generate this +** code to fill the register in the initialization section of the +** VDBE program, in order to factor it out of the evaluation loop. */ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ - int r1 = sqlite3GetTempReg(pParse); - int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); - if( r2==r1 ){ - *pReg = r1; + int r2; + pExpr = sqlite3ExprSkipCollate(pExpr); + if( pParse->cookieGoto>0 + && pParse->nMem<32768 + && pExpr->op!=TK_REGISTER + && sqlite3ExprIsConstantNotJoin(pExpr) + ){ + ExprList *p = pParse->pConstExpr; + int i; + *pReg = 0; + if( p ){ + for(i=0; inExpr; i++){ + if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){ + return p->a[i].iAlias; + } + } + } + p = sqlite3ExprListAppend(pParse, p, sqlite3ExprDup(pParse->db, pExpr, 0)); + pParse->pConstExpr = p; + r2 = ++pParse->nMem; + if( p ) p->a[p->nExpr-1].iAlias = r2; }else{ - sqlite3ReleaseTempReg(pParse, r1); - *pReg = 0; + int r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); + if( r2==r1 ){ + *pReg = r1; + }else{ + sqlite3ReleaseTempReg(pParse, r1); + *pReg = 0; + } } return r2; } @@ -3328,140 +3355,6 @@ void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ } #endif /* SQLITE_DEBUG */ -/* -** Return TRUE if pExpr is an constant expression that is appropriate -** for factoring out of a loop. Appropriate expressions are: -** -** * Any expression that evaluates to two or more opcodes. -** -** * Any OP_Integer, OP_Real, OP_String, OP_Blob, OP_Null, -** or OP_Variable that does not need to be placed in a -** specific register. -** -** There is no point in factoring out single-instruction constant -** expressions that need to be placed in a particular register. -** We could factor them out, but then we would end up adding an -** OP_SCopy instruction to move the value into the correct register -** later. We might as well just use the original instruction and -** avoid the OP_SCopy. -*/ -static int isAppropriateForFactoring(Expr *p){ - if( !sqlite3ExprIsConstantNotJoin(p) ){ - return 0; /* Only constant expressions are appropriate for factoring */ - } - if( (p->flags & EP_FixedDest)==0 ){ - return 1; /* Any constant without a fixed destination is appropriate */ - } - while( p->op==TK_UPLUS ) p = p->pLeft; - switch( p->op ){ -#ifndef SQLITE_OMIT_BLOB_LITERAL - case TK_BLOB: -#endif - case TK_VARIABLE: - case TK_INTEGER: - case TK_FLOAT: - case TK_NULL: - case TK_STRING: { - testcase( p->op==TK_BLOB ); - testcase( p->op==TK_VARIABLE ); - testcase( p->op==TK_INTEGER ); - testcase( p->op==TK_FLOAT ); - testcase( p->op==TK_NULL ); - testcase( p->op==TK_STRING ); - /* Single-instruction constants with a fixed destination are - ** better done in-line. If we factor them, they will just end - ** up generating an OP_SCopy to move the value to the destination - ** register. */ - return 0; - } - case TK_UMINUS: { - if( p->pLeft->op==TK_FLOAT || p->pLeft->op==TK_INTEGER ){ - return 0; - } - break; - } - default: { - break; - } - } - return 1; -} - -/* -** If pExpr is a constant expression that is appropriate for -** factoring out of a loop, then evaluate the expression -** into a register and convert the expression into a TK_REGISTER -** expression. -*/ -static int evalConstExpr(Walker *pWalker, Expr *pExpr){ - Parse *pParse = pWalker->pParse; - switch( pExpr->op ){ - case TK_IN: - case TK_REGISTER: { - return WRC_Prune; - } - case TK_COLLATE: { - return WRC_Continue; - } - case TK_FUNCTION: - case TK_AGG_FUNCTION: - case TK_CONST_FUNC: { - /* The arguments to a function have a fixed destination. - ** Mark them this way to avoid generated unneeded OP_SCopy - ** instructions. - */ - ExprList *pList = pExpr->x.pList; - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - if( pList ){ - int i = pList->nExpr; - struct ExprList_item *pItem = pList->a; - for(; i>0; i--, pItem++){ - if( ALWAYS(pItem->pExpr) ) pItem->pExpr->flags |= EP_FixedDest; - } - } - break; - } - } - if( isAppropriateForFactoring(pExpr) ){ - int r1 = ++pParse->nMem; - int r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); - /* If r2!=r1, it means that register r1 is never used. That is harmless - ** but suboptimal, so we want to know about the situation to fix it. - ** Hence the following assert: */ - assert( r2==r1 ); - exprToRegister(pExpr, r2); - return WRC_Prune; - } - return WRC_Continue; -} - -/* -** Preevaluate constant subexpressions within pExpr and store the -** results in registers. Modify pExpr so that the constant subexpresions -** are TK_REGISTER opcodes that refer to the precomputed values. -** -** This routine is a no-op if the jump to the cookie-check code has -** already occur. Since the cookie-check jump is generated prior to -** any other serious processing, this check ensures that there is no -** way to accidently bypass the constant initializations. -** -** This routine is also a no-op if the SQLITE_FactorOutConst optimization -** is disabled via the sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) -** interface. This allows test logic to verify that the same answer is -** obtained for queries regardless of whether or not constants are -** precomputed into registers or if they are inserted in-line. -*/ -void sqlite3ExprCodeConstants(Parse *pParse, Expr *pExpr){ - Walker w; - if( pParse->cookieGoto ) return; - if( OptimizationDisabled(pParse->db, SQLITE_FactorOutConst) ) return; - memset(&w, 0, sizeof(w)); - w.xExprCallback = evalConstExpr; - w.pParse = pParse; - sqlite3WalkExpr(&w, pExpr); -} - - /* ** Generate code that pushes the value of every element of the given ** expression list into a sequence of registers beginning at target. @@ -3863,7 +3756,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && pA->op!=TK_REGISTER - && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; + && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; if( ExprHasProperty(pA, EP_IntValue) ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ return 2; diff --git a/src/prepare.c b/src/prepare.c index cfc9c34855..7ea7f3bd68 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -524,6 +524,13 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ return i; } +/* +** Free all memory allocations in the pParse object +*/ +void sqlite3ParserReset(Parse *pParse){ + if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr); +} + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -681,6 +688,7 @@ static int sqlite3Prepare( end_prepare: + sqlite3ParserReset(pParse); sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8838f7aa92..22eaafb330 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2278,6 +2278,7 @@ struct Parse { int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ + ExprList *pConstExpr;/* Constant expressions */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ @@ -2891,7 +2892,6 @@ int sqlite3ExprCode(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); -void sqlite3ExprCodeConstants(Parse*, Expr*); int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); @@ -3259,6 +3259,7 @@ void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); +void sqlite3ParserReset(Parse*); int sqlite3Reprepare(Vdbe*); void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); diff --git a/src/trigger.c b/src/trigger.c index 607b831243..1c68a708dd 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -924,6 +924,7 @@ static TriggerPrg *codeRowTrigger( assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); + sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); return pPrg; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 0c4ebf6e44..a90c5b0af4 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -328,6 +328,7 @@ blob_open_out: } sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); + sqlite3ParserReset(pParse); sqlite3StackFree(db, pParse); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); diff --git a/src/vtab.c b/src/vtab.c index 195aa68b25..ca0db214cc 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -738,6 +738,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3VdbeFinalize(pParse->pVdbe); } sqlite3DeleteTable(db, pParse->pNewTable); + sqlite3ParserReset(pParse); sqlite3StackFree(db, pParse); } diff --git a/src/where.c b/src/where.c index 05d379fb89..f6747630c1 100644 --- a/src/where.c +++ b/src/where.c @@ -5426,7 +5426,6 @@ WhereInfo *sqlite3WhereBegin( */ initMaskSet(pMaskSet); whereClauseInit(&pWInfo->sWC, pWInfo); - sqlite3ExprCodeConstants(pParse, pWhere); whereSplit(&pWInfo->sWC, pWhere, TK_AND); sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */ From 602320e326997d4aa1e9b49e0a42f84bd0faac79 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 03:16:34 +0000 Subject: [PATCH 04/78] Another adjustment to the EXPLAIN indentation logic, in order to deal with the sorter loop on a CREATE INDEX statement. FossilOrigin-Name: cbe85cc2a991d89a6cca391ffa1be0582a684e49 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7db6c41970..551ac0d8a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\scommand-line\sshell\sEXPLAIN\sindentation\slogic\sto\shandle\sthe\nsecond\sloop\sof\san\sUPDATE\sthat\sreads\sout\sa\sRowSet. -D 2013-11-14T23:59:33.676 +C Another\sadjustment\sto\sthe\sEXPLAIN\sindentation\slogic,\sin\sorder\sto\sdeal\swith\nthe\ssorter\sloop\son\sa\sCREATE\sINDEX\sstatement. +D 2013-11-15T03:16:34.575 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c fc4673cc49b116e51e7f12de074c0acf8f2388f9 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 7317406831ecced390edba972818f3c5f82238c0 -F src/shell.c 65a259d538b283e190708b43ece0d596563097f8 +F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 10d59226382adcb8016fc2d927e5a0c0b36f3980 -R e492370754f541158ba25713cf44bfcb +P ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 +R 14569e96bfa99ce52d2e8d8452a6eab6 U drh -Z 035eb0414986ea339898609e92b31744 +Z 75087cf5e4d4f5ef7b9253ba0c460b7b diff --git a/manifest.uuid b/manifest.uuid index 57c65bfa2d..064ef8708e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 \ No newline at end of file +cbe85cc2a991d89a6cca391ffa1be0582a684e49 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 6485fad7b9..35fe970382 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1186,7 +1186,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", 0 }; + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 }; const char *azGoto[] = { "Goto", 0 }; From 72dbffd726153324061c78dcbf01404b260524fb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 03:21:43 +0000 Subject: [PATCH 05/78] Fix a typo in the "synopsis" for the OP_Lt opcode that causes an incorrect comment to be added to EXPLAIN output. FossilOrigin-Name: d99a30a25d6102c389f1fb5ec389c137168615e9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 551ac0d8a1..f194ea4c79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sadjustment\sto\sthe\sEXPLAIN\sindentation\slogic,\sin\sorder\sto\sdeal\swith\nthe\ssorter\sloop\son\sa\sCREATE\sINDEX\sstatement. -D 2013-11-15T03:16:34.575 +C Fix\sa\stypo\sin\sthe\s"synopsis"\sfor\sthe\sOP_Lt\sopcode\sthat\scauses\san\s\nincorrect\scomment\sto\sbe\sadded\sto\sEXPLAIN\soutput. +D 2013-11-15T03:21:43.898 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c 3de7e657b98ac67338d775c114a4068faf732402 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c f9a4e08114f97e453a5f13a62c31a357301137cc +F src/vdbe.c d53b6b7e721b18c42754f10d68e75845e387f2ba F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ea141a9b87dbb5fa1402bf7f6e36e89cc9de3cb3 -R 14569e96bfa99ce52d2e8d8452a6eab6 +P cbe85cc2a991d89a6cca391ffa1be0582a684e49 +R 0c746aa4efd05e48b97b713c68a5a0db U drh -Z 75087cf5e4d4f5ef7b9253ba0c460b7b +Z 51d93302282dc3095ac1b627e9f3a079 diff --git a/manifest.uuid b/manifest.uuid index 064ef8708e..cbca5b1319 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cbe85cc2a991d89a6cca391ffa1be0582a684e49 \ No newline at end of file +d99a30a25d6102c389f1fb5ec389c137168615e9 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f70870ca63..c67a347b4c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1797,7 +1797,7 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ #endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */ /* Opcode: Lt P1 P2 P3 P4 P5 -** Synopsis: if r[P1] Date: Fri, 15 Nov 2013 12:41:01 +0000 Subject: [PATCH 06/78] Simplify the range scan code generate while also avoiding an unnecessary OP_Affinity opcode. FossilOrigin-Name: 372686bfbb1da08b04bddb085e30da5dbc8b30d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 23 ++++++++--------------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 22cb55c85f..f1e6876892 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sEXPLAIN\sfixes\sfrom\strunk. -D 2013-11-15T03:30:07.899 +C Simplify\sthe\srange\sscan\scode\sgenerate\swhile\salso\savoiding\san\sunnecessary\nOP_Affinity\sopcode. +D 2013-11-15T12:41:01.696 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 9bff77c96e40bf472050bee6b2f7db8ed8e4402d +F src/where.c 6e7e932ee32a4b2a0e4741880c06fe7a545e0059 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8dc5c76c766828d7c28090bec30ff48227e7b140 d99a30a25d6102c389f1fb5ec389c137168615e9 -R 55f9276a49bf042aa3fa36f2f4c874b2 +P cd579727b107a07140b94f5839d193959d29e6db +R 16d0a5bce69ca1eea8baa7da2e33f0a4 U drh -Z d11ec7b7307706d351f4407390565b7b +Z 29979dcda00f70bdf360a155d984f65d diff --git a/manifest.uuid b/manifest.uuid index 4b7d29ed45..73b69a2d01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd579727b107a07140b94f5839d193959d29e6db \ No newline at end of file +372686bfbb1da08b04bddb085e30da5dbc8b30d8 \ No newline at end of file diff --git a/src/where.c b/src/where.c index f6747630c1..9f4e23de3e 100644 --- a/src/where.c +++ b/src/where.c @@ -3001,7 +3001,7 @@ static Bitmask codeOneLoopStart( int nExtraReg = 0; /* Number of extra registers needed */ int op; /* Instruction opcode */ char *zStartAff; /* Affinity for start of range constraint */ - char *zEndAff; /* Affinity for end of range constraint */ + char cEndAff = 0; /* Affinity for end of range constraint */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -3042,7 +3042,8 @@ static Bitmask codeOneLoopStart( ** starting at regBase. */ regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); - zEndAff = sqlite3DbStrDup(db, zStartAff); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); + if( zStartAff ) cEndAff = zStartAff[nEq]; addrNxt = pLevel->addrNxt; /* If we are doing a reverse order scan on an ascending index, or @@ -3112,23 +3113,15 @@ static Bitmask codeOneLoopStart( if( (pRangeEnd->wtFlags & TERM_VNULL)==0 ){ sqlite3ExprCodeIsNullJump(v, pRight, regBase+nEq, addrNxt); } - if( zEndAff ){ - if( sqlite3CompareAffinity(pRight, zEndAff[nEq])==SQLITE_AFF_NONE){ - /* Since the comparison is to be performed with no conversions - ** applied to the operands, set the affinity to apply to pRight to - ** SQLITE_AFF_NONE. */ - zEndAff[nEq] = SQLITE_AFF_NONE; - } - if( sqlite3ExprNeedsNoAffinityChange(pRight, zEndAff[nEq]) ){ - zEndAff[nEq] = SQLITE_AFF_NONE; - } - } - codeApplyAffinity(pParse, regBase, nEq+1, zEndAff); + if( sqlite3CompareAffinity(pRight, cEndAff)!=SQLITE_AFF_NONE + && !sqlite3ExprNeedsNoAffinityChange(pRight, cEndAff) + ){ + codeApplyAffinity(pParse, regBase+nEq, 1, &cEndAff); + } nConstraint++; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); } sqlite3DbFree(db, zStartAff); - sqlite3DbFree(db, zEndAff); /* Top of the loop body */ pLevel->p2 = sqlite3VdbeCurrentAddr(v); From 776f3a2fa9dd7134755e72c7cf1583f4fdcbfd9a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 13:12:30 +0000 Subject: [PATCH 07/78] Add the --query option to the wordcount test program. FossilOrigin-Name: 5960d11eba4fc6ca136331279689424d03bd6e76 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wordcount.c | 42 +++++++++++++++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f194ea4c79..79187a0a85 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\s"synopsis"\sfor\sthe\sOP_Lt\sopcode\sthat\scauses\san\s\nincorrect\scomment\sto\sbe\sadded\sto\sEXPLAIN\soutput. -D 2013-11-15T03:21:43.898 +C Add\sthe\s--query\soption\sto\sthe\swordcount\stest\sprogram. +D 2013-11-15T13:12:30.792 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1087,7 +1087,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c 2c2cc1119de42e6730ca8bd149666f0e0095108a +F test/wordcount.c b8872ec44e8085bb671048a49cb696bed1100fe3 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cbe85cc2a991d89a6cca391ffa1be0582a684e49 -R 0c746aa4efd05e48b97b713c68a5a0db +P d99a30a25d6102c389f1fb5ec389c137168615e9 +R 0d314918704a2d9deceec12d1b561362 U drh -Z 51d93302282dc3095ac1b627e9f3a079 +Z 4de182ff7f969e11fcd8166760e38fe1 diff --git a/manifest.uuid b/manifest.uuid index cbca5b1319..d03acca621 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d99a30a25d6102c389f1fb5ec389c137168615e9 \ No newline at end of file +5960d11eba4fc6ca136331279689424d03bd6e76 \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index 2161c07174..f8bac4deb6 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -19,6 +19,7 @@ ** --select Use SELECT mode ** --update Use UPDATE mode ** --delete Use DELETE mode +** --query Use QUERY mode ** --nocase Add the NOCASE collating sequence to the words. ** --trace Enable sqlite3_trace() output. ** --summary Show summary information on the collected data. @@ -51,11 +52,15 @@ ** Delete mode means: ** (1) DELETE FROM wordcount WHERE word=$new ** -** Note that delete mode is only useful for preexisting databases. The -** wordcount table is created using IF NOT EXISTS so this utility can be -** run multiple times on the same database file. The --without-rowid, -** --nocase, and --pagesize parameters are only effective when creating -** a new database and are harmless no-ops on preexisting databases. +** Query mode means: +** (1) SELECT cnt FROM wordcount WHERE word=$new +** +** Note that delete mode and query mode are only useful for preexisting +** databases. The wordcount table is created using IF NOT EXISTS so this +** utility can be run multiple times on the same database file. The +** --without-rowid, --nocase, and --pagesize parameters are only effective +** when creating a new database and are harmless no-ops on preexisting +** databases. ** ****************************************************************************** ** @@ -170,6 +175,7 @@ static void checksumFinalize(sqlite3_context *context){ #define MODE_SELECT 2 #define MODE_UPDATE 3 #define MODE_DELETE 4 +#define MODE_QUERY 5 int main(int argc, char **argv){ const char *zFileToRead = 0; /* Input file. NULL for stdin */ @@ -196,6 +202,7 @@ int main(int argc, char **argv){ FILE *in; /* The open input file */ int rc; /* Return code from an SQLite interface */ int iCur, iHiwtr; /* Statistics values, current and "highwater" */ + sqlite3_int64 sumCnt = 0; /* Sum in QUERY mode */ char zInput[2000]; /* A single line of input */ /* Process command-line arguments */ @@ -215,6 +222,8 @@ int main(int argc, char **argv){ iMode = MODE_UPDATE; }else if( strcmp(z,"delete")==0 ){ iMode = MODE_DELETE; + }else if( strcmp(z,"query")==0 ){ + iMode = MODE_QUERY; }else if( strcmp(z,"nocase")==0 ){ useNocase = 1; }else if( strcmp(z,"trace")==0 ){ @@ -303,6 +312,13 @@ int main(int argc, char **argv){ sqlite3_free(zSql); /* Prepare SQL statements that will be needed */ + if( iMode==MODE_QUERY ){ + rc = sqlite3_prepare_v2(db, + "SELECT cnt FROM wordcount WHERE word=?1", + -1, &pSelect, 0); + if( rc ) fatal_error("Could not prepare the SELECT statement: %s\n", + sqlite3_errmsg(db)); + } if( iMode==MODE_SELECT ){ rc = sqlite3_prepare_v2(db, "SELECT 1 FROM wordcount WHERE word=?1", @@ -385,6 +401,12 @@ int main(int argc, char **argv){ }else{ fatal_error("SELECT failed: %s\n", sqlite3_errmsg(db)); } + }else if( iMode==MODE_QUERY ){ + sqlite3_bind_text(pSelect, 1, zInput+i, j-i, SQLITE_STATIC); + if( sqlite3_step(pSelect)==SQLITE_ROW ){ + sumCnt += sqlite3_column_int64(pSelect, 0); + } + sqlite3_reset(pSelect); }else{ sqlite3_bind_text(pInsert, 1, zInput+i, j-i, SQLITE_STATIC); if( sqlite3_step(pInsert)!=SQLITE_DONE ){ @@ -417,6 +439,16 @@ int main(int argc, char **argv){ sqlite3_finalize(pSelect); sqlite3_finalize(pDelete); + if( iMode==MODE_QUERY ){ + printf("sum of cnt: %lld\n", sumCnt); + rc = sqlite3_prepare_v2(db,"SELECT sum(cnt*cnt) FROM wordcount", -1, + &pSelect, 0); + if( rc==SQLITE_OK && sqlite3_step(pSelect)==SQLITE_ROW ){ + printf("double-check: %lld\n", sqlite3_column_int64(pSelect, 0)); + } + sqlite3_finalize(pSelect); + } + if( showSummary ){ sqlite3_create_function(db, "checksum", -1, SQLITE_UTF8, 0, 0, checksumStep, checksumFinalize); From 10d1edf0b6b114a00f897161fff7dec17a2b8183 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 15:52:39 +0000 Subject: [PATCH 08/78] Improvements to the Expr comparison routine to make it more general. Improvements to unary-minus code generation so that it can make use of a global constant register with a zero value. FossilOrigin-Name: 835be656bb0e83c8108104869166aa9dd850d265 --- manifest | 14 ++++++------ manifest.uuid | 2 +- src/expr.c | 57 +++++++++++++++++++++++++++---------------------- src/sqliteInt.h | 2 +- 4 files changed, 41 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index f1e6876892..b2dff6970f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\srange\sscan\scode\sgenerate\swhile\salso\savoiding\san\sunnecessary\nOP_Affinity\sopcode. -D 2013-11-15T12:41:01.696 +C Improvements\sto\sthe\sExpr\scomparison\sroutine\sto\smake\sit\smore\sgeneral.\nImprovements\sto\sunary-minus\scode\sgeneration\sso\sthat\sit\scan\smake\suse\sof\na\sglobal\sconstant\sregister\swith\sa\szero\svalue. +D 2013-11-15T15:52:39.123 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef -F src/expr.c b54ac7b5a77cf2967b4194aba95005544e8b705e +F src/expr.c eb7eb7fa7848dc4e3b67a2f0bf32f794804ca38a F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 @@ -224,7 +224,7 @@ F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h c5dfd52fcc677725c750b1570b090f70a5cb60ec +F src/sqliteInt.h 11b0dd04b1a2eb86a348fd818c7a63bf015cb0dd F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P cd579727b107a07140b94f5839d193959d29e6db -R 16d0a5bce69ca1eea8baa7da2e33f0a4 +P 372686bfbb1da08b04bddb085e30da5dbc8b30d8 +R a53a2df918863d2e307a62344ad87323 U drh -Z 29979dcda00f70bdf360a155d984f65d +Z a11accb78dd4b773c18bb01c1b2ffc18 diff --git a/manifest.uuid b/manifest.uuid index 73b69a2d01..05249a4c01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -372686bfbb1da08b04bddb085e30da5dbc8b30d8 \ No newline at end of file +835be656bb0e83c8108104869166aa9dd850d265 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 524f24cbb3..15b21d1dff 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2356,6 +2356,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ int regFree2 = 0; /* If non-zero free this temporary register */ int r1, r2, r3, r4; /* Various register numbers */ sqlite3 *db = pParse->db; /* The database connection */ + Expr tempX; /* Temporary expression node */ assert( target>0 && target<=pParse->nMem ); if( v==0 ){ @@ -2575,8 +2576,10 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ codeReal(v, pLeft->u.zToken, 1, target); #endif }else{ - regFree1 = r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Integer, 0, r1); + tempX.op = TK_INTEGER; + tempX.flags = EP_IntValue|EP_TokenOnly; + tempX.u.iValue = 0; + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); testcase( regFree2==0 ); @@ -2892,7 +2895,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ ExprList *pEList; /* List of WHEN terms */ struct ExprList_item *aListelem; /* Array of WHEN terms */ Expr opCompare; /* The X==Ei expression */ - Expr cacheX; /* Cached expression X */ Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ VVA_ONLY( int iCacheLevel = pParse->iCacheLevel; ) @@ -2904,13 +2906,13 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ nExpr = pEList->nExpr; endLabel = sqlite3VdbeMakeLabel(v); if( (pX = pExpr->pLeft)!=0 ){ - cacheX = *pX; + tempX = *pX; testcase( pX->op==TK_COLUMN ); testcase( pX->op==TK_REGISTER ); - exprToRegister(&cacheX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); + exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); testcase( regFree1==0 ); opCompare.op = TK_EQ; - opCompare.pLeft = &cacheX; + opCompare.pLeft = &tempX; pTest = &opCompare; /* Ticket b351d95f9cd5ef17e9d9dbae18f5ca8611190001: ** The value in regFree1 might get SCopy-ed into the file result. @@ -3732,16 +3734,18 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** an incorrect 0 or 1 could lead to a malfunction. */ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ - if( pA==0||pB==0 ){ + u32 combinedFlags; + if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; } - assert( !ExprHasProperty(pA, EP_TokenOnly|EP_Reduced) ); - assert( !ExprHasProperty(pB, EP_TokenOnly|EP_Reduced) ); - if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){ + combinedFlags = pA->flags | pB->flags; + if( combinedFlags & EP_IntValue ){ + if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){ + return 0; + } return 2; } - if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){ + if( pA->op!=pB->op /*&& (pA->op!=TK_REGISTER || pA->op2!=pB->op)*/ ){ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ return 1; } @@ -3750,23 +3754,26 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ } return 2; } - if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; - if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; - if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - if( pA->iColumn!=pB->iColumn ) return 2; - if( pA->iTable!=pB->iTable - && pA->op!=TK_REGISTER - && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; - if( ExprHasProperty(pA, EP_IntValue) ){ - if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ - return 2; - } - }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){ - if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; + if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken ){ if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return pA->op==TK_COLLATE ? 1 : 2; } } + if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; + testcase( combinedFlags & EP_TokenOnly ); + testcase( combinedFlags & EP_Reduced ); + if( (combinedFlags & EP_TokenOnly)==0 ){ + if( combinedFlags & EP_xIsSelect ) return 2; + if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + if( (combinedFlags & EP_Reduced)==0 ){ + if( pA->iColumn!=pB->iColumn ) return 2; + if( pA->iTable!=pB->iTable + && pA->op!=TK_REGISTER + && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; + } + } return 0; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 22eaafb330..9c4a9cc0b8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1829,7 +1829,7 @@ struct Expr { #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE opeartor */ -#define EP_FixedDest 0x000200 /* Result needed in a specific register */ + /* unused 0x000200 */ #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x001000 /* COLLATE, AS, or UNLIKELY */ From a0d6e3a501d543421db787fa230a2abdd1a34d39 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 16:48:23 +0000 Subject: [PATCH 09/78] Add test cases for INSERT INTO ... DEFAULT VALUES on tables with numeric constants in CHECK constraints. FossilOrigin-Name: 79ec485b548fcfc508c4d5fa32ed0604e1b0c5d9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/default.test | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b2dff6970f..e0cc1e9cbb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sExpr\scomparison\sroutine\sto\smake\sit\smore\sgeneral.\nImprovements\sto\sunary-minus\scode\sgeneration\sso\sthat\sit\scan\smake\suse\sof\na\sglobal\sconstant\sregister\swith\sa\szero\svalue. -D 2013-11-15T15:52:39.123 +C Add\stest\scases\sfor\sINSERT\sINTO\s...\sDEFAULT\sVALUES\son\stables\swith\snumeric\nconstants\sin\sCHECK\sconstraints. +D 2013-11-15T16:48:23.550 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -423,7 +423,7 @@ F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47 F test/date.test 42973251b9429f2c41b77eb98a7b0b0ba2d3b2c0 F test/dbstatus.test 8de104bb5606f19537d23cd553b41349b5ab1204 F test/dbstatus2.test 10418e62b3db5dca070f0c3eef3ea13946f339c2 -F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc +F test/default.test 792c3c70836f1901e2a8cb34fa0880ed71e2c1a9 F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 372686bfbb1da08b04bddb085e30da5dbc8b30d8 -R a53a2df918863d2e307a62344ad87323 +P 835be656bb0e83c8108104869166aa9dd850d265 +R eed45a05b059c0c6c1ee8ceb9dc6b477 U drh -Z a11accb78dd4b773c18bb01c1b2ffc18 +Z 845e07c690cff6d1b0e87cc7b8d86036 diff --git a/manifest.uuid b/manifest.uuid index 05249a4c01..55a6e48723 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -835be656bb0e83c8108104869166aa9dd850d265 \ No newline at end of file +79ec485b548fcfc508c4d5fa32ed0604e1b0c5d9 \ No newline at end of file diff --git a/test/default.test b/test/default.test index 95a4ee039c..d6b6f97d98 100644 --- a/test/default.test +++ b/test/default.test @@ -64,4 +64,39 @@ ifcapable pragma { } {0 c {} 0 'abc' 0} } +do_execsql_test default-3.1 { + CREATE TABLE t3( + a INTEGER PRIMARY KEY AUTOINCREMENT, + b INT DEFAULT 12345 UNIQUE NOT NULL CHECK( b>=0 AND b<99999 ), + c VARCHAR(123,456) DEFAULT 'hello' NOT NULL ON CONFLICT REPLACE, + d REAL, + e FLOATING POINT(5,10) DEFAULT 4.36, + f NATIONAL CHARACTER(15) COLLATE RTRIM, + g LONG INTEGER DEFAULT( 3600*12 ) + ); + INSERT INTO t3 VALUES(null, 5, 'row1', '5.25', 'xyz', 321, '432'); + SELECT a, typeof(a), b, typeof(b), c, typeof(c), + d, typeof(d), e, typeof(e), f, typeof(f), + g, typeof(g) FROM t3; +} {1 integer 5 integer row1 text 5.25 real xyz text 321 text 432 integer} +do_execsql_test default-3.2 { + DELETE FROM t3; + INSERT INTO t3 DEFAULT VALUES; + SELECT * FROM t3; +} {2 12345 hello {} 4.36 {} 43200} +do_execsql_test default-3.3 { + CREATE TABLE t300( + a INT DEFAULT 2147483647, + b INT DEFAULT 2147483648, + c INT DEFAULT +9223372036854775807, + d INT DEFAULT -2147483647, + e INT DEFAULT -2147483648, + f INT DEFAULT -9223372036854775808, + g INT DEFAULT (-(-9223372036854775808)), + h INT DEFAULT (-(-9223372036854775807)) + ); + INSERT INTO t300 DEFAULT VALUES; + SELECT * FROM t300; +} {2147483647 2147483648 9223372036854775807 -2147483647 -2147483648 -9223372036854775808 9.22337203685478e+18 9223372036854775807} + finish_test From c2acc4e46620a10da17651bea3e81a04c56a823f Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 18:15:19 +0000 Subject: [PATCH 10/78] Changes to make the new constant expression factoring logic more general and more testable. FossilOrigin-Name: d10fb49a92f5f6e93093ae83544e5aec7984361a --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/build.c | 2 +- src/expr.c | 28 +++++++++++----------------- src/resolve.c | 26 +++++++++++++------------- src/select.c | 17 +++++++++-------- src/sqliteInt.h | 9 +++++++-- src/where.c | 3 --- 8 files changed, 53 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index e0cc1e9cbb..461a040ced 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sINSERT\sINTO\s...\sDEFAULT\sVALUES\son\stables\swith\snumeric\nconstants\sin\sCHECK\sconstraints. -D 2013-11-15T16:48:23.550 +C Changes\sto\smake\sthe\snew\sconstant\sexpression\sfactoring\slogic\smore\sgeneral\nand\smore\stestable. +D 2013-11-15T18:15:19.953 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -169,13 +169,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btree.c 260dedc13119e6fb7930380bd3d294b98362bf5a F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 -F src/build.c 5b744617019f6011ee35a88fe046f3fdf6f85c53 +F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef -F src/expr.c eb7eb7fa7848dc4e3b67a2f0bf32f794804ca38a +F src/expr.c 016e9dccac357b32d3ef960fa1690c3b17625e1e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 @@ -217,14 +217,14 @@ F src/pragma.c c8d70c47ec8d8ba93575d92e34d30ddff8e9b517 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 -F src/resolve.c fc4673cc49b116e51e7f12de074c0acf8f2388f9 +F src/resolve.c 6fcceeb653a0020b14491975d567c989e794d408 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 7317406831ecced390edba972818f3c5f82238c0 +F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 11b0dd04b1a2eb86a348fd818c7a63bf015cb0dd +F src/sqliteInt.h e16eb6e62146234c05f34a4403a75cf242777ad7 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c 6e7e932ee32a4b2a0e4741880c06fe7a545e0059 +F src/where.c c7d50e26bad54218d8fa109d3127b9769b9474ab F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 835be656bb0e83c8108104869166aa9dd850d265 -R eed45a05b059c0c6c1ee8ceb9dc6b477 +P 79ec485b548fcfc508c4d5fa32ed0604e1b0c5d9 +R 81b3d4bed81861e7b07996884febd358 U drh -Z 845e07c690cff6d1b0e87cc7b8d86036 +Z 2fbf2a6281b456f08de0df7e1fd4f785 diff --git a/manifest.uuid b/manifest.uuid index 55a6e48723..6dae777ddd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -79ec485b548fcfc508c4d5fa32ed0604e1b0c5d9 \ No newline at end of file +d10fb49a92f5f6e93093ae83544e5aec7984361a \ No newline at end of file diff --git a/src/build.c b/src/build.c index 68d71da4ee..27f026c8dd 100644 --- a/src/build.c +++ b/src/build.c @@ -187,7 +187,7 @@ void sqlite3FinishCoding(Parse *pParse){ ExprList *pEL = pParse->pConstExpr; pParse->cookieGoto = 0; for(i=0; inExpr; i++){ - sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].iAlias); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); } } diff --git a/src/expr.c b/src/expr.c index 15b21d1dff..cc2966cf13 100644 --- a/src/expr.c +++ b/src/expr.c @@ -930,8 +930,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->sortOrder = pOldItem->sortOrder; pItem->done = 0; pItem->bSpanIsTab = pOldItem->bSpanIsTab; - pItem->iOrderByCol = pOldItem->iOrderByCol; - pItem->iAlias = pOldItem->iAlias; + pItem->u = pOldItem->u; } return pNew; } @@ -2908,7 +2907,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( (pX = pExpr->pLeft)!=0 ){ tempX = *pX; testcase( pX->op==TK_COLUMN ); - testcase( pX->op==TK_REGISTER ); exprToRegister(&tempX, sqlite3ExprCodeTemp(pParse, pX, ®Free1)); testcase( regFree1==0 ); opCompare.op = TK_EQ; @@ -2932,7 +2930,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ testcase( pTest->op==TK_COLUMN ); sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); - testcase( aListelem[i+1].pExpr->op==TK_REGISTER ); sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); sqlite3VdbeAddOp2(v, OP_Goto, 0, endLabel); sqlite3ExprCachePop(pParse, 1); @@ -3000,7 +2997,6 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollate(pExpr); if( pParse->cookieGoto>0 - && pParse->nMem<32768 && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ @@ -3010,14 +3006,14 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ if( p ){ for(i=0; inExpr; i++){ if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){ - return p->a[i].iAlias; + return p->a[i].u.iConstExprReg; } } } p = sqlite3ExprListAppend(pParse, p, sqlite3ExprDup(pParse->db, pExpr, 0)); pParse->pConstExpr = p; r2 = ++pParse->nMem; - if( p ) p->a[p->nExpr-1].iAlias = r2; + if( p ) p->a[p->nExpr-1].u.iConstExprReg = r2; }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); @@ -3069,12 +3065,13 @@ int sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int target){ int inReg; inReg = sqlite3ExprCode(pParse, pExpr, target); assert( target>0 ); - /* This routine is called for terms to INSERT or UPDATE. And the only - ** other place where expressions can be converted into TK_REGISTER is - ** in WHERE clause processing. So as currently implemented, there is - ** no way for a TK_REGISTER to exist here. But it seems prudent to - ** keep the ALWAYS() in case the conditions above change with future - ** modifications or enhancements. */ + /* The only place, other than this routine, where expressions can be + ** converted to TK_REGISTER is internal subexpressions in BETWEEN and + ** CASE operators. Neither ever calls this routine. And this routine + ** is never called twice on the same expression. Hence it is impossible + ** for the input to this routine to already be a register. Nevertheless, + ** it seems prudent to keep the ALWAYS() in case the conditions above + ** change with future modifications or enhancements. */ if( ALWAYS(pExpr->op!=TK_REGISTER) ){ int iMem; iMem = ++pParse->nMem; @@ -3745,7 +3742,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ } return 2; } - if( pA->op!=pB->op /*&& (pA->op!=TK_REGISTER || pA->op2!=pB->op)*/ ){ + if( pA->op!=pB->op ){ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){ return 1; } @@ -3760,8 +3757,6 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - testcase( combinedFlags & EP_TokenOnly ); - testcase( combinedFlags & EP_Reduced ); if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; @@ -3770,7 +3765,6 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ if( (combinedFlags & EP_Reduced)==0 ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable - && pA->op!=TK_REGISTER && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; } } diff --git a/src/resolve.c b/src/resolve.c index b41f234429..b5ba80ec75 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -108,10 +108,10 @@ static void resolveAlias( pDup = sqlite3PExpr(pParse, TK_AS, pDup, 0, 0); if( pDup==0 ) return; ExprSetProperty(pDup, EP_Skip); - if( pEList->a[iCol].iAlias==0 ){ - pEList->a[iCol].iAlias = (u16)(++pParse->nAlias); + if( pEList->a[iCol].u.x.iAlias==0 ){ + pEList->a[iCol].u.x.iAlias = (u16)(++pParse->nAlias); } - pDup->iTable = pEList->a[iCol].iAlias; + pDup->iTable = pEList->a[iCol].u.x.iAlias; } if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); @@ -976,7 +976,7 @@ static int resolveCompoundOrderBy( pItem->pExpr->pLeft = pNew; } sqlite3ExprDelete(db, pE); - pItem->iOrderByCol = (u16)iCol; + pItem->u.x.iOrderByCol = (u16)iCol; pItem->done = 1; }else{ moreToDo = 1; @@ -997,8 +997,8 @@ static int resolveCompoundOrderBy( /* ** Check every term in the ORDER BY or GROUP BY clause pOrderBy of ** the SELECT statement pSelect. If any term is reference to a -** result set expression (as determined by the ExprList.a.iOrderByCol field) -** then convert that term into a copy of the corresponding result set +** result set expression (as determined by the ExprList.a.u.x.iOrderByCol +** field) then convert that term into a copy of the corresponding result set ** column. ** ** If any errors are detected, add an error message to pParse and @@ -1025,12 +1025,12 @@ int sqlite3ResolveOrderGroupBy( pEList = pSelect->pEList; assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ - if( pItem->iOrderByCol ){ - if( pItem->iOrderByCol>pEList->nExpr ){ + if( pItem->u.x.iOrderByCol ){ + if( pItem->u.x.iOrderByCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType,0); + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0); } } return 0; @@ -1079,7 +1079,7 @@ static int resolveOrderGroupBy( ** a copy of the iCol-th result-set column. The subsequent call to ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ - pItem->iOrderByCol = (u16)iCol; + pItem->u.x.iOrderByCol = (u16)iCol; continue; } } @@ -1091,18 +1091,18 @@ static int resolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, nResult); return 1; } - pItem->iOrderByCol = (u16)iCol; + pItem->u.x.iOrderByCol = (u16)iCol; continue; } /* Otherwise, treat the ORDER BY term as an ordinary expression */ - pItem->iOrderByCol = 0; + pItem->u.x.iOrderByCol = 0; if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ - pItem->iOrderByCol = j+1; + pItem->u.x.iOrderByCol = j+1; } } } diff --git a/src/select.c b/src/select.c index 5cdef3aedc..04a523434b 100644 --- a/src/select.c +++ b/src/select.c @@ -2372,8 +2372,8 @@ static int multiSelectOrderBy( for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ struct ExprList_item *pItem; for(j=0, pItem=pOrderBy->a; jiOrderByCol>0 ); - if( pItem->iOrderByCol==i ) break; + assert( pItem->u.x.iOrderByCol>0 ); + if( pItem->u.x.iOrderByCol==i ) break; } if( j==nOrderBy ){ Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); @@ -2381,7 +2381,7 @@ static int multiSelectOrderBy( pNew->flags |= EP_IntValue; pNew->u.iValue = i; pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); - if( pOrderBy ) pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i; + if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; } } } @@ -2397,8 +2397,9 @@ static int multiSelectOrderBy( if( aPermute ){ struct ExprList_item *pItem; for(i=0, pItem=pOrderBy->a; iiOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr ); - aPermute[i] = pItem->iOrderByCol - 1; + assert( pItem->u.x.iOrderByCol>0 + && pItem->u.x.iOrderByCol<=p->pEList->nExpr ); + aPermute[i] = pItem->u.x.iOrderByCol - 1; } pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy, 1); if( pKeyMerge ){ @@ -2978,7 +2979,7 @@ static int flattenSubquery( if( p->pOrderBy ){ int ii; for(ii=0; iipOrderBy->nExpr; ii++){ - if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0; + if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } } @@ -4385,10 +4386,10 @@ int sqlite3Select( struct ExprList_item *pItem; /* For looping over expression in a list */ for(k=p->pEList->nExpr, pItem=p->pEList->a; k>0; k--, pItem++){ - pItem->iAlias = 0; + pItem->u.x.iAlias = 0; } for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ - pItem->iAlias = 0; + pItem->u.x.iAlias = 0; } if( p->nSelectRow>100 ) p->nSelectRow = 100; }else{ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9c4a9cc0b8..e6385e27cf 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1900,8 +1900,13 @@ struct ExprList { u8 sortOrder; /* 1 for DESC or 0 for ASC */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ - u16 iOrderByCol; /* For ORDER BY, column number in result set */ - u16 iAlias; /* Index into Parse.aAlias[] for zName */ + union { + struct { + u16 iOrderByCol; /* For ORDER BY, column number in result set */ + u16 iAlias; /* Index into Parse.aAlias[] for zName */ + } x; + int iConstExprReg; /* Register in which Expr value is cached */ + } u; } *a; /* Alloc a power of two greater or equal to nExpr */ }; diff --git a/src/where.c b/src/where.c index 9f4e23de3e..d9e16a1ed3 100644 --- a/src/where.c +++ b/src/where.c @@ -669,9 +669,6 @@ static int isLikeOrGlob( pRight = pList->a[0].pExpr; op = pRight->op; - if( op==TK_REGISTER ){ - op = pRight->op2; - } if( op==TK_VARIABLE ){ Vdbe *pReprepare = pParse->pReprepare; int iCol = pRight->iColumn; From 40864a14017f2fa8a323040fcbefd35407a3f48d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 18:58:37 +0000 Subject: [PATCH 11/78] Fix comments on the OP_Divide and OP_Remainder operators, especially the "Synopsis:" comment, so that they agree with the actual implementation. FossilOrigin-Name: cc17f1f05f15e9c62659a49c0656ff2b667bf701 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 79187a0a85..a346bf8ac2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--query\soption\sto\sthe\swordcount\stest\sprogram. -D 2013-11-15T13:12:30.792 +C Fix\scomments\son\sthe\sOP_Divide\sand\sOP_Remainder\soperators,\sespecially\sthe\n"Synopsis:"\scomment,\sso\sthat\sthey\sagree\swith\sthe\sactual\simplementation. +D 2013-11-15T18:58:37.334 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c 3de7e657b98ac67338d775c114a4068faf732402 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c d53b6b7e721b18c42754f10d68e75845e387f2ba +F src/vdbe.c 5573893423aec2d64871e8d504fadbcdaad39fed F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d99a30a25d6102c389f1fb5ec389c137168615e9 -R 0d314918704a2d9deceec12d1b561362 +P 5960d11eba4fc6ca136331279689424d03bd6e76 +R eeac4cc42ec89642fb7c3d8492dc346d U drh -Z 4de182ff7f969e11fcd8166760e38fe1 +Z cf9b95755a71f68840dd49a0488c3357 diff --git a/manifest.uuid b/manifest.uuid index d03acca621..479ceb1e91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5960d11eba4fc6ca136331279689424d03bd6e76 \ No newline at end of file +cc17f1f05f15e9c62659a49c0656ff2b667bf701 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c67a347b4c..1cd7be94ea 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1322,7 +1322,7 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ ** If either input is NULL, the result is NULL. */ /* Opcode: Divide P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]/r[P2] +** Synopsis: r[P3]=r[P2]/r[P1] ** ** Divide the value in register P1 by the value in register P2 ** and store the result in register P3 (P3=P2/P1). If the value in @@ -1330,11 +1330,11 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ ** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * -** Synopsis: r[P3]=r[P1]%r[P2] +** Synopsis: r[P3]=r[P2]%r[P1] ** -** Compute the remainder after integer division of the value in -** register P1 by the value in register P2 and store the result in P3. -** If the value in register P2 is zero the result is NULL. +** Compute the remainder after integer register P2 is divided by +** register P1 and store the result in register P3. +** If the value in register P1 is zero the result is NULL. ** If either operand is NULL, the result is NULL. */ case OP_Add: /* same as TK_PLUS, in1, in2, out3 */ From 85f8aa790783479016861787e5c945e9ee6f0a89 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 15 Nov 2013 20:06:26 +0000 Subject: [PATCH 12/78] Add ALWAYS and NEVER macros to currently unreachable but important branches in sqlite3ExprCompare(). FossilOrigin-Name: cee835fe902e46f283257fb8ec9d9744c7d6dd77 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aaa37eeb63..9ae591ea2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\soperator\scomment\sfixes\sfrom\strunk. -D 2013-11-15T19:00:20.523 +C Add\sALWAYS\sand\sNEVER\smacros\sto\scurrently\sunreachable\sbut\simportant\sbranches\sin\nsqlite3ExprCompare(). +D 2013-11-15T20:06:26.444 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef -F src/expr.c 016e9dccac357b32d3ef960fa1690c3b17625e1e +F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d10fb49a92f5f6e93093ae83544e5aec7984361a cc17f1f05f15e9c62659a49c0656ff2b667bf701 -R 5cbfa311a6440baa1aab3a14e0b86372 +P 9f14f55c8ab77e73dbffb7a9c99422bef14cc17a +R 14d70c56fa6d70d4b8ae495a017a7ed6 U drh -Z 9cd1e63a69ab310f8ae9d30ed54eea9a +Z d160133bb6592eb2691b4e35ce057d8a diff --git a/manifest.uuid b/manifest.uuid index 2be76a8e59..b556a77d11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9f14f55c8ab77e73dbffb7a9c99422bef14cc17a \ No newline at end of file +cee835fe902e46f283257fb8ec9d9744c7d6dd77 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index cc2966cf13..048146b375 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3757,15 +3757,15 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){ } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; - if( (combinedFlags & EP_TokenOnly)==0 ){ + if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){ if( combinedFlags & EP_xIsSelect ) return 2; if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; - if( (combinedFlags & EP_Reduced)==0 ){ + if( ALWAYS((combinedFlags & EP_Reduced)==0) ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable - && (pA->iTable!=iTab || pB->iTable>=0) ) return 2; + && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; } } return 0; From 143867516b9a5937f87bbe239a23526b7e369b69 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 12:56:46 +0000 Subject: [PATCH 13/78] Fix testcase misc7-16 so that it works with the new UNIQUE constraint error message format. FossilOrigin-Name: c7f2ed9f44be3b66a542ee42c0db63bab8ffd2db --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/misc7.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a346bf8ac2..7a24f800bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\scomments\son\sthe\sOP_Divide\sand\sOP_Remainder\soperators,\sespecially\sthe\n"Synopsis:"\scomment,\sso\sthat\sthey\sagree\swith\sthe\sactual\simplementation. -D 2013-11-15T18:58:37.334 +C Fix\stestcase\smisc7-16\sso\sthat\sit\sworks\swith\sthe\snew\sUNIQUE\sconstraint\serror\nmessage\sformat. +D 2013-11-16T12:56:46.327 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -697,7 +697,7 @@ F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6 F test/misc5.test 528468b26d03303b1f047146e5eefc941b9069f5 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 -F test/misc7.test 50c02c35ef7924c246eb3d8d71dfbf90ba352f8f +F test/misc7.test 1265eb98c2e22a446a13fdef754118b272716684 F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054 F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022 @@ -1139,7 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5960d11eba4fc6ca136331279689424d03bd6e76 -R eeac4cc42ec89642fb7c3d8492dc346d +P cc17f1f05f15e9c62659a49c0656ff2b667bf701 +R b62a58b0c81de204f01fd6d52945fa47 U drh -Z cf9b95755a71f68840dd49a0488c3357 +Z 7ba076cecbcdde244db85dd719f20d67 diff --git a/manifest.uuid b/manifest.uuid index 479ceb1e91..f80a0bc0b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc17f1f05f15e9c62659a49c0656ff2b667bf701 \ No newline at end of file +c7f2ed9f44be3b66a542ee42c0db63bab8ffd2db \ No newline at end of file diff --git a/test/misc7.test b/test/misc7.test index 96062a93b9..ec042ff0ee 100644 --- a/test/misc7.test +++ b/test/misc7.test @@ -355,7 +355,7 @@ do_ioerr_test misc7-16 -sqlprep { COMMIT; }} msg] - if {!$rc || ($rc && [string first "columns" $msg]==0)} { + if {!$rc || ($rc && [string first "UNIQUE" $msg]==0)} { set msg } else { error $msg From 64bbbf338371beb242520cd381151576a02a5135 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 14:03:53 +0000 Subject: [PATCH 14/78] Avoid unnecessary OP_IfNull checks when doing a range query where there is a constraint on the lower bound of the range. FossilOrigin-Name: de08a7e7abbad9b94d0268d096ef4555d31c8b0c --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a99086baf0..c58e814cf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sand\sperformance\simprovement\sto\sthe\slogic\sthat\sfactors\s\nconstant\sexpressions\souf\sof\sinner\sloops. -D 2013-11-16T13:55:34.349 +C Avoid\sunnecessary\sOP_IfNull\schecks\swhen\sdoing\sa\srange\squery\swhere\sthere\nis\sa\sconstraint\son\sthe\slower\sbound\sof\sthe\srange. +D 2013-11-16T14:03:53.332 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c c7d50e26bad54218d8fa109d3127b9769b9474ab +F src/where.c de64e326bb2a07e5591900b11a93d743df2a6919 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1139,8 +1139,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c7f2ed9f44be3b66a542ee42c0db63bab8ffd2db cee835fe902e46f283257fb8ec9d9744c7d6dd77 -R 9a08d5cf387c0a6debd995e2224a08b5 -T +closed cee835fe902e46f283257fb8ec9d9744c7d6dd77 +P ee9353fdf3c8f19cd3c344ea8fb7c6d13cadd632 +R bbc3c855c90e1aef97168122cf6d1f16 U drh -Z c4756f7866a605223b6628b959e50ab9 +Z c2c8cf1e135b3375a8bab4d9c0d72dac diff --git a/manifest.uuid b/manifest.uuid index bb971a575a..152a7e472d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee9353fdf3c8f19cd3c344ea8fb7c6d13cadd632 \ No newline at end of file +de08a7e7abbad9b94d0268d096ef4555d31c8b0c \ No newline at end of file diff --git a/src/where.c b/src/where.c index d9e16a1ed3..ba6e5e0c46 100644 --- a/src/where.c +++ b/src/where.c @@ -3143,6 +3143,7 @@ static Bitmask codeOneLoopStart( if( (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0 && (j = pIdx->aiColumn[nEq])>=0 && pIdx->pTable->aCol[j].notNull==0 + && (nEq || (pLoop->wsFlags & WHERE_BTM_LIMIT)==0) ){ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, nEq, r1); VdbeComment((v, "%s", pIdx->pTable->aCol[j].zName)); From aedfc5078ab2326e50a55104c8499844ecc28ef3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 15:35:18 +0000 Subject: [PATCH 15/78] Fully constraint the ORDER BY on the top-10 line of the --summary output from the wordcount test program. Add the run-wordcount.bash script for running wordcount in various configurations. FossilOrigin-Name: 7edf39eb93a8f9059a788f5fccf41c2be40afd4d --- manifest | 13 ++++---- manifest.uuid | 2 +- test/run-wordcount.bash | 66 +++++++++++++++++++++++++++++++++++++++++ test/wordcount.c | 2 +- 4 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 test/run-wordcount.bash diff --git a/manifest b/manifest index c58e814cf3..681c38774e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\sOP_IfNull\schecks\swhen\sdoing\sa\srange\squery\swhere\sthere\nis\sa\sconstraint\son\sthe\slower\sbound\sof\sthe\srange. -D 2013-11-16T14:03:53.332 +C Fully\sconstraint\sthe\sORDER\sBY\son\sthe\stop-10\sline\sof\sthe\s--summary\soutput\nfrom\sthe\swordcount\stest\sprogram.\s\sAdd\sthe\srun-wordcount.bash\sscript\sfor\nrunning\swordcount\sin\svarious\sconfigurations. +D 2013-11-16T15:35:18.956 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -757,6 +757,7 @@ F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 +F test/run-wordcount.bash 1c6a8b75738db8c53e5125be3d81ab63ef9eefd0 F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec @@ -1087,7 +1088,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c b8872ec44e8085bb671048a49cb696bed1100fe3 +F test/wordcount.c c80f378f26fbf6ada602c4313ae88fc47439263e F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1139,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ee9353fdf3c8f19cd3c344ea8fb7c6d13cadd632 -R bbc3c855c90e1aef97168122cf6d1f16 +P de08a7e7abbad9b94d0268d096ef4555d31c8b0c +R 172f7957a55e2959255a9b6c3406c731 U drh -Z c2c8cf1e135b3375a8bab4d9c0d72dac +Z e8555787a9b5df5e1de6c7d36654ffb3 diff --git a/manifest.uuid b/manifest.uuid index 152a7e472d..6d386d4ae9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de08a7e7abbad9b94d0268d096ef4555d31c8b0c \ No newline at end of file +7edf39eb93a8f9059a788f5fccf41c2be40afd4d \ No newline at end of file diff --git a/test/run-wordcount.bash b/test/run-wordcount.bash new file mode 100644 index 0000000000..b4b4dcd7e9 --- /dev/null +++ b/test/run-wordcount.bash @@ -0,0 +1,66 @@ +#!/bin/bash +# +# This script runs the wordcount program in different ways, comparing +# the output from each. +# + + +# Run the wordcount command with argument supplied and with --summary. +# Store the results in wc-out.txt and report the run-time. +# +function time_wordcount { + /usr/bin/time --format='%e %C' ./wordcount --summary $* >wc-out.txt +} + +# Compare wc-out.txt against wc-baseline.txt and report any differences. +# +function compare_results { + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi +} + +# Select the source text to be analyzed. +# +if test "x$1" = "x"; +then echo "Usage: $0 FILENAME [ARGS...]"; exit 1; +fi + +# Do test runs +# +rm -f wcdb1.db +time_wordcount wcdb1.db $* --insert +mv wc-out.txt wc-baseline.txt +rm -f wcdb2.db +time_wordcount wcdb2.db $* --insert --without-rowid +compare_results + +rm -f wcdb1.db +time_wordcount wcdb1.db $* --replace +compare_results +rm -f wcdb2.db +time_wordcount wcdb2.db $* --replace --without-rowid +compare_results + +rm -f wcdb1.db +time_wordcount wcdb1.db $* --select +compare_results +rm -f wcdb2.db +time_wordcount wcdb2.db $* --select --without-rowid +compare_results + +time_wordcount wcdb1.db $* --query +mv wc-out.txt wc-baseline.txt +time_wordcount wcdb2.db $* --query --without-rowid +compare_results + +time_wordcount wcdb1.db $* --delete +mv wc-out.txt wc-baseline.txt +time_wordcount wcdb2.db $* --delete --without-rowid +compare_results + +# Clean up temporary files created. +# +rm -rf wcdb1.db wcdb2.db wc-out.txt wc-baseline.txt diff --git a/test/wordcount.c b/test/wordcount.c index f8bac4deb6..59d8540a05 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -459,7 +459,7 @@ int main(int argc, char **argv){ "SELECT 'avg(cnt): ', avg(cnt) FROM wordcount;\n" "SELECT 'sum(cnt=1):', sum(cnt=1) FROM wordcount;\n" "SELECT 'top 10: ', group_concat(word, ', ') FROM " - "(SELECT word FROM wordcount ORDER BY cnt DESC LIMIT 10);\n" + "(SELECT word FROM wordcount ORDER BY cnt DESC, word LIMIT 10);\n" "SELECT 'checksum: ', checksum(word, cnt) FROM " "(SELECT word, cnt FROM wordcount ORDER BY word);\n" "PRAGMA integrity_check;\n", From 6a53499a203bb8e7d1996f39fad7af02a2d2774b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 20:13:39 +0000 Subject: [PATCH 16/78] Enhance the DELETE logic so that it can make use of WHERE_ONEPASS_DESIRED for rowid tables. FossilOrigin-Name: 8f479a72758ab6fedb171ada612b1963143c32fa --- manifest | 23 +++++++++-------- manifest.uuid | 2 +- src/delete.c | 52 ++++++++++++++++++++++++++++---------- src/insert.c | 26 ++++++++++++------- src/pragma.c | 2 +- src/sqliteInt.h | 2 +- src/update.c | 66 ++++++++++++++++++++++--------------------------- 7 files changed, 101 insertions(+), 72 deletions(-) diff --git a/manifest b/manifest index 681c38774e..31f36d8ac7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fully\sconstraint\sthe\sORDER\sBY\son\sthe\stop-10\sline\sof\sthe\s--summary\soutput\nfrom\sthe\swordcount\stest\sprogram.\s\sAdd\sthe\srun-wordcount.bash\sscript\sfor\nrunning\swordcount\sin\svarious\sconfigurations. -D 2013-11-16T15:35:18.956 +C Enhance\sthe\sDELETE\slogic\sso\sthat\sit\scan\smake\suse\sof\sWHERE_ONEPASS_DESIRED\nfor\srowid\stables. +D 2013-11-16T20:13:39.579 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c ddb92f44595366c4817e576b5f11cad5a915c3ef +F src/delete.c 765215277172cd66123516b92c99804bfab490f1 F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -183,7 +183,7 @@ F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08 -F src/insert.c 63003c569c55793c3278ad7634bdd0c49d755a47 +F src/insert.c 3cf8012325857d162f74389420b14be7976a538d F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b @@ -213,7 +213,7 @@ F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 -F src/pragma.c c8d70c47ec8d8ba93575d92e34d30ddff8e9b517 +F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 @@ -224,7 +224,7 @@ F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h e16eb6e62146234c05f34a4403a75cf242777ad7 +F src/sqliteInt.h 03b91c6bceccd7718473f3d790abcb8d5c2b1bf1 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c 3de7e657b98ac67338d775c114a4068faf732402 +F src/update.c 6a45368f8c7b400ffdac9a4c6cd19a5bbf3385e2 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1140,7 +1140,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P de08a7e7abbad9b94d0268d096ef4555d31c8b0c -R 172f7957a55e2959255a9b6c3406c731 +P 7edf39eb93a8f9059a788f5fccf41c2be40afd4d +R a6d07ee396f35147cc60e236a37bb900 +T *branch * optimize-delete +T *sym-optimize-delete * +T -sym-trunk * U drh -Z e8555787a9b5df5e1de6c7d36654ffb3 +Z fab6ca68390544d72160beaeac98129b diff --git a/manifest.uuid b/manifest.uuid index 6d386d4ae9..0a6d9a3628 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7edf39eb93a8f9059a788f5fccf41c2be40afd4d \ No newline at end of file +8f479a72758ab6fedb171ada612b1963143c32fa \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 4fb3946595..c36c9447f7 100644 --- a/src/delete.c +++ b/src/delete.c @@ -234,12 +234,16 @@ void sqlite3DeleteFrom( int iTabCur; /* Cursor number for the table */ int iDataCur; /* VDBE cursor for the canonical data source */ int iIdxCur; /* Cursor number of the first index */ + int nIdx; /* Number of indices */ sqlite3 *db; /* Main database structure */ AuthContext sContext; /* Authorization context */ NameContext sNC; /* Name context to resolve expressions in */ int iDb; /* Database number */ int memCnt = -1; /* Memory cell used for change counting */ int rcauth; /* Value returned by authorization callback */ + int okOnePass; /* True for one-pass algorithm without the FIFO */ + int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ + u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ @@ -295,11 +299,11 @@ void sqlite3DeleteFrom( } assert(!isView || pTrigger); - /* Assign cursor number to the table and all its indices. + /* Assign cursor numbers to the table and all its indices. */ assert( pTabList->nSrc==1 ); iTabCur = pTabList->a[0].iCursor = pParse->nTab++; - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ pParse->nTab++; } @@ -399,8 +403,8 @@ void sqlite3DeleteFrom( /* Open cursors for all indices of the table. */ - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, - iTabCur, &iDataCur, &iIdxCur); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, + &iDataCur, &iIdxCur); /* Loop over the primary keys to be deleted. */ addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph); @@ -424,22 +428,39 @@ void sqlite3DeleteFrom( ** all rowids to be deleted into a RowSet. */ int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ - int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ int regRowid; /* Actual register containing rowids */ /* Collect rowids of every row to be deleted. */ sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, WHERE_DUPLICATES_OK, 0 + pParse, pTabList, pWhere, 0, 0, + WHERE_DUPLICATES_OK|WHERE_ONEPASS_DESIRED, iTabCur+1 ); if( pWInfo==0 ) goto delete_from_cleanup; - regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iRowid, 0); - sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } + regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, + pParse->nMem+1, 0); + if( regRowid>pParse->nMem ) pParse->nMem = regRowid; + if( okOnePass ){ + aToOpen = sqlite3DbMallocRaw(db, nIdx+2); + if( aToOpen==0 ) goto delete_from_cleanup; + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; + addr = sqlite3VdbeAddOp0(v, OP_Goto); + }else{ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); + } sqlite3WhereEnd(pWInfo); + if( okOnePass ){ + sqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeJumpHere(v, addr); + } /* Delete every item whose key was written to the list during the ** database scan. We have to delete items after the scan is complete @@ -451,20 +472,22 @@ void sqlite3DeleteFrom( ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ if( !isView ){ - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, &iDataCur, &iIdxCur); assert( iDataCur==iTabCur ); assert( iIdxCur==iDataCur+1 ); } - addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid); + if( !okOnePass ){ + addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, regRowid); + } /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, regRowid, pVTab, P4_VTAB); sqlite3VdbeChangeP5(v, OE_Abort); sqlite3MayAbort(pParse); }else @@ -472,11 +495,13 @@ void sqlite3DeleteFrom( { int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - iRowid, 1, count, OE_Default, 0); + regRowid, 1, count, OE_Default, okOnePass); } /* End of the delete loop */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + if( !okOnePass ){ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + } sqlite3VdbeResolveLabel(v, end); /* Close the cursors open on the table and its indexes. */ @@ -510,6 +535,7 @@ delete_from_cleanup: sqlite3AuthContextPop(&sContext); sqlite3SrcListDelete(db, pTabList); sqlite3ExprDelete(db, pWhere); + sqlite3DbFree(db, aToOpen); return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise diff --git a/src/insert.c b/src/insert.c index 967abac840..b1a9104f71 100644 --- a/src/insert.c +++ b/src/insert.c @@ -820,7 +820,7 @@ void sqlite3Insert( /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; - nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, -1, 0, &iDataCur, &iIdxCur); aRegIdx = sqlite3DbMallocRaw(db, sizeof(int)*(nIdx+1)); if( aRegIdx==0 ){ @@ -1680,16 +1680,19 @@ int sqlite3OpenTableAndIndices( Table *pTab, /* Table to be opened */ int op, /* OP_OpenRead or OP_OpenWrite */ 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 */ int *piIdxCur /* Write the first index cursor number here */ ){ int i; int iDb; + int iDataCur; Index *pIdx; Vdbe *v; assert( op==OP_OpenRead || op==OP_OpenWrite ); if( IsVirtual(pTab) ){ + assert( aToOpen==0 ); *piDataCur = 0; *piIdxCur = 1; return 0; @@ -1698,20 +1701,25 @@ int sqlite3OpenTableAndIndices( v = sqlite3GetVdbe(pParse); assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; - if( HasRowid(pTab) ){ - *piDataCur = iBase++; - sqlite3OpenTable(pParse, *piDataCur, iDb, pTab, op); + iDataCur = iBase++; + if( piDataCur ) *piDataCur = iDataCur; + if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); }else{ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } - *piIdxCur = iBase; + if( piIdxCur ) *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); - if( pIdx->autoIndex==2 && !HasRowid(pTab) ) *piDataCur = iIdxCur; - sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - VdbeComment((v, "%s", pIdx->zName)); + if( pIdx->autoIndex==2 && !HasRowid(pTab) && piDataCur ){ + *piDataCur = iIdxCur; + } + if( aToOpen==0 || aToOpen[i+1] ){ + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + VdbeComment((v, "%s", pIdx->zName)); + } } if( iBase>pParse->nTab ) pParse->nTab = iBase; return i; diff --git a/src/pragma.c b/src/pragma.c index 76a452c466..bbd27b8c18 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1891,7 +1891,7 @@ void sqlite3Pragma( sqlite3VdbeJumpHere(v, addr); sqlite3ExprCacheClear(pParse); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, - 1, &iDataCur, &iIdxCur); + 1, 0, &iDataCur, &iIdxCur); sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e6385e27cf..f52c6c1d14 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2942,7 +2942,7 @@ int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*); void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*); void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); -int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, int*, int*); +int sqlite3OpenTableAndIndices(Parse*, Table*, int, int, u8*, int*, int*); void sqlite3BeginWriteOperation(Parse*, int, int); void sqlite3MultiWrite(Parse*); void sqlite3MayAbort(Parse*); diff --git a/src/update.c b/src/update.c index 34176603e2..ec565660e1 100644 --- a/src/update.c +++ b/src/update.c @@ -101,6 +101,7 @@ void sqlite3Update( Index *pIdx; /* For looping over indices */ Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ int nIdx; /* Number of indices that need updating */ + int iBaseCur; /* Base cursor number */ int iDataCur; /* Cursor for the canonical data btree */ int iIdxCur; /* Cursor for the first index */ sqlite3 *db; /* The database structure */ @@ -108,6 +109,7 @@ void sqlite3Update( int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the ** an expression for the i-th column of the table. ** aXRef[i]==-1 if the i-th column is not changed. */ + u8 *aToOpen; /* 1 for tables and indices to be opened */ u8 chngPk; /* PRIMARY KEY changed in a WITHOUT ROWID table */ u8 chngRowid; /* Rowid changed in a normal table */ u8 chngKey; /* Either chngPk or chngRowid */ @@ -176,16 +178,13 @@ void sqlite3Update( if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto update_cleanup; } - aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol ); - if( aXRef==0 ) goto update_cleanup; - for(i=0; inCol; i++) aXRef[i] = -1; /* Allocate a cursors for the main database table and for all indices. ** The index cursors might not be used, but if they are used they ** need to occur right after the database cursor. So go ahead and ** allocate enough space, just in case. */ - pTabList->a[0].iCursor = iDataCur = pParse->nTab++; + pTabList->a[0].iCursor = iBaseCur = iDataCur = pParse->nTab++; iIdxCur = iDataCur+1; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ @@ -196,6 +195,17 @@ void sqlite3Update( pParse->nTab++; } + /* 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 ); + if( aXRef==0 ) goto update_cleanup; + aRegIdx = aXRef+pTab->nCol; + aToOpen = (u8*)(aRegIdx+nIdx); + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + for(i=0; inCol; i++) aXRef[i] = -1; + /* Initialize the name-context */ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; @@ -256,15 +266,10 @@ void sqlite3Update( hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); - /* Allocate memory for the array aRegIdx[]. There is one entry in the - ** array for each index associated with table being updated. Fill in - ** the value with a register number for indices that are to be used - ** and with zero for unused indices. + /* There is one entry in the aRegIdx[] array for each index on the table + ** being updated. Fill in aRegIdx[] with a register number that will hold + ** the key for accessing each index. */ - if( nIdx>0 ){ - aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx ); - if( aRegIdx==0 ) goto update_cleanup; - } for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int reg; if( chngKey || hasFK || pIdx->pPartIdxWhere || pIdx==pPk ){ @@ -278,6 +283,7 @@ void sqlite3Update( } } } + if( reg==0 ) aToOpen[j+1] = 0; aRegIdx[j] = reg; } @@ -401,42 +407,29 @@ void sqlite3Update( ** action, then we need to open all indices because we might need ** to be deleting some records. */ - if( !okOnePass && HasRowid(pTab) ){ - sqlite3OpenTable(pParse, iDataCur, iDb, pTab, OP_OpenWrite); - } - sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); if( onError==OE_Replace ){ - openAll = 1; + memset(aToOpen, 1, nIdx+1); }else{ - openAll = 0; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->onError==OE_Replace ){ - openAll = 1; + memset(aToOpen, 1, nIdx+1); break; } } } - for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ - int iThisCur = iIdxCur+i; - assert( aRegIdx ); - if( (openAll || aRegIdx[i]>0) - && iThisCur!=aiCurOnePass[1] - ){ - assert( iThisCur!=aiCurOnePass[0] ); - sqlite3VdbeAddOp3(v, OP_OpenWrite, iThisCur, pIdx->tnum, iDb); - sqlite3VdbeSetP4KeyInfo(pParse, pIdx); - assert( pParse->nTab>iThisCur ); - VdbeComment((v, "%s", pIdx->zName)); - if( okOnePass && pPk && iThisCur==iDataCur ){ - sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, - regKey, nKey); - } - } + if( okOnePass ){ + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; } + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iBaseCur, aToOpen, + 0, 0); } /* Top of the update loop */ if( okOnePass ){ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey); + } labelContinue = labelBreak; sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); }else if( pPk ){ @@ -656,8 +649,7 @@ void sqlite3Update( update_cleanup: sqlite3AuthContextPop(&sContext); - sqlite3DbFree(db, aRegIdx); - sqlite3DbFree(db, aXRef); + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pChanges); sqlite3ExprDelete(db, pWhere); From 156c7919d9f0895266d1b34eccd39bf893a1e8b4 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 20:45:01 +0000 Subject: [PATCH 17/78] The one-pass optimization is now working for DELETE on WITHOUT ROWID tables. FossilOrigin-Name: e4d220a381388f900a95d1b656a82f14c837f92e --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/delete.c | 41 +++++++++++++++++++++++++++++++---------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 31f36d8ac7..6c93f9afcb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sDELETE\slogic\sso\sthat\sit\scan\smake\suse\sof\sWHERE_ONEPASS_DESIRED\nfor\srowid\stables. -D 2013-11-16T20:13:39.579 +C The\sone-pass\soptimization\sis\snow\sworking\sfor\sDELETE\son\sWITHOUT\sROWID\stables. +D 2013-11-16T20:45:01.087 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 765215277172cd66123516b92c99804bfab490f1 +F src/delete.c 35750d35fe9f174ccb98bae0d6627dcf83a7965a F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -1140,10 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7edf39eb93a8f9059a788f5fccf41c2be40afd4d -R a6d07ee396f35147cc60e236a37bb900 -T *branch * optimize-delete -T *sym-optimize-delete * -T -sym-trunk * +P 8f479a72758ab6fedb171ada612b1963143c32fa +R b6e41a6a6d551dfa6da0e7b0e42124eb U drh -Z fab6ca68390544d72160beaeac98129b +Z f0edfafd89abfe9d193a6a7758aa54ff diff --git a/manifest.uuid b/manifest.uuid index 0a6d9a3628..1a4b2e1489 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f479a72758ab6fedb171ada612b1963143c32fa \ No newline at end of file +e4d220a381388f900a95d1b656a82f14c837f92e \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index c36c9447f7..30b415aa35 100644 --- a/src/delete.c +++ b/src/delete.c @@ -386,20 +386,37 @@ void sqlite3DeleteFrom( iKey = ++pParse->nMem; iEph = pParse->nTab++; - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); sqlite3VdbeSetP4KeyInfo(pParse, pPk); - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, + WHERE_ONEPASS_DESIRED, iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; + okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); for(i=0; iaiColumn[i],iPk+i); } - sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, - sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey); if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } + if( okOnePass ){ + aToOpen = sqlite3DbMallocRaw(db, nIdx+2); + if( aToOpen==0 ) goto delete_from_cleanup; + memset(aToOpen, 1, nIdx+1); + aToOpen[nIdx+1] = 0; + if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; + if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; + sqlite3VdbeChangeToNoop(v, addr); + addr = sqlite3VdbeAddOp0(v, OP_Goto); + }else{ + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, + sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey); + } sqlite3WhereEnd(pWInfo); + if( okOnePass ){ + sqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeJumpHere(v, addr); + } /* Open cursors for all indices of the table. */ @@ -407,16 +424,20 @@ void sqlite3DeleteFrom( &iDataCur, &iIdxCur); /* Loop over the primary keys to be deleted. */ - addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph); - sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk); + if( !okOnePass ){ + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph); + sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk); + } /* Delete the row */ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - iPk, 0, 1, OE_Default, 0); + iPk, nPk*okOnePass, 1, OE_Default, okOnePass); /* End of the delete loop */ - sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1); - sqlite3VdbeJumpHere(v, addr); + if( !okOnePass ){ + sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1); + sqlite3VdbeJumpHere(v, addr); + } /* Close the cursors open on the table and its indexes. */ assert( iDataCur>=iIdxCur ); From 9612947260c61cb2497a8bfa174f59a2eb6d63d0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 22:48:52 +0000 Subject: [PATCH 18/78] Combine the rowid and WITHOUT ROWID paths for DELETE into a single path. FossilOrigin-Name: c4734b881a64a9d21d03a14e901785797577fbd8 --- manifest | 12 +-- manifest.uuid | 2 +- src/delete.c | 226 ++++++++++++++++++++++++-------------------------- 3 files changed, 115 insertions(+), 125 deletions(-) diff --git a/manifest b/manifest index 6c93f9afcb..dd8429d568 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sone-pass\soptimization\sis\snow\sworking\sfor\sDELETE\son\sWITHOUT\sROWID\stables. -D 2013-11-16T20:45:01.087 +C Combine\sthe\srowid\sand\sWITHOUT\sROWID\spaths\sfor\sDELETE\sinto\sa\ssingle\spath. +D 2013-11-16T22:48:52.173 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 35750d35fe9f174ccb98bae0d6627dcf83a7965a +F src/delete.c 1bcc9d7f2e48cf9043a44bdbd333c38c2ef6676a F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8f479a72758ab6fedb171ada612b1963143c32fa -R b6e41a6a6d551dfa6da0e7b0e42124eb +P e4d220a381388f900a95d1b656a82f14c837f92e +R d0df7aac2a46f76fbd08b30c4f269d2a U drh -Z f0edfafd89abfe9d193a6a7758aa54ff +Z 2d947a1a8ff0ceb82e3a6fad03406bbd diff --git a/manifest.uuid b/manifest.uuid index 1a4b2e1489..e3dbc37284 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e4d220a381388f900a95d1b656a82f14c837f92e \ No newline at end of file +c4734b881a64a9d21d03a14e901785797577fbd8 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 30b415aa35..35010a483a 100644 --- a/src/delete.c +++ b/src/delete.c @@ -227,7 +227,6 @@ void sqlite3DeleteFrom( Vdbe *v; /* The virtual database engine */ Table *pTab; /* The table from which records will be deleted */ const char *zDb; /* Name of database holding pTab */ - int end, addr = 0; /* A couple addresses of generated code */ int i; /* Loop counter */ WhereInfo *pWInfo; /* Information about the WHERE clause */ Index *pIdx; /* For looping over indices of the table */ @@ -244,7 +243,18 @@ void sqlite3DeleteFrom( int okOnePass; /* True for one-pass algorithm without the FIFO */ int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ - + Index *pPk; /* The PRIMARY KEY index on the table */ + int iPk; /* First of nPk registerss holding PRIMARY KEY value */ + i16 nPk = 1; /* Number of components of the PRIMARY KEY */ + int iKey; /* Memory cell holding row key of to be deleted */ + i16 nKey; /* Number of memory cells of row key */ + int iEphCur = 0; /* Ephemeral table holding all primary key values */ + int iRowSet = 0; /* Register for rowset of rows to delete */ + int addrBypass = 0; /* Address of jump over the delete logic */ + int addrLoop = 0; /* Top of the delete loop */ + int addrDelete = 0; /* Jump directly to the delete logic */ + int addrEphOpen = 0; /* Instruction to open the Ephermeral table */ + #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ @@ -369,146 +379,121 @@ void sqlite3DeleteFrom( } }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ - if( !HasRowid(pTab) ){ - /* There is a WHERE clause on a WITHOUT ROWID table. + { + if( HasRowid(pTab) ){ + /* For a rowid table, initialize the RowSet to an empty set */ + pPk = 0; + nPk = 1; + iRowSet = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + }else{ + /* For a WITHOUT ROWID table, create an ephermeral table used to + ** hold all primary keys for rows to be deleted. */ + pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + nPk = pPk->nKeyCol; + iPk = pParse->nMem+1; + pParse->nMem += nPk; + iEphCur = pParse->nTab++; + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } + + /* Construct a query to find the rowid or primary key for every row + ** to be deleted, based on the WHERE clause. */ - Index *pPk; /* The PRIMARY KEY index on the table */ - int iPk; /* First of nPk memory cells holding PRIMARY KEY value */ - int iEph; /* Ephemeral table holding all primary key values */ - int iKey; /* Key value inserting into iEph */ - i16 nPk; /* Number of components of the PRIMARY KEY */ - - pPk = sqlite3PrimaryKeyIndex(pTab); - assert( pPk!=0 ); - nPk = pPk->nKeyCol; - iPk = pParse->nMem+1; - pParse->nMem += nPk; - iKey = ++pParse->nMem; - iEph = pParse->nTab++; - - addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); - sqlite3VdbeSetP4KeyInfo(pParse, pPk); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - for(i=0; iaiColumn[i],iPk+i); - } + + /* Keep track of the number of rows to be deleted */ if( db->flags & SQLITE_CountRows ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } + + /* Extract the rowid or primary key for the current row */ + if( pPk ){ + for(i=0; iaiColumn[i], iPk+i); + } + iKey = iPk; + nKey = nPk; + }else{ + iKey = pParse->nMem + 1; + iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0); + if( iKey>pParse->nMem ) pParse->nMem = iKey; + } + if( okOnePass ){ + /* For ONEPASS, no need to store the rowid/primary-key. There is only + ** 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); if( aToOpen==0 ) goto delete_from_cleanup; memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; - sqlite3VdbeChangeToNoop(v, addr); - addr = sqlite3VdbeAddOp0(v, OP_Goto); - }else{ + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); + addrDelete = sqlite3VdbeAddOp0(v, OP_Goto); /* Jump to DELETE logic */ + }else if( pPk ){ + /* Construct a composite key for the row to be deleted and remember it */ + iKey = ++pParse->nMem; + nKey = 0; /* Zero tells OP_Found to use a composite key */ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, sqlite3IndexAffinityStr(v, pPk), P4_TRANSIENT); - sqlite3VdbeAddOp2(v, OP_IdxInsert, iEph, iKey); - } - sqlite3WhereEnd(pWInfo); - if( okOnePass ){ - sqlite3VdbeAddOp0(v, OP_Halt); - sqlite3VdbeJumpHere(v, addr); - } - - /* Open cursors for all indices of the table. - */ - sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, - &iDataCur, &iIdxCur); - - /* Loop over the primary keys to be deleted. */ - if( !okOnePass ){ - addr = sqlite3VdbeAddOp1(v, OP_Rewind, iEph); - sqlite3VdbeAddOp2(v, OP_RowKey, iEph, iPk); - } - - /* Delete the row */ - sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - iPk, nPk*okOnePass, 1, OE_Default, okOnePass); - - /* End of the delete loop */ - if( !okOnePass ){ - sqlite3VdbeAddOp2(v, OP_Next, iEph, addr+1); - sqlite3VdbeJumpHere(v, addr); - } - - /* Close the cursors open on the table and its indexes. */ - assert( iDataCur>=iIdxCur ); - for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur+i); - } - }else{ - /* There is a WHERE clause on a rowid table. Run a loop that extracts - ** all rowids to be deleted into a RowSet. - */ - int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ - int regRowid; /* Actual register containing rowids */ - - /* Collect rowids of every row to be deleted. - */ - sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); - pWInfo = sqlite3WhereBegin( - pParse, pTabList, pWhere, 0, 0, - WHERE_DUPLICATES_OK|WHERE_ONEPASS_DESIRED, iTabCur+1 - ); - if( pWInfo==0 ) goto delete_from_cleanup; - okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - if( db->flags & SQLITE_CountRows ){ - sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); - } - regRowid = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, - pParse->nMem+1, 0); - if( regRowid>pParse->nMem ) pParse->nMem = regRowid; - if( okOnePass ){ - aToOpen = sqlite3DbMallocRaw(db, nIdx+2); - if( aToOpen==0 ) goto delete_from_cleanup; - memset(aToOpen, 1, nIdx+1); - aToOpen[nIdx+1] = 0; - if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; - if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; - addr = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); }else{ - sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, regRowid); + /* Get the rowid of the row to be deleted and remember it in the RowSet */ + nKey = 1; /* OP_Seek always uses a single rowid */ + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); } + + /* End of the WHERE loop */ sqlite3WhereEnd(pWInfo); if( okOnePass ){ - sqlite3VdbeAddOp0(v, OP_Halt); - sqlite3VdbeJumpHere(v, addr); + /* Bypass the delete logic below if the WHERE loop found zero rows */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, addrDelete); } - - /* Delete every item whose key was written to the list during the - ** database scan. We have to delete items after the scan is complete - ** because deleting an item can change the scan order. */ - end = sqlite3VdbeMakeLabel(v); - + /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the ** only effect this statement has is to fire the INSTEAD OF - ** triggers. */ + ** triggers. + */ if( !isView ){ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen, &iDataCur, &iIdxCur); - assert( iDataCur==iTabCur ); - assert( iIdxCur==iDataCur+1 ); + assert( pPk || iDataCur==iTabCur ); + assert( pPk || iIdxCur==iDataCur+1 ); } - - if( !okOnePass ){ - addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, regRowid); - } - + + /* Set up a loop over the rowids/primary-keys that were found in the + ** where-clause loop above. + */ + if( okOnePass ){ + /* Just one row. Hence the top-of-loop is a no-op */ + assert( nKey==nPk ); /* OP_Found will use an unpacked key */ + }else if( pPk ){ + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); + sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); + assert( nKey==0 ); /* OP_Found will use a composite key */ + }else{ + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + assert( nKey==1 ); + } + /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, regRowid, pVTab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); sqlite3VdbeChangeP5(v, OE_Abort); sqlite3MayAbort(pParse); }else @@ -516,23 +501,28 @@ void sqlite3DeleteFrom( { int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, - regRowid, 1, count, OE_Default, okOnePass); + iKey, nKey, count, OE_Default, okOnePass); } - - /* End of the delete loop */ - if( !okOnePass ){ - sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); - } - sqlite3VdbeResolveLabel(v, end); - + + /* End of the loop over all rowids/primary-keys. */ + if( okOnePass ){ + sqlite3VdbeJumpHere(v, addrBypass); + }else if( pPk ){ + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); + sqlite3VdbeJumpHere(v, addrLoop); + }else{ + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); + sqlite3VdbeJumpHere(v, addrLoop); + } + /* Close the cursors open on the table and its indexes. */ if( !isView && !IsVirtual(pTab) ){ - sqlite3VdbeAddOp1(v, OP_Close, iDataCur); + if( !pPk ) sqlite3VdbeAddOp1(v, OP_Close, iDataCur); for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp1(v, OP_Close, iIdxCur + i); } } - } + } /* End non-truncate path */ /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into From 52a82e69661ea8787bfc5183fb9f806f579413dc Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 23:03:06 +0000 Subject: [PATCH 19/78] Fix an OOM-recovery problem in the DELETE code generator. FossilOrigin-Name: dc7be158b82ab9156d0fcdf3394f881eac4d23c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/delete.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dd8429d568..57e956a2dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Combine\sthe\srowid\sand\sWITHOUT\sROWID\spaths\sfor\sDELETE\sinto\sa\ssingle\spath. -D 2013-11-16T22:48:52.173 +C Fix\san\sOOM-recovery\sproblem\sin\sthe\sDELETE\scode\sgenerator. +D 2013-11-16T23:03:06.762 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 1bcc9d7f2e48cf9043a44bdbd333c38c2ef6676a +F src/delete.c af69db684408d06a446e2ba2d050399773f91b9b F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e4d220a381388f900a95d1b656a82f14c837f92e -R d0df7aac2a46f76fbd08b30c4f269d2a +P c4734b881a64a9d21d03a14e901785797577fbd8 +R 10d8931262d0ae5f1928488f5d08f78e U drh -Z 2d947a1a8ff0ceb82e3a6fad03406bbd +Z 412c615fb9ef758b4ed11a541f1ecdcc diff --git a/manifest.uuid b/manifest.uuid index e3dbc37284..bdf0f87e31 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4734b881a64a9d21d03a14e901785797577fbd8 \ No newline at end of file +dc7be158b82ab9156d0fcdf3394f881eac4d23c3 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 35010a483a..a110e89937 100644 --- a/src/delete.c +++ b/src/delete.c @@ -433,7 +433,10 @@ void sqlite3DeleteFrom( */ nKey = nPk; /* OP_Found will use an unpacked key */ aToOpen = sqlite3DbMallocRaw(db, nIdx+2); - if( aToOpen==0 ) goto delete_from_cleanup; + if( aToOpen==0 ){ + sqlite3WhereEnd(pWInfo); + goto delete_from_cleanup; + } memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; From c51331d16d29094f6907fc48693243a53104a479 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 16 Nov 2013 23:16:31 +0000 Subject: [PATCH 20/78] Fix a couple of minor problems with the new delete logic. FossilOrigin-Name: a11243f840d35aaed8ee3b9901c3950bc584a417 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 3 ++- src/update.c | 3 +-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 57e956a2dd..609e196dbc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sOOM-recovery\sproblem\sin\sthe\sDELETE\scode\sgenerator. -D 2013-11-16T23:03:06.762 +C Fix\sa\scouple\sof\sminor\sproblems\swith\sthe\snew\sdelete\slogic. +D 2013-11-16T23:16:31.845 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c af69db684408d06a446e2ba2d050399773f91b9b +F src/delete.c b612d06c095acc5df50a208a9b023c96deb11e5a F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c 6a45368f8c7b400ffdac9a4c6cd19a5bbf3385e2 +F src/update.c 18e9b11b499c1205ec2b6e87322a7edc8772e550 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P c4734b881a64a9d21d03a14e901785797577fbd8 -R 10d8931262d0ae5f1928488f5d08f78e +P dc7be158b82ab9156d0fcdf3394f881eac4d23c3 +R 0c59b10189d7db2055b513cecd6f14e5 U drh -Z 412c615fb9ef758b4ed11a541f1ecdcc +Z ca24d69af9eecebf1768d25aef1413b7 diff --git a/manifest.uuid b/manifest.uuid index bdf0f87e31..501d33762c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dc7be158b82ab9156d0fcdf3394f881eac4d23c3 \ No newline at end of file +a11243f840d35aaed8ee3b9901c3950bc584a417 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index a110e89937..1b3d7a24bc 100644 --- a/src/delete.c +++ b/src/delete.c @@ -403,7 +403,8 @@ void sqlite3DeleteFrom( ** to be deleted, based on the WHERE clause. */ pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, - WHERE_ONEPASS_DESIRED, iTabCur+1); + WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK, + iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); diff --git a/src/update.c b/src/update.c index ec565660e1..1783b447af 100644 --- a/src/update.c +++ b/src/update.c @@ -114,7 +114,6 @@ void sqlite3Update( u8 chngRowid; /* Rowid changed in a normal table */ u8 chngKey; /* Either chngPk or chngRowid */ Expr *pRowidExpr = 0; /* Expression defining the new record number */ - int openAll = 0; /* True if all indices need to be opened */ AuthContext sContext; /* The authorization context */ NameContext sNC; /* The name-context to resolve expressions in */ int iDb; /* Database containing the table being updated */ @@ -622,7 +621,7 @@ void sqlite3Update( /* Close all tables */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ assert( aRegIdx ); - if( openAll || aRegIdx[i]>0 ){ + if( aToOpen[i+1] ){ sqlite3VdbeAddOp2(v, OP_Close, iIdxCur+i, 0); } } From 83d47afe24c67964373920c0e8e998a19dd1d0cd Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 17 Nov 2013 02:42:02 +0000 Subject: [PATCH 21/78] Make sure one-pass DELETE for WITHOUT ROWID tables correctly positions the PRIMARY KEY cursor. Make the same fix for UPDATE. FossilOrigin-Name: 6bd5750b7d5da221b0689f6df6be5ed0dce61bec --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/delete.c | 24 +++++++++++++++++------- src/update.c | 3 ++- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 609e196dbc..9f1bb087f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scouple\sof\sminor\sproblems\swith\sthe\snew\sdelete\slogic. -D 2013-11-16T23:16:31.845 +C Make\ssure\sone-pass\sDELETE\sfor\sWITHOUT\sROWID\stables\scorrectly\spositions\sthe\nPRIMARY\sKEY\scursor.\s\sMake\sthe\ssame\sfix\sfor\sUPDATE. +D 2013-11-17T02:42:02.540 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c b612d06c095acc5df50a208a9b023c96deb11e5a +F src/delete.c d88e4fbfeca5a8cf48b7d358b9a68d5e81f314b7 F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c 18e9b11b499c1205ec2b6e87322a7edc8772e550 +F src/update.c cc3d826923f7b61566dedbb3cfce5f13964f35a4 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P dc7be158b82ab9156d0fcdf3394f881eac4d23c3 -R 0c59b10189d7db2055b513cecd6f14e5 +P a11243f840d35aaed8ee3b9901c3950bc584a417 +R f429117cda51c1a8c08160d9a3f515e6 U drh -Z ca24d69af9eecebf1768d25aef1413b7 +Z 2718e457b564d6fbe8d10873d690a300 diff --git a/manifest.uuid b/manifest.uuid index 501d33762c..01e77e462a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a11243f840d35aaed8ee3b9901c3950bc584a417 \ No newline at end of file +6bd5750b7d5da221b0689f6df6be5ed0dce61bec \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 1b3d7a24bc..c4bf8cc813 100644 --- a/src/delete.c +++ b/src/delete.c @@ -461,7 +461,8 @@ void sqlite3DeleteFrom( sqlite3WhereEnd(pWInfo); if( okOnePass ){ /* Bypass the delete logic below if the WHERE loop found zero rows */ - addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); + addrBypass = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBypass); sqlite3VdbeJumpHere(v, addrDelete); } @@ -483,6 +484,10 @@ void sqlite3DeleteFrom( if( okOnePass ){ /* Just one row. Hence the top-of-loop is a no-op */ assert( nKey==nPk ); /* OP_Found will use an unpacked key */ + if( aToOpen[iDataCur-iTabCur] ){ + assert( pPk!=0 ); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + } }else if( pPk ){ addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey); @@ -510,7 +515,7 @@ void sqlite3DeleteFrom( /* End of the loop over all rowids/primary-keys. */ if( okOnePass ){ - sqlite3VdbeJumpHere(v, addrBypass); + sqlite3VdbeResolveLabel(v, addrBypass); }else if( pPk ){ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); sqlite3VdbeJumpHere(v, addrLoop); @@ -617,6 +622,7 @@ void sqlite3GenerateRowDelete( if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ u32 mask; /* Mask of OLD.* columns in use */ int iCol; /* Iterator used while populating OLD.* */ + int addrStart; /* Start of BEFORE trigger programs */ /* TODO: Could use temporary registers here. Also could attempt to ** avoid copying the contents of the rowid register. */ @@ -637,15 +643,19 @@ void sqlite3GenerateRowDelete( } /* Invoke BEFORE DELETE trigger programs. */ + addrStart = sqlite3VdbeCurrentAddr(v); sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel ); - /* Seek the cursor to the row to be deleted again. It may be that - ** the BEFORE triggers coded above have already removed the row - ** being deleted. Do not attempt to delete the row a second time, and - ** do not fire AFTER triggers. */ - sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + /* If any BEFORE triggers were coded, then seek the cursor to the + ** row to be deleted again. It may be that the BEFORE triggers moved + ** the cursor or of already deleted the row that the cursor was + ** pointing to. + */ + if( addrStart Date: Mon, 18 Nov 2013 08:41:06 +0000 Subject: [PATCH 22/78] Fix a problem with the shell tool EXPLAIN indentation code and VDBE sub-programs. FossilOrigin-Name: 9c8d6856253f8da06b2cb5dc6bd89b6952fa03ed --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/shell.c | 25 ++++++++++++++++++------- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 7c8e58d4ae..affb135257 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enable\sthe\sONEPASS\soptimization\sfor\sDELETE,\sfor\sboth\srowid\sand\sWITHOUT\nROWID\stables. -D 2013-11-18T03:11:54.195 +C Fix\sa\sproblem\swith\sthe\sshell\stool\sEXPLAIN\sindentation\scode\sand\sVDBE\ssub-programs. +D 2013-11-18T08:41:06.910 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c 6fcceeb653a0020b14491975d567c989e794d408 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb -F src/shell.c b98e74123d6c2e20369607c1da2d23c71db633d9 +F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1140,8 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7edf39eb93a8f9059a788f5fccf41c2be40afd4d 6bd5750b7d5da221b0689f6df6be5ed0dce61bec -R de0ce1af524d0d7134e767478b5898b6 -T +closed 6bd5750b7d5da221b0689f6df6be5ed0dce61bec -U drh -Z b3bca10fc785a82e3f00cdade511d055 +P 44a07afdd9b3ae2460bc963383295deb0915f899 +R fd745146c0298a78435ee62db781f33d +U dan +Z ccddbfb4ee4200a6ab72b0a768e815b9 diff --git a/manifest.uuid b/manifest.uuid index 7959da7ea1..243e76568d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44a07afdd9b3ae2460bc963383295deb0915f899 \ No newline at end of file +9c8d6856253f8da06b2cb5dc6bd89b6952fa03ed \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 35fe970382..37e9b451bc 100644 --- a/src/shell.c +++ b/src/shell.c @@ -466,6 +466,7 @@ struct callback_data { FILE *pLog; /* Write log output here */ int *aiIndent; /* Array of indents used in MODE_Explain */ int nIndent; /* Size of array aiIndent[] */ + int iIndent; /* Index of current op in aiIndent[] */ }; /* @@ -771,10 +772,10 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int w = strlen30(azArg[i]); } if( i==1 && p->aiIndent && p->pStmt ){ - int iOp = sqlite3_column_int(p->pStmt, 0); - if( iOpnIndent ){ - fprintf(p->out, "%*.s", p->aiIndent[iOp], ""); + if( p->iIndentnIndent ){ + fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); } + p->iIndent++; } if( w<0 ){ fprintf(p->out,"%*.*s%s",-w,-w, @@ -1184,7 +1185,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ const char *z; /* Used to check if this is an EXPLAIN */ int *abYield = 0; /* True if op is an OP_Yield */ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ - int iOp; + int iOp; /* Index of operation in p->aiIndent[] */ const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 }; @@ -1199,8 +1200,16 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ int i; + int iAddr = sqlite3_column_int(pSql, 0); const char *zOp = (const char*)sqlite3_column_text(pSql, 1); + + /* Set p2 to the P2 field of the current opcode. Then, assuming that + ** p2 is an instruction address, set variable p2op to the index of that + ** instruction in the aiIndent[] array. p2 and p2op may be different if + ** the current instruction is part of a sub-program generated by an + ** SQL trigger or foreign key. */ int p2 = sqlite3_column_int(pSql, 3); + int p2op = (p2 + (iOp-iAddr)); /* Grow the p->aiIndent array as required */ if( iOp>=nAlloc ){ @@ -1213,13 +1222,14 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){ p->nIndent = iOp+1; if( str_in_array(zOp, azNext) ){ - for(i=p2; iaiIndent[i] += 2; + for(i=p2op; iaiIndent[i] += 2; } - if( str_in_array(zOp, azGoto) && p2nIndent && abYield[p2] ){ - for(i=p2+1; iaiIndent[i] += 2; + if( str_in_array(zOp, azGoto) && p2opnIndent && abYield[p2op] ){ + for(i=p2op; iaiIndent[i] += 2; } } + p->iIndent = 0; sqlite3_free(abYield); sqlite3_reset(pSql); } @@ -1231,6 +1241,7 @@ static void explain_data_delete(struct callback_data *p){ sqlite3_free(p->aiIndent); p->aiIndent = 0; p->nIndent = 0; + p->iIndent = 0; } /* From 2bea7cde6e5671d0220c10e0ed60d514e8413f6c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Nov 2013 11:20:50 +0000 Subject: [PATCH 23/78] Fix harmless compiler warnings from clang scan-build. FossilOrigin-Name: 8d002740bffca2a76d2dfbc1a67293d34f9de9ba --- ext/fts3/fts3.c | 7 +++++-- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/fkey.c | 2 ++ 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 1719bac7d1..4850893346 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -333,6 +333,9 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ #define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \ v = (v & mask1) | ( (*ptr++) << shift ); \ if( (v & mask2)==0 ){ var = v; return ret; } +#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \ + v = (*ptr++); \ + if( (v & mask2)==0 ){ var = v; return ret; } /* ** Read a 64-bit variable-length integer from memory starting at p[0]. @@ -345,7 +348,7 @@ int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ u64 b; int shift; - GETVARINT_STEP(a, p, 0, 0x00, 0x80, *v, 1); + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *v, 1); GETVARINT_STEP(a, p, 7, 0x7F, 0x4000, *v, 2); GETVARINT_STEP(a, p, 14, 0x3FFF, 0x200000, *v, 3); GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *v, 4); @@ -368,7 +371,7 @@ int sqlite3Fts3GetVarint32(const char *p, int *pi){ u32 a; #ifndef fts3GetVarint32 - GETVARINT_STEP(a, p, 0, 0x00, 0x80, *pi, 1); + GETVARINT_INIT(a, p, 0, 0x00, 0x80, *pi, 1); #else a = (*p++); assert( a & 0x80 ); diff --git a/manifest b/manifest index affb135257..4e0353f3ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\sshell\stool\sEXPLAIN\sindentation\scode\sand\sVDBE\ssub-programs. -D 2013-11-18T08:41:06.910 +C Fix\sharmless\scompiler\swarnings\sfrom\sclang\sscan-build. +D 2013-11-18T11:20:50.241 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c dceaa5079833caa2e7945433e1eb93bb22f623a3 +F ext/fts3/fts3.c 3ae281c073c91a10bb42787426499d03df295b7a F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 @@ -177,7 +177,7 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb -F src/fkey.c 78364daed38e26269c53ddb94c515bceac1063c6 +F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 44a07afdd9b3ae2460bc963383295deb0915f899 -R fd745146c0298a78435ee62db781f33d -U dan -Z ccddbfb4ee4200a6ab72b0a768e815b9 +P 9c8d6856253f8da06b2cb5dc6bd89b6952fa03ed +R c9f2a197b3482dc9e1f22f87445d00db +U drh +Z 2979703407de49dd5b579d61d89bb322 diff --git a/manifest.uuid b/manifest.uuid index 243e76568d..90b13ca154 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c8d6856253f8da06b2cb5dc6bd89b6952fa03ed \ No newline at end of file +8d002740bffca2a76d2dfbc1a67293d34f9de9ba \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index 1cb6cb0d42..46c90a0989 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -548,6 +548,7 @@ static void fkScanChildren( assert( pIdx==0 || pIdx->pTable==pTab ); assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); assert( pIdx!=0 || pFKey->nCol==1 ); + assert( pIdx!=0 || HasRowid(pTab) ); if( nIncr<0 ){ iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); @@ -600,6 +601,7 @@ static void fkScanChildren( }else{ Expr *pEq, *pAll = 0; Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pIdx!=0 ); for(i=0; inKeyCol; i++){ i16 iCol = pIdx->aiColumn[i]; pLeft = exprTableRegister(pParse, pTab, regData, iCol); From 2365bac1e2d716141036d736f9edd1ae2b83993a Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Nov 2013 18:48:50 +0000 Subject: [PATCH 24/78] Fix documentation typos. No changes to code. FossilOrigin-Name: 7caeb09c52bde4649b02b339f611c8e30f6d1c68 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqlite.h.in | 13 ++++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 4e0353f3ad..ec98f2b851 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sfrom\sclang\sscan-build. -D 2013-11-18T11:20:50.241 +C Fix\sdocumentation\stypos.\s\sNo\schanges\sto\scode. +D 2013-11-18T18:48:50.010 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -221,7 +221,7 @@ F src/resolve.c 6fcceeb653a0020b14491975d567c989e794d408 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 -F src/sqlite.h.in 4dedcab5b32358bf7a596badffe7363be1f1a82d +F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 03b91c6bceccd7718473f3d790abcb8d5c2b1bf1 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9c8d6856253f8da06b2cb5dc6bd89b6952fa03ed -R c9f2a197b3482dc9e1f22f87445d00db +P 8d002740bffca2a76d2dfbc1a67293d34f9de9ba +R d98b977ab05ba38a226703beb7c26537 U drh -Z 2979703407de49dd5b579d61d89bb322 +Z c53e0578e3a1f9608c085ee4cd6a5e4a diff --git a/manifest.uuid b/manifest.uuid index 90b13ca154..5126360f83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d002740bffca2a76d2dfbc1a67293d34f9de9ba \ No newline at end of file +7caeb09c52bde4649b02b339f611c8e30f6d1c68 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 83e698ac6f..e6dcfaba9a 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -365,7 +365,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); **
    **
  • The application must insure that the 1st parameter to sqlite3_exec() ** is a valid and open [database connection]. -**
  • The application must not close [database connection] specified by +**
  • The application must not close the [database connection] specified by ** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. **
  • The application must not modify the SQL statement text passed into ** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. @@ -442,7 +442,7 @@ int sqlite3_exec( ** [sqlite3_extended_result_codes()] API. ** ** Some of the available extended result codes are listed here. -** One may expect the number of extended result codes will be expand +** One may expect the number of extended result codes will increase ** over time. Software that uses extended result codes should expect ** to see new result codes in future releases of SQLite. ** @@ -1380,7 +1380,7 @@ int sqlite3_db_config(sqlite3*, int op, ...); ** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** -** The xInit method initializes the memory allocator. (For example, +** The xInit method initializes the memory allocator. For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite3_shutdown()] and should deallocate any resources acquired @@ -3106,7 +3106,6 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. -** the **
  • ** */ @@ -3836,7 +3835,7 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or ** [sqlite3_finalize()] is called. ^The memory space used to hold strings ** and BLOBs is freed automatically. Do not pass the pointers returned -** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into ** [sqlite3_free()]. ** ** ^(If a memory allocation error occurs during the evaluation of any @@ -4914,8 +4913,8 @@ int sqlite3_release_memory(int); ** ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the -** [sqlite3_release_memory()] interface, this interface is effect even -** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is +** [sqlite3_release_memory()] interface, this interface is in effect even +** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is ** omitted. ** ** See also: [sqlite3_release_memory()] From 64ff26f74166ee88c2d94cab965741a70f87468b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 18 Nov 2013 19:32:15 +0000 Subject: [PATCH 25/78] Add comments identifing where the skip-scan option is decided in the query planner, to aid in tuning that decision. No changes to code. FossilOrigin-Name: e9df04cec48bb8b4ea26ec9024a22ea42b2338eb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ec98f2b851..5015b49889 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sdocumentation\stypos.\s\sNo\schanges\sto\scode. -D 2013-11-18T18:48:50.010 +C Add\scomments\sidentifing\swhere\sthe\sskip-scan\soption\sis\sdecided\sin\sthe\nquery\splanner,\sto\said\sin\stuning\sthat\sdecision.\s\sNo\schanges\sto\scode. +D 2013-11-18T19:32:15.750 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c de64e326bb2a07e5591900b11a93d743df2a6919 +F src/where.c c0a9bab3e783ecab6add9d08430dd5414810f2fe F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8d002740bffca2a76d2dfbc1a67293d34f9de9ba -R d98b977ab05ba38a226703beb7c26537 +P 7caeb09c52bde4649b02b339f611c8e30f6d1c68 +R 05f4e654e5dee11a1ac27e9ef3c549a9 U drh -Z c53e0578e3a1f9608c085ee4cd6a5e4a +Z b6f4e67d2e374e89823b36eebb6a35ba diff --git a/manifest.uuid b/manifest.uuid index 5126360f83..8f6426f507 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7caeb09c52bde4649b02b339f611c8e30f6d1c68 \ No newline at end of file +e9df04cec48bb8b4ea26ec9024a22ea42b2338eb \ No newline at end of file diff --git a/src/where.c b/src/where.c index ba6e5e0c46..a163895bb7 100644 --- a/src/where.c +++ b/src/where.c @@ -3918,10 +3918,15 @@ static int whereLoopAddBtreeIndex( saved_nOut = pNew->nOut; pNew->rSetup = 0; rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); + + /* Consider using a skip-scan if there are no WHERE clause constraints + ** available for the left-most terms of the index, and if the average + ** number of repeats in the left-most terms is at least 50. + */ if( pTerm==0 && saved_nEq==saved_nSkip && saved_nEq+1nKeyCol - && pProbe->aiRowEst[saved_nEq+1]>50 + && pProbe->aiRowEst[saved_nEq+1]>50 /* TUNING: Minimum for skip-scan */ ){ LogEst nIter; pNew->u.btree.nEq++; From f37139f65b960b7992688958049c5e8c5e1ff38f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Nov 2013 00:31:25 +0000 Subject: [PATCH 26/78] Fix an requirement mark in a test script so that it matches the typo-corrected requirement. No changes to code. FossilOrigin-Name: 072412d5e3f92c9c6548f5c86d396d3f024df3f7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/e_expr.test | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5015b49889..dc1ca6920f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scomments\sidentifing\swhere\sthe\sskip-scan\soption\sis\sdecided\sin\sthe\nquery\splanner,\sto\said\sin\stuning\sthat\sdecision.\s\sNo\schanges\sto\scode. -D 2013-11-18T19:32:15.750 +C Fix\san\srequirement\smark\sin\sa\stest\sscript\sso\sthat\sit\smatches\sthe\ntypo-corrected\srequirement.\s\sNo\schanges\sto\scode. +D 2013-11-19T00:31:25.328 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test d5cdda0e4ffb17760858ed4c7c4ece07efc40f71 +F test/e_expr.test 7d7feeadb555b49476e9ca4a145fcf7c0a81ce34 F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7caeb09c52bde4649b02b339f611c8e30f6d1c68 -R 05f4e654e5dee11a1ac27e9ef3c549a9 +P e9df04cec48bb8b4ea26ec9024a22ea42b2338eb +R 8f5d4972dc75b885604bc463d0ac1318 U drh -Z b6f4e67d2e374e89823b36eebb6a35ba +Z c2cf09f17232f53b07d5ac061fb00e80 diff --git a/manifest.uuid b/manifest.uuid index 8f6426f507..13b5f1cc80 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e9df04cec48bb8b4ea26ec9024a22ea42b2338eb \ No newline at end of file +072412d5e3f92c9c6548f5c86d396d3f024df3f7 \ No newline at end of file diff --git a/test/e_expr.test b/test/e_expr.test index f0705757ac..2018db8a05 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1081,9 +1081,9 @@ ifcapable !icu { # EVIDENCE-OF: R-33693-50180 The REGEXP operator is a special syntax for # the regexp() user function. # -# EVIDENCE-OF: R-57289-13578 If a application-defined SQL function named -# "regexp" is added at run-time, that function will be called in order -# to implement the REGEXP operator. +# EVIDENCE-OF: R-65524-61849 If an application-defined SQL function +# named "regexp" is added at run-time, then the "X REGEXP Y" operator +# will be implemented as a call to "regexp(Y,X)". # proc regexpfunc {args} { eval lappend ::regexpargs $args From 5c82f4df9f2c51b7b53901121b65542d60ca84d6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Nov 2013 02:34:11 +0000 Subject: [PATCH 27/78] Avoid seeking on the main data table during the first loop of an UPDATE if an index is sufficient to check the WHERE clause. FossilOrigin-Name: 57158d9daf4d777411fffb1c1d20d89b291d9214 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index dc1ca6920f..dee084c753 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\srequirement\smark\sin\sa\stest\sscript\sso\sthat\sit\smatches\sthe\ntypo-corrected\srequirement.\s\sNo\schanges\sto\scode. -D 2013-11-19T00:31:25.328 +C Avoid\sseeking\son\sthe\smain\sdata\stable\sduring\sthe\sfirst\sloop\sof\san\sUPDATE\nif\san\sindex\sis\ssufficient\sto\scheck\sthe\sWHERE\sclause. +D 2013-11-19T02:34:11.947 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -276,7 +276,7 @@ F src/test_vfstrace.c 34b544e80ba7fb77be15395a609c669df2e660a2 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba -F src/update.c cc3d826923f7b61566dedbb3cfce5f13964f35a4 +F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P e9df04cec48bb8b4ea26ec9024a22ea42b2338eb -R 8f5d4972dc75b885604bc463d0ac1318 +P 072412d5e3f92c9c6548f5c86d396d3f024df3f7 +R ef3f52da3f64e056bcf519f817dc69c2 U drh -Z c2cf09f17232f53b07d5ac061fb00e80 +Z b9dbca4948b9d68d76792a11f3b2fa7e diff --git a/manifest.uuid b/manifest.uuid index 13b5f1cc80..1cdbc74de7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -072412d5e3f92c9c6548f5c86d396d3f024df3f7 \ No newline at end of file +57158d9daf4d777411fffb1c1d20d89b291d9214 \ No newline at end of file diff --git a/src/update.c b/src/update.c index 9405234e8c..f2be6d984c 100644 --- a/src/update.c +++ b/src/update.c @@ -263,6 +263,11 @@ void sqlite3Update( assert( chngPk==0 || chngPk==1 ); chngKey = chngRowid + chngPk; + /* The SET expressions are not actually used inside the WHERE loop. + ** So reset the colUsed mask + */ + pTabList->a[0].colUsed = 0; + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); /* There is one entry in the aRegIdx[] array for each index on the table From 6bc69a2d4b0b23dee133db83992c106210b25c32 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Nov 2013 12:33:23 +0000 Subject: [PATCH 28/78] Change Noop-comments in where.c into Module-comments, so that they are omitting without SQLITE_ENABLE_MODULE_COMMENTS. FossilOrigin-Name: 3e577f40183c56e60866d8382b044688a1b77eaf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index dee084c753..f97a14f179 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sseeking\son\sthe\smain\sdata\stable\sduring\sthe\sfirst\sloop\sof\san\sUPDATE\nif\san\sindex\sis\ssufficient\sto\scheck\sthe\sWHERE\sclause. -D 2013-11-19T02:34:11.947 +C Change\sNoop-comments\sin\swhere.c\sinto\sModule-comments,\sso\sthat\sthey\sare\nomitting\swithout\sSQLITE_ENABLE_MODULE_COMMENTS. +D 2013-11-19T12:33:23.661 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c c0a9bab3e783ecab6add9d08430dd5414810f2fe +F src/where.c aa72ba871fa835a513cae1c7432dc1d785eb23e4 F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 072412d5e3f92c9c6548f5c86d396d3f024df3f7 -R ef3f52da3f64e056bcf519f817dc69c2 +P 57158d9daf4d777411fffb1c1d20d89b291d9214 +R 4e071f5e12e1562d0bddca81679884f9 U drh -Z b9dbca4948b9d68d76792a11f3b2fa7e +Z a3df5d2252057bf6401f296b034ac821 diff --git a/manifest.uuid b/manifest.uuid index 1cdbc74de7..fe9187568e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57158d9daf4d777411fffb1c1d20d89b291d9214 \ No newline at end of file +3e577f40183c56e60866d8382b044688a1b77eaf \ No newline at end of file diff --git a/src/where.c b/src/where.c index a163895bb7..3d36625c45 100644 --- a/src/where.c +++ b/src/where.c @@ -2756,7 +2756,7 @@ static Bitmask codeOneLoopStart( bRev = (pWInfo->revMask>>iLevel)&1; omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 && (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)==0; - VdbeNoopComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); + VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); /* Create labels for the "break" and "continue" instructions ** for the current loop. Jump to addrBrk to break out of a loop. @@ -3461,7 +3461,7 @@ static Bitmask codeOneLoopStart( if( pAlt->wtFlags & (TERM_CODED) ) continue; testcase( pAlt->eOperator & WO_EQ ); testcase( pAlt->eOperator & WO_IN ); - VdbeNoopComment((v, "begin transitive constraint")); + VdbeModuleComment((v, "begin transitive constraint")); pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt)); if( pEAlt ){ *pEAlt = *pAlt->pExpr; @@ -5736,7 +5736,7 @@ WhereInfo *sqlite3WhereBegin( } /* Done. */ - VdbeNoopComment((v, "Begin WHERE-core")); + VdbeModuleComment((v, "Begin WHERE-core")); return pWInfo; /* Jump here if malloc fails */ @@ -5763,7 +5763,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Generate loop termination code. */ - VdbeNoopComment((v, "End WHERE-core")); + VdbeModuleComment((v, "End WHERE-core")); sqlite3ExprCacheClear(pParse); for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; @@ -5809,7 +5809,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } sqlite3VdbeJumpHere(v, addr); } - VdbeNoopComment((v, "End WHERE-loop%d: %s", i, + VdbeModuleComment((v, "End WHERE-loop%d: %s", i, pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); } From c138dafe88b1d9ed28668fd828750cacac4c8aff Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Nov 2013 13:55:34 +0000 Subject: [PATCH 29/78] Minor performance improvement to sqlite3SerialTypeGet(). FossilOrigin-Name: 17e8524fc05aa1e6074c19a8ccccc5ab5883103a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 7 ++----- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f97a14f179..c865825202 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sNoop-comments\sin\swhere.c\sinto\sModule-comments,\sso\sthat\sthey\sare\nomitting\swithout\sSQLITE_ENABLE_MODULE_COMMENTS. -D 2013-11-19T12:33:23.661 +C Minor\sperformance\simprovement\sto\ssqlite3SerialTypeGet(). +D 2013-11-19T13:55:34.757 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -284,7 +284,7 @@ F src/vdbe.c 5573893423aec2d64871e8d504fadbcdaad39fed F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c dd0f6ab9dc159911facfc0a7a2164af44779bdda +F src/vdbeaux.c 91f9e1fb59561fa7ba312b518b6123982c912d6c F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 57158d9daf4d777411fffb1c1d20d89b291d9214 -R 4e071f5e12e1562d0bddca81679884f9 +P 3e577f40183c56e60866d8382b044688a1b77eaf +R 9b965afdaedc9147b48bd003e56ae3cc U drh -Z a3df5d2252057bf6401f296b034ac821 +Z 24ee7b128cc14b239861141ccdef04d6 diff --git a/manifest.uuid b/manifest.uuid index fe9187568e..84c9771b22 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e577f40183c56e60866d8382b044688a1b77eaf \ No newline at end of file +17e8524fc05aa1e6074c19a8ccccc5ab5883103a \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 166cf7508f..dc284b54ae 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2966,15 +2966,12 @@ u32 sqlite3VdbeSerialGet( return 0; } default: { + static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem }; u32 len = (serial_type-12)/2; pMem->z = (char *)buf; pMem->n = len; pMem->xDel = 0; - if( serial_type&0x01 ){ - pMem->flags = MEM_Str | MEM_Ephem; - }else{ - pMem->flags = MEM_Blob | MEM_Ephem; - } + pMem->flags = aFlag[serial_type&1]; return len; } } From 707f1c560aac8ce6dc9b5bbbf16a3265ef203f3e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 19 Nov 2013 18:17:20 +0000 Subject: [PATCH 30/78] Fix a harmless MSVC compiler warning. FossilOrigin-Name: 6cc023bb29be51847fbbfab95c24fc89993ccdba --- ext/fts3/fts3.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 4850893346..3b9efee54c 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -360,7 +360,7 @@ int sqlite3Fts3GetVarint(const char *p, sqlite_int64 *v){ if( (c & 0x80)==0 ) break; } *v = b; - return p - pStart; + return (int)(p - pStart); } /* diff --git a/manifest b/manifest index c865825202..588130af14 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\simprovement\sto\ssqlite3SerialTypeGet(). -D 2013-11-19T13:55:34.757 +C Fix\sa\sharmless\sMSVC\scompiler\swarning. +D 2013-11-19T18:17:20.533 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 3ae281c073c91a10bb42787426499d03df295b7a +F ext/fts3/fts3.c 1e667eacb3fe4b4ad6f863920da4286f071f6e07 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3e577f40183c56e60866d8382b044688a1b77eaf -R 9b965afdaedc9147b48bd003e56ae3cc +P 17e8524fc05aa1e6074c19a8ccccc5ab5883103a +R fdf3e89d3298858e83482c5ae882639e U drh -Z 24ee7b128cc14b239861141ccdef04d6 +Z 293cb080495f6949faacc3bee3334f1e diff --git a/manifest.uuid b/manifest.uuid index 84c9771b22..ca50561c4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -17e8524fc05aa1e6074c19a8ccccc5ab5883103a \ No newline at end of file +6cc023bb29be51847fbbfab95c24fc89993ccdba \ No newline at end of file From 83b301b0af0831b7f65f4608e1ab00228c74defa Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 00:59:02 +0000 Subject: [PATCH 31/78] Performance improvement for the OP_MustBeInt opcode in the VDBE. FossilOrigin-Name: 96a65388e75fed96e2e73ef65726f6db88cc5ccd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 18 ++++++++++-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 588130af14..63b26c9cc0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\sMSVC\scompiler\swarning. -D 2013-11-19T18:17:20.533 +C Performance\simprovement\sfor\sthe\sOP_MustBeInt\sopcode\sin\sthe\sVDBE. +D 2013-11-20T00:59:02.349 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 5573893423aec2d64871e8d504fadbcdaad39fed +F src/vdbe.c 9e2b906528de10d62c33e7c4f1ac50f96d43b4ed F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 17e8524fc05aa1e6074c19a8ccccc5ab5883103a -R fdf3e89d3298858e83482c5ae882639e +P 6cc023bb29be51847fbbfab95c24fc89993ccdba +R ea2b846df6a1b7af99928ae17f1103b5 U drh -Z 293cb080495f6949faacc3bee3334f1e +Z 854085182559c61795f3e3e96d9d7a82 diff --git a/manifest.uuid b/manifest.uuid index ca50561c4c..3983daa607 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6cc023bb29be51847fbbfab95c24fc89993ccdba \ No newline at end of file +96a65388e75fed96e2e73ef65726f6db88cc5ccd \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1cd7be94ea..21d0dfaab2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1662,17 +1662,19 @@ case OP_AddImm: { /* in1 */ */ case OP_MustBeInt: { /* jump, in1 */ pIn1 = &aMem[pOp->p1]; - applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); if( (pIn1->flags & MEM_Int)==0 ){ - if( pOp->p2==0 ){ - rc = SQLITE_MISMATCH; - goto abort_due_to_error; - }else{ - pc = pOp->p2 - 1; + applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding); + if( (pIn1->flags & MEM_Int)==0 ){ + if( pOp->p2==0 ){ + rc = SQLITE_MISMATCH; + goto abort_due_to_error; + }else{ + pc = pOp->p2 - 1; + break; + } } - }else{ - MemSetTypeFlag(pIn1, MEM_Int); } + MemSetTypeFlag(pIn1, MEM_Int); break; } From 79353dbd5fbb4ab914159b596b50ac62f2aea2e5 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 02:53:58 +0000 Subject: [PATCH 32/78] Simplifications to the VdbeCursor object. FossilOrigin-Name: 5562cd343d8f69242e06a51a7f1aef7ee7d78eec --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- src/vdbe.c | 1 - src/vdbeInt.h | 8 +++----- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 63b26c9cc0..0b494c9b3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovement\sfor\sthe\sOP_MustBeInt\sopcode\sin\sthe\sVDBE. -D 2013-11-20T00:59:02.349 +C Simplifications\sto\sthe\sVdbeCursor\sobject. +D 2013-11-20T02:53:58.741 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c 1a295d8b0a2ba08919ad9300ebf7b67988ff4030 +F src/expr.c d81090a3f3bb0845fa6c6795d221ec23ef107737 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 @@ -280,9 +280,9 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 9e2b906528de10d62c33e7c4f1ac50f96d43b4ed +F src/vdbe.c da810a2b71f26e23d597e3b966166db8f1117fad F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 62eb680327011f3a4b0336642b0ca9d6ecc6eb91 +F src/vdbeInt.h 4044cd2e9dc1aef3e15fc68f80cbdf2446eff369 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 91f9e1fb59561fa7ba312b518b6123982c912d6c F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6cc023bb29be51847fbbfab95c24fc89993ccdba -R ea2b846df6a1b7af99928ae17f1103b5 +P 96a65388e75fed96e2e73ef65726f6db88cc5ccd +R ca796b6fcdb020d784b4cd61fedf5893 U drh -Z 854085182559c61795f3e3e96d9d7a82 +Z 97e722e14aa88f975fca1769e7e16ee6 diff --git a/manifest.uuid b/manifest.uuid index 3983daa607..27fbbf3bcd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96a65388e75fed96e2e73ef65726f6db88cc5ccd \ No newline at end of file +5562cd343d8f69242e06a51a7f1aef7ee7d78eec \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 048146b375..ce541ed8ab 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1193,7 +1193,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ /* Consider functions to be constant if all their arguments are constant ** and pWalker->u.i==2 */ case TK_FUNCTION: - if( pWalker->u.i==2 ) return 0; + if( pWalker->u.i==2 ) return WRC_Continue; /* Fall through */ case TK_ID: case TK_COLUMN: diff --git a/src/vdbe.c b/src/vdbe.c index 21d0dfaab2..bee9a4efe3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4504,7 +4504,6 @@ case OP_Rewind: { /* jump */ pCrsr = pC->pCursor; assert( pCrsr ); rc = sqlite3BtreeFirst(pCrsr, &res); - pC->atFirst = res==0 ?1:0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; pC->rowidIsValid = 0; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4f63189f5e..d5cad65ecd 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -61,12 +61,10 @@ struct VdbeCursor { BtCursor *pCursor; /* The cursor structure of the backend */ Btree *pBt; /* Separate file holding temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ - int iDb; /* Index of cursor database in db->aDb[] (or -1) */ int pseudoTableReg; /* Register holding pseudotable content. */ - int nField; /* Number of fields in the header */ - Bool zeroed; /* True if zeroed out and ready for reuse */ + i16 nField; /* Number of fields in the header */ + i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ Bool rowidIsValid; /* True if lastRowid is valid */ - Bool atFirst; /* True if pointing to first entry */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow; /* True if pointing to a row with no data */ Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ @@ -79,7 +77,7 @@ struct VdbeCursor { const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ - i64 lastRowid; /* Last rowid from a Next or NextIdx operation */ + i64 lastRowid; /* Rowid being deleted by OP_Delete */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists */ From 399af1d2c26f383c6069b30e2ca966de31689aba Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 17:25:55 +0000 Subject: [PATCH 33/78] Refactoring the OP_Column opcode for improved performance and maintainability. FossilOrigin-Name: 7c914e3997d2b28164a2fa7eb4398262b6ddb4b2 --- manifest | 19 ++-- manifest.uuid | 2 +- src/vdbe.c | 294 ++++++++++++++++++++------------------------------ src/vdbeInt.h | 8 +- src/vdbeaux.c | 2 +- 5 files changed, 135 insertions(+), 190 deletions(-) diff --git a/manifest b/manifest index 0b494c9b3b..91be839db0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplifications\sto\sthe\sVdbeCursor\sobject. -D 2013-11-20T02:53:58.741 +C Refactoring\sthe\sOP_Column\sopcode\sfor\simproved\sperformance\sand\nmaintainability. +D 2013-11-20T17:25:55.912 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,11 +280,11 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c da810a2b71f26e23d597e3b966166db8f1117fad +F src/vdbe.c d4b8a9067a163f18535324c76bafdddff6b93491 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 4044cd2e9dc1aef3e15fc68f80cbdf2446eff369 +F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 91f9e1fb59561fa7ba312b518b6123982c912d6c +F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90 F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1140,7 +1140,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 96a65388e75fed96e2e73ef65726f6db88cc5ccd -R ca796b6fcdb020d784b4cd61fedf5893 +P 5562cd343d8f69242e06a51a7f1aef7ee7d78eec +R 71521f10a62f5e2d15e34378a9a872cf +T *branch * OP_Column-refactor +T *sym-OP_Column-refactor * +T -sym-trunk * U drh -Z 97e722e14aa88f975fca1769e7e16ee6 +Z 41c0df82986aff89d8eb065b326b79ba diff --git a/manifest.uuid b/manifest.uuid index 27fbbf3bcd..6e355397de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5562cd343d8f69242e06a51a7f1aef7ee7d78eec \ No newline at end of file +7c914e3997d2b28164a2fa7eb4398262b6ddb4b2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bee9a4efe3..874645f189 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -214,7 +214,7 @@ static VdbeCursor *allocateCursor( nByte = ROUND8(sizeof(VdbeCursor)) + (isBtreeCursor?sqlite3BtreeCursorSize():0) + - 2*nField*sizeof(u32); + (2*nField+2)*sizeof(u32); assert( iCurnCursor ); if( p->apCsr[iCur] ){ @@ -228,10 +228,11 @@ static VdbeCursor *allocateCursor( pCx->nField = nField; if( nField ){ pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; + pCx->aOffset = pCx->aType + nField; } if( isBtreeCursor ){ pCx->pCursor = (BtCursor*) - &pMem->z[ROUND8(sizeof(VdbeCursor))+2*nField*sizeof(u32)]; + &pMem->z[ROUND8(sizeof(VdbeCursor))+(2*nField+2)*sizeof(u32)]; sqlite3BtreeCursorZero(pCx->pCursor); } } @@ -2253,151 +2254,101 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ ** skipped for length() and all content loading can be skipped for typeof(). */ case OP_Column: { - u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ - char *zRec; /* Pointer to complete record-data */ BtCursor *pCrsr; /* The BTree cursor */ u32 *aType; /* aType[i] holds the numeric type of the i-th column */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ int nField; /* number of fields in the record */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ - char *zData; /* Part of the record being decoded */ Mem *pDest; /* Where to write the extracted value */ Mem sMem; /* For storing the record being decoded */ - u8 *zIdx; /* Index into header */ - u8 *zEndHdr; /* Pointer to first byte after the header */ + const u8 *zData; /* Part of the record being decoded */ + const u8 *zHdr; /* Next unparsed byte of the header */ + const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u32 szField; /* Number of bytes in the content of a field */ - int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ - p1 = pOp->p1; - p2 = pOp->p2; - pC = 0; - memset(&sMem, 0, sizeof(sMem)); assert( p1nCursor ); + p2 = pOp->p2; + sMem.zMalloc = 0; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); - zRec = 0; - - /* This block sets the variable payloadSize to be the total number of - ** bytes in the record. - ** - ** zRec is set to be the complete text of the record if it is available. - ** The complete record text is always available for pseudo-tables - ** If the record is stored in a cursor, the complete record text - ** might be available in the pC->aRow cache. Or it might not be. - ** If the data is unavailable, zRec is set to NULL. - ** - ** We also compute the number of columns in the record. For cursors, - ** the number of columns is stored in the VdbeCursor.nField element. - */ pC = p->apCsr[p1]; assert( pC!=0 ); + nField = pC->nField; + assert( p2aType; + aOffset = pC->aOffset; #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); #endif pCrsr = pC->pCursor; - if( pCrsr!=0 ){ - /* The record is stored in a B-Tree */ - rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; - if( pC->nullRow ){ - payloadSize = 0; - }else if( pC->cacheStatus==p->cacheCtr ){ - payloadSize = pC->payloadSize; - zRec = (char*)pC->aRow; - }else if( pC->isIndex ){ - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); - assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ - /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the - ** payload size, so it is impossible for payloadSize64 to be - ** larger than 32 bits. */ - assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); - payloadSize = (u32)payloadSize64; - }else{ - assert( sqlite3BtreeCursorIsValid(pCrsr) ); - VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &payloadSize); - assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ - } - }else{ - assert( pC->pseudoTableReg>0 ); - pReg = &aMem[pC->pseudoTableReg]; - if( pC->multiPseudo ){ - sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); - Deephemeralize(pDest); + assert( pCrsr!=0 || pC->pseudoTableReg>0 ); + + /* 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 || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){ + if( pCrsr==0 ){ + assert( pC->pseudoTableReg>0 ); + pReg = &aMem[pC->pseudoTableReg]; + if( pC->multiPseudo ){ + sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); + Deephemeralize(pDest); + goto op_column_out; + } + assert( pReg->flags & MEM_Blob ); + assert( memIsValid(pReg) ); + pC->payloadSize = pC->szRow = avail = pReg->n; + pC->aRow = (u8*)pReg->z; + }else if( pC->nullRow ){ + MemSetTypeFlag(pDest, MEM_Null); goto op_column_out; - } - assert( pReg->flags & MEM_Blob ); - assert( memIsValid(pReg) ); - payloadSize = pReg->n; - zRec = pReg->z; - pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; - assert( payloadSize==0 || zRec!=0 ); - } - - /* If payloadSize is 0, then just store a NULL. This can happen because of - ** nullRow or because of a corrupt database. */ - if( payloadSize==0 ){ - MemSetTypeFlag(pDest, MEM_Null); - goto op_column_out; - } - assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); - if( payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - - nField = pC->nField; - assert( p2aType; - if( pC->cacheStatus==p->cacheCtr ){ - aOffset = pC->aOffset; - }else{ - assert(aType); - avail = 0; - pC->aOffset = aOffset = &aType[nField]; - pC->payloadSize = payloadSize; - pC->cacheStatus = p->cacheCtr; - - /* Figure out how many bytes are in the header */ - if( zRec ){ - zData = zRec; }else{ if( pC->isIndex ){ - zData = (char*)sqlite3BtreeKeyFetch(pCrsr, &avail); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the + ** payload size, so it is impossible for payloadSize64 to be + ** larger than 32 bits. */ + assert( (payloadSize64 & SQLITE_MAX_U32)==(u64)payloadSize64 ); + pC->aRow = sqlite3BtreeKeyFetch(pCrsr, &avail); + pC->payloadSize = (u32)payloadSize64; }else{ - zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + VVA_ONLY(rc =) sqlite3BtreeDataSize(pCrsr, &pC->payloadSize); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + pC->aRow = sqlite3BtreeDataFetch(pCrsr, &avail); } - /* If KeyFetch()/DataFetch() managed to get the entire payload, - ** save the payload in the pC->aRow cache. That will save us from - ** having to make additional calls to fetch the content portion of - ** the record. - */ - assert( avail>=0 ); - if( payloadSize <= (u32)avail ){ - zRec = zData; - pC->aRow = (u8*)zData; + assert( avail<=65536 ); /* Maximum page size is 64KiB */ + if( pC->payloadSize <= (u32)avail ){ + pC->szRow = pC->payloadSize; }else{ - pC->aRow = 0; + pC->szRow = avail; + } + if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + goto too_big; } } - /* The following assert is true in all cases except when - ** the database file has been corrupted externally. - ** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */ - szHdr = getVarint32((u8*)zData, offset); + + pC->cacheStatus = p->cacheCtr; + pC->iHdrOffset = getVarint32(pC->aRow, offset); + pC->nHdrParsed = 0; + aOffset[0] = offset; + if( availaRow = 0; + pC->szRow = 0; + } /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. @@ -2408,78 +2359,55 @@ case OP_Column: { ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ - if( offset > 98307 ){ + if( offset > 98307 || offset > pC->payloadSize ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } + } - /* Compute in len the number of bytes of data we need to read in order - ** to get nField type values. offset is an upper bound on this. But - ** nField might be significantly less than the true number of columns - ** in the table, and in that case, 5*nField+3 might be smaller than offset. - ** We want to minimize len in order to limit the size of the memory - ** allocation, especially if a corrupt database file has caused offset - ** to be oversized. Offset is limited to 98307 above. But 98307 might - ** still exceed Robson memory allocation limits on some configurations. - ** On systems that cannot tolerate large memory allocations, nField*5+3 - ** will likely be much smaller since nField will likely be less than - ** 20 or so. This insures that Robson memory allocation limits are - ** not exceeded even for corrupt database files. - */ - len = nField*5 + 3; - if( len > (int)offset ) len = (int)offset; - - /* The KeyFetch() or DataFetch() above are fast and will get the entire - ** record header in most cases. But they will fail to get the complete - ** record header if the record header does not fit on a single page - ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to - ** acquire the complete header text. - */ - if( !zRec && availisIndex, &sMem); + /* Make sure at least the first p2+1 entries of the header have been + ** parsed and valid information is in aOffset[] and aType[]. + */ + if( pC->nHdrParsed<=p2 && pC->iHdrOffsetaRow==0 ){ + memset(&sMem, 0, sizeof(sMem)); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, pC->aOffset[0], pC->isIndex,&sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - zData = sMem.z; + zData = (u8*)sMem.z; + }else{ + zData = pC->aRow; } - zEndHdr = (u8 *)&zData[len]; - zIdx = (u8 *)&zData[szHdr]; - /* Scan the header and use it to fill in the aType[] and aOffset[] - ** arrays. aType[i] will contain the type integer for the i-th - ** column and aOffset[i] will contain the offset from the beginning - ** of the record to the start of the data for the i-th column - */ - for(i=0; inHdrParsed; + offset = aOffset[i]; + zHdr = zData + pC->iHdrOffset; + zEndHdr = zData + pC->aOffset[0]; + for(; i<=p2 && zHdrnHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ){ + sqlite3VdbeMemRelease(&sMem); + sMem.flags = MEM_Null; } - sqlite3VdbeMemRelease(&sMem); - sMem.flags = MEM_Null; /* If we have read more header data than was contained in the header, ** or if the end of the last field appears to be past the end of the @@ -2487,8 +2415,10 @@ case OP_Column: { ** of the record (when all fields present), then we must be dealing ** with a corrupt database. */ - if( (zIdx > zEndHdr) || (offset > payloadSize) - || (zIdx==zEndHdr && offset!=payloadSize) ){ + if( (zHdr > zEndHdr) + || (offset > pC->payloadSize) + || (zHdr==zEndHdr && offset!=pC->payloadSize) + ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } @@ -2500,12 +2430,12 @@ case OP_Column: { ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ - if( aOffset[p2] ){ + if( p2nHdrParsed ){ assert( rc==SQLITE_OK ); - if( zRec ){ + if( pC->szRow>=aOffset[p2+1] ){ /* This is the common case where the whole row fits on a single page */ VdbeMemRelease(pDest); - sqlite3VdbeSerialGet((u8 *)&zRec[aOffset[p2]], aType[p2], pDest); + sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); }else{ /* This branch happens only when the row overflows onto multiple pages */ t = aType[p2]; @@ -2517,18 +2447,19 @@ case OP_Column: { ** bogus content rather than reading content from disk. NULL works ** for text and blob and whatever is in the payloadSize64 variable ** will work for everything else. */ - zData = t<12 ? (char*)&payloadSize64 : 0; + zData = t<12 ? (u8*)&payloadSize64 : 0; }else{ len = sqlite3VdbeSerialTypeLen(t); + memset(&sMem, 0, sizeof(sMem)); sqlite3VdbeMemMove(&sMem, pDest); rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, &sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - zData = sMem.z; + zData = (u8*)sMem.z; } - sqlite3VdbeSerialGet((u8*)zData, t, pDest); + sqlite3VdbeSerialGet(zData, t, pDest); } pDest->enc = encoding; }else{ @@ -3312,6 +3243,8 @@ case OP_OpenWrite: { nField = pOp->p4.i; } assert( pOp->p1>=0 ); + assert( nField>=0 ); + testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; @@ -3372,6 +3305,7 @@ case OP_OpenEphemeral: { SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; @@ -3417,6 +3351,8 @@ case OP_OpenEphemeral: { case OP_SorterOpen: { VdbeCursor *pCx; + assert( pOp->p1>=0 ); + assert( pOp->p2>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->pKeyInfo = pOp->p4.pKeyInfo; @@ -3448,6 +3384,7 @@ case OP_OpenPseudo: { VdbeCursor *pCx; assert( pOp->p1>=0 ); + assert( pOp->p3>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; @@ -4421,6 +4358,7 @@ case OP_NullRow: { assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; + pC->cacheStatus = CACHE_STALE; assert( pC->pCursor || pC->pVtabCursor ); if( pC->pCursor ){ sqlite3BtreeClearCursor(pC->pCursor); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index d5cad65ecd..fdd1f46744 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -93,10 +93,14 @@ struct VdbeCursor { ** be NULL. */ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - int payloadSize; /* Total number of bytes in the record */ + u32 payloadSize; /* Total number of bytes in the record */ + u16 nHdrParsed; /* Number of header fields parsed so far */ + u16 nFieldPresent; /* Number of fields in the record */ + u32 szRow; /* Byte available in aRow */ + u32 iHdrOffset; /* Offset to next unparsed byte of the header */ u32 *aType; /* Type values for all entries in the record */ u32 *aOffset; /* Cached offsets to the start of each columns data */ - u8 *aRow; /* Data for the current row, if all on one page */ + const u8 *aRow; /* Data for the current row, if all on one page */ }; typedef struct VdbeCursor VdbeCursor; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index dc284b54ae..2e3cdfb711 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2658,7 +2658,7 @@ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ #endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; - }else if( ALWAYS(p->pCursor) ){ + }else if( p->pCursor ){ int hasMoved; int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); if( rc ) return rc; From c8606e416a6cab18e24a33d730a1a43376b0003c Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 19:28:03 +0000 Subject: [PATCH 34/78] Further performance tweaks to OP_Column. FossilOrigin-Name: 0e3f5df695216a27602a53eed5d25231b055adc8 --- manifest | 17 ++- manifest.uuid | 2 +- src/vdbe.c | 261 +++++++++++++++++++++++---------------------- test/analyze9.test | 3 +- 4 files changed, 146 insertions(+), 137 deletions(-) diff --git a/manifest b/manifest index 91be839db0..a7de779afd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactoring\sthe\sOP_Column\sopcode\sfor\simproved\sperformance\sand\nmaintainability. -D 2013-11-20T17:25:55.912 +C Further\sperformance\stweaks\sto\sOP_Column. +D 2013-11-20T19:28:03.982 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c d4b8a9067a163f18535324c76bafdddff6b93491 +F src/vdbe.c 1a6e2c9413fca3b2d00c49e85a861e0adc8b6c6a F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -313,7 +313,7 @@ F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4 F test/analyze6.test d31defa011a561b938b4608d3538c1b4e0b5e92c F test/analyze7.test bb1409afc9e8629e414387ef048b8e0e3e0bdc4f F test/analyze8.test 093d15c1c888eed5034304a98c992f7360130b88 -F test/analyze9.test 1b9b7e9a096d1536f03d9ad7b72f638ef5669347 +F test/analyze9.test 339e87723cd4dc158dc5e9095acd8df9e87faf79 F test/analyzeA.test 1a5c40079894847976d983ca39c707aaa44b6944 F test/analyzeB.test 8bf35ee0a548aea831bf56762cb8e7fdb1db083d F test/async.test 1d0e056ba1bb9729283a0f22718d3a25e82c277b @@ -1140,10 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5562cd343d8f69242e06a51a7f1aef7ee7d78eec -R 71521f10a62f5e2d15e34378a9a872cf -T *branch * OP_Column-refactor -T *sym-OP_Column-refactor * -T -sym-trunk * +P 7c914e3997d2b28164a2fa7eb4398262b6ddb4b2 +R 72749b37eba95a49879e9308fdcd90bb U drh -Z 41c0df82986aff89d8eb065b326b79ba +Z 441207295dddfadd80f4cc85b77f0a53 diff --git a/manifest.uuid b/manifest.uuid index 6e355397de..458e461e6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7c914e3997d2b28164a2fa7eb4398262b6ddb4b2 \ No newline at end of file +0e3f5df695216a27602a53eed5d25231b055adc8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 874645f189..f3832ab34f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2255,13 +2255,11 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ */ case OP_Column: { i64 payloadSize64; /* Number of bytes in the record */ - int p1; /* P1 value of the opcode */ int p2; /* column number to retrieve */ VdbeCursor *pC; /* The VDBE cursor */ BtCursor *pCrsr; /* The BTree cursor */ u32 *aType; /* aType[i] holds the numeric type of the i-th column */ u32 *aOffset; /* aOffset[i] is offset to start of data for i-th column */ - int nField; /* number of fields in the record */ int len; /* The length of the serialized data for the column */ int i; /* Loop counter */ Mem *pDest; /* Where to write the extracted value */ @@ -2275,17 +2273,14 @@ case OP_Column: { u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ - p1 = pOp->p1; - assert( p1nCursor ); p2 = pOp->p2; - sMem.zMalloc = 0; assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); - pC = p->apCsr[p1]; + assert( pOp->p1>=0 && pOp->p1nCursor ); + pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - nField = pC->nField; - assert( p2nField ); aType = pC->aType; aOffset = pC->aOffset; #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -2293,27 +2288,31 @@ case OP_Column: { #endif pCrsr = pC->pCursor; assert( pCrsr!=0 || pC->pseudoTableReg>0 ); + assert( pC->pseudoTableReg==0 || pC->nullRow ); /* 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 || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){ - if( pCrsr==0 ){ - assert( pC->pseudoTableReg>0 ); - pReg = &aMem[pC->pseudoTableReg]; - if( pC->multiPseudo ){ - sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); - Deephemeralize(pDest); + if( pC->nullRow ){ + if( pCrsr==0 ){ + assert( pC->pseudoTableReg>0 ); + pReg = &aMem[pC->pseudoTableReg]; + if( pC->multiPseudo ){ + sqlite3VdbeMemShallowCopy(pDest, pReg+p2, MEM_Ephem); + Deephemeralize(pDest); + goto op_column_out; + } + assert( pReg->flags & MEM_Blob ); + assert( memIsValid(pReg) ); + pC->payloadSize = pC->szRow = avail = pReg->n; + pC->aRow = (u8*)pReg->z; + }else{ + MemSetTypeFlag(pDest, MEM_Null); goto op_column_out; } - assert( pReg->flags & MEM_Blob ); - assert( memIsValid(pReg) ); - pC->payloadSize = pC->szRow = avail = pReg->n; - pC->aRow = (u8*)pReg->z; - }else if( pC->nullRow ){ - MemSetTypeFlag(pDest, MEM_Null); - goto op_column_out; }else{ + assert( pCrsr ); if( pC->isIndex ){ assert( sqlite3BtreeCursorIsValid(pCrsr) ); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); @@ -2361,65 +2360,85 @@ case OP_Column: { */ if( offset > 98307 || offset > pC->payloadSize ){ rc = SQLITE_CORRUPT_BKPT; - goto op_column_out; + goto op_column_error; } } /* Make sure at least the first p2+1 entries of the header have been ** parsed and valid information is in aOffset[] and aType[]. */ - if( pC->nHdrParsed<=p2 && pC->iHdrOffsetaRow==0 ){ - memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, pC->aOffset[0], pC->isIndex,&sMem); - if( rc!=SQLITE_OK ){ - goto op_column_out; - } - zData = (u8*)sMem.z; - }else{ - zData = pC->aRow; - } - - /* Fill in aType[i] and aOffset[i] values through the p2-th field. */ - i = pC->nHdrParsed; - offset = aOffset[i]; - zHdr = zData + pC->iHdrOffset; - zEndHdr = zData + pC->aOffset[0]; - for(; i<=p2 && zHdrnHdrParsed = i; - pC->iHdrOffset = (u32)(zHdr - zData); - if( pC->aRow==0 ){ - sqlite3VdbeMemRelease(&sMem); - sMem.flags = MEM_Null; - } - - /* If we have read more header data than was contained in the header, - ** or if the end of the last field appears to be past the end of the - ** record, or if the end of the last field appears to be before the end - ** of the record (when all fields present), then we must be dealing - ** with a corrupt database. + if( pC->nHdrParsed<=p2 ){ + /* If there is more header available for parsing, try to extract + ** additional fields up through the p2-th field */ - if( (zHdr > zEndHdr) - || (offset > pC->payloadSize) - || (zHdr==zEndHdr && offset!=pC->payloadSize) - ){ - rc = SQLITE_CORRUPT_BKPT; + if( pC->iHdrOffsetaRow==0 ){ + memset(&sMem, 0, sizeof(sMem)); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, pC->aOffset[0], pC->isIndex, + &sMem); + if( rc!=SQLITE_OK ){ + goto op_column_error; + } + zData = (u8*)sMem.z; + }else{ + zData = pC->aRow; + } + + /* Fill in aType[i] and aOffset[i] values through the p2-th field. */ + i = pC->nHdrParsed; + offset = aOffset[i]; + zHdr = zData + pC->iHdrOffset; + zEndHdr = zData + aOffset[0]; + assert( i<=p2 && zHdrnHdrParsed = i; + pC->iHdrOffset = (u32)(zHdr - zData); + if( pC->aRow==0 ){ + sqlite3VdbeMemRelease(&sMem); + sMem.flags = MEM_Null; + } + + /* If we have read more header data than was contained in the header, + ** or if the end of the last field appears to be past the end of the + ** record, or if the end of the last field appears to be before the end + ** of the record (when all fields present), then we must be dealing + ** with a corrupt database. + */ + if( (zHdr > zEndHdr) + || (offset > pC->payloadSize) + || (zHdr==zEndHdr && offset!=pC->payloadSize) + ){ + rc = SQLITE_CORRUPT_BKPT; + goto op_column_error; + } + } + + /* If after nHdrParsed is still not up to p2, that means that the record + ** has fewer than p2 columns. So the result will be either the default + ** value or a NULL. */ + if( pC->nHdrParsed<=p2 ){ + if( pOp->p4type==P4_MEM ){ + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + }else{ + MemSetTypeFlag(pDest, MEM_Null); + } goto op_column_out; } } @@ -2430,64 +2449,56 @@ case OP_Column: { ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ - if( p2nHdrParsed ){ - assert( rc==SQLITE_OK ); - if( pC->szRow>=aOffset[p2+1] ){ - /* This is the common case where the whole row fits on a single page */ - VdbeMemRelease(pDest); - sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); - }else{ - /* This branch happens only when the row overflows onto multiple pages */ - t = aType[p2]; - if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 - && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) - ){ - /* Content is irrelevant for the typeof() function and for - ** the length(X) function if X is a blob. So we might as well use - ** bogus content rather than reading content from disk. NULL works - ** for text and blob and whatever is in the payloadSize64 variable - ** will work for everything else. */ - zData = t<12 ? (u8*)&payloadSize64 : 0; - }else{ - len = sqlite3VdbeSerialTypeLen(t); - memset(&sMem, 0, sizeof(sMem)); - sqlite3VdbeMemMove(&sMem, pDest); - rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, - &sMem); - if( rc!=SQLITE_OK ){ - goto op_column_out; - } - zData = (u8*)sMem.z; - } - sqlite3VdbeSerialGet(zData, t, pDest); - } - pDest->enc = encoding; + assert( p2nHdrParsed ); + assert( rc==SQLITE_OK ); + if( pC->szRow>=aOffset[p2+1] ){ + /* This is the common case where the whole row fits on a single page */ + VdbeMemRelease(pDest); + sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); }else{ - if( pOp->p4type==P4_MEM ){ - sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + /* This branch happens only when the row overflows onto multiple pages */ + t = aType[p2]; + if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 + && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) + ){ + /* Content is irrelevant for the typeof() function and for + ** the length(X) function if X is a blob. So we might as well use + ** bogus content rather than reading content from disk. NULL works + ** for text and blob and whatever is in the payloadSize64 variable + ** will work for everything else. */ + zData = t<12 ? (u8*)&payloadSize64 : 0; + sMem.zMalloc = 0; }else{ - MemSetTypeFlag(pDest, MEM_Null); + len = sqlite3VdbeSerialTypeLen(t); + memset(&sMem, 0, sizeof(sMem)); + sqlite3VdbeMemMove(&sMem, pDest); + rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, + &sMem); + if( rc!=SQLITE_OK ){ + goto op_column_error; + } + zData = (u8*)sMem.z; + } + sqlite3VdbeSerialGet(zData, t, pDest); + /* If we dynamically allocated space to hold the data (in the + ** sqlite3VdbeMemFromBtree() call above) then transfer control of that + ** dynamically allocated space over to the pDest structure. + ** This prevents a memory copy. */ + if( sMem.zMalloc ){ + assert( sMem.z==sMem.zMalloc ); + assert( !(pDest->flags & MEM_Dyn) ); + assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z ); + pDest->flags &= ~(MEM_Ephem|MEM_Static); + pDest->flags |= MEM_Term; + pDest->z = sMem.z; + pDest->zMalloc = sMem.zMalloc; } } - - /* If we dynamically allocated space to hold the data (in the - ** sqlite3VdbeMemFromBtree() call above) then transfer control of that - ** dynamically allocated space over to the pDest structure. - ** This prevents a memory copy. - */ - if( sMem.zMalloc ){ - assert( sMem.z==sMem.zMalloc ); - assert( !(pDest->flags & MEM_Dyn) ); - assert( !(pDest->flags & (MEM_Blob|MEM_Str)) || pDest->z==sMem.z ); - pDest->flags &= ~(MEM_Ephem|MEM_Static); - pDest->flags |= MEM_Term; - pDest->z = sMem.z; - pDest->zMalloc = sMem.zMalloc; - } - - rc = sqlite3VdbeMemMakeWriteable(pDest); + pDest->enc = encoding; op_column_out: + rc = sqlite3VdbeMemMakeWriteable(pDest); +op_column_error: UPDATE_MAX_BLOBSIZE(pDest); REGISTER_TRACE(pOp->p3, pDest); break; diff --git a/test/analyze9.test b/test/analyze9.test index aaf0ba3bb0..0fce55ac4b 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -805,8 +805,9 @@ do_test 16.1 { ANALYZE; } set nByte2 [lindex [sqlite3_db_status db SCHEMA_USED 0] 1] + puts -nonewline " (nByte=$nByte nByte2=$nByte2)" - expr {$nByte2 > $nByte+900 && $nByte2 < $nByte+1050} + expr {$nByte2 > $nByte+900 && $nByte2 < $nByte+1100} } {1} #------------------------------------------------------------------------- From 380d68513316fa6fabd50f222ed8c5d68fc7376d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 20:58:00 +0000 Subject: [PATCH 35/78] Improved comments on the OP_Column changes. Optimize out loading of overflow pages for content with zero length. Add test cases for the latter. FossilOrigin-Name: 0e05679db7aa302a49e087a81f85203844b98cbe --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 46 +++++++++++++++++++++++++--------------------- test/func.test | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index a7de779afd..a137e832e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\sperformance\stweaks\sto\sOP_Column. -D 2013-11-20T19:28:03.982 +C Improved\scomments\son\sthe\sOP_Column\schanges.\s\sOptimize\sout\sloading\sof\soverflow\npages\sfor\scontent\swith\szero\slength.\s\sAdd\stest\scases\sfor\sthe\slatter. +D 2013-11-20T20:58:00.360 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 1a6e2c9413fca3b2d00c49e85a861e0adc8b6c6a +F src/vdbe.c 987f375b8ba5b5c3d0ded64191f72706221f76f9 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -573,7 +573,7 @@ F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584 F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057 F test/fts4unicode.test e28ba1a14181e709dcdf47455f207adf14c7cfe0 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test c7e80a44eebac8604397eb2ad83d0d5d9d541237 +F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 7c914e3997d2b28164a2fa7eb4398262b6ddb4b2 -R 72749b37eba95a49879e9308fdcd90bb +P 0e3f5df695216a27602a53eed5d25231b055adc8 +R 7b4a6a3b4e08d369fabb1ea696a3ba02 U drh -Z 441207295dddfadd80f4cc85b77f0a53 +Z a02194f256e2495862011254263d6e91 diff --git a/manifest.uuid b/manifest.uuid index 458e461e6b..d385d476cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e3f5df695216a27602a53eed5d25231b055adc8 \ No newline at end of file +0e05679db7aa302a49e087a81f85203844b98cbe \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f3832ab34f..e70cd49ae0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2284,11 +2284,11 @@ case OP_Column: { aType = pC->aType; aOffset = pC->aOffset; #ifndef SQLITE_OMIT_VIRTUALTABLE - assert( pC->pVtabCursor==0 ); + assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ #endif pCrsr = pC->pCursor; - assert( pCrsr!=0 || pC->pseudoTableReg>0 ); - assert( pC->pseudoTableReg==0 || pC->nullRow ); + assert( pCrsr!=0 || pC->pseudoTableReg>0 ); /* pCrsr NULL on PseudoTables */ + assert( pCrsr!=0 || pC->nullRow ); /* pC->nullRow on PseudoTables */ /* If the cursor cache is stale, bring it up-to-date */ rc = sqlite3VdbeCursorMoveto(pC); @@ -2339,12 +2339,15 @@ case OP_Column: { goto too_big; } } - pC->cacheStatus = p->cacheCtr; pC->iHdrOffset = getVarint32(pC->aRow, offset); pC->nHdrParsed = 0; aOffset[0] = offset; if( availaRow does not have to hold the entire row, but it does at least + ** need to cover the header of the record. If pC->aRow does not contain + ** the complete header, then set it to zero, forcing the header to be + ** dynamically allocated. */ pC->aRow = 0; pC->szRow = 0; } @@ -2368,8 +2371,8 @@ case OP_Column: { ** parsed and valid information is in aOffset[] and aType[]. */ if( pC->nHdrParsed<=p2 ){ - /* If there is more header available for parsing, try to extract - ** additional fields up through the p2-th field + /* If there is more header available for parsing in the record, try + ** to extract additional fields up through the p2+1-th field */ if( pC->iHdrOffsetnHdrParsed<=p2 ){ if( pOp->p4type==P4_MEM ){ sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); @@ -2443,33 +2447,33 @@ case OP_Column: { } } - /* Get the column information. If aOffset[p2] is non-zero, then - ** deserialize the value from the record. If aOffset[p2] is zero, - ** then there are not enough fields in the record to satisfy the - ** request. In this case, set the value NULL or to P4 if P4 is - ** a pointer to a Mem object. + /* Extract the content for the p2+1-th column. Control can only + ** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are + ** all valid. */ assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); if( pC->szRow>=aOffset[p2+1] ){ - /* This is the common case where the whole row fits on a single page */ + /* This is the common case where the desired content fits on the original + ** page - where the content is not on an overflow page */ VdbeMemRelease(pDest); sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest); }else{ - /* This branch happens only when the row overflows onto multiple pages */ + /* This branch happens only when content is on overflow pages */ t = aType[p2]; - if( (pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 - && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0) + if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 + && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) + || (len = sqlite3VdbeSerialTypeLen(t))==0 ){ /* Content is irrelevant for the typeof() function and for ** the length(X) function if X is a blob. So we might as well use ** bogus content rather than reading content from disk. NULL works ** for text and blob and whatever is in the payloadSize64 variable - ** will work for everything else. */ - zData = t<12 ? (u8*)&payloadSize64 : 0; + ** will work for everything else. Content is also irrelevant if + ** the content length is 0. */ + zData = t<=13 ? (u8*)&payloadSize64 : 0; sMem.zMalloc = 0; }else{ - len = sqlite3VdbeSerialTypeLen(t); memset(&sMem, 0, sizeof(sMem)); sqlite3VdbeMemMove(&sMem, pDest); rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, diff --git a/test/func.test b/test/func.test index 7c7d55e1b7..edec591eae 100644 --- a/test/func.test +++ b/test/func.test @@ -1319,6 +1319,24 @@ do_test func-29.6 { set x } {1} +# The OP_Column opcode has an optimization that avoids loading content +# for fields with content-length=0 when the content offset is on an overflow +# page. Make sure the optimization works. +# +do_execsql_test func-29.10 { + CREATE TABLE t29b(a,b,c,d,e,f,g,h,i); + INSERT INTO t29b + VALUES(1, hex(randomblob(2000)), null, 0, 1, '', zeroblob(0),'x',x'01'); + SELECT typeof(c), typeof(d), typeof(e), typeof(f), + typeof(g), typeof(h), typeof(i) FROM t29b; +} {null integer integer text blob text blob} +do_execsql_test func-29.11 { + SELECT length(f), length(g), length(h), length(i) FROM t29b; +} {0 0 1 1} +do_execsql_test func-29.12 { + SELECT quote(f), quote(g), quote(h), quote(i) FROM t29b; +} {'' X'' 'x' X'01'} + # EVIDENCE-OF: R-29701-50711 The unicode(X) function returns the numeric # unicode code point corresponding to the first character of the string # X. From 14da87f8c5d78b59303e1415a445b9461cf59b7a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 20 Nov 2013 21:51:33 +0000 Subject: [PATCH 36/78] Reduce the size of the VdbeCursor object from 144 to 120 bytes. FossilOrigin-Name: 5f9d50688508affd0bc8e4d52e21dacfacdbb5ce --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 39 +++++++++++++++++---------------------- src/vdbeInt.h | 26 ++++++++++---------------- src/vdbeblob.c | 7 ++++--- 5 files changed, 40 insertions(+), 50 deletions(-) diff --git a/manifest b/manifest index a137e832e8..ad39786967 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\sOP_Column\schanges.\s\sOptimize\sout\sloading\sof\soverflow\npages\sfor\scontent\swith\szero\slength.\s\sAdd\stest\scases\sfor\sthe\slatter. -D 2013-11-20T20:58:00.360 +C Reduce\sthe\ssize\sof\sthe\sVdbeCursor\sobject\sfrom\s144\sto\s120\sbytes. +D 2013-11-20T21:51:33.976 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,12 +280,12 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 987f375b8ba5b5c3d0ded64191f72706221f76f9 +F src/vdbe.c b55581dbd26eee6a03a7c673e9080db306fb8113 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h fbae1c449049a1a26ebbdf44e1beb08344072b72 +F src/vdbeInt.h fc6a1ca59e679cb27f55fd2bc7d91cfb963251dd F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90 -F src/vdbeblob.c d883398f7260725147dbf5b40c2b61332aee47f9 +F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0e3f5df695216a27602a53eed5d25231b055adc8 -R 7b4a6a3b4e08d369fabb1ea696a3ba02 +P 0e05679db7aa302a49e087a81f85203844b98cbe +R 25fcd0453526b0fb55425cafc8bedd31 U drh -Z a02194f256e2495862011254263d6e91 +Z 51316cd0cd8c72b5a20c8e69a256a48d diff --git a/manifest.uuid b/manifest.uuid index d385d476cd..66bae4760d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0e05679db7aa302a49e087a81f85203844b98cbe \ No newline at end of file +5f9d50688508affd0bc8e4d52e21dacfacdbb5ce \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e70cd49ae0..f01d2cc33c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -228,7 +228,6 @@ static VdbeCursor *allocateCursor( pCx->nField = nField; if( nField ){ pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; - pCx->aOffset = pCx->aType + nField; } if( isBtreeCursor ){ pCx->pCursor = (BtCursor*) @@ -2282,7 +2281,7 @@ case OP_Column: { assert( pC!=0 ); assert( p2nField ); aType = pC->aType; - aOffset = pC->aOffset; + aOffset = aType + pC->nField; #ifndef SQLITE_OMIT_VIRTUALTABLE assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */ #endif @@ -2313,7 +2312,7 @@ case OP_Column: { } }else{ assert( pCrsr ); - if( pC->isIndex ){ + if( pC->isTable==0 ){ assert( sqlite3BtreeCursorIsValid(pCrsr) ); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &payloadSize64); assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ @@ -2378,8 +2377,8 @@ case OP_Column: { /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); - rc = sqlite3VdbeMemFromBtree(pCrsr, 0, pC->aOffset[0], pC->isIndex, - &sMem); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], + !pC->isTable, &sMem); if( rc!=SQLITE_OK ){ goto op_column_error; } @@ -2476,7 +2475,7 @@ case OP_Column: { }else{ memset(&sMem, 0, sizeof(sMem)); sqlite3VdbeMemMove(&sMem, pDest); - rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, pC->isIndex, + rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable, &sMem); if( rc!=SQLITE_OK ){ goto op_column_error; @@ -3273,12 +3272,11 @@ case OP_OpenWrite: { ** sqlite3BtreeCursor() may return is SQLITE_OK. */ assert( rc==SQLITE_OK ); - /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of + /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point ** and report database corruption if they were not, but this check has ** since moved into the btree layer. */ pCur->isTable = pOp->p4type!=P4_KEYINFO; - pCur->isIndex = !pCur->isTable; break; } @@ -3353,7 +3351,6 @@ case OP_OpenEphemeral: { } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); - pCx->isIndex = !pCx->isTable; break; } @@ -3373,7 +3370,6 @@ case OP_SorterOpen: { pCx->pKeyInfo = pOp->p4.pKeyInfo; assert( pCx->pKeyInfo->db==db ); assert( pCx->pKeyInfo->enc==ENC(db) ); - pCx->isSorter = 1; rc = sqlite3VdbeSorterInit(db, pCx); break; } @@ -3405,7 +3401,6 @@ case OP_OpenPseudo: { pCx->nullRow = 1; pCx->pseudoTableReg = pOp->p2; pCx->isTable = 1; - pCx->isIndex = 0; pCx->multiPseudo = pOp->p5; break; } @@ -3764,7 +3759,7 @@ case OP_Found: { /* jump, in3 */ if( rc!=SQLITE_OK ){ break; } - pC->seekResult = res; + pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1; alreadyExists = (res==0); pC->nullRow = 1-alreadyExists; pC->deferredMoveto = 0; @@ -3818,7 +3813,7 @@ case OP_NotExists: { /* jump, in3 */ pc = pOp->p2 - 1; assert( pC->rowidIsValid==0 ); } - pC->seekResult = res; + pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1; break; } @@ -4041,7 +4036,7 @@ case OP_InsertInt: { i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; /* Cursor to table into which insert is written */ int nZero; /* Number of zero-bytes to append */ - int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + i8 seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ @@ -4221,7 +4216,7 @@ case OP_SorterData: { pOut = &aMem[pOp->p2]; pC = p->apCsr[pOp->p1]; - assert( pC->isSorter ); + assert( isSorter(pC) ); rc = sqlite3VdbeSorterRowkey(pC, pOut); break; } @@ -4261,9 +4256,9 @@ case OP_RowData: { /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - assert( pC->isSorter==0 ); + assert( isSorter(pC)==0 ); assert( pC->isTable || pOp->opcode!=OP_RowData ); - assert( pC->isIndex || pOp->opcode==OP_RowData ); + assert( pC->isTable==0 || pOp->opcode==OP_RowData ); assert( pC!=0 ); assert( pC->nullRow==0 ); assert( pC->pseudoTableReg==0 ); @@ -4280,7 +4275,7 @@ case OP_RowData: { rc = sqlite3VdbeCursorMoveto(pC); if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; - if( pC->isIndex ){ + if( pC->isTable==0 ){ assert( !pC->isTable ); VVA_ONLY(rc =) sqlite3BtreeKeySize(pCrsr, &n64); assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ @@ -4300,7 +4295,7 @@ case OP_RowData: { } pOut->n = n; MemSetTypeFlag(pOut, MEM_Blob); - if( pC->isIndex ){ + if( pC->isTable==0 ){ rc = sqlite3BtreeKey(pCrsr, 0, n, pOut->z); }else{ rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z); @@ -4449,7 +4444,7 @@ case OP_Rewind: { /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->isSorter==(pOp->opcode==OP_SorterSort) ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) ); res = 1; if( isSorter(pC) ){ rc = sqlite3VdbeSorterRewind(db, pC, &res); @@ -4513,7 +4508,7 @@ case OP_Next: { /* jump */ if( pC==0 ){ break; /* See ticket #2273 */ } - assert( pC->isSorter==(pOp->opcode==OP_SorterNext) ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterNext) ); if( isSorter(pC) ){ assert( pOp->opcode==OP_SorterNext ); rc = sqlite3VdbeSorterNext(db, pC, &res); @@ -4561,7 +4556,7 @@ case OP_IdxInsert: { /* in2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->isSorter==(pOp->opcode==OP_SorterInsert) ); + assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; assert( pIn2->flags & MEM_Blob ); pCrsr = pC->pCursor; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index fdd1f46744..4820df7af6 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -36,7 +36,7 @@ typedef struct VdbeOp Op; /* ** Boolean values */ -typedef unsigned char Bool; +typedef unsigned Bool; /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; @@ -63,16 +63,16 @@ struct VdbeCursor { KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int pseudoTableReg; /* Register holding pseudotable content. */ i16 nField; /* Number of fields in the header */ + u16 nHdrParsed; /* Number of header fields parsed so far */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ - Bool rowidIsValid; /* True if lastRowid is valid */ - Bool useRandomRowid; /* Generate new record numbers semi-randomly */ - Bool nullRow; /* True if pointing to a row with no data */ - Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ - Bool isTable; /* True if a table requiring integer keys */ - Bool isIndex; /* True if an index containing keys only - no data */ - Bool isOrdered; /* True if the underlying table is BTREE_UNORDERED */ - Bool isSorter; /* True if a new-style sorter */ - Bool multiPseudo; /* Multi-register pseudo-cursor */ + i8 seekResult; /* Result of previous sqlite3BtreeMoveto() */ + Bool nullRow:1; /* True if pointing to a row with no data */ + Bool rowidIsValid :1; /* True if lastRowid is valid */ + Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ + Bool deferredMoveto:1;/* A call to sqlite3BtreeMoveto() is needed */ + Bool isTable:1; /* True if a table requiring integer keys */ + Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ + Bool multiPseudo:1; /* Multi-register pseudo-cursor */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ @@ -80,9 +80,6 @@ struct VdbeCursor { i64 lastRowid; /* Rowid being deleted by OP_Delete */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ - /* Result of last sqlite3BtreeMoveto() done by an OP_NotExists */ - int seekResult; - /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of @@ -94,12 +91,9 @@ struct VdbeCursor { */ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ u32 payloadSize; /* Total number of bytes in the record */ - u16 nHdrParsed; /* Number of header fields parsed so far */ - u16 nFieldPresent; /* Number of fields in the record */ u32 szRow; /* Byte available in aRow */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ u32 *aType; /* Type values for all entries in the record */ - u32 *aOffset; /* Cached offsets to the start of each columns data */ const u8 *aRow; /* Data for the current row, if all on one page */ }; typedef struct VdbeCursor VdbeCursor; diff --git a/src/vdbeblob.c b/src/vdbeblob.c index a90c5b0af4..7859d4a6c5 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -64,7 +64,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ rc = sqlite3_step(p->pStmt); if( rc==SQLITE_ROW ){ - u32 type = v->apCsr[0]->aType[p->iCol]; + VdbeCursor *pC = v->apCsr[0]; + u32 type = pC->aType[p->iCol]; if( type<12 ){ zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" @@ -73,9 +74,9 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ sqlite3_finalize(p->pStmt); p->pStmt = 0; }else{ - p->iOffset = v->apCsr[0]->aOffset[p->iCol]; + p->iOffset = pC->aType[p->iCol + pC->nField]; p->nByte = sqlite3VdbeSerialTypeLen(type); - p->pCsr = v->apCsr[0]->pCursor; + p->pCsr = pC->pCursor; sqlite3BtreeEnterCursor(p->pCsr); sqlite3BtreeCacheOverflow(p->pCsr); sqlite3BtreeLeaveCursor(p->pCsr); From 1fd522ff49b5f889214785301cb08eaedb20682e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 00:10:35 +0000 Subject: [PATCH 37/78] Unpack some fields, adding some space back to the VdbeCursor object, in order to help the code to run a little faster. FossilOrigin-Name: f8d5efcd7b92492b833b6cd1cb6bec006c6a0809 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 6 +++--- src/vdbeInt.h | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ad39786967..b28f74bcf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reduce\sthe\ssize\sof\sthe\sVdbeCursor\sobject\sfrom\s144\sto\s120\sbytes. -D 2013-11-20T21:51:33.976 +C Unpack\ssome\sfields,\sadding\ssome\sspace\sback\sto\sthe\sVdbeCursor\sobject,\nin\sorder\sto\shelp\sthe\scode\sto\srun\sa\slittle\sfaster. +D 2013-11-21T00:10:35.929 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,9 +280,9 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c b55581dbd26eee6a03a7c673e9080db306fb8113 +F src/vdbe.c fb6007ac59ebebf398ce1709f9cef367bfd15dce F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h fc6a1ca59e679cb27f55fd2bc7d91cfb963251dd +F src/vdbeInt.h 7cb3c641d42154ea0c66055ca77557005ff4535d F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 0e05679db7aa302a49e087a81f85203844b98cbe -R 25fcd0453526b0fb55425cafc8bedd31 +P 5f9d50688508affd0bc8e4d52e21dacfacdbb5ce +R 11a6306351cf31959d33e284a4627112 U drh -Z 51316cd0cd8c72b5a20c8e69a256a48d +Z 5afd15b6c955a3c65a923acb8d5d260f diff --git a/manifest.uuid b/manifest.uuid index 66bae4760d..b0ba0a8bff 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f9d50688508affd0bc8e4d52e21dacfacdbb5ce \ No newline at end of file +f8d5efcd7b92492b833b6cd1cb6bec006c6a0809 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f01d2cc33c..d50a23fb85 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3759,7 +3759,7 @@ case OP_Found: { /* jump, in3 */ if( rc!=SQLITE_OK ){ break; } - pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1; + pC->seekResult = res; alreadyExists = (res==0); pC->nullRow = 1-alreadyExists; pC->deferredMoveto = 0; @@ -3813,7 +3813,7 @@ case OP_NotExists: { /* jump, in3 */ pc = pOp->p2 - 1; assert( pC->rowidIsValid==0 ); } - pC->seekResult = res==0 ? 0 : res<0 ? -1 : +1; + pC->seekResult = res; break; } @@ -4036,7 +4036,7 @@ case OP_InsertInt: { i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; /* Cursor to table into which insert is written */ int nZero; /* Number of zero-bytes to append */ - i8 seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ const char *zDb; /* database name - used by the update hook */ const char *zTbl; /* Table name - used by the opdate hook */ int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4820df7af6..b1b7f2eacc 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -61,15 +61,15 @@ struct VdbeCursor { BtCursor *pCursor; /* The cursor structure of the backend */ Btree *pBt; /* Separate file holding temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ + int seekResult; /* Result of previous sqlite3BtreeMoveto() */ int pseudoTableReg; /* Register holding pseudotable content. */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ - i8 seekResult; /* Result of previous sqlite3BtreeMoveto() */ - Bool nullRow:1; /* True if pointing to a row with no data */ - Bool rowidIsValid :1; /* True if lastRowid is valid */ + u8 nullRow; /* True if pointing to a row with no data */ + u8 rowidIsValid; /* True if lastRowid is valid */ + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */ - Bool deferredMoveto:1;/* A call to sqlite3BtreeMoveto() is needed */ Bool isTable:1; /* True if a table requiring integer keys */ Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Bool multiPseudo:1; /* Multi-register pseudo-cursor */ From 5cc1023e1c1c36f44618a7e3e65caf2967d51561 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 01:04:02 +0000 Subject: [PATCH 38/78] Reduce the size of VdbeCursor again, this time without a performance hit. FossilOrigin-Name: 933939932c44bccb0958f203a5bd24e683c1cf38 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 11 +++-------- src/vdbeInt.h | 9 +++++++-- src/vdbeaux.c | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index b28f74bcf3..667c92d94a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Unpack\ssome\sfields,\sadding\ssome\sspace\sback\sto\sthe\sVdbeCursor\sobject,\nin\sorder\sto\shelp\sthe\scode\sto\srun\sa\slittle\sfaster. -D 2013-11-21T00:10:35.929 +C Reduce\sthe\ssize\sof\sVdbeCursor\sagain,\sthis\stime\swithout\sa\sperformance\shit. +D 2013-11-21T01:04:02.826 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,11 +280,11 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c fb6007ac59ebebf398ce1709f9cef367bfd15dce +F src/vdbe.c c375ba0385f747e58d98686f5f4f0439c6297b35 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 7cb3c641d42154ea0c66055ca77557005ff4535d +F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c c592609996435944837b8906fbbcfcfac0714c90 +F src/vdbeaux.c bbf06ccbb159611d55e32783c6e9fdec75b120d0 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5f9d50688508affd0bc8e4d52e21dacfacdbb5ce -R 11a6306351cf31959d33e284a4627112 +P f8d5efcd7b92492b833b6cd1cb6bec006c6a0809 +R 842b8e02c5c12ba51889f25ba6cef74b U drh -Z 5afd15b6c955a3c65a923acb8d5d260f +Z a21060677c94bf6a3d8120f6bac96f14 diff --git a/manifest.uuid b/manifest.uuid index b0ba0a8bff..8232c53684 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f8d5efcd7b92492b833b6cd1cb6bec006c6a0809 \ No newline at end of file +933939932c44bccb0958f203a5bd24e683c1cf38 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index d50a23fb85..e234ea412f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -212,9 +212,8 @@ static VdbeCursor *allocateCursor( int nByte; VdbeCursor *pCx = 0; nByte = - ROUND8(sizeof(VdbeCursor)) + - (isBtreeCursor?sqlite3BtreeCursorSize():0) + - (2*nField+2)*sizeof(u32); + ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + (isBtreeCursor?sqlite3BtreeCursorSize():0); assert( iCurnCursor ); if( p->apCsr[iCur] ){ @@ -226,12 +225,9 @@ static VdbeCursor *allocateCursor( memset(pCx, 0, sizeof(VdbeCursor)); pCx->iDb = iDb; pCx->nField = nField; - if( nField ){ - pCx->aType = (u32 *)&pMem->z[ROUND8(sizeof(VdbeCursor))]; - } if( isBtreeCursor ){ pCx->pCursor = (BtCursor*) - &pMem->z[ROUND8(sizeof(VdbeCursor))+(2*nField+2)*sizeof(u32)]; + &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; sqlite3BtreeCursorZero(pCx->pCursor); } } @@ -5807,7 +5803,6 @@ case OP_VOpen: { pCur = allocateCursor(p, pOp->p1, 0, -1, 0); if( pCur ){ pCur->pVtabCursor = pVtabCursor; - pCur->pModule = pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; pModule->xClose(pVtabCursor); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b1b7f2eacc..adcb13db37 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -53,6 +53,9 @@ typedef struct AuxData AuxData; ** loop over all entries of the Btree. You can also insert new BTree ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. +** +** Cursors can also point to virtual tables, sorters, or "pseudo-tables". +** A pseudo-table is a single-row table implemented by registers. ** ** Every cursor that the virtual machine has open is represented by an ** instance of the following structure. @@ -74,7 +77,6 @@ struct VdbeCursor { Bool isOrdered:1; /* True if the underlying table is BTREE_UNORDERED */ Bool multiPseudo:1; /* Multi-register pseudo-cursor */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ - const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ i64 seqCount; /* Sequence counter */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ i64 lastRowid; /* Rowid being deleted by OP_Delete */ @@ -93,8 +95,11 @@ struct VdbeCursor { u32 payloadSize; /* Total number of bytes in the record */ u32 szRow; /* Byte available in aRow */ u32 iHdrOffset; /* Offset to next unparsed byte of the header */ - u32 *aType; /* Type values for all entries in the record */ const u8 *aRow; /* Data for the current row, if all on one page */ + u32 aType[1]; /* Type values for all entries in the record */ + /* 2*nField extra array elements allocated for aType[], beyond the one + ** static element declared in the structure. nField total array slots for + ** aType[] and nField+1 array slots for aOffset[] */ }; typedef struct VdbeCursor VdbeCursor; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2e3cdfb711..0c74f51ba7 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1674,7 +1674,7 @@ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( pCx->pVtabCursor ){ sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor; - const sqlite3_module *pModule = pCx->pModule; + const sqlite3_module *pModule = pVtabCursor->pVtab->pModule; p->inVtabMethod = 1; pModule->xClose(pVtabCursor); p->inVtabMethod = 0; From f93cd949a0744703b3332cbcb4e647c4889ec9c3 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 03:12:25 +0000 Subject: [PATCH 39/78] Performance optimization to the OP_Next and OP_Prev opcodes. FossilOrigin-Name: ecaac28a2e78aca148fc614fe54bf2706aed8be2 --- manifest | 17 +++++++-------- manifest.uuid | 2 +- src/vdbe.c | 60 ++++++++++++++++++++++++++++++++------------------- src/vdbeaux.c | 4 +++- src/where.c | 2 +- 5 files changed, 51 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index 27f372c562..96d39f59d5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sOP_Column\sopcode\sto\smake\sit\sclearer\sand\seasier\sto\smaintain.\nOverall,\sperformance\stests\sshow\sabout\sa\s1%\sspeed\sincrease\swith\sthis\schange. -D 2013-11-21T01:33:45.684 +C Performance\soptimization\sto\sthe\sOP_Next\sand\sOP_Prev\sopcodes. +D 2013-11-21T03:12:25.082 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,11 +280,11 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c c375ba0385f747e58d98686f5f4f0439c6297b35 +F src/vdbe.c 1aabde68130182a3cceb70d1c59122b93244b97e F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c bbf06ccbb159611d55e32783c6e9fdec75b120d0 +F src/vdbeaux.c 648f72365268979e89cd2ba8e5f2b4ecb1843fb0 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4 F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74 -F src/where.c aa72ba871fa835a513cae1c7432dc1d785eb23e4 +F src/where.c e558bfa67009ab7de08a7a1960ae0dd443241cdd F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -1140,8 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 5562cd343d8f69242e06a51a7f1aef7ee7d78eec 933939932c44bccb0958f203a5bd24e683c1cf38 -R 842b8e02c5c12ba51889f25ba6cef74b -T +closed 933939932c44bccb0958f203a5bd24e683c1cf38 +P 972881c6d394c199961f01dcbeb4a6e8b5c919a1 +R d4a5420dc1635b387e6b0a099e73a8c3 U drh -Z 16455d71573d7ca0de3f10177a1e6082 +Z 0f90f7ea40ab09ca14f9f529358ed102 diff --git a/manifest.uuid b/manifest.uuid index 29bb141912..f6fdc094e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -972881c6d394c199961f01dcbeb4a6e8b5c919a1 \ No newline at end of file +ecaac28a2e78aca148fc614fe54bf2706aed8be2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e234ea412f..57a0e39429 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4467,7 +4467,8 @@ case OP_Rewind: { /* jump */ ** to the following instruction. But if the cursor advance was successful, ** jump immediately to P2. ** -** The P1 cursor must be for a real table, not a pseudo-table. +** 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. ** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreeNext(). @@ -4475,7 +4476,12 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. ** -** See also: Prev +** See also: Prev, NextIfOpen +*/ +/* Opcode: NextIfOpen P1 P2 * * P5 +** +** This opcode works just like OP_Next except that if cursor P1 is not +** open it behaves a no-op. */ /* Opcode: Prev P1 P2 * * P5 ** @@ -4484,7 +4490,8 @@ case OP_Rewind: { /* jump */ ** to the following instruction. But if the cursor backup was successful, ** jump immediately to P2. ** -** The P1 cursor must be for a real table, not a pseudo-table. +** The P1 cursor must be for a real table, not a pseudo-table. If P1 is +** not open then the behavior is undefined. ** ** P4 is always of type P4_ADVANCE. The function pointer points to ** sqlite3BtreePrevious(). @@ -4492,38 +4499,47 @@ case OP_Rewind: { /* jump */ ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. */ -case OP_SorterNext: /* jump */ -case OP_Prev: /* jump */ -case OP_Next: { /* jump */ +/* Opcode: PrevIfOpen P1 P2 * * P5 +** +** This opcode works just like OP_Prev except that if cursor P1 is not +** open it behaves a no-op. +*/ +case OP_SorterNext: { /* jump */ VdbeCursor *pC; int res; + pC = p->apCsr[pOp->p1]; + assert( isSorter(pC) ); + rc = sqlite3VdbeSorterNext(db, pC, &res); + goto next_tail; +case OP_PrevIfOpen: /* jump */ +case OP_NextIfOpen: /* jump */ + if( p->apCsr[pOp->p1]==0 ) break; + /* Fall through */ +case OP_Prev: /* jump */ +case OP_Next: /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p5aCounter) ); pC = p->apCsr[pOp->p1]; - if( pC==0 ){ - break; /* See ticket #2273 */ - } - assert( isSorter(pC)==(pOp->opcode==OP_SorterNext) ); - if( isSorter(pC) ){ - assert( pOp->opcode==OP_SorterNext ); - rc = sqlite3VdbeSorterNext(db, pC, &res); - }else{ - /* res = 1; // Always initialized by the xAdvance() call */ - assert( pC->deferredMoveto==0 ); - assert( pC->pCursor ); - assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); - assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); - rc = pOp->p4.xAdvance(pC->pCursor, &res); - } - pC->nullRow = (u8)res; + assert( pC!=0 ); + assert( pC->deferredMoveto==0 ); + assert( pC->pCursor ); + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); + 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); + rc = pOp->p4.xAdvance(pC->pCursor, &res); +next_tail: pC->cacheStatus = CACHE_STALE; if( res==0 ){ + pC->nullRow = 0; pc = pOp->p2 - 1; p->aCounter[pOp->p5]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif + }else{ + pC->nullRow = 1; } pC->rowidIsValid = 0; goto check_for_interrupt; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 0c74f51ba7..e31b89bb09 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -453,12 +453,14 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ } #endif case OP_Next: + case OP_NextIfOpen: case OP_SorterNext: { pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; break; } - case OP_Prev: { + case OP_Prev: + case OP_PrevIfOpen: { pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; break; diff --git a/src/where.c b/src/where.c index 3d36625c45..101ca1a7c6 100644 --- a/src/where.c +++ b/src/where.c @@ -2406,7 +2406,7 @@ static int codeEqualityTerm( }else{ pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg); } - pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; + pIn->eEndLoopOp = bRev ? OP_PrevIfOpen : OP_NextIfOpen; sqlite3VdbeAddOp1(v, OP_IsNull, iReg); }else{ pLevel->u.in.nIn = 0; From 76694c3ae5dc7f7a0b92e1e8e45d477936057537 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 03:43:12 +0000 Subject: [PATCH 40/78] A simple change to the OP_Function opcode improves overall performance by about 0.5%. FossilOrigin-Name: b890eefd57fbd189f7df611e82eb1fb4b197e1c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 96d39f59d5..ecd4861c86 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sto\sthe\sOP_Next\sand\sOP_Prev\sopcodes. -D 2013-11-21T03:12:25.082 +C A\ssimple\schange\sto\sthe\sOP_Function\sopcode\simproves\soverall\sperformance\sby\nabout\s0.5%. +D 2013-11-21T03:43:12.554 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 1aabde68130182a3cceb70d1c59122b93244b97e +F src/vdbe.c 9d8490d65b06d2e21dd0f0e6286c07e7f3095a48 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 972881c6d394c199961f01dcbeb4a6e8b5c919a1 -R d4a5420dc1635b387e6b0a099e73a8c3 +P ecaac28a2e78aca148fc614fe54bf2706aed8be2 +R 33f1c98c35afb745f70ac2d0738f01fc U drh -Z 0f90f7ea40ab09ca14f9f529358ed102 +Z a8c7ba243cd2d2fb4fb7b6cf27c27770 diff --git a/manifest.uuid b/manifest.uuid index f6fdc094e7..c568fbf63a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecaac28a2e78aca148fc614fe54bf2706aed8be2 \ No newline at end of file +b890eefd57fbd189f7df611e82eb1fb4b197e1c3 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 57a0e39429..e94c885045 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1487,10 +1487,6 @@ case OP_Function: { assert( pOp->p4type==P4_FUNCDEF ); ctx.pFunc = pOp->p4.pFunc; - ctx.s.flags = MEM_Null; - ctx.s.db = db; - ctx.s.xDel = 0; - ctx.s.zMalloc = 0; ctx.iOp = pc; ctx.pVdbe = p; @@ -1498,7 +1494,10 @@ case OP_Function: { ** the pointer to ctx.s so in case the user-function can use ** the already allocated buffer instead of allocating a new one. */ - sqlite3VdbeMemMove(&ctx.s, pOut); + memcpy(&ctx.s, pOut, sizeof(Mem)); + pOut->flags = MEM_Null; + pOut->xDel = 0; + pOut->zMalloc = 0; MemSetTypeFlag(&ctx.s, MEM_Null); ctx.fErrorOrAux = 0; From e09f43f8b78369852773661c52df015b21ef3932 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 04:18:31 +0000 Subject: [PATCH 41/78] Another improvement to OP_Function and an improvement to OP_Move. FossilOrigin-Name: 70b056fb6f60cdfbe24e4b77a1770eef064a73c6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 11 ++++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ecd4861c86..6c4d9ef46a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\ssimple\schange\sto\sthe\sOP_Function\sopcode\simproves\soverall\sperformance\sby\nabout\s0.5%. -D 2013-11-21T03:43:12.554 +C Another\simprovement\sto\sOP_Function\sand\san\simprovement\sto\sOP_Move. +D 2013-11-21T04:18:31.892 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 9d8490d65b06d2e21dd0f0e6286c07e7f3095a48 +F src/vdbe.c bfbbaf9daddfd0228747e4e47677bd34dc306388 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P ecaac28a2e78aca148fc614fe54bf2706aed8be2 -R 33f1c98c35afb745f70ac2d0738f01fc +P b890eefd57fbd189f7df611e82eb1fb4b197e1c3 +R f453cb4528248c0309ea050c9ba4ca77 U drh -Z a8c7ba243cd2d2fb4fb7b6cf27c27770 +Z 2b2e2a3a32727285c9b4dfbebd948b02 diff --git a/manifest.uuid b/manifest.uuid index c568fbf63a..4fff4fd7d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b890eefd57fbd189f7df611e82eb1fb4b197e1c3 \ No newline at end of file +70b056fb6f60cdfbe24e4b77a1770eef064a73c6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e94c885045..f30810dd8a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1081,15 +1081,15 @@ case OP_Move: { int p1; /* Register to copy from */ int p2; /* Register to copy to */ - n = pOp->p3 + 1; + n = pOp->p3; p1 = pOp->p1; p2 = pOp->p2; - assert( n>0 && p1>0 && p2>0 ); + assert( n>=0 && p1>0 && p2>0 ); assert( p1+n<=p2 || p2+n<=p1 ); pIn1 = &aMem[p1]; pOut = &aMem[p2]; - while( n-- ){ + do{ assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); assert( memIsValid(pIn1) ); @@ -1106,7 +1106,7 @@ case OP_Move: { REGISTER_TRACE(p2++, pOut); pIn1++; pOut++; - } + }while( n-- ); break; } @@ -1532,7 +1532,8 @@ case OP_Function: { /* Copy the result of the function into register P3 */ sqlite3VdbeChangeEncoding(&ctx.s, encoding); - sqlite3VdbeMemMove(pOut, &ctx.s); + assert( pOut->flags==MEM_Null ); + memcpy(pOut, &ctx.s, sizeof(Mem)); if( sqlite3VdbeMemTooBig(pOut) ){ goto too_big; } From b1fba2868b7e1c1932fe7985658ca409e8bbd6da Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 14:33:48 +0000 Subject: [PATCH 42/78] Add the ability to factor constant functions out of inner loops. But do not factor out non-constant functions, like random(). FossilOrigin-Name: 1b0f779e19a5c0d51eddd2d88db50034d77d132c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 13 ++++++++----- src/func.c | 10 +++++----- src/resolve.c | 1 + src/sqliteInt.h | 15 ++++++++++++--- 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 6c4d9ef46a..f32b14861b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\simprovement\sto\sOP_Function\sand\san\simprovement\sto\sOP_Move. -D 2013-11-21T04:18:31.892 +C Add\sthe\sability\sto\sfactor\sconstant\sfunctions\sout\sof\sinner\sloops.\s\sBut\sdo\nnot\sfactor\sout\snon-constant\sfunctions,\slike\srandom(). +D 2013-11-21T14:33:48.381 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,10 +175,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c d81090a3f3bb0845fa6c6795d221ec23ef107737 +F src/expr.c c3a87def4d55a2bf734de266e74388be8617f98e F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 -F src/func.c 96caa9dfd1febf9a4b720de4c43ccfb392a52b73 +F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 F src/global.c 5caf4deab621abb45b4c607aad1bd21c20aac759 F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4 F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22 @@ -217,14 +217,14 @@ F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 -F src/resolve.c 6fcceeb653a0020b14491975d567c989e794d408 +F src/resolve.c 1568ba369113851743ec7123d859a358e63664bb F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 03b91c6bceccd7718473f3d790abcb8d5c2b1bf1 +F src/sqliteInt.h 300dbe249ea28b094bdf304d6d96d414fef0bb26 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b890eefd57fbd189f7df611e82eb1fb4b197e1c3 -R f453cb4528248c0309ea050c9ba4ca77 +P 70b056fb6f60cdfbe24e4b77a1770eef064a73c6 +R 4b398323e41fc9e4c6f9c8eb17716c1f U drh -Z 2b2e2a3a32727285c9b4dfbebd948b02 +Z 4f758cd7144fa1f23ddbc35887f66833 diff --git a/manifest.uuid b/manifest.uuid index 4fff4fd7d3..c8206cdd9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -70b056fb6f60cdfbe24e4b77a1770eef064a73c6 \ No newline at end of file +1b0f779e19a5c0d51eddd2d88db50034d77d132c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ce541ed8ab..f0a4190401 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1191,9 +1191,12 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ switch( pExpr->op ){ /* Consider functions to be constant if all their arguments are constant - ** and pWalker->u.i==2 */ + ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST + ** flag. */ case TK_FUNCTION: - if( pWalker->u.i==2 ) return WRC_Continue; + if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){ + return WRC_Continue; + } /* Fall through */ case TK_ID: case TK_COLUMN: @@ -2697,9 +2700,9 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); - testcase( (pDef->funcFlags&~SQLITE_FUNC_ENCMASK) - ==SQLITE_FUNC_LENGTH ); - pFarg->a[0].pExpr->op2 = pDef->funcFlags&~SQLITE_FUNC_ENCMASK; + testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); + pFarg->a[0].pExpr->op2 = + pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); } } diff --git a/src/func.c b/src/func.c index c9962f6d91..46c606ac06 100644 --- a/src/func.c +++ b/src/func.c @@ -1664,8 +1664,8 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE), FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY), - FUNCTION(random, 0, 0, 0, randomFunc ), - FUNCTION(randomblob, 1, 0, 0, randomBlob ), + VFUNCTION(random, 0, 0, 0, randomFunc ), + VFUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), @@ -1675,9 +1675,9 @@ void sqlite3RegisterGlobalFunctions(void){ FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc ), #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ FUNCTION(quote, 1, 0, 0, quoteFunc ), - FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), - FUNCTION(changes, 0, 0, 0, changes ), - FUNCTION(total_changes, 0, 0, 0, total_changes ), + VFUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), + VFUNCTION(changes, 0, 0, 0, changes ), + VFUNCTION(total_changes, 0, 0, 0, total_changes ), FUNCTION(replace, 3, 0, 0, replaceFunc ), FUNCTION(zeroblob, 1, 0, 0, zeroblobFunc ), #ifdef SQLITE_SOUNDEX diff --git a/src/resolve.c b/src/resolve.c index b5ba80ec75..999c628c06 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -725,6 +725,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->op = TK_NULL; return WRC_Prune; } + if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant); } #endif if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f52c6c1d14..84c69972a1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1143,6 +1143,7 @@ struct FuncDestructor { #define SQLITE_FUNC_COUNT 0x100 /* Built-in count(*) aggregate */ #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */ #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */ +#define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -1155,6 +1156,9 @@ struct FuncDestructor { ** as the user-data (sqlite3_user_data()) for the function. If ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. ** +** VFUNCTION(zName, nArg, iArg, bNC, xFunc) +** Like FUNCTION except it omits the SQLITE_FUNC_CONSTANT flag. +** ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) ** Used to create an aggregate function definition implemented by ** the C functions xStep and xFinal. The first four parameters @@ -1170,16 +1174,20 @@ struct FuncDestructor { ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} +#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags, \ + {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, #zName, 0, 0} #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, 0, #zName, 0, 0} #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_UTF8|flags, (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + (void *)arg, 0, likeFunc, 0, 0, #zName, 0, 0} #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \ {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0} @@ -1839,6 +1847,7 @@ struct Expr { #define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_Constant 0x080000 /* Node is a constant */ /* ** These macros can be used to test, set, or clear bits in the From 10f468f37a17a99a98748e49b26bc825b0938851 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 14:44:38 +0000 Subject: [PATCH 43/78] Remove the obsolete TK_CONST_FUNC token type. FossilOrigin-Name: 9b4217f055e9bced186b4c56a5753bd6da7115b5 --- addopcodes.awk | 1 - manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 4 ---- src/parse.y | 7 +------ src/resolve.c | 2 -- 6 files changed, 11 insertions(+), 23 deletions(-) diff --git a/addopcodes.awk b/addopcodes.awk index c90e1dd7f4..c18c4f3599 100644 --- a/addopcodes.awk +++ b/addopcodes.awk @@ -28,7 +28,6 @@ END { printf "#define TK_%-29s %4d\n", "COLUMN", ++max printf "#define TK_%-29s %4d\n", "AGG_FUNCTION", ++max printf "#define TK_%-29s %4d\n", "AGG_COLUMN", ++max - printf "#define TK_%-29s %4d\n", "CONST_FUNC", ++max printf "#define TK_%-29s %4d\n", "UMINUS", ++max printf "#define TK_%-29s %4d\n", "UPLUS", ++max } diff --git a/manifest b/manifest index f32b14861b..5d827ec820 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\sfactor\sconstant\sfunctions\sout\sof\sinner\sloops.\s\sBut\sdo\nnot\sfactor\sout\snon-constant\sfunctions,\slike\srandom(). -D 2013-11-21T14:33:48.381 +C Remove\sthe\sobsolete\sTK_CONST_FUNC\stoken\stype. +D 2013-11-21T14:44:38.999 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -8,7 +8,7 @@ F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 52f7e22bfcec71a462e34194b4ae1671380fde59 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 -F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 +F addopcodes.awk 87ca612393d0f439550634bd2c156ea9ff6195ae F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c c3a87def4d55a2bf734de266e74388be8617f98e +F src/expr.c 98800f5a545bc93ab90acf4c89e904069c8b4bcf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -209,7 +209,7 @@ F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 F src/os_win.c ef091b347d682cb24fc575ac9a6290341af62e2b F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c -F src/parse.y 073a8294e1826f1b1656e84806b77e4199f4bb57 +F src/parse.y acee1a9958539e21263362b194594c5255ad2fca F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c a467393909a4ed7ca9de066d85ba5c5b04a5be63 @@ -217,7 +217,7 @@ F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7 F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768 F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 -F src/resolve.c 1568ba369113851743ec7123d859a358e63664bb +F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 70b056fb6f60cdfbe24e4b77a1770eef064a73c6 -R 4b398323e41fc9e4c6f9c8eb17716c1f +P 1b0f779e19a5c0d51eddd2d88db50034d77d132c +R 4765b9c971cb7bd4e939f413b1d14806 U drh -Z 4f758cd7144fa1f23ddbc35887f66833 +Z 408c8bf331ed8f56b61161d6e80b7e89 diff --git a/manifest.uuid b/manifest.uuid index c8206cdd9a..1c14211a72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b0f779e19a5c0d51eddd2d88db50034d77d132c \ No newline at end of file +9b4217f055e9bced186b4c56a5753bd6da7115b5 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f0a4190401..62055d246b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2626,7 +2626,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } break; } - case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ int nFarg; /* Number of function arguments */ @@ -2639,8 +2638,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ CollSeq *pColl = 0; /* A collating sequence */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - testcase( op==TK_CONST_FUNC ); - testcase( op==TK_FUNCTION ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ pFarg = 0; }else{ @@ -3206,7 +3203,6 @@ void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){ } case TK_AGG_FUNCTION: - case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pFarg; /* List of function arguments */ if( ExprHasProperty(pExpr, EP_TokenOnly) ){ diff --git a/src/parse.y b/src/parse.y index 07e607dcf9..ba9feb10fc 100644 --- a/src/parse.y +++ b/src/parse.y @@ -854,12 +854,7 @@ expr(A) ::= ID(X) LP STAR RP(E). { spanSet(&A,&X,&E); } term(A) ::= CTIME_KW(OP). { - /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are - ** treated as functions that return constants */ - A.pExpr = sqlite3ExprFunction(pParse, 0,&OP); - if( A.pExpr ){ - A.pExpr->op = TK_CONST_FUNC; - } + A.pExpr = sqlite3ExprFunction(pParse, 0, &OP); spanSet(&A, &OP, &OP); } diff --git a/src/resolve.c b/src/resolve.c index 999c628c06..2c0907cc47 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -667,7 +667,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Resolve function names */ - case TK_CONST_FUNC: case TK_FUNCTION: { ExprList *pList = pExpr->x.pList; /* The argument list */ int n = pList ? pList->nExpr : 0; /* Number of arguments */ @@ -680,7 +679,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ - testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); notValidPartIdxWhere(pParse, pNC, "functions"); zId = pExpr->u.zToken; From d1a01edac9ff763ef8d2909bf6deff4ad68345bf Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 16:08:52 +0000 Subject: [PATCH 44/78] When one or more arguments to a function are constants, try to factor out just those arguments into initialization code. FossilOrigin-Name: 50d350abbc9176cd6fc606bc45b8fc3020719500 --- manifest | 16 ++++++------ manifest.uuid | 2 +- src/expr.c | 66 +++++++++++++++++++++++++++++++++++-------------- src/select.c | 5 ++-- src/sqliteInt.h | 5 +++- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 5d827ec820..6704560739 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\sobsolete\sTK_CONST_FUNC\stoken\stype. -D 2013-11-21T14:44:38.999 +C When\sone\sor\smore\sarguments\sto\sa\sfunction\sare\sconstants,\stry\sto\sfactor\nout\sjust\sthose\sarguments\sinto\sinitialization\scode. +D 2013-11-21T16:08:52.350 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c 98800f5a545bc93ab90acf4c89e904069c8b4bcf +F src/expr.c 3c629b4b208933c115f5652d2c6fcc877188c4fb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -219,12 +219,12 @@ F src/printf.c da9119eb31a187a4b99f60aa4a225141c0ebb74b F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 -F src/select.c 253cb683e4a05b0b56b0f9c816f3c4a4e5575ebb +F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 300dbe249ea28b094bdf304d6d96d414fef0bb26 +F src/sqliteInt.h 8cd0bb5b2cd8430482460c2a302edd2619d17293 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 1b0f779e19a5c0d51eddd2d88db50034d77d132c -R 4765b9c971cb7bd4e939f413b1d14806 +P 9b4217f055e9bced186b4c56a5753bd6da7115b5 +R cd046aaa4606fb86e4dbb88d28c9046d U drh -Z 408c8bf331ed8f56b61161d6e80b7e89 +Z f1aad5e966fd81185b357b5fc8c7f131 diff --git a/manifest.uuid b/manifest.uuid index 1c14211a72..65377c8b4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b4217f055e9bced186b4c56a5753bd6da7115b5 \ No newline at end of file +50d350abbc9176cd6fc606bc45b8fc3020719500 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 62055d246b..9d405343e9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2681,8 +2681,21 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ break; } + for(i=0; ia[i].pExpr) ){ + constMask |= (1<funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + } + } if( pFarg ){ - r1 = sqlite3GetTempRange(pParse, nFarg); + if( constMask ){ + r1 = pParse->nMem+1; + pParse->nMem += nFarg; + }else{ + r1 = sqlite3GetTempRange(pParse, nFarg); + } /* For length() and typeof() functions with a column argument, ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG @@ -2704,7 +2717,8 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ } sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ - sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); + sqlite3ExprCodeExprList(pParse, pFarg, r1, + SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ }else{ r1 = 0; @@ -2728,14 +2742,6 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); } #endif - for(i=0; ia[i].pExpr) ){ - constMask |= (1<funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ - pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); - } - } if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); @@ -2743,7 +2749,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ sqlite3VdbeAddOp4(v, OP_Function, constMask, r1, target, (char*)pDef, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nFarg); - if( nFarg ){ + if( nFarg && constMask==0 ){ sqlite3ReleaseTempRange(pParse, r1, nFarg); } break; @@ -2980,6 +2986,19 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ return inReg; } +/* +** Factor out the code of the given expression to initialization time. +*/ +void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){ + ExprList *p; + assert( pParse->cookieGoto>0 ); /* Only possible if cookie will be coded */ + p = pParse->pConstExpr; + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + p = sqlite3ExprListAppend(pParse, p, pExpr); + if( p ) p->a[p->nExpr-1].u.iConstExprReg = regDest; + pParse->pConstExpr = p; +} + /* ** Generate code to evaluate an expression and store the results ** into a register. Return the register number where the results @@ -3010,10 +3029,8 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ } } } - p = sqlite3ExprListAppend(pParse, p, sqlite3ExprDup(pParse->db, pExpr, 0)); - pParse->pConstExpr = p; r2 = ++pParse->nMem; - if( p ) p->a[p->nExpr-1].u.iConstExprReg = r2; + sqlite3ExprCodeAtInit(pParse, pExpr, r2); }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); @@ -3358,25 +3375,36 @@ void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){ ** expression list into a sequence of registers beginning at target. ** ** Return the number of elements evaluated. +** +** The SQLITE_ECEL_DUP flag prevents the arguments from being +** filled using OP_SCopy. OP_Copy must be used instead. +** +** The SQLITE_ECEL_FACTOR argument allows constant arguments to be +** factored out into initialization code. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ int target, /* Where to write results */ - int doHardCopy /* Make a hard copy of every element */ + u8 flags /* SQLITE_ECEL_* flags */ ){ struct ExprList_item *pItem; int i, n; + u8 copyOp = (flags & SQLITE_ECEL_DUP) ? OP_Copy : OP_SCopy; assert( pList!=0 ); assert( target>0 ); assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ n = pList->nExpr; + if( pParse->cookieGoto<=0 ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; ipExpr; - int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); - if( inReg!=target+i ){ - sqlite3VdbeAddOp2(pParse->pVdbe, doHardCopy ? OP_Copy : OP_SCopy, - inReg, target+i); + if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ + sqlite3ExprCodeAtInit(pParse, pExpr, target+i); + }else{ + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); + if( inReg!=target+i ){ + sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i); + } } } return n; diff --git a/src/select.c b/src/select.c index 04a523434b..aa8e54b02f 100644 --- a/src/select.c +++ b/src/select.c @@ -599,7 +599,8 @@ static void selectInnerLoop( ** values returned by the SELECT are not required. */ sqlite3ExprCacheClear(pParse); - sqlite3ExprCodeExprList(pParse, pEList, regResult, eDest==SRT_Output); + sqlite3ExprCodeExprList(pParse, pEList, regResult, + (eDest==SRT_Output)?SQLITE_ECEL_DUP:0); } nColumn = nResultCol; @@ -3885,7 +3886,7 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){ if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); - sqlite3ExprCodeExprList(pParse, pList, regAgg, 1); + sqlite3ExprCodeExprList(pParse, pList, regAgg, SQLITE_ECEL_DUP); }else{ nArg = 0; regAgg = 0; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 84c69972a1..7c4c04337b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2903,10 +2903,13 @@ void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); int sqlite3ExprCode(Parse*, Expr*, int); +void sqlite3ExprCodeAtInit(Parse*, Expr*, int); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); -int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int); +int sqlite3ExprCodeExprList(Parse*, ExprList*, int, u8); +#define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ +#define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite3*,const char*, const char*); From 66e810247e1ff653eec5a6c659077dbaa7a704cd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 17:24:18 +0000 Subject: [PATCH 45/78] Make sure the OP_Next and OP_NextIfOpen opcodes are numbered close together for efficiency in switch() statements. OP_Prev and OP_PrevIfOpen too. FossilOrigin-Name: d4ccf0f5c656c8f0e1c32d5f7971b131f42c3cbd --- manifest | 12 ++++++------ manifest.uuid | 2 +- mkopcodeh.awk | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6704560739..df072dad3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sone\sor\smore\sarguments\sto\sa\sfunction\sare\sconstants,\stry\sto\sfactor\nout\sjust\sthose\sarguments\sinto\sinitialization\scode. -D 2013-11-21T16:08:52.350 +C Make\ssure\sthe\sOP_Next\sand\sOP_NextIfOpen\sopcodes\sare\snumbered\sclose\stogether\nfor\sefficiency\sin\sswitch()\sstatements.\s\sOP_Prev\sand\sOP_PrevIfOpen\stoo. +D 2013-11-21T17:24:18.502 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -147,7 +147,7 @@ F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 F mkopcodec.awk c2ff431854d702cdd2d779c9c0d1f58fa16fa4ea -F mkopcodeh.awk 987ee588ff3bb4043bed2185c1ee2bdc39b1e526 +F mkopcodeh.awk c6b3fa301db6ef7ac916b14c60868aeaec1337b5 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9b4217f055e9bced186b4c56a5753bd6da7115b5 -R cd046aaa4606fb86e4dbb88d28c9046d +P 50d350abbc9176cd6fc606bc45b8fc3020719500 +R 16f76a040c17f047b64a9d8c8a36388d U drh -Z f1aad5e966fd81185b357b5fc8c7f131 +Z fd90afc91aa027f8da5b0d6d8b4c3462 diff --git a/manifest.uuid b/manifest.uuid index 65377c8b4c..83ee884daf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50d350abbc9176cd6fc606bc45b8fc3020719500 \ No newline at end of file +d4ccf0f5c656c8f0e1c32d5f7971b131f42c3cbd \ No newline at end of file diff --git a/mkopcodeh.awk b/mkopcodeh.awk index f8da18e306..babfdc68d3 100644 --- a/mkopcodeh.awk +++ b/mkopcodeh.awk @@ -136,8 +136,10 @@ END { || name=="OP_VUpdate" \ || name=="OP_VFilter" \ || name=="OP_Next" \ + || name=="OP_NextIfOpen" \ || name=="OP_SorterNext" \ || name=="OP_Prev" \ + || name=="OP_PrevIfOpen" \ ){ cnt++ while( used[cnt] ) cnt++ From 2b53e00f730ae91a0e7a35843ce88eb9d9900b4b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 19:05:04 +0000 Subject: [PATCH 46/78] Remove a test from sqlite3VdbeMemFromBtree() which was unnecessary, and after the recent OP_Column refactoring, unreachable. FossilOrigin-Name: 23667f3ba09b7e839d76c42669dc9247a91262c8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index df072dad3a..71b6ca6a99 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\sOP_Next\sand\sOP_NextIfOpen\sopcodes\sare\snumbered\sclose\stogether\nfor\sefficiency\sin\sswitch()\sstatements.\s\sOP_Prev\sand\sOP_PrevIfOpen\stoo. -D 2013-11-21T17:24:18.502 +C Remove\sa\stest\sfrom\ssqlite3VdbeMemFromBtree()\swhich\swas\sunnecessary,\sand\nafter\sthe\srecent\sOP_Column\srefactoring,\sunreachable. +D 2013-11-21T19:05:04.606 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -286,7 +286,7 @@ F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c 648f72365268979e89cd2ba8e5f2b4ecb1843fb0 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c cc529bbf4f13e4e181bdb446bf6e6962ab030b4b +F src/vdbemem.c 4f227e2e28493a680dd84e6a4d28c9b01dca172b F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 50d350abbc9176cd6fc606bc45b8fc3020719500 -R 16f76a040c17f047b64a9d8c8a36388d +P d4ccf0f5c656c8f0e1c32d5f7971b131f42c3cbd +R 66dccb4d546e53b7ddedb9ff6684fbe4 U drh -Z fd90afc91aa027f8da5b0d6d8b4c3462 +Z 06ed94041404ba9e41a5bfcb0e125483 diff --git a/manifest.uuid b/manifest.uuid index 83ee884daf..d71d94e1bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4ccf0f5c656c8f0e1c32d5f7971b131f42c3cbd \ No newline at end of file +23667f3ba09b7e839d76c42669dc9247a91262c8 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index c4bae54fd1..4f058d13ea 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -917,7 +917,7 @@ int sqlite3VdbeMemFromBtree( } assert( zData!=0 ); - if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){ + if( offset+amt<=available ){ sqlite3VdbeMemRelease(pMem); pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; From d2b637c2af8b322592cfdfe6323558403fa24246 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 19:27:45 +0000 Subject: [PATCH 47/78] Add the --timer option to the wordcount test program. FossilOrigin-Name: a89fdf87553f01c150729c570796b5078a9b069d --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wordcount.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 71b6ca6a99..45a9f70ccb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\stest\sfrom\ssqlite3VdbeMemFromBtree()\swhich\swas\sunnecessary,\sand\nafter\sthe\srecent\sOP_Column\srefactoring,\sunreachable. -D 2013-11-21T19:05:04.606 +C Add\sthe\s--timer\soption\sto\sthe\swordcount\stest\sprogram. +D 2013-11-21T19:27:45.727 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1088,7 +1088,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c c80f378f26fbf6ada602c4313ae88fc47439263e +F test/wordcount.c a42341b7a01229782b9bd97ff2eeebae830adbea F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d4ccf0f5c656c8f0e1c32d5f7971b131f42c3cbd -R 66dccb4d546e53b7ddedb9ff6684fbe4 +P 23667f3ba09b7e839d76c42669dc9247a91262c8 +R 6f7d4c37e1e4a4d7b173a8698f60d4e6 U drh -Z 06ed94041404ba9e41a5bfcb0e125483 +Z be6cc4796ccce786831080c9b4f10bd9 diff --git a/manifest.uuid b/manifest.uuid index d71d94e1bf..a07e42dce4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23667f3ba09b7e839d76c42669dc9247a91262c8 \ No newline at end of file +a89fdf87553f01c150729c570796b5078a9b069d \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index 59d8540a05..c4d641b1e9 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -29,6 +29,7 @@ ** --commit NNN Commit after every NNN operations ** --nosync Use PRAGMA synchronous=OFF ** --journal MMMM Use PRAGMA journal_mode=MMMM +** --timer Time the operation of this program ** ** Modes: ** @@ -80,6 +81,21 @@ #include #include "sqlite3.h" +/* Return the current wall-clock time */ +static sqlite3_int64 realTime(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs->iVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; +} + /* Print an error message and exit */ static void fatal_error(const char *zMsg, ...){ va_list ap; @@ -186,6 +202,7 @@ int main(int argc, char **argv){ int doTrace = 0; /* True for --trace */ int showStats = 0; /* True for --stats */ int showSummary = 0; /* True for --summary */ + int showTimer = 0; /* True for --timer */ int cacheSize = 0; /* Desired cache size. 0 means default */ int pageSize = 0; /* Desired page size. 0 means default */ int commitInterval = 0; /* How often to commit. 0 means never */ @@ -203,6 +220,7 @@ int main(int argc, char **argv){ int rc; /* Return code from an SQLite interface */ int iCur, iHiwtr; /* Statistics values, current and "highwater" */ sqlite3_int64 sumCnt = 0; /* Sum in QUERY mode */ + sqlite3_int64 startTime; char zInput[2000]; /* A single line of input */ /* Process command-line arguments */ @@ -234,6 +252,8 @@ int main(int argc, char **argv){ showStats = 1; }else if( strcmp(z,"summary")==0 ){ showSummary = 1; + }else if( strcmp(z,"timer")==0 ){ + showTimer = i; }else if( strcmp(z,"cachesize")==0 && i Date: Thu, 21 Nov 2013 20:48:42 +0000 Subject: [PATCH 48/78] Fix the code generator to honor turning off constant expression factoring. FossilOrigin-Name: 882622662dfadf49c65c7d80b7fd87533d079ce9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 6 +++--- src/sqliteInt.h | 7 +++++++ 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 45a9f70ccb..baab9046f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--timer\soption\sto\sthe\swordcount\stest\sprogram. -D 2013-11-21T19:27:45.727 +C Fix\sthe\scode\sgenerator\sto\shonor\sturning\soff\sconstant\sexpression\sfactoring. +D 2013-11-21T20:48:42.154 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c 3c629b4b208933c115f5652d2c6fcc877188c4fb +F src/expr.c afc039ecfe2b990572f813aee0cbd734c167c955 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -224,7 +224,7 @@ F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 8cd0bb5b2cd8430482460c2a302edd2619d17293 +F src/sqliteInt.h 5cf2c563e8909cd21378b47ace439826f1407120 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -1140,7 +1140,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 23667f3ba09b7e839d76c42669dc9247a91262c8 -R 6f7d4c37e1e4a4d7b173a8698f60d4e6 +P a89fdf87553f01c150729c570796b5078a9b069d +R 71de4796954de06b931dd50d526bd744 U drh -Z be6cc4796ccce786831080c9b4f10bd9 +Z 94a313bef91e05454ee1a8fb62156d74 diff --git a/manifest.uuid b/manifest.uuid index a07e42dce4..441a088dc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a89fdf87553f01c150729c570796b5078a9b069d \ No newline at end of file +882622662dfadf49c65c7d80b7fd87533d079ce9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9d405343e9..2fb26b20fd 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2991,7 +2991,7 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ */ void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){ ExprList *p; - assert( pParse->cookieGoto>0 ); /* Only possible if cookie will be coded */ + assert( ConstFactorOk(pParse) ); p = pParse->pConstExpr; pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); p = sqlite3ExprListAppend(pParse, p, pExpr); @@ -3015,7 +3015,7 @@ void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; pExpr = sqlite3ExprSkipCollate(pExpr); - if( pParse->cookieGoto>0 + if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) ){ @@ -3395,7 +3395,7 @@ int sqlite3ExprCodeExprList( assert( target>0 ); assert( pParse->pVdbe!=0 ); /* Never gets this far otherwise */ n = pList->nExpr; - if( pParse->cookieGoto<=0 ) flags &= ~SQLITE_ECEL_FACTOR; + if( !ConstFactorOk(pParse) ) flags &= ~SQLITE_ECEL_FACTOR; for(pItem=pList->a, i=0; ipExpr; if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7c4c04337b..932b29c5de 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1077,6 +1077,13 @@ struct sqlite3 { #define OptimizationEnabled(db, mask) 1 #endif +/* +** Return true if it OK to factor constant expressions into the initialization +** code. The argument is a Parse object for the code generator. +*/ +#define ConstFactorOk(P) \ + ((P)->cookieGoto>0 && OptimizationEnabled((P)->db,SQLITE_FactorOutConst)) + /* ** Possible values for the sqlite.magic field. ** The numbers are obtained at random and have no special meaning, other From d673cddad6151cbbbe045e2e805b363b17781071 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 21:23:31 +0000 Subject: [PATCH 49/78] Do not reuse factored constants that might have had their encodings changed. FossilOrigin-Name: 487f20366ce77f0c90865d10d5aaedd95af98694 --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/expr.c | 24 +++++++++++++++++------- src/sqliteInt.h | 3 ++- test/func5.test | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 16 deletions(-) create mode 100644 test/func5.test diff --git a/manifest b/manifest index baab9046f7..bf817c4cac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\scode\sgenerator\sto\shonor\sturning\soff\sconstant\sexpression\sfactoring. -D 2013-11-21T20:48:42.154 +C Do\snot\sreuse\sfactored\sconstants\sthat\smight\shave\shad\stheir\sencodings\schanged. +D 2013-11-21T21:23:31.703 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe -F src/expr.c afc039ecfe2b990572f813aee0cbd734c167c955 +F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235 @@ -224,7 +224,7 @@ F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h 5cf2c563e8909cd21378b47ace439826f1407120 +F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -577,6 +577,7 @@ F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f +F test/func5.test 1435dd313c0bae70d6af089c97a2a997fc5d0e53 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 @@ -1140,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a89fdf87553f01c150729c570796b5078a9b069d -R 71de4796954de06b931dd50d526bd744 +P 882622662dfadf49c65c7d80b7fd87533d079ce9 +R 919d251b93f214648dcb5abd041a55e3 U drh -Z 94a313bef91e05454ee1a8fb62156d74 +Z 333bbe2ad90c7a14f3cc2f1f3886517e diff --git a/manifest.uuid b/manifest.uuid index 441a088dc5..4a7a4a96ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -882622662dfadf49c65c7d80b7fd87533d079ce9 \ No newline at end of file +487f20366ce77f0c90865d10d5aaedd95af98694 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2fb26b20fd..6c8a8cce77 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2989,13 +2989,22 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ /* ** Factor out the code of the given expression to initialization time. */ -void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){ +void sqlite3ExprCodeAtInit( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The expression to code when the VDBE initializes */ + int regDest, /* Store the value in this register */ + u8 reusable /* True if this expression is reusable */ +){ ExprList *p; assert( ConstFactorOk(pParse) ); p = pParse->pConstExpr; pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); p = sqlite3ExprListAppend(pParse, p, pExpr); - if( p ) p->a[p->nExpr-1].u.iConstExprReg = regDest; + if( p ){ + struct ExprList_item *pItem = &p->a[p->nExpr-1]; + pItem->u.iConstExprReg = regDest; + pItem->reusable = reusable; + } pParse->pConstExpr = p; } @@ -3023,14 +3032,15 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int i; *pReg = 0; if( p ){ - for(i=0; inExpr; i++){ - if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){ - return p->a[i].u.iConstExprReg; + struct ExprList_item *pItem; + for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ + if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){ + return pItem->u.iConstExprReg; } } } r2 = ++pParse->nMem; - sqlite3ExprCodeAtInit(pParse, pExpr, r2); + sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1); }else{ int r1 = sqlite3GetTempReg(pParse); r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); @@ -3399,7 +3409,7 @@ int sqlite3ExprCodeExprList( for(pItem=pList->a, i=0; ipExpr; if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){ - sqlite3ExprCodeAtInit(pParse, pExpr, target+i); + sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0); }else{ int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 932b29c5de..6373bb75d7 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1916,6 +1916,7 @@ struct ExprList { u8 sortOrder; /* 1 for DESC or 0 for ASC */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ + unsigned reusable :1; /* Constant expression is reusable */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ @@ -2910,7 +2911,7 @@ void sqlite3ExprCacheRemove(Parse*, int, int); void sqlite3ExprCacheClear(Parse*); void sqlite3ExprCacheAffinityChange(Parse*, int, int); int sqlite3ExprCode(Parse*, Expr*, int); -void sqlite3ExprCodeAtInit(Parse*, Expr*, int); +void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8); int sqlite3ExprCodeTemp(Parse*, Expr*, int*); int sqlite3ExprCodeTarget(Parse*, Expr*, int); int sqlite3ExprCodeAndCache(Parse*, Expr*, int); diff --git a/test/func5.test b/test/func5.test new file mode 100644 index 0000000000..83ecb785db --- /dev/null +++ b/test/func5.test @@ -0,0 +1,33 @@ +# 2013-11-21 +# +# 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. +# +#************************************************************************* +# +# Verify that constant string expressions that get factored into initializing +# code are not reused between function parameters and other values in the +# VDBE program, as the function might have changed the encoding. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test func5-1.1 { + PRAGMA encoding=UTF16le; + CREATE TABLE t1(x,a,b,c); + INSERT INTO t1 VALUES(1,'ab','cd',1); + INSERT INTO t1 VALUES(2,'gh','ef',5); + INSERT INTO t1 VALUES(3,'pqr','fuzzy',99); + INSERT INTO t1 VALUES(4,'abcdefg','xy',22); + INSERT INTO t1 VALUES(5,'shoe','mayer',2953); + SELECT x FROM t1 WHERE c=instr('abcdefg',b) OR a='abcdefg' ORDER BY +x; +} {2 4} +do_execsql_test func5-1.2 { + SELECT x FROM t1 WHERE a='abcdefg' OR c=instr('abcdefg',b) ORDER BY +x; +} {2 4} + +finish_test From 7a909855f29e82a0b761088204d8e89142973ca0 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 21:40:45 +0000 Subject: [PATCH 50/78] Modify wordcount so that timer information appears on standard error instead of standard output. Rename the run-wordcount.bash script to run-wordcount.sh and simplify it so that it stands a better chance of running on non-GNU systems. FossilOrigin-Name: 586c11ed7cc6b8e2c7181231e37791c2fbc95272 --- manifest | 14 ++++---- manifest.uuid | 2 +- test/run-wordcount.bash | 66 ---------------------------------- test/run-wordcount.sh | 78 +++++++++++++++++++++++++++++++++++++++++ test/wordcount.c | 7 ++-- 5 files changed, 90 insertions(+), 77 deletions(-) delete mode 100644 test/run-wordcount.bash create mode 100644 test/run-wordcount.sh diff --git a/manifest b/manifest index bf817c4cac..23ffdc0333 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sreuse\sfactored\sconstants\sthat\smight\shave\shad\stheir\sencodings\schanged. -D 2013-11-21T21:23:31.703 +C Modify\swordcount\sso\sthat\stimer\sinformation\sappears\son\sstandard\serror\sinstead\nof\sstandard\soutput.\s\sRename\sthe\srun-wordcount.bash\sscript\sto\srun-wordcount.sh\nand\ssimplify\sit\sso\sthat\sit\sstands\sa\sbetter\schance\sof\srunning\son\snon-GNU\s\nsystems. +D 2013-11-21T21:40:45.620 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -758,7 +758,7 @@ F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 -F test/run-wordcount.bash 1c6a8b75738db8c53e5125be3d81ab63ef9eefd0 +F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 w test/run-wordcount.bash F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec @@ -1089,7 +1089,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c a42341b7a01229782b9bd97ff2eeebae830adbea +F test/wordcount.c 6ce4090a90cd4a34b7cf7f8969c033cedab72399 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 882622662dfadf49c65c7d80b7fd87533d079ce9 -R 919d251b93f214648dcb5abd041a55e3 +P 487f20366ce77f0c90865d10d5aaedd95af98694 +R 24abe371fb3b49f56b9cb321d5c8bf3d U drh -Z 333bbe2ad90c7a14f3cc2f1f3886517e +Z e03360c4606d03267f7f33fe62a05d71 diff --git a/manifest.uuid b/manifest.uuid index 4a7a4a96ed..772e51934b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -487f20366ce77f0c90865d10d5aaedd95af98694 \ No newline at end of file +586c11ed7cc6b8e2c7181231e37791c2fbc95272 \ No newline at end of file diff --git a/test/run-wordcount.bash b/test/run-wordcount.bash deleted file mode 100644 index b4b4dcd7e9..0000000000 --- a/test/run-wordcount.bash +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -# -# This script runs the wordcount program in different ways, comparing -# the output from each. -# - - -# Run the wordcount command with argument supplied and with --summary. -# Store the results in wc-out.txt and report the run-time. -# -function time_wordcount { - /usr/bin/time --format='%e %C' ./wordcount --summary $* >wc-out.txt -} - -# Compare wc-out.txt against wc-baseline.txt and report any differences. -# -function compare_results { - if cmp -s wc-out.txt wc-baseline.txt; - then echo hi >/dev/null; - else echo ERROR:; - diff -u wc-baseline.txt wc-out.txt; - fi -} - -# Select the source text to be analyzed. -# -if test "x$1" = "x"; -then echo "Usage: $0 FILENAME [ARGS...]"; exit 1; -fi - -# Do test runs -# -rm -f wcdb1.db -time_wordcount wcdb1.db $* --insert -mv wc-out.txt wc-baseline.txt -rm -f wcdb2.db -time_wordcount wcdb2.db $* --insert --without-rowid -compare_results - -rm -f wcdb1.db -time_wordcount wcdb1.db $* --replace -compare_results -rm -f wcdb2.db -time_wordcount wcdb2.db $* --replace --without-rowid -compare_results - -rm -f wcdb1.db -time_wordcount wcdb1.db $* --select -compare_results -rm -f wcdb2.db -time_wordcount wcdb2.db $* --select --without-rowid -compare_results - -time_wordcount wcdb1.db $* --query -mv wc-out.txt wc-baseline.txt -time_wordcount wcdb2.db $* --query --without-rowid -compare_results - -time_wordcount wcdb1.db $* --delete -mv wc-out.txt wc-baseline.txt -time_wordcount wcdb2.db $* --delete --without-rowid -compare_results - -# Clean up temporary files created. -# -rm -rf wcdb1.db wcdb2.db wc-out.txt wc-baseline.txt diff --git a/test/run-wordcount.sh b/test/run-wordcount.sh new file mode 100644 index 0000000000..1755d58161 --- /dev/null +++ b/test/run-wordcount.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# +# This script runs the wordcount program in different ways, comparing +# the output from each. +# + +# Select the source text to be analyzed. +# +if test "x$1" = "x"; +then echo "Usage: $0 FILENAME [ARGS...]"; exit 1; +fi + +# Do test runs +# +rm -f wcdb1.db +./wordcount --timer --summary wcdb1.db $* --insert >wc-out.txt +mv wc-out.txt wc-baseline.txt +rm -f wcdb2.db +./wordcount --timer --summary wcdb2.db $* --insert --without-rowid >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + +rm -f wcdb1.db +./wordcount --timer --summary wcdb1.db $* --replace >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi +rm -f wcdb2.db +./wordcount --timer --summary wcdb2.db $* --replace --without-rowid >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + +rm -f wcdb1.db +./wordcount --timer --summary wcdb1.db $* --select >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + +rm -f wcdb2.db +./wordcount --timer --summary wcdb2.db $* --select --without-rowid >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + +./wordcount --timer --summary wcdb1.db $* --query >wc-out.txt +mv wc-out.txt wc-baseline.txt +./wordcount --timer --summary wcdb2.db $* --query --without-rowid >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + +./wordcount --timer --summary wcdb1.db $* --delete >wc-out.txt +mv wc-out.txt wc-baseline.txt +./wordcount --timer --summary wcdb2.db $* --delete --without-rowid >wc-out.txt + if cmp -s wc-out.txt wc-baseline.txt; + then echo hi >/dev/null; + else echo ERROR:; + diff -u wc-baseline.txt wc-out.txt; + fi + + +# Clean up temporary files created. +# +rm -rf wcdb1.db wcdb2.db wc-out.txt wc-baseline.txt diff --git a/test/wordcount.c b/test/wordcount.c index c4d641b1e9..24924e1b0a 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -473,9 +473,10 @@ int main(int argc, char **argv){ if( showTimer ){ sqlite3_int64 elapseTime = realTime() - startTime; - printf("/* %3d.%03d", (int)(elapseTime/1000), (int)(elapseTime%1000)); - for(i=0; i Date: Thu, 21 Nov 2013 21:59:53 +0000 Subject: [PATCH 51/78] Changes some offset and amount parameters from "int" to "u32" to avoid harmless signed/unsigned comparison warnings. FossilOrigin-Name: 4e8c5d0795cb7c603182bfa70f3855d654f0997e --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/btree.c | 6 +++--- src/btree.h | 4 ++-- src/vdbe.c | 2 +- src/vdbeInt.h | 2 +- src/vdbeaux.c | 4 ++-- src/vdbemem.c | 8 ++++---- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index 23ffdc0333..78fc61f7ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\swordcount\sso\sthat\stimer\sinformation\sappears\son\sstandard\serror\sinstead\nof\sstandard\soutput.\s\sRename\sthe\srun-wordcount.bash\sscript\sto\srun-wordcount.sh\nand\ssimplify\sit\sso\sthat\sit\sstands\sa\sbetter\schance\sof\srunning\son\snon-GNU\s\nsystems. -D 2013-11-21T21:40:45.620 +C Changes\ssome\soffset\sand\samount\sparameters\sfrom\s"int"\sto\s"u32"\sto\savoid\nharmless\ssigned/unsigned\scomparison\swarnings. +D 2013-11-21T21:59:53.570 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,8 +166,8 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 260dedc13119e6fb7930380bd3d294b98362bf5a -F src/btree.h bfe0e8c5759b4ec77b0d18390064a6ef3cdffaaf +F src/btree.c 17ca5729d07ba03f81633aab56de87956d9b188a +F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 @@ -280,13 +280,13 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c bfbbaf9daddfd0228747e4e47677bd34dc306388 +F src/vdbe.c 4d637218b7ffcc76fdcf461c71d277e7a4250e74 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 -F src/vdbeInt.h 0ac03c790b8ea4568b747550ba9bbf92a8e8feb2 +F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 648f72365268979e89cd2ba8e5f2b4ecb1843fb0 +F src/vdbeaux.c 5251f17828ff49664f457b6d8a1585297ce7a7a9 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c 4f227e2e28493a680dd84e6a4d28c9b01dca172b +F src/vdbemem.c cd02a6ade205ebe989983b7e3d64a5358b8e5e1f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -758,7 +758,7 @@ F test/rollback.test e9504a009a202c3ed711da2e6879ff60c5a4669c F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test f777404492adb0e00868fd706a3721328fd3af48 F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 -F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 w test/run-wordcount.bash +F test/run-wordcount.sh 891e89c4c2d16e629cd45951d4ed899ad12afc09 F test/savepoint.test 6c53f76dffe5df0dd87646efe3e7aa159c36e07b F test/savepoint2.test 9b8543940572a2f01a18298c3135ad0c9f4f67d7 F test/savepoint3.test e328085853b14898d78ceea00dfe7db18bb6a9ec @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 487f20366ce77f0c90865d10d5aaedd95af98694 -R 24abe371fb3b49f56b9cb321d5c8bf3d +P 586c11ed7cc6b8e2c7181231e37791c2fbc95272 +R 723b7c82330581cbe6be5156936bfadc U drh -Z e03360c4606d03267f7f33fe62a05d71 +Z 3bf6b81cb7a632df512ea0b6d5ca4d08 diff --git a/manifest.uuid b/manifest.uuid index 772e51934b..9fe6a08b40 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -586c11ed7cc6b8e2c7181231e37791c2fbc95272 \ No newline at end of file +4e8c5d0795cb7c603182bfa70f3855d654f0997e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index cebf95e8da..2a5b45e5c6 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4206,7 +4206,7 @@ int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ */ static const unsigned char *fetchPayload( BtCursor *pCur, /* Cursor pointing to entry to read from */ - int *pAmt, /* Write the number of available bytes here */ + u32 *pAmt, /* Write the number of available bytes here */ int skipKey /* read beginning at data if this is true */ ){ unsigned char *aPayload; @@ -4256,7 +4256,7 @@ static const unsigned char *fetchPayload( ** These routines is used to get quick access to key and data ** in the common case where no overflow pages are used. */ -const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ +const void *sqlite3BtreeKeyFetch(BtCursor *pCur, u32 *pAmt){ const void *p = 0; assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); @@ -4265,7 +4265,7 @@ const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ } return p; } -const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ +const void *sqlite3BtreeDataFetch(BtCursor *pCur, u32 *pAmt){ const void *p = 0; assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); diff --git a/src/btree.h b/src/btree.h index 33b3ed1f08..3eb5906955 100644 --- a/src/btree.h +++ b/src/btree.h @@ -178,8 +178,8 @@ int sqlite3BtreeEof(BtCursor*); int sqlite3BtreePrevious(BtCursor*, int *pRes); int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); -const void *sqlite3BtreeKeyFetch(BtCursor*, int *pAmt); -const void *sqlite3BtreeDataFetch(BtCursor*, int *pAmt); +const void *sqlite3BtreeKeyFetch(BtCursor*, u32 *pAmt); +const void *sqlite3BtreeDataFetch(BtCursor*, u32 *pAmt); int sqlite3BtreeDataSize(BtCursor*, u32 *pSize); int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*); void sqlite3BtreeSetCachedRowid(BtCursor*, sqlite3_int64); diff --git a/src/vdbe.c b/src/vdbe.c index f30810dd8a..b45b71af18 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2264,7 +2264,7 @@ case OP_Column: { const u8 *zEndHdr; /* Pointer to first byte after the header */ u32 offset; /* Offset into the data */ u32 szField; /* Number of bytes in the content of a field */ - int avail; /* Number of bytes of available data */ + u32 avail; /* Number of bytes of available data */ u32 t; /* A type code from the record header */ Mem *pReg; /* PseudoTable input register */ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index adcb13db37..371c4d6dc1 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -424,7 +424,7 @@ double sqlite3VdbeRealValue(Mem*); void sqlite3VdbeIntegerAffinity(Mem*); int sqlite3VdbeMemRealify(Mem*); int sqlite3VdbeMemNumerify(Mem*); -int sqlite3VdbeMemFromBtree(BtCursor*,int,int,int,Mem*); +int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*); void sqlite3VdbeMemRelease(Mem *p); void sqlite3VdbeMemReleaseExternal(Mem *p); #define VdbeMemRelease(X) \ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e31b89bb09..bea60ba9d1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3205,7 +3205,7 @@ int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ /* Read in the complete content of the index entry */ memset(&m, 0, sizeof(m)); - rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m); if( rc ){ return rc; } @@ -3283,7 +3283,7 @@ int sqlite3VdbeIdxKeyCompare( return SQLITE_CORRUPT_BKPT; } memset(&m, 0, sizeof(m)); - rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m); + rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m); if( rc ){ return rc; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 4f058d13ea..a67305f350 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -896,13 +896,13 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ */ int sqlite3VdbeMemFromBtree( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ - int offset, /* Offset from the start of data to return bytes from. */ - int amt, /* Number of bytes to return. */ + u32 offset, /* Offset from the start of data to return bytes from. */ + u32 amt, /* Number of bytes to return. */ int key, /* If true, retrieve from the btree key, not data. */ Mem *pMem /* OUT: Return data in this Mem structure. */ ){ char *zData; /* Data from the btree layer */ - int available = 0; /* Number of bytes available on the local btree page */ + u32 available = 0; /* Number of bytes available on the local btree page */ int rc = SQLITE_OK; /* Return code */ assert( sqlite3BtreeCursorIsValid(pCur) ); @@ -936,7 +936,7 @@ int sqlite3VdbeMemFromBtree( sqlite3VdbeMemRelease(pMem); } } - pMem->n = amt; + pMem->n = (int)amt; return rc; } From cb4f870884990a08f584cc13369423b86aeb829f Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 21 Nov 2013 22:02:52 +0000 Subject: [PATCH 52/78] Slight change to the --timer output on wordcount for better display on windows: Avoid showing the full pathname of the executable. FossilOrigin-Name: b9e047b9e3c2ee4df4a2d921db62f590fa5452d3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wordcount.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 78fc61f7ea..ff465e9eb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\ssome\soffset\sand\samount\sparameters\sfrom\s"int"\sto\s"u32"\sto\savoid\nharmless\ssigned/unsigned\scomparison\swarnings. -D 2013-11-21T21:59:53.570 +C Slight\schange\sto\sthe\s--timer\soutput\son\swordcount\sfor\sbetter\sdisplay\son\s\nwindows:\s\sAvoid\sshowing\sthe\sfull\spathname\sof\sthe\sexecutable. +D 2013-11-21T22:02:52.851 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1089,7 +1089,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c 6ce4090a90cd4a34b7cf7f8969c033cedab72399 +F test/wordcount.c 800b6ab98ac05b7c6343575c45055f72273c9cc2 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 586c11ed7cc6b8e2c7181231e37791c2fbc95272 -R 723b7c82330581cbe6be5156936bfadc +P 4e8c5d0795cb7c603182bfa70f3855d654f0997e +R ffed574cf9d774930b45b0d81c7e5184 U drh -Z 3bf6b81cb7a632df512ea0b6d5ca4d08 +Z 0797bb1805b05388278b1c28ef08180c diff --git a/manifest.uuid b/manifest.uuid index 9fe6a08b40..3cc841abaa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4e8c5d0795cb7c603182bfa70f3855d654f0997e \ No newline at end of file +b9e047b9e3c2ee4df4a2d921db62f590fa5452d3 \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index 24924e1b0a..b21b4272bc 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -473,9 +473,9 @@ int main(int argc, char **argv){ if( showTimer ){ sqlite3_int64 elapseTime = realTime() - startTime; - fprintf(stderr, "%3d.%03d", (int)(elapseTime/1000), + fprintf(stderr, "%3d.%03d wordcount", (int)(elapseTime/1000), (int)(elapseTime%1000)); - for(i=0; i Date: Thu, 21 Nov 2013 23:37:02 +0000 Subject: [PATCH 53/78] Fix a harmless clang warning in the command-line shell. FossilOrigin-Name: 3d47a556f0074e39b880186fb7661b1b8955f742 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ff465e9eb5..3ad0bc1e9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slight\schange\sto\sthe\s--timer\soutput\son\swordcount\sfor\sbetter\sdisplay\son\s\nwindows:\s\sAvoid\sshowing\sthe\sfull\spathname\sof\sthe\sexecutable. -D 2013-11-21T22:02:52.851 +C Fix\sa\sharmless\sclang\swarning\sin\sthe\scommand-line\sshell. +D 2013-11-21T23:37:02.064 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -220,7 +220,7 @@ F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68 F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a -F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17 +F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 4e8c5d0795cb7c603182bfa70f3855d654f0997e -R ffed574cf9d774930b45b0d81c7e5184 +P b9e047b9e3c2ee4df4a2d921db62f590fa5452d3 +R e1c23de46d9a8c9f6f6b75ce3e87aab2 U drh -Z 0797bb1805b05388278b1c28ef08180c +Z c20a6fbb51178b9cf782e69ef465aa75 diff --git a/manifest.uuid b/manifest.uuid index 3cc841abaa..b695247fd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9e047b9e3c2ee4df4a2d921db62f590fa5452d3 \ No newline at end of file +3d47a556f0074e39b880186fb7661b1b8955f742 \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 37e9b451bc..1db1e64e7e 100644 --- a/src/shell.c +++ b/src/shell.c @@ -1307,7 +1307,7 @@ static int shell_exec( /* If the shell is currently in ".explain" mode, gather the extra ** data required to add indents to the output.*/ - if( pArg->mode==MODE_Explain ){ + if( pArg && pArg->mode==MODE_Explain ){ explain_data_prepare(pArg, pStmt); } From f201496c6adc76f00a24a3336aec68fc10dc886a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 22 Nov 2013 00:49:43 +0000 Subject: [PATCH 54/78] Minor correction to the batch build tool for MSVC. FossilOrigin-Name: 22144c9df260910c4b67960b0e6a6bd5a6758cd7 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/build-all-msvc.bat | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3ad0bc1e9d..b4ebce1d9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\sclang\swarning\sin\sthe\scommand-line\sshell. -D 2013-11-21T23:37:02.064 +C Minor\scorrection\sto\sthe\sbatch\sbuild\stool\sfor\sMSVC. +D 2013-11-22T00:49:43.704 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1092,7 +1092,7 @@ F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a F test/wordcount.c 800b6ab98ac05b7c6343575c45055f72273c9cc2 F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd -F tool/build-all-msvc.bat 1bac6adc3fdb4d9204f21d17b14be25778370e48 x +F tool/build-all-msvc.bat e0917e787df675b020d250d60a00de8abaa4e30a x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P b9e047b9e3c2ee4df4a2d921db62f590fa5452d3 -R e1c23de46d9a8c9f6f6b75ce3e87aab2 -U drh -Z c20a6fbb51178b9cf782e69ef465aa75 +P 3d47a556f0074e39b880186fb7661b1b8955f742 +R 57564d661112762174840a226a6b5fb4 +U mistachkin +Z 4e5d5b9eac4581fb824e1e1729660a2d diff --git a/manifest.uuid b/manifest.uuid index b695247fd4..2486e092a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d47a556f0074e39b880186fb7661b1b8955f742 \ No newline at end of file +22144c9df260910c4b67960b0e6a6bd5a6758cd7 \ No newline at end of file diff --git a/tool/build-all-msvc.bat b/tool/build-all-msvc.bat index c730943f68..6e0aeb572c 100755 --- a/tool/build-all-msvc.bat +++ b/tool/build-all-msvc.bat @@ -492,9 +492,9 @@ GOTO no_errors GOTO :EOF :fn_CopyVariable - SETLOCAL IF NOT DEFINED %1 GOTO :EOF IF "%2" == "" GOTO :EOF + SETLOCAL SET __ECHO_CMD=ECHO %%%1%% FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO ( SET VALUE=%%V From 20b859530b304b11fe717647cc245d30f370606b Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 22 Nov 2013 21:32:44 +0000 Subject: [PATCH 55/78] Fix harmless compiler warning. FossilOrigin-Name: f336c18fb72ab90e93640b12ac540d41accc7658 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/delete.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b4ebce1d9a..d0cb9d093e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\scorrection\sto\sthe\sbatch\sbuild\stool\sfor\sMSVC. -D 2013-11-22T00:49:43.704 +C Fix\sharmless\scompiler\swarning. +D 2013-11-22T21:32:44.862 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -174,7 +174,7 @@ F src/callback.c f99a8957ba2adf369645fac0db09ad8adcf1caa2 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 -F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe +F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93 F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5 @@ -1141,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 3d47a556f0074e39b880186fb7661b1b8955f742 -R 57564d661112762174840a226a6b5fb4 +P 22144c9df260910c4b67960b0e6a6bd5a6758cd7 +R a6046c7308cc14b222954cb363712891 U mistachkin -Z 4e5d5b9eac4581fb824e1e1729660a2d +Z 1a138036d5d9c73c4e767d01f06aef9f diff --git a/manifest.uuid b/manifest.uuid index 2486e092a6..f3f95c10e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22144c9df260910c4b67960b0e6a6bd5a6758cd7 \ No newline at end of file +f336c18fb72ab90e93640b12ac540d41accc7658 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 4b57cf2805..5315db9e71 100644 --- a/src/delete.c +++ b/src/delete.c @@ -244,7 +244,7 @@ void sqlite3DeleteFrom( int aiCurOnePass[2]; /* The write cursors opened by WHERE_ONEPASS */ u8 *aToOpen = 0; /* Open cursor iTabCur+j if aToOpen[j] is true */ Index *pPk; /* The PRIMARY KEY index on the table */ - int iPk; /* First of nPk registers holding PRIMARY KEY value */ + int iPk = 0; /* First of nPk registers holding PRIMARY KEY value */ i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ int iKey; /* Memory cell holding key of row to be deleted */ i16 nKey; /* Number of memory cells in the row key */ From ac1f10458b9ab22ee0679ba8e4bff3a046e1a0ca Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Nov 2013 00:27:29 +0000 Subject: [PATCH 56/78] Add experimental sqlite3_config option to control the native Win32 heap size. FossilOrigin-Name: f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 --- manifest | 24 +++++++++------ manifest.uuid | 2 +- src/main.c | 7 +++++ src/os_win.c | 16 +++++++--- src/sqlite.h.in | 8 +++++ src/test_config.c | 6 ++++ src/test_malloc.c | 28 +++++++++++++++++ test/win32heap.test | 74 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 149 insertions(+), 16 deletions(-) create mode 100644 test/win32heap.test diff --git a/manifest b/manifest index d0cb9d093e..cdad278b03 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning. -D 2013-11-22T21:32:44.862 +C Add\sexperimental\ssqlite3_config\soption\sto\scontrol\sthe\snative\sWin32\sheap\ssize. +D 2013-11-23T00:27:29.844 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 32bf1e6e164a6fa0ddf1bf2616c6eafbefd6e9b0 +F src/main.c 68e5b72cc2cdc2a0101c3bf7a1112fc39a4c6441 F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -206,7 +206,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 -F src/os_win.c ef091b347d682cb24fc575ac9a6290341af62e2b +F src/os_win.c 39e9fc083fc35caedeb72f7724791a089722f896 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca @@ -221,7 +221,7 @@ F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 -F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e +F src/sqlite.h.in 1399855c547dbe3cbc556f5423067834e0945b88 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 @@ -242,7 +242,7 @@ F src/test_async.c 21e11293a2f72080eda70e1124e9102044531cd8 F src/test_autoext.c dea8a01a7153b9adc97bd26161e4226329546e12 F src/test_backup.c 3875e899222b651e18b662f86e0e50daa946344e F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16 -F src/test_config.c e825cd6a4a8f498be246fc5934fe5fd702b9441f +F src/test_config.c 10d0e00dd6315879a6d9fac20bd063c7bbbfb8f8 F src/test_demovfs.c 69b2085076654ebc18014cbc6386f04409c959a9 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_fs.c ced436e3d4b8e4681328409b8081051ce614e28f @@ -253,7 +253,7 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c eba4e1c5847cc98e7edc98f62265cd2abafba7a6 +F src/test_malloc.c eec5258da8ca468e3165bfa5e2e4461fe08ed385 F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8 F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -1083,6 +1083,7 @@ F test/whereF.test 5b2ba0dbe8074aa13e416b37c753991f0a2492d7 F test/whereG.test 2a3d5181decc801b36600fa1c40b0dad2ccc267f F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31 F test/wild001.test bca33f499866f04c24510d74baf1e578d4e44b1c +F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361 F test/win32longpath.test e2aafc07e6990fe86c69be22a3d1a0e210cd329b F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 @@ -1141,7 +1142,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 22144c9df260910c4b67960b0e6a6bd5a6758cd7 -R a6046c7308cc14b222954cb363712891 +P f336c18fb72ab90e93640b12ac540d41accc7658 +R 4fb7e3d2adbb1a56917a356c46494b14 +T *branch * winHeapSize +T *sym-winHeapSize * +T -sym-trunk * U mistachkin -Z 1a138036d5d9c73c4e767d01f06aef9f +Z 570dda2e20bfd9c30436e58012ccd873 diff --git a/manifest.uuid b/manifest.uuid index f3f95c10e6..18b1640e79 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f336c18fb72ab90e93640b12ac540d41accc7658 \ No newline at end of file +f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 5e03662d38..61d06fdb78 100644 --- a/src/main.c +++ b/src/main.c @@ -515,6 +515,13 @@ int sqlite3_config(int op, ...){ break; } +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) + case SQLITE_CONFIG_HEAP_SIZE: { + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + break; + } +#endif + default: { rc = SQLITE_ERROR; break; diff --git a/src/os_win.c b/src/os_win.c index a2f5513a2b..a1c3a04d7b 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -1401,14 +1401,20 @@ static int winMemInit(void *pAppData){ #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE if( !pWinMemData->hHeap ){ + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; + if( dwMaximumSize==0 ){ + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; + }else if( dwInitialSize>dwMaximumSize ){ + dwInitialSize = dwMaximumSize; + } pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, - SQLITE_WIN32_HEAP_MAX_SIZE); + dwInitialSize, dwMaximumSize); if( !pWinMemData->hHeap ){ sqlite3_log(SQLITE_NOMEM, - "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u", - osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, - SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, + dwMaximumSize); return SQLITE_NOMEM; } pWinMemData->bOwned = TRUE; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index e6dcfaba9a..7c39f4efe9 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1682,6 +1682,13 @@ struct sqlite3_mem_methods { ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ ** ^If either argument to this option is negative, then that argument is ** changed to its compile-time default. +** +** [[SQLITE_CONFIG_HEAP_SIZE]] +**
    SQLITE_CONFIG_HEAP_SIZE +**
    ^This option is only available if SQLite is compiled for Windows +** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. +** SQLITE_CONFIG_HEAP_SIZE takes a 32-bit integer value that specifies +** the maximum size of the heap. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1706,6 +1713,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ +#define SQLITE_CONFIG_HEAP_SIZE 23 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options diff --git a/src/test_config.c b/src/test_config.c index 8d871aa74c..f44be40508 100644 --- a/src/test_config.c +++ b/src/test_config.c @@ -63,6 +63,12 @@ static void set_options(Tcl_Interp *interp){ Tcl_SetVar2(interp, "sqlite_options", "curdir", "0", TCL_GLOBAL_ONLY); #endif +#ifdef SQLITE_WIN32_MALLOC + Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "1", TCL_GLOBAL_ONLY); +#else + Tcl_SetVar2(interp, "sqlite_options", "win32malloc", "0", TCL_GLOBAL_ONLY); +#endif + #ifdef SQLITE_DEBUG Tcl_SetVar2(interp, "sqlite_options", "debug", "1", TCL_GLOBAL_ONLY); #else diff --git a/src/test_malloc.c b/src/test_malloc.c index f513e24bf4..0c2d6ba223 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1130,6 +1130,33 @@ static int test_config_heap( return TCL_OK; } +/* +** Usage: sqlite3_config_heap_size NBYTE +*/ +static int test_config_heap_size( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int nByte; /* Size to pass to sqlite3_config() */ + int rc; /* Return code of sqlite3_config() */ + + Tcl_Obj * CONST *aArg = &objv[1]; + int nArg = objc-1; + + if( nArg!=1 ){ + Tcl_WrongNumArgs(interp, 1, objv, "NBYTE"); + return TCL_ERROR; + } + if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR; + + rc = sqlite3_config(SQLITE_CONFIG_HEAP_SIZE, nByte); + + Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); + return TCL_OK; +} + /* ** Usage: sqlite3_config_error [DB] ** @@ -1473,6 +1500,7 @@ int Sqlitetest_malloc_Init(Tcl_Interp *interp){ { "sqlite3_db_status", test_db_status ,0 }, { "install_malloc_faultsim", test_install_malloc_faultsim ,0 }, { "sqlite3_config_heap", test_config_heap ,0 }, + { "sqlite3_config_heap_size", test_config_heap_size ,0 }, { "sqlite3_config_memstatus", test_config_memstatus ,0 }, { "sqlite3_config_lookaside", test_config_lookaside ,0 }, { "sqlite3_config_error", test_config_error ,0 }, diff --git a/test/win32heap.test b/test/win32heap.test new file mode 100644 index 0000000000..b92f8040e6 --- /dev/null +++ b/test/win32heap.test @@ -0,0 +1,74 @@ +# 2013 November 22 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this script is recovery from transient manditory locks +# that sometimes appear on database files due to anti-virus software. +# + +if {$tcl_platform(platform)!="windows"} return + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !win32malloc { + finish_test + return +} + +set testprefix win32heap + +do_test 1.1 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap_size 1048576 + sqlite3_initialize +} {SQLITE_OK} + +do_test 1.2 { + sqlite3 db test.db + catchsql { + CREATE TABLE t1(x); + } +} {0 {}} + +do_test 1.3 { + catchsql { + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576)); + } +} {1 {out of memory}} + +do_test 1.4 { + catchsql { + SELECT COUNT(*) FROM t1; + } +} {0 0} + +do_test 1.5 { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap_size 0 + sqlite3_initialize +} {SQLITE_OK} + +do_test 1.6 { + sqlite3 db test.db + catchsql { + INSERT INTO t1 (x) VALUES(RANDOMBLOB(1048576)); + } +} {0 {}} + +do_test 1.7 { + catchsql { + SELECT COUNT(*) FROM t1; + } +} {0 1} + +finish_test From ad1ca9a792645499bb35d16fa5a5a7599f14efa3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Nov 2013 04:16:58 +0000 Subject: [PATCH 57/78] Add the "speedtest1.exe" test program. FossilOrigin-Name: fb6f0c6d77b2318e6e587951514aea91db128c3c --- Makefile.in | 3 + Makefile.msc | 4 + main.mk | 3 + manifest | 19 +- manifest.uuid | 2 +- test/speedtest1.c | 1013 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1034 insertions(+), 10 deletions(-) create mode 100644 test/speedtest1.c diff --git a/Makefile.in b/Makefile.in index b38edda821..a0217c4343 100644 --- a/Makefile.in +++ b/Makefile.in @@ -940,6 +940,9 @@ showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.c wordcount$(TEXE): $(TOP)/test/wordcount.c sqlite3.c $(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.c $(TLIBS) +speedtest1$(TEXE): $(TOP)/test/wordcount.c sqlite3.lo + $(LTLINK) -o $@ $(TOP)/test/speedtest1.c sqlite3.lo $(TLIBS) + # Standard install and cleanup targets # lib_install: libsqlite3.la diff --git a/Makefile.msc b/Makefile.msc index 3bc01c07b4..e8b45c40a0 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1342,6 +1342,10 @@ wordcount.exe: $(TOP)/test/wordcount.c sqlite3.c $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ $(TOP)/test/wordcount.c sqlite3.c +speedtest1.exe: $(TOP)/test/speedtest1.c sqlite3.c + $(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ + $(TOP)/test/speedtest1.c sqlite3.c + clean: del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib del /Q *.cod *.da *.bb *.bbg gmon.out diff --git a/main.mk b/main.mk index 9f06366566..41d1743832 100644 --- a/main.mk +++ b/main.mk @@ -630,6 +630,9 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o wordcount$(EXE) \ $(TOP)/test/wordcount.c sqlite3.c +speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o + $(TCC) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB) + # This target will fail if the SQLite amalgamation contains any exported # symbols that do not begin with "sqlite3_". It is run as part of the # releasetest.tcl script. diff --git a/manifest b/manifest index d0cb9d093e..cad280251e 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Fix\sharmless\scompiler\swarning. -D 2013-11-22T21:32:44.862 +C Add\sthe\s"speedtest1.exe"\stest\sprogram. +D 2013-11-23T04:16:58.402 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 +F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 19243469fcd1073319ea5b7db97609c1cfb3b1c0 +F Makefile.msc 83e270cf9225161ca700bcf93f65ac6ba59816db F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 52f7e22bfcec71a462e34194b4ae1671380fde59 @@ -142,7 +142,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff -F main.mk f57b51e64f50e9924b3f14df3c2e8b66893a8ce5 +F main.mk 82fd90375561d7b66287ae5a8b09e1e027394019 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338 @@ -819,6 +819,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b +F test/speedtest1.c b84e185c290a28bab4882773d963372b5ba2b17b F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1141,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 22144c9df260910c4b67960b0e6a6bd5a6758cd7 -R a6046c7308cc14b222954cb363712891 -U mistachkin -Z 1a138036d5d9c73c4e767d01f06aef9f +P f336c18fb72ab90e93640b12ac540d41accc7658 +R 84910a35b8353ac0918edf1cf1e1a63c +U drh +Z 46189456ad548cdae1d22fac7ad55b97 diff --git a/manifest.uuid b/manifest.uuid index f3f95c10e6..e275290da2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f336c18fb72ab90e93640b12ac540d41accc7658 \ No newline at end of file +fb6f0c6d77b2318e6e587951514aea91db128c3c \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c new file mode 100644 index 0000000000..b9452f971a --- /dev/null +++ b/test/speedtest1.c @@ -0,0 +1,1013 @@ +/* +** A program for performance testing. +** +** The available command-line options are described below: +*/ +static const char zHelp[] = + "Usage: %s [--options] DATABASE\n" + "Options:\n" + " --autovacuum Enable AUTOVACUUM mode\n" + " --cachesize N Set the cache size to N\n" + " --exclusive Enable locking_mode=EXCLUSIVE\n" + " --heap SIZE MIN Use an alternative memory allocator with sizes given\n" + " --incrvacuum Enable incremenatal vacuum mode\n" + " --journalmode M Set the journal_mode to MODE\n" + " --key KEY Set the encryption key to KEY\n" + " --lookaside N SZ Configure lookaside for N slots of SZ bytes each\n" + " --nosync Set PRAGMA synchronous=OFF\n" + " --notnull Add NOT NULL constraints to table columns\n" + " --pagesize N Set the page size to N\n" + " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n" + " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n" + " --reprepare Reprepare each statement upon every invocation\n" + " --sqlonly No-op. Only show the SQL that would have been run.\n" + " --size N Relative test size. Default=100\n" + " --stats Show statistics at the end\n" + " --testset T Run test-set T\n" + " --trace Turn on SQL tracing\n" + " --utf16be Set text encoding to UTF-16BE\n" + " --utf16le Set text encoding to UTF-16LE\n" + " --without-rowid Use WITHOUT ROWID where appropriate\n" +; + + +#include "sqlite3.h" +#include +#include +#include +#include +#include +#include + +/* All global state is held in this structure */ +static struct Global { + sqlite3 *db; /* The open database connection */ + sqlite3_stmt *pStmt; /* Current SQL statement */ + sqlite3_int64 iStart; /* Start-time for the current test */ + sqlite3_int64 iTotal; /* Total time */ + int bWithoutRowid; /* True for --without-rowid */ + int bReprepare; /* True to reprepare the SQL on each rerun */ + int bSqlOnly; /* True to print the SQL once only */ + int szTest; /* Scale factor for test iterations */ + const char *zWR; /* Might be WITHOUT ROWID */ + const char *zNN; /* Might be NOT NULL */ + const char *zPK; /* Might be UNIQUE or PRIMARY KEY */ + unsigned int x, y; /* Pseudo-random number generator state */ + int nResult; /* Size of the current result */ + char zResult[3000]; /* Text of the current result */ +} g; + +/* +** Return non-zero if string z matches glob pattern zGlob and zero if the +** pattern does not match. +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front +*/ +int speedtest1_strglob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + + while( (c = (*(zGlob++)))!=0 ){ + if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && speedtest1_strglob(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( speedtest1_strglob(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++; + if( !isdigit(z[0]) ) return 0; + z++; + while( isdigit(z[0]) ){ z++; } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + return *z==0; +} + +/* +** Return the value of a hexadecimal digit. Return -1 if the input +** is not a hex digit. +*/ +static int hexDigitValue(char c){ + if( c>='0' && c<='9' ) return c - '0'; + if( c>='a' && c<='f' ) return c - 'a' + 10; + if( c>='A' && c<='F' ) return c - 'A' + 10; + return -1; +} + +/* +** Interpret zArg as an integer value, possibly with suffixes. +*/ +static sqlite3_int64 integerValue(const char *zArg){ + sqlite3_int64 v = 0; + static const struct { char *zSuffix; int iMult; } aMult[] = { + { "KiB", 1024 }, + { "MiB", 1024*1024 }, + { "GiB", 1024*1024*1024 }, + { "KB", 1000 }, + { "MB", 1000000 }, + { "GB", 1000000000 }, + { "K", 1000 }, + { "M", 1000000 }, + { "G", 1000000000 }, + }; + int i; + int isNeg = 0; + if( zArg[0]=='-' ){ + isNeg = 1; + zArg++; + }else if( zArg[0]=='+' ){ + zArg++; + } + if( zArg[0]=='0' && zArg[1]=='x' ){ + int x; + zArg += 2; + while( (x = hexDigitValue(zArg[0]))>=0 ){ + v = (v<<4) + x; + zArg++; + } + }else{ + while( isdigit(zArg[0]) ){ + v = v*10 + zArg[0] - '0'; + zArg++; + } + } + for(i=0; iiVersion>=1 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; +} + +/* Return a pseudo-random unsigned integer */ +unsigned int speedtest1_random(void){ + g.x = (g.x>>1) ^ ((1+~(g.x&1)) & 0xd0000001); + g.y = g.y*1103515245 + 12345; + return g.x ^ g.y; +} + +/* Map the value in within the range of 1...limit into another +** number in a way that is chatic and invertable. +*/ +unsigned swizzle(unsigned in, unsigned limit){ + unsigned out = 0; + while( limit ){ + out = (out<<1) | (in&1); + in >>= 1; + limit >>= 1; + } + return out; +} + +/* Round up a number so that it is a power of two minus one +*/ +unsigned roundup_allones(unsigned limit){ + unsigned m = 1; + while( m "one hundred twenty three" +*/ +int speedtest1_numbername(unsigned int n, char *zOut, int nOut){ + static const char *ones[] = { "zero", "one", "two", "three", "four", "five", + "six", "seven", "eight", "nine", "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", + "eighteen", "nineteen" }; + static const char *tens[] = { "", "ten", "twenty", "thirty", "forty", + "fifty", "sixty", "seventy", "eighty", "ninety" }; + int i = 0; + + if( n>=1000000000 ){ + i += speedtest1_numbername(n/1000000000, zOut+i, nOut-i); + sqlite3_snprintf(nOut-i, zOut+i, " billion"); + i += (int)strlen(zOut+i); + n = n % 1000000000; + } + if( n>=1000000 ){ + if( i && i=1000 ){ + if( i && i=100 ){ + if( i && i=20 ){ + if( i && i0 ){ + if( i && iNAMEWIDTH ){ + zName[NAMEWIDTH] = 0; + n = NAMEWIDTH; + } + if( g.bSqlOnly ){ + printf("/* %4d - %s%.*s */\n", iTestNum, zName, NAMEWIDTH-n, zDots); + }else{ + printf("%4d - %s%.*s ", iTestNum, zName, NAMEWIDTH-n, zDots); + fflush(stdout); + } + sqlite3_free(zName); + g.nResult = 0; + g.iStart = speedtest1_timestamp(); + g.x = 2903710987; + g.y = 1157229256; +} + +/* Complete a test case */ +void speedtest1_end_test(void){ + sqlite3_int64 iElapseTime = speedtest1_timestamp() - g.iStart; + if( !g.bSqlOnly ){ + g.iTotal += iElapseTime; + printf("%4d.%03ds\n", (int)(iElapseTime/1000), (int)(iElapseTime%1000)); + } + if( g.pStmt ){ + sqlite3_finalize(g.pStmt); + g.pStmt = 0; + } +} + +/* Report end of testing */ +void speedtest1_final(void){ + if( !g.bSqlOnly ){ + printf(" TOTAL%.*s %4d.%03ds\n", NAMEWIDTH-5, zDots, + (int)(g.iTotal/1000), (int)(g.iTotal%1000)); + } +} + +/* Print an error message and exit */ +static void fatal_error(const char *zMsg, ...){ + va_list ap; + va_start(ap, zMsg); + vfprintf(stderr, zMsg, ap); + va_end(ap); + exit(1); +} + +/* Run SQL */ +void speedtest1_exec(const char *zFormat, ...){ + va_list ap; + char *zSql; + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( g.bSqlOnly ){ + int n = (int)strlen(zSql); + while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } + printf("%.*s;\n", n, zSql); + }else{ + sqlite3_exec(g.db, zSql, 0, 0, 0); + } + sqlite3_free(zSql); +} + +/* Prepare an SQL statement */ +void speedtest1_prepare(const char *zFormat, ...){ + va_list ap; + char *zSql; + va_start(ap, zFormat); + zSql = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + if( g.bSqlOnly ){ + int n = (int)strlen(zSql); + while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } + printf("%.*s;\n", n, zSql); + }else{ + int rc; + if( g.pStmt ) sqlite3_finalize(g.pStmt); + rc = sqlite3_prepare_v2(g.db, zSql, -1, &g.pStmt, 0); + if( rc ){ + fatal_error("SQL error: %s\n", sqlite3_errmsg(g.db)); + } + } + sqlite3_free(zSql); +} + +/* Run an SQL statement previously prepared */ +void speedtest1_run(void){ + int i, n, len; + if( g.bSqlOnly ) return; + assert( g.pStmt ); + g.nResult = 0; + while( sqlite3_step(g.pStmt)==SQLITE_ROW ){ + n = sqlite3_column_count(g.pStmt); + for(i=0; i0 ) g.zResult[g.nResult++] = ' '; + memcpy(g.zResult + g.nResult, z, len+1); + g.nResult += len; + } + } + } + if( g.bReprepare ){ + sqlite3_stmt *pNew; + sqlite3_prepare_v2(g.db, sqlite3_sql(g.pStmt), -1, &pNew, 0); + sqlite3_finalize(g.pStmt); + g.pStmt = pNew; + }else{ + sqlite3_reset(g.pStmt); + } +} + +/* The sqlite3_trace() callback function */ +static void traceCallback(void *NotUsed, const char *zSql){ + int n = (int)strlen(zSql); + while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ) n--; + fprintf(stderr,"%.*s;\n", n, zSql); +} + +/* Substitute random() function that gives the same random +** sequence on each run, for repeatability. */ +static void randomFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random()); +} + +/* +** The main and default testset +*/ +void testset_main(void){ + int i; /* Loop counter */ + int n; /* iteration count */ + int sz; /* Size of the tables */ + int maxb; /* Maximum swizzled value */ + unsigned x1, x2; /* Parameters */ + int len; /* Length of the zNum[] string */ + char zNum[2000]; /* A number name */ + + sz = n = g.szTest*500; + maxb = roundup_allones(sz); + speedtest1_begin_test(100, "%d INSERTs into table with no index", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE TABLE t1(a INTEGER %s, b INTEGER %s, c TEXT %s);", + g.zNN, g.zNN, g.zNN); + speedtest1_prepare("INSERT INTO t1 VALUES(?1,?2,?3); -- %d times", n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1); + sqlite3_bind_int(g.pStmt, 2, i); + sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz; + speedtest1_begin_test(110, "%d ordered INSERTS with one index/PK", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE TABLE t2(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", + g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + speedtest1_prepare("INSERT INTO t2 VALUES(?1,?2,?3); -- %d times", n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + sqlite3_bind_int(g.pStmt, 1, i); + sqlite3_bind_int64(g.pStmt, 2, (sqlite3_int64)x1); + sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz; + speedtest1_begin_test(120, "%d unordered INSERTS with one index/PK", n); + speedtest1_exec("BEGIN"); + speedtest1_exec("CREATE TABLE t3(a INTEGER %s %s, b INTEGER %s, c TEXT %s) %s", + g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + speedtest1_prepare("INSERT INTO t3 VALUES(?1,?2,?3); -- %d times", n); + for(i=1; i<=n; i++){ + x1 = swizzle(i,maxb); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + sqlite3_bind_int(g.pStmt, 2, i); + sqlite3_bind_int64(g.pStmt, 1, (sqlite3_int64)x1); + sqlite3_bind_text(g.pStmt, 3, zNum, -1, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = g.szTest/2; + speedtest1_begin_test(130, "%d SELECTS, numeric BETWEEN, unindexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + " WHERE b BETWEEN ?1 AND ?2; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = g.szTest/5; + speedtest1_begin_test(140, "%d SELECTS, LIKE, unindexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + " WHERE c LIKE ?1; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb; + zNum[0] = '%'; + len = speedtest1_numbername(i, zNum+1, sizeof(zNum)-2); + zNum[len] = '%'; + zNum[len+1] = 0; + sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + speedtest1_begin_test(150, "CREATE INDEX five times"); + speedtest1_exec( + "BEGIN;\n" + "CREATE UNIQUE INDEX t1b ON t1(b);\n" + "CREATE INDEX t1c ON t1(c);\n" + "CREATE UNIQUE INDEX t2b ON t2(b);\n" + "CREATE INDEX t2c ON t2(c DESC);\n" + "CREATE INDEX t3bc ON t3(b,c);\n" + "COMMIT;\n" + ); + speedtest1_end_test(); + + + n = sz/5; + speedtest1_begin_test(160, "%d SELECTS, numeric BETWEEN, indexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + " WHERE b BETWEEN ?1 AND ?2; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz/5; + speedtest1_begin_test(161, "%d SELECTS, numeric BETWEEN, PK", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT count(*), avg(b), sum(length(c)) FROM t2\n" + " WHERE a BETWEEN ?1 AND ?2; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz/5; + speedtest1_begin_test(170, "%d SELECTS, text BETWEEN, indexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT count(*), avg(b), sum(length(c)) FROM t1\n" + " WHERE c BETWEEN ?1 AND (?1||'~'); -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = swizzle(i, maxb); + len = speedtest1_numbername(x1, zNum, sizeof(zNum)-1); + sqlite3_bind_text(g.pStmt, 1, zNum, len, SQLITE_STATIC); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + n = sz; + speedtest1_begin_test(180, "%d INSERTS with three indexes", n); + speedtest1_exec("BEGIN"); + speedtest1_exec( + "CREATE TABLE t4(\n" + " a INTEGER %s %s,\n" + " b INTEGER %s,\n" + " c TEXT %s\n" + ") %s", + g.zNN, g.zPK, g.zNN, g.zNN, g.zWR); + speedtest1_exec("CREATE INDEX t4b ON t4(b)"); + speedtest1_exec("CREATE INDEX t4c ON t4(c)"); + speedtest1_exec("INSERT INTO t4 SELECT * FROM t1"); + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + n = sz; + speedtest1_begin_test(190, "DELETE and REFILL one table", n); + speedtest1_exec( + "DELETE FROM t2;" + "INSERT INTO t2 SELECT * FROM t1;" + ); + speedtest1_end_test(); + + + speedtest1_begin_test(200, "VACUUM"); + speedtest1_exec("VACUUM"); + speedtest1_end_test(); + + + speedtest1_begin_test(210, "ALTER TABLE ADD COLUMN, and query"); + speedtest1_exec("ALTER TABLE t2 ADD COLUMN d DEFAULT 123"); + speedtest1_exec("SELECT sum(d) FROM t2"); + speedtest1_end_test(); + + + n = sz/5; + speedtest1_begin_test(230, "%d UPDATES, numeric BETWEEN, indexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "UPDATE t2 SET d=b*2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb; + x2 = speedtest1_random()%10 + sz/5000 + x1; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz; + speedtest1_begin_test(240, "%d UPDATES of individual rows", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "UPDATE t2 SET d=b*3 WHERE a=?1; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%sz + 1; + sqlite3_bind_int(g.pStmt, 1, x1); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + speedtest1_begin_test(250, "One big UPDATE of the whole %d-row table", sz); + speedtest1_exec("UPDATE t2 SET d=b*4"); + speedtest1_end_test(); + + + speedtest1_begin_test(260, "Query added column after filling"); + speedtest1_exec("SELECT sum(d) FROM t2"); + speedtest1_end_test(); + + + + n = sz/5; + speedtest1_begin_test(270, "%d DELETEs, numeric BETWEEN, indexed", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "DELETE FROM t2 WHERE b BETWEEN ?1 AND ?2; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%maxb + 1; + x2 = speedtest1_random()%10 + sz/5000 + x1; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + n = sz; + speedtest1_begin_test(280, "%d DELETEs of individual rows", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "DELETE FROM t3 WHERE a=?1; -- %d times", n + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%sz + 1; + sqlite3_bind_int(g.pStmt, 1, x1); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz); + speedtest1_exec("REPLACE INTO t2 SELECT * FROM t1"); + speedtest1_exec("REPLACE INTO t3 SELECT * FROM t1"); + speedtest1_end_test(); + + + n = sz/5; + speedtest1_begin_test(290, "%d four-ways joins", n); + speedtest1_exec("BEGIN"); + speedtest1_prepare( + "SELECT t1.c FROM t1, t2, t3, t4\n" + " WHERE t4.a BETWEEN ?1 AND ?2\n" + " AND t3.a=t4.b\n" + " AND t2.a=t3.b\n" + " AND t1.c=t2.c" + ); + for(i=1; i<=n; i++){ + x1 = speedtest1_random()%sz + 1; + x2 = speedtest1_random()%10 + x1 + 4; + sqlite3_bind_int(g.pStmt, 1, x1); + sqlite3_bind_int(g.pStmt, 2, x2); + speedtest1_run(); + } + speedtest1_exec("COMMIT"); + speedtest1_end_test(); + + + + speedtest1_begin_test(980, "PRAGMA integrity_check"); + speedtest1_exec("PRAGMA integrity_check"); + speedtest1_end_test(); + + + speedtest1_begin_test(990, "ANALYZE"); + speedtest1_exec("ANALYZE"); + speedtest1_end_test(); +} + +/* +** A testset used for debugging speedtest1 itself. +*/ +void testset_debug1(void){ + unsigned i, n; + unsigned x1, x2; + char zNum[2000]; /* A number name */ + + n = g.szTest; + for(i=1; i<=n; i++){ + x1 = swizzle(i, n); + x2 = swizzle(x1, n); + speedtest1_numbername(x1, zNum, sizeof(zNum)); + printf("%5d %5d %5d %s\n", i, x1, x2, zNum); + } +} + +int main(int argc, char **argv){ + int doAutovac = 0; /* True for --autovacuum */ + int cacheSize = 0; /* Desired cache size. 0 means default */ + int doExclusive = 0; /* True for --exclusive */ + int nHeap = 0, mnHeap = 0; /* Heap size from --heap */ + int doIncrvac = 0; /* True for --incrvacuum */ + const char *zJMode = 0; /* Journal mode */ + const char *zKey = 0; /* Encryption key */ + int nLook = 0, szLook = 0; /* --lookaside configuration */ + int noSync = 0; /* True for --nosync */ + int pageSize = 0; /* Desired page size. 0 means default */ + int nPCache = 0, szPCache = 0;/* --pcache configuration */ + int showStats = 0; /* True for --stats */ + const char *zTSet = "main"; /* Which --testset torun */ + int doTrace = 0; /* True for --trace */ + const char *zEncoding = 0; /* --utf16be or --utf16le */ + const char *zDbName = 0; /* Name of the test database */ + + void *pHeap = 0; /* Allocated heap space */ + void *pLook = 0; /* Allocated lookaside space */ + void *pPCache = 0; /* Allocated storage for pcache */ + int iCur, iHi; /* Stats values, current and "highwater" */ + int i; + + /* Process command-line arguments */ + g.zWR = ""; + g.zNN = ""; + g.zPK = "UNIQUE"; + g.szTest = 100; + for(i=1; i=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + i++; + cacheSize = (int)integerValue(argv[i]); + }else if( strcmp(z,"exclusive")==0 ){ + doExclusive = 1; + }else if( strcmp(z,"heap")==0 ){ + if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); + nHeap = (int)integerValue(argv[i+1]); + mnHeap = (int)integerValue(argv[i+2]); + i += 2; + }else if( strcmp(z,"incrvacuum")==0 ){ + doIncrvac = 1; + }else if( strcmp(z,"journal")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + zJMode = argv[++i]; + }else if( strcmp(z,"key")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + zKey = argv[++i]; + }else if( strcmp(z,"lookaside")==0 ){ + if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); + nLook = (int)integerValue(argv[i+1]); + szLook = (int)integerValue(argv[i+2]); + i += 2; + }else if( strcmp(z,"nosync")==0 ){ + noSync = 1; + }else if( strcmp(z,"notnull")==0 ){ + g.zNN = "NOT NULL"; + }else if( strcmp(z,"pagesize")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + pageSize = (int)integerValue(argv[++i]); + }else if( strcmp(z,"pcache")==0 ){ + if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); + nPCache = (int)integerValue(argv[i+1]); + szPCache = (int)integerValue(argv[i+2]); + i += 2; + }else if( strcmp(z,"primarykey")==0 ){ + g.zPK = "PRIMARY KEY"; + }else if( strcmp(z,"reprepare")==0 ){ + g.bReprepare = 1; + }else if( strcmp(z,"sqlonly")==0 ){ + g.bSqlOnly = 1; + }else if( strcmp(z,"size")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + g.szTest = (int)integerValue(argv[++i]); + }else if( strcmp(z,"stats")==0 ){ + showStats = 1; + }else if( strcmp(z,"testset")==0 ){ + if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); + zTSet = argv[++i]; + }else if( strcmp(z,"trace")==0 ){ + doTrace = 1; + }else if( strcmp(z,"utf16le")==0 ){ + zEncoding = "utf16le"; + }else if( strcmp(z,"utf16be")==0 ){ + zEncoding = "utf16be"; + }else if( strcmp(z,"without-rowid")==0 ){ + g.zWR = "WITHOUT ROWID"; + g.zPK = "PRIMARY KEY"; + }else if( strcmp(z, "help")==0 || strcmp(z,"?")==0 ){ + printf(zHelp, argv[0]); + exit(0); + }else{ + fatal_error("unknown option: %s\nUse \"%s -?\" for help\n", + argv[i], argv[0]); + } + }else if( zDbName==0 ){ + zDbName = argv[i]; + }else{ + fatal_error("surplus argument: %s\nUse \"%s -?\" for help\n", + argv[i], argv[0]); + } + } +#if 0 + if( zDbName==0 ){ + fatal_error(zHelp, argv[0]); + } +#endif + if( nHeap>0 ){ + pHeap = malloc( nHeap ); + if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap); + sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap); + } + if( nPCache>0 && szPCache>0 ){ + pPCache = malloc( nPCache*szPCache ); + if( pPCache==0 ) fatal_error("cannot allocate %d-byte pcache\n", + nPCache*szPCache); + sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, nPCache, szPCache); + } + if( nLook>0 ){ + sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); + } + + /* Open the database and the input file */ + if( sqlite3_open(zDbName, &g.db) ){ + fatal_error("Cannot open database file: %s\n", zDbName); + } + if( nLook>0 && szLook>0 ){ + pLook = malloc( nLook*szLook ); + sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook); + } + + /* Set database connection options */ + sqlite3_create_function(g.db, "random", 0, SQLITE_UTF8, 0, randomFunc, 0, 0); + if( doTrace ) sqlite3_trace(g.db, traceCallback, 0); + if( zKey ){ + speedtest1_exec("PRAGMA key('%s')", zKey); + } + if( zEncoding ){ + speedtest1_exec("PRAGMA encoding=%s", zEncoding); + } + if( doAutovac ){ + speedtest1_exec("PRAGMA auto_vacuum=FULL"); + }else if( doIncrvac ){ + speedtest1_exec("PRAGMA auto_vacuum=INCREMENTAL"); + } + if( pageSize ){ + speedtest1_exec("PRAGMA page_size=%d", pageSize); + } + if( cacheSize ){ + speedtest1_exec("PRAGMA cache_size=%d", cacheSize); + } + if( noSync ) speedtest1_exec("PRAGMA synchronous=OFF"); + if( doExclusive ){ + speedtest1_exec("PRAGMA locking_mode=EXCLUSIVE"); + } + if( zJMode ){ + speedtest1_exec("PRAGMA journal_mode=%s", zJMode); + } + + if( strcmp(zTSet,"main")==0 ){ + testset_main(); + }else if( strcmp(zTSet,"debug1")==0 ){ + testset_debug1(); + }else{ + fatal_error("unknown testset: \"%s\"\n", zTSet); + } + speedtest1_final(); + + /* Database connection statistics printed after both prepared statements + ** have been finalized */ + if( showStats ){ + sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHi, 0); + printf("-- Lookaside Slots Used: %d (max %d)\n", iCur,iHi); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHi, 0); + printf("-- Successful lookasides: %d\n", iHi); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur,&iHi,0); + printf("-- Lookaside size faults: %d\n", iHi); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur,&iHi,0); + printf("-- Lookaside OOM faults: %d\n", iHi); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHi, 0); + printf("-- Pager Heap Usage: %d bytes\n", iCur); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHi, 1); + printf("-- Page cache hits: %d\n", iCur); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHi, 1); + printf("-- Page cache misses: %d\n", iCur); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHi, 1); + printf("-- Page cache writes: %d\n", iCur); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHi, 0); + printf("-- Schema Heap Usage: %d bytes\n", iCur); + sqlite3_db_status(g.db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHi, 0); + printf("-- Statement Heap Usage: %d bytes\n", iCur); + } + + sqlite3_close(g.db); + + /* Global memory usage statistics printed after the database connection + ** has closed. Memory usage should be zero at this point. */ + if( showStats ){ + sqlite3_status(SQLITE_STATUS_MEMORY_USED, &iCur, &iHi, 0); + printf("-- Memory Used (bytes): %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_MALLOC_COUNT, &iCur, &iHi, 0); + printf("-- Outstanding Allocations: %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_PAGECACHE_OVERFLOW, &iCur, &iHi, 0); + printf("-- Pcache Overflow Bytes: %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_SCRATCH_OVERFLOW, &iCur, &iHi, 0); + printf("-- Scratch Overflow Bytes: %d (max %d)\n", iCur,iHi); + sqlite3_status(SQLITE_STATUS_MALLOC_SIZE, &iCur, &iHi, 0); + printf("-- Largest Allocation: %d bytes\n",iHi); + sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0); + printf("-- Largest Pcache Allocation: %d bytes\n",iHi); + sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0); + printf("-- Largest Scratch Allocation: %d bytes\n", iHi); + } + + /* Release memory */ + free( pLook ); + free( pPCache ); + free( pHeap ); + return 0; +} From 1617577e7792b35ff10bfa7d77c7606418cdc386 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 23 Nov 2013 04:22:19 +0000 Subject: [PATCH 58/78] Adjust MSVC makefile to avoid using forward slashes in file names. FossilOrigin-Name: facf6deaa61ed2e1744711d621d7f50fe2067803 --- Makefile.msc | 12 ++++++------ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index e8b45c40a0..437cb0eac3 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1334,17 +1334,17 @@ sqlite3_analyzer.exe: sqlite3_analyzer.c $(LIBRESOBJS) $(LTLINK) -DBUILD_sqlite -DTCLSH=2 -I$(TCLINCDIR) sqlite3_analyzer.c \ /link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS) -showdb.exe: $(TOP)/tool/showdb.c sqlite3.c +showdb.exe: $(TOP)\tool\showdb.c sqlite3.c $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)/tool/showdb.c sqlite3.c + $(TOP)\tool\showdb.c sqlite3.c -wordcount.exe: $(TOP)/test/wordcount.c sqlite3.c +wordcount.exe: $(TOP)\test\wordcount.c sqlite3.c $(LTLINK) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)/test/wordcount.c sqlite3.c + $(TOP)\test\wordcount.c sqlite3.c -speedtest1.exe: $(TOP)/test/speedtest1.c sqlite3.c +speedtest1.exe: $(TOP)\test\speedtest1.c sqlite3.c $(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -o $@ \ - $(TOP)/test/speedtest1.c sqlite3.c + $(TOP)\test\speedtest1.c sqlite3.c clean: del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib diff --git a/manifest b/manifest index cad280251e..d0287ba0a4 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\sthe\s"speedtest1.exe"\stest\sprogram. -D 2013-11-23T04:16:58.402 +C Adjust\sMSVC\smakefile\sto\savoid\susing\sforward\sslashes\sin\sfile\snames. +D 2013-11-23T04:22:19.145 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 -F Makefile.msc 83e270cf9225161ca700bcf93f65ac6ba59816db +F Makefile.msc a6247094079f3ef97dcd7a69d0e13ff718c7073e F Makefile.vxworks db21ed42a01d5740e656b16f92cb5d8d5e5dd315 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F VERSION 52f7e22bfcec71a462e34194b4ae1671380fde59 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f336c18fb72ab90e93640b12ac540d41accc7658 -R 84910a35b8353ac0918edf1cf1e1a63c -U drh -Z 46189456ad548cdae1d22fac7ad55b97 +P fb6f0c6d77b2318e6e587951514aea91db128c3c +R dc674c399747716ed8a20163dfd96488 +U mistachkin +Z 44f549b3621dca0c3a961db2024f2475 diff --git a/manifest.uuid b/manifest.uuid index e275290da2..e7cd901b6b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb6f0c6d77b2318e6e587951514aea91db128c3c \ No newline at end of file +facf6deaa61ed2e1744711d621d7f50fe2067803 \ No newline at end of file From c7c9f7110bc57c2f45440a109f1d7616bf06312d Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Nov 2013 04:32:18 +0000 Subject: [PATCH 59/78] Fix the order of parameters to SQLITE_CONFIG_PAGECACHE in the speedtest1.exe program. FossilOrigin-Name: dbe85ef6d265ed31f4b56dfc0c72bad6adcfd7f0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/speedtest1.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d0287ba0a4..41d7d5d0bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sMSVC\smakefile\sto\savoid\susing\sforward\sslashes\sin\sfile\snames. -D 2013-11-23T04:22:19.145 +C Fix\sthe\sorder\sof\sparameters\sto\sSQLITE_CONFIG_PAGECACHE\sin\sthe\nspeedtest1.exe\sprogram. +D 2013-11-23T04:32:18.644 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -819,7 +819,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c b84e185c290a28bab4882773d963372b5ba2b17b +F test/speedtest1.c 19ceb72f81d831bbd22c18d20a5d452075efaf1b F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fb6f0c6d77b2318e6e587951514aea91db128c3c -R dc674c399747716ed8a20163dfd96488 -U mistachkin -Z 44f549b3621dca0c3a961db2024f2475 +P facf6deaa61ed2e1744711d621d7f50fe2067803 +R 5a8018cc116cdda5096d79d3f410c8a0 +U drh +Z 81842b72e206955befee47563d6c51e0 diff --git a/manifest.uuid b/manifest.uuid index e7cd901b6b..6348d3fdae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -facf6deaa61ed2e1744711d621d7f50fe2067803 \ No newline at end of file +dbe85ef6d265ed31f4b56dfc0c72bad6adcfd7f0 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index b9452f971a..abc1e7fc66 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -907,7 +907,7 @@ int main(int argc, char **argv){ pPCache = malloc( nPCache*szPCache ); if( pPCache==0 ) fatal_error("cannot allocate %d-byte pcache\n", nPCache*szPCache); - sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, nPCache, szPCache); + sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); } if( nLook>0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); From e19f8327f87ddb17964f9732d2414f6855b2ad88 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Nov 2013 11:45:58 +0000 Subject: [PATCH 60/78] Report errors from sqlite3_exec() and sqlite3_config() in speedtest1. Fix a bug in the main testing logic that was found by these error reports. FossilOrigin-Name: 659f1a98ae698d062269f8fdac84f733a460f5de --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 21 ++++++++++++++------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 41d7d5d0bc..29763122bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sorder\sof\sparameters\sto\sSQLITE_CONFIG_PAGECACHE\sin\sthe\nspeedtest1.exe\sprogram. -D 2013-11-23T04:32:18.644 +C Report\serrors\sfrom\ssqlite3_exec()\sand\ssqlite3_config()\sin\sspeedtest1.\s\sFix\na\sbug\sin\sthe\smain\stesting\slogic\sthat\swas\sfound\sby\sthese\serror\sreports. +D 2013-11-23T11:45:58.348 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -819,7 +819,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 19ceb72f81d831bbd22c18d20a5d452075efaf1b +F test/speedtest1.c 34dfd9e87c6361fd5ddaed32470d72296a4d8f9e F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P facf6deaa61ed2e1744711d621d7f50fe2067803 -R 5a8018cc116cdda5096d79d3f410c8a0 +P dbe85ef6d265ed31f4b56dfc0c72bad6adcfd7f0 +R 3c84733d697c289c6df74ff384038ce3 U drh -Z 81842b72e206955befee47563d6c51e0 +Z 1e02960cbed70b5ceeaded68b201375e diff --git a/manifest.uuid b/manifest.uuid index 6348d3fdae..52732edbe9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbe85ef6d265ed31f4b56dfc0c72bad6adcfd7f0 \ No newline at end of file +659f1a98ae698d062269f8fdac84f733a460f5de \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index abc1e7fc66..9669495347 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -377,7 +377,10 @@ void speedtest1_exec(const char *zFormat, ...){ while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; } printf("%.*s;\n", n, zSql); }else{ - sqlite3_exec(g.db, zSql, 0, 0, 0); + char *zErrMsg = 0; + int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); + if( zErrMsg ) fatal_error("SQL error: %s\n%s\n", zErrMsg, zSql); + if( rc!=SQLITE_OK ) fatal_error("exec error: %s\n", sqlite3_errmsg(g.db)); } sqlite3_free(zSql); } @@ -731,8 +734,8 @@ void testset_main(void){ speedtest1_begin_test(290, "Refill two %d-row tables using REPLACE", sz); - speedtest1_exec("REPLACE INTO t2 SELECT * FROM t1"); - speedtest1_exec("REPLACE INTO t3 SELECT * FROM t1"); + speedtest1_exec("REPLACE INTO t2(a,b,c) SELECT a,b,c FROM t1"); + speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1"); speedtest1_end_test(); @@ -807,7 +810,8 @@ int main(int argc, char **argv){ void *pLook = 0; /* Allocated lookaside space */ void *pPCache = 0; /* Allocated storage for pcache */ int iCur, iHi; /* Stats values, current and "highwater" */ - int i; + int i; /* Loop counter */ + int rc; /* API return code */ /* Process command-line arguments */ g.zWR = ""; @@ -901,13 +905,15 @@ int main(int argc, char **argv){ if( nHeap>0 ){ pHeap = malloc( nHeap ); if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap); - sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap); + rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap); + if( rc ) fatal_error("heap configuration failed: %d", rc); } if( nPCache>0 && szPCache>0 ){ pPCache = malloc( nPCache*szPCache ); if( pPCache==0 ) fatal_error("cannot allocate %d-byte pcache\n", nPCache*szPCache); - sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); + rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); + if( rc ) fatal_error("pcache configuration failed: %d", rc); } if( nLook>0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); @@ -919,7 +925,8 @@ int main(int argc, char **argv){ } if( nLook>0 && szLook>0 ){ pLook = malloc( nLook*szLook ); - sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook, nLook); + rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook); + if( rc ) fatal_error("lookaside configuration failed: %d", rc); } /* Set database connection options */ From 7b65ad31e1f77ec630df566e84e3dcb8f6c40e71 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Nov 2013 21:29:07 +0000 Subject: [PATCH 61/78] Add newlines at the end of some error messages in speedtest1. FossilOrigin-Name: 6b98f0af7a6522873245d30598d7c79b8aeb9fa0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/speedtest1.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 29763122bc..47369b1136 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Report\serrors\sfrom\ssqlite3_exec()\sand\ssqlite3_config()\sin\sspeedtest1.\s\sFix\na\sbug\sin\sthe\smain\stesting\slogic\sthat\swas\sfound\sby\sthese\serror\sreports. -D 2013-11-23T11:45:58.348 +C Add\snewlines\sat\sthe\send\sof\ssome\serror\smessages\sin\sspeedtest1. +D 2013-11-23T21:29:07.429 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -819,7 +819,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 34dfd9e87c6361fd5ddaed32470d72296a4d8f9e +F test/speedtest1.c 3296bda6fdf2650773fa509dc51504b66da36e57 F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P dbe85ef6d265ed31f4b56dfc0c72bad6adcfd7f0 -R 3c84733d697c289c6df74ff384038ce3 +P 659f1a98ae698d062269f8fdac84f733a460f5de +R 0d67753f14410df579db17c64fb3786e U drh -Z 1e02960cbed70b5ceeaded68b201375e +Z 430a11d968198395db1db68b7169dc35 diff --git a/manifest.uuid b/manifest.uuid index 52732edbe9..fe94011755 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -659f1a98ae698d062269f8fdac84f733a460f5de \ No newline at end of file +6b98f0af7a6522873245d30598d7c79b8aeb9fa0 \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 9669495347..92f489223a 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -906,14 +906,14 @@ int main(int argc, char **argv){ pHeap = malloc( nHeap ); if( pHeap==0 ) fatal_error("cannot allocate %d-byte heap\n", nHeap); rc = sqlite3_config(SQLITE_CONFIG_HEAP, pHeap, nHeap, mnHeap); - if( rc ) fatal_error("heap configuration failed: %d", rc); + if( rc ) fatal_error("heap configuration failed: %d\n", rc); } if( nPCache>0 && szPCache>0 ){ pPCache = malloc( nPCache*szPCache ); if( pPCache==0 ) fatal_error("cannot allocate %d-byte pcache\n", nPCache*szPCache); rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); - if( rc ) fatal_error("pcache configuration failed: %d", rc); + if( rc ) fatal_error("pcache configuration failed: %d\n", rc); } if( nLook>0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); @@ -926,7 +926,7 @@ int main(int argc, char **argv){ if( nLook>0 && szLook>0 ){ pLook = malloc( nLook*szLook ); rc = sqlite3_db_config(g.db, SQLITE_DBCONFIG_LOOKASIDE, pLook, szLook,nLook); - if( rc ) fatal_error("lookaside configuration failed: %d", rc); + if( rc ) fatal_error("lookaside configuration failed: %d\n", rc); } /* Set database connection options */ From 9948e95674a267ab8175812745e2bdad93bbb877 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 23 Nov 2013 22:45:12 +0000 Subject: [PATCH 62/78] A much simpler fix is to simply change MEMSYS5 so that it takes any free block of the appropriate size (the first on the list of free blocks) rather than searching for the one with the smallest address. This is also faster than using the min-heap algorithm. Need to research to verify that the allocator still satisfies the Robson proof, however. FossilOrigin-Name: 8191b512122c13d7fa61d8e5487652f13ec172f7 --- manifest | 15 +++++++++------ manifest.uuid | 2 +- src/mem5.c | 16 ++++++++++------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 47369b1136..3c26785d5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snewlines\sat\sthe\send\sof\ssome\serror\smessages\sin\sspeedtest1. -D 2013-11-23T21:29:07.429 +C A\smuch\ssimpler\sfix\sis\sto\ssimply\schange\sMEMSYS5\sso\sthat\sit\stakes\sany\sfree\nblock\sof\sthe\sappropriate\ssize\s(the\sfirst\son\sthe\slist\sof\sfree\sblocks)\srather\nthan\ssearching\sfor\sthe\sone\swith\sthe\ssmallest\saddress.\s\sThis\sis\salso\sfaster\nthan\susing\sthe\smin-heap\salgorithm.\s\sNeed\sto\sresearch\sto\sverify\sthat\sthe\nallocator\sstill\ssatisfies\sthe\sRobson\sproof,\showever. +D 2013-11-23T22:45:12.906 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -194,7 +194,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem2.c dce31758da87ec2cfa52ba4c5df1aed6e07d8e8f F src/mem3.c 61c9d47b792908c532ca3a62b999cf21795c6534 -F src/mem5.c 0025308a93838022bd5696cf9627ff4e40b19918 +F src/mem5.c 77a525e6a4f623d1008f08a0a4050789e710d71e F src/memjournal.c 0683aac6cab6ec2b5374c0db37c0deb2436a3785 F src/mutex.c d3b66a569368015e0fcb1ac15f81c119f504d3bc F src/mutex.h 5bc526e19dccc412b7ff04642f6fdad3fdfdabea @@ -1142,7 +1142,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 659f1a98ae698d062269f8fdac84f733a460f5de -R 0d67753f14410df579db17c64fb3786e +P 6b98f0af7a6522873245d30598d7c79b8aeb9fa0 +R e84ccd96a2888616670da3469dc947a5 +T *branch * memsys5-performance +T *sym-memsys5-performance * +T -sym-trunk * U drh -Z 430a11d968198395db1db68b7169dc35 +Z 93975e1a1bc297cea7284502171ff001 diff --git a/manifest.uuid b/manifest.uuid index fe94011755..a79b866a19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b98f0af7a6522873245d30598d7c79b8aeb9fa0 \ No newline at end of file +8191b512122c13d7fa61d8e5487652f13ec172f7 \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index 5f99ebf43d..35719031f8 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -214,16 +214,20 @@ static int memsys5Size(void *p){ ** entry and return its index. */ static int memsys5UnlinkFirst(int iLogsize){ - int i; int iFirst; assert( iLogsize>=0 && iLogsize<=LOGMAX ); - i = iFirst = mem5.aiFreelist[iLogsize]; - assert( iFirst>=0 ); - while( i>0 ){ - if( inext; + iFirst = mem5.aiFreelist[iLogsize]; +#if 0 + { + int i = iFirst; + assert( iFirst>=0 ); + while( i>0 ){ + if( inext; + } } +#endif memsys5Unlink(iFirst, iLogsize); return iFirst; } From 93307e9d0624fdfa6e765c5feda2092cf2c2a2f9 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 24 Nov 2013 01:14:14 +0000 Subject: [PATCH 63/78] Add the --scratch parameter to speedtest1. Improved error messages when misconfiguring memory parameters in speedtest1. FossilOrigin-Name: 8f3c767a30c552548ead104ca125f182ce4849ad --- manifest | 13 ++--- manifest.uuid | 2 +- test/speedtest1.c | 145 ++++++++++++---------------------------------- 3 files changed, 45 insertions(+), 115 deletions(-) diff --git a/manifest b/manifest index a96cf2f323..aa2b98cdb9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sMEMSYS5\salgorithm\sdoes\snot\shave\sto\sreturn\sthe\sblock\swith\sthe\slowest\naddress.\s\sAny\sblock\sof\sthe\sappropriate\ssize\swill\sdo.\s\sUse\sthe\sfirst\sblock\nfound\son\sthe\sfreelist\sfor\sthe\sappropriate\ssize\sfor\sa\sperformance\simprovement. -D 2013-11-24T00:46:00.452 +C Add\sthe\s--scratch\sparameter\sto\sspeedtest1.\s\sImproved\serror\smessages\swhen\nmisconfiguring\smemory\sparameters\sin\sspeedtest1. +D 2013-11-24T01:14:14.123 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -819,7 +819,7 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523 F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b -F test/speedtest1.c 3296bda6fdf2650773fa509dc51504b66da36e57 +F test/speedtest1.c aa08ae8e3591bf5c028be9396a84237640761d8c F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940 @@ -1142,8 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6b98f0af7a6522873245d30598d7c79b8aeb9fa0 8191b512122c13d7fa61d8e5487652f13ec172f7 -R c70b3f80a0897046826a17fb7011539e -T +closed 8191b512122c13d7fa61d8e5487652f13ec172f7 +P 12e612e8e7c4a6f83acf0daf5608151fb5ec1575 +R d231270eb8540c71c1fe43ad7f945ecf U drh -Z dce60b90fb1ae6b64b6c8216e4da2c33 +Z 904197ecb3cb4ac430a652007d0a071c diff --git a/manifest.uuid b/manifest.uuid index 648e8522b0..7967f97b83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12e612e8e7c4a6f83acf0daf5608151fb5ec1575 \ No newline at end of file +8f3c767a30c552548ead104ca125f182ce4849ad \ No newline at end of file diff --git a/test/speedtest1.c b/test/speedtest1.c index 92f489223a..b15f65cfe9 100644 --- a/test/speedtest1.c +++ b/test/speedtest1.c @@ -9,7 +9,7 @@ static const char zHelp[] = " --autovacuum Enable AUTOVACUUM mode\n" " --cachesize N Set the cache size to N\n" " --exclusive Enable locking_mode=EXCLUSIVE\n" - " --heap SIZE MIN Use an alternative memory allocator with sizes given\n" + " --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n" " --incrvacuum Enable incremenatal vacuum mode\n" " --journalmode M Set the journal_mode to MODE\n" " --key KEY Set the encryption key to KEY\n" @@ -20,6 +20,7 @@ static const char zHelp[] = " --pcache N SZ Configure N pages of pagecache each of size SZ bytes\n" " --primarykey Use PRIMARY KEY instead of UNIQUE where appropriate\n" " --reprepare Reprepare each statement upon every invocation\n" + " --scratch N SZ Configure scratch memory for N slots of SZ bytes each\n" " --sqlonly No-op. Only show the SQL that would have been run.\n" " --size N Relative test size. Default=100\n" " --stats Show statistics at the end\n" @@ -57,91 +58,14 @@ static struct Global { char zResult[3000]; /* Text of the current result */ } g; -/* -** Return non-zero if string z matches glob pattern zGlob and zero if the -** pattern does not match. -** -** Globbing rules: -** -** '*' Matches any sequence of zero or more characters. -** -** '?' Matches exactly one character. -** -** [...] Matches one character from the enclosed list of -** characters. -** -** [^...] Matches one character not in the enclosed list. -** -** '#' Matches any sequence of one or more digits with an -** optional + or - sign in front -*/ -int speedtest1_strglob(const char *zGlob, const char *z){ - int c, c2; - int invert; - int seen; - while( (c = (*(zGlob++)))!=0 ){ - if( c=='*' ){ - while( (c=(*(zGlob++))) == '*' || c=='?' ){ - if( c=='?' && (*(z++))==0 ) return 0; - } - if( c==0 ){ - return 1; - }else if( c=='[' ){ - while( *z && speedtest1_strglob(zGlob-1,z)==0 ){ - z++; - } - return (*z)!=0; - } - while( (c2 = (*(z++)))!=0 ){ - while( c2!=c ){ - c2 = *(z++); - if( c2==0 ) return 0; - } - if( speedtest1_strglob(zGlob,z) ) return 1; - } - return 0; - }else if( c=='?' ){ - if( (*(z++))==0 ) return 0; - }else if( c=='[' ){ - int prior_c = 0; - seen = 0; - invert = 0; - c = *(z++); - if( c==0 ) return 0; - c2 = *(zGlob++); - if( c2=='^' ){ - invert = 1; - c2 = *(zGlob++); - } - if( c2==']' ){ - if( c==']' ) seen = 1; - c2 = *(zGlob++); - } - while( c2 && c2!=']' ){ - if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ - c2 = *(zGlob++); - if( c>=prior_c && c<=c2 ) seen = 1; - prior_c = 0; - }else{ - if( c==c2 ){ - seen = 1; - } - prior_c = c2; - } - c2 = *(zGlob++); - } - if( c2==0 || (seen ^ invert)==0 ) return 0; - }else if( c=='#' ){ - if( (z[0]=='-' || z[0]=='+') && isdigit(z[1]) ) z++; - if( !isdigit(z[0]) ) return 0; - z++; - while( isdigit(z[0]) ){ z++; } - }else{ - if( c!=(*(z++)) ) return 0; - } - } - return *z==0; +/* Print an error message and exit */ +static void fatal_error(const char *zMsg, ...){ + va_list ap; + va_start(ap, zMsg); + vfprintf(stderr, zMsg, ap); + va_end(ap); + exit(1); } /* @@ -158,7 +82,7 @@ static int hexDigitValue(char c){ /* ** Interpret zArg as an integer value, possibly with suffixes. */ -static sqlite3_int64 integerValue(const char *zArg){ +static int integerValue(const char *zArg){ sqlite3_int64 v = 0; static const struct { char *zSuffix; int iMult; } aMult[] = { { "KiB", 1024 }, @@ -198,6 +122,7 @@ static sqlite3_int64 integerValue(const char *zArg){ break; } } + if( v>=2147483648 ) fatal_error("parameter to large - max 2147483648"); return isNeg? -v : v; } @@ -356,15 +281,6 @@ void speedtest1_final(void){ } } -/* Print an error message and exit */ -static void fatal_error(const char *zMsg, ...){ - va_list ap; - va_start(ap, zMsg); - vfprintf(stderr, zMsg, ap); - va_end(ap); - exit(1); -} - /* Run SQL */ void speedtest1_exec(const char *zFormat, ...){ va_list ap; @@ -800,6 +716,7 @@ int main(int argc, char **argv){ int noSync = 0; /* True for --nosync */ int pageSize = 0; /* Desired page size. 0 means default */ int nPCache = 0, szPCache = 0;/* --pcache configuration */ + int nScratch = 0, szScratch=0;/* --scratch configuration */ int showStats = 0; /* True for --stats */ const char *zTSet = "main"; /* Which --testset torun */ int doTrace = 0; /* True for --trace */ @@ -809,6 +726,7 @@ int main(int argc, char **argv){ void *pHeap = 0; /* Allocated heap space */ void *pLook = 0; /* Allocated lookaside space */ void *pPCache = 0; /* Allocated storage for pcache */ + void *pScratch = 0; /* Allocated storage for scratch */ int iCur, iHi; /* Stats values, current and "highwater" */ int i; /* Loop counter */ int rc; /* API return code */ @@ -827,13 +745,13 @@ int main(int argc, char **argv){ }else if( strcmp(z,"cachesize")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); i++; - cacheSize = (int)integerValue(argv[i]); + cacheSize = integerValue(argv[i]); }else if( strcmp(z,"exclusive")==0 ){ doExclusive = 1; }else if( strcmp(z,"heap")==0 ){ if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); - nHeap = (int)integerValue(argv[i+1]); - mnHeap = (int)integerValue(argv[i+2]); + nHeap = integerValue(argv[i+1]); + mnHeap = integerValue(argv[i+2]); i += 2; }else if( strcmp(z,"incrvacuum")==0 ){ doIncrvac = 1; @@ -845,8 +763,8 @@ int main(int argc, char **argv){ zKey = argv[++i]; }else if( strcmp(z,"lookaside")==0 ){ if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); - nLook = (int)integerValue(argv[i+1]); - szLook = (int)integerValue(argv[i+2]); + nLook = integerValue(argv[i+1]); + szLook = integerValue(argv[i+2]); i += 2; }else if( strcmp(z,"nosync")==0 ){ noSync = 1; @@ -854,21 +772,26 @@ int main(int argc, char **argv){ g.zNN = "NOT NULL"; }else if( strcmp(z,"pagesize")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); - pageSize = (int)integerValue(argv[++i]); + pageSize = integerValue(argv[++i]); }else if( strcmp(z,"pcache")==0 ){ if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); - nPCache = (int)integerValue(argv[i+1]); - szPCache = (int)integerValue(argv[i+2]); + nPCache = integerValue(argv[i+1]); + szPCache = integerValue(argv[i+2]); i += 2; }else if( strcmp(z,"primarykey")==0 ){ g.zPK = "PRIMARY KEY"; }else if( strcmp(z,"reprepare")==0 ){ g.bReprepare = 1; + }else if( strcmp(z,"scratch")==0 ){ + if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]); + nScratch = integerValue(argv[i+1]); + szScratch = integerValue(argv[i+2]); + i += 2; }else if( strcmp(z,"sqlonly")==0 ){ g.bSqlOnly = 1; }else if( strcmp(z,"size")==0 ){ if( i>=argc-1 ) fatal_error("missing argument on %s\n", argv[i]); - g.szTest = (int)integerValue(argv[++i]); + g.szTest = integerValue(argv[++i]); }else if( strcmp(z,"stats")==0 ){ showStats = 1; }else if( strcmp(z,"testset")==0 ){ @@ -909,12 +832,19 @@ int main(int argc, char **argv){ if( rc ) fatal_error("heap configuration failed: %d\n", rc); } if( nPCache>0 && szPCache>0 ){ - pPCache = malloc( nPCache*szPCache ); - if( pPCache==0 ) fatal_error("cannot allocate %d-byte pcache\n", - nPCache*szPCache); + pPCache = malloc( nPCache*(sqlite3_int64)szPCache ); + if( pPCache==0 ) fatal_error("cannot allocate %lld-byte pcache\n", + nPCache*(sqlite3_int64)szPCache); rc = sqlite3_config(SQLITE_CONFIG_PAGECACHE, pPCache, szPCache, nPCache); if( rc ) fatal_error("pcache configuration failed: %d\n", rc); } + if( nScratch>0 && szScratch>0 ){ + pScratch = malloc( nScratch*(sqlite3_int64)szScratch ); + if( pScratch==0 ) fatal_error("cannot allocate %lld-byte scratch\n", + nScratch*(sqlite3_int64)szScratch); + rc = sqlite3_config(SQLITE_CONFIG_SCRATCH, pScratch, szScratch, nScratch); + if( rc ) fatal_error("scratch configuration failed: %d\n", rc); + } if( nLook>0 ){ sqlite3_config(SQLITE_CONFIG_LOOKASIDE, 0, 0); } @@ -1015,6 +945,7 @@ int main(int argc, char **argv){ /* Release memory */ free( pLook ); free( pPCache ); + free( pScratch ); free( pHeap ); return 0; } From 5bbb7198d11b3a4f29615f54422ea4ef8cd6dae0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sun, 24 Nov 2013 23:18:21 +0000 Subject: [PATCH 64/78] Better support for UTF-8 paths on Cygwin. FossilOrigin-Name: 484162b6e5a8ad9385fe2eb2a5254d13d7b0bc36 --- manifest | 17 ++++++++------ manifest.uuid | 2 +- src/os_win.c | 62 +++++++++++++++++++++++++++++++++------------------ 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/manifest b/manifest index aa2b98cdb9..2eea06db7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--scratch\sparameter\sto\sspeedtest1.\s\sImproved\serror\smessages\swhen\nmisconfiguring\smemory\sparameters\sin\sspeedtest1. -D 2013-11-24T01:14:14.123 +C Better\ssupport\sfor\sUTF-8\spaths\son\sCygwin. +D 2013-11-24T23:18:21.299 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -206,7 +206,7 @@ F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_unix.c 143624d9eabb3b997c59cf594e0d06c56edd43e9 -F src/os_win.c ef091b347d682cb24fc575ac9a6290341af62e2b +F src/os_win.c 1f7cc110551cb8045c2ca7d41ac42e2afa787d56 F src/pager.c 2aa4444ffe86e9282d03bc349a4a5e49bd77c0e8 F src/pager.h f094af9f6ececfaa8a1e93876905a4f34233fb0c F src/parse.y acee1a9958539e21263362b194594c5255ad2fca @@ -1142,7 +1142,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 12e612e8e7c4a6f83acf0daf5608151fb5ec1575 -R d231270eb8540c71c1fe43ad7f945ecf -U drh -Z 904197ecb3cb4ac430a652007d0a071c +P 8f3c767a30c552548ead104ca125f182ce4849ad +R cc715e8459c64ceb8b095c6997a4f82b +T *branch * cygUtf8 +T *sym-cygUtf8 * +T -sym-trunk * +U mistachkin +Z 13c3d5cd43d3e5bbf57c7a19839f68ff diff --git a/manifest.uuid b/manifest.uuid index 7967f97b83..278a780b58 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f3c767a30c552548ead104ca125f182ce4849ad \ No newline at end of file +484162b6e5a8ad9385fe2eb2a5254d13d7b0bc36 \ No newline at end of file diff --git a/src/os_win.c b/src/os_win.c index a2f5513a2b..4f255bd1b5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -4068,7 +4068,7 @@ static const sqlite3_io_methods winIoMethod = { ** sqlite3_vfs object. */ -#if 0 +#if defined(__CYGWIN__) /* ** Convert a filename from whatever the underlying operating system ** supports for filenames into UTF-8. Space to hold the result is @@ -4244,23 +4244,17 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ ** be used. However, we may need to convert the string containing ** its name into UTF-8 (i.e. if it is UTF-16 right now). */ - if( osIsNT() ){ - char *zUtf8 = winUnicodeToUtf8(zConverted); - if( !zUtf8 ){ - sqlite3_free(zConverted); - sqlite3_free(zBuf); - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); - return SQLITE_IOERR_NOMEM; - } - sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); - sqlite3_free(zUtf8); + char *zUtf8 = winConvertToUtf8Filename(zConverted); + if( !zUtf8 ){ sqlite3_free(zConverted); - break; - }else{ - sqlite3_snprintf(nMax, zBuf, "%s", zConverted); - sqlite3_free(zConverted); - break; + sqlite3_free(zBuf); + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); + return SQLITE_IOERR_NOMEM; } + sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zConverted); + break; } sqlite3_free(zConverted); } @@ -4945,19 +4939,43 @@ static int winFullPathname( if( !zOut ){ return SQLITE_IOERR_NOMEM; } - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, - pVfs->mxPathname+1)<0 ){ + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ sqlite3_free(zOut); return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname1", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); } - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - sqlite3_data_directory, winGetDirSep(), zOut); - sqlite3_free(zOut); }else{ - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); + if( !zOut ){ + return SQLITE_IOERR_NOMEM; + } + if( cygwin_conv_path( + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), + zRelative, zOut, pVfs->mxPathname+1)<0 ){ + sqlite3_free(zOut); return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname2", zRelative); + }else{ + char *zUtf8 = winConvertToUtf8Filename(zOut); + if( !zUtf8 ){ + sqlite3_free(zOut); + return SQLITE_IOERR_NOMEM; + } + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); } } return SQLITE_OK; From ec3e6b10f4d4de914b116e365636a8ec934caaed Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 02:38:55 +0000 Subject: [PATCH 65/78] Performance improvements in sqlite3BtreeMovetoUnpacked(). FossilOrigin-Name: d0fb7acea7cbfe6f2d84782a28bb51675a06576f --- manifest | 15 ++++++---- manifest.uuid | 2 +- src/btree.c | 77 +++++++++++++++++++++++++++------------------------ 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/manifest b/manifest index aa2b98cdb9..4b817f5f32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--scratch\sparameter\sto\sspeedtest1.\s\sImproved\serror\smessages\swhen\nmisconfiguring\smemory\sparameters\sin\sspeedtest1. -D 2013-11-24T01:14:14.123 +C Performance\simprovements\sin\ssqlite3BtreeMovetoUnpacked(). +D 2013-11-25T02:38:55.810 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 17ca5729d07ba03f81633aab56de87956d9b188a +F src/btree.c b0fd869c044bbf29640b9e53c43d8846a929d7f4 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,7 +1142,10 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 12e612e8e7c4a6f83acf0daf5608151fb5ec1575 -R d231270eb8540c71c1fe43ad7f945ecf +P 8f3c767a30c552548ead104ca125f182ce4849ad +R c168ba651eff475cfa32f75aa61b62eb +T *branch * btree-optimization +T *sym-btree-optimization * +T -sym-trunk * U drh -Z 904197ecb3cb4ac430a652007d0a071c +Z f59a524da90eada9da104b9026589d30 diff --git a/manifest.uuid b/manifest.uuid index 7967f97b83..0597b2d1cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f3c767a30c552548ead104ca125f182ce4849ad \ No newline at end of file +d0fb7acea7cbfe6f2d84782a28bb51675a06576f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2a5b45e5c6..a21b72a0da 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4647,10 +4647,10 @@ int sqlite3BtreeMovetoUnpacked( } assert( pCur->apPage[0]->intKey || pIdxKey ); for(;;){ - int lwr, upr, idx; + int lwr, upr, idx, c; Pgno chldPg; MemPage *pPage = pCur->apPage[pCur->iPage]; - int c; + u8 *pCell; /* Pointer to current cell in pPage */ /* pPage->nCell must be greater than zero. If this is the root-page ** the cursor would have been INVALID above and this for(;;) loop @@ -4667,30 +4667,45 @@ int sqlite3BtreeMovetoUnpacked( }else{ pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); } - for(;;){ - u8 *pCell; /* Pointer to current cell in pPage */ - + pCur->info.nSize = 0; + if( pPage->intKey ){ assert( idx==pCur->aiIdx[pCur->iPage] ); - pCur->info.nSize = 0; - pCell = findCell(pPage, idx) + pPage->childPtrSize; - if( pPage->intKey ){ + for(;;){ i64 nCellKey; + pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->hasData ){ u32 dummy; pCell += getVarint32(pCell, dummy); } getVarint(pCell, (u64*)&nCellKey); if( nCellKey==intKey ){ - c = 0; + pCur->validNKey = 1; + pCur->info.nKey = nCellKey; + if( !pPage->leaf ){ + lwr = idx; + break; + }else{ + *pRes = 0; + rc = SQLITE_OK; + goto moveto_finish; + } }else if( nCellKeyintKey ); c = +1; + upr = idx-1; } - pCur->validNKey = 1; - pCur->info.nKey = nCellKey; - }else{ + if( lwr>upr ) break; + pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); + } + }else{ + for(;;){ + int nCell; + assert( idx==pCur->aiIdx[pCur->iPage] ); + pCell = findCell(pPage, idx) + pPage->childPtrSize; + /* The maximum supported page-size is 65536 bytes. This means that ** the maximum number of record bytes stored on an index B-Tree ** page is less than 16384 bytes and may be stored as a 2-byte @@ -4699,7 +4714,7 @@ int sqlite3BtreeMovetoUnpacked( ** stored entirely within the b-tree page by inspecting the first ** 2 bytes of the cell. */ - int nCell = pCell[0]; + nCell = pCell[0]; if( nCell<=pPage->max1bytePayload /* && (pCell+nCell)aDataEnd */ ){ @@ -4738,47 +4753,37 @@ int sqlite3BtreeMovetoUnpacked( c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); sqlite3_free(pCellKey); } - } - if( c==0 ){ - if( pPage->intKey && !pPage->leaf ){ - lwr = idx; - break; - }else{ + if( c==0 ){ *pRes = 0; rc = SQLITE_OK; goto moveto_finish; } + if( c<0 ){ + lwr = idx+1; + }else{ + upr = idx-1; + } + if( lwr>upr ) break; + pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); } - if( c<0 ){ - lwr = idx+1; - }else{ - upr = idx-1; - } - if( lwr>upr ){ - break; - } - pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); } assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - chldPg = 0; + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + *pRes = c; + rc = SQLITE_OK; + goto moveto_finish; }else if( lwr>=pPage->nCell ){ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); }else{ chldPg = get4byte(findCell(pPage, lwr)); } - if( chldPg==0 ){ - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - *pRes = c; - rc = SQLITE_OK; - goto moveto_finish; - } pCur->aiIdx[pCur->iPage] = (u16)lwr; pCur->info.nSize = 0; pCur->validNKey = 0; rc = moveToChild(pCur, chldPg); - if( rc ) goto moveto_finish; + if( rc ) break; } moveto_finish: return rc; From d793f447239133ce56d36d54a00274776d2ddd34 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 14:10:15 +0000 Subject: [PATCH 66/78] More improvements to sqlite3BtreeMovetoUnpacked() performance. FossilOrigin-Name: 88680698231b7141401f7166e3aff8dbc6008030 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/btree.c | 29 ++++++++++++++++------------- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 4b817f5f32..d384b8ea6f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\simprovements\sin\ssqlite3BtreeMovetoUnpacked(). -D 2013-11-25T02:38:55.810 +C More\simprovements\sto\ssqlite3BtreeMovetoUnpacked()\sperformance. +D 2013-11-25T14:10:15.692 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c b0fd869c044bbf29640b9e53c43d8846a929d7f4 +F src/btree.c c300cb68948a03f0049addddd9e36f28551e78ae F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,10 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8f3c767a30c552548ead104ca125f182ce4849ad -R c168ba651eff475cfa32f75aa61b62eb -T *branch * btree-optimization -T *sym-btree-optimization * -T -sym-trunk * +P d0fb7acea7cbfe6f2d84782a28bb51675a06576f +R 29c1330ebdfb45d969bc6dbf6661ccf0 U drh -Z f59a524da90eada9da104b9026589d30 +Z d111eff6e7e1e09087be24d32976d9d6 diff --git a/manifest.uuid b/manifest.uuid index 0597b2d1cd..8226805b12 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0fb7acea7cbfe6f2d84782a28bb51675a06576f \ No newline at end of file +88680698231b7141401f7166e3aff8dbc6008030 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a21b72a0da..dd397d6d0e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4662,14 +4662,10 @@ int sqlite3BtreeMovetoUnpacked( assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; - if( biasRight ){ - pCur->aiIdx[pCur->iPage] = (u16)(idx = upr); - }else{ - pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2); - } + idx = biasRight ? upr : (upr+lwr)/2; + pCur->aiIdx[pCur->iPage] = (u16)idx; pCur->info.nSize = 0; if( pPage->intKey ){ - assert( idx==pCur->aiIdx[pCur->iPage] ); for(;;){ i64 nCellKey; pCell = findCell(pPage, idx) + pPage->childPtrSize; @@ -4681,6 +4677,7 @@ int sqlite3BtreeMovetoUnpacked( if( nCellKey==intKey ){ pCur->validNKey = 1; pCur->info.nKey = nCellKey; + pCur->aiIdx[pCur->iPage] = (u16)idx; if( !pPage->leaf ){ lwr = idx; break; @@ -4690,20 +4687,21 @@ int sqlite3BtreeMovetoUnpacked( goto moveto_finish; } }else if( nCellKeyintKey ); - c = +1; upr = idx-1; } - if( lwr>upr ) break; - pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); + if( lwr>upr ){ + c = nCellKeyaiIdx[pCur->iPage] = (u16)idx; + break; + } + idx = (lwr+upr)/2; } }else{ for(;;){ int nCell; - assert( idx==pCur->aiIdx[pCur->iPage] ); pCell = findCell(pPage, idx) + pPage->childPtrSize; /* The maximum supported page-size is 65536 bytes. This means that @@ -4745,6 +4743,7 @@ int sqlite3BtreeMovetoUnpacked( rc = SQLITE_NOMEM; goto moveto_finish; } + pCur->aiIdx[pCur->iPage] = (u16)idx; rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); if( rc ){ sqlite3_free(pCellKey); @@ -4756,6 +4755,7 @@ int sqlite3BtreeMovetoUnpacked( if( c==0 ){ *pRes = 0; rc = SQLITE_OK; + pCur->aiIdx[pCur->iPage] = (u16)idx; goto moveto_finish; } if( c<0 ){ @@ -4763,8 +4763,11 @@ int sqlite3BtreeMovetoUnpacked( }else{ upr = idx-1; } - if( lwr>upr ) break; - pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2); + if( lwr>upr ){ + pCur->aiIdx[pCur->iPage] = (u16)idx; + break; + } + idx = (lwr+upr)/2; } } assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); From bb933ef6e717345c3f803ef140aa743a461abcd0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 15:01:38 +0000 Subject: [PATCH 67/78] More optimizations to sqlite3BtreeMovetoUnpacked(). But there are failures in TH3. Committing this intermediate state to facilitate bisecting. FossilOrigin-Name: f80497be446f84d2000e454e32d717887a7d0cee --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 36 +++++++++++++++++------------------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index d384b8ea6f..8ae6d90150 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\simprovements\sto\ssqlite3BtreeMovetoUnpacked()\sperformance. -D 2013-11-25T14:10:15.692 +C More\soptimizations\sto\ssqlite3BtreeMovetoUnpacked().\s\sBut\sthere\sare\sfailures\nin\sTH3.\s\sCommitting\sthis\sintermediate\sstate\sto\sfacilitate\sbisecting. +D 2013-11-25T15:01:38.218 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c c300cb68948a03f0049addddd9e36f28551e78ae +F src/btree.c 7459c164e26b1dca39d439186a4cf8328e0ffb1f F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P d0fb7acea7cbfe6f2d84782a28bb51675a06576f -R 29c1330ebdfb45d969bc6dbf6661ccf0 +P 88680698231b7141401f7166e3aff8dbc6008030 +R a02e2482a947ddc5fc2d75dda36e99fc U drh -Z d111eff6e7e1e09087be24d32976d9d6 +Z 1dd2b4d4fc066dfd776d99dd8b11e059 diff --git a/manifest.uuid b/manifest.uuid index 8226805b12..133c7ea1ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88680698231b7141401f7166e3aff8dbc6008030 \ No newline at end of file +f80497be446f84d2000e454e32d717887a7d0cee \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dd397d6d0e..26ef64f61d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4662,7 +4662,7 @@ int sqlite3BtreeMovetoUnpacked( assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; - idx = biasRight ? upr : (upr+lwr)/2; + idx = biasRight ? upr : upr/2; pCur->aiIdx[pCur->iPage] = (u16)idx; pCur->info.nSize = 0; if( pPage->intKey ){ @@ -4674,28 +4674,26 @@ int sqlite3BtreeMovetoUnpacked( pCell += getVarint32(pCell, dummy); } getVarint(pCell, (u64*)&nCellKey); - if( nCellKey==intKey ){ + if( nCellKeyupr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); pCur->validNKey = 1; pCur->info.nKey = nCellKey; pCur->aiIdx[pCur->iPage] = (u16)idx; if( !pPage->leaf ){ lwr = idx; + c = 0; break; }else{ *pRes = 0; rc = SQLITE_OK; goto moveto_finish; } - }else if( nCellKeyintKey ); - upr = idx-1; - } - if( lwr>upr ){ - c = nCellKeyaiIdx[pCur->iPage] = (u16)idx; - break; } idx = (lwr+upr)/2; } @@ -4752,19 +4750,18 @@ int sqlite3BtreeMovetoUnpacked( c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); sqlite3_free(pCellKey); } - if( c==0 ){ + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); *pRes = 0; rc = SQLITE_OK; pCur->aiIdx[pCur->iPage] = (u16)idx; goto moveto_finish; } - if( c<0 ){ - lwr = idx+1; - }else{ - upr = idx-1; - } if( lwr>upr ){ - pCur->aiIdx[pCur->iPage] = (u16)idx; break; } idx = (lwr+upr)/2; @@ -4774,6 +4771,7 @@ int sqlite3BtreeMovetoUnpacked( assert( pPage->isInit ); if( pPage->leaf ){ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + pCur->aiIdx[pCur->iPage] = (u16)idx; *pRes = c; rc = SQLITE_OK; goto moveto_finish; From d2022b01186b099d888d36a5b3461d22e55b92e0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 16:23:52 +0000 Subject: [PATCH 68/78] Arrange for sqlite3BtreeMovetoUnpacked() to always leave the cursor cell parse cache invalidated. This fixes issues with previous check-ins on this branch and also runs faster. FossilOrigin-Name: a74675607fe041e37a58a3ec287131de0e5090c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 8ae6d90150..c59e49eba0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\soptimizations\sto\ssqlite3BtreeMovetoUnpacked().\s\sBut\sthere\sare\sfailures\nin\sTH3.\s\sCommitting\sthis\sintermediate\sstate\sto\sfacilitate\sbisecting. -D 2013-11-25T15:01:38.218 +C Arrange\sfor\ssqlite3BtreeMovetoUnpacked()\sto\salways\sleave\sthe\scursor\scell\nparse\scache\sinvalidated.\s\sThis\sfixes\sissues\swith\sprevious\scheck-ins\son\sthis\nbranch\sand\salso\sruns\sfaster. +D 2013-11-25T16:23:52.282 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 7459c164e26b1dca39d439186a4cf8328e0ffb1f +F src/btree.c 0ce10b29df09e9277448157fafb2a254468f9782 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 88680698231b7141401f7166e3aff8dbc6008030 -R a02e2482a947ddc5fc2d75dda36e99fc +P f80497be446f84d2000e454e32d717887a7d0cee +R 2fbc978380b3acf1d85deca4d19cdeda U drh -Z 1dd2b4d4fc066dfd776d99dd8b11e059 +Z f2ec119e1c1685944c58208d97a35f8b diff --git a/manifest.uuid b/manifest.uuid index 133c7ea1ad..64946ffe1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f80497be446f84d2000e454e32d717887a7d0cee \ No newline at end of file +a74675607fe041e37a58a3ec287131de0e5090c3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 26ef64f61d..414933f9df 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4219,7 +4219,7 @@ static const unsigned char *fetchPayload( assert( cursorHoldsMutex(pCur) ); pPage = pCur->apPage[pCur->iPage]; assert( pCur->aiIdx[pCur->iPage]nCell ); - if( NEVER(pCur->info.nSize==0) ){ + if( pCur->info.nSize==0 ){ btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], &pCur->info); } @@ -4664,7 +4664,7 @@ int sqlite3BtreeMovetoUnpacked( upr = pPage->nCell-1; idx = biasRight ? upr : upr/2; pCur->aiIdx[pCur->iPage] = (u16)idx; - pCur->info.nSize = 0; +// pCur->info.nSize = 0; if( pPage->intKey ){ for(;;){ i64 nCellKey; @@ -4781,12 +4781,12 @@ int sqlite3BtreeMovetoUnpacked( chldPg = get4byte(findCell(pPage, lwr)); } pCur->aiIdx[pCur->iPage] = (u16)lwr; - pCur->info.nSize = 0; - pCur->validNKey = 0; rc = moveToChild(pCur, chldPg); if( rc ) break; } moveto_finish: + pCur->info.nSize = 0; + pCur->validNKey = 0; return rc; } From 17566ee243f3e7cb952c8d5e8bb87abc5332cb39 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 16:52:59 +0000 Subject: [PATCH 69/78] Optimize the skipping of the payload size field when doing a binary search for a rowid. FossilOrigin-Name: 55e5bfa231dd52a7cf9ec982967da4963867b9e5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c59e49eba0..c632c86ab1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Arrange\sfor\ssqlite3BtreeMovetoUnpacked()\sto\salways\sleave\sthe\scursor\scell\nparse\scache\sinvalidated.\s\sThis\sfixes\sissues\swith\sprevious\scheck-ins\son\sthis\nbranch\sand\salso\sruns\sfaster. -D 2013-11-25T16:23:52.282 +C Optimize\sthe\sskipping\sof\sthe\spayload\ssize\sfield\swhen\sdoing\sa\sbinary\ssearch\nfor\sa\srowid. +D 2013-11-25T16:52:59.279 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c 0ce10b29df09e9277448157fafb2a254468f9782 +F src/btree.c fc03d3fd338fa66f27160155068a7be3d96c7f8d F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f80497be446f84d2000e454e32d717887a7d0cee -R 2fbc978380b3acf1d85deca4d19cdeda +P a74675607fe041e37a58a3ec287131de0e5090c3 +R d1af21a766586cae5be9dafc0442ac2b U drh -Z f2ec119e1c1685944c58208d97a35f8b +Z a809a2735916d723ee7af54e8adbc7b8 diff --git a/manifest.uuid b/manifest.uuid index 64946ffe1a..6f9576364b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a74675607fe041e37a58a3ec287131de0e5090c3 \ No newline at end of file +55e5bfa231dd52a7cf9ec982967da4963867b9e5 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 414933f9df..6d8934d608 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4664,14 +4664,12 @@ int sqlite3BtreeMovetoUnpacked( upr = pPage->nCell-1; idx = biasRight ? upr : upr/2; pCur->aiIdx[pCur->iPage] = (u16)idx; -// pCur->info.nSize = 0; if( pPage->intKey ){ for(;;){ i64 nCellKey; pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->hasData ){ - u32 dummy; - pCell += getVarint32(pCell, dummy); + while( 0x80 <= *(pCell++) && pCellaDataEnd ){} } getVarint(pCell, (u64*)&nCellKey); if( nCellKey Date: Mon, 25 Nov 2013 17:38:26 +0000 Subject: [PATCH 70/78] Uses shifts rather than division for arithmetic on the cell indices, since those indices are always non-negative. FossilOrigin-Name: 5bf2a3feeb2c83671bf3edeb20a549239e6873bf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 20 +++++++++++--------- src/vdbe.c | 2 +- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c632c86ab1..d7c9c5a901 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\sthe\sskipping\sof\sthe\spayload\ssize\sfield\swhen\sdoing\sa\sbinary\ssearch\nfor\sa\srowid. -D 2013-11-25T16:52:59.279 +C Uses\sshifts\srather\sthan\sdivision\sfor\sarithmetic\son\sthe\scell\sindices,\ssince\nthose\sindices\sare\salways\snon-negative. +D 2013-11-25T17:38:26.358 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c fc03d3fd338fa66f27160155068a7be3d96c7f8d +F src/btree.c f98e6ceada5953859d13848cb3139d248e0ad2e6 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -280,7 +280,7 @@ F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 4d637218b7ffcc76fdcf461c71d277e7a4250e74 +F src/vdbe.c 23d0cfba65b6dadf39a0805d0fba266e8146d678 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P a74675607fe041e37a58a3ec287131de0e5090c3 -R d1af21a766586cae5be9dafc0442ac2b +P 55e5bfa231dd52a7cf9ec982967da4963867b9e5 +R 03a0908b80603703a94d0f74a79b1f34 U drh -Z a809a2735916d723ee7af54e8adbc7b8 +Z 8e81fe7c02afd074478ec63871f47a2f diff --git a/manifest.uuid b/manifest.uuid index 6f9576364b..96f416d29c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55e5bfa231dd52a7cf9ec982967da4963867b9e5 \ No newline at end of file +5bf2a3feeb2c83671bf3edeb20a549239e6873bf \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6d8934d608..abe104242f 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4662,7 +4662,8 @@ int sqlite3BtreeMovetoUnpacked( assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; - idx = biasRight ? upr : upr/2; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ pCur->aiIdx[pCur->iPage] = (u16)idx; if( pPage->intKey ){ for(;;){ @@ -4685,15 +4686,15 @@ int sqlite3BtreeMovetoUnpacked( pCur->aiIdx[pCur->iPage] = (u16)idx; if( !pPage->leaf ){ lwr = idx; - c = 0; - break; + goto moveto_next_layer; }else{ *pRes = 0; rc = SQLITE_OK; goto moveto_finish; } } - idx = (lwr+upr)/2; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ } }else{ for(;;){ @@ -4759,10 +4760,9 @@ int sqlite3BtreeMovetoUnpacked( pCur->aiIdx[pCur->iPage] = (u16)idx; goto moveto_finish; } - if( lwr>upr ){ - break; - } - idx = (lwr+upr)/2; + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ } } assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); @@ -4773,7 +4773,9 @@ int sqlite3BtreeMovetoUnpacked( *pRes = c; rc = SQLITE_OK; goto moveto_finish; - }else if( lwr>=pPage->nCell ){ + } +moveto_next_layer: + if( lwr>=pPage->nCell ){ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); }else{ chldPg = get4byte(findCell(pPage, lwr)); diff --git a/src/vdbe.c b/src/vdbe.c index b45b71af18..f8e95f6399 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4075,7 +4075,7 @@ case OP_InsertInt: { sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey, pData->z, pData->n, nZero, - pOp->p5 & OPFLAG_APPEND, seekResult + (pOp->p5 & OPFLAG_APPEND)!=0, seekResult ); pC->rowidIsValid = 0; pC->deferredMoveto = 0; From 9b2fc61d25072edd6abce3a90255d5be95c6b8f4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 20:14:13 +0000 Subject: [PATCH 71/78] Return an SQLITE_CORRUPT error if the content size field of a table record extends off the end of a page. FossilOrigin-Name: b48c4e402125fb8d2208d358f6e9bbc351f3a49d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7c9c5a901..356b49fd43 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Uses\sshifts\srather\sthan\sdivision\sfor\sarithmetic\son\sthe\scell\sindices,\ssince\nthose\sindices\sare\salways\snon-negative. -D 2013-11-25T17:38:26.358 +C Return\san\sSQLITE_CORRUPT\serror\sif\sthe\scontent\ssize\sfield\sof\sa\stable\srecord\nextends\soff\sthe\send\sof\sa\spage. +D 2013-11-25T20:14:13.468 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c f98e6ceada5953859d13848cb3139d248e0ad2e6 +F src/btree.c c308e64d89de5ea87e5538f7380af4477892e067 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 55e5bfa231dd52a7cf9ec982967da4963867b9e5 -R 03a0908b80603703a94d0f74a79b1f34 +P 5bf2a3feeb2c83671bf3edeb20a549239e6873bf +R 5bcbc7e134df92bc8848f497a4ca3642 U drh -Z 8e81fe7c02afd074478ec63871f47a2f +Z d267e18bd1e4ed89c545a37f1e6bffd5 diff --git a/manifest.uuid b/manifest.uuid index 96f416d29c..6967dda00d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bf2a3feeb2c83671bf3edeb20a549239e6873bf \ No newline at end of file +b48c4e402125fb8d2208d358f6e9bbc351f3a49d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index abe104242f..eff211333c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4219,7 +4219,7 @@ static const unsigned char *fetchPayload( assert( cursorHoldsMutex(pCur) ); pPage = pCur->apPage[pCur->iPage]; assert( pCur->aiIdx[pCur->iPage]nCell ); - if( pCur->info.nSize==0 ){ + if( NEVER(pCur->info.nSize==0) ){ btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], &pCur->info); } @@ -4670,7 +4670,9 @@ int sqlite3BtreeMovetoUnpacked( i64 nCellKey; pCell = findCell(pPage, idx) + pPage->childPtrSize; if( pPage->hasData ){ - while( 0x80 <= *(pCell++) && pCellaDataEnd ){} + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT; + } } getVarint(pCell, (u64*)&nCellKey); if( nCellKey Date: Mon, 25 Nov 2013 21:41:24 +0000 Subject: [PATCH 72/78] Remove a NEVER() from a branch that is now reachable during OOM faults. FossilOrigin-Name: 18bdcb05c26860643f53a6b9e85f84109a3ebe5a --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c28e8a7063..efb60bfaa3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\sthe\ssqlite3BtreeMovetoUnpacked()\sroutine\sin\sstorage\sengine\nmaking\sit\sabout\s17.8%\sfaster,\swhich\sin\sturn\smakes\sSQLite\sover\s1.2%\sfaster\noverall. -D 2013-11-25T20:50:23.619 +C Remove\sa\sNEVER()\sfrom\sa\sbranch\sthat\sis\snow\sreachable\sduring\sOOM\sfaults. +D 2013-11-25T21:41:24.083 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -166,7 +166,7 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34 F src/backup.c 1809a7caa2504233bdddd12f5018422421789537 F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 -F src/btree.c c308e64d89de5ea87e5538f7380af4477892e067 +F src/btree.c ec8a4dcac5c1ec1ba9705b8c5a13e62167958317 F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9 F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0 F src/build.c 07054d45319953e54a89d726e589a423e9c1c590 @@ -1142,8 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 8f3c767a30c552548ead104ca125f182ce4849ad b48c4e402125fb8d2208d358f6e9bbc351f3a49d -R 5bcbc7e134df92bc8848f497a4ca3642 -T +closed b48c4e402125fb8d2208d358f6e9bbc351f3a49d +P 032e89934f36de10652d3454a0065a337827221a +R 542bd751b886b00603f8e8e48c8170e2 U drh -Z 31605b8bf42e4d96e843b4f7dc30f0f2 +Z 7e8a0ac6a68793100fecd3fb349d5622 diff --git a/manifest.uuid b/manifest.uuid index 1836affbb0..287b09b299 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -032e89934f36de10652d3454a0065a337827221a \ No newline at end of file +18bdcb05c26860643f53a6b9e85f84109a3ebe5a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index eff211333c..27e7146893 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4219,7 +4219,7 @@ static const unsigned char *fetchPayload( assert( cursorHoldsMutex(pCur) ); pPage = pCur->apPage[pCur->iPage]; assert( pCur->aiIdx[pCur->iPage]nCell ); - if( NEVER(pCur->info.nSize==0) ){ + if( pCur->info.nSize==0 ){ btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], &pCur->info); } From af8641bd456f48f4dce54ce2303ac0cdb551ce41 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Mon, 25 Nov 2013 21:49:04 +0000 Subject: [PATCH 73/78] Clarify docs for the SQLITE_CONFIG_WIN32_HEAPSIZE option. FossilOrigin-Name: 51e876074af4e34ba01ed122e3bcc042243c9e88 --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/main.c | 2 +- src/sqlite.h.in | 10 +++++----- src/test_malloc.c | 2 +- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index cdad278b03..3a3f1ec7e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\ssqlite3_config\soption\sto\scontrol\sthe\snative\sWin32\sheap\ssize. -D 2013-11-23T00:27:29.844 +C Clarify\sdocs\sfor\sthe\sSQLITE_CONFIG_WIN32_HEAPSIZE\soption. +D 2013-11-25T21:49:04.683 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -188,7 +188,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 68e5b72cc2cdc2a0101c3bf7a1112fc39a4c6441 +F src/main.c 441a2e106d0e2913fec47e5f13d5802c742e32bb F src/malloc.c 543a8eb5508eaf4cadf55a9b503379eba2088128 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -221,7 +221,7 @@ F src/resolve.c a70e32ae6ccb7b780f2b6d3e9e21837affc25ee5 F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0 F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a F src/shell.c c4d06a9238a515ff4bc86b8626139633c09a00a2 -F src/sqlite.h.in 1399855c547dbe3cbc556f5423067834e0945b88 +F src/sqlite.h.in a63edec76cca981ce859b5cfa4776121b7a113e5 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 @@ -253,7 +253,7 @@ F src/test_intarray.c 87847c71c3c36889c0bcc9c4baf9d31881665d61 F src/test_intarray.h 2ece66438cfd177b78d1bfda7a4180cd3a10844d F src/test_journal.c f5c0a05b7b3d5930db769b5ee6c3766dc2221a64 F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e -F src/test_malloc.c eec5258da8ca468e3165bfa5e2e4461fe08ed385 +F src/test_malloc.c 1ff5b1243d96124c9a180f3b89424820a1f337f3 F src/test_multiplex.c 9f304bf04170c91c0318238d512df2da039eb1c8 F src/test_multiplex.h 110a8c4d356e0aa464ca8730375608a9a0b61ae1 F src/test_mutex.c 293042d623ebba969160f471a82aa1551626454f @@ -1142,10 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P f336c18fb72ab90e93640b12ac540d41accc7658 -R 4fb7e3d2adbb1a56917a356c46494b14 -T *branch * winHeapSize -T *sym-winHeapSize * -T -sym-trunk * +P f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 +R 27fb3c9a311fe5f2bbe8062f9b160f8d U mistachkin -Z 570dda2e20bfd9c30436e58012ccd873 +Z d9c5f17d385924b0a9e66e3497c49033 diff --git a/manifest.uuid b/manifest.uuid index 18b1640e79..e16a6221c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f09f11e94b5a7c2e51d99c3700d2acd2f3903de9 \ No newline at end of file +51e876074af4e34ba01ed122e3bcc042243c9e88 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 61d06fdb78..a6a04b4b4c 100644 --- a/src/main.c +++ b/src/main.c @@ -516,7 +516,7 @@ int sqlite3_config(int op, ...){ } #if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) - case SQLITE_CONFIG_HEAP_SIZE: { + case SQLITE_CONFIG_WIN32_HEAPSIZE: { sqlite3GlobalConfig.nHeap = va_arg(ap, int); break; } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 7c39f4efe9..ca5972bfcf 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -1683,12 +1683,12 @@ struct sqlite3_mem_methods { ** ^If either argument to this option is negative, then that argument is ** changed to its compile-time default. ** -** [[SQLITE_CONFIG_HEAP_SIZE]] -**
    SQLITE_CONFIG_HEAP_SIZE +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] +**
    SQLITE_CONFIG_WIN32_HEAPSIZE **
    ^This option is only available if SQLite is compiled for Windows ** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. -** SQLITE_CONFIG_HEAP_SIZE takes a 32-bit integer value that specifies -** the maximum size of the heap. +** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value +** that specifies the maximum size of the heap. ** */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ @@ -1713,7 +1713,7 @@ struct sqlite3_mem_methods { #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ -#define SQLITE_CONFIG_HEAP_SIZE 23 /* int nByte */ +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options diff --git a/src/test_malloc.c b/src/test_malloc.c index 0c2d6ba223..e3cfcaa9f0 100644 --- a/src/test_malloc.c +++ b/src/test_malloc.c @@ -1151,7 +1151,7 @@ static int test_config_heap_size( } if( Tcl_GetIntFromObj(interp, aArg[0], &nByte) ) return TCL_ERROR; - rc = sqlite3_config(SQLITE_CONFIG_HEAP_SIZE, nByte); + rc = sqlite3_config(SQLITE_CONFIG_WIN32_HEAPSIZE, nByte); Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_VOLATILE); return TCL_OK; From 0b9dadacd8454f0de0ab071efc9d8b7e0400b480 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 25 Nov 2013 22:24:36 +0000 Subject: [PATCH 74/78] Change a while-loop into a do-loop in sqlite3VdbeRecordCompare() and add an assert() to verify that the do-loop really is appropriate. This gives about a 10% performance boost in that routine, or a 0.9% boost overall. FossilOrigin-Name: 011a6be439eb884c944a3318bf631bed3135f8ec --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index efb60bfaa3..f73f3143f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sNEVER()\sfrom\sa\sbranch\sthat\sis\snow\sreachable\sduring\sOOM\sfaults. -D 2013-11-25T21:41:24.083 +C Change\sa\swhile-loop\sinto\sa\sdo-loop\sin\ssqlite3VdbeRecordCompare()\sand\sadd\nan\sassert()\sto\sverify\sthat\sthe\sdo-loop\sreally\sis\sappropriate.\s\sThis\sgives\nabout\sa\s10%\sperformance\sboost\sin\sthat\sroutine,\sor\sa\s0.9%\sboost\soverall. +D 2013-11-25T22:24:36.845 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -284,7 +284,7 @@ F src/vdbe.c 23d0cfba65b6dadf39a0805d0fba266e8146d678 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed -F src/vdbeaux.c 5251f17828ff49664f457b6d8a1585297ce7a7a9 +F src/vdbeaux.c a880c3c7d7c58543574ff7c96feddc5a1deaeae2 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde F src/vdbemem.c cd02a6ade205ebe989983b7e3d64a5358b8e5e1f F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 @@ -1142,7 +1142,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 032e89934f36de10652d3454a0065a337827221a -R 542bd751b886b00603f8e8e48c8170e2 +P 18bdcb05c26860643f53a6b9e85f84109a3ebe5a +R dac23119194b70834a8988d5969d30b0 U drh -Z 7e8a0ac6a68793100fecd3fb349d5622 +Z 2ee808e2592f93c91c4a4d0443aab097 diff --git a/manifest.uuid b/manifest.uuid index 287b09b299..dec077a3f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18bdcb05c26860643f53a6b9e85f84109a3ebe5a \ No newline at end of file +011a6be439eb884c944a3318bf631bed3135f8ec \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index bea60ba9d1..e2e3843ffd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3114,7 +3114,8 @@ int sqlite3VdbeRecordCompare( d1 = szHdr1; assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); assert( pKeyInfo->aSortOrder!=0 ); - while( idx1nField ){ + assert( idx1nField ); + do{ u32 serial_type1; /* Read the serial types for the next element in each key. */ @@ -3147,7 +3148,7 @@ int sqlite3VdbeRecordCompare( return rc; } i++; - } + }while( idx1nField ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a From de1a8b8c691ecc8be8b9741b6b5b5cd141c8c3da Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 15:45:02 +0000 Subject: [PATCH 75/78] Change the REAL-to-INTEGER casting behavior so that if the REAL value is greater than 9223372036854775807.0 then it is cast to the latest possible integer, 9223372036854775807. This is sensible and the way most platforms work in hardware. The former behavior was that oversize REALs would be cast to the smallest possible integer, -9223372036854775808, which is the way Intel hardware works. FossilOrigin-Name: 6f53fc7106658d44edf63068f9a8522fa5a7688b --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/util.c | 3 +-- src/vdbe.c | 4 +++- src/vdbemem.c | 29 ++++++----------------------- test/autoinc.test | 2 +- test/e_expr.test | 4 ++-- 7 files changed, 25 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 62e099e034..435fa42b93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Better\ssupport\sfor\sUTF-8\spaths\son\sCygwin. -D 2013-11-26T00:28:50.946 +C Change\sthe\sREAL-to-INTEGER\scasting\sbehavior\sso\sthat\sif\sthe\sREAL\svalue\nis\sgreater\sthan\s9223372036854775807.0\sthen\sit\sis\scast\sto\sthe\slatest\npossible\sinteger,\s9223372036854775807.\s\sThis\sis\ssensible\sand\sthe\sway\nmost\splatforms\swork\sin\shardware.\s\sThe\sformer\sbehavior\swas\sthat\soversize\nREALs\swould\sbe\scast\sto\sthe\ssmallest\spossible\sinteger,\s-9223372036854775808,\nwhich\sis\sthe\sway\sIntel\shardware\sworks. +D 2013-11-26T15:45:02.186 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -278,15 +278,15 @@ F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4 F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba F src/update.c c05a0ee658f1a149e0960dfd110f3b8bd846bcb0 F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269 -F src/util.c 2fa6c821d28bbdbeec1b2a7b091a281c9ef8f918 +F src/util.c cbe054290f780fcd472b89d701c7404c51ec9684 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 -F src/vdbe.c 23d0cfba65b6dadf39a0805d0fba266e8146d678 +F src/vdbe.c 061d30aea5bbe70926236836be259ed217ee65c0 F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644 F src/vdbeInt.h 05fbda0e061dbc4aaa2709a8cccf3515c245b263 F src/vdbeapi.c 93a22a9ba2abe292d5c2cf304d7eb2e894dde0ed F src/vdbeaux.c a880c3c7d7c58543574ff7c96feddc5a1deaeae2 F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde -F src/vdbemem.c cd02a6ade205ebe989983b7e3d64a5358b8e5e1f +F src/vdbemem.c af650c2019dc197f062440cdb4650b7204e648bf F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147 F src/vdbetrace.c e7ec40e1999ff3c6414424365d5941178966dcbc F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd @@ -330,7 +330,7 @@ F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f F test/auth2.test c3b415b76c033bedb81292118fb7c01f5f10cbcd F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5 -F test/autoinc.test bd30d372d00045252f6c2e41b5f41455e1975acf +F test/autoinc.test c58912526998a39e11f66b533e23cfabea7f25b7 F test/autoindex1.test d4dfe14001dfcb74cfbd7107f45a79fc1ab6183e F test/autovacuum.test 941892505d2c0f410a0cb5970dfa1c7c4e5f6e74 F test/autovacuum_ioerr2.test 8a367b224183ad801e0e24dcb7d1501f45f244b4 @@ -437,7 +437,7 @@ F test/e_createtable.test 3b453432cd14a12732ee9467597d2274ca37ce36 F test/e_delete.test d5186e2f5478b659f16a2c8b66c09892823e542a F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 0c9f7f60989164a70a67a9d9c26d1083bc808306 -F test/e_expr.test 7d7feeadb555b49476e9ca4a145fcf7c0a81ce34 +F test/e_expr.test 0808bc72c7b2a2fab4291418ecd73f4d09d7d671 F test/e_fkey.test d83a04478bb9c02d2c513518548a69f818869f41 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459 F test/e_insert.test 1e44f84d2abe44d66e4fbf198be4b20e3cc724a0 @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 914e6c9d88828b66e8385c4a264702471faa34cf 484162b6e5a8ad9385fe2eb2a5254d13d7b0bc36 -R 1b8f9bd2dcb67783ed3f85d3422a2824 -U mistachkin -Z f0ab176076e12054e72ef7c2fe54ec51 +P 9954327c0febc0ece46f62e05976330a1b82b48f +R 55fc64123fadbe14b9ab9765d23a7587 +U drh +Z 850b84acf394562818ad72b52ff1802d diff --git a/manifest.uuid b/manifest.uuid index b5dd746957..fa5bbf9cf1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9954327c0febc0ece46f62e05976330a1b82b48f \ No newline at end of file +6f53fc7106658d44edf63068f9a8522fa5a7688b \ No newline at end of file diff --git a/src/util.c b/src/util.c index 50ffd98650..5aa8af68d9 100644 --- a/src/util.c +++ b/src/util.c @@ -512,7 +512,7 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ u = u*10 + c - '0'; } if( u>LARGEST_INT64 ){ - *pNum = SMALLEST_INT64; + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; }else{ @@ -543,7 +543,6 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ /* zNum is exactly 9223372036854775808. Fits if negative. The ** special case 2 overflow if positive */ assert( u-1==LARGEST_INT64 ); - assert( (*pNum)==SMALLEST_INT64 ); return neg ? 0 : 2; } } diff --git a/src/vdbe.c b/src/vdbe.c index f8e95f6399..71e4d673c0 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3514,7 +3514,9 @@ case OP_SeekGt: { /* jump, in3 */ ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); - if( iKey==SMALLEST_INT64 && (pIn3->r<(double)iKey || pIn3->r>0) ){ + if( (iKey==SMALLEST_INT64 && pIn3->r<(double)iKey) + || (iKey==LARGEST_INT64 && pIn3->r>(double)iKey) + ){ /* The P3 value is too large in magnitude to be expressed as an ** integer. */ res = 1; diff --git a/src/vdbemem.c b/src/vdbemem.c index a67305f350..0fe7a3bcb4 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -303,15 +303,8 @@ void sqlite3VdbeMemRelease(Mem *p){ /* ** Convert a 64-bit IEEE double into a 64-bit signed integer. -** If the double is too large, return 0x8000000000000000. -** -** Most systems appear to do this simply by assigning -** variables and without the extra range tests. But -** there are reports that windows throws an expection -** if the floating point value is out of range. (See ticket #2880.) -** Because we do not completely understand the problem, we will -** take the conservative approach and always do range tests -** before attempting the conversion. +** If the double is out of range of a 64-bit signed integer then +** return the closest available 64-bit signed integer. */ static i64 doubleToInt64(double r){ #ifdef SQLITE_OMIT_FLOATING_POINT @@ -328,14 +321,10 @@ static i64 doubleToInt64(double r){ static const i64 maxInt = LARGEST_INT64; static const i64 minInt = SMALLEST_INT64; - if( r<(double)minInt ){ - return minInt; - }else if( r>(double)maxInt ){ - /* minInt is correct here - not maxInt. It turns out that assigning - ** a very large positive number to an integer results in a very large - ** negative integer. This makes no sense, but it is what x86 hardware - ** does so for compatibility we will do the same in software. */ + if( r<=(double)minInt ){ return minInt; + }else if( r>=(double)maxInt ){ + return maxInt; }else{ return (i64)r; } @@ -417,17 +406,11 @@ void sqlite3VdbeIntegerAffinity(Mem *pMem){ ** ** The second and third terms in the following conditional enforces ** the second condition under the assumption that addition overflow causes - ** values to wrap around. On x86 hardware, the third term is always - ** true and could be omitted. But we leave it in because other - ** architectures might behave differently. + ** values to wrap around. */ if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64 -#if defined(__i486__) || defined(__x86_64__) - && ALWAYS(pMem->u.iu.iflags |= MEM_Int; } diff --git a/test/autoinc.test b/test/autoinc.test index 98f6919b03..239600616b 100644 --- a/test/autoinc.test +++ b/test/autoinc.test @@ -216,7 +216,7 @@ do_test autoinc-2.27 { } {t1 1238} do_test autoinc-2.28 { execsql { - UPDATE sqlite_sequence SET seq='12345678901234567890' + UPDATE sqlite_sequence SET seq='-12345678901234567890' WHERE name='t1'; INSERT INTO t1 VALUES(NULL,6); SELECT * FROM t1; diff --git a/test/e_expr.test b/test/e_expr.test index 2018db8a05..eead6a2b93 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1606,14 +1606,14 @@ do_expr_test e_expr-31.1.4 { CAST(-0.99999 AS INTEGER) } integer 0 # an INTEGER then the result of the cast is the largest negative # integer: -9223372036854775808. # -do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer -9223372036854775808 +do_expr_test e_expr-31.2.1 { CAST(2e+50 AS INT) } integer 9223372036854775807 do_expr_test e_expr-31.2.2 { CAST(-2e+50 AS INT) } integer -9223372036854775808 do_expr_test e_expr-31.2.3 { CAST(-9223372036854775809.0 AS INT) } integer -9223372036854775808 do_expr_test e_expr-31.2.4 { CAST(9223372036854775809.0 AS INT) -} integer -9223372036854775808 +} integer 9223372036854775807 # EVIDENCE-OF: R-09295-61337 Casting a TEXT or BLOB value into NUMERIC From dbb3c98ad1eaf5e3ab00757f04a35c6d6e898e11 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:20:28 +0000 Subject: [PATCH 76/78] Do not try to run the atof1.test test script on ARM hardware which lacks the "long double" type. FossilOrigin-Name: fafca560f28f526abdf1474c33af94665a65aaf0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/atof1.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 435fa42b93..b4dc5841dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sREAL-to-INTEGER\scasting\sbehavior\sso\sthat\sif\sthe\sREAL\svalue\nis\sgreater\sthan\s9223372036854775807.0\sthen\sit\sis\scast\sto\sthe\slatest\npossible\sinteger,\s9223372036854775807.\s\sThis\sis\ssensible\sand\sthe\sway\nmost\splatforms\swork\sin\shardware.\s\sThe\sformer\sbehavior\swas\sthat\soversize\nREALs\swould\sbe\scast\sto\sthe\ssmallest\spossible\sinteger,\s-9223372036854775808,\nwhich\sis\sthe\sway\sIntel\shardware\sworks. -D 2013-11-26T15:45:02.186 +C Do\snot\stry\sto\srun\sthe\satof1.test\stest\sscript\son\sARM\shardware\swhich\slacks\nthe\s"long\sdouble"\stype. +D 2013-11-26T16:20:28.799 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -321,7 +321,7 @@ F test/async2.test c0a9bd20816d7d6a2ceca7b8c03d3d69c28ffb8b F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 -F test/atof1.test 9bf1d25180a2e05fc12ce3940cc8003033642f68 +F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7 F test/attach.test 0d112b7713611fdf0340260192749737135fda5f F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 9954327c0febc0ece46f62e05976330a1b82b48f -R 55fc64123fadbe14b9ab9765d23a7587 +P 6f53fc7106658d44edf63068f9a8522fa5a7688b +R 0b6d53f178500662f3ea7da63b0a8b9a U drh -Z 850b84acf394562818ad72b52ff1802d +Z 1b696475d3b2c1907923dd0866112072 diff --git a/manifest.uuid b/manifest.uuid index fa5bbf9cf1..a2f192f5f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f53fc7106658d44edf63068f9a8522fa5a7688b \ No newline at end of file +fafca560f28f526abdf1474c33af94665a65aaf0 \ No newline at end of file diff --git a/test/atof1.test b/test/atof1.test index 76eb4273b9..5c04d02290 100644 --- a/test/atof1.test +++ b/test/atof1.test @@ -15,7 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -if {![info exists __GNUC__]} { +if {![info exists __GNUC__] || [regexp arm $tcl_platform(machine)]} { finish_test return } From 0425f18959aaafb4c1ce703d461acfb7a8ae65d3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:48:04 +0000 Subject: [PATCH 77/78] Change tclsqlite3.c so that it never invokes ctype macros with signed character arguments. FossilOrigin-Name: c07caabf2396c84b2ccb0e9f98ae6279ce41c59d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b4dc5841dc..ce7a5e9090 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\stry\sto\srun\sthe\satof1.test\stest\sscript\son\sARM\shardware\swhich\slacks\nthe\s"long\sdouble"\stype. -D 2013-11-26T16:20:28.799 +C Change\stclsqlite3.c\sso\sthat\sit\snever\sinvokes\sctype\smacros\swith\ssigned\ncharacter\sarguments. +D 2013-11-26T16:48:04.270 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -228,7 +228,7 @@ F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 3b5f3716e320480659239abe887164521c575d83 +F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153 F src/test1.c 5757066e503a8ed51313cb3a5d9bcdcced2991a9 F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35 F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P 6f53fc7106658d44edf63068f9a8522fa5a7688b -R 0b6d53f178500662f3ea7da63b0a8b9a +P fafca560f28f526abdf1474c33af94665a65aaf0 +R 6dbbdfc524469f7c72c8eb6b873b5729 U drh -Z 1b696475d3b2c1907923dd0866112072 +Z 7b1df47f508bb396c6901395cdb1db93 diff --git a/manifest.uuid b/manifest.uuid index a2f192f5f4..eb8198cac8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fafca560f28f526abdf1474c33af94665a65aaf0 \ No newline at end of file +c07caabf2396c84b2ccb0e9f98ae6279ce41c59d \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index b8fdf23c4e..0f57dda6ca 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -424,13 +424,12 @@ static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ */ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ SqlFunc *p, *pNew; - int i; - pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); + int nName = strlen30(zName); + pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 ); pNew->zName = (char*)&pNew[1]; - for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } - pNew->zName[i] = 0; + memcpy(pNew->zName, zName, nName+1); for(p=pDb->pFunc; p; p=p->pNext){ - if( strcmp(p->zName, pNew->zName)==0 ){ + if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){ Tcl_Free((char*)pNew); return p; } @@ -1083,13 +1082,14 @@ static int dbPrepareAndBind( int nSql; /* Length of zSql in bytes */ int nVar; /* Number of variables in statement */ int iParm = 0; /* Next free entry in apParm */ + char c; int i; Tcl_Interp *interp = pDb->interp; *ppPreStmt = 0; /* Trim spaces from the start of zSql and calculate the remaining length. */ - while( isspace(zSql[0]) ){ zSql++; } + while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; } nSql = strlen30(zSql); for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ From 55fcab39be8186caac6c7d1262a7c943564623bb Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 26 Nov 2013 16:51:13 +0000 Subject: [PATCH 78/78] Fix a possible NULL pointer deference in the wordcount test program. FossilOrigin-Name: 6f91dca0de908dc2b15130a6593a61c3147a409f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/wordcount.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ce7a5e9090..d7a8adc696 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\stclsqlite3.c\sso\sthat\sit\snever\sinvokes\sctype\smacros\swith\ssigned\ncharacter\sarguments. -D 2013-11-26T16:48:04.270 +C Fix\sa\spossible\sNULL\spointer\sdeference\sin\sthe\swordcount\stest\sprogram. +D 2013-11-26T16:51:13.426 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e1a9b4258bbde53f5636f4e238c65b7e11459e2b F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -1091,7 +1091,7 @@ F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a -F test/wordcount.c 800b6ab98ac05b7c6343575c45055f72273c9cc2 +F test/wordcount.c 9915e06cb33d8ca8109b8700791afe80d305afda F test/zeroblob.test caaecfb4f908f7bc086ed238668049f96774d688 F test/zerodamage.test 209d7ed441f44cc5299e4ebffbef06fd5aabfefd F tool/build-all-msvc.bat e0917e787df675b020d250d60a00de8abaa4e30a x @@ -1143,7 +1143,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff -P fafca560f28f526abdf1474c33af94665a65aaf0 -R 6dbbdfc524469f7c72c8eb6b873b5729 +P c07caabf2396c84b2ccb0e9f98ae6279ce41c59d +R d1a47818d75d4c09a9dcb48899bdd6d5 U drh -Z 7b1df47f508bb396c6901395cdb1db93 +Z 42f2f4c4e3d27d9172438c5ee2b1524f diff --git a/manifest.uuid b/manifest.uuid index eb8198cac8..50a66e6b11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c07caabf2396c84b2ccb0e9f98ae6279ce41c59d \ No newline at end of file +6f91dca0de908dc2b15130a6593a61c3147a409f \ No newline at end of file diff --git a/test/wordcount.c b/test/wordcount.c index b21b4272bc..cf63e983c2 100644 --- a/test/wordcount.c +++ b/test/wordcount.c @@ -116,7 +116,7 @@ static int printResult(void *NotUsed, int nArg, char **azArg, char **azNm){ int i; printf("--"); for(i=0; i