From 3c6fbd6dd91535e9f61bb77d0013d5fd2a170692 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Apr 2021 20:13:53 +0000 Subject: [PATCH 01/46] Remove a couple of NEVER() macros from the code for walking window lists. FossilOrigin-Name: 4ec9ef4bcd12bd9ba5e1a2424f75479070d12c25f1272548c6cf3f89be826b8c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/walker.c | 9 ++------- test/window1.test | 19 +++++++++++++++++++ 4 files changed, 30 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index bb5e1dc388..0282d47597 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\sin\spermutations\smod. -D 2021-04-17T20:04:40.828 +C Remove\sa\scouple\sof\sNEVER()\smacros\sfrom\sthe\scode\sfor\swalking\swindow\slists. +D 2021-04-17T20:13:53.876 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c df4f432b10011cd587b16afa861ae8878ef1b872dd042565efa4db346bbdc793 +F src/walker.c 49a9c0b8fb1de273aa0bce2e3f671056c11db8220c04ca1120ed1ce5b619f227 F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 0e42f4ad53962e90349462520891734ed3217c7852f41c69ffac7a9eeaf31451 @@ -1770,7 +1770,7 @@ F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2 F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test 515512f47c654e1b19e9708aa53d269dfe7acafd3c458e1dfdda783ac8822150 +F test/window1.test 54e160bdeb8b06fb3b97993e0eec45ee4c3294f39ad63007c921c40961298815 F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f0dd9cf2d7045d3634294bcf2722d3d7b0a6c4c3ef713b0f7f54fbe31432027f 9f5f16cf093cd8b8c7649f664eaf2ad8128fd50e182720dbddf05a6d9227c037 -R 87aec11a4649f0fdf92c1e3a7b1989d4 -U larrybr -Z 0c46d5306f1cd3c2e7d5358adc5fc62f +P 7a1316f32c857b5ec9e50c5d341f977f998dbf404f4758e3fe317fd8ef25f41e +R 30207d0f4281a6cd8ec3b314354fd0f5 +U dan +Z 3ba541f2adb5c2a2b0eb425e20d42a84 diff --git a/manifest.uuid b/manifest.uuid index cd3456b968..d299496b7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7a1316f32c857b5ec9e50c5d341f977f998dbf404f4758e3fe317fd8ef25f41e \ No newline at end of file +4ec9ef4bcd12bd9ba5e1a2424f75479070d12c25f1272548c6cf3f89be826b8c \ No newline at end of file diff --git a/src/walker.c b/src/walker.c index 6483638815..84fb71790c 100644 --- a/src/walker.c +++ b/src/walker.c @@ -32,15 +32,10 @@ static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ if( rc ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pFilter); if( rc ) return WRC_Abort; - - /* The next two are purely for calls to sqlite3RenameExprUnmap() - ** within sqlite3WindowOffsetExpr(). Because of constraints imposed - ** by sqlite3WindowOffsetExpr(), they can never fail. The results do - ** not matter anyhow. */ rc = sqlite3WalkExpr(pWalker, pWin->pStart); - if( NEVER(rc) ) return WRC_Abort; + if( rc ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); - if( NEVER(rc) ) return WRC_Abort; + if( rc ) return WRC_Abort; if( bOneOnly ) break; } return WRC_Continue; diff --git a/test/window1.test b/test/window1.test index 0f4e0e2c87..604007e515 100644 --- a/test/window1.test +++ b/test/window1.test @@ -387,6 +387,25 @@ do_catchsql_test 9.4 { END; } {1 {trigger cannot use variables}} +do_catchsql_test 9.4.2 { + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(a,b) + SELECT a, max(d) OVER w1 FROM t1 + WINDOW w1 AS ( + ORDER BY a ROWS BETWEEN ? PRECEDING AND UNBOUNDED FOLLOWING + ); + END; +} {1 {trigger cannot use variables}} +do_catchsql_test 9.4.3 { + CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN + INSERT INTO t1(a,b) + SELECT a, max(d) OVER w1 FROM t1 + WINDOW w1 AS ( + ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND ? FOLLOWING + ); + END; +} {1 {trigger cannot use variables}} + #------------------------------------------------------------------------- # do_execsql_test 10.0 { From 0a746cc528744f771b76b366cae87f2285951490 Mon Sep 17 00:00:00 2001 From: dan Date: Sun, 18 Apr 2021 05:30:39 +0000 Subject: [PATCH 02/46] Ensure that all records are updated by setting the OPFLAG_SAVEPOSITION flag when updating records as part of ALTER TABLE DROP COLUMN. FossilOrigin-Name: 354a4db5cb769c6aed386f43ee26d7e42342e92f781eef100c09751dc5b51751 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/alter.c | 7 ++++++- test/alterdropcol.test | 25 +++++++++++++++++++++++++ 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0282d47597..deecc028a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\scouple\sof\sNEVER()\smacros\sfrom\sthe\scode\sfor\swalking\swindow\slists. -D 2021-04-17T20:13:53.876 +C Ensure\sthat\sall\srecords\sare\supdated\sby\ssetting\sthe\sOPFLAG_SAVEPOSITION\sflag\swhen\supdating\srecords\sas\spart\sof\sALTER\sTABLE\sDROP\sCOLUMN. +D 2021-04-18T05:30:39.861 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 14d5d9ba332de515c6e2f729e728426cdd6f5683cdc356ba6b6e3444e1ed210e +F src/alter.c 9dde656dfd53325dae24973fa7d6597ef64dcfd1bc3c3baefcf7b88c5af0d0a8 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c f4c5352b7e65760bed220e46176b540d43fdb2d9453a262c5fa467e5a8dfaa61 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -649,7 +649,7 @@ F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256b F test/alterauth2.test 381b1ab603c9ef96314a3158528ea17f7964449385a28eeaf8191120b2e24a8d F test/altercol.test b11fa1b131e80ab5b6ecfb3b725fb0419c14ca6efba5adb57aeabfc9baa0c8f3 F test/altercorrupt.test 584d707a80e106952d6382790c8919bcf9f0db678ed3a1c09fd98b7f9d1d3a10 -F test/alterdropcol.test 79d68fbe6256bd9d55ea8ba495c9f8f61bcd09644eb3fd33329851ad217ba7d7 +F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41 F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7a1316f32c857b5ec9e50c5d341f977f998dbf404f4758e3fe317fd8ef25f41e -R 30207d0f4281a6cd8ec3b314354fd0f5 +P 4ec9ef4bcd12bd9ba5e1a2424f75479070d12c25f1272548c6cf3f89be826b8c +R ad21a6d9a36497d430b1bdf7e1327f29 U dan -Z 3ba541f2adb5c2a2b0eb425e20d42a84 +Z 9d80b290d00ddd51864fc31db6dbc49c diff --git a/manifest.uuid b/manifest.uuid index d299496b7b..78813f74f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ec9ef4bcd12bd9ba5e1a2424f75479070d12c25f1272548c6cf3f89be826b8c \ No newline at end of file +354a4db5cb769c6aed386f43ee26d7e42342e92f781eef100c09751dc5b51751 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 043b47f6dc..e9640d2389 100644 --- a/src/alter.c +++ b/src/alter.c @@ -2119,7 +2119,11 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ }else{ regOut = reg+1+nField; } - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regOut); + }else{ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + } nField++; } } @@ -2129,6 +2133,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ }else{ sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); } + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr); diff --git a/test/alterdropcol.test b/test/alterdropcol.test index 8891942b09..8674e981a3 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -309,6 +309,31 @@ do_execsql_test 8.2 { SELECT sql FROM sqlite_schema; } {{CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT)}} +#------------------------------------------------------------------------- + +foreach {tn wo} { + 1 {} + 2 {WITHOUT ROWID} +} { + reset_db + do_execsql_test 9.$tn.0 " + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c) $wo; + " + do_execsql_test 9.$tn.1 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50000 + ) + INSERT INTO t1(a, b, c) SELECT i, 123, 456 FROM s; + } + do_execsql_test 9.$tn.2 { + ALTER TABLE t1 DROP COLUMN b; + } + + do_execsql_test 9.$tn.3 { + SELECT count(*), c FROM t1 GROUP BY c; + } {50000 456} +} + finish_test From 60b95335e2031461c3d2f9332d308e4875ed92ae Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 19 Apr 2021 15:05:27 +0000 Subject: [PATCH 03/46] In the query flattener, avoid invalidating an expression if an OOM occurs. This prevents problems in higher-level routines that might not check for the OOM after processing a subquery. dbsqlfuzz fb70fa8602421f87673e0670b0712ff2b5240ea0 FossilOrigin-Name: d564d8882ef18b55ebf93e838426b485281c7ebe3a9b321a2f984ed0f229cc25 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 19 +++++++++---------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index deecc028a0..a7e32a4219 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sall\srecords\sare\supdated\sby\ssetting\sthe\sOPFLAG_SAVEPOSITION\sflag\swhen\supdating\srecords\sas\spart\sof\sALTER\sTABLE\sDROP\sCOLUMN. -D 2021-04-18T05:30:39.861 +C In\sthe\squery\sflattener,\savoid\sinvalidating\san\sexpression\sif\san\sOOM\soccurs.\nThis\sprevents\sproblems\sin\shigher-level\sroutines\sthat\smight\snot\scheck\sfor\nthe\sOOM\safter\sprocessing\sa\ssubquery.\ndbsqlfuzz\sfb70fa8602421f87673e0670b0712ff2b5240ea0 +D 2021-04-19T15:05:27.545 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c ab7dcf61ffe21e51c4ed8df5f22aaff6473d27d19f62914f38ebcb30fe404c44 +F src/select.c 8b466a1c0d48d2210e93b7af46f5586fb7f80ccc0bc0f9859a4a2a7038d18d47 F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4ec9ef4bcd12bd9ba5e1a2424f75479070d12c25f1272548c6cf3f89be826b8c -R ad21a6d9a36497d430b1bdf7e1327f29 -U dan -Z 9d80b290d00ddd51864fc31db6dbc49c +P 354a4db5cb769c6aed386f43ee26d7e42342e92f781eef100c09751dc5b51751 +R d34f55f4a0ce3de7a5176125f81c3be7 +U drh +Z ca72275528f30884ea5a49fdd0fac3b4 diff --git a/manifest.uuid b/manifest.uuid index 78813f74f2..b7cd55624d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -354a4db5cb769c6aed386f43ee26d7e42342e92f781eef100c09751dc5b51751 \ No newline at end of file +d564d8882ef18b55ebf93e838426b485281c7ebe3a9b321a2f984ed0f229cc25 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a543702bf3..176115689f 100644 --- a/src/select.c +++ b/src/select.c @@ -3627,10 +3627,11 @@ static Expr *substExpr( } testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); - if( pNew && pSubst->isLeftJoin ){ + if( pNew==0 ) return pExpr; + if( pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( pNew && ExprHasProperty(pExpr,EP_FromJoin) ){ + if( ExprHasProperty(pExpr,EP_FromJoin) ){ sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable); } sqlite3ExprDelete(db, pExpr); @@ -3638,15 +3639,13 @@ static Expr *substExpr( /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ - if( pExpr ){ - if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ - CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); - pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, - (pColl ? pColl->zName : "BINARY") - ); - } - ExprClearProperty(pExpr, EP_Collate); + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); } + ExprClearProperty(pExpr, EP_Collate); } } }else{ From 6a4f7f0225cdf62e7b06362d6d691948424d43c1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Apr 2021 16:45:09 +0000 Subject: [PATCH 04/46] Remove fts5 test functions fts5_expr(), fts5_expr_tcl(), fts5_isalnum() and fts5_fold() from release builds. FossilOrigin-Name: c68a6c6c898d2acd1f7032ff98f8f3f99eb0b37ffbc6ee88d0dd7badf55a0e0a --- ext/fts5/fts5_expr.c | 6 ++++++ manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 088d8b8cae..556c7934ed 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2412,6 +2412,7 @@ Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( return pRet; } +#ifdef SQLITE_TEST static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ sqlite3_int64 nByte = 0; Fts5ExprTerm *p; @@ -2778,12 +2779,14 @@ static void fts5ExprFold( sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); } } +#endif /* ifdef SQLITE_TEST */ /* ** This is called during initialization to register the fts5_expr() scalar ** UDF with the SQLite handle passed as the only argument. */ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ +#ifdef SQLITE_TEST struct Fts5ExprFunc { const char *z; void (*x)(sqlite3_context*,int,sqlite3_value**); @@ -2801,6 +2804,9 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ struct Fts5ExprFunc *p = &aFunc[i]; rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } +#else + int rc = SQLITE_OK; +#endif /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and ** sqlite3Fts5ParserFallback() are unused */ diff --git a/manifest b/manifest index a7e32a4219..bdf1af9998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\squery\sflattener,\savoid\sinvalidating\san\sexpression\sif\san\sOOM\soccurs.\nThis\sprevents\sproblems\sin\shigher-level\sroutines\sthat\smight\snot\scheck\sfor\nthe\sOOM\safter\sprocessing\sa\ssubquery.\ndbsqlfuzz\sfb70fa8602421f87673e0670b0712ff2b5240ea0 -D 2021-04-19T15:05:27.545 +C Remove\sfts5\stest\sfunctions\sfts5_expr(),\sfts5_expr_tcl(),\sfts5_isalnum()\sand\sfts5_fold()\sfrom\srelease\sbuilds. +D 2021-04-19T16:45:09.148 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3 -F ext/fts5/fts5_expr.c 016bd06030679bd31b0f07ef87d62c42031e5da25cb3174a84e5b0f6ef4b47b0 +F ext/fts5/fts5_expr.c 5d0ab73f08af31837b1a4cbcaf571e74d7bb87f4f15bf79709de1b67ff4bfc05 F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 F ext/fts5/fts5_index.c a2ee22478318ad2c176fb06b0a7a752b770056cde6a0a8d8a50968f3afcc306e F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 354a4db5cb769c6aed386f43ee26d7e42342e92f781eef100c09751dc5b51751 -R d34f55f4a0ce3de7a5176125f81c3be7 -U drh -Z ca72275528f30884ea5a49fdd0fac3b4 +P d564d8882ef18b55ebf93e838426b485281c7ebe3a9b321a2f984ed0f229cc25 +R 864bb68049ae279060a9cc19673f4524 +U dan +Z 3936923389936689750015fb37ea53e3 diff --git a/manifest.uuid b/manifest.uuid index b7cd55624d..20ba36c564 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d564d8882ef18b55ebf93e838426b485281c7ebe3a9b321a2f984ed0f229cc25 \ No newline at end of file +c68a6c6c898d2acd1f7032ff98f8f3f99eb0b37ffbc6ee88d0dd7badf55a0e0a \ No newline at end of file From 1bb89e9cc88bd9cb18b9d970f41ec28f47913a53 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 19 Apr 2021 18:03:52 +0000 Subject: [PATCH 05/46] Ensure that a WITHOUT ROWID table does not have the .iPKey field set, even if an OOM error occurs while parsing a schema in PRAGMA writable_schema=ON mode. Add extra assert() statements to triple-check that this never happens. dbsqlfuzz 803bb1f63d6f3bd6c14db568494d6e96be8f1ec9. FossilOrigin-Name: 41228350a620a7de1ee748a4e19a96749c4d39418853fe8b68c43cf401dbd7cd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 8 +++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bdf1af9998..a8e05ccf8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sfts5\stest\sfunctions\sfts5_expr(),\sfts5_expr_tcl(),\sfts5_isalnum()\sand\sfts5_fold()\sfrom\srelease\sbuilds. -D 2021-04-19T16:45:09.148 +C Ensure\sthat\sa\sWITHOUT\sROWID\stable\sdoes\snot\shave\sthe\s.iPKey\sfield\sset,\seven\sif\nan\sOOM\serror\soccurs\swhile\sparsing\sa\sschema\sin\sPRAGMA\swritable_schema=ON\smode.\nAdd\sextra\sassert()\sstatements\sto\striple-check\sthat\sthis\snever\shappens.\ndbsqlfuzz\s803bb1f63d6f3bd6c14db568494d6e96be8f1ec9. +D 2021-04-19T18:03:52.285 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 15cfe91aa3b3b91d3dc20faaa7c64b627ca9794b22be8b184054cb6b947505fc F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 9f15ff3e074d3989cc1396f575118eb4c28fb677d33f54393ec263799c94b5bd +F src/build.c 1cf8ab071ebab0ee8e26eae02b47b4316f69d8b33cc85031fbb356e4b2dbb624 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d564d8882ef18b55ebf93e838426b485281c7ebe3a9b321a2f984ed0f229cc25 -R 864bb68049ae279060a9cc19673f4524 -U dan -Z 3936923389936689750015fb37ea53e3 +P c68a6c6c898d2acd1f7032ff98f8f3f99eb0b37ffbc6ee88d0dd7badf55a0e0a +R dc70ab0f44ebdf675caf06b341f7b818 +U drh +Z 1cbf32554360abc3c11df2874bfd353f diff --git a/manifest.uuid b/manifest.uuid index 20ba36c564..830ff59177 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c68a6c6c898d2acd1f7032ff98f8f3f99eb0b37ffbc6ee88d0dd7badf55a0e0a \ No newline at end of file +41228350a620a7de1ee748a4e19a96749c4d39418853fe8b68c43cf401dbd7cd \ No newline at end of file diff --git a/src/build.c b/src/build.c index a6a6edb9b8..ecc08f60f7 100644 --- a/src/build.c +++ b/src/build.c @@ -461,6 +461,8 @@ Table *sqlite3LocateTable( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } + }else{ + assert( HasRowid(p) || p->iPKey<0 ); } return p; @@ -2179,7 +2181,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); - if( pList==0 ) return; + if( pList==0 ){ + pTab->tabFlags &= ~TF_WithoutRowid; + return; + } if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } @@ -2642,6 +2647,7 @@ void sqlite3EndTable( Table *pOld; Schema *pSchema = p->pSchema; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( HasRowid(p) || p->iPKey<0 ); pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ From 5e8e7464d0c325a3c669079c65af250b67eb2944 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 19 Apr 2021 19:59:16 +0000 Subject: [PATCH 06/46] An improvement to check-in [1a341378ab24a509] that omits the new Walker.bWalkWinDefn boolean (which is not always initialized) and uses a special value for xSelectCallback2 instead. FossilOrigin-Name: bef2238de9550de84d4cd1c970a542b43db288d73d09a3c3ced7f98bb3188fd3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/attach.c | 3 +-- src/sqliteInt.h | 2 +- src/walker.c | 14 ++++++++++++-- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a8e05ccf8d..7212c81c3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sa\sWITHOUT\sROWID\stable\sdoes\snot\shave\sthe\s.iPKey\sfield\sset,\seven\sif\nan\sOOM\serror\soccurs\swhile\sparsing\sa\sschema\sin\sPRAGMA\swritable_schema=ON\smode.\nAdd\sextra\sassert()\sstatements\sto\striple-check\sthat\sthis\snever\shappens.\ndbsqlfuzz\s803bb1f63d6f3bd6c14db568494d6e96be8f1ec9. -D 2021-04-19T18:03:52.285 +C An\simprovement\sto\scheck-in\s[1a341378ab24a509]\sthat\somits\sthe\snew\nWalker.bWalkWinDefn\sboolean\s(which\sis\snot\salways\sinitialized)\sand\suses\na\sspecial\svalue\sfor\sxSelectCallback2\sinstead. +D 2021-04-19T19:59:16.863 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9dde656dfd53325dae24973fa7d6597ef64dcfd1bc3c3baefcf7b88c5af0d0a8 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c f4c5352b7e65760bed220e46176b540d43fdb2d9453a262c5fa467e5a8dfaa61 +F src/attach.c 8783d67d2c61371dfae46e4043158d44b73c14154d62560cd4cb1e0dfc6337a1 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -547,7 +547,7 @@ F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee01 F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 73abdd2a633ccff6e4b5d44994d68a25b8009eca6a94d2d582404e74114071af +F src/sqliteInt.h 234ab17b1797cbc2adb7741a15786edf72bc96d40b4de68795e91926cfd46eba F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -628,7 +628,7 @@ F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c 49a9c0b8fb1de273aa0bce2e3f671056c11db8220c04ca1120ed1ce5b619f227 +F src/walker.c 52fb58ff39452ef37e58bfa429a9ecb17e8ed3e9dda05912c0d869f80d3f4600 F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 0e42f4ad53962e90349462520891734ed3217c7852f41c69ffac7a9eeaf31451 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c68a6c6c898d2acd1f7032ff98f8f3f99eb0b37ffbc6ee88d0dd7badf55a0e0a -R dc70ab0f44ebdf675caf06b341f7b818 +P 41228350a620a7de1ee748a4e19a96749c4d39418853fe8b68c43cf401dbd7cd +R c0c275822c8f8667f4e8b17de48e016f U drh -Z 1cbf32554360abc3c11df2874bfd353f +Z 2d9c6d7cb083a0246b23dde2c969e400 diff --git a/manifest.uuid b/manifest.uuid index 830ff59177..fdb7461d81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41228350a620a7de1ee748a4e19a96749c4d39418853fe8b68c43cf401dbd7cd \ No newline at end of file +bef2238de9550de84d4cd1c970a542b43db288d73d09a3c3ced7f98bb3188fd3 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 8fcfb0438b..9bd57f2865 100644 --- a/src/attach.c +++ b/src/attach.c @@ -511,10 +511,9 @@ void sqlite3FixInit( pFix->w.pParse = pParse; pFix->w.xExprCallback = fixExprCb; pFix->w.xSelectCallback = fixSelectCb; - pFix->w.xSelectCallback2 = 0; + pFix->w.xSelectCallback2 = sqlite3WalkWinDefnDummyCallback; pFix->w.walkerDepth = 0; pFix->w.eCode = 0; - pFix->w.bWalkWinDefn = 1; pFix->w.u.pFix = pFix; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 69d9b49124..21c6f6f30f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3833,7 +3833,6 @@ struct Walker { void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ int walkerDepth; /* Number of subqueries */ u16 eCode; /* A small processing code */ - unsigned bWalkWinDefn : 1; /* True to walk pWinDefn */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int n; /* A counter */ @@ -3881,6 +3880,7 @@ int sqlite3SelectWalkNoop(Walker*, Select*); int sqlite3SelectWalkFail(Walker*, Select*); int sqlite3WalkerDepthIncrease(Walker*,Select*); void sqlite3WalkerDepthDecrease(Walker*,Select*); +void sqlite3WalkWinDefnDummyCallback(Walker*,Select*); #ifdef SQLITE_DEBUG void sqlite3SelectWalkAssert2(Walker*, Select*); diff --git a/src/walker.c b/src/walker.c index 84fb71790c..28c80fa798 100644 --- a/src/walker.c +++ b/src/walker.c @@ -112,6 +112,16 @@ int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ return WRC_Continue; } +/* +** This is a no-op callback for Walker->xSelectCallback2. If this +** callback is set, then the Select->pWinDefn list is traversed. +*/ +void sqlite3WalkWinDefnDummyCallback(Walker *pWalker, Select *p){ + UNUSED_PARAMETER(pWalker); + UNUSED_PARAMETER(p); + /* No-op */ +} + /* ** Walk all expressions associated with SELECT statement p. Do ** not invoke the SELECT callback on p, but do (of course) invoke @@ -128,7 +138,7 @@ int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ #if !defined(SQLITE_OMIT_WINDOWFUNC) if( p->pWinDefn ){ Parse *pParse; - if( pWalker->bWalkWinDefn + if( pWalker->xSelectCallback2==sqlite3WalkWinDefnDummyCallback || ((pParse = pWalker->pParse)!=0 && IN_RENAME_OBJECT) ){ /* The following may return WRC_Abort if there are unresolvable @@ -167,7 +177,7 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ } } return WRC_Continue; -} +} /* ** Call sqlite3WalkExpr() for every expression in Select statement p. From 8c6cb1bc6f2bb3bd814b6d4c7cd11aad4186c41d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 19 Apr 2021 20:36:13 +0000 Subject: [PATCH 07/46] Improvement to check-in [d564d8882ef18b55] to detect the OOM fault even if it occurs deep down inside the duplicated expression. FossilOrigin-Name: 3e863cd09355abd80c1053d6d4dabb55841f806e3c418f923d67d36bf8313cb0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7212c81c3e..1468ff515b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C An\simprovement\sto\scheck-in\s[1a341378ab24a509]\sthat\somits\sthe\snew\nWalker.bWalkWinDefn\sboolean\s(which\sis\snot\salways\sinitialized)\sand\suses\na\sspecial\svalue\sfor\sxSelectCallback2\sinstead. -D 2021-04-19T19:59:16.863 +C Improvement\sto\scheck-in\s[d564d8882ef18b55]\sto\sdetect\sthe\sOOM\sfault\seven\nif\sit\soccurs\sdeep\sdown\sinside\sthe\sduplicated\sexpression. +D 2021-04-19T20:36:13.043 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -542,7 +542,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 8b466a1c0d48d2210e93b7af46f5586fb7f80ccc0bc0f9859a4a2a7038d18d47 +F src/select.c 2c4f89257327581f918863d49aded6087552926de799c0d0ebea70200c478cb2 F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 41228350a620a7de1ee748a4e19a96749c4d39418853fe8b68c43cf401dbd7cd -R c0c275822c8f8667f4e8b17de48e016f +P bef2238de9550de84d4cd1c970a542b43db288d73d09a3c3ced7f98bb3188fd3 +R 9cdbf20427098ae8915fe3c4c7011236 U drh -Z 2d9c6d7cb083a0246b23dde2c969e400 +Z 0ff14260d9ccebe4f6d06776ae79e9ce diff --git a/manifest.uuid b/manifest.uuid index fdb7461d81..f214941acb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bef2238de9550de84d4cd1c970a542b43db288d73d09a3c3ced7f98bb3188fd3 \ No newline at end of file +3e863cd09355abd80c1053d6d4dabb55841f806e3c418f923d67d36bf8313cb0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 176115689f..92c2ecf8f9 100644 --- a/src/select.c +++ b/src/select.c @@ -3627,7 +3627,10 @@ static Expr *substExpr( } testcase( ExprHasProperty(pCopy, EP_Subquery) ); pNew = sqlite3ExprDup(db, pCopy, 0); - if( pNew==0 ) return pExpr; + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pNew); + return pExpr; + } if( pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } From 9da977f1a5563d983087a1d0bd85eba65f35cca2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Apr 2021 12:14:12 +0000 Subject: [PATCH 08/46] In the sqlite3SelectDup() routine, do not do an incomplete duplication due to OOM. This in turn requires several new NEVER() and ALWAYS() macros for unreachable branches. FossilOrigin-Name: a61c0e6b78bd39f55464fafd257e68effded64995a66e8fa2d686e8c507ebe43 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/alter.c | 2 +- src/build.c | 4 ++-- src/expr.c | 8 ++++++++ src/select.c | 2 +- src/walker.c | 2 +- 7 files changed, 24 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 1468ff515b..04fa36690a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvement\sto\scheck-in\s[d564d8882ef18b55]\sto\sdetect\sthe\sOOM\sfault\seven\nif\sit\soccurs\sdeep\sdown\sinside\sthe\sduplicated\sexpression. -D 2021-04-19T20:36:13.043 +C In\sthe\ssqlite3SelectDup()\sroutine,\sdo\snot\sdo\san\sincomplete\sduplication\sdue\nto\sOOM.\s\sThis\sin\sturn\srequires\sseveral\snew\sNEVER()\sand\sALWAYS()\smacros\sfor\nunreachable\sbranches. +D 2021-04-20T12:14:12.835 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 9dde656dfd53325dae24973fa7d6597ef64dcfd1bc3c3baefcf7b88c5af0d0a8 +F src/alter.c e7caf3eefce268250dc1d10322eec637319de486aa1bae7f48c606259455537e F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c 8783d67d2c61371dfae46e4043158d44b73c14154d62560cd4cb1e0dfc6337a1 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -486,7 +486,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 15cfe91aa3b3b91d3dc20faaa7c64b627ca9794b22be8b184054cb6b947505fc F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 1cf8ab071ebab0ee8e26eae02b47b4316f69d8b33cc85031fbb356e4b2dbb624 +F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -494,7 +494,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 -F src/expr.c f1e3474d693e7dbc75726d7c23a6bb55e7205af8059956c5b3005745eb62990a +F src/expr.c 2b79c16f167b7ec74dfbd325b6f9cd9ff026908017f6804a5af6ba451c13b5b1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93 @@ -542,7 +542,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 2c4f89257327581f918863d49aded6087552926de799c0d0ebea70200c478cb2 +F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -628,7 +628,7 @@ F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c 52fb58ff39452ef37e58bfa429a9ecb17e8ed3e9dda05912c0d869f80d3f4600 +F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 0e42f4ad53962e90349462520891734ed3217c7852f41c69ffac7a9eeaf31451 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bef2238de9550de84d4cd1c970a542b43db288d73d09a3c3ced7f98bb3188fd3 -R 9cdbf20427098ae8915fe3c4c7011236 +P 3e863cd09355abd80c1053d6d4dabb55841f806e3c418f923d67d36bf8313cb0 +R a2f252b041b1ce9ea09cc93be49d1068 U drh -Z 0ff14260d9ccebe4f6d06776ae79e9ce +Z e9f9190f218ee2534b1576005539f8b4 diff --git a/manifest.uuid b/manifest.uuid index f214941acb..df4ac25b6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e863cd09355abd80c1053d6d4dabb55841f806e3c418f923d67d36bf8313cb0 \ No newline at end of file +a61c0e6b78bd39f55464fafd257e68effded64995a66e8fa2d686e8c507ebe43 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index e9640d2389..b68e189140 100644 --- a/src/alter.c +++ b/src/alter.c @@ -1575,7 +1575,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; if( pSelect->selFlags & SF_View ) return WRC_Prune; - if( pSrc==0 ){ + if( NEVER(pSrc==0) ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; } diff --git a/src/build.c b/src/build.c index ecc08f60f7..5506d36de1 100644 --- a/src/build.c +++ b/src/build.c @@ -4595,8 +4595,8 @@ SrcList *sqlite3SrcListAppend( void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; SrcItem *pItem; - assert(pList || pParse->db->mallocFailed ); - if( pList ){ + assert( pList || pParse->db->mallocFailed ); + if( ALWAYS(pList) ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pItem->iCursor>=0 ) continue; pItem->iCursor = pParse->nTab++; diff --git a/src/expr.c b/src/expr.c index d9c8af65c2..bd45fbcd18 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1648,6 +1648,14 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; + if( db->mallocFailed ){ + /* Any prior OOM might have left the Select object incomplete. + ** Delete the whole thing rather than allow an incomplete Select + ** to be used by the code generator. */ + pNew->pNext = 0; + sqlite3SelectDelete(db, pNew); + break; + } *pp = pNew; pp = &pNew->pPrior; pNext = pNew; diff --git a/src/select.c b/src/select.c index 92c2ecf8f9..6a773202e0 100644 --- a/src/select.c +++ b/src/select.c @@ -4207,7 +4207,7 @@ static int flattenSubquery( p->pPrior = pPrior; }else{ pNew->selId = ++pParse->nSelect; - if( aCsrMap && db->mallocFailed==0 ){ + if( aCsrMap && ALWAYS(db->mallocFailed==0) ){ renumberCursors(pParse, pNew, iFrom, aCsrMap); } pNew->pPrior = pPrior; diff --git a/src/walker.c b/src/walker.c index 28c80fa798..e0acd5de22 100644 --- a/src/walker.c +++ b/src/walker.c @@ -164,7 +164,7 @@ int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcItem *pItem; pSrc = p->pSrc; - if( pSrc ){ + if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; From 5b482a98323ee92637e67b55482bf071020fa894 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Apr 2021 13:31:51 +0000 Subject: [PATCH 09/46] Update an assert() in btree.c that may fail with a corrupt database. FossilOrigin-Name: d74bf88c5a027cf080a2892a3538fe5104952b5b3759a6eba1b1a98a75ddf5f4 --- manifest | 16 +++++------ manifest.uuid | 2 +- src/btree.c | 2 +- test/corrupt4.test | 67 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 04fa36690a..155d9af75a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\ssqlite3SelectDup()\sroutine,\sdo\snot\sdo\san\sincomplete\sduplication\sdue\nto\sOOM.\s\sThis\sin\sturn\srequires\sseveral\snew\sNEVER()\sand\sALWAYS()\smacros\sfor\nunreachable\sbranches. -D 2021-04-20T12:14:12.835 +C Update\san\sassert()\sin\sbtree.c\sthat\smay\sfail\swith\sa\scorrupt\sdatabase. +D 2021-04-20T13:31:51.808 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 15cfe91aa3b3b91d3dc20faaa7c64b627ca9794b22be8b184054cb6b947505fc +F src/btree.c 3555069cbe0ce29b44b3b5c7f1c09ee32ce0f52d23ae65e92f7532fba8596962 F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb @@ -781,7 +781,7 @@ F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3 F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35 F test/corrupt3.test 2520432b1fbf99994841e69804a3c59fb828183f4d09b85a1631bc7adca17e31 -F test/corrupt4.test 8d1d86b850fcc43e417450454f2044e52d55778a +F test/corrupt4.test 04965221ecd005901923fdc57f26811fa07178074b0672e50ea424c21638c708 F test/corrupt5.test 387be3250795e2a86e6234745558b80efb248a357d0cd8e53bce75c7463f545d F test/corrupt6.test fc6a891716139665dae0073b6945e3670bf92568 F test/corrupt7.test b036f94bda4b0b23a2919bf717046ce9ecca4543 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3e863cd09355abd80c1053d6d4dabb55841f806e3c418f923d67d36bf8313cb0 -R a2f252b041b1ce9ea09cc93be49d1068 -U drh -Z e9f9190f218ee2534b1576005539f8b4 +P a61c0e6b78bd39f55464fafd257e68effded64995a66e8fa2d686e8c507ebe43 +R 80a099121546ddcbcae1fc148b1f5d09 +U dan +Z d05d5bd1ee90a7e2be097cae4a0b9410 diff --git a/manifest.uuid b/manifest.uuid index df4ac25b6e..af239d71e6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a61c0e6b78bd39f55464fafd257e68effded64995a66e8fa2d686e8c507ebe43 \ No newline at end of file +d74bf88c5a027cf080a2892a3538fe5104952b5b3759a6eba1b1a98a75ddf5f4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7f841145f3..a4179a48fc 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7822,7 +7822,7 @@ static int balance_nonroot( b.szCell[b.nCell] = b.szCell[b.nCell] - leafCorrection; if( !pOld->leaf ){ assert( leafCorrection==0 ); - assert( pOld->hdrOffset==0 ); + assert( pOld->hdrOffset==0 || CORRUPT_DB ); /* The right pointer of the child page pOld becomes the left ** pointer of the divider cell */ memcpy(b.apCell[b.nCell], &pOld->aData[8], 4); diff --git a/test/corrupt4.test b/test/corrupt4.test index 55969c6a8c..0aa42aa6ab 100644 --- a/test/corrupt4.test +++ b/test/corrupt4.test @@ -13,10 +13,10 @@ # This file implements tests to make sure SQLite does not crash or # segfault if it sees a corrupt database file. # -# $Id: corrupt4.test,v 1.1 2007/09/07 14:32:07 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix corrupt4 # This module uses hard-coded offsets which do not work if the reserved_bytes # value is nonzero. @@ -79,4 +79,69 @@ do_test corrupt4-1.4 { } } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- + +reset_db +do_execsql_test 2.0 { + PRAGMA page_size = 512; + CREATE TABLE t1(a, b, c); +} + +# Create a database with a schema so large that the root of the +# sqlite_schema table is the grandparent of its leaves. +# +set nView 1000 +do_test 2.1 { + execsql BEGIN + for {set ii 0} {$ii<$nView} {incr ii} { + execsql " CREATE VIEW v$ii AS SELECT a, b, c FROM t1 " + } + execsql COMMIT +} {} +db close + +proc get2byte {fd offset} { + seek $fd $offset + set bin [read $fd 2] + binary scan $bin S val + set val +} +proc get4byte {fd offset} { + seek $fd $offset + set bin [read $fd 4] + binary scan $bin I val + set val +} +proc put4byte {fd offset val} { + seek $fd $offset + set bin [binary format I $val] + puts -nonewline $fd $bin +} + +# Page 1 is now the grandparent of its leaves. Corrupt the database by setting +# the second rightmost child page number of page 1 to 1. +# +set fd [open test.db r+] +fconfigure $fd -encoding binary -translation binary +set nChild [get2byte $fd 103] +set offChild [get2byte $fd [expr 100+12+($nChild-2)*2]] +set pgnoChild [get4byte $fd $offChild] +put4byte $fd $offChild 1 +close $fd + +sqlite3 db test.db +do_catchsql_test 2.2 { + PRAGMA writable_schema = 1; + SELECT * FROM sqlite_schema; +} {1 {database disk image is malformed}} + +do_test 2.3 { + list [catch { + for {set ii $nView} {$ii<$nView*2} {incr ii} { + execsql "INSERT INTO sqlite_master VALUES(1, 2, 3, 4, 5)" + } + } msg] $msg +} {1 {database disk image is malformed}} + + finish_test From 8cae5a4a4706be4bed8b1c6a62e2923d669e0ae5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Apr 2021 20:48:15 +0000 Subject: [PATCH 10/46] More aggressive detection of database corruption in the rebuildPage() routine. FossilOrigin-Name: a18c65068b16eae3c0725356d7f4775774b23e248c700cef8c15f23459fba68f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 155d9af75a..a8d9b104c9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\san\sassert()\sin\sbtree.c\sthat\smay\sfail\swith\sa\scorrupt\sdatabase. -D 2021-04-20T13:31:51.808 +C More\saggressive\sdetection\sof\sdatabase\scorruption\sin\sthe\srebuildPage()\sroutine. +D 2021-04-20T20:48:15.264 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 3555069cbe0ce29b44b3b5c7f1c09ee32ce0f52d23ae65e92f7532fba8596962 +F src/btree.c df156adf8b9e9532444d32b14548e35857f5be63c7318cfaa22115eaf77c76c9 F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a61c0e6b78bd39f55464fafd257e68effded64995a66e8fa2d686e8c507ebe43 -R 80a099121546ddcbcae1fc148b1f5d09 -U dan -Z d05d5bd1ee90a7e2be097cae4a0b9410 +P d74bf88c5a027cf080a2892a3538fe5104952b5b3759a6eba1b1a98a75ddf5f4 +R 146268cd6811e69e250b31bcf994c66e +U drh +Z 17d2d4ab29ad0140facb747d5996c2c2 diff --git a/manifest.uuid b/manifest.uuid index af239d71e6..68aa084580 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d74bf88c5a027cf080a2892a3538fe5104952b5b3759a6eba1b1a98a75ddf5f4 \ No newline at end of file +a18c65068b16eae3c0725356d7f4775774b23e248c700cef8c15f23459fba68f \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index a4179a48fc..7083f8d386 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7015,7 +7015,7 @@ static int rebuildPage( u8 *pCell = pCArray->apCell[i]; u16 sz = pCArray->szCell[i]; assert( sz>0 ); - if( SQLITE_WITHIN(pCell,aData,pEnd) ){ + if( SQLITE_WITHIN(pCell,aData+j,pEnd) ){ if( ((uptr)(pCell+sz))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; pCell = &pTmp[pCell - aData]; }else if( (uptr)(pCell+sz)>(uptr)pSrcEnd From 935ad98d60de4e76b101a4fcaedc599b46491d63 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 20 Apr 2021 22:48:25 +0000 Subject: [PATCH 11/46] Remove a testcase() that is no longer relevant due to the previous check-in. FossilOrigin-Name: ca70c8ac72c9fe3b92f8e63151229bebdccc769c5c4d603ad4f466dc4bcd11e0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a8d9b104c9..cf6df27caa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\saggressive\sdetection\sof\sdatabase\scorruption\sin\sthe\srebuildPage()\sroutine. -D 2021-04-20T20:48:15.264 +C Remove\sa\stestcase()\sthat\sis\sno\slonger\srelevant\sdue\sto\sthe\sprevious\scheck-in. +D 2021-04-20T22:48:25.584 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c df156adf8b9e9532444d32b14548e35857f5be63c7318cfaa22115eaf77c76c9 +F src/btree.c c747dca6b20dbc6f4de8aad99ac6deae153a099af95718de366c602bb9121a63 F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d74bf88c5a027cf080a2892a3538fe5104952b5b3759a6eba1b1a98a75ddf5f4 -R 146268cd6811e69e250b31bcf994c66e +P a18c65068b16eae3c0725356d7f4775774b23e248c700cef8c15f23459fba68f +R 5da520d950e2a8ca4b2fc54669f1ae8e U drh -Z 17d2d4ab29ad0140facb747d5996c2c2 +Z 554a359b2c97402a5807dfb93b98164e diff --git a/manifest.uuid b/manifest.uuid index 68aa084580..92996aa011 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a18c65068b16eae3c0725356d7f4775774b23e248c700cef8c15f23459fba68f \ No newline at end of file +ca70c8ac72c9fe3b92f8e63151229bebdccc769c5c4d603ad4f466dc4bcd11e0 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7083f8d386..7ff0a46e1e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7030,7 +7030,6 @@ static int rebuildPage( if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; memcpy(pData, pCell, sz); assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); - testcase( sz!=pPg->xCellSize(pPg,pCell) ) i++; if( i>=iEnd ) break; if( pCArray->ixNx[k]<=i ){ From fe599b05f2d6c3700146d30efc82753951a2b482 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Apr 2021 11:32:22 +0000 Subject: [PATCH 12/46] Fix a problem allowing SQL variables to be used expressions within the second and subsequent ON CONFLICT clauses of an UPSERT within a trigger. FossilOrigin-Name: 2a28910a17dc5b3ce43062fdf879f9622f6ec2db19ed780fa7fe5cae781be7b7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/attach.c | 18 ++++++++++-------- test/trigger2.test | 21 ++++++++++++++++++++- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index cf6df27caa..4906a94385 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\stestcase()\sthat\sis\sno\slonger\srelevant\sdue\sto\sthe\sprevious\scheck-in. -D 2021-04-20T22:48:25.584 +C Fix\sa\sproblem\sallowing\sSQL\svariables\sto\sbe\sused\sexpressions\swithin\sthe\ssecond\sand\ssubsequent\sON\sCONFLICT\sclauses\sof\san\sUPSERT\swithin\sa\strigger. +D 2021-04-21T11:32:22.033 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -478,7 +478,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c e7caf3eefce268250dc1d10322eec637319de486aa1bae7f48c606259455537e F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c 8783d67d2c61371dfae46e4043158d44b73c14154d62560cd4cb1e0dfc6337a1 +F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -1618,7 +1618,7 @@ F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test 239eec5343388983f112c16d666aa89960cd85302b6af6cd8408ce8edb7b3316 F test/trigger1.test d30cd09ae8ac365a088f09daba583cc5c0b8fc7d4e1d70809d0b4be3bf6ae2ab -F test/trigger2.test d15da46f7012832faf3e0c536b47024409d5fb1722d2bb77e29c06d96d704bb1 +F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a18c65068b16eae3c0725356d7f4775774b23e248c700cef8c15f23459fba68f -R 5da520d950e2a8ca4b2fc54669f1ae8e -U drh -Z 554a359b2c97402a5807dfb93b98164e +P ca70c8ac72c9fe3b92f8e63151229bebdccc769c5c4d603ad4f466dc4bcd11e0 +R 488802624573ed85b9dab18218ec296a +U dan +Z 006370ce7463f27ee095e187ed12f536 diff --git a/manifest.uuid b/manifest.uuid index 92996aa011..8162c17061 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ca70c8ac72c9fe3b92f8e63151229bebdccc769c5c4d603ad4f466dc4bcd11e0 \ No newline at end of file +2a28910a17dc5b3ce43062fdf879f9622f6ec2db19ed780fa7fe5cae781be7b7 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 9bd57f2865..dcfa4910d0 100644 --- a/src/attach.c +++ b/src/attach.c @@ -573,14 +573,16 @@ int sqlite3FixTriggerStep( return 1; } #ifndef SQLITE_OMIT_UPSERT - if( pStep->pUpsert ){ - Upsert *pUp = pStep->pUpsert; - if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) - || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) - || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) - || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) - ){ - return 1; + { + Upsert *pUp; + for(pUp=pStep->pUpsert; pUp; pUp=pUp->pNextUpsert){ + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) + ){ + return 1; + } } } #endif diff --git a/test/trigger2.test b/test/trigger2.test index 1be72131f7..6e007e969a 100644 --- a/test/trigger2.test +++ b/test/trigger2.test @@ -49,6 +49,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix trigger2 ifcapable {!trigger} { finish_test return @@ -769,6 +770,24 @@ do_execsql_test trigger2-10.1 { } ;# ifcapable view -integrity_check trigger2-999 +#------------------------------------------------------------------------- +reset_db +do_execsql_test 11.1 { + CREATE TABLE t1(a INT PRIMARY KEY, b, c REAL, d, e); + CREATE TABLE t2(a INT, b, c REAL, d, e, PRIMARY KEY(a,b)) WITHOUT ROWID; + CREATE UNIQUE INDEX t2c ON t2(c); + CREATE UNIQUE INDEX t2d ON t2(d); + CREATE UNIQUE INDEX t2e ON t2(e); +} + +do_catchsql_test 11.2 { + CREATE TRIGGER r1 BEFORE INSERT ON t1 BEGIN + INSERT INTO t2(a,b,c,d,e) VALUES(91,NULL,93,94,?1) + ON CONFLICT(b,a) DO NOTHING + ON CONFLICT DO UPDATE SET b=?1; + END; +} {1 {trigger cannot use variables}} + finish_test + From f02b5ad69d6f5544a28c5dfc06d86b0687099905 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 21 Apr 2021 11:58:45 +0000 Subject: [PATCH 13/46] Initialize the key registers in the skip-scan optimization to NULL, in case the query is run on a corrupt database that causes the initialization of the key to be bypassed. dbsqlfuzz 62fdf2bece00d24cac8a4edf2cf562e6eeac779d FossilOrigin-Name: 8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4906a94385..44bb1924bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sallowing\sSQL\svariables\sto\sbe\sused\sexpressions\swithin\sthe\ssecond\sand\ssubsequent\sON\sCONFLICT\sclauses\sof\san\sUPSERT\swithin\sa\strigger. -D 2021-04-21T11:32:22.033 +C Initialize\sthe\skey\sregisters\sin\sthe\sskip-scan\soptimization\sto\sNULL,\sin\scase\nthe\squery\sis\srun\son\sa\scorrupt\sdatabase\sthat\scauses\sthe\sinitialization\sof\sthe\nkey\sto\sbe\sbypassed.\ndbsqlfuzz\s62fdf2bece00d24cac8a4edf2cf562e6eeac779d +D 2021-04-21T11:58:45.294 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -631,7 +631,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 -F src/wherecode.c 0e42f4ad53962e90349462520891734ed3217c7852f41c69ffac7a9eeaf31451 +F src/wherecode.c b4f24544fbaf5ecf0d060d9581e14df7c0de51b5e6c37af5b98048a9ba551b72 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ca70c8ac72c9fe3b92f8e63151229bebdccc769c5c4d603ad4f466dc4bcd11e0 -R 488802624573ed85b9dab18218ec296a -U dan -Z 006370ce7463f27ee095e187ed12f536 +P 2a28910a17dc5b3ce43062fdf879f9622f6ec2db19ed780fa7fe5cae781be7b7 +R 7954326a489059bc0b41d93e80081e98 +U drh +Z f97fdbdacd88c3e91a37650b0d0d7542 diff --git a/manifest.uuid b/manifest.uuid index 8162c17061..fef1c558e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2a28910a17dc5b3ce43062fdf879f9622f6ec2db19ed780fa7fe5cae781be7b7 \ No newline at end of file +8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 9c43607320..25ba60854f 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -700,6 +700,7 @@ static int codeAllEqualityTerms( if( nSkip ){ int iIdxCur = pLevel->iIdxCur; + sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, nSkip); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); From 7437c25b63be5cdf678dc5d2f25d1837c126c8b7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 21 Apr 2021 12:03:36 +0000 Subject: [PATCH 14/46] Add recent dbsqlfuzz test cases to test/fuzzdata8.db. FossilOrigin-Name: 6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzdata8.db | Bin 1980416 -> 2080768 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 44bb1924bc..8307184414 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Initialize\sthe\skey\sregisters\sin\sthe\sskip-scan\soptimization\sto\sNULL,\sin\scase\nthe\squery\sis\srun\son\sa\scorrupt\sdatabase\sthat\scauses\sthe\sinitialization\sof\sthe\nkey\sto\sbe\sbypassed.\ndbsqlfuzz\s62fdf2bece00d24cac8a4edf2cf562e6eeac779d -D 2021-04-21T11:58:45.294 +C Add\srecent\sdbsqlfuzz\stest\scases\sto\stest/fuzzdata8.db. +D 2021-04-21T12:03:36.478 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1056,7 +1056,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db 74b8510c083d3d59cd66a5336051960b7d6517590cc9bfdcb2f68fcbd26dd18f +F test/fuzzdata8.db a5f04edee03f0446759272e976f7e68568201077b8adf5c769f5b2a8ddc3e10d F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2a28910a17dc5b3ce43062fdf879f9622f6ec2db19ed780fa7fe5cae781be7b7 -R 7954326a489059bc0b41d93e80081e98 +P 8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b +R 164f9f0b95c7a15d85aa81eeb6367354 U drh -Z f97fdbdacd88c3e91a37650b0d0d7542 +Z 7326b988597bb541d036316f91b93fa0 diff --git a/manifest.uuid b/manifest.uuid index fef1c558e2..9dac01beae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b \ No newline at end of file +6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 68c10cbc5156d8427fc984fabab96b5188b53448..463a5d274e57af108dc3cc99f0be7c9ac8928f6f 100644 GIT binary patch delta 77510 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 From a23a873fbb02bdb20923aae7d2476f07d4245bc3 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Apr 2021 20:52:17 +0000 Subject: [PATCH 15/46] Add the experimental sqlite3session_changeset_size() API. FossilOrigin-Name: b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8 --- ext/session/sessionsize.test | 108 ++++++++++++++++++++++++++ ext/session/sqlite3session.c | 143 +++++++++++++++++++++++++++++++---- ext/session/sqlite3session.h | 11 +++ ext/session/test_session.c | 7 ++ manifest | 34 +++++---- manifest.uuid | 2 +- src/sqlite.h.in | 10 +++ src/vdbe.c | 4 +- src/vdbeInt.h | 4 +- src/vdbeapi.c | 11 +++ src/vdbeaux.c | 4 +- src/vdbeblob.c | 2 +- 12 files changed, 305 insertions(+), 35 deletions(-) create mode 100644 ext/session/sessionsize.test diff --git a/ext/session/sessionsize.test b/ext/session/sessionsize.test new file mode 100644 index 0000000000..8347097e96 --- /dev/null +++ b/ext/session/sessionsize.test @@ -0,0 +1,108 @@ +# 2021 April 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. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionsize + +proc do_changeset_size_test {tn sql} { + sqlite3session S db main + S attach * + db eval $sql + + set sz [S changeset_size] + set C [S changeset] + set szC [string length $C] + S delete + + do_test $tn "expr $sz" $szC +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 'abc', 'def'); + INSERT INTO t1 VALUES(2, 'ghi', 'jkl'); +} + +do_changeset_size_test 1.1 { + INSERT INTO t1 VALUES(3, 'hello', 'world'); +} + +do_changeset_size_test 1.2 { + DELETE FROM t1 WHERE a=2; +} + +do_changeset_size_test 1.3 { + DELETE FROM t1 WHERE a=3; + INSERT INTO t1 VALUES(3, 1, 2); +} + +do_changeset_size_test 1.4 { + UPDATE t1 SET c='hello world' WHERE a=3; +} + +#------------------------------------------------------------------------- + +do_execsql_test 2.0 { + CREATE TABlE t2(a, b, c, d, PRIMARY KEY(a, b)) WITHOUT ROWID; + CREATE TABlE t3(a, b, c, d PRIMARY KEY); +} + +do_changeset_size_test 2.1 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50 + ) + INSERT INTO t2 SELECT i, i+1, i+2, i+3 FROM s; + + UPDATE t2 SET c=randomblob(a) WHERE a>10 +} + +do_changeset_size_test 2.2 { + DELETE FROM t2 WHERE a=1; + INSERT INTO t2 VALUES(1, 4, 3, 4); +} + +do_changeset_size_test 2.2 { + UPDATE t2 SET b=4 WHERE a=2 +} + +do_changeset_size_test 2.3 { + INSERT INTO t2 VALUES('a', 'b', 'c', 'd'); + UPDATE t2 SET c='qwertyuiop' WHERE a='a'; +} + +do_changeset_size_test 2.4 { + DELETE FROM t2 WHERE a='a'; + INSERT INTO t2 VALUES('a', 'b', 'c', 'd'); +} + +do_changeset_size_test 2.5 { + UPDATE t2 SET a='aa', b='bb' WHERE (a, b) = ('a', 'b'); +} + +do_changeset_size_test 2.6 { + UPDATE t2 SET a='a', b='b' WHERE (a, b) = ('aa', 'bb'); +} + +do_changeset_size_test 2.7 { + INSERT INTO t3 DEFAULT VALUES; + INSERT INTO t3 VALUES(1,2,3,4); +} + +finish_test + diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 8210056a89..077a6e0900 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -49,6 +49,7 @@ struct sqlite3_session { void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); i64 nMalloc; /* Number of bytes of data allocated */ + i64 nMaxChangesetSize; sqlite3_value *pZeroBlob; /* Value containing X'' */ sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ @@ -291,8 +292,9 @@ struct SessionTable { ** this structure stored in a SessionTable.aChange[] hash table. */ struct SessionChange { - int op; /* One of UPDATE, DELETE, INSERT */ - int bIndirect; /* True if this change is "indirect" */ + u8 op; /* One of UPDATE, DELETE, INSERT */ + u8 bIndirect; /* True if this change is "indirect" */ + int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ SessionChange *pNext; /* For hash-table collisions */ @@ -1121,6 +1123,10 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){ pTab->bStat1 = 1; } + + pSession->nMaxChangesetSize += ( + 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName) + 1 + ); } } return (pSession->rc || pTab->abPK==0); @@ -1166,6 +1172,103 @@ static int sessionStat1Depth(void *pCtx){ return p->hook.xDepth(p->hook.pCtx); } +static int sessionUpdateMaxSize( + int op, + sqlite3_session *pSession, /* Session object pTab is attached to */ + SessionTable *pTab, /* Table that change applies to */ + SessionChange *pC /* Update pC->nMaxSize */ +){ + i64 nNew = 2; + if( pC->op==SQLITE_INSERT ){ + if( op!=SQLITE_DELETE ){ + int ii; + for(ii=0; iinCol; ii++){ + sqlite3_value *p = 0; + pSession->hook.xNew(pSession->hook.pCtx, ii, &p); + sessionSerializeValue(0, p, &nNew); + } + } + }else if( op==SQLITE_DELETE ){ + nNew += pC->nRecord; + if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){ + nNew += pC->nRecord; + } + }else{ + int ii; + u8 *pCsr = pC->aRecord; + for(ii=0; iinCol; ii++){ + int bChanged = 1; + int nOld = 0; + int eType; + sqlite3_value *p = 0; + pSession->hook.xNew(pSession->hook.pCtx, ii, &p); + if( p==0 ){ + return SQLITE_NOMEM; + } + + eType = *pCsr++; + switch( eType ){ + case SQLITE_NULL: + bChanged = sqlite3_value_type(p)!=SQLITE_NULL; + break; + + case SQLITE_FLOAT: + case SQLITE_INTEGER: { + if( eType==sqlite3_value_type(p) ){ + sqlite3_int64 iVal = sessionGetI64(pCsr); + if( eType==SQLITE_INTEGER ){ + bChanged = (iVal!=sqlite3_value_int64(p)); + }else{ + double dVal; + memcpy(&dVal, &iVal, 8); + bChanged = (dVal!=sqlite3_value_double(p)); + } + } + nOld = 8; + pCsr += 8; + break; + } + + default: { + int nByte; + nOld = sessionVarintGet(pCsr, &nByte); + pCsr += nOld; + nOld += nByte; + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + if( eType==sqlite3_value_type(p) + && nByte==sqlite3_value_bytes(p) + && (nByte==0 || 0==memcmp(pCsr, sqlite3_value_blob(p), nByte)) + ){ + bChanged = 0; + } + pCsr += nByte; + break; + } + } + + if( bChanged && pTab->abPK[ii] ){ + nNew = pC->nRecord + 2; + break; + } + + if( bChanged ){ + nNew += 1 + nOld; + sessionSerializeValue(0, p, &nNew); + }else if( pTab->abPK[ii] ){ + nNew += 2 + nOld; + }else{ + nNew += 2; + } + } + } + + if( nNew>pC->nMaxSize ){ + int nIncr = nNew - pC->nMaxSize; + pC->nMaxSize = nNew; + pSession->nMaxChangesetSize += nIncr; + } + return SQLITE_OK; +} /* ** This function is only called from with a pre-update-hook reporting a @@ -1239,7 +1342,6 @@ static void sessionPreupdateOneChange( /* Create a new change object containing all the old values (if ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK ** values (if this is an INSERT). */ - SessionChange *pChange; /* New change object */ sqlite3_int64 nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ @@ -1265,13 +1367,13 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sessionMalloc64(pSession, nByte); - if( !pChange ){ + pC = (SessionChange *)sessionMalloc64(pSession, nByte); + if( !pC ){ rc = SQLITE_NOMEM; goto error_out; }else{ - memset(pChange, 0, sizeof(SessionChange)); - pChange->aRecord = (u8 *)&pChange[1]; + memset(pC, 0, sizeof(SessionChange)); + pC->aRecord = (u8 *)&pC[1]; } /* Populate the change object. None of the preupdate_old(), @@ -1286,17 +1388,17 @@ static void sessionPreupdateOneChange( }else if( pTab->abPK[i] ){ pSession->hook.xNew(pSession->hook.pCtx, i, &p); } - sessionSerializeValue(&pChange->aRecord[nByte], p, &nByte); + sessionSerializeValue(&pC->aRecord[nByte], p, &nByte); } /* Add the change to the hash-table */ if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ - pChange->bIndirect = 1; + pC->bIndirect = 1; } - pChange->nRecord = nByte; - pChange->op = op; - pChange->pNext = pTab->apChange[iHash]; - pTab->apChange[iHash] = pChange; + pC->nRecord = nByte; + pC->op = op; + pC->pNext = pTab->apChange[iHash]; + pTab->apChange[iHash] = pC; }else if( pC->bIndirect ){ /* If the existing change is considered "indirect", but this current @@ -1307,8 +1409,12 @@ static void sessionPreupdateOneChange( pC->bIndirect = 0; } } + + assert( rc==SQLITE_OK ); + rc = sessionUpdateMaxSize(op, pSession, pTab, pC); } + /* If an error has occurred, mark the session object as failed. */ error_out: if( pTab->bStat1 ){ @@ -2520,7 +2626,9 @@ int sqlite3session_changeset( int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ - return sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset, ppChangeset); + int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); + assert( rc || pnChangeset==0 || *pnChangeset<=pSession->nMaxChangesetSize ); + return rc; } /* @@ -2612,6 +2720,13 @@ sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ return pSession->nMalloc; } +/* +** Return the maximum size of sqlite3session_changeset() output. +*/ +sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession){ + return pSession->nMaxChangesetSize; +} + /* ** Do the work for either sqlite3changeset_start() or start_strm(). */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 9ebf360ea3..78d25ba0f3 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -323,6 +323,17 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ); +/* +** CAPI3REF: Load The Difference Between Tables Into A Session +** METHOD: sqlite3session_changeset_size() +** +** This function returns an upper limit, in bytes, of the size of the +** changeset that might be produced if sqlite3session_changeset() were +** called. The final changeset size might be equal to or smaller than +** the size in bytes returned by this function. +*/ +sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); + /* ** CAPI3REF: Load The Difference Between Tables Into A Session ** METHOD: sqlite3_session diff --git a/ext/session/test_session.c b/ext/session/test_session.c index c3898fd860..b7c96b2657 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -246,6 +246,7 @@ static int SQLITE_TCLAPI test_session_cmd( { "patchset", 0, "", }, /* 7 */ { "diff", 2, "FROMDB TBL", }, /* 8 */ { "memory_used", 0, "", }, /* 9 */ + { "changeset_size", 0, "", }, /* 10 */ { 0 } }; int iSub; @@ -357,6 +358,12 @@ static int SQLITE_TCLAPI test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nMalloc)); break; } + + case 10: { + sqlite3_int64 nSize = sqlite3session_changeset_size(pSession); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSize)); + break; + } } return TCL_OK; diff --git a/manifest b/manifest index 8307184414..0c5737175f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srecent\sdbsqlfuzz\stest\scases\sto\stest/fuzzdata8.db. -D 2021-04-21T12:03:36.478 +C Add\sthe\sexperimental\ssqlite3session_changeset_size()\sAPI. +D 2021-04-21T20:52:17.903 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -453,11 +453,12 @@ F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 +F ext/session/sessionsize.test 32ce42e9fed589276ef072b68c6f325e54ef7ef67c37ccd3ec8c822dd997f3c7 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c a7c5ac1acfe21d94b37921b29b0458d64d022a66b282338eee4aafa9c018cb1c -F ext/session/sqlite3session.h f48662626e7a3176a188787a0bd360933dd46cccd98df01c208b02051c540fb7 -F ext/session/test_session.c 90ccf1c30c857bd2fb3f6c990163e8f389ddbdbdc7fa5baa2f6f5f287df41c08 +F ext/session/sqlite3session.c b205b57eecfb93aee23653ba4b07be6930afaa3760317c22ad9872a0bc451d3f +F ext/session/sqlite3session.h 7d05ae78d03f778bf13f8160595b263d9436260137a8f50c78dc956f4d5121e2 +F ext/session/test_session.c b3d03f73b73d3794007392cf5a9bc27d1a2d3e970d500ab52026c726fa528142 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb @@ -544,7 +545,7 @@ F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 -F src/sqlite.h.in 18ec33e32001721fd4e9c4705a24a85dff04956ac2c0a21775058884ba845b09 +F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqliteInt.h 234ab17b1797cbc2adb7741a15786edf72bc96d40b4de68795e91926cfd46eba @@ -614,12 +615,12 @@ F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286 -F src/vdbe.c 045088321542f47419b30be7088137097a9a80946e8eee163899d3ab3d5d9312 +F src/vdbe.c ff3ccdd969774e6ce821b54d076286c84137e2f0e6387b1133bafbaa7470f749 F src/vdbe.h 25dabb25c7e157b84e59260cfb5b466c3ac103ede9f36f4db371332c47601abe -F src/vdbeInt.h 000d9ab1ea4cb55a80de15e28f3f595645b4fddef34bca4347fb3db8031d9041 -F src/vdbeapi.c 4a43e303ec3354c785f453e881521969378e85628278ab74ba4a9df790c0d93b -F src/vdbeaux.c 1ffaf15d48b1678dfd403c02ee60061c10a5dd447051860e793cd3393ab019fe -F src/vdbeblob.c 37d627ef71aca9a11b3c4063b3d7f1a5f14c4364f9abded40016e37bf15ba392 +F src/vdbeInt.h 58980223a32495ad059d10581b83e133abdc77248b1bab85c080cab8a13bd819 +F src/vdbeapi.c d9e99daf59fec928986838b3389a7337e82fec6b3b5de30206cb99fb4661b94e +F src/vdbeaux.c 065a10392378109f08435bd50d03dff315e384cde2831d6b8dbaec05f33b10af +F src/vdbeblob.c c6b8db50b227f66fb404215732068df76485b5b433e5f9d4d9ac27410b218193 F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 @@ -1913,7 +1914,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b -R 164f9f0b95c7a15d85aa81eeb6367354 -U drh -Z 7326b988597bb541d036316f91b93fa0 +P 6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 +R e870b873cf49a44c733c175dd8b4c0b8 +T *branch * session-changeset-size +T *sym-session-changeset-size * +T -sym-trunk * +U dan +Z c5add95d4af95f7f7d5a36a6c86b17cc diff --git a/manifest.uuid b/manifest.uuid index 9dac01beae..3de85455ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 \ No newline at end of file +b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9085dc882a..56f23f2b08 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9546,6 +9546,15 @@ int sqlite3_db_cacheflush(sqlite3*); ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** +** When the [sqlite3_blob_write()] API is used to update a blob column, +** the pre-update hook is invoked with SQLITE_DELETE. This is because the +** in this case the new values are not available. In this case, when a +** callback made with op==SQLITE_DELETE is actuall a write using the +** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns +** the index of the column being written. In other cases, where the +** pre-update hook is being invoked for some other reason, including a +** regular DELETE, sqlite3_preupdate_blobwrite() returns -1. +** ** See also: [sqlite3_update_hook()] */ #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) @@ -9566,6 +9575,7 @@ int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); int sqlite3_preupdate_count(sqlite3 *); int sqlite3_preupdate_depth(sqlite3 *); int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); +int sqlite3_preupdate_blobwrite(sqlite3 *); #endif /* diff --git a/src/vdbe.c b/src/vdbe.c index cb4e5ea8d3..c34ea72453 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5080,7 +5080,7 @@ case OP_Insert: { /* Invoke the pre-update hook, if any */ if( pTab ){ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ - sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); + sqlite3VdbePreUpdateHook(p,pC,SQLITE_INSERT,zDb,pTab,x.nKey,pOp->p2,-1); } if( db->xUpdateCallback==0 || pTab->aCol==0 ){ /* Prevent post-update hook from running in cases when it should not */ @@ -5240,7 +5240,7 @@ case OP_Delete: { sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, pTab, pC->movetoTarget, - pOp->p3 + pOp->p3, -1 ); } if( opflags & OPFLAG_ISNOOP ) break; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index cb423f20a1..5e3e523f92 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -472,6 +472,7 @@ struct PreUpdate { UnpackedRecord *pUnpacked; /* Unpacked version of aRecord[] */ UnpackedRecord *pNewUnpacked; /* Unpacked version of new.* record */ int iNewReg; /* Register for new.* values */ + int iBlobWrite; /* Value returned by preupdate_blobwrite() */ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ @@ -560,7 +561,8 @@ void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK -void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); +void sqlite3VdbePreUpdateHook( + Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int,int); #endif int sqlite3VdbeTransferError(Vdbe *p); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index ba3bdf6a5f..b21634dc80 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1905,6 +1905,17 @@ int sqlite3_preupdate_depth(sqlite3 *db){ } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +/* +** This function is designed to be called from within a pre-update callback +** only. +*/ +int sqlite3_preupdate_blobwrite(sqlite3 *db){ + PreUpdate *p = db->pPreUpdate; + return (p ? p->iBlobWrite : -1); +} +#endif + #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is called from within a pre-update callback to retrieve diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 296408064f..d22a6a5592 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5189,7 +5189,8 @@ void sqlite3VdbePreUpdateHook( const char *zDb, /* Database name */ Table *pTab, /* Modified table */ i64 iKey1, /* Initial key value */ - int iReg /* Register for new.* record */ + int iReg, /* Register for new.* record */ + int iBlobWrite ){ sqlite3 *db = v->db; i64 iKey2; @@ -5225,6 +5226,7 @@ void sqlite3VdbePreUpdateHook( preupdate.iKey1 = iKey1; preupdate.iKey2 = iKey2; preupdate.pTab = pTab; + preupdate.iBlobWrite = iBlobWrite; db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 47e3497dd0..a4e79bf89b 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -420,7 +420,7 @@ static int blobReadWrite( sqlite3_int64 iKey; iKey = sqlite3BtreeIntegerKey(p->pCsr); sqlite3VdbePreUpdateHook( - v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1 + v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol ); } #endif From 31536304a5f1d1f6eb91a77f597909474fff7c63 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 21 Apr 2021 23:13:26 +0000 Subject: [PATCH 16/46] The new OP_Null opcode from check-in [8b54102a00852b72] was not coded correctly. This check-in attempts to fix that. FossilOrigin-Name: 02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8307184414..a267bec5dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\srecent\sdbsqlfuzz\stest\scases\sto\stest/fuzzdata8.db. -D 2021-04-21T12:03:36.478 +C The\snew\sOP_Null\sopcode\sfrom\scheck-in\s[8b54102a00852b72]\swas\snot\scoded\ncorrectly.\s\sThis\scheck-in\sattempts\sto\sfix\sthat. +D 2021-04-21T23:13:26.408 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -631,7 +631,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 -F src/wherecode.c b4f24544fbaf5ecf0d060d9581e14df7c0de51b5e6c37af5b98048a9ba551b72 +F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8b54102a00852b72783b5b2f336c7a093adbdc8e1b94d46b7d315ae6e5d9476b -R 164f9f0b95c7a15d85aa81eeb6367354 +P 6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 +R c08ea2e3d9f1c824a6f5c3535918762c U drh -Z 7326b988597bb541d036316f91b93fa0 +Z 1a1da1d17ff339b1b7dc133d35a59f0c diff --git a/manifest.uuid b/manifest.uuid index 9dac01beae..fc9b5114be 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 \ No newline at end of file +02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 25ba60854f..6b4bc8a217 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -700,7 +700,7 @@ static int codeAllEqualityTerms( if( nSkip ){ int iIdxCur = pLevel->iIdxCur; - sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, nSkip); + sqlite3VdbeAddOp3(v, OP_Null, 0, regBase, regBase+nSkip-1); sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); From 824043150fde6d8b221138c95fb18bf3d75c674f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 12:38:30 +0000 Subject: [PATCH 17/46] In the whereLoopXfer() routine, ensure that the destination is fully initialized even if an OOM error occurs. FossilOrigin-Name: c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a267bec5dd..9c363fb2b9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\snew\sOP_Null\sopcode\sfrom\scheck-in\s[8b54102a00852b72]\swas\snot\scoded\ncorrectly.\s\sThis\scheck-in\sattempts\sto\sfix\sthat. -D 2021-04-21T23:13:26.408 +C In\sthe\swhereLoopXfer()\sroutine,\sensure\sthat\sthe\sdestination\sis\sfully\ninitialized\seven\sif\san\sOOM\serror\soccurs. +D 2021-04-22T12:38:30.898 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -629,7 +629,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 -F src/where.c 1c305bab0996a63219a6cb3d4718587f3a5dc5608120c4448985aa2bef88b7f5 +F src/where.c cb76c17d0bded653040cb16e2f4532fa7b20f5f8c205f4078d346562821107a2 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 -R c08ea2e3d9f1c824a6f5c3535918762c +P 02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04 +R 3d8464626ec4ed7160b5e3f3b7bf199b U drh -Z 1a1da1d17ff339b1b7dc133d35a59f0c +Z 9339130783244dccd8482f7c789d5fd4 diff --git a/manifest.uuid b/manifest.uuid index fc9b5114be..8ee3ab80b8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04 \ No newline at end of file +c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 97814d4316..5859f866e0 100644 --- a/src/where.c +++ b/src/where.c @@ -1942,7 +1942,7 @@ static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ whereLoopClearUnion(db, pTo); if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ - memset(&pTo->u, 0, sizeof(pTo->u)); + memset(pTo, 0, WHERE_LOOP_XFER_SZ); return SQLITE_NOMEM_BKPT; } memcpy(pTo, pFrom, WHERE_LOOP_XFER_SZ); From 1da9c97bc0f80f9e05348b36f6cdfb61aee3010f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 13:59:54 +0000 Subject: [PATCH 18/46] Ensure that the typedefs for specific-length integers in zipfile.c are correct. FossilOrigin-Name: f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5 --- ext/misc/zipfile.c | 22 ++++++++++++++++++++-- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index f9fbcfc0bd..4aefc61dcc 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -36,10 +36,24 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_AMALGAMATION +#ifndef UINT32_TYPE +# ifdef HAVE_UINT32_T +# define UINT32_TYPE uint32_t +# else +# define UINT32_TYPE unsigned int +# endif +#endif +#ifndef UINT16_TYPE +# ifdef HAVE_UINT16_T +# define UINT16_TYPE uint16_t +# else +# define UINT16_TYPE unsigned short int +# endif +#endif typedef sqlite3_int64 i64; typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned long u32; +typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ +typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ #define MIN(a,b) ((a)<(b) ? (a) : (b)) #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) @@ -2170,6 +2184,10 @@ static int zipfileRegister(sqlite3 *db){ zipfileStep, zipfileFinal ); } + assert( sizeof(i64)==8 ); + assert( sizeof(u32)==4 ); + assert( sizeof(u16)==2 ); + assert( sizeof(u8)==1 ); return rc; } #else /* SQLITE_OMIT_VIRTUALTABLE */ diff --git a/manifest b/manifest index 9c363fb2b9..56bf854028 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\swhereLoopXfer()\sroutine,\sensure\sthat\sthe\sdestination\sis\sfully\ninitialized\seven\sif\san\sOOM\serror\soccurs. -D 2021-04-22T12:38:30.898 +C Ensure\sthat\sthe\stypedefs\sfor\sspecific-length\sintegers\sin\szipfile.c\sare\ncorrect. +D 2021-04-22T13:59:54.423 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -337,7 +337,7 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0 F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c e35e035bc2765b1ccdcb15f9815c2112843fcbc8f36aa071f0e5935df7072228 +F ext/misc/zipfile.c 5fe27e5dd6527bfce5d734b5a039a8a65b4893fe86b225f89bcac9f062f9c8ac F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622 F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 02af30aab24878c4382a8863512b816889400104549b51df6a632767fee48d04 -R 3d8464626ec4ed7160b5e3f3b7bf199b +P c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7 +R 68effacd960bb41901ef2b804dd3c9b2 U drh -Z 9339130783244dccd8482f7c789d5fd4 +Z c5ba6536955e62a1fdaffb0e62c18960 diff --git a/manifest.uuid b/manifest.uuid index 8ee3ab80b8..5201e43b18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7 \ No newline at end of file +f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5 \ No newline at end of file From 68b63c0195fe0e42e36dd9de42038c3a63c5b453 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 14:43:16 +0000 Subject: [PATCH 19/46] Fix the date/time translation logic in the zipfile extension so that it works with boundary cases. See [forum:/forumpost/d82289d69f|forum post d82289d69f] for the trouble report. FossilOrigin-Name: c8de5f061359c174e143e5e81ade8aa9b7d71ba57287459cf0f4f2c94459c345 --- ext/misc/zipfile.c | 44 +++++++++++++++++--------------------------- manifest | 14 +++++++------- manifest.uuid | 2 +- test/zipfile.test | 12 ++++++++++++ 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index 4aefc61dcc..86f7ba0f94 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -720,34 +720,24 @@ static int zipfileScanExtra(u8 *aExtra, int nExtra, u32 *pmTime){ ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx */ static u32 zipfileMtime(ZipfileCDS *pCDS){ - int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); - int M = ((pCDS->mDate >> 5) & 0x0F); - int D = (pCDS->mDate & 0x1F); - int B = -13; - - int sec = (pCDS->mTime & 0x1F)*2; - int min = (pCDS->mTime >> 5) & 0x3F; - int hr = (pCDS->mTime >> 11) & 0x1F; - i64 JD; - - /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */ - - /* Calculate the JD in seconds for noon on the day in question */ - if( M<3 ){ - Y = Y-1; - M = M+12; + int Y,M,D,X1,X2,A,B,sec,min,hr; + i64 JDsec; + Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); + M = ((pCDS->mDate >> 5) & 0x0F); + D = (pCDS->mDate & 0x1F); + sec = (pCDS->mTime & 0x1F)*2; + min = (pCDS->mTime >> 5) & 0x3F; + hr = (pCDS->mTime >> 11) & 0x1F; + if( M<=2 ){ + Y--; + M += 12; } - JD = (i64)(24*60*60) * ( - (int)(365.25 * (Y + 4716)) - + (int)(30.6001 * (M + 1)) - + D + B - 1524 - ); - - /* Correct the JD for the time within the day */ - JD += (hr-12) * 3600 + min * 60 + sec; - - /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */ - return (u32)(JD - (i64)(24405875) * 24*60*6); + X1 = 36525*(Y+4716)/100; + X2 = 306001*(M+1)/10000; + A = Y/100; + B = 2 - A + (A/4); + JDsec = (i64)((X1 + X2 + D + B - 1524.5)*86400) + hr*3600 + min*60 + sec; + return (u32)(JDsec - (i64)24405875*(i64)8640); } /* diff --git a/manifest b/manifest index 56bf854028..82769f5dc1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\stypedefs\sfor\sspecific-length\sintegers\sin\szipfile.c\sare\ncorrect. -D 2021-04-22T13:59:54.423 +C Fix\sthe\sdate/time\stranslation\slogic\sin\sthe\szipfile\sextension\sso\sthat\sit\nworks\swith\sboundary\scases.\sSee\n[forum:/forumpost/d82289d69f|forum\spost\sd82289d69f]\sfor\sthe\strouble\sreport. +D 2021-04-22T14:43:16.313 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -337,7 +337,7 @@ F ext/misc/vfsstat.c 389ea13983d3af926504c314f06a83cc858d5adc24b40af74aaed1fece0 F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c 5fe27e5dd6527bfce5d734b5a039a8a65b4893fe86b225f89bcac9f062f9c8ac +F ext/misc/zipfile.c acbad31bd9c9ec3540fa72b2e3fcd6f757eb33117d51528c0e13d0da5c836908 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c b880ca5cb857d6d6f52e72eb7397813058ef48c78c5402cd04ff2b6b5437f622 F ext/rbu/rbu1.test 221d9c18a5e600ac9ac6b1810d99d9f99163a7909ba61597876ab6e4d4beb3d6 @@ -1808,7 +1808,7 @@ F test/wordcount.c d721a4b6fae93e6e33449700bce1686bc23257c27425bc3ef1599dc912ade F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc F test/zeroblob.test 07a5b11ab591d1f26c626945fb7f228f68b993533b2ada77273edf6ee29db174 F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc -F test/zipfile.test 429cb81c518487fa1b644b6b04b6e9af704a4fa767bd1a110204c5f03b2e8616 +F test/zipfile.test 0d8758d8c0d63f16644f959689f78969d223789d998964276554039f067b4548 F test/zipfile2.test 9903388a602a3834189857a985106ff95c3bba6a3969e0134127df991889db5d F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c F tool/GetFile.cs 47852aa0d806fe47ed1ac5138bdce7f000fe87aaa7f28107d0cb1e26682aeb44 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c4258708c08c5b1956052f9febbf22c1e94c8352a25059063746921d2cc373b7 -R 68effacd960bb41901ef2b804dd3c9b2 +P f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5 +R 47aeeb02b3e6db8af535c3912f07085e U drh -Z c5ba6536955e62a1fdaffb0e62c18960 +Z 9069cf44b16e12ef7fd701f145234e86 diff --git a/manifest.uuid b/manifest.uuid index 5201e43b18..30d074038a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5 \ No newline at end of file +c8de5f061359c174e143e5e81ade8aa9b7d71ba57287459cf0f4f2c94459c345 \ No newline at end of file diff --git a/test/zipfile.test b/test/zipfile.test index 79298a0506..8749f17c38 100644 --- a/test/zipfile.test +++ b/test/zipfile.test @@ -843,4 +843,16 @@ do_catchsql_test 16.20 { REPLACE INTO zipfile VALUES(null,null,null,null,null,123,null); } {1 {zipfile: missing filename}} +# 2021-04-22 forum https://sqlite.org/forum/forumpost/d82289d69f +do_execsql_test 17.1 { + WITH vlist(x) AS ( + VALUES(9223372036854775807), + (-9223372036854775808), + (9223372036854775806), + (-9223372036854775807) + ) + SELECT DISTINCT typeof(zipfile(0,0,x,0)) FROM vlist; +} {blob} + + finish_test From 65b930553d0993898c870a671aabb905aea6adb6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 16:54:34 +0000 Subject: [PATCH 20/46] Improved handling of errors in ALTER TABLE RENAME. dbsqlfuzz 3e3e2e076e53d02288f80af41a11143a6ddf8c88 FossilOrigin-Name: 9c7a449f52a391506ebf4a8efa4ff27e6e97bd8da4b300a5c0dd942a209fe474 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/alter.c | 5 ++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 82769f5dc1..cdecd89839 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sdate/time\stranslation\slogic\sin\sthe\szipfile\sextension\sso\sthat\sit\nworks\swith\sboundary\scases.\sSee\n[forum:/forumpost/d82289d69f|forum\spost\sd82289d69f]\sfor\sthe\strouble\sreport. -D 2021-04-22T14:43:16.313 +C Improved\shandling\sof\serrors\sin\sALTER\sTABLE\sRENAME.\ndbsqlfuzz\s3e3e2e076e53d02288f80af41a11143a6ddf8c88 +D 2021-04-22T16:54:34.579 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c e7caf3eefce268250dc1d10322eec637319de486aa1bae7f48c606259455537e +F src/alter.c 0fe0f82a9cf3c4c136aa5fe7bce147a12ff3389cd009a29d8a62ce4037763e5d F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -1913,7 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f1f2a49007e938ea7a00dda6f8898b1cd38525c0de1e1cac00a7aebcd7b625f5 -R 47aeeb02b3e6db8af535c3912f07085e +P c8de5f061359c174e143e5e81ade8aa9b7d71ba57287459cf0f4f2c94459c345 +R 9f8e3aa4e06604d48764d6477368e363 U drh -Z 9069cf44b16e12ef7fd701f145234e86 +Z ad07977beb7e233f7ead65c4a88efde4 diff --git a/manifest.uuid b/manifest.uuid index 30d074038a..c3e5437c91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c8de5f061359c174e143e5e81ade8aa9b7d71ba57287459cf0f4f2c94459c345 \ No newline at end of file +9c7a449f52a391506ebf4a8efa4ff27e6e97bd8da4b300a5c0dd942a209fe474 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index b68e189140..d3fe6bf2e1 100644 --- a/src/alter.c +++ b/src/alter.c @@ -918,7 +918,10 @@ static RenameToken *renameTokenFind( void *pPtr ){ RenameToken **pp; - assert( pPtr!=0 ); + if( pPtr==0 ){ + assert( pParse->nErr || pParse->db->mallocFailed ); + return 0; + } for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ if( (*pp)->p==pPtr ){ RenameToken *pToken = *pp; From 6d29a4fe5be41d63d7c2ba8a82ad9777a4acc39f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Apr 2021 17:40:28 +0000 Subject: [PATCH 21/46] Add the sqlite3session_object_config() API. Current used to enable/disable collecting data for sqlite3session_changeset_size(). FossilOrigin-Name: 4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55 --- ext/session/sessionsize.test | 23 +++++++++++++++++++ ext/session/sqlite3session.c | 43 +++++++++++++++++++++++++++++++----- ext/session/sqlite3session.h | 27 ++++++++++++++++++++++ ext/session/test_session.c | 26 ++++++++++++++++++++++ manifest | 21 ++++++++---------- manifest.uuid | 2 +- 6 files changed, 124 insertions(+), 18 deletions(-) diff --git a/ext/session/sessionsize.test b/ext/session/sessionsize.test index 8347097e96..04d05514db 100644 --- a/ext/session/sessionsize.test +++ b/ext/session/sessionsize.test @@ -104,5 +104,28 @@ do_changeset_size_test 2.7 { INSERT INTO t3 VALUES(1,2,3,4); } +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_test 3.1 { + sqlite3session S db main + S object_config_size -1 +} 1 + +do_test 3.2.1 { S object_config_size 0 } 0 +do_test 3.2.2 { S object_config_size -1 } 0 +do_test 3.2.3 { S object_config_size 1 } 1 +do_test 3.2.4 { S object_config_size -1 } 1 + +do_test 3.3 { S attach t1 } {} +do_test 3.4 { S object_config_size 1 } {SQLITE_MISUSE} +do_test 3.4 { S object_config_size -1 } {1} + +S delete + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 077a6e0900..1f6c58b4db 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -42,6 +42,7 @@ struct SessionHook { struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ + int bEnableSize; /* True if changeset_size() enabled */ int bEnable; /* True if currently recording */ int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ @@ -1124,9 +1125,11 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ pTab->bStat1 = 1; } - pSession->nMaxChangesetSize += ( - 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName) + 1 - ); + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += ( + 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 + ); + } } } return (pSession->rc || pTab->abPK==0); @@ -1411,7 +1414,9 @@ static void sessionPreupdateOneChange( } assert( rc==SQLITE_OK ); - rc = sessionUpdateMaxSize(op, pSession, pTab, pC); + if( pSession->bEnableSize ){ + rc = sessionUpdateMaxSize(op, pSession, pTab, pC); + } } @@ -2627,7 +2632,9 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ){ int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); - assert( rc || pnChangeset==0 || *pnChangeset<=pSession->nMaxChangesetSize ); + assert( rc || pnChangeset==0 + || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize + ); return rc; } @@ -2720,6 +2727,32 @@ sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ return pSession->nMalloc; } +/* +** Configure the session object passed as the first argument. +*/ +int sqlite3session_object_config(sqlite3_session *pSession, int op, void *pArg){ + int rc = SQLITE_OK; + switch( op ){ + case SQLITE_SESSION_OBJCONFIG_SIZE: { + int iArg = *(int*)pArg; + if( iArg>=0 ){ + if( pSession->pTable ){ + rc = SQLITE_MISUSE; + }else{ + pSession->bEnableSize = (iArg!=0); + } + } + *(int*)pArg = pSession->bEnableSize; + break; + } + + default: + rc = SQLITE_MISUSE; + } + + return rc; +} + /* ** Return the maximum size of sqlite3session_changeset() output. */ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 78d25ba0f3..43a03fc04d 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -79,6 +79,33 @@ int sqlite3session_create( */ void sqlite3session_delete(sqlite3_session *pSession); +/* +** CAPIREF: Conigure a Session Object +** METHOD: sqlite3_session +*/ +int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +** CAPI3REF: Arguments for sqlite3session_object_config() +** +** The following values may passed as the the 4th parameter to +** [sqlite3session_object_config]. +** +**
SQLITE_SESSION_OBJCONFIG_SIZE
+** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object diff --git a/ext/session/test_session.c b/ext/session/test_session.c index b7c96b2657..f2fc77eee3 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -247,6 +247,7 @@ static int SQLITE_TCLAPI test_session_cmd( { "diff", 2, "FROMDB TBL", }, /* 8 */ { "memory_used", 0, "", }, /* 9 */ { "changeset_size", 0, "", }, /* 10 */ + { "object_config_size", 1, "INTEGER", }, /* 11 */ { 0 } }; int iSub; @@ -364,6 +365,23 @@ static int SQLITE_TCLAPI test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSize)); break; } + case 11: { + int rc; + int iArg; + if( Tcl_GetIntFromObj(interp, objv[2], &iArg) ){ + return TCL_ERROR; + } + rc = sqlite3session_object_config( + pSession, SQLITE_SESSION_OBJCONFIG_SIZE, &iArg + ); + if( rc!=SQLITE_OK ){ + extern const char *sqlite3ErrName(int); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + }else{ + Tcl_SetObjResult(interp, Tcl_NewIntObj(iArg)); + } + break; + } } return TCL_OK; @@ -389,6 +407,7 @@ static int SQLITE_TCLAPI test_sqlite3session( Tcl_CmdInfo info; int rc; /* sqlite3session_create() return code */ TestSession *p; /* New wrapper object */ + int iArg = -1; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CMD DB-HANDLE DB-NAME"); @@ -409,6 +428,13 @@ static int SQLITE_TCLAPI test_sqlite3session( return test_session_error(interp, rc, 0); } + /* Query the SQLITE_SESSION_OBJCONFIG_SIZE option to ensure that it + ** is clear by default. Then set it. */ + sqlite3session_object_config(p->pSession,SQLITE_SESSION_OBJCONFIG_SIZE,&iArg); + assert( iArg==0 ); + iArg = 1; + sqlite3session_object_config(p->pSession,SQLITE_SESSION_OBJCONFIG_SIZE,&iArg); + Tcl_CreateObjCommand( interp, Tcl_GetString(objv[1]), test_session_cmd, (ClientData)p, test_session_del diff --git a/manifest b/manifest index 0c5737175f..11730cc2f5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\ssqlite3session_changeset_size()\sAPI. -D 2021-04-21T20:52:17.903 +C Add\sthe\ssqlite3session_object_config()\sAPI.\sCurrent\sused\sto\senable/disable\scollecting\sdata\sfor\ssqlite3session_changeset_size(). +D 2021-04-22T17:40:28.167 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -453,12 +453,12 @@ F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionrebase.test ccfa716b23bd1d3b03217ee58cfd90c78d4b99f53e6a9a2f05e82363b9142810 -F ext/session/sessionsize.test 32ce42e9fed589276ef072b68c6f325e54ef7ef67c37ccd3ec8c822dd997f3c7 +F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a347ea9820a002dd8 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c b205b57eecfb93aee23653ba4b07be6930afaa3760317c22ad9872a0bc451d3f -F ext/session/sqlite3session.h 7d05ae78d03f778bf13f8160595b263d9436260137a8f50c78dc956f4d5121e2 -F ext/session/test_session.c b3d03f73b73d3794007392cf5a9bc27d1a2d3e970d500ab52026c726fa528142 +F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee +F ext/session/sqlite3session.h 874b084ea97252a57ff1b79bb5da172ab4156f6302a8d3e3f5c88ce2748480d8 +F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb @@ -1914,10 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6fe50dcc239d2d1fc2a38aa705f4c75cbe26b3e48d098537306d96d6a4005659 -R e870b873cf49a44c733c175dd8b4c0b8 -T *branch * session-changeset-size -T *sym-session-changeset-size * -T -sym-trunk * +P b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8 +R fa53b8d1cc3def8dc3ef8249968de9f0 U dan -Z c5add95d4af95f7f7d5a36a6c86b17cc +Z 5eb2943cb766ada953003dbe5c9f5486 diff --git a/manifest.uuid b/manifest.uuid index 3de85455ce..9cca027a55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b5564a6fd54875db1de884fdc0e5eeabcd6aa5595ad03a8a60843503e830a2d8 \ No newline at end of file +4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55 \ No newline at end of file From 3d8c92d041b380f66dc753ee38aaeb3b87d559cb Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 18:02:48 +0000 Subject: [PATCH 22/46] Raise an error on an attempt to rename an eponymous virtual table. FossilOrigin-Name: c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc --- manifest | 21 ++++++++++----------- manifest.uuid | 2 +- src/alter.c | 6 +++--- src/sqliteInt.h | 1 + src/vtab.c | 1 + test/tabfunc01.test | 44 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index f3b5c36ea1..8e06cc3024 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\ssqlite3session_changeset_size()\sAPI. -D 2021-04-22T17:55:42.561 +C Raise\san\serror\son\san\sattempt\sto\srename\san\seponymous\svirtual\stable. +D 2021-04-22T18:02:48.159 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -477,7 +477,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 0fe0f82a9cf3c4c136aa5fe7bce147a12ff3389cd009a29d8a62ce4037763e5d +F src/alter.c 6c62a47364d4eb142de6b0aa8a21e83450ad115ca5c2100f031af171777af068 F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c a7d1a7df69f053951ec1665e5894c61184fda3f677323762f1c3679ebd27d5c7 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -548,7 +548,7 @@ F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee01 F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 234ab17b1797cbc2adb7741a15786edf72bc96d40b4de68795e91926cfd46eba +F src/sqliteInt.h a00cc0642e2a4e26367313dc553781253e278a0e571e7211cc56245a8db3e0e7 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -625,7 +625,7 @@ F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a F src/vdbetrace.c 666c6fd9f1b62be6999e072a45b913e3c2c3518bc60dfd4d54fe304130acb724 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c 032a0165c147fda16927e6a3230e90c068d4af93f887ce94e26f678fe48e5e4c +F src/vtab.c b928405ccb66040fc6c3a11eaa93ddb02cbf20f9ab6860b301b222b9b50dc089 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -1440,7 +1440,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 5ca6d004157a3e886a55a9387b960cc0db41acd88753eb597ff409ec6cfb1be0 +F test/tabfunc01.test acb5be558868c65d8cf3495539fff23093d77139eb1e4e8c4580568099f98645 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1914,8 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 9c7a449f52a391506ebf4a8efa4ff27e6e97bd8da4b300a5c0dd942a209fe474 4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55 -R a84d1eee362399318f4f6d583239c517 -T +closed 4d5fd2151e024d11289b6c4fbce2996d8d07b2b5a1c953ef895c237e79d3aa55 -U dan -Z 9bc3972a508ee6a4946adabac402e49c +P 3de544d495fee553d95fde3fb656745d633138115d25ed39760a1ea7c8c3fae6 +R 6a9c7cdbbc90921854925aabbca2bec9 +U drh +Z f41afbcd09712ab0e6057d2e621e731f diff --git a/manifest.uuid b/manifest.uuid index b0538c1e62..4f68886728 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3de544d495fee553d95fde3fb656745d633138115d25ed39760a1ea7c8c3fae6 \ No newline at end of file +c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d3fe6bf2e1..32a472943b 100644 --- a/src/alter.c +++ b/src/alter.c @@ -29,8 +29,9 @@ ** Or, if zName is not a system table, zero is returned. */ static int isAlterableTable(Parse *pParse, Table *pTab){ - if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE + || (pTab->tabFlags & TF_Eponymous)!=0 || ( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(pParse->db) ) @@ -918,8 +919,7 @@ static RenameToken *renameTokenFind( void *pPtr ){ RenameToken **pp; - if( pPtr==0 ){ - assert( pParse->nErr || pParse->db->mallocFailed ); + if( NEVER(pPtr==0) ){ return 0; } for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 21c6f6f30f..b8b6b340dc 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2236,6 +2236,7 @@ struct Table { #define TF_Shadow 0x1000 /* True for a shadow table */ #define TF_HasStat4 0x2000 /* STAT4 info available for this table */ #define TF_Ephemeral 0x4000 /* An ephemeral table */ +#define TF_Eponymous 0x8000 /* An eponymous virtual table */ /* ** Test to see whether or not a table is a virtual table. This is diff --git a/src/vtab.c b/src/vtab.c index ded12c13bb..c9dcadae4b 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -1221,6 +1221,7 @@ int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pTab->pSchema = db->aDb[0].pSchema; assert( pTab->nModuleArg==0 ); pTab->iPKey = -1; + pTab->tabFlags |= TF_Eponymous; addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); addModuleArgument(pParse, pTab, 0); addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 04bc6f42ad..797267b338 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -227,6 +227,50 @@ do_test tabfunc01-751 { } } {5.0 x5 | 7.0 x7 | 13.0 x13 | 17.0 x17 | 23.0 x23 |} +ifcapable altertable { + do_test tabfunc01-800 { + catchsql { + ALTER TABLE generate_series ADD COLUMN col2; + } + } {1 {virtual tables may not be altered}} + do_test tabfunc01-810 { + catchsql { + ALTER TABLE generate_series RENAME TO flubber; + } + } {1 {table generate_series may not be altered}} + do_test tabfunc01-820 { + catchsql { + ALTER TABLE generate_series RENAME start TO flubber; + } + } {1 {table generate_series may not be altered}} + do_test tabfunc01-830 { + catchsql { + ALTER TABLE generate_series DROP COLUMN start; + } + } {1 {table generate_series may not be altered}} + do_test tabfunc01-900 { + catchsql { + ALTER TABLE pragma_compile_options ADD COLUMN col2; + } + } {1 {virtual tables may not be altered}} + do_test tabfunc01-910 { + catchsql { + ALTER TABLE pragma_compile_options RENAME TO flubber; + } + } {1 {table pragma_compile_options may not be altered}} + do_test tabfunc01-920 { + catchsql { + ALTER TABLE pragma_compile_options RENAME start TO flubber; + } + } {1 {table pragma_compile_options may not be altered}} + do_test tabfunc01-930 { + catchsql { + ALTER TABLE pragma_compile_options DROP COLUMN start; + } + } {1 {table pragma_compile_options may not be altered}} +} + + # Free up memory allocations intarray_addr int64array_addr From 9ad39a33ff27b1dbb559ed66bc628332f54cbf26 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Apr 2021 18:39:02 +0000 Subject: [PATCH 23/46] Change to comments in sqlite3session.h. No changes to code. FossilOrigin-Name: 353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4 --- ext/session/sqlite3session.h | 13 +++++++++---- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 43a03fc04d..71a81a29be 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -354,10 +354,15 @@ int sqlite3session_changeset( ** CAPI3REF: Load The Difference Between Tables Into A Session ** METHOD: sqlite3session_changeset_size() ** -** This function returns an upper limit, in bytes, of the size of the -** changeset that might be produced if sqlite3session_changeset() were -** called. The final changeset size might be equal to or smaller than -** the size in bytes returned by this function. +** By default, this function always returns 0. For it to return +** a useful result, the sqlite3_session object must have been configured +** to enable this API using [sqlite3session_object_config()] with the +** SQLITE_SESSION_OBJCONFIG_SIZE verb. +** +** When enabled, this function returns an upper limit, in bytes, for the size +** of the changeset that might be produced if sqlite3session_changeset() were +** called. The final changeset size might be equal to or smaller than the +** size in bytes returned by this function. */ sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession); diff --git a/manifest b/manifest index 8e06cc3024..9aceafb7e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Raise\san\serror\son\san\sattempt\sto\srename\san\seponymous\svirtual\stable. -D 2021-04-22T18:02:48.159 +C Change\sto\scomments\sin\ssqlite3session.h.\sNo\schanges\sto\scode. +D 2021-04-22T18:39:02.999 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -457,7 +457,7 @@ F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a3 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee -F ext/session/sqlite3session.h 874b084ea97252a57ff1b79bb5da172ab4156f6302a8d3e3f5c88ce2748480d8 +F ext/session/sqlite3session.h ec62833f3ec760a00b23a0e2a975d2b94eddf02b0e2782d3656c2d4cb31462cd F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3de544d495fee553d95fde3fb656745d633138115d25ed39760a1ea7c8c3fae6 -R 6a9c7cdbbc90921854925aabbca2bec9 -U drh -Z f41afbcd09712ab0e6057d2e621e731f +P c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc +R 228bf6971f815b2ca44e384d3a7a930f +U dan +Z decb5ec2c0a760459a806819d684ee15 diff --git a/manifest.uuid b/manifest.uuid index 4f68886728..8af05def73 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc \ No newline at end of file +353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4 \ No newline at end of file From 743b5fd589a0b29b825f4df2e11a4110398c09f8 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 22 Apr 2021 18:52:36 +0000 Subject: [PATCH 24/46] Further tweaks for comments in sqlite3session.h. FossilOrigin-Name: 553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331 --- ext/session/sqlite3session.h | 6 +++++- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 71a81a29be..e4aed9a252 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -82,6 +82,10 @@ void sqlite3session_delete(sqlite3_session *pSession); /* ** CAPIREF: Conigure a Session Object ** METHOD: sqlite3_session +** +** This method is used to configure a session object after it has been +** created. At present the only valid value for the second parameter is +** [SQLITE_SESSION_OBJCONFIG_SIZE]. */ int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); @@ -351,7 +355,7 @@ int sqlite3session_changeset( ); /* -** CAPI3REF: Load The Difference Between Tables Into A Session +** CAPI3REF: Return An Upper-limit For The Size Of The Changeset ** METHOD: sqlite3session_changeset_size() ** ** By default, this function always returns 0. For it to return diff --git a/manifest b/manifest index 9aceafb7e9..b06177bed4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sto\scomments\sin\ssqlite3session.h.\sNo\schanges\sto\scode. -D 2021-04-22T18:39:02.999 +C Further\stweaks\sfor\scomments\sin\ssqlite3session.h. +D 2021-04-22T18:52:36.228 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -457,7 +457,7 @@ F ext/session/sessionsize.test 6f644aff31c7f1e4871e9ff3542766e18da68fc7e587b83a3 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5 F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc F ext/session/sqlite3session.c 703634ca25b4b903ae8ec25045802a8c8deca36a65d2b993c4bc8888f6d6c7ee -F ext/session/sqlite3session.h ec62833f3ec760a00b23a0e2a975d2b94eddf02b0e2782d3656c2d4cb31462cd +F ext/session/sqlite3session.h 4c299467627cd27ac31fcbd062274da676d0c471be22f1255867f30f4f832b9a F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205eef790274a787 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P c7909e8e0d0577c6109f13c0b14fb565239aae8af8963d659f363e124f3437fc -R 228bf6971f815b2ca44e384d3a7a930f +P 353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4 +R 970d450353664119291274972bab682f U dan -Z decb5ec2c0a760459a806819d684ee15 +Z d027be7cc2a74dfabc69d2b1025902d9 diff --git a/manifest.uuid b/manifest.uuid index 8af05def73..286f093327 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4 \ No newline at end of file +553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331 \ No newline at end of file From 214b50314a878a0b6856d83cfde99c4ea3a5fcd5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 19:34:31 +0000 Subject: [PATCH 25/46] Fix harmless compiler warnings of unused function parameters in FTS5. FossilOrigin-Name: 14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62 --- ext/fts5/fts5_expr.c | 1 + ext/fts5/fts5_index.c | 1 + manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index 556c7934ed..f3cec00be8 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -2806,6 +2806,7 @@ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ } #else int rc = SQLITE_OK; + UNUSED_PARAM2(pGlobal,db); #endif /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 80423e2a0d..858b549cf8 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -6720,6 +6720,7 @@ int sqlite3Fts5IndexInit(sqlite3 *db){ return rc; #else return SQLITE_OK; + UNUSED_PARAM(db); #endif } diff --git a/manifest b/manifest index b06177bed4..56e9b22191 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\stweaks\sfor\scomments\sin\ssqlite3session.h. -D 2021-04-22T18:52:36.228 +C Fix\sharmless\scompiler\swarnings\sof\sunused\sfunction\sparameters\sin\sFTS5. +D 2021-04-22T19:34:31.184 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,9 +117,9 @@ F ext/fts5/fts5Int.h 26c74dd5776f798436fbf604a0bf0e8de263b35b5060b05c15f9085845d F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c 8336d0ff6db0933f63cfec8ae0ab76e68393259cbccc0b46e1f79f7fa1842ff3 -F ext/fts5/fts5_expr.c 5d0ab73f08af31837b1a4cbcaf571e74d7bb87f4f15bf79709de1b67ff4bfc05 +F ext/fts5/fts5_expr.c 9462249a3bb82d0e49b163500f9d2197c2e4cd95bf440a9bbfc3906b22ea1e1b F ext/fts5/fts5_hash.c 1aa93c9b5f461afba66701ee226297dc78402b3bdde81e90a10de5fe3df14959 -F ext/fts5/fts5_index.c a2ee22478318ad2c176fb06b0a7a752b770056cde6a0a8d8a50968f3afcc306e +F ext/fts5/fts5_index.c a45f0d7ada22b49afb44f530c8cc63b6bdd5c71a854a048d5b67cc177b605f27 F ext/fts5/fts5_main.c f497ca97cb2802311ec93733b595762dc5b044ce3c6c8ce5fb3e871dd3fccd5d F ext/fts5/fts5_storage.c 58ba71e6cd3d43a5735815e7956ee167babb4d2cbfe206905174792af4d09d75 F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 353ebb71c4113a35a92011c72f9c1d6c56f3bf681d94426a6a73e40f219ff2f4 -R 970d450353664119291274972bab682f -U dan -Z d027be7cc2a74dfabc69d2b1025902d9 +P 553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331 +R dbd6c4917cb3459c326bcc5cc7cbb278 +U drh +Z b5984b3e4e7f3be1661b64c450fae240 diff --git a/manifest.uuid b/manifest.uuid index 286f093327..5405487829 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331 \ No newline at end of file +14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62 \ No newline at end of file From eca3c67b1c3297ab8e02a182f2c65009910e957f Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 22 Apr 2021 20:01:02 +0000 Subject: [PATCH 26/46] Change a memcpy() into a memmove() to prevent a warning about overlapping regions passed to memcpy() in case of some obscure and unlikely database corruption. FossilOrigin-Name: bab132cbd18a529389a0315e60f30ccf1b565823116e0ec9b4f7684db1914c80 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 56e9b22191..ee5bf7326e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sof\sunused\sfunction\sparameters\sin\sFTS5. -D 2021-04-22T19:34:31.184 +C Change\sa\smemcpy()\sinto\sa\smemmove()\sto\sprevent\sa\swarning\sabout\soverlapping\nregions\spassed\sto\smemcpy()\sin\scase\sof\ssome\sobscure\sand\sunlikely\sdatabase\ncorruption. +D 2021-04-22T20:01:02.989 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c c747dca6b20dbc6f4de8aad99ac6deae153a099af95718de366c602bb9121a63 +F src/btree.c 054bd037a6b759eb5d6af7916df8226972f6a852514aee8110022ddac10aaf7f F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 553ada28f356d773c145b502163d766285e73fd4f64dc05f98e3e43ade806331 -R dbd6c4917cb3459c326bcc5cc7cbb278 +P 14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62 +R c9ee6b07c5b3bb7ab60fe0fd462562c3 U drh -Z b5984b3e4e7f3be1661b64c450fae240 +Z 41223c7313ced80558031a39a6e27102 diff --git a/manifest.uuid b/manifest.uuid index 5405487829..722d61088c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62 \ No newline at end of file +bab132cbd18a529389a0315e60f30ccf1b565823116e0ec9b4f7684db1914c80 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 7ff0a46e1e..d3c76cde93 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7028,7 +7028,7 @@ static int rebuildPage( put2byte(pCellptr, (pData - aData)); pCellptr += 2; if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; - memcpy(pData, pCell, sz); + memmove(pData, pCell, sz); assert( sz==pPg->xCellSize(pPg, pCell) || CORRUPT_DB ); i++; if( i>=iEnd ) break; From 7a04e296f3de54e69de1275780cbd1953a59b6d1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Apr 2021 00:59:38 +0000 Subject: [PATCH 27/46] Improved OOM detection in sqlite3ExprCheckIN(). dbsqlfuzz 46ae2d8f473ac672f3042cc14ab67aeab9ffa6c2 FossilOrigin-Name: fac12115a994a1b4347586e68faf38895ee9cb588eaa84c6f71cf9afd4c488b4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ee5bf7326e..799493bf33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sa\smemcpy()\sinto\sa\smemmove()\sto\sprevent\sa\swarning\sabout\soverlapping\nregions\spassed\sto\smemcpy()\sin\scase\sof\ssome\sobscure\sand\sunlikely\sdatabase\ncorruption. -D 2021-04-22T20:01:02.989 +C Improved\sOOM\sdetection\sin\ssqlite3ExprCheckIN().\ndbsqlfuzz\s46ae2d8f473ac672f3042cc14ab67aeab9ffa6c2 +D 2021-04-23T00:59:38.110 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 -F src/expr.c 2b79c16f167b7ec74dfbd325b6f9cd9ff026908017f6804a5af6ba451c13b5b1 +F src/expr.c a658bd4ee3a7873545ec1813875e42322693124413ac1aee8492cd7a529307eb F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 14273915979f8fbf80111e795b5511a6ee24638896b9d434d6ccf4bf7f7a7f62 -R c9ee6b07c5b3bb7ab60fe0fd462562c3 +P bab132cbd18a529389a0315e60f30ccf1b565823116e0ec9b4f7684db1914c80 +R 259277b673035beade7ee2dd59080902 U drh -Z 41223c7313ced80558031a39a6e27102 +Z 1f0ec772a56912a103f4a51a8e42c261 diff --git a/manifest.uuid b/manifest.uuid index 722d61088c..ffc5b87754 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bab132cbd18a529389a0315e60f30ccf1b565823116e0ec9b4f7684db1914c80 \ No newline at end of file +fac12115a994a1b4347586e68faf38895ee9cb588eaa84c6f71cf9afd4c488b4 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index bd45fbcd18..f40f160610 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3207,7 +3207,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ */ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ int nVector = sqlite3ExprVectorSize(pIn->pLeft); - if( (pIn->flags & EP_xIsSelect) ){ + if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){ if( nVector!=pIn->x.pSelect->pEList->nExpr ){ sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); return 1; From f3d5a684610ed339a90cbb6f4ed8ea4db13b5f53 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 23 Apr 2021 11:37:01 +0000 Subject: [PATCH 28/46] Fix an assert() in fts5_index.c that may fail if the database records are corrupt. FossilOrigin-Name: dfadb96edfef1d49e48a659264b9eb8d7f98d95d159d95c92c30dd4ba6c6e739 --- ext/fts5/fts5_index.c | 3 +- ext/fts5/test/fts5corrupt3.test | 201 ++++++++++++++++++++++++++++++++ manifest | 18 +-- manifest.uuid | 2 +- test/altertab.test | 13 +++ 5 files changed, 226 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 858b549cf8..869d7a8b71 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5079,7 +5079,8 @@ static void fts5MergePrefixLists( nTail = pHead->iter.nPoslist - pHead->iOff; /* WRITEPOSLISTSIZE */ - assert( tmp.n+nTail<=nTmp ); + assert_nc( tmp.n+nTail<=nTmp ); + assert( tmp.n+nTail<=nTmp+nMerge*10 ); if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){ if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; break; diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 9b43f3e069..631cb2159c 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -14591,6 +14591,207 @@ do_catchsql_test 74.1 { SELECT rowid, quote(matchinfo(t1,'p�xyb Date: Fri, 23 Apr 2021 11:50:23 +0000 Subject: [PATCH 29/46] New dbsqlfuzz cases added to test/fuzzdata8.db. FossilOrigin-Name: 8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzdata8.db | Bin 2080768 -> 2101248 bytes 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8ab55d844a..3ec8e6e5e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sin\sfts5_index.c\sthat\smay\sfail\sif\sthe\sdatabase\srecords\sare\scorrupt. -D 2021-04-23T11:37:01.302 +C New\sdbsqlfuzz\scases\sadded\sto\stest/fuzzdata8.db. +D 2021-04-23T11:50:23.401 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1057,7 +1057,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db a5f04edee03f0446759272e976f7e68568201077b8adf5c769f5b2a8ddc3e10d +F test/fuzzdata8.db eb5547e7aa31b689ede8d23c038e5150d319ae80deb2bdf596afe1cc1be5fb3d F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fac12115a994a1b4347586e68faf38895ee9cb588eaa84c6f71cf9afd4c488b4 -R 464657ffa7a12124b99852f982cc5947 -U dan -Z 8349500b404a7d60139d72d7d8608cb3 +P dfadb96edfef1d49e48a659264b9eb8d7f98d95d159d95c92c30dd4ba6c6e739 +R f71832aa3639a7009e00557426a88ac8 +U drh +Z b11cbf762d5f76435820b844409483c7 diff --git a/manifest.uuid b/manifest.uuid index a850531df3..d1cf303890 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfadb96edfef1d49e48a659264b9eb8d7f98d95d159d95c92c30dd4ba6c6e739 \ No newline at end of file +8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537 \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 463a5d274e57af108dc3cc99f0be7c9ac8928f6f..92bd92d253e90652ee64b48380eda5111135a3e1 100644 GIT binary patch delta 37952 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 mh|r*lTehN1O(|M^iJ*s5Tzvs*r1fq6sZY9 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 Date: Fri, 23 Apr 2021 12:16:16 +0000 Subject: [PATCH 30/46] Give a better final output line for the --spinner option on fuzzcheck. FossilOrigin-Name: 93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3ec8e6e5e0..30b01a01e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sdbsqlfuzz\scases\sadded\sto\stest/fuzzdata8.db. -D 2021-04-23T11:50:23.401 +C Give\sa\sbetter\sfinal\soutput\sline\sfor\sthe\s--spinner\soption\son\sfuzzcheck. +D 2021-04-23T12:16:16.167 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1049,7 +1049,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 74a457891ba166e7f4121eaaae81f4dbceb053b65ddee47db3eccd2ba59cd67d +F test/fuzzcheck.c 2913b64b61f516eea47186fd9fcce484d47a517bc68e808959ec8f28d85ed276 F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P dfadb96edfef1d49e48a659264b9eb8d7f98d95d159d95c92c30dd4ba6c6e739 -R f71832aa3639a7009e00557426a88ac8 +P 8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537 +R 0636bb5c7df9e106c29e61e18eff1e44 U drh -Z b11cbf762d5f76435820b844409483c7 +Z 449a373ccfec5f2aae5d22ef16608762 diff --git a/manifest.uuid b/manifest.uuid index d1cf303890..a1cebcf535 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537 \ No newline at end of file +93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index ea0543ca5e..7f2f226b43 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -2050,7 +2050,8 @@ int main(int argc, char **argv){ } } if( bSpinner ){ - printf("\n"); + int nTotal = g.nDb*g.nSql; + printf("\r%s: %d/%d \n", zDbName, nTotal, nTotal); }else if( !quietFlag && !verboseFlag ){ printf(" 100%% - %d tests\n", g.nDb*g.nSql); } From ba6619d7be98aad188dfa2f5211cbf3ec6cba6d0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Apr 2021 12:58:16 +0000 Subject: [PATCH 31/46] Enhance the --load-dbsql and related options of fuzzcheck so that if the argument is a single - then filenames are read from standard input. FossilOrigin-Name: e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 28 +++++++++++++++++++++------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 30b01a01e9..023acc4c4f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Give\sa\sbetter\sfinal\soutput\sline\sfor\sthe\s--spinner\soption\son\sfuzzcheck. -D 2021-04-23T12:16:16.167 +C Enhance\sthe\s--load-dbsql\sand\srelated\soptions\sof\sfuzzcheck\sso\sthat\sif\sthe\nargument\sis\sa\ssingle\s-\sthen\sfilenames\sare\sread\sfrom\sstandard\sinput. +D 2021-04-23T12:58:16.190 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1049,7 +1049,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 2913b64b61f516eea47186fd9fcce484d47a517bc68e808959ec8f28d85ed276 +F test/fuzzcheck.c 5884fb8b9ce3f884fb2407b5baca193ef458244fe8bed727e7dfeeaedd106977 F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8da88508932e475c8c6af1553268ff02e3e013b78ccc94b14532ec928fc62537 -R 0636bb5c7df9e106c29e61e18eff1e44 +P 93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0 +R c74134fa30bd59bb0667fa273ac36999 U drh -Z 449a373ccfec5f2aae5d22ef16608762 +Z 8e87378c3d4125548230641f32954b37 diff --git a/manifest.uuid b/manifest.uuid index a1cebcf535..3882a2d34f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0 \ No newline at end of file +e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 7f2f226b43..2d99fa4be7 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -1435,9 +1435,10 @@ static void showHelp(void){ " --limit-heap N Limit heap memory to N. Default: 100M\n" " --limit-mem N Limit memory used by test SQLite instance to N bytes\n" " --limit-vdbe Panic if any test runs for more than 100,000 cycles\n" -" --load-sql ARGS... Load SQL scripts fron files into SOURCE-DB\n" -" --load-db ARGS... Load template databases from files into SOURCE_DB\n" -" --load-dbsql ARGS.. Load dbsqlfuzz outputs into the xsql table\n" +" --load-sql FILE.. Load SQL scripts fron files into SOURCE-DB\n" +" --load-db FILE.. Load template databases from files into SOURCE_DB\n" +" --load-dbsql FILE.. Load dbsqlfuzz outputs into the xsql table\n" +" ^^^^------ Use \"-\" for FILE to read filenames from stdin\n" " -m TEXT Add a description to the database\n" " --native-vfs Use the native VFS for initially empty database files\n" " --native-malloc Turn off MEMSYS3/5 and Lookaside\n" @@ -1778,10 +1779,23 @@ int main(int argc, char **argv){ rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); if( rc ) fatalError("cannot start a transaction"); for(i=iFirstInsArg; i0 && isspace(zLine[kk-1]) ) kk--; + sqlite3_bind_text(pStmt, 1, zLine, kk, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + if( rc ) fatalError("insert failed for %s", zLine); + } + }else{ + sqlite3_bind_text(pStmt, 1, argv[i], -1, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + if( rc ) fatalError("insert failed for %s", argv[i]); + } } sqlite3_finalize(pStmt); rc = sqlite3_exec(db, "COMMIT", 0, 0, 0); From 1521270010348f21ece9720a1d68fc1b20212a6e Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 23 Apr 2021 13:57:53 +0000 Subject: [PATCH 32/46] Fix harmless compiler warnings in fuzzcheck. FossilOrigin-Name: e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzcheck.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 023acc4c4f..cffece22e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s--load-dbsql\sand\srelated\soptions\sof\sfuzzcheck\sso\sthat\sif\sthe\nargument\sis\sa\ssingle\s-\sthen\sfilenames\sare\sread\sfrom\sstandard\sinput. -D 2021-04-23T12:58:16.190 +C Fix\sharmless\scompiler\swarnings\sin\sfuzzcheck. +D 2021-04-23T13:57:53.490 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1049,7 +1049,7 @@ F test/fuzz3.test 9c813e6613b837cb7a277b0383cd66bfa07042b4cf0317157c35852f30043c F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 5884fb8b9ce3f884fb2407b5baca193ef458244fe8bed727e7dfeeaedd106977 +F test/fuzzcheck.c 59bcbb5f5c6dcec4f6f5c4e4456b5dc7211ea893f2204c80ceb4277bba83fb9b F test/fuzzdata1.db d36e88741b4f23bcbaaf55b006290669d03c6c891cf13c7b3a53bc1b097b693f F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 93729614e21ee674b83b0d2babb71bb758f1a2ec55bf9bda057fb7739f2e14e0 -R c74134fa30bd59bb0667fa273ac36999 +P e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8 +R 0d6d5083b1bd81e35ec0482661bc1aa7 U drh -Z 8e87378c3d4125548230641f32954b37 +Z e0790c7fde3af00747fdeda620b522cb diff --git a/manifest.uuid b/manifest.uuid index 3882a2d34f..51f48e6ca4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8 \ No newline at end of file +e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1 \ No newline at end of file diff --git a/test/fuzzcheck.c b/test/fuzzcheck.c index 2d99fa4be7..e7fa5261b8 100644 --- a/test/fuzzcheck.c +++ b/test/fuzzcheck.c @@ -1781,10 +1781,10 @@ int main(int argc, char **argv){ for(i=iFirstInsArg; i0 && isspace(zLine[kk-1]) ) kk--; + while( kk>0 && (zLine[kk]=='\n' || zLine[kk]=='\r')) kk--; sqlite3_bind_text(pStmt, 1, zLine, kk, SQLITE_STATIC); sqlite3_step(pStmt); rc = sqlite3_reset(pStmt); From 971ae9f66ae571787b4e9d7b87c6f1be8ecea9ab Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 24 Apr 2021 12:20:10 +0000 Subject: [PATCH 33/46] Fix testcase altertab-25.1 due to check-in [c7909e8e0d0577c6] disallowing ALTER TABLE on eponymous virtual tables. FossilOrigin-Name: 32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/altertab.test | 3 +-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index cffece22e7..4502b7f8e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sfuzzcheck. -D 2021-04-23T13:57:53.490 +C Fix\stestcase\saltertab-25.1\sdue\sto\scheck-in\s[c7909e8e0d0577c6]\sdisallowing\nALTER\sTABLE\son\seponymous\svirtual\stables. +D 2021-04-24T12:20:10.489 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -657,7 +657,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239 F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2 -F test/altertab.test 2af1ca53fd8581931c5b602e56e4ad5f12c5634e9e8203e918bc6c553d6879c7 +F test/altertab.test 51e744cd230f3a37119a6593c5955a9669993c51a453feed581bd8e46ed48928 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e1548802b6de7037baf388d27a7f3658abafe07b6f48d5ec97e5f644303592d8 -R 0d6d5083b1bd81e35ec0482661bc1aa7 +P e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1 +R cf484e06e363477fe958c24db002cbc0 U drh -Z e0790c7fde3af00747fdeda620b522cb +Z bae3a8673bc5b7dab6af1040deb31bfe diff --git a/manifest.uuid b/manifest.uuid index 51f48e6ca4..03fe5a0afb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1 \ No newline at end of file +32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1 \ No newline at end of file diff --git a/test/altertab.test b/test/altertab.test index 35ea4d30b2..c92dba1eb3 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -744,10 +744,9 @@ do_execsql_test 25.1 { CREATE VIEW v3(b) AS WITH b AS (SELECT b FROM (SELECT * FROM t2)) VALUES(1); } -breakpoint do_catchsql_test 25.2 { ALTER TABLE json_each RENAME TO t4; -} {1 {}} +} {1 {table json_each may not be altered}} finish_test From ba9ebc2d127528d5f2c9ed97f2c986ec358f8f38 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 24 Apr 2021 12:24:08 +0000 Subject: [PATCH 34/46] Treat byte-order marks (BOMs) at the start of a token as whitespace. This enhancement is inspired by [forum:/forumpost/ed8f696a20|forum post ed8f696a20]. FossilOrigin-Name: 3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tokenize.c | 25 +++++++++++++++++-------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 4502b7f8e4..dda2d26af2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stestcase\saltertab-25.1\sdue\sto\scheck-in\s[c7909e8e0d0577c6]\sdisallowing\nALTER\sTABLE\son\seponymous\svirtual\stables. -D 2021-04-24T12:20:10.489 +C Treat\sbyte-order\smarks\s(BOMs)\sat\sthe\sstart\sof\sa\stoken\sas\swhitespace.\nThis\senhancement\sis\sinspired\sby\n[forum:/forumpost/ed8f696a20|forum\spost\sed8f696a20]. +D 2021-04-24T12:24:08.900 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -607,7 +607,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 0b9c82fa628b5adce93e2bcaf935a24d43eb83344fb51551f7835526d0693fc4 +F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c F src/trigger.c f8493674f5c8f103c1a2cd0616af9dca85c7058450f9fe47cacd15cf5d512d52 F src/update.c b3abdaf4a314bbed238da69a6ca54c0f21262119389b412ee5778fffe62dd3cc @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e7b4ffecc610c494ebd506977402ec48cc799780f96c6293c0ccf27697160aa1 -R cf484e06e363477fe958c24db002cbc0 +P 32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1 +R 1d0e571ef291122bdf317bcd3d07015b U drh -Z bae3a8673bc5b7dab6af1040deb31bfe +Z 9d760c4ee05493d61d6146a0ceb36fa0 diff --git a/manifest.uuid b/manifest.uuid index 03fe5a0afb..5733a0c591 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1 \ No newline at end of file +3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index 5e01de2b90..5d250e6f6a 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -56,6 +56,7 @@ #define CC_ID 27 /* unicode characters usable in IDs */ #define CC_ILLEGAL 28 /* Illegal character */ #define CC_NUL 29 /* 0x00 */ +#define CC_BOM 30 /* First byte of UTF8 BOM: 0xEF 0xBB 0xBF */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII @@ -68,14 +69,14 @@ static const unsigned char aiClass[] = { /* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, /* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, -/* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Bx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Cx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Dx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Ex */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -/* Fx */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 +/* 8x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 9x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ax */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Cx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Dx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* Ex */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 30, +/* Fx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27 #endif #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ @@ -535,6 +536,14 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ i = 1; break; } + case CC_BOM: { + if( z[1]==0xbb && z[2]==0xbf ){ + *tokenType = TK_SPACE; + return 3; + } + i = 1; + break; + } case CC_NUL: { *tokenType = TK_ILLEGAL; return 0; From 113a33c5398e2e673853e01d48703e00c17f6bc5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 24 Apr 2021 23:40:05 +0000 Subject: [PATCH 35/46] Make window range queries more robust against corrupt database files. dbsqlfuzz f22df3a7b2aab0937a415484514fc2f68a293c99. FossilOrigin-Name: 506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/window.c | 31 ++++++++++++++++++++----------- test/fuzzdata8.db | Bin 2101248 -> 2104320 bytes 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index dda2d26af2..9c94a08655 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Treat\sbyte-order\smarks\s(BOMs)\sat\sthe\sstart\sof\sa\stoken\sas\swhitespace.\nThis\senhancement\sis\sinspired\sby\n[forum:/forumpost/ed8f696a20|forum\spost\sed8f696a20]. -D 2021-04-24T12:24:08.900 +C Make\swindow\srange\squeries\smore\srobust\sagainst\scorrupt\sdatabase\sfiles.\ndbsqlfuzz\sf22df3a7b2aab0937a415484514fc2f68a293c99. +D 2021-04-24T23:40:05.083 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -634,7 +634,7 @@ F src/where.c cb76c17d0bded653040cb16e2f4532fa7b20f5f8c205f4078d346562821107a2 F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e -F src/window.c ae9fbd0cbaa39e1b384c13289ed769f9981383bde7b2f262c70ad6c42e5ab226 +F src/window.c 35b14e7a53fe0472b42679919c474de3a5b5c1615fe90a2c41431f37e4ede1be F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 @@ -1057,7 +1057,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db eb5547e7aa31b689ede8d23c038e5150d319ae80deb2bdf596afe1cc1be5fb3d +F test/fuzzdata8.db cb843f55a3ab450c0ae82cb86731019f8180a0bd59de9f3656cfff5d6ba7a0a7 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 32255e39cbde65492d88177464cee9e10cb20cf3105208416be131e2c89b63e1 -R 1d0e571ef291122bdf317bcd3d07015b +P 3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b +R 046b16c6ecc6c0794b90790e7eea9c3c U drh -Z 9d760c4ee05493d61d6146a0ceb36fa0 +Z e9d04fc2504496c7597cf6435acf852a diff --git a/manifest.uuid b/manifest.uuid index 5733a0c591..320919c064 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b \ No newline at end of file +506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78 \ No newline at end of file diff --git a/src/window.c b/src/window.c index ad3b47dad4..61e57cf374 100644 --- a/src/window.c +++ b/src/window.c @@ -1570,6 +1570,7 @@ struct WindowCodeArg { int regGosub; /* Register used with OP_Gosub(addrGosub) */ int regArg; /* First in array of accumulator registers */ int eDelete; /* See above */ + int regRowid; WindowCsrAndReg start; WindowCsrAndReg current; @@ -2246,16 +2247,24 @@ static int windowCodeOp( /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the ** start cursor does not advance past the end cursor within the - ** temporary table. It otherwise might, if (a>b). */ + ** temporary table. It otherwise might, if (a>b). Also ensure that, + ** if the input cursor is still finding new rows, that the end + ** cursor does not go past it to EOF. */ if( pMWin->eStart==pMWin->eEnd && regCountdown - && pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE + && pMWin->eFrmType==TK_RANGE ){ int regRowid1 = sqlite3GetTempReg(pParse); int regRowid2 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); - sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); - sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); - VdbeCoverage(v); + if( op==WINDOW_AGGINVERSE ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); + sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); + VdbeCoverage(v); + }else if( p->regRowid ){ + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid1); + sqlite3VdbeAddOp3(v, OP_Ge, p->regRowid, lblDone, regRowid1); + VdbeCoverage(v); + } sqlite3ReleaseTempReg(pParse, regRowid1); sqlite3ReleaseTempReg(pParse, regRowid2); assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ); @@ -2752,7 +2761,6 @@ void sqlite3WindowCodeStep( int addrEmpty; /* Address of OP_Rewind in flush: */ int regNew; /* Array of registers holding new input row */ int regRecord; /* regNew array in record form */ - int regRowid; /* Rowid for regRecord in eph table */ int regNewPeer = 0; /* Peer values for new row (part of regNew) */ int regPeer = 0; /* Peer values for current row */ int regFlushPart = 0; /* Register for "Gosub flush_partition" */ @@ -2824,7 +2832,7 @@ void sqlite3WindowCodeStep( regNew = pParse->nMem+1; pParse->nMem += nInput; regRecord = ++pParse->nMem; - regRowid = ++pParse->nMem; + s.regRowid = ++pParse->nMem; /* If the window frame contains an " PRECEDING" or " FOLLOWING" ** clause, allocate registers to store the results of evaluating each @@ -2880,9 +2888,9 @@ void sqlite3WindowCodeStep( } /* Insert the new row into the ephemeral table */ - sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid); - addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, s.regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, s.regRowid); + addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, s.regRowid); VdbeCoverageNeverNull(v); /* This block is run for the first row of each partition */ @@ -3000,6 +3008,7 @@ void sqlite3WindowCodeStep( sqlite3VdbeJumpHere(v, addrGosubFlush); } + s.regRowid = 0; addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); VdbeCoverage(v); if( pMWin->eEnd==TK_PRECEDING ){ diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 92bd92d253e90652ee64b48380eda5111135a3e1..6f9754a2ec655467e30ee2b6b0bdf700cda2a3ad 100644 GIT binary patch delta 29741 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
    t^bhpA%nc(wp^XjmlTossDTo4~xWaM|-a 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 delta 29024 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 Date: Sun, 25 Apr 2021 23:13:04 +0000 Subject: [PATCH 36/46] Skip test when no JSON. FossilOrigin-Name: 6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/altertab.test | 9 +++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 9c94a08655..89fb77087d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\swindow\srange\squeries\smore\srobust\sagainst\scorrupt\sdatabase\sfiles.\ndbsqlfuzz\sf22df3a7b2aab0937a415484514fc2f68a293c99. -D 2021-04-24T23:40:05.083 +C Skip\stest\swhen\sno\sJSON. +D 2021-04-25T23:13:04.410 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -657,7 +657,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239 F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2 -F test/altertab.test 51e744cd230f3a37119a6593c5955a9669993c51a453feed581bd8e46ed48928 +F test/altertab.test 2f5a008e0cc8ce1d8adbb3ee665836d143fcdf5573b288402080a4443116d863 F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 3d55c21c167631f42d155aadec544e629bd078de9992aa5a74694d08bc52052b -R 046b16c6ecc6c0794b90790e7eea9c3c -U drh -Z e9d04fc2504496c7597cf6435acf852a +P 506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78 +R a3adb437018949e904deac97f67bdced +U larrybr +Z a369a5f1b7d7ca6da895ee1e87f6f32e diff --git a/manifest.uuid b/manifest.uuid index 320919c064..6f2365d639 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78 \ No newline at end of file +6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5 \ No newline at end of file diff --git a/test/altertab.test b/test/altertab.test index c92dba1eb3..7a59b858a6 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -744,9 +744,10 @@ do_execsql_test 25.1 { CREATE VIEW v3(b) AS WITH b AS (SELECT b FROM (SELECT * FROM t2)) VALUES(1); } -do_catchsql_test 25.2 { - ALTER TABLE json_each RENAME TO t4; -} {1 {table json_each may not be altered}} - +ifcapable json1 { + do_catchsql_test 25.2 { + ALTER TABLE json_each RENAME TO t4; + } {1 {table json_each may not be altered}} +} finish_test From bb0eec438dcffd532636c26876f7d660c40dec28 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Apr 2021 14:09:48 +0000 Subject: [PATCH 37/46] Do not initialize eponymous virtual tables when parsing the schema. This can happen if the db is corrupt. FossilOrigin-Name: cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 2 +- test/corruptN.test | 30 ++++++++++++++++++++++++++---- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 89fb77087d..915d1b610b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Skip\stest\swhen\sno\sJSON. -D 2021-04-25T23:13:04.410 +C Do\snot\sinitialize\seponymous\svirtual\stables\swhen\sparsing\sthe\sschema.\sThis\scan\shappen\sif\sthe\sdb\sis\scorrupt. +D 2021-04-26T14:09:48.640 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 054bd037a6b759eb5d6af7916df8226972f6a852514aee8110022ddac10aaf7f F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 45889a1ac425eb7d60113ce65a519c55c5d5d01f2a9e978ab1467f8653bb57eb +F src/build.c f4072218dacf42f45b733d1a9a98b3a4d7b8c676a7e5d8ff17d70b60aff687ae F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 @@ -801,7 +801,7 @@ F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af F test/corruptL.test df132ba9ffd6fa15038380b4154998b9904ab8f1ea78400d7da53c920cb3b13d F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 -F test/corruptN.test 352c8f006b46130c27c06d4894c0919123308440473d699ec796b9c04f828ad8 +F test/corruptN.test 7a8a8399f57cdc6a189f275230300ccbb2b31a5aea8399070251beeebe2cc02b F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 F test/count.test 5364003488249957750a5f15ee42ca1cd7b100b1131c2dc71fff266a1250bf55 F test/countofview.test e17d6e6688cf74f22783c9ec6e788c0790ee4fbbaee713affd00b1ac0bb39b86 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 506333742103c1f440db5da819a36f3b518f7b49e94a7b74419b02bbcadc5a78 -R a3adb437018949e904deac97f67bdced -U larrybr -Z a369a5f1b7d7ca6da895ee1e87f6f32e +P 6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5 +R 4aa43db253eb81fd5ee71cacf2798ab6 +U dan +Z 0aa56f60b5e694663814cab953c70c9d diff --git a/manifest.uuid b/manifest.uuid index 6f2365d639..916f75b86d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5 \ No newline at end of file +cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea \ No newline at end of file diff --git a/src/build.c b/src/build.c index 5506d36de1..47b0d56932 100644 --- a/src/build.c +++ b/src/build.c @@ -438,7 +438,7 @@ Table *sqlite3LocateTable( /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ - if( pParse->disableVtab==0 ){ + if( pParse->disableVtab==0 && db->init.busy==0 ){ Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ pMod = sqlite3PragmaVtabRegister(db, zName); diff --git a/test/corruptN.test b/test/corruptN.test index c015537448..8eca2fdb8d 100644 --- a/test/corruptN.test +++ b/test/corruptN.test @@ -182,13 +182,35 @@ sqlite3 db test.db breakpoint do_catchsql_test 3.1 { PRAGMA writable_schema = 1; - PRAGMA vdbe_trace = 1; REPLACE INTO x1 VALUES(5, 2, 3); } {1 {database disk image is malformed}} -explain_i { - REPLACE INTO x1 VALUES(5, 2, 3); - } +#------------------------------------------------------------------------- + +reset_db +db func strreplace strreplace +proc strreplace {orig a b} { + string map [list $a $b] $orig +} + +do_execsql_test 4.0 { + CREATE TABLE t1(a, b); + CREATE INDEX t1a ON t1(a); + CREATE INDEX t1b ON t1(b); + + PRAGMA writable_schema = 1; + UPDATE sqlite_schema + SET sql = strreplace(sql, 't1', 'json_each') + WHERE type='index'; +} + +db close +sqlite3 db test.db + +do_execsql_test 4.1 { + PRAGMA writable_schema = 1; + SELECT * FROM t1 +} From 8ed8ddf759ea846e880880ba1c8089027af4bdc7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 26 Apr 2021 14:32:48 +0000 Subject: [PATCH 38/46] When doing the optimization that attempts to avoid sorting on a GROUP BY, do not assume that the values in an index on an expression are non-NULL. Bug discovered by Wang Ke's fuzzer and reported at [forum:/forumpost/74330094d8|forum post 74330094d8]. FossilOrigin-Name: 7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 24 ++++++++++++++++-------- test/select5.test | 11 ++++++++--- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 915d1b610b..2587b84672 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sinitialize\seponymous\svirtual\stables\swhen\sparsing\sthe\sschema.\sThis\scan\shappen\sif\sthe\sdb\sis\scorrupt. -D 2021-04-26T14:09:48.640 +C When\sdoing\sthe\soptimization\sthat\sattempts\sto\savoid\ssorting\son\sa\nGROUP\sBY,\sdo\snot\sassume\sthat\sthe\svalues\sin\san\sindex\son\san\sexpression\sare\nnon-NULL.\s\sBug\sdiscovered\sby\sWang\sKe's\sfuzzer\sand\sreported\sat\n[forum:/forumpost/74330094d8|forum\spost\s74330094d8]. +D 2021-04-26T14:32:48.507 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 69e770e96fd56cc21608992bf2c6f1f3dc5cf2572d0495c6a643b06c3a679f14 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c 6e540867a30d81e00205995fa2dc0e3d25365a7402251c9fd5d19aa4ff5e60b6 -F src/where.c cb76c17d0bded653040cb16e2f4532fa7b20f5f8c205f4078d346562821107a2 +F src/where.c 22705995adaa97f7fb9163f31b9277c457d6995dcb0c4fcf52d1b317d9594d1f F src/whereInt.h 446e5e8018f83358ef917cf32d8e6a86dc8430113d0b17e720f1839d3faa44c4 F src/wherecode.c 992bf0d7520bffd345472fb9bc83a1ca0134e46d9e904879bb21e1e77957fcc3 F src/whereexpr.c d8cafcf6781cf871082f04d7540862cf0fe30cb381dd1b2145a380376364fe8e @@ -1341,7 +1341,7 @@ F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b -F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546 +F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae F test/select6.test 319d45e414cdd321bf17cfacedaf19e3935ad64dac357c53f1492338c6e9b801 F test/select7.test f659f231489349e8c5734e610803d7654207318f F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6fcb2438f88a70ed67e19103bfa263a6c98b06962207f153559c9516d8c7b5d5 -R 4aa43db253eb81fd5ee71cacf2798ab6 -U dan -Z 0aa56f60b5e694663814cab953c70c9d +P cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea +R 2da26e596e1a7e2946b3d9957b9e2544 +U drh +Z 7e0cb4449b883dc9661e9768d506cfb3 diff --git a/manifest.uuid b/manifest.uuid index 916f75b86d..08cbb5f746 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea \ No newline at end of file +7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 5859f866e0..1755a85b58 100644 --- a/src/where.c +++ b/src/where.c @@ -3879,6 +3879,10 @@ static i8 wherePathSatisfiesOrderBy( assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) ); assert( pIndex->aiColumn[nColumn-1]==XN_ROWID || !HasRowid(pIndex->pTable)); + /* All relevant terms of the index must also be non-NULL in order + ** for isOrderDistinct to be true. So the isOrderDistint value + ** computed here might be a false positive. Corrections will be + ** made at tag-20210426-1 below */ isOrderDistinct = IsUniqueIndex(pIndex) && (pLoop->wsFlags & WHERE_SKIPSCAN)==0; } @@ -3946,15 +3950,19 @@ static i8 wherePathSatisfiesOrderBy( } /* An unconstrained column that might be NULL means that this - ** WhereLoop is not well-ordered + ** WhereLoop is not well-ordered. tag-20210426-1 */ - if( isOrderDistinct - && iColumn>=0 - && j>=pLoop->u.btree.nEq - && pIndex->pTable->aCol[iColumn].notNull==0 - ){ - isOrderDistinct = 0; - } + if( isOrderDistinct ){ + if( iColumn>=0 + && j>=pLoop->u.btree.nEq + && pIndex->pTable->aCol[iColumn].notNull==0 + ){ + isOrderDistinct = 0; + } + if( iColumn==XN_EXPR ){ + isOrderDistinct = 0; + } + } /* Find the ORDER BY term that corresponds to the j-th column ** of the index and mark that ORDER BY term off diff --git a/test/select5.test b/test/select5.test index 8f451eacbb..8de306cf40 100644 --- a/test/select5.test +++ b/test/select5.test @@ -12,7 +12,6 @@ # focus of this file is testing aggregate functions and the # GROUP BY and HAVING clauses of SELECT statements. # -# $Id: select5.test,v 1.20 2008/08/21 14:15:59 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -251,7 +250,13 @@ do_test select5-8.8 { } } {two 3 one 9} +# 2021-04-26 forum https://sqlite.org/forum/forumpost/74330094d8 +reset_db +do_execsql_test select5-9.1 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null); + CREATE UNIQUE INDEX t1b ON t1(abs(b)); + SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b); +} {NULL NULL | 1 NULL |} - - finish_test From 3c6edc8a11cc1eeebb98fb5a009e9ba773b237e2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 26 Apr 2021 15:28:06 +0000 Subject: [PATCH 39/46] More aggressive detection of OOM errors in resolveAlias(). dbsqlfuzz 7f96832c2ef7ee472022ed805b064e55e41094b2 FossilOrigin-Name: e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 3 +++ src/resolve.c | 5 ++++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2587b84672..8b0d580207 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sdoing\sthe\soptimization\sthat\sattempts\sto\savoid\ssorting\son\sa\nGROUP\sBY,\sdo\snot\sassume\sthat\sthe\svalues\sin\san\sindex\son\san\sexpression\sare\nnon-NULL.\s\sBug\sdiscovered\sby\sWang\sKe's\sfuzzer\sand\sreported\sat\n[forum:/forumpost/74330094d8|forum\spost\s74330094d8]. -D 2021-04-26T14:32:48.507 +C More\saggressive\sdetection\sof\sOOM\serrors\sin\sresolveAlias().\ndbsqlfuzz\s7f96832c2ef7ee472022ed805b064e55e41094b2 +D 2021-04-26T15:28:06.192 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 -F src/expr.c a658bd4ee3a7873545ec1813875e42322693124413ac1aee8492cd7a529307eb +F src/expr.c 01ae116c42159f5a7383d9fa30aa04ad8929a244439237aafbdfa105d989700f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93 @@ -541,7 +541,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c d778af9986f3b0107c5b255dcfe2696e8e99e00fb77c5115bbfea4e92c3302e7 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c e299d53c4077fc32bc63741b5b27fdf8a1328cb8e812b9fafb55441c4c73a80a +F src/resolve.c 91d9763a72dae4d3355e281430144196c5e449e9de71cb7e40cc6d72d16fd8bc F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P cb8c41aa20bb351c4c712ed7a3617187ceeb0905ede1e6f561bc1d89f31c95ea -R 2da26e596e1a7e2946b3d9957b9e2544 +P 7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33 +R ada4d10a3f13ea7772d60432e91e1a7f U drh -Z 7e0cb4449b883dc9661e9768d506cfb3 +Z 9a742d1c6c9822afcbd83680adccc0b5 diff --git a/manifest.uuid b/manifest.uuid index 08cbb5f746..47923d9c65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33 \ No newline at end of file +e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f40f160610..c869d762fb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1324,6 +1324,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( pzBuffer ){ zAlloc = *pzBuffer; staticFlag = EP_Static; + assert( zAlloc!=0 ); }else{ zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); staticFlag = 0; @@ -2356,8 +2357,10 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){ */ int sqlite3ExprCanBeNull(const Expr *p){ u8 op; + assert( p!=0 ); while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; + assert( p!=0 ); } op = p->op; if( op==TK_REGISTER ) op = p->op2; diff --git a/src/resolve.c b/src/resolve.c index a5253b57c6..242aca1aed 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -81,7 +81,10 @@ static void resolveAlias( assert( pOrig!=0 ); db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); - if( pDup!=0 ){ + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + pDup = 0; + }else{ incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); From f0ac29090b810170701880e6f5c71814554d1aa8 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Apr 2021 15:32:36 +0000 Subject: [PATCH 40/46] Fix a problem that could cause a crash in sqlite3BtreeDelete() when operating on a corrupt database file. FossilOrigin-Name: 6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8b0d580207..e326d43ba7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\saggressive\sdetection\sof\sOOM\serrors\sin\sresolveAlias().\ndbsqlfuzz\s7f96832c2ef7ee472022ed805b064e55e41094b2 -D 2021-04-26T15:28:06.192 +C Fix\sa\sproblem\sthat\scould\scause\sa\scrash\sin\ssqlite3BtreeDelete()\swhen\soperating\son\sa\scorrupt\sdatabase\sfile. +D 2021-04-26T15:32:36.748 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 054bd037a6b759eb5d6af7916df8226972f6a852514aee8110022ddac10aaf7f +F src/btree.c 0555f7e97ede886ac3d7aaec363b44498c9716dd45f3f0484de31eb90e30a37e F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 F src/build.c f4072218dacf42f45b733d1a9a98b3a4d7b8c676a7e5d8ff17d70b60aff687ae @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7178dc3a32c3a4a33e437fd5026f6f72e4809ceb7d2cd12a25a74b80d5c95d33 -R ada4d10a3f13ea7772d60432e91e1a7f -U drh -Z 9a742d1c6c9822afcbd83680adccc0b5 +P e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41 +R c7130d9859bde8d12c0aa5a6e27eb502 +U dan +Z e8491501cdc34da079f5af9614d000fd diff --git a/manifest.uuid b/manifest.uuid index 47923d9c65..fa473ef722 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41 \ No newline at end of file +6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d3c76cde93..80b955682a 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9114,7 +9114,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); if( pCur->eState==CURSOR_REQUIRESEEK ){ rc = btreeRestoreCursorPosition(pCur); - if( rc ) return rc; + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; } assert( CORRUPT_DB || pCur->eState==CURSOR_VALID ); From ada2323d95569c557a244bf0769e94623a312b48 Mon Sep 17 00:00:00 2001 From: larrybr Date: Mon, 26 Apr 2021 20:18:08 +0000 Subject: [PATCH 41/46] refix altertab.test FossilOrigin-Name: db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/altertab.test | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e326d43ba7..c3610b67dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sthat\scould\scause\sa\scrash\sin\ssqlite3BtreeDelete()\swhen\soperating\son\sa\scorrupt\sdatabase\sfile. -D 2021-04-26T15:32:36.748 +C refix\saltertab.test +D 2021-04-26T20:18:08.281 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -657,7 +657,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altermalloc3.test 059841a3de6b6780efd9f0b30bf1d9b4443c555f68d39975cbcac2583167b239 F test/alterqf.test 67568ad152db8c1187b15633b801242cf960f1beafc51261a3d1725d910baeb2 -F test/altertab.test 2f5a008e0cc8ce1d8adbb3ee665836d143fcdf5573b288402080a4443116d863 +F test/altertab.test 2591f93cc1c5ac1f1854b096ffdfe10caf0a8bcdfc8f830bdc9a554e08e6dd6d F test/altertab2.test b0d62f323ca5dab42b0bc028c52e310ebdd13e655e8fac070fe622bad7852c2b F test/altertab3.test 2b82fa2236a3a91553d53ae5555d8e723c7eec174c41f1fa62ff497355398479 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e99faf4f82746761c389e24db1b00ee94b9f849e7bcb29517fa0ca10290afc41 -R c7130d9859bde8d12c0aa5a6e27eb502 -U dan -Z e8491501cdc34da079f5af9614d000fd +P 6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740 +R ba22c3c4a5936f02c9f9a04f2d00726e +U larrybr +Z 772b7b8a90d9d4ffae7545c81ee9f9c9 diff --git a/manifest.uuid b/manifest.uuid index fa473ef722..d5946f8155 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740 \ No newline at end of file +db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95 \ No newline at end of file diff --git a/test/altertab.test b/test/altertab.test index 7a59b858a6..47659935c2 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -744,7 +744,7 @@ do_execsql_test 25.1 { CREATE VIEW v3(b) AS WITH b AS (SELECT b FROM (SELECT * FROM t2)) VALUES(1); } -ifcapable json1 { +ifcapable json1&&vtab { do_catchsql_test 25.2 { ALTER TABLE json_each RENAME TO t4; } {1 {table json_each may not be altered}} From feef4472715787c269f3a9d2078f89e59dc9bd3f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 26 Apr 2021 21:00:51 +0000 Subject: [PATCH 42/46] Add ALWAYS() to branches that are no longer reachable due to recent enhancements. FossilOrigin-Name: 63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- src/resolve.c | 4 +--- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c3610b67dc..96a18f9950 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C refix\saltertab.test -D 2021-04-26T20:18:08.281 +C Add\sALWAYS()\sto\sbranches\sthat\sare\sno\slonger\sreachable\sdue\sto\srecent\nenhancements. +D 2021-04-26T21:00:51.168 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/date.c e0632f335952b32401482d099321bbf12716b29d6e72836b53ae49683ebae4bf F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c F src/delete.c 73f57a9a183532c344a3135cf8f2a5589376e39183e0b5f562d6b61b2af0f4d8 -F src/expr.c 01ae116c42159f5a7383d9fa30aa04ad8929a244439237aafbdfa105d989700f +F src/expr.c 70e2cf6e270bb97ab6602336c82060bee0720cd887483f85c645ac1df97d4a34 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c e9063648396c58778f77583a678342fe4a9bc82436bf23c5f9f444f2df0fdaa4 F src/func.c 88fd711754a7241cb9f8eb1391370fd0c0cea756b3358efa274c5d1efd59af93 @@ -541,7 +541,7 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/prepare.c d778af9986f3b0107c5b255dcfe2696e8e99e00fb77c5115bbfea4e92c3302e7 F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 91d9763a72dae4d3355e281430144196c5e449e9de71cb7e40cc6d72d16fd8bc +F src/resolve.c c38bbb89d7ba7a8673ec4f59b63e0980eb859c39ff2acc5df8b3d0f2dcd33115 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c6334660dfe81cc33a14b87b25d748b1c98b0702b7bc6db2e3ced16dc992740 -R ba22c3c4a5936f02c9f9a04f2d00726e -U larrybr -Z 772b7b8a90d9d4ffae7545c81ee9f9c9 +P db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95 +R ffed239cd8e8956a4bed4ffe71f5ac2a +U drh +Z 5f325b4c5576cc7e02232be8d2acb561 diff --git a/manifest.uuid b/manifest.uuid index d5946f8155..cb8994e4d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95 \ No newline at end of file +63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c869d762fb..1402609311 100644 --- a/src/expr.c +++ b/src/expr.c @@ -99,7 +99,7 @@ Expr *sqlite3ExprAddCollateToken( if( pExpr==0 ) return 0; if( pExpr->op==TK_VECTOR ){ ExprList *pList = pExpr->x.pList; - if( pList!=0 ){ + if( ALWAYS(pList!=0) ){ int i; for(i=0; inExpr; i++){ pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, diff --git a/src/resolve.c b/src/resolve.c index 242aca1aed..4f5c5b9614 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -106,10 +106,8 @@ static void resolveAlias( pExpr->flags |= EP_MemToken; } if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( pExpr->y.pWin!=0 ){ + if( ALWAYS(pExpr->y.pWin!=0) ){ pExpr->y.pWin->pOwner = pExpr; - }else{ - assert( db->mallocFailed ); } } sqlite3DbFree(db, pDup); From c7f5077e8832da1200cdddef1461093058577273 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 26 Apr 2021 21:23:01 +0000 Subject: [PATCH 43/46] Fix the [/info/df1d6482f9e92daf|UNION ALL flattener optimization] so that it works better with recursive CTEs. dbsqlfuzz 88ed5c66789fced139d148aed823cba7c0926dd7 FossilOrigin-Name: f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 5 ++++- test/unionall.test | 9 +++++++++ 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 96a18f9950..b88d6a87a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sALWAYS()\sto\sbranches\sthat\sare\sno\slonger\sreachable\sdue\sto\srecent\nenhancements. -D 2021-04-26T21:00:51.168 +C Fix\sthe\s[/info/df1d6482f9e92daf|UNION\sALL\sflattener\soptimization]\sso\sthat\sit\nworks\sbetter\swith\srecursive\sCTEs.\ndbsqlfuzz\s88ed5c66789fced139d148aed823cba7c0926dd7 +D 2021-04-26T21:23:01.727 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -543,7 +543,7 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c c38bbb89d7ba7a8673ec4f59b63e0980eb859c39ff2acc5df8b3d0f2dcd33115 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c bc08a79364ad2056b1b3b83142b1cc4eacabf850603166f3a72581d56c320d9c +F src/select.c 57dbb27e0d0cb2438487c797365a4c17294d0df3c25c970ca87f123105f33ed0 F src/shell.c.in 9320b476fde0f7c46700e5695b69b435f1e46843a1513cdd187ac426cdbee016 F src/sqlite.h.in 372554fcd1e1ed25ba44a316e8abdaad712470b7dcfa185ece54f51b10fbde10 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1645,7 +1645,7 @@ F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unionall.test 369dac51f4e7b94442b054d3d7f2e6755cd6994274718228878e3bd47c425f6d +F test/unionall.test fee6e6adebe5446938475432ae8b042835a286c7e2efdc1b186d2182dfb93ffb F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 F test/unionvtab.test e1704ab1b4c1bb3ffc9da4681f8e85a0b909fd80b937984fc94b27415ac8e5a4 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P db032156932fb0dcae5ffb7cbdfb711079daa595713fcb254f09f8ef90c81d95 -R ffed239cd8e8956a4bed4ffe71f5ac2a +P 63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e +R da5d0b0a21e7425e4176968ab9360867 U drh -Z 5f325b4c5576cc7e02232be8d2acb561 +Z 940b2dbbcc463a3babc791d1e318439e diff --git a/manifest.uuid b/manifest.uuid index cb8994e4d3..652d27ecb1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e \ No newline at end of file +f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6a773202e0..570c92b03a 100644 --- a/src/select.c +++ b/src/select.c @@ -3767,7 +3767,10 @@ static void srclistRenumberCursors( for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ if( i!=iExcept ){ Select *p; - pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor]==0 ){ + aCsrMap[pItem->iCursor] = pParse->nTab++; + } + pItem->iCursor = aCsrMap[pItem->iCursor]; for(p=pItem->pSelect; p; p=p->pPrior){ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); } diff --git a/test/unionall.test b/test/unionall.test index 2f8027ccb7..7554a3b308 100644 --- a/test/unionall.test +++ b/test/unionall.test @@ -355,4 +355,13 @@ do_execsql_test 6.1 { 9 10 800 100 9 10 800 400 } +# 2021-04-26 dbsqlfuzz 88ed5c66789fced139d148aed823cba7c0926dd7 +reset_db +do_execsql_test 7.1 { + WITH c1(x) AS (VALUES(0) UNION ALL SELECT 100+x FROM c1 WHERE x<100 UNION ALL SELECT 1+x FROM c1 WHERE x<1) + SELECT x, y, '|' + FROM c1 AS x1, (SELECT x+1 AS y FROM c1 WHERE x<1 UNION ALL SELECT 1+x FROM c1 WHERE 1 Date: Mon, 26 Apr 2021 22:30:49 +0000 Subject: [PATCH 44/46] New dbsqlfuzz cases added to test/fuzzdata8.db. FossilOrigin-Name: 88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzdata8.db | Bin 2104320 -> 2118656 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index b88d6a87a5..c0f0a3f4d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s[/info/df1d6482f9e92daf|UNION\sALL\sflattener\soptimization]\sso\sthat\sit\nworks\sbetter\swith\srecursive\sCTEs.\ndbsqlfuzz\s88ed5c66789fced139d148aed823cba7c0926dd7 -D 2021-04-26T21:23:01.727 +C New\sdbsqlfuzz\scases\sadded\sto\stest/fuzzdata8.db. +D 2021-04-26T22:30:49.648 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1057,7 +1057,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db cb843f55a3ab450c0ae82cb86731019f8180a0bd59de9f3656cfff5d6ba7a0a7 +F test/fuzzdata8.db 00e053a6a486be9edf2d6bae8f3911ca7e2cc27aa32291d1c8258130e9eb9eb3 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 63c50fbdeed831ba450d1dce67e968a7daa2b69ac1270eb271fb1e1873d4a07e -R da5d0b0a21e7425e4176968ab9360867 +P f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c +R d8e1326693278e6f1513c26703f6c0aa U drh -Z 940b2dbbcc463a3babc791d1e318439e +Z bb52e9bce99951a04289010ee988307c diff --git a/manifest.uuid b/manifest.uuid index 652d27ecb1..703532bf7c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c \ No newline at end of file +88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 6f9754a2ec655467e30ee2b6b0bdf700cda2a3ad..1601b1edb6a1b9e81cceaf1e5f60731ed23809eb 100644 GIT binary patch delta 43227 zcmd4330PIt_cwm`8SXiEJm)Zj0vAV66i{$P1?O3Co&~2IP(g7X;9S(K93YgXrip23 zX$qk%bA+-SDuuGaa=^5-GR3m8a`>-vH5$IX|L6Do-uL;vug`PW#WU=^_F8*b`?Eg# zW*^9A**kTXTT6>GnPgwnpZ_N1MK)(~#VK#eSzh`;lZjXK0VGAeKS`!1nM~YodOwoC z=zU3kulFJOjoypoMZG7<&-Lyk&*!wcj@g(7V7OtZq{3o z+^DxC`K;c8WVRkla&ng5oW3ULF(k+8Q6z`!O-T;YBS{X>8NB1l1LpvV#II~NyA9=8bYGuU=nS}$E+2(nAIT< zGkW@w(k3JfSDF@)4^4B)g{I5~BqrA*F)_?U z9c6-x{!AtJnMRZMOrvU%7(~7^^&r=oI+N#22}b8_=S?D>{AFsXkcc90nL_d}*lJm7 zx!Y2|4btnrVHZ*$&nef2q8EJXD6=xsCTC6!s~5|$P9bf5+@%@o?u|b1fDQN8T}~ zL8Eug!Sap@ik{H8W$S3TvP2Gn7k4U6pm2#C0K4Bc`?6Qyt#{2m*h;XUFvrU~ z#x$GLG_GMgNIqc>7D#gwOg~|63$JI%7JKH**%Mq{`gV?R#mB?36XwJg^q;oY0bP1` z=`_%l8Pl{;q^oDY9(`Rgu6})8na!I{YeyI7S%-A*(!Yywf1ZnOW;TcN`(BX{oh@16 zSYN9p%QdKP4|*Z7cW>8|vSJ#~b9L?Cua9e7jO+2+^WtM7BCX?^h0lv{B@S?f4^Heo zsLO!x=!nShn23l!bZAub7CkdBCek&onep_zX7pE#=db29*JA&;W}X*EdWFNDzSf|T z{}o+g;z@}`i~g4iJ!wR0BsnI+^+Z$Gyf{z0v&PMyIdj7F%rTjhr%m|JX8u>||KGBO zXc*&hV-sCH2Dtk68|WI?e^8hIO2wXr8}@u`MQTy5;N2BU+H!&U9b^5WcCalNvin#y zxz!@qB3HwPE=c{21w!+K7A+_yJhNF%XL;ART6}{#_ZTp+M_=lS z@$DX8&TQry+tx~53-W$eT03JJr@Hzi4(!z3)i86?B8W=!uLE!2_iFV2W>*~Z-||lU zzmJl6aW$r&Ib-hR@sX~G$Gvf0<4%bK28MeE$IJ<-X%RIe=*hVIuk?%mjSl($KRSE& z=+(v5Fm-HN{ds?x?i!A4=o!m@4qN|!*K!^df2w(VM`qGYFt<_jw${$ZYC)^6DgRF3 z^nBOifRbm@7Vs=AU!OY(Qg~b6{9g0Ml>}#e&9OSLd1zpM31p`6tS)@tTk2NQYu*8# z)ywa@_nDGai{|iB{r;|w!(6G)m((wb%09=l22lQHuq%J{?4Bjlm#*VkLn!~Hb_baD zdu;{3{;hTp%g;tvr;NOe_8<(UMimb%4 z;Wv&&mXxoHVI^^!&v2|s$&n4I40ihmdzH-Hx{_l}At5L@vLt%Dugn}JU3b69ixixg zVoDAlnaN;*O>jWb*P+2Bg~j7I)(lt!<=K+e`)2d3d44i>Dmi_!1)sn8&~h%e1>DhW zpO#!W+>mE+;Cjv)oF6^k532hIctiEGRxe0zC<-MhW!rexBEM{30lfcZr~>LnpU{$% z$4ASeBAE6~hDXo(`{ln?;af8J11~1DI+*D!NjsCz#Awo~HR!)fq-w=SJZqD$S7gD# z4VL(lW9Ra0Oe;yQ+R9{AFs)atO`7B{yfmp~?3bGvYy12)Khaw-<)!8`$(7&sTC&i7 zdAe6g?zJ6u!B;SCfH2)VtYqY!I8IJn(a=XQ9IIxc5ovTqL12$0)*ZsSvybt-oz0bLs!R4|Q-q#t;{x!QFH7J= zBT(suLI8Wjv)&MP&dUcX0+|i#)@D@_>kHb479R|#$G+oPKNP}^$CBXVXcmpJk?btb zk|C-w3&+T4_9@T$qY!I6F#w7?F<(e(!K_%f6|3UeKosKHBiS4zn)K(IKWU4GZMv{` zIFTYK(-64q&w}$m_(269J9`Iz?#>)MH?(#B#-9?QFp+sfdQYYn3}#~fmfu92)tlw= zY#3AyVD&IOiG9Jd;ZT{(0-$gRO96EZOU4fdvKBlW0hJ?I6jb+R5*!^ts*WAXw(@Kw ztQf=QL3TeH1&veKB8cwCoY-U(+aZg!1k=4*Pjpn#GLikv*x-UmEK;D510eOGGaQFb zVy`iIOwNMZg6Zk`^l*KQn!=v4i6P{^ZV)qx4ac8mGb<;iQ0vB_FwZc|c*skY0j|cfaWxM%f+Eo_L-l8Z4U+QgO?H&7Wt=>1L*u%F>5UOJk1dm? z9r| zO5a*MsJ-|r#;8t*^547%L+G!(0%e6hgYf8X)`e#okT}qLFb*$bukvgrBo6g{A1n5; z<~*B))uViK8I-N{j>NJznU6(mAef$?{8%^Z+ia;cyQqJC!F0tK1|HokaQ1B$&8C+g zXVYbhA7{MJ77O!M%MG#meWvi@9MWSxRK*I*pyDKNhO!Qd8Q$w7oWPNlY=@aG#H4Gi zIfpGjXBIQfQi)aUFcTK%&x%0yC40!k1ysNi$a|TK!{D3L^I-2lAsGC>V9(*L>&#bR z+332)8t~ZYHd|p9BWdgoG4yQ(w|`=>vOB*|W5Ki|wC0i(r~S;HXDqAq9=j#8Ci`!5 zD$jCC1+Iz6nqpH6SILRXsL~Y>HrpBw>ZRZf_>P?`mV_9?DPfW1l=SVK1*(5yBE0Ft zh0D)98x$>=)_VGcr(QEO^yMzg&*o2wqRNNWRBi_4o#0TM>c_2R?CH_~j^>J$z~<6A zk?@fhjif583<=|T0V+m2CG1n1E0x%4D7;{c$Ao$uXQernEYuN~HRTpCwyHFmdqWVL z3#QGArw+UwYqTb}v=z5i5Mt>%q<&`mL*G~~th62Xh-1%}CU6S`F^=wMJ<%=NaK|`tEtvu!aguE{KHr_o;MsZZbLJ8EyLCZTtzlt9GJxI<=IBKQeq2* zwht|S*m@v$n&)0hTb|owg|jJ~AJ!Vl-Qb1I(Q#JD7{di)y%dhgVoSmF zdY8XgD(H8?g)1g;7T&U@jBi2HQ?}*t?X0F`{V%3+^~3^Ft`PFZE1RLkHgg?FnxH87 zVHy`Bv6rCoq2dPhE5{V9&g8s#wheB_t2y}eJZ=%sw!`fNbsjES#68Wkm!WdB8VJX# z9o?W`7qtoIWpibc&`K~}`m6m6e}^zwJPFfwav-r{%<$o-Gsp@S60xM1OXAoYz#e$V zVyk`Jdps+FuvOksF#5-k`jGGmHw{v5^CC<=;jQ5L16(8Cysz1W=FzdB*Ya(S@rSt+ zJlmgN{&5h7lyQ?}v7KPL9QD}bTTXF}2{14nDQX!nn5t&|{VMKfZ3WY}(&MJkvniZd zL{A@px=`3&zcP&=4KjJ(Nx%G=7D zMaRa*Hj8T>7YAD>`ZUD2YVHg#yw$u_3?$Fa&JoPIBfOhe+1XByc5b|eWzmj z11_KA--(?7>D#<>p=d9&K+$hL%Kkn4AfA7BTpWab%K2cBz<*!Z`v{T; zdUwU1t@t;2b`FYn`h19=#Pdyf_HpTG-|Qz#K~W+&qr9Rps)+x9 zHyU^aQ&;(UAa)T<7i>tL^X859`x05T5xc-9aZX7~tZ41JwU3`yri!Dv%8eSSghu-`9a ztzUW3W378o+|nF}t>5QQ^XylA^bH@xAi-f3uudg^g=4=#ukO!_Pt5tjANeapT*VH z{A`KwkQZwXhKk?)q6?C}f+0HJzu0KhHI508*UC&Y<9+@sp4Nf9c=I5L{*IUSrwFu1 zF+*jVI0#%Nep9gEV}3lt`_=q;Llp{cE7Qfn*yKEaoMDJn_=+(Z1-sBx7JCY&hhvN$ z-X5uWM?I~0k8zAE4G=^o_7Y6b&G!rd>=Y=Jam)@GM}68tiWKUPgKG<~^UMLsA990m zm`iw#XHH1|g!9F~dcwCnQ=t8kkh<6~T)4n971#iAHe9|EBBLHDT$98;f@#|<3XUIG znAg5}y#>=Zv*~}$aa)`)k`rmFXWn?Mk5G$2(Ip`QySEk&nQ7w?c~J?;pX~KH-cJxD zp828BS?D8+{b;2aM(=lmw4X_*S9%M6LcojBeX*>!(190ysJKAT76{)#bz!I%6kcHi zpmLTAqq8Qq8$L1QA-Vl#B7) zP$7zEwV^UaD8+*#g&sT$hVr>W2Pix!XjnZ|n8`uEA8l)4&lsV9L9x&dUOXt!wsNQ- zl#Ul@u!lm2ot!TOEfEgm$CHGnJaa+HZjQqLG~qgJ>fy>kfp$*mLSxz7p8}6Jrb6+2 z;S1`1Eb?SzGIW?POcCmC?~sJA&lmc0B0;;X9vqt|%!lm4P`A;(aNJWUoHxb-s}EbZ zg*JsIQ-nM?JWx;}VK6mi%yw#P(+P40sxJ$3Jr6d3^V5XJkg|t!z_A@dBJA12)y2Z4 z!Z-sF$eSg!#iD&e5)VbEgbbtPa11*wY^UAELE$=0)%jFn)e0j_HL(cDm>|UBtA~Z> z85V97QfMWbAasJJ$Ax_3ej_N)6jtEMwF1q|jUnThum<|=7BV1vcEG3LO0x8$C6M%> z3V(;P-NKpDO@`%~{Jnv+f;5Hl&siV_Zx_DiX*c(W%H)EiewHFg8ZNlt@&*BnN~1wL zDm40wIym~I5anrm3|=`Pw4&ZNPUsB@tA&~PTd`m5i3`EQW$Fy2hiRu zin?q9%$P*uxeQnoeo-mZ<5_34eRQ-xDDtZQy8Q)0(P|N8y4%(O)}Q zT%t_GDOJJ-p0$Vf!kq1~<29k2XB{BRX56`9+)02#5zZb^q$qVU{icx5vqY#Etb}3x zYN5y~4yJ8joTowxea8u%4vZN@5QeZsB8g zNLc8742rIX^u-N>#M+WLTrk}qbV#fgJR!%-M^*zdY$ar5=`)zMJi z(i{r0U(+TtcaWbI)+`h=U`vwO2WWXn!JZSuH#s&2@}4#pok=1EdMOar*zXl1JdmJ@ zry)^TCB{O#rD7O1m?nNAu@U$nQ{;Hj$a0OtD_`=VG@ygcR(zByG7c(c@U@^{zHe8f zu1rEJu6)gB8WmCWpZ)_aQkx(0;}}#`@MdF7On`FUzXKf2@C(PO+2VShO$6<(Z)>C) zzn8?36tHF?n=Ss%LA1Z{KG3>prnQ_I$+yX%f9y9G7v_p9cs2!?PBj-E@tb5sc|K4U zXYPyNtQCWJHWjq#e%-LwdXd1*G|-;mJ7U*O;t}39EjEs#@D{Og1oLI*`1@o1La~l4 zjuuSsX8={(7N6cJT6t;4-Vvi{<$%fvuja63o*=`f-hL5=B9rKo4yoPbS{S-pyk>wF zcU~7K;M7ua9nEL;y%TAw*e~{k2MxTV;ozGh#VIB>6WKx0!qBl_{MpPhA@L;N0A0P! zpLiyU*%-FkZwv#95W7R}9skRi-QPUNvqsN>#0tIzL=Q9{#Jk5ug=cf2Qu2?g3F@Z6 zj6tFI@PkugA4wb|n7#-F{bwl_+vS;G|VYJQglSaaUmox6x(C8 z%Y4+M!XikX#rr|gVt+~<3^X6b`*+2Mo<6l0!gg6N*VIyNlHLC2 zYpQF^mEIRaM3#!7%v{BZMrwEYKg{>^|Jr;jJmy1c(Yu~zKJy=?`w+e;j{O(A5z@j| z;+5}1hk4qw&C{M$sH*`({?U{ro~En@-6x=_Q59|K=-oB{?xzTI7fBpP^+nbAso3ME z=jfg1Au(6=F*-&SZ;UM2C@3Ej3;g^1qfXiYr4RG-++SG_wig@2bJeT zzlQ8p-u72ci9A%V;jN{e&9W$tr@A}U)P2ZPcOF%<9xJ~#yySBE1!BTt^FB|5H-J8a zy6V3;FozMULOReyGSEyD$qNv(%X+rPam#2sHo{ycvI(fAns0F;P#rH~YE|eUk3DyI zir)fxIfm~4**~(GIhu0WtPoVY`6gDUnZ0?o_1|rpVNR6TL{#RRDfZq>FKtJ)x0$vX zWI|(`K`=_jLNUbX?PQ{gr+KGw@fFzmH17h^{w%*tXKOW|zRGVAy(dM<(wrtUXyUm9;Y-X$7O!n`Kbz+RSjYQVuqjnq4dFP9kXE zQ^a5HW9UY66|=rdPwb9sVI46J5TG`(f9|QV7;5GYhgfLoj{V&3Lf`+_pQckPg8PaBh_CP*`nl z2FFgCUGkgHx1KJTw$C*lYY*u?yq(bel=-fVIfJGV!0qYZkFVpx)8-Y79e}*{!L$o_ z-~6q_4x(_*OkmxiaL}4b1jK!2roF*oid*O^J3^s@`7E>3CG^qFGzI#T}p%)-zQLzjqj7REi%4Op`aSyr%~`RzTcxPi1GbC z3bl>z4^VI!-)B&$XMCTf^oQ|X0aXDMhy+GT)W%8_qK%6m;^Ht%8i(mEBub8bghDI2 z%AKnNVXdWR*fL&vpRf*aJxwTOK!QX;<|nkLF<$&M|I_ShyxU!()!;K+!r5jsoZm-! zmLqs0I#Du`8`2|5m?@a<8%TY^zqt_0hDvX9mM`>^YKCaa$u)M;|MsB6SVGF_a{*$0 zG?V>CN;i1%V&;UIguhLf0??HrUFF#&6vi8>U53E%5`ln|B;c)8J-YSn*S||dL_5fy zMJ^6YlfLBH6%^8?Xj#mpIIOYZw4tzflhn=F!dzV*HVZG$lj`y88f3g9MMKCosWFaO zByHyj2hp4%9U%8qNDG{?O3LG)=&Y0kYf#F7sC^Pa#wPYPXkPvlWG9bh%3-(>`YBrlh`K=c}^;_s^UfP`25TL5X* z2yuz>7Z{-RjoYJ@=dDk4wi3{`Y{|(EERF=hnfnX zGzY0U0~q(?SYVChB}U5^^QDKS!J;@%Fg-h@#=Z?8dy~b1UzbZaI9mMA9+y6re|e_Q z0>PB;2^c(1c>EAlWJ?_lcl?}VnvdDg6XBlEi@e70E~An6RDnG>GJ^EeIlh{ zdXZ6E`2VGB$$~HqO#bxcFzu&Dg_&d(uO~Iv?GWdI<)) z^Q=d;8Bi4|2jC|Uq(GkW`>W+=1o~%s7PkIuOMtSUsats-5Y6%%yeJB$XFOUxd99OG zE+ZTSww^XeL#?`UB&OKqF&1XVGGDm^$E1P)`4>?VOe;Na^}}9)@&ZYuMR(I=$cU5^ z(H17(^#B!|lcoWAlFTePEmD4-7l}5-X;9um?gzmw?Voo+5g$ zt*2YDqO}~wF|{;aP8XRSGZN)MdRZ{7^0co5C>!O#$2LrNY8LeCB7YXdO&Q66#XOv5f4Hohs*WECe#P3C+Q^f{0`vd`-y9 z^lTxV26<>}IGZhmP|z+2P`yG9MAroQs+qY^NRw&e34`I!1_uGPq&{{^m&no2<|vWu%$M)5`lV~-Vu1i8(^?~;>oIgMNZ24hZE3tRQl}*R`cWRsAUUX-_ztC; z7O@UBz9|jzf zcZ(Ecak12!%wf3mMe|VdM$Z5<<{XjxNGupDkIPMYk?4h7OGtKV;gIsBV>m89Desnz zwDm5jMx8)#jnQJTtkM`IEeg)b`C=$_**{zEjo+T5j?CJk@R>}xgD|pJH>m7t>4-C` zd-njcqc>rT=O0UVoWU;PbDjs6IF%+U-lKq|55u{hb>M*?y zjXqCNL!oGxtl*)H&|rpRZpnpAB=#hih(fi|OFE)(SMDr}4Jj8JY7{iiuzU9vZFR~f z=Pop^q&_aS+xp=;rIU+W8`n~xX@=Eo>AZA`PKonph(hp0g$S(mP`<$k^_a0f*mr-R zg_ifOQ0!yL#-)NKOJO}JP_R(N23^AV?hR2k3oX#KEjC#Ur`2V)QPxx_T5EHzYiub7 zi=sIoX_>{pfKegl29{r$NbFFqADnDp3C6H+3oW5ZSmb9hk~~c;UrAyk8j%BxV#ZN~ z$@Smtr$^8rd^{DX-7FoU;zP;&AB8W17A-BOSl`lC7C%v>O!RXe%j%w|@uhZ_Miv%{ zA9S@eVHeO2~QdE@(jHRJ{W2t6k#wGH4+XFv%G*?Mq0-6Y!qDVVIiD2#qyfO#-K3C zFjESRYU4YVVg*a0MT`68WEDH0%Kd6^VfY6pp3&Jotrxt9V$mcBXQ!T3m4Z zOUruW!C5pZTPH*HRf`H+=2{$Z(aRcwDZW-p87F*Y>1J%%xJ=^ZTD&2pCxzy(T(=Cz z#fL4+B{qk0J+2Jc%lpaLKG-^)!|&d;1TZ!ikGiZKDdW?hOEgR|-zZ}qE-tj>@UUf@ z#R9o!Ewk8s3=0elVyK=8xJiKUD}JF+^(_uP4j+DE5gBna*kH9i zr7~iypE1J>->^k^G}fqx8r>OOQXuVFt`nqHp;{*xg)GLSt&H1`+E`yR8tBcIK!umJ z@t>`Gn`2pUW{DRe#y2c}7BQCk!a)N7O2DEZYi|b84?QzB6W-yhDYmJ-}78phSU{en8)=6 zA6m{D$}WfUvjJ^ARzR|Xi#E)^2Dm+sKMj??2SgcW;Ap1)&|*dPK|s0Z)(WV66c7au zKeyCg=L!ral-$w;H`uLHc=imGJFGFUT(&T%Fb7iqXk~qqEA_FC6bOnQ6<{UG(Q~KM z^f*ilvJy#+SoGXVNIh%pmug#SzqAU9U-)Nx;&|eJB)(yr3rF6wbTS%544yTRI+z=U zuI-jB9+Tu^LRmoBlRo@Klr@~?!JT_r15Do^kjs^RZV6(4=t_};iF+Q7?X`p$T0g}@ z?gdLs!DUNV<3|2J9E;>w>f(QN-yx;(R!Rb_gDaw356bRX8sO!bR$2qnAA}OHW(-lF zAu8gzj@Br~3ZUHLqKsu{>tLP%g!LnUt86-f?Hf|8J)!-5n}n@gYb@mcW)VO+WJ!e0J*-yDOS1AdgECS@Q+t7BoY7f` zslshSVWhR6EViP(Y8S`|vcCRULm&-b#IlLj4orN3p4$RjnO`GFFR;|3gfx}^#WIIC zCcSI*XIM1Z`kL7wKWuFcT7<1LY)iM+k$2{r^?1Ql_&C0GWLO(oURkkFC*DJzXGQA_ zdWN-)_;O)_-UiAttW(6T`CatZ7&X&c!NeD-&X-Wgw9<6DjVNcv_x5~NPT2n<>m?gu zA#8at?Lb#pzmwRjDCAmgPSzgP7p=FM_!_q{v_6So)gelb`EJFUbrD1y{g-i-@Ri63Cf zJ^#84t51t6GmtA43Uj?9Ao~Y`M~n7a2N1|HV_0arg7!#_JkY}pmw2^hhm^u1|Jk!TSL@YGUD#i3UVJy zz=TRGO(R4hX=Ee#`JDA-nRSLc7p(7z?-X^^J3;wHvi`C4o%D_neTn`&{QMw25w~2j zrZDkMvd0k!J7p$gS6OMhe-x{}wz?QZerFwlSzlR~npqj7o+d0m?V`00lx^|}hT(DA zRQ&#?)sJW8kXq=I2vw5J1>Z;6ym4N&^*Nq!kKE=q!h`Nw*AnglTNGO=xNg&~VfsDm zIzmA5wX~G{^rL(8UDJ{Q?gS{1+sVr(f6tP>p!nK;$BKv6<|2C+GImlf^N;GhdB~pX z?WwFTfg}^EtuN4UZEj07oO%)_+_jE{iltg8etp+Ei-Y#TUeWN(FV?w6_2UUenQ+fK zmC|r|KKA@Ihx@?y@0le$>t%}-iG-q_v$n+!0k#2FgQM_rH^cZDkKrYVuzhXRaJsaf zEmWZVk}KSHLp-}`s@@eH5w;&V@dLVBfk|;%G6(5LoH6j*Eo)a$=MvN9Y@X8zDb>yt zC<_zKaOAeNQ%xg07W4BUGdAk~A41fc+JTUJ*V^)NGiJrwawT?-2&u;Hk5Nc4z70Ia z`2LhaBjfusQ2W@%0_6L|W8pyCLkBrTD>3eM*aCU}mHOIb$#P=+ez09;x_VOyW zD7Bp?U~;~VfXQpn;-GCLrYy2;GeDY2TSKnnciFZ8p3s^hU#l%P9ZpTE&fqqtQ?3q*xI$EE? z-8*eVcvg+VZo`9j;ADo4c7H`S!nA%cLbcb3{bANZQnN2G_A_2wW=ml>{vDfY5&IHyQp->&4Zk{L3t{Y6 zNR77dfYlux;~@6~duQxlX|qX`rX2m5Z7VO{BYp2<%sKnp9G^ab}8no!KM?xm%M|-E_=Vw7BV-5o;mDK{OQ5=OXdksO-k4y3Q1 zZaVcUbaT_OSD~Yu_+dg@w-?E#ZaVoYG<4J2D+IV{DiEx03rWsRP&t3wO`CcCx|^aC zzRJy${K#$0gm1g4N&Hcre8V5omykT5FDChhzKG;&I-Mclcj)s;zMyB(Ic5HNJ(J|K z`Ye)9>oZ9%)iX#g($h&U&}WdGrB5e0Rj2;OPtvE59IsC%nW8^Ma;QF$E#?N$-*3(%A^-^$STs>9I}eECWovd zJ)1*Tk@Ot0inJ()s*+~9sYYqCo9rQtb1yVynWQmpGKe(7O$L#MxXB*UVE0^-1Ke{= zCi7u8?YhmA++-E=XgArzJj_j&F!ynjCCr`Oh9&&;K_vfMC+oBR&mFD*>$Lb^ofQqP z;2qgc7~fDkVSFJ_Ji^`p)xP#;80Idf`5g)sdkUW6zig zuCIe-aH%c@tEbx)CQ={Z>r&LrlAwB^!-1*u>@U$NK`b2V*u&u)OYF%a9Sp2&$u-8Z zwRS(kYd)}-qj|ag0W;`;YiuzXx5Azx8(ga+t&L^wO`>H#DJ}|Z1#Blo53#$AMUMt1 z-v};A_7E5~>`7Q+l-kK4|5aYMM^P+ptE>qFdtlTz_P!LQ{C&}G{(}8S(I844^8ZJ5 zCyh#IKH!@I``G>l+?MQ)zt^d70XRi$} zerO+oZyz_}sFqOK*M9P!eS`2Ndn{wEVE=J@eN4D!ck!?W?9B>B*_V}8*a;+QgK9m; zLk_u5?TpS962sEI2BSyXU*$0V3;PO5B<9n;5k@5&nO$Xj*`t5yDEkMV+nr$RTlQ~2ZDDT()V~9< z{jc_SINE2&^taQog!}e)c-CdV;2?Gcr37{>0hsRRa8mMjpkowL$QZ{#!rP9{MorzJ z*kP6S^B)7>a?RRt#8<3Ju}?gbNv*Zm`}ySjMmOH z8q<|Ny@=aMutLh`woMGP2Rp13_%(E7gL=kpuwnV$sGqTCQ9>dnusfGu)-wH($DGCDcdKw&G+{CNBWjsJEyrjcX2$dWPdj(rBP<36=_ zHXa`jwVFF_u>KHp*%kom@3tM7ecpbUVO9&ryB@YrX{w=rDKmUC@P$eGIKhOTc=Au* zv@}|hM4v&Z(QhJnEHoRcqB)_aid{xS2E%2Sy&Y79JGLN=l;sYQK|=mBb{xDvLUKaWFncooGS3lY5s9OdHw#GXxrR|DY#gBzD`)@X z&A3q}xN{tfS!(H0!%a^C8)Bz)#R|t8GO?>ouhneCo8Y^f9WBUf1oVY5TCq^%3lr&2MAk9UJqL~Bko*6(Rhe#O@h)*P~C zAmLQ=cs8AAJ`UQK&Ol+O@tqD^b~)$_)o#ao5*?6C{ags6{G%-um+y0A$>Ma{_9h!O z4TRB09Gk_={7ijX=~2fcCK@rsY)n3H+r=3@)XZT2+m60$4raV-UqggWhkXiEoV7h%%FkvmyR!(xR5Ge0_mRxJOdREl^mp_Z$BDn`{=pcOUBW+b=dYB$4QQ5 zW1j@|1l6@f31hG~OYH{Vq^beX>$c+n(+yJadMMPDDR5w%+8z7eaqQ=q8~SutX`6f3 zaoHdbuGzvxK)RRO1Hz}OXR*t#4x&ZUAbdcpWP~kY|EJDyUZjYFUk+Q>I7i?Z!MVl4 zX6|_8aC#0`^3OotW`Y$1ROj0kaTaBb;vi#{vm@3Ca$aQO3VL%T#++AvWB4%GDRKmj z@4cuHwa4Y8+}~>0dqqjYf%Tkp=5P(}{YnuTS|Xfuc%2SzX-W!?k92O~2?W35t0ZEV zXyT=EdizlC_Yxo(NEXV|Ohi^nM)y*+tJ=L$NB;+0io}u7jAp z<`kEc7Eigd2B zD3(su-8}5{;i1D^=W!37?WAF|9km|LOB|ila0cSmRJ>*tnYI_B@ z4tI{Gm1>XE8)q+b{vuIMYT7F2^Pc0B{HvIF&M9+ff8IGl5{WkRTCkz)QxJXCZiZ>6 ziRjlT$k_m;jm~>a+(`xQ2G)d-l$(l^kc=KY{Wy%^y#99wdJb3cuTuiW835^XogHvQ zp>rqC_81-thTMJTUYNGs2|U}2m0g@s1eu~a6v=aYJUSOahrP~nqB)T;ylvbeiVRg= z{P&CfB+8Gu4mfWzvE)!ceIaTGowt~{i=NzvVeOokspPeyhO5m^yQk#+5SHky1!eD1 zle&~Sk4lV|j3r(z|D_QNIHbpHW??Z6md7|n(JE)SVHl@@7|Gb@L+2YzETzg0f}%Pv zLFg^39dDg;?v>dReDR_)l{3(9{s_dp=o9$wRlIc7>18%(MX&N6yQAw{=Vc}yrq{~g z>;SC^R0V1-Ovu&t8i^;q94el-5|UT#BqZ-G_@J%U9Gb>?dD9_Frju%VYi*x+es zd|T*(J$#gd28;0bVT#D1C5WaK;u8KoN}=#GC|LQ1Gmc)SDu_wZ3gKfT8!CNqavfzO zqf?k;nkuxi)>CL@JqugC=unPYU&)3sUKAj@B9yBftAM<(Y+;az=}QhNbVB;N5RJ#I3Wb4xSho!$j-z2;Ap6$C z*OHWB#_`QREPI~e?}HSXqw||Do>0cZ>S$*jT;-?CqU*!xx_BWvrdbR||DaT`f)-9Y zd{ayDH|#B&*(G38xmA!pSPj9w;}tqAdKo%!VttI5r0kOEh>_{=lK^3r(iul)DBC#W zxF=80_yF|~t!|b!_-m$OH4btfo2w>5yX%g(YnHgi7~v2bd&cH9IJVHZ{he`pAxEk7 z1XaM$#mY5~@bhC?bgyioB4hL>^%BFzZsjvZQ2MbP6!sIGv1?UXt|9U|B09@U2v z+#(jfP9zBN2L1mI=of_fxVT7JP7pk7=9CYiafovpJnEt>fcY1c0ob)vIl>5#SFZ|9 z;fPr|LFaI2#rf#6(xjlL;tNyiIIXz(O=TiSK)un4fI8762)U|!S!Cj{oBP@&L{YR*wOO<3=VE#kv zX!f8+Zy>#w!LN0kNAU7NBMSPP{$CO2@t-ZoVVQ(Ad0^v-89hLja9m-P9QEf)y4s=8SRz$QuxP0DR98LG z14xfDi1JZwrLihSDc)GQk{d+Df8{uVt~Tmb#(Y4_<<>#c4aaxTVSzFqAGA}=9AyEt zwHzfsD9$wwscP%FaE6gx)K7^Y3CETyA3?%XRCM2;9PwDOl$*q$X$%eb7kjCT1!jZV zN$Md>V5#h;a|$t+O^smKWRUs^$0+ACM}365W^*CT zGxo7`xY~!&Db+k)r3G@NN(*E#XiLe|MBWgp3VEYa>!lnjbY?-zM)Vy)!!GQ zp9&FhZ<;z#B3fo%s5lkMa+NW7CQ~IAN!^;6ay1T`ukPXK#A?mth%`CwBf8WQB^*na z7>d`2cDIe0^T}r5Imq%Af4~cFwIL%=s%C}+njvHH%2G8`rX$U!Zw)uO z2Qp~2Mm-@KP;dmsQe3%CZORc06}CvBA0Jq+(vJ^B zVpz6f<&Y{3By{2j#|qfHg^Fu}VM~<^y7GtjAYqbP4Cz7QT(}jjM&ZeA>PLd{<4}b} z6JF))4A*w5bu2B9jdT-;_oy9gU8NXgL?LS56gN?QzZv$}xmd`Yvl)S@LO6Xu7efLK zMv>k4^^G_RUrPg;(XQa3V&Duy3=|Dflc4Wcj=ws*X0jh@JVQUz!mC8I-lq~Df_}De zvHH_r{oeYZdfGsyipCiQ-EjoNscdc>p1I>_#=+>E`yvqb#9r?)~Y;FB9}h8uoR!zIy&?9Yq}hCuLdsv>sE@8tHznBU0hVgeQ1 z87tO?wqY3E!|N!A_aCW}z`A0Hs?B6LN7U%&uzc~BL(@313q9QfQh@>}y8W7L(0s3T zGKwAwDTl1|qahUf!sG!Oad`r@d`qwVG&eDacZ_=c2yKs^kV)n{wFCwq)zTux?o?)P zNWMvtTP{6x!O63VQQH65=VGZ#jg~z!lH*-2%ea%Jgj5X$_b2ATHTWVwJ0BcOOQ(@@cTB|k=uu@1I2kH{-ORUvS zqmu!H@P@7t_*lE6cAc3AN4IJbOFxAZXKM;g)3ps)(OGNG)0x&A&u9%8HtM1A^!s2) ze9IDM8TRG^cYt8}aej>rLThYLASRQN!%-NhD-WH<8iP>Qb-MO2Tn)`IFF+DWNDX(A@YYP2C~o2n6JKseES?Hz`vCTML4C&D|6 zwYQmJop_F=z#W~^reqZ>_D$31;BhM4S*E>>C(^Zei4dY(#YxPCdD=GPXSS3&+Dtt2 zgOdi-ZO}Bh)K;tGF%Xi0eq?L{C=Ik~uy@ezuG{5hf%r|@CM-4q2zPkJ0Otc84Q$Nq8pfs~skMpo}=JP0u-l zpuN-UvN5g}L-ZbP5FCs4a)A1(r5R-ZQ1RmUBb~&6~nU!{QjPblk3bjp5m|K%*uU9$eGPp{kxnKa21{ zv!UYab(dq$!P!!6KfW2@)str{@$5m3*sIDdt(4(+AznoAT?J>4YD8&wd08zY(c`Zy z1U=VljS-2hE2`zL3uhv{rig0})pggwc8$E=V&c`&`kHp;FB*&U2P~&hxyV_Y;6X^^|^SA={&1R zH#HW8mnd76Kp2x@Iu_&+n{D#Y^>HREwLKaIhNiUu3}+2Ctf-IQvs>IBt}rq z2Z*Njl$kbB*RiHU!mE@!!W2hkZNtD9@|0;4yOCuI7h&D1HCh2GnqUH`Xe~vrH7C;8 z_d-i4t1GN8fFM3a{b!lpq6QC{qL?Aq^dUc=X@T@S6@_!@G}AdzKuGL-6QTigOo#@2 zjrpgWP62mzDcnX|Uog3;X1&Et-p5R@Q{7%;1U=p-v{87F;&bwZj&Rp%*U=x3nR>H+ z^Gsya#bA$5lNq|t#CP`ESMYj+Qr|Qkq>|&Hm`WLA>IS>Wt0q6|^R#J?0B~sLOj8Ti zW{Ii4L1@Yr7MKE}v>tc8MTJ{TJz2_fQ(riZ-ixXN-G*tn)S05z1KR>!xjDP;P?U$y{;eEOUbiUMoYn>AxT(W3{EGbpm^? z0%A~GW;!Fh&7!xMU<`|V%5;R62p4IH78bH{{$}{OsLsrL(Da2C7}4k&(?Is>$0nT6 z6ONcpAsB;ZerB4@9zAM;Nf!Ya2W*t-kY`fe4Y(fKUNo&|%d1VZG`gKA@f~o742)_C zk}=bKqZaWS8}FQ83LJ7m5M;%01F*R;ifQ*V?+sH8M)zA$?p>F8(+*H&wA_R`-87Zc z+G!3wtGU9*=|K{cbGX<#iecXSX7F;sr(FT`1nDS~(;cVD1ruG6;RQaj^YgqkdQ&TGY#MG7c zUN(*5zcpahUOA5QlI4D7dVw;&GNn?%ZmADJ38Pp_nKS^q@*R?$-tCO=FR(J8_EVJk zj)Z`bSXnlJU1g?E-XuuXn|cS@Fi)IZBS;@YlG7C3SB_;T`p7t|{<)KUT_b!%k()d) z^0$|_=@FoN>g!0rt!pu|rpd$oBW z8=5X};Z$V6>-M_KP?lg>%Wh`KMsCbnd`SL@GL`~rwnY#bM_!ZJULzZ?rl>bo~euF zErRsrc5@((RRy3?=^})`%4(CefWVoalCdNBiYk9Kccr?4mLFN-v+_v|K%?bDEi>4x zWpbe?e8b8|Sa67~NHI@fPZ!DyHLz=ycQ+59l20wySl5;EA)RoIfs(I8T;8T(|Qt$(3hMf)xX!Y`y(w`-Ew*i!S8LF>m2=D#ZE{6j8KEc{CTZ{<=d%Qr_- z)t1m`%K8Nr7fdo=qAq(iJz2#@`E2l^@Eb)%i*u+%V<}-jdm7kSiUwoZqU6t1f z0H~H9Hg6%%WpfT#&&{`(@~!-(ppinrw5P?c^#k*K_Q!*=M#Hic%Rt^FNnnMaT3|7Y z*k-N=;#0!;rp%lqu-!k&eYKbx_4CXT=-CR;vw8n3e*q%2S{_Y+@e_&Gexn&eS^dQh zl$UJYz^42mza+piRXvn*T!7<7OBs*CJW=q5oJ+o1$xLP6$kWODj@p@WKG95M-)hVb z0miH95tcvrkZa5QlKC_@UPY~t+h7NALGu{fY%~u8LnuY90*m4+4a`%GJo4k$c3e{% z*$%6@kD!x)c#^`{VzX${@SZnvVQZ)&O=?D`D&=#$r42v{iV&rgWOD_)$?N4}t|vT1 zLZoo);Y4g_hRO*Tq+3D(Qaz{6XBYq&EOiAk4||syQe}TBh9aLf&qmCE*$eIK#YgF2 zie(OEY_{sicV1(n3cWdnyftbBc~{6k^7|qvx>g-XIg2dev~8fd}34tJ<`{_T(DE&ZYh?H9cnHW z*ol7TB#q!G%HG(dsKnEZ?}4n8^*{qXo0ef7W7H*MNUu`vw^Ec;XQT9MY=Fax?1A~m7x^XA3(7MN1(2cdg(y*ZVC90L*-^8q~4?&|*A zpv+BK_7yYi&3siMtSZ0Lm@kcbmh-e3NTp_!I!aFE>k2~j#y)GtQ!tiNv*ce{Nx3-- zp%!;n!&I7a#*Bp|L~0H%t(;0JVU`$**a=$E;sWz@5#(;QZ6e_JT48=iFSOzqAeEIZ zvy|Lv6~mxX`NAc^oK_)Uf=%vOQQ?2LVbO==LBbp3%^3B|%^eQ z1d(OJG&s+1^ij?Mb<4dKya{&>O8$GRiQOP|#e{u`j{_s$VM?icA_84##yjS%Qit6c zfzA}Y*F4h@zx#mzVyx=Hk&EL=&0e!dYKbo=Q03=Qj(@bEaj*r*jPW@hX6TcP|L6&c zi;zT%cWP!Z?>IB|c7JP8|6q&2Ic_HH4 zF`1}pkwu}r?V(8s6ctV6t<;R;UreUT??A@-IG;t}ZnpR+qgqa6S*K<6KuxU%WM(hR zVY|+laa01;n%~@4!%{|>%Yz~z6U%6G6}_+>gc&(s$TL{R1@qe)JX7kk%@MF&ERz?o z7cQIO_3XmxCkEdtz)Du~maN?G7`{GXW$4Q4C-ZMq8O%6mO*2OYYe-@B)6M5Fn@)oT zJmClPDM{!?iz`BH%sb!QLBodJFmDxv?tF&;V({P0utoKt%pcV~Z2v9u1Au)|<_*=o z(`)&HhhdkV*JQDbI{9IQ3GNdTc>CeMsL?R0xTJzYcf2J7;2C)pR&mQPo!C2RJo8VH zU%|{Tk!7|c$}&JB^r6h#n$8T5kPielYN!S4!u@B5uY=f@m)e(v^-*ryWl>eO0mRignm?7tAf7FXl?)$lR1{YUu21ZJKwA? zuGBOj+YOD6t@m2Sh}`P8UG~B8&aWL~cRsW!`{o#w@Jiqb6AbI-wi8G|l1_B_N}vY*si$ z?id^u^Z%~3w}Rr1qv&<=r64UcD;Z+JYWU{}d0QAy)!PMdD$TRhatmYXSxaY1xv2ga zR1|}vx@hzh{k}M#&(98IS-OdQKpG_1EOGe;lYzUW%<>UW7Lf9- z_!M0_WSvW8H#|`+XM`0_|G+NGVnLWqsfW!;tl+416HX7yWdz&j+cGI{zSy42^mwqi zIaI0B{>a4%6?auw4hI>Much9T>0I#X0Qfx|I=MFUQi_~p%HX@8ci2lGSf+4$W@)Yk zeSMtw^?dSQ)4(%OW%*JR9>b|s0)^`t%U7Iuud@M@F5y$lX9ns)nYD2CE?V8=``OB8Z#)aG41P}y$C7TP=i!@(Ye&^W>q$h&UPb%ABNn;OP zv8?8%NBMS_!1<1e00y^)XEwEPRBO1)| z7<=M3%Tsz-6UQ2?0N{NnSljD_X8@?OBNEnNy`qQJFxBXVx+ASi44nVB29zSTmY$?_ z;Ec0$WqJTB$0mip*Na|q$jyR=54O=^9jf7|ISKLP=fyW!mETq)u%)VX9=9Au@0Sw) zPT@EZp=Xw(@XlJ{oqZmzV;gK+O{}nOy+ALFu)-S~YkeDe1gN}*p9fl5-_r{(Qq&8P z&8W(vg++g>*o0C(vEux)O^jjJZ(5^-KM9kosOxqcK#L(#5iLF@I;re{btE59IAi1t zu@0xS#@2T1dWH27m|Hqp6NDAC_@ww7t65FJB z>o7qogg`G*{lLh9tSrGgM8h@>v<~OwdW)m2{n^05)^bj+w>ZWc$C8FyPl&>5D($Rm z%u+Un!p<^nw3Rf%t8DRad`co@x`@4$ZJnZnIWbDLJ_cWj&8nf}Q)Q5$daXs2G}U?n zKsxUL-8{PVq3C9-rdg+QGh)GT>+9@^PPXB}Ez)b$#bbMyQo8Dr=-^a9!z$hiO@Zxi zh-V=y>1Im`&Y5-aui8=p85|)41NWdOjxBu5`m`XtPQo7RL$s|KW?9xc%Zsf4LTdv9 z4}rWHaj*Gp?tsJ2KV^kW0#WGFo6LXK`XRdFUpns6#}YqjOB<*at=Zp8j^e=6s>SW!Ulr_`pVn+(Bossx}a=#NXIagRQIX6-LInOg} z=_)HoSTbE-XZQ0%@FhCpf0R*j}YGeqYY-G%~oJT%USk7 z{=JGaxYe;REoTF^TVc!IPW7G5P8PW(bgIBE{l^xEAo?_0ny_oP6MJyQ zo~<#pIcWVDVeN&DtRq;#Mr#hR)=m_`Ye!UjQ|kq4`-E*aZTZ4Fi1J>s0igb@XkcxR zSn;T4RQsB^pXGRMfa|~dnXM~(?3ndgPTD8@SGr9#Z;D`|9wJ8bD10}|I$@om2NwO* z8LLl}-bMv`S?+Jv7sTLPEBo9!NZ7}6Z&_jeEjb`Lg5t5I7p(I%!hXsuw+y2hGe8t_ z)M0aK*!4oIPvBAw?5A zs9?DbY^ZuIPIwvB)?vHqth;qQg0t=}<=5T5bHl$by}PG(2u0qM5&mC&|0r_AOmF1}93v4DmFb8jlkNs3u($ z@x1j0*Y;t`*sCw2f@s~3d=xgPx|8Cwd>!crLv@unTn}#-zIKF8{A`;~ZDv`!6u)Fy zKo@6OKiH+S!N&VOTbycJ1Z3r93A3(XxTiBO_9$DNhIc8;sO?D+>n!zDvBsLVD-z5z z!ZFIUX*aRFYc_-tKsK4ZZ?$#eSskjc+uGh4kTvaXUXdc1_!wcL!!H;j9p}8SAmge6 zjx8lmYDq7=8QPReR#_S`h;^iG97+YFKCgpf{C`CFC*id=6+ z*pW?p?S3KtQVdNf?(AQD*m1lxI>6#iVj?nurc`BFWP+r2saud9VO z!TK{FKh=1h1J|<^2V`}K?Mn_ptWDJU86Iafu)N;3*4!Hth!YBtV5&{l(Y?{pg8eYc zhNt!gS_~Enqz$o6M}sVx?160CehmjFe(u@BGM==ZzQ5c~<>g$WEY%)ETZe^)(xUOO z^@NY`oMvH@ZKUVa*}sO}la>TS?K?vQL$x8l+#!eJYZ_nln(@#L=`*}8Q|Uz!5&Ls& zqd1JQve5D%!^-jo=VL^of_EurwutcUpYTvVxX=bX+?QG~Pl%e=&ERK3#zEY)foyx-pg&xEjRtXvBPREVTt5pq!06$m@KYvYwa2cOA5efGM)tV-k$`b$9tt zY^+bEZMB}q*nJ0=^Zf@HhU9dL|Il_^szVEq@4}|-%O}(f00K_f9?$@+2nD|=u;Oal zbe`}ca*l|6LuYKyh{Atarq>4i3wjbURkv7X6Ffie_2U}W?4k|m<==sYv&x`+ueCY! z!U*R7+ICWuenk*w2+Q4PeHjzKziuVPU$>po=mc6k#QGvDuCq-OH98ID9#IhT^gz}gd&dNfAjz!R62>WS4d#e-fmkZ@cP{B zqF|qFkTAt=BnFkjAKF`Bhq51(ZsP_6)n{;O@CJ6cI*hb$9qXy#j5Of*c%#9v?{h{ez*OofwPr=_u#!+jI4i*y<8&! ztfh;f0b$niJG?_xQC2rQ8*6XPvt3li*=^LRrF}Q`_t}TDmaXmfV8Gph;Jz@8El;rH zFptn$oy__VwQm(j4d?EiUiKDzp6JZrAhACmszrbuF#4@5DeUY6_U3{F;GfP$l_TuE zSb8rz69qexVcByHoTs}Cn=a1kxM#4vnbEl>EHD;WX4k#Me44nmeu_CtE$0sYDL56C#uZnF3j6F{Y&oG>vlAz@OSuU$gCKha0g z9qb+&Fw$O5ojTeRDS4E=pBNwSr|hE*Wm-MTK0zCw7&nP&N84KojYCJ`S%xoBv(Ia(mnm4v6dT%4nMnQYC?LN2fURqyo?3_7sTJe{+b+b0jTD5LQ-^_@J zrScgOR&9%B&4G`c+ECFU39{ekBd-S5uuBwbq#vlEDK@o#YWjmC(!AMTp2#yj4HZ4W za|9!^Y3k6l3?v>N?B#d<w~v(3P?-u-)| z4M%q3j-kE#4@w(2808I2%Scb{o`$Tzg9qS~*gGjx$F<4^H;mmD3Qtc662FBA&%7Pw zTPPS-Ob%qjFC8S14UU{BBg7B>OD5-V@QjTdZue;t;;4F<-Hr$Wd%WPI+aoZ#>xSE- zq<9PofB=Wup92=K@IgB~O_Z7%VKpXTlqq;cv&!G>1p-?!(LNKINm=DBdsp#K^0MXR zCA*oA_r@zL9a$7RIifw4Tr`?l*);nggd$Vn0}jN&<=B7Y;hO$=cC0^Me7zY(7esnk zn=<=pvG}Ypj2970!h3csKza5e17|;fx9y#w-!>Yan~I<9Bd{&hwOH*4jOU~r_djF! zYzLO=ZT6;kKI)p{)sihdVaEoH^V8j7W+O1Ob>X$NVv8&JN1UyXakf7G0MoT*^~ny{ zIWJAI`&jp4JNVGsvg*@D_@I2B+JmHaZwKeKk5!-L@BT^Y_FnK^KUJSI_69>*bN0yV z_LmI;$keykL8jgYWhb!I$LxDy$I*tS2EUyMR~i`DYfftPtSZmmRNS@OUMp!4qPhDH zUny_#{Z_entK#u$&ni#b5k`fklxqmoa=^=m=#p9GS-eYCO5`t`Xs@L}P0rb0-F4Ld zuvS92WJTJ2RZ-2ac8{^+8hhX&EG<}g`Ev93+OAR7ulCkdcgh|iwL|fp_)61c*Dv-t zK^5QsxWPT`V&C7H{9%q$OucEp3~c8;(mP5ih=kof1V$-;gyR&IwU2CiM@9x2FG)hm z-%CFP$}aml0d`Xq2V=(-J9dTL_`L_%yIdUJa5>Cuv^#c^YjvY z!pALtZ%&oQn6{y903oDR*ic=)KpOPkt;0?ZqtLw3&+yO(qg z9a-$jTVQoWK9uYj$Htvo97FZ6GB-SFKf;a~9Lb;xrKm-AMDI8c0tjXR4jlgX z1~#Cu-j4Rh5nH^0=|~py*KvvFpTv>eu_j1jsvF7njB#{_+-FP@OYi4kI#`B#_H%%- ze6VAKUW>@pqrvk&8$QZ`yq{x>ItO4ddIS5bKSwmzcPLvn#xYyqDN%HwD$Q~r#t>Ac z6Zp?@pfGg+nmhs2rTp)SRQ9+X5AZpT&v~ws@}-)1%G!qGS)X~1J)-asmEShV)Onvt zVF?QyeGS4amiMINca3rKhDiaSx~uQ@CIqt4`DYxB4dYSkl!*z608=`8u)a$i*vU+# z1t%P^H!gF)-Z+gGR6E*Jj=>qmdKNhF5TDMpD)y!>A)lR33yhsjk*gZnE+Z~`1-0iq10ti}J?norxUPmbFzRyu1!e)B0v9l3n zSe$@DR5)JehSTz04uta_a$JJplxdH09X<{KIsdtUmOSr3s+cOr5m8)-r|H-)9WGk` zqN4*FdB%aj$tP$@u>*LtPaPkN(xP}g*=gC!P*VDN2ew3cRIn0__tZG9aEs`Y*T9*Y zQRvXI?pL@l0kDqqTJo9p8duhnAXo^tq>i`bDNqOFUE|a3v5^?xKEX%jSD~V&zd0_5 z!ZS>Ji{H9rr`Cxd&mw&Q|M?u{8lBvL>b!!eUfk5~&P|OPIAMlb#+q(+oI|+DW``TO zN*y{rPnY{9`I0HCh11NslsVo-7ChOhr7abXD01v@1lN-1$-m11ORU}b5f3tMx|


    vxArHIjUCR0j#=(6u>48Oh;oR~G> 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 delta 39540 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 fW;J9xdi$eM$CVxG<9|iw Date: Mon, 26 Apr 2021 23:57:02 +0000 Subject: [PATCH 45/46] Improved robustness of the "showdb" debugging program when it is parsing corrupt database files. FossilOrigin-Name: 3eabac2ee50fd70b22a927d3d2934718a15e1f666d8d271b854579156c8b01de --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showdb.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c0f0a3f4d7..f51fabc913 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sdbsqlfuzz\scases\sadded\sto\stest/fuzzdata8.db. -D 2021-04-26T22:30:49.648 +C Improved\srobustness\sof\sthe\s"showdb"\sdebugging\sprogram\swhen\sit\sis\sparsing\ncorrupt\sdatabase\sfiles. +D 2021-04-26T23:57:02.468 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1864,7 +1864,7 @@ F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c 49e810f5c414c792b5bf38cd5557ca9639713ebfef32aaff32faf7cb7ccce513 +F tool/showdb.c d99bd18f8386fd83f8236b1c367e464a6d58e65681f2de25856dfa5076fa67cb F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f80d7bb2c305c1dd4658767660b33259032c048a91f18c654a6bda7332c54a0c -R d8e1326693278e6f1513c26703f6c0aa +P 88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba +R a7a438a7a1e4a8c7f93ba3c58bbec3f4 U drh -Z bb52e9bce99951a04289010ee988307c +Z 323bfb66712236d14601f16d2826d127 diff --git a/manifest.uuid b/manifest.uuid index 703532bf7c..1cf0c55c7a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba \ No newline at end of file +3eabac2ee50fd70b22a927d3d2934718a15e1f666d8d271b854579156c8b01de \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index 09c4d9de44..b4b751e588 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -912,10 +912,19 @@ static void page_usage_btree( int cellstart = hdr+12; u32 child; for(i=0; i= g.pagesize ){ + page_usage_msg(pgno, "too many cells"); + break; + } + ofst = a[cellidx]*256 + a[cellidx+1]; + if( ofst=g.pagesize ){ + page_usage_msg(pgno, "cell %d out of bounds", i); + continue; + } child = decodeInt32(a+ofst); page_usage_btree(child, pgno, i, zName); } From 2f40dc98842b0f707d15d780e981a4763aaa89e1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 27 Apr 2021 00:05:03 +0000 Subject: [PATCH 46/46] Better error messages on showdb. FossilOrigin-Name: 7e18e114b245d17aa259ea9ab42752ccc9ad5303bbac8d8e46928dd10319f545 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showdb.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f51fabc913..2d2561832d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\srobustness\sof\sthe\s"showdb"\sdebugging\sprogram\swhen\sit\sis\sparsing\ncorrupt\sdatabase\sfiles. -D 2021-04-26T23:57:02.468 +C Better\serror\smessages\son\sshowdb. +D 2021-04-27T00:05:03.863 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1864,7 +1864,7 @@ F tool/replace.tcl 60f91e8dd06ab81f74d213ecbd9c9945f32ac048 F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c d99bd18f8386fd83f8236b1c367e464a6d58e65681f2de25856dfa5076fa67cb +F tool/showdb.c 8c6b1cbb86ee25ca2173497183f8fcd444d4e26923e4cf57ddabe66c633b4dab F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 @@ -1914,7 +1914,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 88d20500c516fe89ad1cd42f7366ca190c3790f911f11ab332b86b675f5f69ba -R a7a438a7a1e4a8c7f93ba3c58bbec3f4 +P 3eabac2ee50fd70b22a927d3d2934718a15e1f666d8d271b854579156c8b01de +R 6fea783c7cee361a6851786be6d6a280 U drh -Z 323bfb66712236d14601f16d2826d127 +Z 6b8049099c18bf9fc8a3db324724e010 diff --git a/manifest.uuid b/manifest.uuid index 1cf0c55c7a..28a0d53101 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3eabac2ee50fd70b22a927d3d2934718a15e1f666d8d271b854579156c8b01de \ No newline at end of file +7e18e114b245d17aa259ea9ab42752ccc9ad5303bbac8d8e46928dd10319f545 \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index b4b751e588..5e949939e1 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -917,12 +917,12 @@ static void page_usage_btree( cellidx = cellstart + i*2; if( cellidx+1 >= g.pagesize ){ - page_usage_msg(pgno, "too many cells"); + printf("ERROR: page %d too many cells (%d)\n", pgno, nCell); break; } ofst = a[cellidx]*256 + a[cellidx+1]; if( ofst=g.pagesize ){ - page_usage_msg(pgno, "cell %d out of bounds", i); + printf("ERROR: page %d cell %d out of bounds\n", pgno, i); continue; } child = decodeInt32(a+ofst);