From 46b341530e03b54d9c4ae31b81abb719f4b5f0e2 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Apr 2019 15:41:33 +0000 Subject: [PATCH 001/132] Fix a problem with the user-auth extension and deserializing in-memory databases. FossilOrigin-Name: 09fa0b3c4adf7f81a777975762029ad43dbdc76b02dc32d2307e1c42465213c9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/attach.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8bcfa4877f..e4f193dbad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sscript\sproblem\sin\sfts5corrupt3.test. -D 2019-04-15T13:59:08.804 +C Fix\sa\sproblem\swith\sthe\suser-auth\sextension\sand\sdeserializing\sin-memory\sdatabases. +D 2019-04-15T15:41:33.596 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -454,7 +454,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 25f54387121a0c5fd0f49b299f4070c81af8f26a84edaae6de679c4e4b71b1ff F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644 -F src/attach.c 732d45dbf802b79f66503614a23e862887231d4d4937eac7c28a92c6fdb78e1f +F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -1818,7 +1818,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 0bab4ece6e81916d0f7255a8e553b8ca040cb8a96ab21e294212e232119f8ddc -R 17255f201fee712c437d0bc74b54b3db +P 734192d876e0489cb34e454aaa4a9c6858145791a49959b31dee2917a8e41a7d +R ccb16b8d5f092c09f18270d0885ef69e U dan -Z b7139ecd0efbf2427baaf4b0ae95a55d +Z 8977b16e1e0f2a3bdfa5e727ba8e15b2 diff --git a/manifest.uuid b/manifest.uuid index 1bfa42692b..847e5f4d36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -734192d876e0489cb34e454aaa4a9c6858145791a49959b31dee2917a8e41a7d \ No newline at end of file +09fa0b3c4adf7f81a777975762029ad43dbdc76b02dc32d2307e1c42465213c9 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 65b98a623f..55e0eb5363 100644 --- a/src/attach.c +++ b/src/attach.c @@ -241,7 +241,7 @@ static void attachFunc( assert( zErrDyn==0 || rc!=SQLITE_OK ); } #ifdef SQLITE_USER_AUTHENTICATION - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ u8 newAuth = 0; rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); if( newAuthauth.authLevel ){ From af4d50c4a1be9a4caa06270d17ef9ea8bb7c5519 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 15 Apr 2019 19:17:50 +0000 Subject: [PATCH 002/132] Fix a bug in test module test_fs.c causing a segfault on OpenBSD. FossilOrigin-Name: ee886600297c2a03d9d1d10db88d3d107b48e5d4de5e5d91b0ab16cc7c447ede --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/test_fs.c | 12 ++++-------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index e4f193dbad..62c33b61f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sthe\suser-auth\sextension\sand\sdeserializing\sin-memory\sdatabases. -D 2019-04-15T15:41:33.596 +C Fix\sa\sbug\sin\stest\smodule\stest_fs.c\scausing\sa\ssegfault\son\sOpenBSD. +D 2019-04-15T19:17:50.242 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -547,7 +547,7 @@ F src/test_config.c 5ebafbcd5c75ac1c16bb0c8fe926dc325cc03e780943a88ca50e0d9a4fc4 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c a0c3bdd45ed044115c2c9f7779e56eafff18741e F src/test_devsym.c 1960abbb234b97e9b920f07e99503fc04b443f62bbc3c6ff2c2cea2133e3b8a2 -F src/test_fs.c 70e30fdeb5038997bf5954816042f78ac6fc568c3d9e07c10b7d6af3886462d5 +F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480 F src/test_func.c 181f992e5495644434c4f0e3cc72362a78c295eb2cf3ff4d02498b8bde7aa276 F src/test_hexio.c 1d4469ca61ab202a1fcec6543f584d2407205e8d F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 @@ -1818,7 +1818,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 734192d876e0489cb34e454aaa4a9c6858145791a49959b31dee2917a8e41a7d -R ccb16b8d5f092c09f18270d0885ef69e +P 09fa0b3c4adf7f81a777975762029ad43dbdc76b02dc32d2307e1c42465213c9 +R 2c29be806e15259c3d103a682fe95c22 U dan -Z 8977b16e1e0f2a3bdfa5e727ba8e15b2 +Z 7ef87e754e329fa1f6401ed2164f4318 diff --git a/manifest.uuid b/manifest.uuid index 847e5f4d36..d78b9e0934 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09fa0b3c4adf7f81a777975762029ad43dbdc76b02dc32d2307e1c42465213c9 \ No newline at end of file +ee886600297c2a03d9d1d10db88d3d107b48e5d4de5e5d91b0ab16cc7c447ede \ No newline at end of file diff --git a/src/test_fs.c b/src/test_fs.c index 682a083e67..ddfdc7fb59 100644 --- a/src/test_fs.c +++ b/src/test_fs.c @@ -129,7 +129,7 @@ struct FsdirCsr { char *zDir; /* Buffer containing directory scanned */ DIR *pDir; /* Open directory */ sqlite3_int64 iRowid; - struct DIRENT entry; /* Current entry */ + struct DIRENT *pEntry; }; /* @@ -236,12 +236,8 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){ FsdirCsr *pCsr = (FsdirCsr*)cur; if( pCsr->pDir ){ - struct DIRENT *pRes = 0; - pRes = readdir(pCsr->pDir); - if( pRes!=0 ){ - memcpy(&pCsr->entry, pRes, sizeof(struct DIRENT)); - } - if( pRes==0 ){ + pCsr->pEntry = readdir(pCsr->pDir); + if( pCsr->pEntry==0 ){ closedir(pCsr->pDir); pCsr->pDir = 0; } @@ -304,7 +300,7 @@ static int fsdirColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ break; case 1: /* name */ - sqlite3_result_text(ctx, pCsr->entry.d_name, -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pCsr->pEntry->d_name, -1, SQLITE_TRANSIENT); break; default: From 112e174020809d0b91249716fb9de4aa3ee7437d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 16 Apr 2019 10:51:29 +0000 Subject: [PATCH 003/132] Avoid a sanitizer error in test1.c. Have releasetest.tcl/wapptest.tcl create a file called "makecommand.sh" that can be used to rerun a test from the command line. FossilOrigin-Name: 4de4480ffdea1e923c4b964692ccde92d713c8b6c056bb04bddf1ff55ee891ec --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test1.c | 6 ++++-- test/releasetest.tcl | 25 ++++++++++++++++++++++--- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 62c33b61f8..6f83d909e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\stest\smodule\stest_fs.c\scausing\sa\ssegfault\son\sOpenBSD. -D 2019-04-15T19:17:50.242 +C Avoid\sa\ssanitizer\serror\sin\stest1.c.\sHave\sreleasetest.tcl/wapptest.tcl\screate\sa\sfile\scalled\s"makecommand.sh"\sthat\scan\sbe\sused\sto\srerun\sa\stest\sfrom\sthe\scommand\sline. +D 2019-04-16T10:51:29.014 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -528,7 +528,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 -F src/test1.c cfb303eeddd3670409af6b58d2ddb928b8e9e70822d681d3df88dfaabb7bea6a +F src/test1.c 0dc98af0769302672dcefd07a6128ee14e837b9f6e338a1aaca7ac31e4d8d2f8 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -1227,7 +1227,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 -F test/releasetest.tcl 7712811e0f4e2f198ec786cb2e1352b3793d7395f48a3cceef0572d8823eb75e x +F test/releasetest.tcl 204efd3a87ec1d62da2efde42c673b18b955350a9d3c6ac0b4dbba5bc8595808 x F test/releasetest_data.tcl c3746248b5ad8f99a29020f83501bb25e024156ecc37e05c71c76da4fc8601c6 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb @@ -1818,7 +1818,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 09fa0b3c4adf7f81a777975762029ad43dbdc76b02dc32d2307e1c42465213c9 -R 2c29be806e15259c3d103a682fe95c22 +P ee886600297c2a03d9d1d10db88d3d107b48e5d4de5e5d91b0ab16cc7c447ede +R 8b174ed25bfed0d8eb722ebaa3aaabbf U dan -Z 7ef87e754e329fa1f6401ed2164f4318 +Z 97f4f18a7a6e556c0ee0ac2993a46468 diff --git a/manifest.uuid b/manifest.uuid index d78b9e0934..e29f300b76 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ee886600297c2a03d9d1d10db88d3d107b48e5d4de5e5d91b0ab16cc7c447ede \ No newline at end of file +4de4480ffdea1e923c4b964692ccde92d713c8b6c056bb04bddf1ff55ee891ec \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index bd288a2b78..17819b9239 100644 --- a/src/test1.c +++ b/src/test1.c @@ -4272,13 +4272,15 @@ static int SQLITE_TCLAPI test_prepare_v2( } pzTail = objc>=5 ? &zTail : 0; rc = sqlite3_prepare_v2(db, zCopy, bytes, &pStmt, pzTail); + if( objc>=5 ){ + zTail = &zSql[(zTail - zCopy)]; + } free(zCopy); - zTail = &zSql[(zTail - zCopy)]; assert(rc==SQLITE_OK || pStmt==0); Tcl_ResetResult(interp); if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; - if( rc==SQLITE_OK && zTail && objc>=5 ){ + if( rc==SQLITE_OK && objc>=5 && zTail ){ if( bytes>=0 ){ bytes = bytes - (int)(zTail-zSql); } diff --git a/test/releasetest.tcl b/test/releasetest.tcl index c520a535c8..d216d2a08d 100755 --- a/test/releasetest.tcl +++ b/test/releasetest.tcl @@ -501,7 +501,26 @@ proc run_slave_test {} { unset -nocomplain savedEnv(TCLSH_CMD) } set ::env(TCLSH_CMD) [file nativename [info nameofexecutable]] - set rc [catch [makeCommand $testtarget $makeOpts $cflags $opts]] + + # Create a file called "makecommand.sh" containing the text of + # the make command line. + catch { + set cmd [makeCommand $testtarget $makeOpts $cflags $opts] + set fd [open makecommand.sh w] + foreach e $cmd { + if {[string first " " $e]>=0} { + puts -nonewline $fd "\"$e\"" + } else { + puts -nonewline $fd $e + } + puts -nonewline $fd " " + } + puts $fd "" + close $fd + } msg + + # Run the make command. + set rc [catch {trace_cmd exec {*}$cmd >>& test.log} msg] if {[info exists savedEnv(TCLSH_CMD)]} { set ::env(TCLSH_CMD) $savedEnv(TCLSH_CMD) } else { @@ -737,7 +756,7 @@ proc configureCommand {opts} { # specified targets, compiler flags, and options. # proc makeCommand { targets makeOpts cflags opts } { - set result [list trace_cmd exec] + set result [list] if {$::MSVC} { set nmakeDir [file nativename $::SRCDIR] set nmakeFile [file nativename [file join $nmakeDir Makefile.msc]] @@ -758,7 +777,7 @@ proc makeCommand { targets makeOpts cflags opts } { foreach target $targets { lappend result $target } - lappend result CFLAGS=$cflags OPTS=$opts >>& test.log + lappend result CFLAGS=$cflags OPTS=$opts } # The following procedure prints its arguments if ::TRACE is true. From 2eb2ca839185e9bd5ef57da7078adecbd2e56994 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 16 Apr 2019 11:21:13 +0000 Subject: [PATCH 004/132] Avoid a sanitizer error (pointer arithmatic overflow) in vdbesort.c. FossilOrigin-Name: af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbesort.c | 10 +++++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6f83d909e4..ffa9189f6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\ssanitizer\serror\sin\stest1.c.\sHave\sreleasetest.tcl/wapptest.tcl\screate\sa\sfile\scalled\s"makecommand.sh"\sthat\scan\sbe\sused\sto\srerun\sa\stest\sfrom\sthe\scommand\sline. -D 2019-04-16T10:51:29.014 +C Avoid\sa\ssanitizer\serror\s(pointer\sarithmatic\soverflow)\sin\svdbesort.c. +D 2019-04-16T11:21:13.568 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -597,7 +597,7 @@ F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c 8e6889761e344babdb8a56dd1ac8911501fa648396544d1644f1cd6a87c80dc0 -F src/vdbesort.c 31c7794a517e8b0a1704988f1f7596b74c6fc07eeb7bb85776f50a391ed9d94f +F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 @@ -1818,7 +1818,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 ee886600297c2a03d9d1d10db88d3d107b48e5d4de5e5d91b0ab16cc7c447ede -R 8b174ed25bfed0d8eb722ebaa3aaabbf +P 4de4480ffdea1e923c4b964692ccde92d713c8b6c056bb04bddf1ff55ee891ec +R 53d48b50e3fea254b204992be6aac766 U dan -Z 97f4f18a7a6e556c0ee0ac2993a46468 +Z 2252f4361031453f785e5bf47a799819 diff --git a/manifest.uuid b/manifest.uuid index e29f300b76..afe628e5f9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4de4480ffdea1e923c4b964692ccde92d713c8b6c056bb04bddf1ff55ee891ec \ No newline at end of file +af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80 \ No newline at end of file diff --git a/src/vdbesort.c b/src/vdbesort.c index d84a4118d1..f909f812d6 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -1828,15 +1828,19 @@ int sqlite3VdbeSorterWrite( if( nMin>pSorter->nMemory ){ u8 *aNew; - int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory; + int iListOff = -1; + if( pSorter->list.pList ){ + iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; + } while( nNew < nMin ) nNew = nNew*2; if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; if( nNew < nMin ) nNew = nMin; - aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); if( !aNew ) return SQLITE_NOMEM_BKPT; - pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; + if( iListOff>=0 ){ + pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; + } pSorter->list.aMemory = aNew; pSorter->nMemory = nNew; } From d331c7ab1fa42ab7bcd4e26cf8c60a9201621922 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 16 Apr 2019 19:49:53 +0000 Subject: [PATCH 005/132] Version 3.28.0 FossilOrigin-Name: 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 --- manifest | 13 ++++++++----- manifest.uuid | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/manifest b/manifest index ffa9189f6d..8b766074a8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sa\ssanitizer\serror\s(pointer\sarithmatic\soverflow)\sin\svdbesort.c. -D 2019-04-16T11:21:13.568 +C Version\s3.28.0 +D 2019-04-16T19:49:53.412 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1818,7 +1818,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 4de4480ffdea1e923c4b964692ccde92d713c8b6c056bb04bddf1ff55ee891ec +P af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80 R 53d48b50e3fea254b204992be6aac766 -U dan -Z 2252f4361031453f785e5bf47a799819 +T +bgcolor * #d0c0ff +T +sym-release * +T +sym-version-3.28.0 * +U drh +Z 50f60d1cc2f388d0c03013011d963653 diff --git a/manifest.uuid b/manifest.uuid index afe628e5f9..09e5557944 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80 \ No newline at end of file +884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 \ No newline at end of file From 7e427337fe5df62439b980e2e091a89b36001d79 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 11:34:44 +0000 Subject: [PATCH 006/132] Faster and smaller implementation of sqlite3StrICmp(). FossilOrigin-Name: 7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/util.c | 12 +++++++++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8b766074a8..b6c54ac76e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.28.0 -D 2019-04-16T19:49:53.412 +C Faster\sand\ssmaller\simplementation\sof\ssqlite3StrICmp(). +D 2019-04-17T11:34:44.568 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -588,7 +588,7 @@ F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 -F src/util.c e12939405e77906d06ab0b78c5f513dcd2b7cec2fbb553877b0abfece6067141 +F src/util.c 415fcd6ed9d3bb7cad27d411ae4b9320ea2a18e6750ceb03cbedf453373fec85 F src/vacuum.c 72690ccb6877a88f8473a893cf9f6d7592236f3eebfebfa840b19c708acde574 F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 @@ -1818,10 +1818,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 af61a2fc45a0fa1277d7453779238b77de4c298a9f60714b7dc62ddca5874f80 -R 53d48b50e3fea254b204992be6aac766 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.28.0 * +P 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 +R dcc66ec8a55d4cba7e12163fe5fbfbcf U drh -Z 50f60d1cc2f388d0c03013011d963653 +Z 40a9f6f7fce76c8f72a2cb9229b22090 diff --git a/manifest.uuid b/manifest.uuid index 09e5557944..c8e27168f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 \ No newline at end of file +7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d \ No newline at end of file diff --git a/src/util.c b/src/util.c index 4fa92f83c0..dad2dba3f0 100644 --- a/src/util.c +++ b/src/util.c @@ -322,12 +322,18 @@ int sqlite3_stricmp(const char *zLeft, const char *zRight){ } int sqlite3StrICmp(const char *zLeft, const char *zRight){ unsigned char *a, *b; - int c; + int c, x; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; for(;;){ - c = (int)UpperToLower[*a] - (int)UpperToLower[*b]; - if( c || *a==0 ) break; + c = *a; + x = *b; + if( c==x ){ + if( c==0 ) break; + }else{ + c = (int)UpperToLower[c] - (int)UpperToLower[x]; + if( c ) break; + } a++; b++; } From 698c86f40de408b954381c7a42f0417704e491a9 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 12:07:08 +0000 Subject: [PATCH 007/132] Small performance improvement on the variable-length integer decoder: sqlite3GetVarint(). FossilOrigin-Name: 5df2bf62fcd4dfdaa195062dddbd5ce5420bc239b2649ac8f547e0db34e7f0bb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 24 +++++++----------------- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index b6c54ac76e..1e190dc5d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sand\ssmaller\simplementation\sof\ssqlite3StrICmp(). -D 2019-04-17T11:34:44.568 +C Small\sperformance\simprovement\son\sthe\svariable-length\sinteger\sdecoder:\nsqlite3GetVarint(). +D 2019-04-17T12:07:08.215 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -588,7 +588,7 @@ F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 -F src/util.c 415fcd6ed9d3bb7cad27d411ae4b9320ea2a18e6750ceb03cbedf453373fec85 +F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 72690ccb6877a88f8473a893cf9f6d7592236f3eebfebfa840b19c708acde574 F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 @@ -1818,7 +1818,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 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 -R dcc66ec8a55d4cba7e12163fe5fbfbcf +P 7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d +R abb269365d71bef546a529ae44e4c54c U drh -Z 40a9f6f7fce76c8f72a2cb9229b22090 +Z 80d8752f4698aa123849b705cd651c27 diff --git a/manifest.uuid b/manifest.uuid index c8e27168f5..a698b6544c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d \ No newline at end of file +5df2bf62fcd4dfdaa195062dddbd5ce5420bc239b2649ac8f547e0db34e7f0bb \ No newline at end of file diff --git a/src/util.c b/src/util.c index dad2dba3f0..d12e55516f 100644 --- a/src/util.c +++ b/src/util.c @@ -918,23 +918,12 @@ int sqlite3PutVarint(unsigned char *p, u64 v){ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ u32 a,b,s; - a = *p; - /* a: p0 (unmasked) */ - if (!(a&0x80)) - { - *v = a; + if( ((signed char*)p)[0]>=0 ){ + *v = *p; return 1; } - - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - a &= 0x7f; - a = a<<7; - a |= b; - *v = a; + if( ((signed char*)p)[1]>=0 ){ + *v = ((u32)(p[0]&0x7f)<<7) | p[1]; return 2; } @@ -942,8 +931,9 @@ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ assert( SLOT_2_0 == ((0x7f<<14) | (0x7f)) ); assert( SLOT_4_2_0 == ((0xfU<<28) | (0x7f<<14) | (0x7f)) ); - p++; - a = a<<14; + a = ((u32)p[0])<<14; + b = p[1]; + p += 2; a |= *p; /* a: p0<<14 | p2 (unmasked) */ if (!(a&0x80)) From 8083ef029f8a298462aa461bebc6a1c1190504f7 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 12:29:45 +0000 Subject: [PATCH 008/132] In the "pgidx" command of the showdb utility, try to identify orphaned pages and show when pages have been zeroed out. FossilOrigin-Name: eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showdb.c | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1e190dc5d1..bae2f7cb9c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\simprovement\son\sthe\svariable-length\sinteger\sdecoder:\nsqlite3GetVarint(). -D 2019-04-17T12:07:08.215 +C In\sthe\s"pgidx"\scommand\sof\sthe\sshowdb\sutility,\stry\sto\sidentify\sorphaned\spages\nand\sshow\swhen\spages\shave\sbeen\szeroed\sout. +D 2019-04-17T12:29:45.915 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1768,7 +1768,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 af978d1437562776fa4d94bf0cb772314c464e71ef24134a6e2301564ae60bc2 +F tool/showdb.c b4cd49d8f4df86349a6b41993a3eb5651e18a3f9903b4fbb70d18b66c8a358ca F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 @@ -1818,7 +1818,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 7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d -R abb269365d71bef546a529ae44e4c54c +P 5df2bf62fcd4dfdaa195062dddbd5ce5420bc239b2649ac8f547e0db34e7f0bb +R f4eb9f2a8e78f2d407da5d6c15776852 U drh -Z 80d8752f4698aa123849b705cd651c27 +Z 369a3d8533a731558ce8e524f18f4b7d diff --git a/manifest.uuid b/manifest.uuid index a698b6544c..9dae86999e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5df2bf62fcd4dfdaa195062dddbd5ce5420bc239b2649ac8f547e0db34e7f0bb \ No newline at end of file +eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index cb6ddabca6..a3301392ab 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -835,9 +835,20 @@ static void page_usage_cell( } } +/* +** True if the memory is all zeros +*/ +static int allZero(unsigned char *a, int n){ + while( n && (a++)[0]==0 ){ n--; } + return n==0; +} + /* -** Describe the usages of a b-tree page +** Describe the usages of a b-tree page. +** +** If parent==0, then this is the root of a btree. If parent<0 then +** this is an orphan page. */ static void page_usage_btree( int pgno, /* Page to describe */ @@ -854,16 +865,32 @@ static void page_usage_btree( if( pgno<=0 || pgno>g.mxPage ) return; a = fileRead((pgno-1)*g.pagesize, g.pagesize); switch( a[hdr] ){ + case 0: { + if( allZero(a, g.pagesize) ){ + zType = "zeroed page"; + }else if( parent<0 ){ + return; + }else{ + zType = "corrupt node"; + } + break; + } case 2: zType = "interior node of index"; break; case 5: zType = "interior node of table"; break; case 10: zType = "leaf of index"; break; case 13: zType = "leaf of table"; break; + default: { + if( parent<0 ) return; + zType = "corrupt node"; + } } - if( parent ){ + if( parent>0 ){ page_usage_msg(pgno, "%s [%s], child %d of page %d", zType, zName, idx, parent); - }else{ + }else if( parent==0 ){ page_usage_msg(pgno, "root %s [%s]", zType, zName); + }else{ + page_usage_msg(pgno, "orphaned %s", zType); } nCell = a[hdr+3]*256 + a[hdr+4]; if( a[hdr]==2 || a[hdr]==5 ){ @@ -988,6 +1015,7 @@ static void page_usage_report(const char *zPrg, const char *zDbName){ /* Print the report and free memory used */ for(i=1; i<=g.mxPage; i++){ + if( zPageUse[i]==0 ) page_usage_btree(i, -1, 0, 0); printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???"); sqlite3_free(zPageUse[i]); } From 25f933ad93e5990cf5b02fb5447790b027273710 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 13:23:28 +0000 Subject: [PATCH 009/132] In the "pgidx" report from "showdb", also show the number of rows on each database btree page. FossilOrigin-Name: 2bda9dc41c07092ae37d0c6001c1271e0622bfff7151201fc2bb4c95422c087b --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/showdb.c | 22 ++++++++++++++-------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index bae2f7cb9c..b0c452f0bf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s"pgidx"\scommand\sof\sthe\sshowdb\sutility,\stry\sto\sidentify\sorphaned\spages\nand\sshow\swhen\spages\shave\sbeen\szeroed\sout. -D 2019-04-17T12:29:45.915 +C In\sthe\s"pgidx"\sreport\sfrom\s"showdb",\salso\sshow\sthe\snumber\sof\srows\son\seach\ndatabase\sbtree\spage. +D 2019-04-17T13:23:28.341 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1768,7 +1768,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 b4cd49d8f4df86349a6b41993a3eb5651e18a3f9903b4fbb70d18b66c8a358ca +F tool/showdb.c 97d14a1ce32d5edda84081a5c939bd8975abd89568a773b288940e67e4c7e3ad F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9920bcc64f58378ff1118caead34147201f48c68 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 @@ -1818,7 +1818,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 5df2bf62fcd4dfdaa195062dddbd5ce5420bc239b2649ac8f547e0db34e7f0bb -R f4eb9f2a8e78f2d407da5d6c15776852 +P eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d +R cec164e033a6cbc58045abf1be62db04 U drh -Z 369a3d8533a731558ce8e524f18f4b7d +Z 343bb3a0f539a2adef3662c41f5a7ef0 diff --git a/manifest.uuid b/manifest.uuid index 9dae86999e..0138e20713 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d \ No newline at end of file +2bda9dc41c07092ae37d0c6001c1271e0622bfff7151201fc2bb4c95422c087b \ No newline at end of file diff --git a/tool/showdb.c b/tool/showdb.c index a3301392ab..a28656b3ea 100644 --- a/tool/showdb.c +++ b/tool/showdb.c @@ -861,6 +861,7 @@ static void page_usage_btree( int nCell; int i; int hdr = pgno==1 ? 100 : 0; + char zEntry[30]; if( pgno<=0 || pgno>g.mxPage ) return; a = fileRead((pgno-1)*g.pagesize, g.pagesize); @@ -884,15 +885,20 @@ static void page_usage_btree( zType = "corrupt node"; } } - if( parent>0 ){ - page_usage_msg(pgno, "%s [%s], child %d of page %d", - zType, zName, idx, parent); - }else if( parent==0 ){ - page_usage_msg(pgno, "root %s [%s]", zType, zName); - }else{ - page_usage_msg(pgno, "orphaned %s", zType); - } nCell = a[hdr+3]*256 + a[hdr+4]; + if( nCell==1 ){ + sqlite3_snprintf(sizeof(zEntry),zEntry,"1 row"); + }else{ + sqlite3_snprintf(sizeof(zEntry),zEntry,"%d rows", nCell); + } + if( parent>0 ){ + page_usage_msg(pgno, "%s [%s], child %d of page %d, %s", + zType, zName, idx, parent, zEntry); + }else if( parent==0 ){ + page_usage_msg(pgno, "root %s [%s], %s", zType, zName, zEntry); + }else{ + page_usage_msg(pgno, "orphaned %s, %s", zType, zEntry); + } if( a[hdr]==2 || a[hdr]==5 ){ int cellstart = hdr+12; unsigned int child; From e551b5147289167db2b014e8ec28fc7ea2454fc4 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 13:58:07 +0000 Subject: [PATCH 010/132] Fix a typo in the CLI help output for the ".dump" command. FossilOrigin-Name: 57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b0c452f0bf..e0354febee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\s"pgidx"\sreport\sfrom\s"showdb",\salso\sshow\sthe\snumber\sof\srows\son\seach\ndatabase\sbtree\spage. -D 2019-04-17T13:23:28.341 +C Fix\sa\stypo\sin\sthe\sCLI\shelp\soutput\sfor\sthe\s".dump"\scommand. +D 2019-04-17T13:58:07.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -519,7 +519,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c186796810 +F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1818,7 +1818,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 eed701ef919c70d891727250be6a1b626aeb894c562d221e319ae6d74fc71d3d -R cec164e033a6cbc58045abf1be62db04 +P 2bda9dc41c07092ae37d0c6001c1271e0622bfff7151201fc2bb4c95422c087b +R ee4f0f969d031bd4425aa6a98371d250 U drh -Z 343bb3a0f539a2adef3662c41f5a7ef0 +Z ad2376f2f5e5882069506690bf4da926 diff --git a/manifest.uuid b/manifest.uuid index 0138e20713..bab25e09dd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2bda9dc41c07092ae37d0c6001c1271e0622bfff7151201fc2bb4c95422c087b \ No newline at end of file +57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index d8c57b481e..78dddd7a29 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3489,7 +3489,7 @@ static const char *(azHelp[]) = { " Options:", " --preserve-rowids Include ROWID values in the output", " --newlines Allow unescaped newline characters in output", - " TABLE is LIKE pattern for the tables to dump", + " TABLE is a LIKE pattern for the tables to dump", ".echo on|off Turn command echo on or off", ".eqp on|off|full|... Enable or disable automatic EXPLAIN QUERY PLAN", " Other Modes:", From 680f0fe32aaf79d3e7ea5dba7a0c84c4693812ed Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 17 Apr 2019 21:12:05 +0000 Subject: [PATCH 011/132] Small performance and size optimization in sqlite3WalFindFrame(). FossilOrigin-Name: 03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wal.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e0354febee..f83ec61a87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sthe\sCLI\shelp\soutput\sfor\sthe\s".dump"\scommand. -D 2019-04-17T13:58:07.370 +C Small\sperformance\sand\ssize\soptimization\sin\ssqlite3WalFindFrame(). +D 2019-04-17T21:12:05.934 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -601,7 +601,7 @@ F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f4 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 9eccc7ebb532a7b0fd3cabc16cff576b9afa763472272db67d84fb8cec96f5c0 +F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c ff2955dc2743c1af05ba5a8232ab72724d9a63b76dbee256368f40fd3ef82db5 @@ -1818,7 +1818,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 2bda9dc41c07092ae37d0c6001c1271e0622bfff7151201fc2bb4c95422c087b -R ee4f0f969d031bd4425aa6a98371d250 +P 57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 +R f55569b51e361d573aabfbfaa6d9bc9b U drh -Z ad2376f2f5e5882069506690bf4da926 +Z 08f602e532329cf65b2b6561fc1b8227 diff --git a/manifest.uuid b/manifest.uuid index bab25e09dd..9c4b3facf1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 \ No newline at end of file +03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe \ No newline at end of file diff --git a/src/wal.c b/src/wal.c index 845ac56792..53a9e508b8 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2908,9 +2908,9 @@ int sqlite3WalFindFrame( } nCollide = HASHTABLE_NSLOT; for(iKey=walHash(pgno); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ - u32 iFrame = sLoc.aHash[iKey] + sLoc.iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame - && sLoc.aPgno[sLoc.aHash[iKey]]==pgno ){ + u32 iH = sLoc.aHash[iKey]; + u32 iFrame = iH + sLoc.iZero; + if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } From f1173b69b1c3bfc68ea2877e6fabf15902b7bf72 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 17 Apr 2019 21:17:22 +0000 Subject: [PATCH 012/132] Add the experimental dbdata extension. FossilOrigin-Name: a3ab58832935e1399ecc7e4d8daefa3a6afa6b301792ce7176bc5d7c173510fb --- ext/misc/dbdata.c | 620 ++++++++++++++++++++++++++++++++++++++++++++++ manifest | 17 +- manifest.uuid | 2 +- test/dbdata.test | 54 ++++ 4 files changed, 686 insertions(+), 7 deletions(-) create mode 100644 ext/misc/dbdata.c create mode 100644 test/dbdata.test diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c new file mode 100644 index 0000000000..c0ad8c1f9e --- /dev/null +++ b/ext/misc/dbdata.c @@ -0,0 +1,620 @@ +/* +** 2019-04-17 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains an implementation of the eponymous "sqlite_dbdata" +** virtual table. sqlite_dbdata is used to extract data directly from a +** database b-tree page and its associated overflow pages, bypassing the b-tree +** layer. The table schema is equivalent to: +** +** CREATE TABLE sqlite_dbdata( +** pgno INTEGER, +** cell INTEGER, +** field INTEGER, +** value ANY, +** schema TEXT HIDDEN +** ); +** +** Each page of the database is inspected. If it cannot be interpreted as a +** b-tree page, or if it is a b-tree page containing 0 entries, the +** sqlite_dbdata table contains no rows for that page. Otherwise, the table +** contains one row for each field in the record associated with each +** cell on the page. For intkey b-trees, the key value is stored in field -1. +** +** For example, for the database: +** +** CREATE TABLE t1(a, b); -- root page is page 2 +** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five'); +** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten'); +** +** the sqlite_dbdata table contains, as well as from entries related to +** page 1, content equivalent to: +** +** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES +** (2, 0, -1, 5 ), +** (2, 0, 0, 'v' ), +** (2, 0, 1, 'five'), +** (2, 1, -1, 10 ), +** (2, 1, 0, 'x' ), +** (2, 1, 1, 'ten' ); +** +** If database corruption is encountered, this module does not report an +** error. Instead, it attempts to extract as much data as possible and +** ignores the corruption. +** +** This module requires that the "sqlite_dbpage" eponymous virtual table be +** available. +*/ +#if !defined(SQLITEINT_H) +#include "sqlite3ext.h" + +typedef unsigned char u8; +typedef unsigned int u32; + +#endif +SQLITE_EXTENSION_INIT1 +#include +#include + +typedef struct DbdataTable DbdataTable; +typedef struct DbdataCursor DbdataCursor; + +/* A cursor for the sqlite_dbdata table */ +struct DbdataCursor { + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pStmt; /* For fetching database pages */ + + int iPgno; /* Current page number */ + u8 *aPage; /* Buffer containing page */ + int nPage; /* Size of aPage[] in bytes */ + int nCell; /* Number of cells on aPage[] */ + int iCell; /* Current cell number */ + u8 *pRec; /* Buffer containing current record */ + int nRec; /* Size of pRec[] in bytes */ + int nField; /* Number of fields in pRec */ + int iField; /* Current field number */ + sqlite3_int64 iIntkey; /* Integer key value */ + + sqlite3_int64 iRowid; +}; + +/* The sqlite_dbdata table */ +struct DbdataTable { + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection */ +}; + +#define DBDATA_COLUMN_PGNO 0 +#define DBDATA_COLUMN_CELL 1 +#define DBDATA_COLUMN_FIELD 2 +#define DBDATA_COLUMN_VALUE 3 +#define DBDATA_COLUMN_SCHEMA 4 + +#define DBDATA_SCHEMA \ + "CREATE TABLE x(" \ + " pgno INTEGER," \ + " cell INTEGER," \ + " field INTEGER," \ + " value ANY," \ + " schema TEXT HIDDEN" \ + ")" + +/* +** Connect to the sqlite_dbdata virtual table. +*/ +static int dbdataConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + DbdataTable *pTab = 0; + int rc = sqlite3_declare_vtab(db, DBDATA_SCHEMA); + + if( rc==SQLITE_OK ){ + pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable)); + if( pTab==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(pTab, 0, sizeof(DbdataTable)); + pTab->db = db; + } + } + + *ppVtab = (sqlite3_vtab*)pTab; + return rc; +} + +/* +** Disconnect from or destroy a dbdata virtual table. +*/ +static int dbdataDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* +** +** This function interprets two types of constraints: +** +** schema=? +** pgno=? +** +** If neither are present, idxNum is set to 0. If schema=? is present, +** the 0x01 bit in idxNum is set. If pgno=? is present, the 0x02 bit +** in idxNum is set. +** +** If both parameters are present, schema is in position 0 and pgno in +** position 1. +*/ +static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + int i; + int iSchema = -1; + int iPgno = -1; + + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + if( p->iColumn==DBDATA_COLUMN_SCHEMA ){ + if( p->usable==0 ) return SQLITE_CONSTRAINT; + iSchema = i; + } + if( p->iColumn==DBDATA_COLUMN_PGNO && p->usable ){ + iPgno = i; + } + } + } + + if( iSchema>=0 ){ + pIdxInfo->aConstraintUsage[iSchema].argvIndex = 1; + pIdxInfo->aConstraintUsage[iSchema].omit = 1; + } + if( iPgno>=0 ){ + pIdxInfo->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0); + pIdxInfo->aConstraintUsage[iPgno].omit = 1; + } + pIdxInfo->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00); + return SQLITE_OK; +} + +/* +** Open a new dbdata cursor. +*/ +static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + DbdataCursor *pCsr; + + pCsr = (DbdataCursor*)sqlite3_malloc64(sizeof(DbdataCursor)); + if( pCsr==0 ){ + return SQLITE_NOMEM; + }else{ + memset(pCsr, 0, sizeof(DbdataCursor)); + pCsr->base.pVtab = pVTab; + } + + *ppCursor = (sqlite3_vtab_cursor *)pCsr; + return SQLITE_OK; +} + +static void dbdataResetCursor(DbdataCursor *pCsr){ + sqlite3_finalize(pCsr->pStmt); + pCsr->pStmt = 0; + pCsr->iPgno = 1; + pCsr->iCell = 0; + pCsr->iField = 0; +} + +/* +** Close a dbdata cursor. +*/ +static int dbdataClose(sqlite3_vtab_cursor *pCursor){ + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + dbdataResetCursor(pCsr); + sqlite3_free(pCsr); + return SQLITE_OK; +} + + +/* Decode big-endian integers */ +static unsigned int get_uint16(unsigned char *a){ + return (a[0]<<8)|a[1]; +} +static unsigned int get_uint32(unsigned char *a){ + return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3]; +} + +static int dbdataLoadPage( + DbdataCursor *pCsr, + u32 pgno, + u8 **ppPage, + int *pnPage +){ + int rc2; + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = pCsr->pStmt; + + *ppPage = 0; + *pnPage = 0; + sqlite3_bind_int64(pStmt, 2, pgno); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + int nCopy = sqlite3_column_bytes(pStmt, 0); + u8 *pPage = (u8*)sqlite3_malloc64(nCopy); + if( pPage==0 ){ + rc = SQLITE_NOMEM; + }else{ + const u8 *pCopy = sqlite3_column_blob(pStmt, 0); + memcpy(pPage, pCopy, nCopy); + *ppPage = pPage; + *pnPage = nCopy; + } + } + rc2 = sqlite3_reset(pStmt); + if( *ppPage==0 ) rc = rc2; + + return rc; +} + +/* +** Read a varint. Put the value in *pVal and return the number of bytes. +*/ +static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ + sqlite3_int64 v = 0; + int i; + for(i=0; i<8; i++){ + v = (v<<7) + (z[i]&0x7f); + if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; } + } + v = (v<<8) + (z[i]&0xff); + *pVal = v; + return 9; +} + +/* +** Move a dbdata cursor to the next entry in the file. +*/ +static int dbdataNext(sqlite3_vtab_cursor *pCursor){ + DbdataCursor *pCsr = (DbdataCursor *)pCursor; + + pCsr->iRowid++; + while( 1 ){ + int rc; + + if( pCsr->aPage==0 ){ + rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); + if( rc!=SQLITE_OK ) return rc; + pCsr->iCell = 0; + pCsr->nCell = get_uint16(&pCsr->aPage[pCsr->iPgno==1 ? 103 : 3]); + } + + /* If there is no record loaded, load it now. */ + if( pCsr->pRec==0 ){ + int iOff = (pCsr->iPgno==1 ? 100 : 0); + int bHasRowid = 0; + int nPointer = 0; + sqlite3_int64 nPayload = 0; + sqlite3_int64 nHdr = 0; + int iHdr; + int U, X; + int nLocal; + + switch( pCsr->aPage[iOff] ){ + case 0x02: + nPointer = 4; + break; + case 0x0a: + break; + case 0x0d: + bHasRowid = 1; + break; + default: + pCsr->iCell = pCsr->nCell; + break; + } + if( pCsr->iCell>=pCsr->nCell ){ + sqlite3_free(pCsr->aPage); + pCsr->aPage = 0; + return SQLITE_OK; + } + + iOff += 8 + nPointer + pCsr->iCell*2; + iOff = get_uint16(&pCsr->aPage[iOff]); + + /* For an interior node cell, skip past the child-page number */ + iOff += nPointer; + + /* Load the "byte of payload including overflow" field */ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload); + + /* If this is a leaf intkey cell, load the rowid */ + if( bHasRowid ){ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); + } + + /* Allocate space for payload */ + pCsr->pRec = (u8*)sqlite3_malloc64(nPayload); + if( pCsr->pRec==0 ) return SQLITE_NOMEM; + pCsr->nRec = nPayload; + + U = pCsr->nPage; + if( bHasRowid ){ + X = U-35; + }else{ + X = ((U-12)*64/255)-23; + } + if( nPayload<=X ){ + nLocal = nPayload; + }else{ + int M, K; + M = ((U-12)*32/255)-23; + K = M+((nPayload-M)%(U-4)); + if( K<=X ){ + nLocal = K; + }else{ + nLocal = M; + } + } + + /* Load the nLocal bytes of payload */ + memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); + iOff += nLocal; + + /* Load content from overflow pages */ + if( nPayload>nLocal ){ + sqlite3_int64 nRem = nPayload - nLocal; + u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); + while( nRem>0 ){ + u8 *aOvfl = 0; + int nOvfl = 0; + int nCopy; + rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); + assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); + if( rc!=SQLITE_OK ) return rc; + + nCopy = U-4; + if( nCopy>nRem ) nCopy = nRem; + memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); + nRem -= nCopy; + + sqlite3_free(aOvfl); + } + } + + /* Figure out how many fields in the record */ + pCsr->nField = 0; + iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); + while( iHdrpRec[iHdr], &iDummy); + pCsr->nField++; + } + + pCsr->iField = (bHasRowid ? -2 : -1); + } + + pCsr->iField++; + if( pCsr->iFieldnField ) return SQLITE_OK; + + /* Advance to the next cell. The next iteration of the loop will load + ** the record and so on. */ + sqlite3_free(pCsr->pRec); + pCsr->pRec = 0; + pCsr->iCell++; + } + + assert( !"can't get here" ); + return SQLITE_OK; +} + +/* We have reached EOF if previous sqlite3_step() returned +** anything other than SQLITE_ROW; +*/ +static int dbdataEof(sqlite3_vtab_cursor *pCursor){ + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + return pCsr->aPage==0; +} + +/* Position a cursor back to the beginning. +*/ +static int dbdataFilter( + sqlite3_vtab_cursor *pCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; + int rc; + const char *zSchema = "main"; + + dbdataResetCursor(pCsr); + assert( pCsr->iPgno==1 ); + if( idxNum & 0x01 ){ + zSchema = sqlite3_value_text(argv[0]); + } + if( idxNum & 0x02 ){ + pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); + } + + rc = sqlite3_prepare_v2(pTab->db, + "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, + &pCsr->pStmt, 0 + ); + if( rc==SQLITE_OK ){ + rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); + } + if( rc==SQLITE_OK ){ + rc = dbdataNext(pCursor); + } + return rc; +} + +static int dbdataValueBytes(int eType){ + switch( eType ){ + case 0: case 8: case 9: + case 10: case 11: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + return 4; + case 5: + return 6; + case 6: + case 7: + return 8; + default: + return ((eType-12) / 2); + } +} + +static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ + switch( eType ){ + case 0: + case 10: + case 11: + sqlite3_result_null(pCtx); + break; + + case 8: + sqlite3_result_int(pCtx, 0); + break; + case 9: + sqlite3_result_int(pCtx, 1); + break; + + case 1: case 2: case 3: case 4: case 5: case 6: case 7: { + sqlite3_uint64 v = (signed char)pData[0]; + pData++; + switch( eType ){ + case 7: + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + + if( eType==7 ){ + double r; + memcpy(&r, &v, sizeof(r)); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_int64(pCtx, (sqlite3_int64)v); + } + break; + } + + default: { + int n = ((eType-12) / 2); + if( eType % 2 ){ + sqlite3_result_text(pCtx, pData, n, SQLITE_TRANSIENT); + }else{ + sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); + } + } + } +} + +/* Return a column for the sqlite_dbdata table */ +static int dbdataColumn( + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, + int i +){ + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + switch( i ){ + case DBDATA_COLUMN_PGNO: + sqlite3_result_int64(ctx, pCsr->iPgno); + break; + case DBDATA_COLUMN_CELL: + sqlite3_result_int(ctx, pCsr->iCell); + break; + case DBDATA_COLUMN_FIELD: + sqlite3_result_int(ctx, pCsr->iField); + break; + case DBDATA_COLUMN_VALUE: { + if( pCsr->iField<0 ){ + sqlite3_result_int64(ctx, pCsr->iIntkey); + }else{ + int iHdr; + sqlite3_int64 iType; + sqlite3_int64 iOff; + int i; + iHdr = dbdataGetVarint(pCsr->pRec, &iOff); + for(i=0; iiField; i++){ + iHdr += dbdataGetVarint(&pCsr->pRec[iHdr], &iType); + iOff += dbdataValueBytes(iType); + } + dbdataGetVarint(&pCsr->pRec[iHdr], &iType); + + dbdataValue(ctx, iType, &pCsr->pRec[iOff]); + } + break; + } + } + return SQLITE_OK; +} + +/* Return the ROWID for the sqlite_dbdata table */ +static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + *pRowid = pCsr->iRowid; + return SQLITE_OK; +} + + +/* +** Invoke this routine to register the "sqlite_dbdata" virtual table module +*/ +static int sqlite3DbdataRegister(sqlite3 *db){ + static sqlite3_module dbdata_module = { + 0, /* iVersion */ + 0, /* xCreate */ + dbdataConnect, /* xConnect */ + dbdataBestIndex, /* xBestIndex */ + dbdataDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + dbdataOpen, /* xOpen - open a cursor */ + dbdataClose, /* xClose - close a cursor */ + dbdataFilter, /* xFilter - configure scan constraints */ + dbdataNext, /* xNext - advance a cursor */ + dbdataEof, /* xEof - check for end of scan */ + dbdataColumn, /* xColumn - read data */ + dbdataRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ + }; + return sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); +} + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_dbdata_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + SQLITE_EXTENSION_INIT2(pApi); + return sqlite3DbdataRegister(db); +} diff --git a/manifest b/manifest index b6c54ac76e..59bdc64972 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sand\ssmaller\simplementation\sof\ssqlite3StrICmp(). -D 2019-04-17T11:34:44.568 +C Add\sthe\sexperimental\sdbdata\sextension. +D 2019-04-17T21:17:22.795 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,6 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb +F ext/misc/dbdata.c 436a7883a7f1455c5d2853bd927c5ac31826b21c6e16ca11a21d7262d25ff838 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -786,6 +787,7 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 +F test/dbdata.test 6e791619d18e0cff2c79392de980ca0594368cdaa05326f043f866beb0c82614 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee @@ -1818,7 +1820,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 884b4b7e502b4e991677b53971277adfaf0a04a284f8e483e2553d0f83156b50 -R dcc66ec8a55d4cba7e12163fe5fbfbcf -U drh -Z 40a9f6f7fce76c8f72a2cb9229b22090 +P 7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d +R 9b65ccecf461800383c04a268416aaa8 +T *branch * dbdata +T *sym-dbdata * +T -sym-trunk * +U dan +Z f99e8e6e33bab5d12ccf1d6f1a7cae6f diff --git a/manifest.uuid b/manifest.uuid index c8e27168f5..dc49ef98d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d \ No newline at end of file +a3ab58832935e1399ecc7e4d8daefa3a6afa6b301792ce7176bc5d7c173510fb \ No newline at end of file diff --git a/test/dbdata.test b/test/dbdata.test new file mode 100644 index 0000000000..c4412a5de9 --- /dev/null +++ b/test/dbdata.test @@ -0,0 +1,54 @@ +# 2019-04-11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing the sqlite_dbpage virtual table. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix dbdata + +ifcapable !vtab||!compound { + finish_test + return +} +db enable_load_extension 1 +if { [catch { db eval { SELECT load_extension('../dbdata') } }] } { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE T1(a, b); + INSERT INTO t1(rowid, a ,b) VALUES(5, 'v', 'five'); + INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten'); +} + +do_execsql_test 1.1 { + SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata WHERE pgno=2; +} { + 2 0 -1 5 + 2 0 0 'v' + 2 0 1 'five' + 2 1 -1 10 + 2 1 0 'x' + 2 1 1 'ten' +} + +set big [string repeat big 2000] +do_execsql_test 1.2 { + INSERT INTO t1 VALUES(NULL, $big); + SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1; +} $big + + + +finish_test From 7a3e50dc97e83e7f2501c6ce96adc9cbf50c6cd4 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Thu, 18 Apr 2019 19:21:19 +0000 Subject: [PATCH 013/132] Minor simplification of NULL value handling for STAT4. FossilOrigin-Name: 5718a9d5fc3fdfc89db869501c81fda39b3ec5c7e11fa0038fc258e316f5d8a1 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/vdbemem.c | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f83ec61a87..70ae3b8bd2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sand\ssize\soptimization\sin\ssqlite3WalFindFrame(). -D 2019-04-17T21:12:05.934 +C Minor\ssimplification\sof\sNULL\svalue\shandling\sfor\sSTAT4. +D 2019-04-18T19:21:19.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -596,7 +596,7 @@ F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 -F src/vdbemem.c 8e6889761e344babdb8a56dd1ac8911501fa648396544d1644f1cd6a87c80dc0 +F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b @@ -1818,7 +1818,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 57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 -R f55569b51e361d573aabfbfaa6d9bc9b -U drh -Z 08f602e532329cf65b2b6561fc1b8227 +P 03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe +R eb7a1c9198e6574d14aeef303b481c00 +T *branch * nullStat4 +T *sym-nullStat4 * +T -sym-trunk * +U mistachkin +Z c61752927ede7d3abde97db4bfed824e diff --git a/manifest.uuid b/manifest.uuid index 9c4b3facf1..f8755ba8b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe \ No newline at end of file +5718a9d5fc3fdfc89db869501c81fda39b3ec5c7e11fa0038fc258e316f5d8a1 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 10c23adfd3..80d494867c 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1511,7 +1511,7 @@ static int valueFromExpr( }else if( op==TK_NULL ){ pVal = valueNew(db, pCtx); if( pVal==0 ) goto no_mem; - sqlite3VdbeMemNumerify(pVal); + sqlite3VdbeMemSetNull(pVal); } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ From 3b412ac2473707fc7bc4ce29466d7b7dc4988905 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 18 Apr 2019 21:14:11 +0000 Subject: [PATCH 014/132] Add the sqlite_dbptr virtual table to the dbdata extension. For querying the links between b-tree pages. FossilOrigin-Name: 3213a15f2133afbb0a4fec3b8f6e0eeca8c0befafd6658c41074e84f589d5d32 --- ext/misc/dbdata.c | 347 ++++++++++++++++++++++++++++------------------ manifest | 17 +-- manifest.uuid | 2 +- test/dbdata.test | 52 ++++++- 4 files changed, 270 insertions(+), 148 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index c0ad8c1f9e..eb2bc01600 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -23,6 +23,9 @@ ** schema TEXT HIDDEN ** ); ** +** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE +** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND "schema". +** ** Each page of the database is inspected. If it cannot be interpreted as a ** b-tree page, or if it is a b-tree page containing 0 entries, the ** sqlite_dbdata table contains no rows for that page. Otherwise, the table @@ -52,6 +55,13 @@ ** ** This module requires that the "sqlite_dbpage" eponymous virtual table be ** available. +** +** +** CREATE TABLE sqlite_dbptr( +** pgno INTEGER, +** child INTEGER, +** schema TEXT HIDDEN +** ); */ #if !defined(SQLITEINT_H) #include "sqlite3ext.h" @@ -67,6 +77,7 @@ SQLITE_EXTENSION_INIT1 typedef struct DbdataTable DbdataTable; typedef struct DbdataCursor DbdataCursor; + /* A cursor for the sqlite_dbdata table */ struct DbdataCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ @@ -77,19 +88,22 @@ struct DbdataCursor { int nPage; /* Size of aPage[] in bytes */ int nCell; /* Number of cells on aPage[] */ int iCell; /* Current cell number */ + int bOnePage; /* True to stop after one page */ + sqlite3_int64 iRowid; + + /* Only for the sqlite_dbdata table */ u8 *pRec; /* Buffer containing current record */ int nRec; /* Size of pRec[] in bytes */ int nField; /* Number of fields in pRec */ int iField; /* Current field number */ sqlite3_int64 iIntkey; /* Integer key value */ - - sqlite3_int64 iRowid; }; /* The sqlite_dbdata table */ struct DbdataTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database connection */ + int bPtr; /* True for sqlite3_dbptr table */ }; #define DBDATA_COLUMN_PGNO 0 @@ -98,6 +112,10 @@ struct DbdataTable { #define DBDATA_COLUMN_VALUE 3 #define DBDATA_COLUMN_SCHEMA 4 +#define DBPTR_COLUMN_PGNO 0 +#define DBPTR_COLUMN_CHILD 1 +#define DBPTR_COLUMN_SCHEMA 2 + #define DBDATA_SCHEMA \ "CREATE TABLE x(" \ " pgno INTEGER," \ @@ -107,6 +125,13 @@ struct DbdataTable { " schema TEXT HIDDEN" \ ")" +#define DBPTR_SCHEMA \ + "CREATE TABLE x(" \ + " pgno INTEGER," \ + " child INTEGER," \ + " schema TEXT HIDDEN" \ + ")" + /* ** Connect to the sqlite_dbdata virtual table. */ @@ -118,7 +143,7 @@ static int dbdataConnect( char **pzErr ){ DbdataTable *pTab = 0; - int rc = sqlite3_declare_vtab(db, DBDATA_SCHEMA); + int rc = sqlite3_declare_vtab(db, pAux ? DBPTR_SCHEMA : DBDATA_SCHEMA); if( rc==SQLITE_OK ){ pTab = (DbdataTable*)sqlite3_malloc64(sizeof(DbdataTable)); @@ -127,6 +152,7 @@ static int dbdataConnect( }else{ memset(pTab, 0, sizeof(DbdataTable)); pTab->db = db; + pTab->bPtr = (pAux!=0); } } @@ -157,14 +183,16 @@ static int dbdataDisconnect(sqlite3_vtab *pVtab){ ** position 1. */ static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + DbdataTable *pTab = (DbdataTable*)tab; int i; int iSchema = -1; int iPgno = -1; + int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA); for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ - if( p->iColumn==DBDATA_COLUMN_SCHEMA ){ + if( p->iColumn==colSchema ){ if( p->usable==0 ) return SQLITE_CONSTRAINT; iSchema = i; } @@ -210,6 +238,7 @@ static void dbdataResetCursor(DbdataCursor *pCsr){ pCsr->iPgno = 1; pCsr->iCell = 0; pCsr->iField = 0; + pCsr->bOnePage = 0; } /* @@ -281,132 +310,152 @@ static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ ** Move a dbdata cursor to the next entry in the file. */ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ - DbdataCursor *pCsr = (DbdataCursor *)pCursor; + DbdataCursor *pCsr = (DbdataCursor*)pCursor; + DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; pCsr->iRowid++; while( 1 ){ int rc; + int iOff = (pCsr->iPgno==1 ? 100 : 0); if( pCsr->aPage==0 ){ rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); - if( rc!=SQLITE_OK ) return rc; - pCsr->iCell = 0; - pCsr->nCell = get_uint16(&pCsr->aPage[pCsr->iPgno==1 ? 103 : 3]); + if( rc!=SQLITE_OK || pCsr->aPage==0 ) return rc; + pCsr->iCell = pTab->bPtr ? -2 : 0; + pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]); } - /* If there is no record loaded, load it now. */ - if( pCsr->pRec==0 ){ - int iOff = (pCsr->iPgno==1 ? 100 : 0); - int bHasRowid = 0; - int nPointer = 0; - sqlite3_int64 nPayload = 0; - sqlite3_int64 nHdr = 0; - int iHdr; - int U, X; - int nLocal; - - switch( pCsr->aPage[iOff] ){ - case 0x02: - nPointer = 4; - break; - case 0x0a: - break; - case 0x0d: - bHasRowid = 1; - break; - default: - pCsr->iCell = pCsr->nCell; - break; + if( pTab->bPtr ){ + if( pCsr->aPage[iOff]!=0x02 && pCsr->aPage[iOff]!=0x05 ){ + pCsr->iCell = pCsr->nCell; } + pCsr->iCell++; if( pCsr->iCell>=pCsr->nCell ){ sqlite3_free(pCsr->aPage); pCsr->aPage = 0; + if( pCsr->bOnePage ) return SQLITE_OK; + pCsr->iPgno++; + }else{ return SQLITE_OK; } + }else{ + /* If there is no record loaded, load it now. */ + if( pCsr->pRec==0 ){ + int bHasRowid = 0; + int nPointer = 0; + sqlite3_int64 nPayload = 0; + sqlite3_int64 nHdr = 0; + int iHdr; + int U, X; + int nLocal; + + switch( pCsr->aPage[iOff] ){ + case 0x02: + nPointer = 4; + break; + case 0x0a: + break; + case 0x0d: + bHasRowid = 1; + break; + default: + /* This is not a b-tree page with records on it. Continue. */ + pCsr->iCell = pCsr->nCell; + break; + } - iOff += 8 + nPointer + pCsr->iCell*2; - iOff = get_uint16(&pCsr->aPage[iOff]); - - /* For an interior node cell, skip past the child-page number */ - iOff += nPointer; - - /* Load the "byte of payload including overflow" field */ - iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload); - - /* If this is a leaf intkey cell, load the rowid */ - if( bHasRowid ){ - iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); - } - - /* Allocate space for payload */ - pCsr->pRec = (u8*)sqlite3_malloc64(nPayload); - if( pCsr->pRec==0 ) return SQLITE_NOMEM; - pCsr->nRec = nPayload; - - U = pCsr->nPage; - if( bHasRowid ){ - X = U-35; - }else{ - X = ((U-12)*64/255)-23; - } - if( nPayload<=X ){ - nLocal = nPayload; - }else{ - int M, K; - M = ((U-12)*32/255)-23; - K = M+((nPayload-M)%(U-4)); - if( K<=X ){ - nLocal = K; + if( pCsr->iCell>=pCsr->nCell ){ + sqlite3_free(pCsr->aPage); + pCsr->aPage = 0; + if( pCsr->bOnePage ) return SQLITE_OK; + pCsr->iPgno++; + continue; + } + + iOff += 8 + nPointer + pCsr->iCell*2; + iOff = get_uint16(&pCsr->aPage[iOff]); + + /* For an interior node cell, skip past the child-page number */ + iOff += nPointer; + + /* Load the "byte of payload including overflow" field */ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload); + + /* If this is a leaf intkey cell, load the rowid */ + if( bHasRowid ){ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); + } + + /* Allocate space for payload */ + pCsr->pRec = (u8*)sqlite3_malloc64(nPayload); + if( pCsr->pRec==0 ) return SQLITE_NOMEM; + pCsr->nRec = nPayload; + + U = pCsr->nPage; + if( bHasRowid ){ + X = U-35; }else{ - nLocal = M; + X = ((U-12)*64/255)-23; } - } - - /* Load the nLocal bytes of payload */ - memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); - iOff += nLocal; - - /* Load content from overflow pages */ - if( nPayload>nLocal ){ - sqlite3_int64 nRem = nPayload - nLocal; - u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); - while( nRem>0 ){ - u8 *aOvfl = 0; - int nOvfl = 0; - int nCopy; - rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); - assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); - if( rc!=SQLITE_OK ) return rc; - - nCopy = U-4; - if( nCopy>nRem ) nCopy = nRem; - memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); - nRem -= nCopy; - - sqlite3_free(aOvfl); + if( nPayload<=X ){ + nLocal = nPayload; + }else{ + int M, K; + M = ((U-12)*32/255)-23; + K = M+((nPayload-M)%(U-4)); + if( K<=X ){ + nLocal = K; + }else{ + nLocal = M; + } } + + /* Load the nLocal bytes of payload */ + memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); + iOff += nLocal; + + /* Load content from overflow pages */ + if( nPayload>nLocal ){ + sqlite3_int64 nRem = nPayload - nLocal; + u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); + while( nRem>0 ){ + u8 *aOvfl = 0; + int nOvfl = 0; + int nCopy; + rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); + assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); + if( rc!=SQLITE_OK ) return rc; + + nCopy = U-4; + if( nCopy>nRem ) nCopy = nRem; + memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); + nRem -= nCopy; + + sqlite3_free(aOvfl); + } + } + + /* Figure out how many fields in the record */ + pCsr->nField = 0; + iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); + while( iHdrpRec[iHdr], &iDummy); + pCsr->nField++; + } + + pCsr->iField = (bHasRowid ? -2 : -1); } - - /* Figure out how many fields in the record */ - pCsr->nField = 0; - iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); - while( iHdrpRec[iHdr], &iDummy); - pCsr->nField++; - } - - pCsr->iField = (bHasRowid ? -2 : -1); + + pCsr->iField++; + if( pCsr->iFieldnField ) return SQLITE_OK; + + /* Advance to the next cell. The next iteration of the loop will load + ** the record and so on. */ + sqlite3_free(pCsr->pRec); + pCsr->pRec = 0; + pCsr->iCell++; } - - pCsr->iField++; - if( pCsr->iFieldnField ) return SQLITE_OK; - - /* Advance to the next cell. The next iteration of the loop will load - ** the record and so on. */ - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; - pCsr->iCell++; } assert( !"can't get here" ); @@ -440,6 +489,7 @@ static int dbdataFilter( } if( idxNum & 0x02 ){ pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); + pCsr->bOnePage = 1; } rc = sqlite3_prepare_v2(pTab->db, @@ -533,34 +583,54 @@ static int dbdataColumn( int i ){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; - switch( i ){ - case DBDATA_COLUMN_PGNO: - sqlite3_result_int64(ctx, pCsr->iPgno); - break; - case DBDATA_COLUMN_CELL: - sqlite3_result_int(ctx, pCsr->iCell); - break; - case DBDATA_COLUMN_FIELD: - sqlite3_result_int(ctx, pCsr->iField); - break; - case DBDATA_COLUMN_VALUE: { - if( pCsr->iField<0 ){ - sqlite3_result_int64(ctx, pCsr->iIntkey); - }else{ - int iHdr; - sqlite3_int64 iType; - sqlite3_int64 iOff; - int i; - iHdr = dbdataGetVarint(pCsr->pRec, &iOff); - for(i=0; iiField; i++){ - iHdr += dbdataGetVarint(&pCsr->pRec[iHdr], &iType); - iOff += dbdataValueBytes(iType); + DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; + if( pTab->bPtr ){ + switch( i ){ + case DBPTR_COLUMN_PGNO: + sqlite3_result_int64(ctx, pCsr->iPgno); + break; + case DBPTR_COLUMN_CHILD: { + int iOff = pCsr->iPgno==1 ? 100 : 0; + if( pCsr->iCell<0 ){ + iOff += 8; + }else{ + iOff += 12 + pCsr->iCell*2; + iOff = get_uint16(&pCsr->aPage[iOff]); } - dbdataGetVarint(&pCsr->pRec[iHdr], &iType); - - dbdataValue(ctx, iType, &pCsr->pRec[iOff]); + sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff])); + break; + } + } + }else{ + switch( i ){ + case DBDATA_COLUMN_PGNO: + sqlite3_result_int64(ctx, pCsr->iPgno); + break; + case DBDATA_COLUMN_CELL: + sqlite3_result_int(ctx, pCsr->iCell); + break; + case DBDATA_COLUMN_FIELD: + sqlite3_result_int(ctx, pCsr->iField); + break; + case DBDATA_COLUMN_VALUE: { + if( pCsr->iField<0 ){ + sqlite3_result_int64(ctx, pCsr->iIntkey); + }else{ + int iHdr; + sqlite3_int64 iType; + sqlite3_int64 iOff; + int i; + iHdr = dbdataGetVarint(pCsr->pRec, &iOff); + for(i=0; iiField; i++){ + iHdr += dbdataGetVarint(&pCsr->pRec[iHdr], &iType); + iOff += dbdataValueBytes(iType); + } + dbdataGetVarint(&pCsr->pRec[iHdr], &iType); + + dbdataValue(ctx, iType, &pCsr->pRec[iOff]); + } + break; } - break; } } return SQLITE_OK; @@ -604,7 +674,12 @@ static int sqlite3DbdataRegister(sqlite3 *db){ 0, /* xRollbackTo */ 0 /* xShadowName */ }; - return sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); + + int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_module(db, "sqlite_dbptr", &dbdata_module, (void*)1); + } + return rc; } #ifdef _WIN32 diff --git a/manifest b/manifest index 59bdc64972..d6a2b045e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sexperimental\sdbdata\sextension. -D 2019-04-17T21:17:22.795 +C Add\sthe\ssqlite_dbptr\svirtual\stable\sto\sthe\sdbdata\sextension.\sFor\squerying\sthe\slinks\sbetween\sb-tree\spages. +D 2019-04-18T21:14:11.260 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 436a7883a7f1455c5d2853bd927c5ac31826b21c6e16ca11a21d7262d25ff838 +F ext/misc/dbdata.c 20d85d7d7503817a5f9ac7d93c4ae7bf5fcc40570a77adc417acab0500058c99 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -787,7 +787,7 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 -F test/dbdata.test 6e791619d18e0cff2c79392de980ca0594368cdaa05326f043f866beb0c82614 +F test/dbdata.test 573fa3347744863e47d011e4e8e9b87c6795ba92a759bf5d5c68da975900ddd4 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee @@ -1820,10 +1820,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 7ac500fb5abfe1ad60f2ffdcc8fbe5ccc1c641bbeed53f00940e9ff78788e53d -R 9b65ccecf461800383c04a268416aaa8 -T *branch * dbdata -T *sym-dbdata * -T -sym-trunk * +P a3ab58832935e1399ecc7e4d8daefa3a6afa6b301792ce7176bc5d7c173510fb +R 901e9e476021499846a29c847f49c578 U dan -Z f99e8e6e33bab5d12ccf1d6f1a7cae6f +Z e0c2ac18f5bd53328c7a0485e8c7ef97 diff --git a/manifest.uuid b/manifest.uuid index dc49ef98d8..6ee3f97f4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3ab58832935e1399ecc7e4d8daefa3a6afa6b301792ce7176bc5d7c173510fb \ No newline at end of file +3213a15f2133afbb0a4fec3b8f6e0eeca8c0befafd6658c41074e84f589d5d32 \ No newline at end of file diff --git a/test/dbdata.test b/test/dbdata.test index c4412a5de9..5a0df5dc86 100644 --- a/test/dbdata.test +++ b/test/dbdata.test @@ -43,12 +43,62 @@ do_execsql_test 1.1 { 2 1 1 'ten' } -set big [string repeat big 2000] +breakpoint do_execsql_test 1.2 { + SELECT pgno, cell, field, quote(value) FROM sqlite_dbdata; +} { + 1 0 -1 1 + 1 0 0 'table' + 1 0 1 'T1' + 1 0 2 'T1' + 1 0 3 2 + 1 0 4 {'CREATE TABLE T1(a, b)'} + 2 0 -1 5 + 2 0 0 'v' + 2 0 1 'five' + 2 1 -1 10 + 2 1 0 'x' + 2 1 1 'ten' +} + +set big [string repeat big 2000] +do_execsql_test 1.3 { INSERT INTO t1 VALUES(NULL, $big); SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1; } $big +#------------------------------------------------------------------------- +reset_db +db enable_load_extension 1 +db eval { SELECT load_extension('../dbdata') } + +do_execsql_test 2.0 { + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10 + ) + INSERT INTO t1 SELECT randomblob(900) FROM s; +} + +do_execsql_test 2.1 { + SELECT * FROM sqlite_dbptr WHERE pgno=2; +} { + 2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21 +} + +do_execsql_test 2.2 { + SELECT * FROM sqlite_dbptr WHERE pgno=3; +} { + 3 24 3 23 +} + +do_execsql_test 2.3 { + SELECT * FROM sqlite_dbptr +} { + 2 25 2 6 2 7 2 9 2 11 2 13 2 15 2 17 2 19 2 21 + 3 24 3 23 +} finish_test From d5c851c1cbcb96d541fa7e6e20342c2a437434e9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Apr 2019 13:38:34 +0000 Subject: [PATCH 015/132] Streamline the processing of the AND operator. Slightly smaller and faster. FossilOrigin-Name: 7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/expr.c | 31 ++++++++++++++----------------- src/fkey.c | 10 +++++----- src/parse.y | 2 +- src/select.c | 12 ++++++------ src/sqliteInt.h | 2 +- src/where.c | 2 +- src/wherecode.c | 4 ++-- 9 files changed, 43 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index f83ec61a87..b92980907b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sand\ssize\soptimization\sin\ssqlite3WalFindFrame(). -D 2019-04-17T21:12:05.934 +C Streamline\sthe\sprocessing\sof\sthe\sAND\soperator.\s\sSlightly\ssmaller\sand\sfaster. +D 2019-04-19T13:38:34.610 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -470,9 +470,9 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c e100212835d20498780e7c6d2bdb16c677ecc04350fb75db3bf192a86ba48c92 +F src/expr.c d9b219b2a20f9a99712c24b6c6b21588006260eb3f8bdc96df8262869b58512a F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c bd0138acdc008c1845ccf92f8e73787880562de649471804801c06fed814c765 +F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -507,7 +507,7 @@ F src/os_win.c 85d9e532d0444ab6c16d7431490c2e279e282aa0917b0e988996b1ae0de5c5a0 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3 -F src/parse.y 8de9b1da4dc0f9615cfa9f4cbdd368b4ac822e1cbbc57b0fe071d9a83988df6d +F src/parse.y 22f64d8a8910acd17580450513b58d64187b0962848380c7f0a39376b8a48cee F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c be64b2f3908a7f97c56c963676eb12f0d6254c95b28cdc1d73a186eff213219d @@ -518,12 +518,12 @@ F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 +F src/select.c e6c6a75e9aac747ea26b5e2d1d7a9af50b813ea5524d4ec556a0afc72a6d69d4 F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h d229b6a5f70fe6c57d2f91f0edc60a9c4437397b4a5b59fd72fe9eb3b94d3437 +F src/sqliteInt.h 3a9497a4d7261e348390a1390d00d50f51ebab2ee97335b287447aa9e12bf543 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -604,9 +604,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 -F src/where.c ff2955dc2743c1af05ba5a8232ab72724d9a63b76dbee256368f40fd3ef82db5 +F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 -F src/wherecode.c 83be72e8d1c0231d0db06ffe5cfd32c7834bd00d2ed869306a2c1e0828488752 +F src/wherecode.c 0e76672930bea322eb3606d891a4744be55c09bcd3a995bfd501af62a46e0625 F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1818,7 +1818,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 57638248de147efe8d663b3ae1389f590c7b2b7225ecfe295699d68c2893cd09 -R f55569b51e361d573aabfbfaa6d9bc9b +P 03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe +R 4d121f6250fa4d728fb8a46a98d547d3 U drh -Z 08f602e532329cf65b2b6561fc1b8227 +Z 1c6157db33fa1baf603ced1f230aa369 diff --git a/manifest.uuid b/manifest.uuid index 9c4b3facf1..73ca7c5e56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe \ No newline at end of file +7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 9a5e0345a0..c9f917ce55 100644 --- a/src/expr.c +++ b/src/expr.c @@ -850,20 +850,16 @@ Expr *sqlite3PExpr( Expr *pRight /* Right operand */ ){ Expr *p; - if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){ - /* Take advantage of short-circuit false optimization for AND */ - p = sqlite3ExprAnd(pParse->db, pLeft, pRight); - }else{ - p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); - if( p ){ - memset(p, 0, sizeof(Expr)); - p->op = op & 0xff; - p->iAgg = -1; - } + p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); + if( p ){ + memset(p, 0, sizeof(Expr)); + p->op = op & 0xff; + p->iAgg = -1; sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); - } - if( p ) { sqlite3ExprCheckHeight(pParse, p->nHeight); + }else{ + sqlite3ExprDelete(pParse->db, pLeft); + sqlite3ExprDelete(pParse->db, pRight); } return p; } @@ -919,19 +915,20 @@ static int exprAlwaysFalse(Expr *p){ ** of returning an AND expression, just return a constant expression with ** a value of false. */ -Expr *sqlite3ExprAnd(sqlite3 *db, Expr *pLeft, Expr *pRight){ - if( pLeft==0 ){ +Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ + sqlite3 *db = pParse->db; + if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ return pLeft; + }else if( pParse->nErr || IN_RENAME_OBJECT ){ + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){ sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); }else{ - Expr *pNew = sqlite3ExprAlloc(db, TK_AND, 0, 0); - sqlite3ExprAttachSubtrees(db, pNew, pLeft, pRight); - return pNew; + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); } } diff --git a/src/fkey.c b/src/fkey.c index 9633c41449..14ee983c55 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -591,7 +591,7 @@ static void fkScanChildren( zCol = pFKey->pFrom->aCol[iCol].zName; pRight = sqlite3Expr(db, TK_ID, zCol); pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); - pWhere = sqlite3ExprAnd(db, pWhere, pEq); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); } /* If the child table is the same as the parent table, then add terms @@ -625,11 +625,11 @@ static void fkScanChildren( pLeft = exprTableRegister(pParse, pTab, regData, iCol); pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); - pAll = sqlite3ExprAnd(db, pAll, pEq); + pAll = sqlite3ExprAnd(pParse, pAll, pEq); } pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); } - pWhere = sqlite3ExprAnd(db, pWhere, pNe); + pWhere = sqlite3ExprAnd(pParse, pWhere, pNe); } /* Resolve the references in the WHERE clause. */ @@ -1235,7 +1235,7 @@ static Trigger *fkActionTrigger( sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) ); - pWhere = sqlite3ExprAnd(db, pWhere, pEq); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); /* For ON UPDATE, construct the next term of the WHEN clause. ** The final WHEN clause will be like this: @@ -1251,7 +1251,7 @@ static Trigger *fkActionTrigger( sqlite3ExprAlloc(db, TK_ID, &tNew, 0), sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) ); - pWhen = sqlite3ExprAnd(db, pWhen, pEq); + pWhen = sqlite3ExprAnd(pParse, pWhen, pEq); } if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ diff --git a/src/parse.y b/src/parse.y index beb4eebd44..c87c759cca 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1064,7 +1064,7 @@ expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. { } } -expr(A) ::= expr(A) AND(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} +expr(A) ::= expr(A) AND expr(Y). {A=sqlite3ExprAnd(pParse,A,Y);} expr(A) ::= expr(A) OR(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);} diff --git a/src/select.c b/src/select.c index 7d8a425416..89bc8b1933 100644 --- a/src/select.c +++ b/src/select.c @@ -355,7 +355,7 @@ static void addWhereTerm( ExprSetVVAProperty(pEq, EP_NoReduce); pEq->iRightJoinTable = (i16)pE2->iTable; } - *ppWhere = sqlite3ExprAnd(db, *ppWhere, pEq); + *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* @@ -489,7 +489,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ */ if( pRight->pOn ){ if( isOuter ) setJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(pParse->db, p->pWhere, pRight->pOn); + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); pRight->pOn = 0; } @@ -4034,7 +4034,7 @@ static int flattenSubquery( if( isLeftJoin>0 ){ setJoinExpr(pWhere, iNewParent); } - pParent->pWhere = sqlite3ExprAnd(db, pWhere, pParent->pWhere); + pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere); if( db->mallocFailed==0 ){ SubstContext x; x.pParse = pParse; @@ -4369,9 +4369,9 @@ static int pushDownWhereTerms( x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); if( pSubq->selFlags & SF_Aggregate ){ - pSubq->pHaving = sqlite3ExprAnd(pParse->db, pSubq->pHaving, pNew); + pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); }else{ - pSubq->pWhere = sqlite3ExprAnd(pParse->db, pSubq->pWhere, pNew); + pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew); } pSubq = pSubq->pPrior; } @@ -5418,7 +5418,7 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pNew ){ Expr *pWhere = pS->pWhere; SWAP(Expr, *pNew, *pExpr); - pNew = sqlite3ExprAnd(db, pWhere, pNew); + pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew); pS->pWhere = pNew; pWalker->eCode = 1; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 72953e6009..8868fd3867 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3854,7 +3854,7 @@ Expr *sqlite3Expr(sqlite3*,int,const char*); void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); void sqlite3PExprAddSelect(Parse*, Expr*, Select*); -Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*); +Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); diff --git a/src/where.c b/src/where.c index cd00fe96b8..b421e4ae93 100644 --- a/src/where.c +++ b/src/where.c @@ -737,7 +737,7 @@ static void constructAutomaticIndex( && (pTerm->wtFlags & TERM_VIRTUAL)==0 && !ExprHasProperty(pExpr, EP_FromJoin) && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ - pPartial = sqlite3ExprAnd(pParse->db, pPartial, + pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ diff --git a/src/wherecode.c b/src/wherecode.c index f710690189..6aadb24142 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -999,7 +999,7 @@ static void codeCursorHint( } /* If we survive all prior tests, that means this term is worth hinting */ - pExpr = sqlite3ExprAnd(db, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); + pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ sWalker.xExprCallback = codeCursorHintFixExpr; @@ -1964,7 +1964,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); pExpr = sqlite3ExprDup(db, pExpr, 0); - pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr); + pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } if( pAndExpr ){ /* The extra 0x10000 bit on the opcode is masked off and does not From ad31727fc68e47612edcc1566ef88174da75f258 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Apr 2019 16:21:51 +0000 Subject: [PATCH 016/132] Use macros to determine if an expression is always true or always false. FossilOrigin-Name: 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 40 +++++++--------------------------------- src/sqliteInt.h | 4 ++++ 4 files changed, 19 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index b92980907b..7e497dd6b8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Streamline\sthe\sprocessing\sof\sthe\sAND\soperator.\s\sSlightly\ssmaller\sand\sfaster. -D 2019-04-19T13:38:34.610 +C Use\smacros\sto\sdetermine\sif\san\sexpression\sis\salways\strue\sor\salways\sfalse. +D 2019-04-19T16:21:51.905 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -470,7 +470,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c d9b219b2a20f9a99712c24b6c6b21588006260eb3f8bdc96df8262869b58512a +F src/expr.c 18f8875c247ef5491826619d7ad1d5a67a7a370d76d92066761bd3c015a2d16b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee @@ -523,7 +523,7 @@ F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 3a9497a4d7261e348390a1390d00d50f51ebab2ee97335b287447aa9e12bf543 +F src/sqliteInt.h b8d576ae658a3529d2bb72f4ce27892937a2f5cc3b63294250c556007ce112de F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1818,7 +1818,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 03f2e78899fad99b0a0951b3a408268276954d4cd785389ed9a0192c9217f6fe -R 4d121f6250fa4d728fb8a46a98d547d3 +P 7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403 +R 8599c4a645fc2e6f1e9b669040f6d312 U drh -Z 1c6157db33fa1baf603ced1f230aa369 +Z 635a58ce2bb9d7966c1e1a49c0802a30 diff --git a/manifest.uuid b/manifest.uuid index 73ca7c5e56..7226259af2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403 \ No newline at end of file +6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c9f917ce55..0484f3b452 100644 --- a/src/expr.c +++ b/src/expr.c @@ -773,7 +773,7 @@ Expr *sqlite3ExprAlloc( pNew->iAgg = -1; if( pToken ){ if( nExtra==0 ){ - pNew->flags |= EP_IntValue|EP_Leaf; + pNew->flags |= EP_IntValue|EP_Leaf|(iValue?EP_IsTrue:EP_IsFalse); pNew->u.iValue = iValue; }else{ pNew->u.zToken = (char*)&pNew[1]; @@ -880,33 +880,6 @@ void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ } -/* -** If the expression is always either TRUE or FALSE (respectively), -** then return 1. If one cannot determine the truth value of the -** expression at compile-time return 0. -** -** This is an optimization. If is OK to return 0 here even if -** the expression really is always false or false (a false negative). -** But it is a bug to return 1 if the expression might have different -** boolean values in different circumstances (a false positive.) -** -** Note that if the expression is part of conditional for a -** LEFT JOIN, then we cannot determine at compile-time whether or not -** is it true or false, so always return 0. -*/ -static int exprAlwaysTrue(Expr *p){ - int v = 0; - if( ExprHasProperty(p, EP_FromJoin) ) return 0; - if( !sqlite3ExprIsInteger(p, &v) ) return 0; - return v!=0; -} -static int exprAlwaysFalse(Expr *p){ - int v = 0; - if( ExprHasProperty(p, EP_FromJoin) ) return 0; - if( !sqlite3ExprIsInteger(p, &v) ) return 0; - return v==0; -} - /* ** Join two expressions using an AND operator. If either expression is ** NULL, then just return the other expression. @@ -923,7 +896,7 @@ Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ return pLeft; }else if( pParse->nErr || IN_RENAME_OBJECT ){ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); - }else if( exprAlwaysFalse(pLeft) || exprAlwaysFalse(pRight) ){ + }else if( ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight) ){ sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); return sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[0], 0); @@ -1818,6 +1791,7 @@ int sqlite3ExprIdToTrueFalse(Expr *pExpr){ || sqlite3StrICmp(pExpr->u.zToken, "false")==0) ){ pExpr->op = TK_TRUEFALSE; + ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse); return 1; } return 0; @@ -4522,9 +4496,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ #endif default: { default_expr: - if( exprAlwaysTrue(pExpr) ){ + if( ExprAlwaysTrue(pExpr) ){ sqlite3VdbeGoto(v, dest); - }else if( exprAlwaysFalse(pExpr) ){ + }else if( ExprAlwaysFalse(pExpr) ){ /* No-op */ }else{ r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); @@ -4692,9 +4666,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ #endif default: { default_expr: - if( exprAlwaysFalse(pExpr) ){ + if( ExprAlwaysFalse(pExpr) ){ sqlite3VdbeGoto(v, dest); - }else if( exprAlwaysTrue(pExpr) ){ + }else if( ExprAlwaysTrue(pExpr) ){ /* no-op */ }else{ r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 8868fd3867..2812433185 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2530,6 +2530,8 @@ struct Expr { #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ #define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ #define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ +#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ +#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ /* ** The EP_Propagate mask is a set of properties that automatically propagate @@ -2545,6 +2547,8 @@ struct Expr { #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P)) #define ExprSetProperty(E,P) (E)->flags|=(P) #define ExprClearProperty(E,P) (E)->flags&=~(P) +#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue) +#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse) /* The ExprSetVVAProperty() macro is used for Verification, Validation, ** and Accreditation only. It works like ExprSetProperty() during VVA From 65455fc682394dc7ec0b0c5599a2175e05e94f4b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 19 Apr 2019 16:34:22 +0000 Subject: [PATCH 017/132] Fix a problem with renaming a table that starts with "sqlite". Fix for ticket [f00d7b65]. FossilOrigin-Name: a2ead8aa4517b63cda7bf84464326e9cb5e228224caa603568c0e04ea44e6588 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/alter.c | 12 +++++++----- test/altertab.test | 10 ++++++++++ 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 7e497dd6b8..726d1cb5a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\smacros\sto\sdetermine\sif\san\sexpression\sis\salways\strue\sor\salways\sfalse. -D 2019-04-19T16:21:51.905 +C Fix\sa\sproblem\swith\srenaming\sa\stable\sthat\sstarts\swith\s"sqlite".\sFix\sfor\sticket\s[f00d7b65]. +D 2019-04-19T16:34:22.819 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -452,7 +452,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 25f54387121a0c5fd0f49b299f4070c81af8f26a84edaae6de679c4e4b71b1ff +F src/alter.c 85b41586b2527c8288b249fb0beb96f25860e5b2bf94c02f788b3d0f686354ee F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644 F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df @@ -626,7 +626,7 @@ F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1 F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b -F test/altertab.test 6e13f13d8c30708f16187908c31dadb1bfff9e3cb2a07a7392a7a5e076f58f4a +F test/altertab.test 372df7d8f09e1ee22d23551677cedff3b048b0059c1f1b9a01a6401b94a2367c F test/altertab2.test 5d423a2d1006085b05cc1b788863d5a860ea2da21c4f892d15e2f2a34c78348a F test/altertab3.test 40f2ce9be675e354d3e55c72f8baf38813be975ff4dd9e6b3144493c3c5bc033 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1818,7 +1818,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 7713996aa99ce6dd35b5a2db74dd26658fb8d9817169b2a7531cdef6edb41403 -R 8599c4a645fc2e6f1e9b669040f6d312 -U drh -Z 635a58ce2bb9d7966c1e1a49c0802a30 +P 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc +R f6dd462947f07b27748cf5926546c234 +U dan +Z 3ea7f1435e33deb3b5fe1ff707282194 diff --git a/manifest.uuid b/manifest.uuid index 7226259af2..d2a30fd50f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc \ No newline at end of file +a2ead8aa4517b63cda7bf84464326e9cb5e228224caa603568c0e04ea44e6588 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d71074795b..e5f4e2b182 100644 --- a/src/alter.c +++ b/src/alter.c @@ -54,7 +54,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\".%s " - "WHERE name NOT LIKE 'sqlite_%%'" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", zDb, MASTER_NAME, @@ -65,7 +65,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ sqlite3NestedParse(pParse, "SELECT 1 " "FROM temp.%s " - "WHERE name NOT LIKE 'sqlite_%%'" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", MASTER_NAME, zDb @@ -186,7 +186,7 @@ void sqlite3AlterRenameTable( "UPDATE \"%w\".%s SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" - "AND name NOT LIKE 'sqlite_%%'" + "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName ); @@ -197,7 +197,8 @@ void sqlite3AlterRenameTable( "tbl_name = %Q, " "name = CASE " "WHEN type='table' THEN %Q " - "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' " + " AND type='index' THEN " "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " "WHERE tbl_name=%Q COLLATE nocase AND " @@ -571,7 +572,8 @@ void sqlite3AlterRenameColumn( sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " - "WHERE name NOT LIKE 'sqlite_%%' AND (type != 'index' OR tbl_name = %Q)" + "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " + " AND (type != 'index' OR tbl_name = %Q)" " AND sql NOT LIKE 'create virtual%%'", zDb, MASTER_NAME, zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, diff --git a/test/altertab.test b/test/altertab.test index 4a12f0d8f0..91ad66d732 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -559,4 +559,14 @@ ifcapable fts3 { } } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 17.0 { + CREATE TABLE sqlite1234 (id integer); + ALTER TABLE sqlite1234 RENAME TO User; + SELECT name, sql FROM sqlite_master WHERE sql IS NOT NULL; +} { + User {CREATE TABLE "User" (id integer)} +} + finish_test From 17180fca9d46d95c9572edcc17409827e057260c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Apr 2019 17:26:19 +0000 Subject: [PATCH 018/132] Improved optimization of the AND and OR operators. FossilOrigin-Name: 0fbd154eb419b57b9c064c1f47346835d6324388b966b73f8a0122de065f08b1 --- manifest | 16 +++++----- manifest.uuid | 2 +- src/expr.c | 81 +++++++++++++++++++++++++++++++++++-------------- src/sqliteInt.h | 1 + 4 files changed, 69 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 726d1cb5a5..217fbfbbe7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\srenaming\sa\stable\sthat\sstarts\swith\s"sqlite".\sFix\sfor\sticket\s[f00d7b65]. -D 2019-04-19T16:34:22.819 +C Improved\soptimization\sof\sthe\sAND\sand\sOR\soperators. +D 2019-04-19T17:26:19.629 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -470,7 +470,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 18f8875c247ef5491826619d7ad1d5a67a7a370d76d92066761bd3c015a2d16b +F src/expr.c 23a2a2d86e3ae932738c2209448d6cfceed6db4843e9efeac134e1dd9475b9da F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee @@ -523,7 +523,7 @@ F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h b8d576ae658a3529d2bb72f4ce27892937a2f5cc3b63294250c556007ce112de +F src/sqliteInt.h 866311ac436c0c2039fccc7ea976fbc79d40c1c2ea687161fa4ba64379b53ae6 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1818,7 +1818,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 6de980a09c3a7adf71f2c9a63a242673b5e1f246e8ee071b26844275f0dad0fc -R f6dd462947f07b27748cf5926546c234 -U dan -Z 3ea7f1435e33deb3b5fe1ff707282194 +P a2ead8aa4517b63cda7bf84464326e9cb5e228224caa603568c0e04ea44e6588 +R a28bb5dcc6ba5c574a36c8b8a1f1839d +U drh +Z 2808a241e92b97d6352cee8d905a5827 diff --git a/manifest.uuid b/manifest.uuid index d2a30fd50f..fa55f384cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2ead8aa4517b63cda7bf84464326e9cb5e228224caa603568c0e04ea44e6588 \ No newline at end of file +0fbd154eb419b57b9c064c1f47346835d6324388b966b73f8a0122de065f08b1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0484f3b452..874a044d7e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1808,6 +1808,33 @@ int sqlite3ExprTruthValue(const Expr *pExpr){ return pExpr->u.zToken[4]==0; } +/* +** If pExpr is an AND or OR expression, try to simplify it by eliminating +** terms that are always true or false. Return the simplified expression. +** Or return the original expression if no simplification is possible. +** +** Examples: +** +** (x<10) AND true => (x<10) +** (x<10) AND false => false +** (x<10) AND (y=22 OR false) => (x<10) AND (y=22) +** (x<10) AND (y=22 OR true) => (x<10) +** (y=22) OR true => true +*/ +Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ + assert( pExpr!=0 ); + if( pExpr->op==TK_AND || pExpr->op==TK_OR ){ + Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight); + Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft); + if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){ + pExpr = pExpr->op==TK_AND ? pRight : pLeft; + }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){ + pExpr = pExpr->op==TK_AND ? pLeft : pRight; + } + } + return pExpr; +} + /* ** These routines are Walker callbacks used to check expressions to @@ -4399,18 +4426,23 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ if( NEVER(pExpr==0) ) return; /* No way this can happen */ op = pExpr->op; switch( op ){ - case TK_AND: { - int d2 = sqlite3VdbeMakeLabel(pParse); - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); - break; - } + case TK_AND: case TK_OR: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); + }else if( op==TK_AND ){ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + }else{ + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + } break; } case TK_NOT: { @@ -4566,18 +4598,23 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ assert( pExpr->op!=TK_GE || op==OP_Lt ); switch( pExpr->op ){ - case TK_AND: { - testcase( jumpIfNull==0 ); - sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - break; - } + case TK_AND: case TK_OR: { - int d2 = sqlite3VdbeMakeLabel(pParse); - testcase( jumpIfNull==0 ); - sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - sqlite3VdbeResolveLabel(v, d2); + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); + if( pAlt!=pExpr ){ + sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); + }else if( pExpr->op==TK_AND ){ + testcase( jumpIfNull==0 ); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + }else{ + int d2 = sqlite3VdbeMakeLabel(pParse); + testcase( jumpIfNull==0 ); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, + jumpIfNull^SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); + } break; } case TK_NOT: { diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2812433185..00ac00274f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3859,6 +3859,7 @@ void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); void sqlite3PExprAddSelect(Parse*, Expr*, Select*); Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); +Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); From 6b23603eb9ab79dac61a232b2b1c8f6857ecb329 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Apr 2019 22:01:10 +0000 Subject: [PATCH 019/132] Increase the version number to 3.29 for the next development cycle. FossilOrigin-Name: 6cf16703fd4a835c249c947006ae4a4bf81873c8ca1803945453c9845f882dc1 --- VERSION | 2 +- configure | 70 +++++++++++++++++++++------------------------------ manifest | 14 +++++------ manifest.uuid | 2 +- 4 files changed, 38 insertions(+), 50 deletions(-) diff --git a/VERSION b/VERSION index a72fd67b60..c7c9773262 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.28.0 +3.29.0 diff --git a/configure b/configure index b957c3c63e..a8b1214943 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.28.0. +# Generated by GNU Autoconf 2.69 for sqlite 3.29.0. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -726,8 +726,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.28.0' -PACKAGE_STRING='sqlite 3.28.0' +PACKAGE_VERSION='3.29.0' +PACKAGE_STRING='sqlite 3.29.0' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -863,7 +863,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -965,7 +964,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1218,15 +1216,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1364,7 +1353,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1477,7 +1466,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sqlite 3.28.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.29.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1517,7 +1506,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1543,7 +1531,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.28.0:";; + short | recursive ) echo "Configuration of sqlite 3.29.0:";; esac cat <<\_ACEOF @@ -1669,7 +1657,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.28.0 +sqlite configure 3.29.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2088,7 +2076,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sqlite $as_me 3.28.0, which was +It was created by sqlite $as_me 3.29.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3946,13 +3934,13 @@ if ${lt_cv_nm_interface+:} false; then : else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3949: $ac_compile\"" >&5) + (eval echo "\"\$as_me:3937: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:3952: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:3940: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:3955: output\"" >&5) + (eval echo "\"\$as_me:3943: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5158,7 +5146,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5161 "configure"' > conftest.$ac_ext + echo '#line 5149 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6683,11 +6671,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6686: $lt_compile\"" >&5) + (eval echo "\"\$as_me:6674: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:6690: \$? = $ac_status" >&5 + echo "$as_me:6678: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7022,11 +7010,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7025: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7013: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7029: \$? = $ac_status" >&5 + echo "$as_me:7017: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7127,11 +7115,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7130: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7118: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7134: \$? = $ac_status" >&5 + echo "$as_me:7122: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7182,11 +7170,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7185: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7173: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7189: \$? = $ac_status" >&5 + echo "$as_me:7177: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -9562,7 +9550,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9565 "configure" +#line 9553 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -9658,7 +9646,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 9661 "configure" +#line 9649 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10007,7 +9995,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10053,7 +10041,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10077,7 +10065,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10122,7 +10110,7 @@ else We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -10146,7 +10134,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31)) +#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; @@ -12244,7 +12232,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sqlite $as_me 3.28.0, which was +This file was extended by sqlite $as_me 3.29.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -12310,7 +12298,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sqlite config.status 3.28.0 +sqlite config.status 3.29.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/manifest b/manifest index 217fbfbbe7..3d0c1a64d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\soptimization\sof\sthe\sAND\sand\sOR\soperators. -D 2019-04-19T17:26:19.629 +C Increase\sthe\sversion\snumber\sto\s3.29\sfor\sthe\snext\sdevelopment\scycle. +D 2019-04-19T22:01:10.982 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -7,7 +7,7 @@ F Makefile.in 4640daf826b80947a924ac44275c451ffc13007c7c866a5730c8ce5cf9e1dc74 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 26957950b2b4f3b26e311eeea70437f85a77765f71d3a06489466d66ee321100 F README.md 74745e53db87fdc86f571dd7ec1bd18e154d0abd6d37d2292a1062e931318a29 -F VERSION 288d756b1b7be03ecdbf1795c23af2c8425f2e46ba6979a14ef53360308f080d +F VERSION cc8cd90333c65cdf4cb346f356a2ce1eb0f5b7fa1d17a34d7350103e7320af1f F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 @@ -34,7 +34,7 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.h.in 6376abec766e9a0785178b1823b5a587e9f1ccbc F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 -F configure b013bf805064650b072817c7c7f0a295cfcec5b1afec15e59ea4e9996543f51e x +F configure 4a97fb6ccce582ebb3dc5a7e281e5e2823574dad851b8ccf814aa6de9f4c7ad2 x F configure.ac 3552d3aecade98a9d4b64bceb48ffb7726cbc85902efde956812942f060fbd0a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -1818,7 +1818,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 a2ead8aa4517b63cda7bf84464326e9cb5e228224caa603568c0e04ea44e6588 -R a28bb5dcc6ba5c574a36c8b8a1f1839d +P 0fbd154eb419b57b9c064c1f47346835d6324388b966b73f8a0122de065f08b1 +R 0cc980e0dc04d81764cc0d3f65347d88 U drh -Z 2808a241e92b97d6352cee8d905a5827 +Z c6ca1ce47aa8677b9fa6820037fce811 diff --git a/manifest.uuid b/manifest.uuid index fa55f384cc..54fe64b1de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0fbd154eb419b57b9c064c1f47346835d6324388b966b73f8a0122de065f08b1 \ No newline at end of file +6cf16703fd4a835c249c947006ae4a4bf81873c8ca1803945453c9845f882dc1 \ No newline at end of file From 1d2d71a02cac0e4a13d54ae1bd3b3351abbf9828 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 19 Apr 2019 23:05:56 +0000 Subject: [PATCH 020/132] Mark a single branch as no longer reachable. FossilOrigin-Name: 4f35b3b78a461b0617a5cd04f60d2ab277bcc7c994dae463851a3cb5d041a723 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3d0c1a64d4..b01d6fa7e7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\sversion\snumber\sto\s3.29\sfor\sthe\snext\sdevelopment\scycle. -D 2019-04-19T22:01:10.982 +C Mark\sa\ssingle\sbranch\sas\sno\slonger\sreachable. +D 2019-04-19T23:05:56.134 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -470,7 +470,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 23a2a2d86e3ae932738c2209448d6cfceed6db4843e9efeac134e1dd9475b9da +F src/expr.c f65db06a0fcff760cadfb79d579a41e3eb7eff38848d5d6359137822f4fa2ec9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee @@ -1818,7 +1818,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 0fbd154eb419b57b9c064c1f47346835d6324388b966b73f8a0122de065f08b1 -R 0cc980e0dc04d81764cc0d3f65347d88 +P 6cf16703fd4a835c249c947006ae4a4bf81873c8ca1803945453c9845f882dc1 +R ff3642bada516bde6836db167619c845 U drh -Z c6ca1ce47aa8677b9fa6820037fce811 +Z 2a6d21c59c4950c9897c2627e0f9536a diff --git a/manifest.uuid b/manifest.uuid index 54fe64b1de..43ee2ab2a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6cf16703fd4a835c249c947006ae4a4bf81873c8ca1803945453c9845f882dc1 \ No newline at end of file +4f35b3b78a461b0617a5cd04f60d2ab277bcc7c994dae463851a3cb5d041a723 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 874a044d7e..ca63eb66c0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2079,7 +2079,7 @@ int sqlite3ExprContainsSubquery(Expr *p){ */ int sqlite3ExprIsInteger(Expr *p, int *pValue){ int rc = 0; - if( p==0 ) return 0; /* Can only happen following on OOM */ + if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ /* If an expression is an integer literal that fits in a signed 32-bit ** integer, then the EP_IntValue flag will have already been set */ From 68cb86ef23e3bc9e6362fec4937968a65ec025b5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 20 Apr 2019 20:57:28 +0000 Subject: [PATCH 021/132] Add the ".recovery" command to the shell tool. For recovering the maximum amount data from corrupt databases. Still needs work. FossilOrigin-Name: 7461d2e120f2149315ddac2676d51d7445bcdb8e97543effd9c30603517ef9da --- ext/misc/dbdata.c | 194 ++++++++++++++++---------------- main.mk | 1 + manifest | 18 +-- manifest.uuid | 2 +- src/shell.c.in | 277 +++++++++++++++++++++++++++++++++++++++++++--- tool/mkshellc.tcl | 8 +- 6 files changed, 375 insertions(+), 125 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index eb2bc01600..aae862fc7f 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -63,11 +63,11 @@ ** schema TEXT HIDDEN ** ); */ -#if !defined(SQLITEINT_H) +#if !defined(SQLITEINT_H) #include "sqlite3ext.h" typedef unsigned char u8; -typedef unsigned int u32; +typedef unsigned long u32; #endif SQLITE_EXTENSION_INIT1 @@ -94,8 +94,11 @@ struct DbdataCursor { /* Only for the sqlite_dbdata table */ u8 *pRec; /* Buffer containing current record */ int nRec; /* Size of pRec[] in bytes */ - int nField; /* Number of fields in pRec */ + int nHdr; /* Size of header in bytes */ int iField; /* Current field number */ + u8 *pHdrPtr; + u8 *pPtr; + sqlite3_int64 iIntkey; /* Integer key value */ }; @@ -306,6 +309,78 @@ static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ return 9; } +static int dbdataValueBytes(int eType){ + switch( eType ){ + case 0: case 8: case 9: + case 10: case 11: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + return 4; + case 5: + return 6; + case 6: + case 7: + return 8; + default: + return ((eType-12) / 2); + } +} + +static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ + switch( eType ){ + case 0: + case 10: + case 11: + sqlite3_result_null(pCtx); + break; + + case 8: + sqlite3_result_int(pCtx, 0); + break; + case 9: + sqlite3_result_int(pCtx, 1); + break; + + case 1: case 2: case 3: case 4: case 5: case 6: case 7: { + sqlite3_uint64 v = (signed char)pData[0]; + pData++; + switch( eType ){ + case 7: + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + + if( eType==7 ){ + double r; + memcpy(&r, &v, sizeof(r)); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_int64(pCtx, (sqlite3_int64)v); + } + break; + } + + default: { + int n = ((eType-12) / 2); + if( eType % 2 ){ + sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT); + }else{ + sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); + } + } + } +} + + /* ** Move a dbdata cursor to the next entry in the file. */ @@ -435,20 +510,23 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ } } - /* Figure out how many fields in the record */ - pCsr->nField = 0; iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); - while( iHdrpRec[iHdr], &iDummy); - pCsr->nField++; + pCsr->nHdr = nHdr; + pCsr->pHdrPtr = &pCsr->pRec[iHdr]; + pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; + pCsr->iField = (bHasRowid ? -1 : 0); + }else{ + pCsr->iField++; + if( pCsr->iField>0 ){ + sqlite3_int64 iType; + pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType); + pCsr->pPtr += dbdataValueBytes(iType); } - - pCsr->iField = (bHasRowid ? -2 : -1); } - - pCsr->iField++; - if( pCsr->iFieldnField ) return SQLITE_OK; + + if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ + return SQLITE_OK; + } /* Advance to the next cell. The next iteration of the loop will load ** the record and so on. */ @@ -485,7 +563,7 @@ static int dbdataFilter( dbdataResetCursor(pCsr); assert( pCsr->iPgno==1 ); if( idxNum & 0x01 ){ - zSchema = sqlite3_value_text(argv[0]); + zSchema = (const char*)sqlite3_value_text(argv[0]); } if( idxNum & 0x02 ){ pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); @@ -498,6 +576,8 @@ static int dbdataFilter( ); if( rc==SQLITE_OK ){ rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); + }else{ + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); } if( rc==SQLITE_OK ){ rc = dbdataNext(pCursor); @@ -505,77 +585,6 @@ static int dbdataFilter( return rc; } -static int dbdataValueBytes(int eType){ - switch( eType ){ - case 0: case 8: case 9: - case 10: case 11: - return 0; - case 1: - return 1; - case 2: - return 2; - case 3: - return 3; - case 4: - return 4; - case 5: - return 6; - case 6: - case 7: - return 8; - default: - return ((eType-12) / 2); - } -} - -static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ - switch( eType ){ - case 0: - case 10: - case 11: - sqlite3_result_null(pCtx); - break; - - case 8: - sqlite3_result_int(pCtx, 0); - break; - case 9: - sqlite3_result_int(pCtx, 1); - break; - - case 1: case 2: case 3: case 4: case 5: case 6: case 7: { - sqlite3_uint64 v = (signed char)pData[0]; - pData++; - switch( eType ){ - case 7: - case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 4: v = (v<<8) + pData[0]; pData++; - case 3: v = (v<<8) + pData[0]; pData++; - case 2: v = (v<<8) + pData[0]; pData++; - } - - if( eType==7 ){ - double r; - memcpy(&r, &v, sizeof(r)); - sqlite3_result_double(pCtx, r); - }else{ - sqlite3_result_int64(pCtx, (sqlite3_int64)v); - } - break; - } - - default: { - int n = ((eType-12) / 2); - if( eType % 2 ){ - sqlite3_result_text(pCtx, pData, n, SQLITE_TRANSIENT); - }else{ - sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); - } - } - } -} - /* Return a column for the sqlite_dbdata table */ static int dbdataColumn( sqlite3_vtab_cursor *pCursor, @@ -616,18 +625,9 @@ static int dbdataColumn( if( pCsr->iField<0 ){ sqlite3_result_int64(ctx, pCsr->iIntkey); }else{ - int iHdr; sqlite3_int64 iType; - sqlite3_int64 iOff; - int i; - iHdr = dbdataGetVarint(pCsr->pRec, &iOff); - for(i=0; iiField; i++){ - iHdr += dbdataGetVarint(&pCsr->pRec[iHdr], &iType); - iOff += dbdataValueBytes(iType); - } - dbdataGetVarint(&pCsr->pRec[iHdr], &iType); - - dbdataValue(ctx, iType, &pCsr->pRec[iOff]); + dbdataGetVarint(pCsr->pHdrPtr, &iType); + dbdataValue(ctx, iType, pCsr->pPtr); } break; } diff --git a/main.mk b/main.mk index f418eec68a..508554d733 100644 --- a/main.mk +++ b/main.mk @@ -738,6 +738,7 @@ SHELL_SRC = \ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/dbdata.c \ $(TOP)/src/test_windirent.c shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl diff --git a/manifest b/manifest index d6a2b045e8..c103da1624 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite_dbptr\svirtual\stable\sto\sthe\sdbdata\sextension.\sFor\squerying\sthe\slinks\sbetween\sb-tree\spages. -D 2019-04-18T21:14:11.260 +C Add\sthe\s".recovery"\scommand\sto\sthe\sshell\stool.\sFor\srecovering\sthe\smaximum\samount\sdata\sfrom\scorrupt\sdatabases.\sStill\sneeds\swork. +D 2019-04-20T20:57:28.136 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 20d85d7d7503817a5f9ac7d93c4ae7bf5fcc40570a77adc417acab0500058c99 +F ext/misc/dbdata.c 8f74f25565e1f57942f75134ef94ab73058849bed87d92be619be7d3b8a7d054 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -441,7 +441,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 23d3660f7053d196aef76938bf78b10fc3ce1831a85d96bd71565758788f34d4 +F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in c1986496062f9dba4ed5b70db06b5e0f32e1954cdcfab0b30372c6c186796810 +F src/shell.c.in 3646e448cc207fa3118266c2a23f177306b068e42aae6fee64323ffb13307680 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1754,7 +1754,7 @@ F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl 49039adedafbc430d2959400da2e0e8f20ef8dcf6898e447c946e7d50ef5906b -F tool/mkshellc.tcl 1f45770aea226ac093a9c72f718efbb88a2a2833409ec2e1c4cecae4202626f5 +F tool/mkshellc.tcl d18a6769f766bd5a0fd5fd60e6bbde38ed6d1a41fced5fe32ac01ab9d2e0d5ec F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -1820,7 +1820,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 a3ab58832935e1399ecc7e4d8daefa3a6afa6b301792ce7176bc5d7c173510fb -R 901e9e476021499846a29c847f49c578 +P 3213a15f2133afbb0a4fec3b8f6e0eeca8c0befafd6658c41074e84f589d5d32 +R 9a7e323fe9ebfe9eb0759e1c70136795 U dan -Z e0c2ac18f5bd53328c7a0485e8c7ef97 +Z 100e3ccaddf1d19d0bacd74d773a93b7 diff --git a/manifest.uuid b/manifest.uuid index 6ee3f97f4e..0b854fa40a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3213a15f2133afbb0a4fec3b8f6e0eeca8c0befafd6658c41074e84f589d5d32 \ No newline at end of file +7461d2e120f2149315ddac2676d51d7445bcdb8e97543effd9c30603517ef9da \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index d8c57b481e..c38bfb64b9 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -948,6 +948,8 @@ INCLUDE ../ext/misc/sqlar.c INCLUDE ../ext/expert/sqlite3expert.h INCLUDE ../ext/expert/sqlite3expert.c +INCLUDE ../ext/misc/dbdata.c + #if defined(SQLITE_ENABLE_SESSION) /* ** State information for a single open session @@ -1102,6 +1104,7 @@ struct ShellState { #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ #define SHFLG_CountChanges 0x00000020 /* .changes setting */ #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ +#define SHFLG_Recover 0x00000080 /* .dump is --recover */ /* ** Macros for testing and setting shellFlgs @@ -3999,6 +4002,7 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); sqlite3_completion_init(p->db, 0, 0); + sqlite3_dbdata_init(p->db, 0, 0); #ifdef SQLITE_HAVE_ZLIB sqlite3_zipfile_init(p->db, 0, 0); sqlite3_sqlar_init(p->db, 0, 0); @@ -6026,6 +6030,238 @@ end_ar_command: **********************************************************************************/ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ +static void shellExec(sqlite3 *db, int *pRc, const char *zSql){ + int rc = *pRc; + if( rc==SQLITE_OK ){ + char *zErr = 0; + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); + if( rc!=SQLITE_OK ){ + raw_printf(stderr, "SQL error: %s\n", zErr); + } + *pRc = rc; + } +} + +static void *shellMalloc(int *pRc, sqlite3_int64 nByte){ + void *pRet = 0; + if( *pRc==SQLITE_OK ){ + pRet = sqlite3_malloc64(nByte); + if( pRet==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + memset(pRet, 0, nByte); + } + } + return pRet; +} + +static char *shellMPrintf(int *pRc, const char *zFmt, ...){ + char *z = 0; + if( *pRc==SQLITE_OK ){ + va_list ap; + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + va_end(ap); + if( z==0 ){ + *pRc = SQLITE_NOMEM; + } + } + return z; +} + +typedef struct RecoverTable RecoverTable; +struct RecoverTable { + char *zName; /* Name of table */ + char *zQuoted; /* Quoted version of zName */ + char *zCreate; /* SQL to create table in default schema */ + int nCol; /* Number of columns in table */ + char **azlCol; /* Array of column lists */ +}; + +/* +** Free a RecoverTable object allocated by recoverNewTable() +*/ +static void recoverFreeTable(RecoverTable *pTab){ + if( pTab ){ + sqlite3_free(pTab->zName); + sqlite3_free(pTab->zQuoted); + sqlite3_free(pTab->zCreate); + if( pTab->azlCol ){ + int i; + for(i=0; inCol; i++){ + sqlite3_free(pTab->azlCol[i]); + } + sqlite3_free(pTab->azlCol); + } + sqlite3_free(pTab); + } +} + +static RecoverTable *recoverNewTable( + ShellState *pState, + int *pRc, + int iRoot, + int nCol +){ + RecoverTable *pRet = 0; + + pRet = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); + if( pRet ){ + sqlite3_stmt *pStmt = 0; + pRet->zName = shellMPrintf(pRc, "orphan_%d_%d", nCol, iRoot); + pRet->zQuoted = shellMPrintf(pRc, "%Q", pRet->zName); + pRet->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * nCol); + pRet->nCol = nCol; + + shellPreparePrintf(pState->db, pRc, &pStmt, + "WITH s(i) AS (" + " SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<%d" + ")" + "SELECT i-1, group_concat('c' || i, ', ') OVER (ORDER BY i) FROM s", + nCol + ); + while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int idx = sqlite3_column_int(pStmt, 0); + const char *zText = (const char*)sqlite3_column_text(pStmt, 1); + pRet->azlCol[idx] = shellMPrintf(pRc, "%s", zText); + } + shellFinalize(pRc, pStmt); + + pRet->zCreate = shellMPrintf(pRc, "CREATE TABLE %Q (id, %s)", + pRet->zName, pRet->azlCol[nCol-1] + ); + } + + if( *pRc!=SQLITE_OK ){ + recoverFreeTable(pRet); + pRet = 0; + } + + return pRet; +} + +/* +** This function is called to recover data from the database. A script +** to construct a new database containing all recovered data is output +** on stream pState->out. +*/ +static int recoverDatabaseCmd(ShellState *pState){ + const char *zSql; + int rc = SQLITE_OK; + sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ + + shellExec(pState->db, &rc, + /* Attach an in-memory database named 'recovery'. Create an indexed + ** cache of the sqlite_dbptr virtual table. */ + "ATTACH '' AS recovery;" + "CREATE TABLE recovery.dbptr(" + " pgno, child, PRIMARY KEY(child, pgno)" + ") WITHOUT ROWID;" + "INSERT OR IGNORE INTO dbptr(pgno, child) SELECT * FROM sqlite_dbptr;" + + /* Delete any pointer to page 1. This ensures that page 1 is considered + ** a root page, regardless of how corrupt the db is. */ + "DELETE FROM recovery.dbptr WHERE child = 1;" + + /* Delete all pointers to any pages that have more than one pointer + ** to them. Such pages will be treated as root pages when recovering + ** data. */ + "DELETE FROM recovery.dbptr WHERE child IN (" + " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1" + ");" + + /* Create the "map" table that will (eventually) contain instructions + ** for dealing with each page in the db that contains one or more + ** records. */ + "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, maxlen INT, root INT);" + + /* Populate table [map]. If there are circular loops of pages in the + ** database, the following adds all pages in such a loop to the map + ** as individual root pages. This could be handled better. */ + "WITH pages(i, maxlen) AS (" + " SELECT page_count, max(field+1) " + " FROM pragma_page_count, sqlite_dbdata WHERE pgno=page_count" + " UNION ALL" + " SELECT * FROM (SELECT i-1, max(field+1)" + " FROM pages, sqlite_dbdata WHERE pgno=i-1 AND i>=2)" + ")" + "INSERT INTO recovery.map(pgno, maxlen, root) SELECT i, maxlen, (" + " WITH p(orig, pgno, parent) AS (" + " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)" + " UNION ALL" + " SELECT i, p.parent, " + " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p" + " )" + " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" + ") " + "FROM pages WHERE maxlen > 0;" + + /* Extract data from page 1 and any linked pages into table + ** recovery.schema. With the same schema as an sqlite_master table. */ + "CREATE TABLE recovery.schema(type, name, tbl_name, rootpage, sql);" + "INSERT INTO recovery.schema SELECT " + " max(CASE WHEN field=0 THEN value ELSE NULL END)," + " max(CASE WHEN field=1 THEN value ELSE NULL END)," + " max(CASE WHEN field=2 THEN value ELSE NULL END)," + " max(CASE WHEN field=3 THEN value ELSE NULL END)," + " max(CASE WHEN field=4 THEN value ELSE NULL END)" + "FROM sqlite_dbdata WHERE pgno IN (" + " SELECT pgno FROM recovery.map WHERE root=1" + ")" + "GROUP BY pgno, cell;" + ); + +#if 0 + zSql = "SELECT type ||','|| name ||','|| tbl_name ||','|| rootpage ||','|| sql FROM recovery.schema;"; + shellPrepare(pState->db, &rc, zSql, &pLoop); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ + raw_printf(pState->out, "%s\n", (const char*)sqlite3_column_text(pLoop, 0)); + } + shellFinalize(&rc, pLoop); + return rc; +#endif + + /* Loop through each root page. */ + zSql = "SELECT root,max(maxlen) FROM recovery.map WHERE root>1 GROUP BY root"; + shellPrepare(pState->db, &rc, zSql, &pLoop); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ + int iRoot = sqlite3_column_int(pLoop, 0); + int nCol = sqlite3_column_int(pLoop, 1); + RecoverTable *pTab; + + pTab = recoverNewTable(pState, &rc, iRoot, nCol); + if( pTab ){ + sqlite3_stmt *pData = 0; + raw_printf(pState->out, "%s;\n", pTab->zCreate); + shellPreparePrintf(pState->db, &rc, &pData, + "SELECT max(field), group_concat(quote(value), ', ') " + "FROM sqlite_dbdata WHERE pgno IN (" + " SELECT pgno FROM recovery.map WHERE root=%d" + ")" + "GROUP BY pgno, cell;", iRoot + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pData) ){ + int iMax = sqlite3_column_int(pData, 0); + const char *zVal = (const char*)sqlite3_column_text(pData, 1); + if( iMax+1==pTab->nCol ){ + raw_printf(pState->out, "INSERT INTO %s VALUES( %s );\n", + pTab->zQuoted, zVal); + }else{ + raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", + pTab->zQuoted, pTab->azlCol[iMax], zVal + ); + } + } + shellFinalize(&rc, pData); + } + recoverFreeTable(pTab); + } + shellFinalize(&rc, pLoop); + + sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0); + return rc; +} + /* ** If an input line begins with "." then invoke this routine to @@ -6313,6 +6549,11 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = shell_dbinfo_command(p, nArg, azArg); }else + if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){ + open_db(p, 0); + rc = recoverDatabaseCmd(p); + }else + if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ const char *zLike = 0; int i; @@ -6350,7 +6591,9 @@ static int do_meta_command(char *zLine, ShellState *p){ zLike = azArg[i]; } } + open_db(p, 0); + /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ @@ -6365,30 +6608,30 @@ static int do_meta_command(char *zLine, ShellState *p){ p->nErr = 0; if( zLike==0 ){ run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); + "SELECT name, type, sql FROM sqlite_master " + "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" + ); run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); + "SELECT name, type, sql FROM sqlite_master " + "WHERE name=='sqlite_sequence'" + ); run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 + ); }else{ char *zSql; zSql = sqlite3_mprintf( - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE %Q AND type=='table'" - " AND sql NOT NULL", zLike); + "SELECT name, type, sql FROM sqlite_master " + "WHERE tbl_name LIKE %Q AND type=='table'" + " AND sql NOT NULL", zLike); run_schema_dump_query(p,zSql); sqlite3_free(zSql); zSql = sqlite3_mprintf( - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL" - " AND type IN ('index','trigger','view')" - " AND tbl_name LIKE %Q", zLike); + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name LIKE %Q", zLike); run_table_dump_query(p, zSql, 0); sqlite3_free(zSql); } @@ -6398,7 +6641,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0); sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0); - raw_printf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n"); + raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n"); p->showHeader = savedShowHeader; p->shellFlgs = savedShellFlags; }else diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 534ac6156a..73eacdb9da 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -40,16 +40,21 @@ proc omit_redundant_typedefs {line} { } return $line } +set iLine 0 while {1} { set lx [omit_redundant_typedefs [gets $in]] if {[eof $in]} break; + incr iLine if {[regexp {^INCLUDE } $lx]} { set cfile [lindex $lx 1] puts $out "/************************* Begin $cfile ******************/" + puts $out "#line 1 \"$cfile\"" set in2 [open $topdir/src/$cfile rb] while {![eof $in2]} { set lx [omit_redundant_typedefs [gets $in2]] - if {[regexp {^#include "sqlite} $lx]} continue + if {[regexp {^#include "sqlite} $lx]} { + set lx "/* $lx */" + } if {[regexp {^# *include "test_windirent.h"} $lx]} { set lx "/* $lx */" } @@ -58,6 +63,7 @@ while {1} { } close $in2 puts $out "/************************* End $cfile ********************/" + puts $out "#line [expr $iLine+1] \"shell.c.in\"" continue } puts $out $lx From a9a5465eb44d0d8f1c3c9d288b7f23f628ddb50b Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Apr 2019 11:47:40 +0000 Subject: [PATCH 022/132] Fix an assert() that may be false for corrupt databases. FossilOrigin-Name: b2ce5ed175cb5029ac07392ae371c86eeec23c74624aad007dee51cf359f3eeb --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 7 +++---- test/corruptL.test | 28 ++++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index b01d6fa7e7..60a9580844 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\sa\ssingle\sbranch\sas\sno\slonger\sreachable. -D 2019-04-19T23:05:56.134 +C Fix\san\sassert()\sthat\smay\sbe\sfalse\sfor\scorrupt\sdatabases. +D 2019-04-22T11:47:40.572 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -459,7 +459,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 958939f608e351a36756e3749596472baa0e5aae54eebd14e6beffe7a68aafc7 +F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 61655dad911a967a69fb49df57268fd15ce8f1af3fe0a1bd90c128ef2cacfb7a @@ -762,7 +762,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test a569f3cece872a1f21568bd5378f55ce5c365c50845a06fae65a2721cce62264 +F test/corruptL.test 13763e4769eeef308badfcc95dea5d5e00e61a1732a1214a48ff24d3f5db8cbc F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c F test/countofview.test e3d4cd6900e4e4f074968ab24b8b87d3671cd624961bef40fd3a6b8f574343cf @@ -1818,7 +1818,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 6cf16703fd4a835c249c947006ae4a4bf81873c8ca1803945453c9845f882dc1 -R ff3642bada516bde6836db167619c845 -U drh -Z 2a6d21c59c4950c9897c2627e0f9536a +P 4f35b3b78a461b0617a5cd04f60d2ab277bcc7c994dae463851a3cb5d041a723 +R b79fbec9cc96d7584a3a8f94492a3f38 +U dan +Z 002b02d6adc168b9ce09f7701a50dc63 diff --git a/manifest.uuid b/manifest.uuid index 43ee2ab2a5..0b8dab0f77 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f35b3b78a461b0617a5cd04f60d2ab277bcc7c994dae463851a3cb5d041a723 \ No newline at end of file +b2ce5ed175cb5029ac07392ae371c86eeec23c74624aad007dee51cf359f3eeb \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index b31f74e794..e282ff4ed4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4284,10 +4284,9 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ rc = newDatabase(pBt); pBt->nPage = get4byte(28 + pBt->pPage1->aData); - /* The database size was written into the offset 28 of the header - ** when the transaction started, so we know that the value at offset - ** 28 is nonzero. */ - assert( pBt->nPage>0 ); + /* pBt->nPage might be zero if the database was corrupt when + ** the transaction was started. Otherwise, it must be at least 1. */ + assert( CORRUPT_DB || pBt->nPage>0 ); } sqlite3BtreeLeave(p); } diff --git a/test/corruptL.test b/test/corruptL.test index 213af9d343..6f129e8408 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -838,4 +838,32 @@ do_catchsql_test 8.1 { INSERT INTO t3 SELECT * FROM t2; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 9.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename crash-ab10597e4e1c32.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 01 0f d6 00 0f d6 00 00 ................ +| 4048: 00 00 00 00 00 00 28 01 06 17 11 11 01 3d 74 61 ......(......=ta +| 4064: 62 6c 65 74 31 74 31 02 43 52 45 41 54 45 20 54 blet1t1.CREATE T +| 4080: 41 42 4c 45 20 74 31 28 61 2c 62 2c 63 2c 64 29 ABLE t1(a,b,c,d) +| page 2 offset 4096 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| end crash-ab10597e4e1c32.db +}]} {} + +do_execsql_test 9.1 { + SAVEPOINT one; +} +do_catchsql_test 9.3 { + INSERT INTO t1(b,c) VALUES(5,6); +} {1 {database disk image is malformed}} +do_execsql_test 9.3 { + ROLLBACK TO one; +} + finish_test From 2b13cd99d30c78d4ca13380fcb9484ad1aba829f Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 22 Apr 2019 20:05:54 +0000 Subject: [PATCH 023/132] Early detection of SQLITE_TOOBIG when processing nested queries. FossilOrigin-Name: 5d85d80ef8b216639244c6f4e6a2c0050af3cf9c3998f372bae4a19c0430f2fd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 60a9580844..bac1dda39b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sthat\smay\sbe\sfalse\sfor\scorrupt\sdatabases. -D 2019-04-22T11:47:40.572 +C Early\sdetection\sof\sSQLITE_TOOBIG\swhen\sprocessing\snested\squeries. +D 2019-04-22T20:05:54.645 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c e6c6a75e9aac747ea26b5e2d1d7a9af50b813ea5524d4ec556a0afc72a6d69d4 +F src/select.c e2c1f53e429753699593f3918c465d17b528cbdce3e41db08adcdfa9a19cd9ae F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1818,7 +1818,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 4f35b3b78a461b0617a5cd04f60d2ab277bcc7c994dae463851a3cb5d041a723 -R b79fbec9cc96d7584a3a8f94492a3f38 -U dan -Z 002b02d6adc168b9ce09f7701a50dc63 +P b2ce5ed175cb5029ac07392ae371c86eeec23c74624aad007dee51cf359f3eeb +R 1131fd6ab632cf843fd3481da275126c +U drh +Z 2b97e19a94f7f535b7b97df584acbe3e diff --git a/manifest.uuid b/manifest.uuid index 0b8dab0f77..4e5afda521 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2ce5ed175cb5029ac07392ae371c86eeec23c74624aad007dee51cf359f3eeb \ No newline at end of file +5d85d80ef8b216639244c6f4e6a2c0050af3cf9c3998f372bae4a19c0430f2fd \ No newline at end of file diff --git a/src/select.c b/src/select.c index 89bc8b1933..436e7c1a8d 100644 --- a/src/select.c +++ b/src/select.c @@ -4797,7 +4797,7 @@ int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral; - return SQLITE_OK; + return pParse->rc; } /* From b40af49d735f7ea8111bf37dab5c3f041e549290 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 22 Apr 2019 20:52:12 +0000 Subject: [PATCH 024/132] Enhance the ".recover" command. Fix a problem with overflow pages in dbdata.c. FossilOrigin-Name: f193ca587f9e4f925f4f2343b0b07053bd6f93dd87fc6f8f41cf4479e90cf562 --- ext/misc/dbdata.c | 1 + manifest | 16 ++-- manifest.uuid | 2 +- src/shell.c.in | 207 ++++++++++++++++++++++++++++++++++++++++------ test/dbdata.test | 10 +++ 5 files changed, 201 insertions(+), 35 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index aae862fc7f..7662417ae5 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -506,6 +506,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); nRem -= nCopy; + pgnoOvfl = get_uint32(aOvfl); sqlite3_free(aOvfl); } } diff --git a/manifest b/manifest index c103da1624..b830ce2b1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".recovery"\scommand\sto\sthe\sshell\stool.\sFor\srecovering\sthe\smaximum\samount\sdata\sfrom\scorrupt\sdatabases.\sStill\sneeds\swork. -D 2019-04-20T20:57:28.136 +C Enhance\sthe\s".recover"\scommand.\sFix\sa\sproblem\swith\soverflow\spages\sin\sdbdata.c. +D 2019-04-22T20:52:12.850 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 8f74f25565e1f57942f75134ef94ab73058849bed87d92be619be7d3b8a7d054 +F ext/misc/dbdata.c 6a0ccc33e8c5ef3b6164eec7839cb4dff44e27bee0717f1660dbb8ee77ee4cf8 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 3646e448cc207fa3118266c2a23f177306b068e42aae6fee64323ffb13307680 +F src/shell.c.in 7dd0babc42bc136b8dd070152981ee2325b787571f58326e68e6ad35d764aa33 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -787,7 +787,7 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 -F test/dbdata.test 573fa3347744863e47d011e4e8e9b87c6795ba92a759bf5d5c68da975900ddd4 +F test/dbdata.test c8d97bafd1b2efb1e445871c4641208dcd91e686d2dfbb6463d83934adbd1ac5 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee @@ -1820,7 +1820,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 3213a15f2133afbb0a4fec3b8f6e0eeca8c0befafd6658c41074e84f589d5d32 -R 9a7e323fe9ebfe9eb0759e1c70136795 +P 7461d2e120f2149315ddac2676d51d7445bcdb8e97543effd9c30603517ef9da +R 14050e9b3d7e7a784dc8a127e6275222 U dan -Z 100e3ccaddf1d19d0bacd74d773a93b7 +Z abcbf2aebf4cbfcbf65f71e558364487 diff --git a/manifest.uuid b/manifest.uuid index 0b854fa40a..65b5fdd250 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7461d2e120f2149315ddac2676d51d7445bcdb8e97543effd9c30603517ef9da \ No newline at end of file +f193ca587f9e4f925f4f2343b0b07053bd6f93dd87fc6f8f41cf4479e90cf562 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index c38bfb64b9..abba5b0168 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6073,9 +6073,9 @@ typedef struct RecoverTable RecoverTable; struct RecoverTable { char *zName; /* Name of table */ char *zQuoted; /* Quoted version of zName */ - char *zCreate; /* SQL to create table in default schema */ int nCol; /* Number of columns in table */ char **azlCol; /* Array of column lists */ + int iPk; }; /* @@ -6085,7 +6085,6 @@ static void recoverFreeTable(RecoverTable *pTab){ if( pTab ){ sqlite3_free(pTab->zName); sqlite3_free(pTab->zQuoted); - sqlite3_free(pTab->zCreate); if( pTab->azlCol ){ int i; for(i=0; inCol; i++){ @@ -6097,17 +6096,141 @@ static void recoverFreeTable(RecoverTable *pTab){ } } +static void recoverOldTable( + int *pRc, /* IN/OUT: Error code */ + RecoverTable *pTab, + const char *zName, /* Name of table */ + const char *zSql, /* CREATE TABLE statement */ + int bIntkey, + int nCol +){ + sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */ + int rc = *pRc; + + if( rc==SQLITE_OK ){ + int nSqlCol = 0; + int bSqlIntkey = 0; + sqlite3_stmt *pStmt = 0; + + rc = sqlite3_open("", &dbtmp); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0); + if( rc==SQLITE_ERROR ){ + rc = SQLITE_OK; + goto finished; + } + } + shellPreparePrintf(dbtmp, &rc, &pStmt, + "SELECT count(*) FROM pragma_table_info(%Q)", zName + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + nSqlCol = sqlite3_column_int(pStmt, 0); + } + shellFinalize(&rc, pStmt); + + if( rc!=SQLITE_OK || nSqlColiPk = sqlite3_column_int(pPkFinder, 0); + zPk = (const char*)sqlite3_column_text(pPkFinder, 1); + } + + pTab->zName = shellMPrintf(&rc, "%s", zName); + pTab->zQuoted = shellMPrintf(&rc, "%Q", pTab->zName); + pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * nSqlCol); + pTab->nCol = nSqlCol; + + if( nSqlCol==1 && pTab->iPk==0 ){ + pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk); + }else{ + shellPreparePrintf(dbtmp, &rc, &pStmt, + "SELECT -1+row_number() OVER (ORDER BY cid)," + " %Q||%Q||group_concat(name, ', ') FILTER (WHERE cid!=%d) " + " OVER (ORDER BY cid) " + "FROM pragma_table_info(%Q)", + (bIntkey ? zPk : ""), (bIntkey ? ", " : ""), + pTab->iPk, zName + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int idx = sqlite3_column_int(pStmt, 0); + const char *zText = (const char*)sqlite3_column_text(pStmt, 1); + pTab->azlCol[idx] = shellMPrintf(&rc, "%s", zText); + } + shellFinalize(&rc, pStmt); + } + shellFinalize(&rc, pPkFinder); + } + } + + finished: + sqlite3_close(dbtmp); + *pRc = rc; +} + static RecoverTable *recoverNewTable( ShellState *pState, int *pRc, int iRoot, + int bIntkey, int nCol ){ + sqlite3_stmt *pStmt = 0; RecoverTable *pRet = 0; + int bNoop = 0; + const char *zSql = 0; + const char *zName = 0; pRet = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); - if( pRet ){ + if( pRet ) pRet->iPk = -2; + + /* Search the recovered schema for an object with root page iRoot. */ + shellPreparePrintf(pState->db, pRc, &pStmt, + "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot + ); + while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zType = (const char*)sqlite3_column_text(pStmt, 0); + if( bIntkey==0 && sqlite3_stricmp(zType, "index")==0 ){ + bNoop = 1; + break; + } + if( sqlite3_stricmp(zType, "table")==0 ){ + zName = (const char*)sqlite3_column_text(pStmt, 1); + zSql = (const char*)sqlite3_column_text(pStmt, 2); + recoverOldTable(pRc, pRet, zName, zSql, bIntkey, nCol); + break; + } + } + shellFinalize(pRc, pStmt); + if( bNoop ){ + sqlite3_free(pRet); + return 0; + } + + if( pRet && pRet->zName==0 ){ sqlite3_stmt *pStmt = 0; + pRet->zName = shellMPrintf(pRc, "orphan_%d_%d", nCol, iRoot); pRet->zQuoted = shellMPrintf(pRc, "%Q", pRet->zName); pRet->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * nCol); @@ -6117,8 +6240,8 @@ static RecoverTable *recoverNewTable( "WITH s(i) AS (" " SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<%d" ")" - "SELECT i-1, group_concat('c' || i, ', ') OVER (ORDER BY i) FROM s", - nCol + "SELECT i-1, %Q || group_concat('c' || i, ', ') OVER (ORDER BY i) FROM s", + nCol, (bIntkey ? "id, " : "") ); while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ int idx = sqlite3_column_int(pStmt, 0); @@ -6127,9 +6250,15 @@ static RecoverTable *recoverNewTable( } shellFinalize(pRc, pStmt); - pRet->zCreate = shellMPrintf(pRc, "CREATE TABLE %Q (id, %s)", + if( *pRc==SQLITE_OK ){ + char *zCreate = shellMPrintf(pRc, "CREATE TABLE %Q (%s)", pRet->zName, pRet->azlCol[nCol-1] - ); + ); + if( zCreate ){ + raw_printf(pState->out, "%s;\n", zCreate); + sqlite3_free(zCreate); + } + } } if( *pRc!=SQLITE_OK ){ @@ -6146,7 +6275,6 @@ static RecoverTable *recoverNewTable( ** on stream pState->out. */ static int recoverDatabaseCmd(ShellState *pState){ - const char *zSql; int rc = SQLITE_OK; sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ @@ -6173,7 +6301,9 @@ static int recoverDatabaseCmd(ShellState *pState){ /* Create the "map" table that will (eventually) contain instructions ** for dealing with each page in the db that contains one or more ** records. */ - "CREATE TABLE recovery.map(pgno INTEGER PRIMARY KEY, maxlen INT, root INT);" + "CREATE TABLE recovery.map(" + "pgno INTEGER PRIMARY KEY, maxlen INT, intkey, root INT" + ");" /* Populate table [map]. If there are circular loops of pages in the ** database, the following adds all pages in such a loop to the map @@ -6182,10 +6312,12 @@ static int recoverDatabaseCmd(ShellState *pState){ " SELECT page_count, max(field+1) " " FROM pragma_page_count, sqlite_dbdata WHERE pgno=page_count" " UNION ALL" - " SELECT * FROM (SELECT i-1, max(field+1)" - " FROM pages, sqlite_dbdata WHERE pgno=i-1 AND i>=2)" + " SELECT i-1, (" + " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1" + " ) FROM pages WHERE i>=2" ")" - "INSERT INTO recovery.map(pgno, maxlen, root) SELECT i, maxlen, (" + "INSERT INTO recovery.map(pgno, maxlen, intkey, root) " + " SELECT i, maxlen, NULL, (" " WITH p(orig, pgno, parent) AS (" " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)" " UNION ALL" @@ -6195,6 +6327,9 @@ static int recoverDatabaseCmd(ShellState *pState){ " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" ") " "FROM pages WHERE maxlen > 0;" + "UPDATE recovery.map AS o SET intkey = (" + " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno" + ");" /* Extract data from page 1 and any linked pages into table ** recovery.schema. With the same schema as an sqlite_master table. */ @@ -6221,36 +6356,53 @@ static int recoverDatabaseCmd(ShellState *pState){ return rc; #endif + /* Open a transaction, then print out all non-virtual, non-"sqlite_%" + ** CREATE TABLE statements that extracted from the existing schema. */ + if( rc==SQLITE_OK ){ + sqlite3_stmt *pStmt = 0; + raw_printf(pState->out, "BEGIN;\n"); + shellPrepare(pState->db, &rc, + "SELECT sql FROM recovery.schema " + "WHERE type='table' " + " AND length(sql)>6" + " AND sql LIKE 'create table%'" + " AND name NOT LIKE 'sqliteX_%' ESCAPE 'X'", &pStmt + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0); + raw_printf(pState->out, "%s;\n", zCreateTable); + } + shellFinalize(&rc, pStmt); + } + /* Loop through each root page. */ - zSql = "SELECT root,max(maxlen) FROM recovery.map WHERE root>1 GROUP BY root"; - shellPrepare(pState->db, &rc, zSql, &pLoop); + shellPrepare(pState->db, &rc, + "SELECT root, intkey, max(maxlen) FROM recovery.map" + " WHERE root>1 GROUP BY root, intkey", &pLoop + ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ int iRoot = sqlite3_column_int(pLoop, 0); - int nCol = sqlite3_column_int(pLoop, 1); + int bIntkey = sqlite3_column_int(pLoop, 1); + int nCol = sqlite3_column_int(pLoop, 2); RecoverTable *pTab; - pTab = recoverNewTable(pState, &rc, iRoot, nCol); + pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol); if( pTab ){ sqlite3_stmt *pData = 0; - raw_printf(pState->out, "%s;\n", pTab->zCreate); shellPreparePrintf(pState->db, &rc, &pData, "SELECT max(field), group_concat(quote(value), ', ') " "FROM sqlite_dbdata WHERE pgno IN (" " SELECT pgno FROM recovery.map WHERE root=%d" ")" - "GROUP BY pgno, cell;", iRoot + " AND field!=%d " + "GROUP BY pgno, cell;", iRoot, pTab->iPk ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pData) ){ int iMax = sqlite3_column_int(pData, 0); const char *zVal = (const char*)sqlite3_column_text(pData, 1); - if( iMax+1==pTab->nCol ){ - raw_printf(pState->out, "INSERT INTO %s VALUES( %s );\n", - pTab->zQuoted, zVal); - }else{ - raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", - pTab->zQuoted, pTab->azlCol[iMax], zVal - ); - } + raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", + pTab->zQuoted, pTab->azlCol[iMax>0?iMax:0], zVal + ); } shellFinalize(&rc, pData); } @@ -6258,6 +6410,9 @@ static int recoverDatabaseCmd(ShellState *pState){ } shellFinalize(&rc, pLoop); + if( rc==SQLITE_OK ){ + raw_printf(pState->out, "COMMIT;\n"); + } sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0); return rc; } diff --git a/test/dbdata.test b/test/dbdata.test index 5a0df5dc86..391b278025 100644 --- a/test/dbdata.test +++ b/test/dbdata.test @@ -67,6 +67,16 @@ do_execsql_test 1.3 { SELECT value FROM sqlite_dbdata WHERE pgno=2 AND cell=2 AND field=1; } $big +do_execsql_test 1.4 { + DELETE FROM t1; + INSERT INTO t1 VALUES(NULL, randomblob(5050)); +} +do_test 1.5 { + execsql { + SELECT quote(value) FROM sqlite_dbdata WHERE pgno=2 AND cell=0 AND field=1; + } +} [db one {SELECT quote(b) FROM t1}] + #------------------------------------------------------------------------- reset_db db enable_load_extension 1 From f4b331535d7a1f55eb5eb4fdab5ec0a50d1dd73a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Apr 2019 12:30:15 +0000 Subject: [PATCH 025/132] Improvement on the previous check-in. Parse.rc is less reliable than Parse.nErr for detecting SQLITE_TOOBIG errors. FossilOrigin-Name: 8d478cfb92fdeb87591403fe1713b290fee309a38b71abee0002012935d1db98 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index bac1dda39b..e66acdb7bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Early\sdetection\sof\sSQLITE_TOOBIG\swhen\sprocessing\snested\squeries. -D 2019-04-22T20:05:54.645 +C Improvement\son\sthe\sprevious\scheck-in.\s\sParse.rc\sis\sless\sreliable\sthan\nParse.nErr\sfor\sdetecting\sSQLITE_TOOBIG\serrors. +D 2019-04-23T12:30:15.974 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c e2c1f53e429753699593f3918c465d17b528cbdce3e41db08adcdfa9a19cd9ae +F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1818,7 +1818,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 b2ce5ed175cb5029ac07392ae371c86eeec23c74624aad007dee51cf359f3eeb -R 1131fd6ab632cf843fd3481da275126c +P 5d85d80ef8b216639244c6f4e6a2c0050af3cf9c3998f372bae4a19c0430f2fd +R 3fe320a5871498cd9f9fa2f114a99352 U drh -Z 2b97e19a94f7f535b7b97df584acbe3e +Z 37b55947258e1ee79a97c65d6538f295 diff --git a/manifest.uuid b/manifest.uuid index 4e5afda521..5a4dc830f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d85d80ef8b216639244c6f4e6a2c0050af3cf9c3998f372bae4a19c0430f2fd \ No newline at end of file +8d478cfb92fdeb87591403fe1713b290fee309a38b71abee0002012935d1db98 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 436e7c1a8d..2df79e2e6c 100644 --- a/src/select.c +++ b/src/select.c @@ -4797,7 +4797,7 @@ int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral; - return pParse->rc; + return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } /* From d94d9e22895ba9226d26530ba492430de6b335c4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Apr 2019 12:31:41 +0000 Subject: [PATCH 026/132] New test cases in fuzzdata8.db. FossilOrigin-Name: 0fe3c3fd30294d15cdfe29e9c49f3c8968e864ec8a114282561642f75586ab09 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/fuzzdata8.db | Bin 1057792 -> 1062912 bytes 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e66acdb7bc..3c314aea61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvement\son\sthe\sprevious\scheck-in.\s\sParse.rc\sis\sless\sreliable\sthan\nParse.nErr\sfor\sdetecting\sSQLITE_TOOBIG\serrors. -D 2019-04-23T12:30:15.974 +C New\stest\scases\sin\sfuzzdata8.db. +D 2019-04-23T12:31:41.656 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -997,7 +997,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db f46c9a5698c1ca75ca6280c7c879a3f46dc82fe4b1ce246827496b806488952d -F test/fuzzdata8.db 5f12b6a8579e89616da9bd6dede1f38748eb04a1265f0b89117274f44d76b227 +F test/fuzzdata8.db 858795dc515318bc27b568d0f83cd766ba8f6c3f7095a331c3b099676cc40567 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1818,7 +1818,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 5d85d80ef8b216639244c6f4e6a2c0050af3cf9c3998f372bae4a19c0430f2fd -R 3fe320a5871498cd9f9fa2f114a99352 +P 8d478cfb92fdeb87591403fe1713b290fee309a38b71abee0002012935d1db98 +R 32be74560d9250fbd31ea09d70d32784 U drh -Z 37b55947258e1ee79a97c65d6538f295 +Z fc3c1491b224e7c3aeefcc1f28d34e05 diff --git a/manifest.uuid b/manifest.uuid index 5a4dc830f1..f110235c6e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d478cfb92fdeb87591403fe1713b290fee309a38b71abee0002012935d1db98 \ No newline at end of file +0fe3c3fd30294d15cdfe29e9c49f3c8968e864ec8a114282561642f75586ab09 \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 929cdfefed3a873a16b25589b689241b389f623b..777f734fc1a968c6f2c008d3254db13816487931 100644 GIT binary patch delta 18383 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 delta 17195 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

WOAbD&#wsU?K9lsnm@eJ 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 From 3ea557e0e7d289b28c05c1797f900ee224fc9471 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Apr 2019 15:30:58 +0000 Subject: [PATCH 027/132] Changes to the --hexdb decoder option in the shell (and also in the TCL test code) so that it works on systems where sscanf() does not recognize "%hhx" as wanting to delivery results into a character-size variable. FossilOrigin-Name: 4258e42d92b0113ba59f407197fc24f21734900e5b02952deed07818be3e3e5d --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/shell.c.in | 8 ++++---- src/test1.c | 8 ++++---- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index c20def1d55..c39a5406fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\ssimplification\sof\sNULL\svalue\shandling\sfor\sSTAT4. -D 2019-04-23T15:08:11.881 +C Changes\sto\sthe\s--hexdb\sdecoder\soption\sin\sthe\sshell\s(and\salso\sin\sthe\sTCL\ntest\scode)\sso\sthat\sit\sworks\son\ssystems\swhere\ssscanf()\sdoes\snot\srecognize\n"%hhx"\sas\swanting\sto\sdelivery\sresults\sinto\sa\scharacter-size\svariable. +D 2019-04-23T15:30:58.115 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -519,7 +519,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 0d1a1abd8f1056ac6b32981442618e988e1e192cec2e904e58c72fcf494c901e +F src/shell.c.in bcfa17eb257bf8dc2359e99ba7e6bdfab7901705db013bc47a5be6d7fa7a037e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -528,7 +528,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 -F src/test1.c 0dc98af0769302672dcefd07a6128ee14e837b9f6e338a1aaca7ac31e4d8d2f8 +F src/test1.c c02d8bc27bb61d987b6f696ef62ce583272dbdd03042a241bc5ac767d3558709 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -1818,8 +1818,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 0fe3c3fd30294d15cdfe29e9c49f3c8968e864ec8a114282561642f75586ab09 5718a9d5fc3fdfc89db869501c81fda39b3ec5c7e11fa0038fc258e316f5d8a1 -R 23ea5d57ea4586c9894c7989b0405f0a -T +closed 5718a9d5fc3fdfc89db869501c81fda39b3ec5c7e11fa0038fc258e316f5d8a1 -U mistachkin -Z eb70dea10b0612f49ef98bf8a7e2a70e +P 69bad9257f8db6a2a761bdd298d972eb48d4f845ec11dedc802ba3bafb979915 +R 77b9435054a3e08f2d59227806ec4211 +U drh +Z 051f88570fa9bfac9ab4955fc59fefc8 diff --git a/manifest.uuid b/manifest.uuid index 0e3ed89aa2..882147fe53 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -69bad9257f8db6a2a761bdd298d972eb48d4f845ec11dedc802ba3bafb979915 \ No newline at end of file +4258e42d92b0113ba59f407197fc24f21734900e5b02952deed07818be3e3e5d \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 78dddd7a29..1f57d1ec3d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3858,7 +3858,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ int j, k; int rc; FILE *in; - unsigned char x[16]; + unsigned int x[16]; char zLine[1000]; if( p->zDbFilename ){ in = fopen(p->zDbFilename, "r"); @@ -3896,14 +3896,14 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ if( strncmp(zLine, "| end ", 6)==0 ){ break; } - rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" - " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx", + rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); if( rc==17 ){ k = iOffset+j; if( k+16<=n ){ - memcpy(a+k, x, 16); + int ii; + for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; } } } diff --git a/src/test1.c b/src/test1.c index 17819b9239..dcbc9e613a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7699,7 +7699,7 @@ static int SQLITE_TCLAPI test_decode_hexdb( int iOffset = 0; int j, k; int rc; - unsigned char x[16]; + unsigned int x[16]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDB"); return TCL_ERROR; @@ -7731,14 +7731,14 @@ static int SQLITE_TCLAPI test_decode_hexdb( iOffset = k; continue; } - rc = sscanf(zIn+i,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" - " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx", + rc = sscanf(zIn+i,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x", &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); if( rc==17 ){ k = iOffset+j; if( k+16<=n ){ - memcpy(a+k, x, 16); + int ii; + for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff; } continue; } From 38f9c7194df5d9c86cbeaa04c22bdee56c3c5635 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 23 Apr 2019 18:03:02 +0000 Subject: [PATCH 028/132] Fixes for the ".recover" shell command. FossilOrigin-Name: 8dcc1d89d955bf58c80a8c30a37960f0cf95719953951a92626cc332cc75ec60 --- manifest | 13 +++---- manifest.uuid | 2 +- src/shell.c.in | 47 +++++++++++++++++++++---- test/recover.test | 88 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 14 deletions(-) create mode 100644 test/recover.test diff --git a/manifest b/manifest index b830ce2b1e..509212bede 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\s".recover"\scommand.\sFix\sa\sproblem\swith\soverflow\spages\sin\sdbdata.c. -D 2019-04-22T20:52:12.850 +C Fixes\sfor\sthe\s".recover"\sshell\scommand. +D 2019-04-23T18:03:02.318 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 7dd0babc42bc136b8dd070152981ee2325b787571f58326e68e6ad35d764aa33 +F src/shell.c.in 6c02cbd1de3b878abc04b08f2f74cc4d65d0a8e52dd3e78194db2a79d686b841 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1226,6 +1226,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 +F test/recover.test a8fed5acf2742268e366abb76a01de6ddce278aae01658488b950c968ebef638 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 @@ -1820,7 +1821,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 7461d2e120f2149315ddac2676d51d7445bcdb8e97543effd9c30603517ef9da -R 14050e9b3d7e7a784dc8a127e6275222 +P f193ca587f9e4f925f4f2343b0b07053bd6f93dd87fc6f8f41cf4479e90cf562 +R 73bcd5cc8a48367ff5a018a5ccb0a79d U dan -Z abcbf2aebf4cbfcbf65f71e558364487 +Z e408dc486ac689ec1d61c890dc79708f diff --git a/manifest.uuid b/manifest.uuid index 65b5fdd250..680d92aac8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f193ca587f9e4f925f4f2343b0b07053bd6f93dd87fc6f8f41cf4479e90cf562 \ No newline at end of file +8dcc1d89d955bf58c80a8c30a37960f0cf95719953951a92626cc332cc75ec60 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index abba5b0168..8ac87fbfa2 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6113,6 +6113,9 @@ static void recoverOldTable( sqlite3_stmt *pStmt = 0; rc = sqlite3_open("", &dbtmp); + if( rc==SQLITE_OK ){ + rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0); + } if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, zSql, 0, 0, 0); if( rc==SQLITE_ERROR ){ @@ -6361,16 +6364,16 @@ static int recoverDatabaseCmd(ShellState *pState){ if( rc==SQLITE_OK ){ sqlite3_stmt *pStmt = 0; raw_printf(pState->out, "BEGIN;\n"); - shellPrepare(pState->db, &rc, + raw_printf(pState->out, "PRAGMA writable_schema = on;\n"); + shellPrepare(pState->db, &rc, "SELECT sql FROM recovery.schema " - "WHERE type='table' " - " AND length(sql)>6" - " AND sql LIKE 'create table%'" - " AND name NOT LIKE 'sqliteX_%' ESCAPE 'X'", &pStmt + "WHERE type='table' AND sql LIKE 'create table%'", &pStmt ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zCreateTable = (const char*)sqlite3_column_text(pStmt, 0); - raw_printf(pState->out, "%s;\n", zCreateTable); + raw_printf(pState->out, "CREATE TABLE IF NOT EXISTS %s;\n", + &zCreateTable[12] + ); } shellFinalize(&rc, pStmt); } @@ -6378,7 +6381,9 @@ static int recoverDatabaseCmd(ShellState *pState){ /* Loop through each root page. */ shellPrepare(pState->db, &rc, "SELECT root, intkey, max(maxlen) FROM recovery.map" - " WHERE root>1 GROUP BY root, intkey", &pLoop + " WHERE root>1 GROUP BY root, intkey ORDER BY root=(" + " SELECT rootpage FROM recovery.schema WHERE name='sqlite_sequence'" + ")", &pLoop ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ int iRoot = sqlite3_column_int(pLoop, 0); @@ -6389,6 +6394,9 @@ static int recoverDatabaseCmd(ShellState *pState){ pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol); if( pTab ){ sqlite3_stmt *pData = 0; + if( 0==sqlite3_stricmp(pTab->zName, "sqlite_sequence") ){ + raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); + } shellPreparePrintf(pState->db, &rc, &pData, "SELECT max(field), group_concat(quote(value), ', ') " "FROM sqlite_dbdata WHERE pgno IN (" @@ -6410,7 +6418,32 @@ static int recoverDatabaseCmd(ShellState *pState){ } shellFinalize(&rc, pLoop); + /* The rest of the schema */ if( rc==SQLITE_OK ){ + sqlite3_stmt *pStmt = 0; + shellPrepare(pState->db, &rc, + "SELECT sql, name FROM recovery.schema " + "WHERE (type='table' AND sql LIKE 'create table%') IS NOT TRUE", &pStmt + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zSql = (const char*)sqlite3_column_text(pStmt, 0); + if( sqlite3_strnicmp(zSql, "create virt", 11)==0 ){ + const char *zName = (const char*)sqlite3_column_text(pStmt, 1); + char *zPrint = shellMPrintf(&rc, + "INSERT INTO sqlite_master VALUES('table', %Q, %Q, 0, %Q)", + zName, zName, zSql + ); + raw_printf(pState->out, "%s;\n", zPrint); + sqlite3_free(zPrint); + }else{ + raw_printf(pState->out, "%s;\n", zSql); + } + } + shellFinalize(&rc, pStmt); + } + + if( rc==SQLITE_OK ){ + raw_printf(pState->out, "PRAGMA writable_schema = off;\n"); raw_printf(pState->out, "COMMIT;\n"); } sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0); diff --git a/test/recover.test b/test/recover.test new file mode 100644 index 0000000000..6ee35054f8 --- /dev/null +++ b/test/recover.test @@ -0,0 +1,88 @@ +# 2019 April 23 +# +# 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. +# +#*********************************************************************** +# +# Test the shell tool ".ar" command. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix recover + +ifcapable !vtab { + finish_test; return +} +set CLI [test_find_cli] + +proc compare_result {db1 db2 sql} { + set r1 [$db1 eval $sql] + set r2 [$db2 eval $sql] + if {$r1 != $r2} { + puts "r1: $r1" + puts "r2: $r2" + error "mismatch for $sql" + } + return "" +} + +proc compare_dbs {db1 db2} { + compare_result $db1 $db2 "SELECT sql FROM sqlite_master ORDER BY 1" + foreach tbl [$db1 eval {SELECT name FROM sqlite_master WHERE type='table'}] { + compare_result $db1 $db2 "SELECT * FROM $tbl" + } +} + +proc do_recover_test {tn} { + set fd [open "|$::CLI test.db .recover"] + fconfigure $fd -encoding binary + fconfigure $fd -translation binary + set sql [read $fd] + close $fd + + forcedelete test.db2 + sqlite3 db2 test.db2 + breakpoint + execsql $sql db2 + uplevel [list do_test $tn [list compare_dbs db db2] {}] + db2 close +} + +set doc { + hello + world +} +do_execsql_test 1.1.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1, 4, X'1234567800'); + INSERT INTO t1 VALUES(2, 'test', 8.1); + INSERT INTO t1 VALUES(3, $doc, 8.4); +} +do_recover_test 1.1.2 + +do_execsql_test 1.2.1 " + DELETE FROM t1; + INSERT INTO t1 VALUES(13, 'hello\r\nworld', 13); +" +do_recover_test 1.2.2 + +do_execsql_test 1.3.1 " + CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c); + INSERT INTO t2 VALUES(NULL, 1, 2); + INSERT INTO t2 VALUES(NULL, 3, 4); + INSERT INTO t2 VALUES(NULL, 5, 6); + CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, b, c); + INSERT INTO t3 VALUES(NULL, 1, 2); + INSERT INTO t3 VALUES(NULL, 3, 4); + INSERT INTO t3 VALUES(NULL, 5, 6); + DELETE FROM t2; +" +do_recover_test 1.3.2 + +finish_test From b182588c8e0cdbafc5987df0a919d29021d1ba58 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 23 Apr 2019 20:48:32 +0000 Subject: [PATCH 029/132] Have ".recover" handle "\r" and "\n" in the same way as ".dump". FossilOrigin-Name: f95f0f02ab6c6cf45f25b613c7ab57f68249689d0a9eddf4c9518ddf0edad365 --- manifest | 12 +++--- manifest.uuid | 2 +- src/shell.c.in | 106 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 101 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 509212bede..e3ab13575f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sfor\sthe\s".recover"\sshell\scommand. -D 2019-04-23T18:03:02.318 +C Have\s".recover"\shandle\s"\\r"\sand\s"\\n"\sin\sthe\ssame\sway\sas\s".dump". +D 2019-04-23T20:48:32.366 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 6c02cbd1de3b878abc04b08f2f74cc4d65d0a8e52dd3e78194db2a79d686b841 +F src/shell.c.in 6e56c60640410885a8c3c264971619407ae5c7f46165e2bfe5fb1ca1a6a58ad0 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 f193ca587f9e4f925f4f2343b0b07053bd6f93dd87fc6f8f41cf4479e90cf562 -R 73bcd5cc8a48367ff5a018a5ccb0a79d +P 8dcc1d89d955bf58c80a8c30a37960f0cf95719953951a92626cc332cc75ec60 +R b9c18dd1095e3f7b028bdaea88f9fcb0 U dan -Z e408dc486ac689ec1d61c890dc79708f +Z edabfc3afbc2656b0ce1a8fb6b1e492b diff --git a/manifest.uuid b/manifest.uuid index 680d92aac8..fdcc68f9a9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8dcc1d89d955bf58c80a8c30a37960f0cf95719953951a92626cc332cc75ec60 \ No newline at end of file +f95f0f02ab6c6cf45f25b613c7ab57f68249689d0a9eddf4c9518ddf0edad365 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 8ac87fbfa2..7989c9dfde 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3934,6 +3934,96 @@ readHexDb_error: } #endif /* SQLITE_ENABLE_DESERIALIZE */ +/* +** Scalar function "shell_escape_crnl" used by the .recover command. +** The argument passed to this function is the output of built-in +** function quote(). If the first character of the input is "'", +** indicating that the value passed to quote() was a text value, +** then this function searches the input for "\n" and "\r" characters +** and adds a wrapper similar to the following: +** +** replace(replace(, '\n', char(10), '\r', char(13)); +** +** Or, if the first character of the input is not "'", then a copy +** of the input is returned. +*/ +static void shellEscapeCrnl( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const char *zText = (const char*)sqlite3_value_text(argv[0]); + if( zText[0]=='\'' ){ + int nText = sqlite3_value_bytes(argv[0]); + int i; + char zBuf1[20]; + char zBuf2[20]; + const char *zNL = 0; + const char *zCR = 0; + int nCR = 0; + int nNL = 0; + + for(i=0; zText[i]; i++){ + if( zNL==0 && zText[i]=='\n' ){ + zNL = unused_string(zText, "\\n", "\\012", zBuf1); + nNL = (int)strlen(zNL); + } + if( zCR==0 && zText[i]=='\r' ){ + zCR = unused_string(zText, "\\r", "\\015", zBuf2); + nCR = (int)strlen(zCR); + } + } + + if( zNL || zCR ){ + int iOut = 0; + i64 nMax = (nNL > nCR) ? nNL : nCR; + i64 nAlloc = nMax * nText + (nMax+12)*2; + char *zOut = (char*)sqlite3_malloc64(nAlloc); + if( zOut==0 ){ + sqlite3_result_error_nomem(context); + return; + } + + if( zNL && zCR ){ + memcpy(&zOut[iOut], "replace(replace(", 16); + iOut += 16; + }else{ + memcpy(&zOut[iOut], "replace(", 8); + iOut += 8; + } + for(i=0; zText[i]; i++){ + if( zText[i]=='\n' ){ + memcpy(&zOut[iOut], zNL, nNL); + iOut += nNL; + }else if( zText[i]=='\r' ){ + memcpy(&zOut[iOut], zCR, nCR); + iOut += nCR; + }else{ + zOut[iOut] = zText[i]; + iOut++; + } + } + + if( zNL ){ + memcpy(&zOut[iOut], ",'", 2); iOut += 2; + memcpy(&zOut[iOut], zNL, nNL); iOut += nNL; + memcpy(&zOut[iOut], "', char(10))", 12); iOut += 12; + } + if( zCR ){ + memcpy(&zOut[iOut], ",'", 2); iOut += 2; + memcpy(&zOut[iOut], zCR, nCR); iOut += nCR; + memcpy(&zOut[iOut], "', char(13))", 12); iOut += 12; + } + + sqlite3_result_text(context, zOut, iOut, SQLITE_TRANSIENT); + sqlite3_free(zOut); + return; + } + } + + sqlite3_result_value(context, argv[0]); +} + /* Flags for open_db(). ** ** The default behavior of open_db() is to exit(1) if the database fails to @@ -4013,6 +4103,8 @@ static void open_db(ShellState *p, int openFlags){ shellModuleSchema, 0, 0); sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p, shellPutsFunc, 0, 0); + sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0, + shellEscapeCrnl, 0, 0); #ifndef SQLITE_NOHAVE_SYSTEM sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, editFunc, 0, 0); @@ -6349,16 +6441,6 @@ static int recoverDatabaseCmd(ShellState *pState){ "GROUP BY pgno, cell;" ); -#if 0 - zSql = "SELECT type ||','|| name ||','|| tbl_name ||','|| rootpage ||','|| sql FROM recovery.schema;"; - shellPrepare(pState->db, &rc, zSql, &pLoop); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ - raw_printf(pState->out, "%s\n", (const char*)sqlite3_column_text(pLoop, 0)); - } - shellFinalize(&rc, pLoop); - return rc; -#endif - /* Open a transaction, then print out all non-virtual, non-"sqlite_%" ** CREATE TABLE statements that extracted from the existing schema. */ if( rc==SQLITE_OK ){ @@ -6398,7 +6480,7 @@ static int recoverDatabaseCmd(ShellState *pState){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); } shellPreparePrintf(pState->db, &rc, &pData, - "SELECT max(field), group_concat(quote(value), ', ') " + "SELECT max(field), group_concat(shell_escape_crnl(quote(value)),', ')" "FROM sqlite_dbdata WHERE pgno IN (" " SELECT pgno FROM recovery.map WHERE root=%d" ")" @@ -6423,7 +6505,7 @@ static int recoverDatabaseCmd(ShellState *pState){ sqlite3_stmt *pStmt = 0; shellPrepare(pState->db, &rc, "SELECT sql, name FROM recovery.schema " - "WHERE (type='table' AND sql LIKE 'create table%') IS NOT TRUE", &pStmt + "WHERE sql NOT LIKE 'create table%'", &pStmt ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zSql = (const char*)sqlite3_column_text(pStmt, 0); From 29e780068b7ffde99f105282fd170de8d94af9b3 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 23 Apr 2019 22:00:39 +0000 Subject: [PATCH 030/132] Make no atttempt to generate VDBE code for VACUUM after a syntax error. FossilOrigin-Name: 930842470da27d72650033ef2c1df413e70f7c40eb46f91027b35f5ee156af38 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vacuum.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index c39a5406fc..14d1e9f274 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\sthe\s--hexdb\sdecoder\soption\sin\sthe\sshell\s(and\salso\sin\sthe\sTCL\ntest\scode)\sso\sthat\sit\sworks\son\ssystems\swhere\ssscanf()\sdoes\snot\srecognize\n"%hhx"\sas\swanting\sto\sdelivery\sresults\sinto\sa\scharacter-size\svariable. -D 2019-04-23T15:30:58.115 +C Make\sno\satttempt\sto\sgenerate\sVDBE\scode\sfor\sVACUUM\safter\sa\ssyntax\serror. +D 2019-04-23T22:00:39.542 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -589,7 +589,7 @@ F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 -F src/vacuum.c 72690ccb6877a88f8473a893cf9f6d7592236f3eebfebfa840b19c708acde574 +F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 @@ -1818,7 +1818,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 69bad9257f8db6a2a761bdd298d972eb48d4f845ec11dedc802ba3bafb979915 -R 77b9435054a3e08f2d59227806ec4211 +P 4258e42d92b0113ba59f407197fc24f21734900e5b02952deed07818be3e3e5d +R 40626349b42f1ecb209e5658c03c5b3b U drh -Z 051f88570fa9bfac9ab4955fc59fefc8 +Z 1ac3dff11ee668e75202966a4ba9668f diff --git a/manifest.uuid b/manifest.uuid index 882147fe53..52172c784b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4258e42d92b0113ba59f407197fc24f21734900e5b02952deed07818be3e3e5d \ No newline at end of file +930842470da27d72650033ef2c1df413e70f7c40eb46f91027b35f5ee156af38 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index 74e6d7df37..e8555ef522 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -106,6 +106,7 @@ void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ Vdbe *v = sqlite3GetVdbe(pParse); int iDb = 0; if( v==0 ) goto build_vacuum_end; + if( pParse->nErr ) goto build_vacuum_end; if( pNm ){ #ifndef SQLITE_BUG_COMPATIBLE_20160819 /* Default behavior: Report an error if the argument to VACUUM is From 49b0572302bd0117210dff47021077b72e8829a9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 24 Apr 2019 00:37:11 +0000 Subject: [PATCH 031/132] Fix for 8-byte alignment asserts that can trigger in some circumstances with 32-bit MSVC. FossilOrigin-Name: 4c02832e0c4351ced9d2391f09ee071c65a74b85a0509bf58f045afeb166f48c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/msvc.h | 5 +++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 14d1e9f274..bb24eb191b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sno\satttempt\sto\sgenerate\sVDBE\scode\sfor\sVACUUM\safter\sa\ssyntax\serror. -D 2019-04-23T22:00:39.542 +C Fix\sfor\s8-byte\salignment\sasserts\sthat\scan\strigger\sin\ssome\scircumstances\swith\s32-bit\sMSVC. +D 2019-04-24T00:37:11.914 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -491,7 +491,7 @@ F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 -F src/msvc.h 4942752b6a253116baaa8de75256c51a459a5e81 +F src/msvc.h 65c892d4c5c768a0f36b1b0c09965f51831665a309507fa0dd156fd9c17e385b F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 @@ -1818,7 +1818,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 4258e42d92b0113ba59f407197fc24f21734900e5b02952deed07818be3e3e5d -R 40626349b42f1ecb209e5658c03c5b3b -U drh -Z 1ac3dff11ee668e75202966a4ba9668f +P 930842470da27d72650033ef2c1df413e70f7c40eb46f91027b35f5ee156af38 +R db45777028714d7f3fa10ea61bc6ed2b +U mistachkin +Z 65565ce83fc26900206c6f2ea5ccb844 diff --git a/manifest.uuid b/manifest.uuid index 52172c784b..4e209f878d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -930842470da27d72650033ef2c1df413e70f7c40eb46f91027b35f5ee156af38 \ No newline at end of file +4c02832e0c4351ced9d2391f09ee071c65a74b85a0509bf58f045afeb166f48c \ No newline at end of file diff --git a/src/msvc.h b/src/msvc.h index 3914b05bcf..471fb5c07b 100644 --- a/src/msvc.h +++ b/src/msvc.h @@ -33,4 +33,9 @@ #pragma warning(disable : 4706) #endif /* defined(_MSC_VER) */ +#if !defined(_WIN64) +#undef SQLITE_4_BYTE_ALIGNED_MALLOC +#define SQLITE_4_BYTE_ALIGNED_MALLOC +#endif /* !defined(_WIN64) */ + #endif /* SQLITE_MSVC_H */ From 8e7e517b686a7ed5f70de5834aaf36708f6b15f2 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 24 Apr 2019 04:53:01 +0000 Subject: [PATCH 032/132] Correction to the #if in the previous check-in. FossilOrigin-Name: 30dc05ac12910d318a737f8d7a0e895e5c42ff4c53472aeebc89f052eac05deb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/msvc.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bb24eb191b..4d382b0b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\s8-byte\salignment\sasserts\sthat\scan\strigger\sin\ssome\scircumstances\swith\s32-bit\sMSVC. -D 2019-04-24T00:37:11.914 +C Correction\sto\sthe\s#if\sin\sthe\sprevious\scheck-in. +D 2019-04-24T04:53:01.938 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -491,7 +491,7 @@ F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 -F src/msvc.h 65c892d4c5c768a0f36b1b0c09965f51831665a309507fa0dd156fd9c17e385b +F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 @@ -1818,7 +1818,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 930842470da27d72650033ef2c1df413e70f7c40eb46f91027b35f5ee156af38 -R db45777028714d7f3fa10ea61bc6ed2b +P 4c02832e0c4351ced9d2391f09ee071c65a74b85a0509bf58f045afeb166f48c +R eddcb1b6b037b4a709f787bfa2928a18 U mistachkin -Z 65565ce83fc26900206c6f2ea5ccb844 +Z e266579bf5292eaae26d35fbb7b56613 diff --git a/manifest.uuid b/manifest.uuid index 4e209f878d..b394645701 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c02832e0c4351ced9d2391f09ee071c65a74b85a0509bf58f045afeb166f48c \ No newline at end of file +30dc05ac12910d318a737f8d7a0e895e5c42ff4c53472aeebc89f052eac05deb \ No newline at end of file diff --git a/src/msvc.h b/src/msvc.h index 471fb5c07b..f174227330 100644 --- a/src/msvc.h +++ b/src/msvc.h @@ -33,9 +33,9 @@ #pragma warning(disable : 4706) #endif /* defined(_MSC_VER) */ -#if !defined(_WIN64) +#if defined(_MSC_VER) && !defined(_WIN64) #undef SQLITE_4_BYTE_ALIGNED_MALLOC #define SQLITE_4_BYTE_ALIGNED_MALLOC -#endif /* !defined(_WIN64) */ +#endif /* defined(_MSC_VER) && !defined(_WIN64) */ #endif /* SQLITE_MSVC_H */ From 04687f9e03f3058d93f91350729ec85e5dda2c04 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Apr 2019 15:13:02 +0000 Subject: [PATCH 033/132] Fix an error in fts3_write.c allowing a corrupt database to cause a crash. FossilOrigin-Name: 6e4a5f22811bcd1485e27073ec96821d448b91b6d1ff1659cc3772449d19a762 --- ext/fts3/fts3_write.c | 4 +- manifest | 16 +-- manifest.uuid | 2 +- test/fts3corrupt4.test | 242 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 253 insertions(+), 11 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 31d6b5f55f..5d1198421b 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -3754,7 +3754,7 @@ static int nodeReaderNext(NodeReader *p){ } p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); - if( nPrefix>p->iOff || nSuffix>p->nNode-p->iOff ){ + if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff ){ return FTS_CORRUPT_VTAB; } blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); @@ -3773,7 +3773,7 @@ static int nodeReaderNext(NodeReader *p){ } } - assert( p->iOff<=p->nNode ); + assert_fts3_nc( p->iOff<=p->nNode ); return rc; } diff --git a/manifest b/manifest index 4d382b0b6d..6123870a76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correction\sto\sthe\s#if\sin\sthe\sprevious\scheck-in. -D 2019-04-24T04:53:01.938 +C Fix\san\serror\sin\sfts3_write.c\sallowing\sa\scorrupt\sdatabase\sto\scause\sa\scrash. +D 2019-04-24T15:13:02.760 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -99,7 +99,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 1d814248a42ddecc6ebd8d9e09673228de2ff5ae1410b8b7f1b22e04b7299fdf +F ext/fts3/fts3_write.c 23b932879837fdf375e1722f0491260bfbb66e11b9bb03f0707eb194bb2704b5 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -923,7 +923,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test af68ede153cbeff7309f7da2f9d8fd12a01f7e1debb03eb748c302079ac5ae05 +F test/fts3corrupt4.test 470d1522d5539fe259f1f9087d420d393a093e340c1f30ded35d40d821b1234a F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338 F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de @@ -1818,7 +1818,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 4c02832e0c4351ced9d2391f09ee071c65a74b85a0509bf58f045afeb166f48c -R eddcb1b6b037b4a709f787bfa2928a18 -U mistachkin -Z e266579bf5292eaae26d35fbb7b56613 +P 30dc05ac12910d318a737f8d7a0e895e5c42ff4c53472aeebc89f052eac05deb +R 2d06dfe9cbc2f258b090816d78bc538f +U dan +Z e5f9a6662908213b0aeb42f0179b5bf4 diff --git a/manifest.uuid b/manifest.uuid index b394645701..117029d59b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30dc05ac12910d318a737f8d7a0e895e5c42ff4c53472aeebc89f052eac05deb \ No newline at end of file +6e4a5f22811bcd1485e27073ec96821d448b91b6d1ff1659cc3772449d19a762 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index 12a3dfa0aa..43e0ffd7f5 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -3915,5 +3915,247 @@ do_catchsql_test 23.1 { SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j'; } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 24.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-369d042958c29b.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 03 10 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...............! +| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~.......... +| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl +| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB +| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3...... +| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir +| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE +| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi +| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER +| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta +| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER +| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc +| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl +| 3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74 ock INTEGER,root +| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE +| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1. +| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit +| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s +| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir +| 3760: 06 0f c7 00 08 00 10 00 00 66 04 07 17 23 23 01 .........f...##. +| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen +| 3792: 64 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 dst1_segments.CR +| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s +| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid +| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY +| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB +| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet +| 3888: 31 4f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1Ocontentt1_cont +| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE +| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do +| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d cid INTEGER PR9M +| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a', +| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 26 0b 48 0e 0f d8 0f af 0f 86 0f 74 ....&.H........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0e 94 03 28 0d 4f 0d 35 0d 1b 05 0b .......(.O.5.... +| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. +| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00 .........?%..r.. +| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5. +| 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42 4.0 20160609 DUB +| 2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54 UG ENA.|E DBSTAT +| 2944: e4 d1 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53 ..TAB ENABLE FTS +| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN +| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA +| 2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLE JSON1 ENABLE +| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE +| 3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 BTREE MAX MEMORY +| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c =50000000 OLIT L +| 3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48 OAC EXTENSION!TH +| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22 DSAKu=0XMOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d ..%..THREADSAFF= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 52 49 4f IT LOAD EXTENRIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 42 b8 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MB. MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 0d a5 0f 19 45 4e 41 42 INARY.......ENAB +| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE. +| 3408: 19 1c 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 14 05 01 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN.BLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17 LE JSO>1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 40 42 4c 45 20 4a 53 4f ...%..EN@BLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 c9 29 e8 19 46 4e 41 42 4c NARY....)..FNABL +| 3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45 H.GEOPOLYXNtCASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 30 46 54 53 35 58 42 49 ..ENABLE0FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0e 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 42 42 4c 45 20 44 42 53 ...1..ENBBLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 4a 4d 11 06 TAT VTABXRTRJM.. +| 3920: 05 f0 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 16 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 06 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e OMPIKER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d 0 201606@9X)TRIM +| page 4 offset 12288 +| 0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 01 00 00 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................ +| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253 +| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606 +| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5 +| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%. +| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%... +| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu +| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%. +| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%... +| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%... +| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso +| 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%.. +| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6e 6f 72 79 ..max.%....enory +| 3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04 .%.....ysM.%.... +| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree. +| 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe. +| 3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P. +| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0 +| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 09 ................ +| 3280: 51 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 Q....20160609... +| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4...... +| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5......... +| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000...... +| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<... +| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00 ................ +| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................ +| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi +| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67 ler............g +| 3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 .stat........... +| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug........... +| 3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02 .eno.le?........ +| 3488: b0 01 02 00 01 02 00 11 02 00 01 02 00 01 02 00 ................ +| 3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 01 ................ +| 3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02 ..Q............. +| 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73 n............fts +| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5.. +| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc... +| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09 .........eopsly. +| 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1 +| 3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64 ............load +| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max. +| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory +| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5 +| 3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca +| 3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02 se<............. +| 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................ +| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................ +| 3776: 04 6f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 .omit........... +| 3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00 .rtree.......... +| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<........... +| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................ +| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................ +| 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe... +| 3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04 .........vtab... +| 3904: 00 01 04 00 01 03 ff ff 01 78 b4 01 01 01 01 02 .........x...... +| 3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................ +| 3952: 01 01 02 00 01 01 01 07 30 01 01 01 02 00 01 01 ........0....... +| 3968: 01 02 00 11 01 01 02 00 01 01 01 02 00 11 01 01 ................ +| 3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01 ................ +| 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 4048: 01 02 00 01 01 09 c2 00 01 01 01 02 00 01 01 01 ................ +| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00 ................ +| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................ +| page 7 offset 24576 +| 0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7 ................ +| 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto +| 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge +| 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. +| end crash-369d042958c29b.db +}]} {} + +do_catchsql_test 24.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) + INSERT INTO t1(a) SELECT randomblob(2829) FROM c; +} {0 {}} + +do_catchsql_test 24.2 { + UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h'; +} {0 {}} + +do_catchsql_test 24.3 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) + INSERT INTO t1(a) SELECT randomblob(2829) FROM c; +} {0 {}} + +do_catchsql_test 24.4 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT null< Date: Wed, 24 Apr 2019 15:57:25 +0000 Subject: [PATCH 034/132] Fix a problem in fts5 where a corrupt position list could lead to a buffer overwrite. FossilOrigin-Name: 516ca8945150bdc1363603e234be5f3f4a3861f581d7cc9455da3e87b9974309 --- ext/fts5/fts5_buffer.c | 6 +- ext/fts5/test/fts5corrupt3.test | 209 ++++++++++++++++++++++++++++++++ manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 222 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index b3d4984128..84bdf63189 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -178,7 +178,11 @@ int sqlite3Fts5PoslistNext64( i64 iOff = *piOff; int iVal; fts5FastGetVarint32(a, i, iVal); - if( iVal==1 ){ + if( iVal<=1 ){ + if( iVal==0 ){ + *pi = i; + return 0; + } fts5FastGetVarint32(a, i, iVal); iOff = ((i64)iVal) << 32; fts5FastGetVarint32(a, i, iVal); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index f7d3fd25a8..6c3767bbc0 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -8128,6 +8128,215 @@ do_catchsql_test 57.1 { INSERT INTO t1(t1) VALUES('optimize') } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 58.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 24576 pagesize 4096 filename crash-5a5acd0ab42d31.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53 ...............S +| 112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00 .....3.......... +| 3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22 ................ +| 3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62 ......1tablebbbb +| 3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62 .CREATE TABLE bb +| 3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65 (a)V.......table +| 3648: 74 31 5f 63 2a 6e 66 69 68 74 31 5f 63 6f 6e 66 t1_c*nfiht1_conf +| 3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 ig.CREATE TABLE +| 3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52 't1_config'(k PR +| 3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49 IMARY KEY, v) WI +| 3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21 THOUT ROWID[...! +| 3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 73 73 !...tablet1_doss +| 3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52 izet1_docsize.CR +| 3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64 EATE TABLE 't1_d +| 3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47 ocsize'(id INTEG +| 3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81 sz BLOB)i....... +| 3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69 -tablet1_idxt1_i +| 3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 dx.CREATE TABLE +| 3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20 't1_idx'(segid, +| 3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d term, pgno, PRIM +| 3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74 ARY KEY(segid, t +| 3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f erm)) WITHOUT RO +| 3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c WIDU........tabl +| 3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02 et1_datat1_data. +| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 CREATE TABLE 't1 +| 3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45 _data'(id INTEGE +| 3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 R PRIMARY KEY, b +| 4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11 lock BLOB)T..... +| 4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41 ...tablet1t1CREA +| 4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45 TE VIRTUAL TABLE +| 4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61 t1 USING fts5(a +| 4064: 2c 62 2c 70 72 65 66 69 78 3d 22 32 2c 32 2c 33 ,b,prefix=.2,2,3 +| 4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29 ,4., content=..) +| page 2 offset 4096 +| 0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4 ..j.7.L....L.... +| 16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ae ...m.K.,........ +| 32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5 ...l.K.)........ +| 48: 0d 97 0d 76 0d 54 0d 30 fd 15 0c f3 0c d3 0c b5 ...v.T.0........ +| 64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0 ...s.T.2........ +| 80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 0a cc 0a ad ...~.H.......... +| 96: 0a 8c 0a 6d 0a 4d 0a 2b 0a 0c 00 00 00 00 00 00 ...m.M.+........ +| 2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00 ................ +| 2384: 30 00 00 00 9c 01 03 35 00 03 01 01 12 02 01 12 0......5........ +| 2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00 ............>... +| 2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68 ....4tabl.....wh +| 2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c er.............< +| 2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e .....4fts4.....n +| 2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03 umb............. +| 2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04 .<.....3the..... +| 2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80 ..whe........... +| 2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01 ...<.....3num... +| 2528: 01 05 01 03 74 61 62 05 62 03 04 0a 19 8c 80 80 ....tab.b....... +| 2544: 80 80 0c 03 00 38 00 00 00 14 03 39 a7 68 03 02 .....8.....9.h.. +| 2560: 04 10 04 33 66 74 73 03 02 02 04 07 18 8c 80 80 ...3fts......... +| 2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02 .....6.....2ta.. +| 2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80 ...h............ +| 2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01 ....<.....2nu... +| 2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80 ....of.......... +| 2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03 ......8.....2ft. +| 2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80 ....is.......... +| 2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08 ......6.....1t.. +| 2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80 ......w......... +| 2704: 80 80 07 03 00 3a ff 00 00 15 02 31 6e 03 08 01 .....:.....1n... +| 2720: 01 02 05 01 01 6f 03 06 01 01 06 04 09 18 8c 80 .....o.......... +| 2736: 80 80 80 06 03 00 36 00 00 00 13 04 02 31 66 03 ......6......1f. +| 2752: 02 01 f1 01 69 03 06 01 01 03 05 06 1c 8c 80 80 ....i........... +| 2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03 .....>.....0the. +| 2784: 06 01 01 14 01 05 77 68 65 72 65 03 02 04 0a 15 ......where..... +| 2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06 ........0....... +| 2816: 06 30 74 61 62 6c cc 03 02 03 07 1c 8c 80 80 80 .0tabl.......... +| 2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65 ....>.....0numbe +| 2848: 72 03 06 01 01 05 01 02 6f 66 02 06 04 0d 13 8c r.......of...... +| 2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02 .......,........ +| 2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03 0n.............. +| 2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03 .<.....0fts4aux. +| 2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00 ....is........*. +| 2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88 .....$.......... +| 2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80 ................ +| 2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77 ......>.....4row +| 2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b s.......ther.... +| 2992: 15 88 80 80 80 80 10 03 00 3e 10 00 00 11 02 01 .........>...... +| 3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80 ...4betw........ +| 3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77 .....<......3row +| 3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88 .......the...... +| 3056: 80 80 80 80 0e 03 05 0c 00 00 00 16 01 01 02 04 ................ +| 3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08 3are.....bet.... +| 3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 03 32 .........<.....2 +| 3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06 th........3and.. +| 3120: 04 01 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16 ...........<.... +| 3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01 .2in.......ro... +| 3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00 .............6.. +| 3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02 ....2ar.....be.. +| 3184: 04 05 07 1b 88 80 bf 80 80 0a 03 00 3c 00 00 00 ............<... +| 3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02 ..1t........2an. +| 3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00 ..............8. +| 3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06 ....1n.......r.. +| 3248: 01 01 05 03 08 17 88 80 80 80 80 08 03 00 34 00 ..............4. +| 3264: 01 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01 ....1b.....i.... +| 3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00 ............8... +| 3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01 ...12.....a..... +| 3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00 ............<... +| 3328: 16 06 30 74 68 65 72 65 02 12 02 00 02 31 31 02 ..0there.....11. +| 3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00 ..............0. +| 3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 71 01 07 .......0the..q.. +| 3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01 ..........>..... +| 3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73 ...0n.......rows +| 3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00 .............<.. +| 3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02 ...0between..... +| 3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a in.............: +| 3456: 08 f0 00 15 04 30 61 6e 64 02 06 01 01 02 02 02 .....0and....... +| 3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00 re.............. +| 3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32 4.....01.......2 +| 3504: 02 02 07 04 08 08 84 80 80 80 80 12 03 00 16 00 ................ +| 3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00 .............<.. +| 3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65 ...4tabl.......e +| 3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c rm.............< +| 3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70 .....4each.....p +| 3584: 72 65 73 01 02 05 04 09 1a 84 80 80 80 80 0f 03 res............. +| 3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02 .:.....3ter..... +| 3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e he.............. +| 3632: 03 00 3c 00 00 00 16 04 33 70 72 65 01 02 05 01 ..<.....3pre.... +| 3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80 .tab............ +| 3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02 ....:.....3for.. +| 3680: 02 02 02 74 73 01 06 01 01 04 03 f8 1b 84 80 80 ...ts........... +| 3696: 80 80 0c 03 00 3c 00 00 00 16 03 32 74 68 01 06 .....<.....2th.. +| 3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84 .....3eac....... +| 3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 .......6.....2ta +| 3744: 01 06 01 01 05 02 01 65 00 02 04 04 09 19 84 80 .......e........ +| 3760: 80 80 80 0a 03 10 38 00 00 00 14 03 32 69 6e 01 ......8.....2in. +| 3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80 ......pr........ +| 3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01 ......6.....2fo. +| 3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80 ....t........... +| 3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04 .....<.....1t... +| 3840: 01 00 03 04 00 03 32 65 61 01 02 03 04 0a 17 84 ......2ea....... +| 3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01 .......4.....1i. +| 3872: 06 01 01 02 de 01 70 01 02 05 04 08 18 84 80 80 ......p......... +| 3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03 .....6.....1e... +| 3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80 ..f............. +| 3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01 ....<.....0term. +| 3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80 ....he.......... +| 3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 74 61 62 ............0tab +| 3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03 le.............. +| 3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74 .0......0present +| 4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00 .............<.. +| 4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e ...0fts.......in +| 4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a ...............: +| 4048: 00 00 00 15 05 30 65 61 63 68 00 f2 03 01 03 66 .....0each.....f +| 4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00 or.............. +| 4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04 ................ +| page 3 offset 8192 +| 0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1 ....2.O......... +| 16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f c1 0f a9 0f a0 ................ +| 32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f .........x.q.h._ +| 48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13 .V.M.A.8./.&.... +| 64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d7 0e cd ................ +| 80: 0e c3 0e ba 0e b0 0e a8 0e 9f 0e 96 0e 8e 0e 85 ................ +| 3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 ................ +| 3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e .....4t ......4. +| 3680: 09 04 01 12 34 03 33 74 68 1c 08 04 01 10 01 03 ....4.3th....... +| 3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10 3n.......2w..... +| 3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04 ..2t.......2n... +| 3728: 01 0e 01 03 32 12 08 04 01 0f f1 03 31 74 10 08 ....2.......1t.. +| 3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 30 fc .....1n.......0. +| 3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03 ......0th....... +| 3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01 0t.......0nu.... +| 3792: 10 01 03 30 6e 04 06 04 01 0c 01 05 52 08 04 01 ...0n.......R... +| 3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04 ...4r.......4 .. +| 3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72 ....3r.......3ar +| 3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 b3 02 .......2t....... +| 3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01 2i.......2ar.... +| 3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08 ...1t.......1n.. +| 3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32 .....1b.......12 +| 3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01 .......0ther.... +| 3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08 ...0t.......0n.. +| 3936: 04 01 10 01 02 30 62 06 09 04 01 10 01 02 30 61 .....0b.......0a +| 3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22 .............4t. +| 3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e .....4 .....3te. +| 3984: 07 04 09 10 01 33 70 1c 07 f4 09 11 01 33 66 1a .....3p......3f. +| 4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 e4 .....2th......2. +| 4016: 16 07 04 09 10 01 32 69 14 07 04 09 10 01 32 66 ......2i......2f +| 4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69 ......1t......1i +| 4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65 ......1......0te +| 4064: 0a 07 04 09 10 01 30 74 08 00 00 00 00 00 00 00 ......0t........ +| page 4 offset 12288 +| 4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10 ................ +| 4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04 ................ +| page 5 offset 16384 +| 0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70 ...............p +| 4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04 gsz.....version. +| page 6 offset 20480 +| 4080: 00 00 23 03 02 01 03 03 02 00 00 00 00 00 00 00 ..#............. +| end crash-5a5acd0ab42d31.db +}]} {} + +do_execsql_test 58.1 { + SELECT * FROM t1('t*'); +} {{} {} {} {} {} {}} sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 6123870a76..fa4ef2e805 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\sin\sfts3_write.c\sallowing\sa\scorrupt\sdatabase\sto\scause\sa\scrash. -D 2019-04-24T15:13:02.760 +C Fix\sa\sproblem\sin\sfts5\swhere\sa\scorrupt\sposition\slist\scould\slead\sto\sa\sbuffer\soverwrite. +D 2019-04-24T15:57:25.189 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -112,7 +112,7 @@ F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7 F ext/fts5/fts5Int.h 5c26dce0ec9272fca726c6fddb92f634d0c912d4ca170330270d488a94b80416 F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa -F ext/fts5/fts5_buffer.c 7d91caa0d862079d787660ec405d2fda6fd4f206d95b870dc7adc3b8f66a400f +F ext/fts5/fts5_buffer.c 43eecc62f191138815211c411481ef327e1d8b555b212b3039e631e7ecc2fb1a F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test d3a07e6fe172ade03310af6056cae45ac3d2880a9bba187908eba735bd170742 +F ext/fts5/test/fts5corrupt3.test fcf7963940e85d4d2e581b7804280215759377d94c03c4dcd5ed35e596b15989 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -1818,7 +1818,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 30dc05ac12910d318a737f8d7a0e895e5c42ff4c53472aeebc89f052eac05deb -R 2d06dfe9cbc2f258b090816d78bc538f +P 6e4a5f22811bcd1485e27073ec96821d448b91b6d1ff1659cc3772449d19a762 +R e4d9c0f0c0cba3c6b8fed93c5d3236d0 U dan -Z e5f9a6662908213b0aeb42f0179b5bf4 +Z a6576a71cacc25b1ec7ae9c9dd8ac9e4 diff --git a/manifest.uuid b/manifest.uuid index 117029d59b..ba745a62cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e4a5f22811bcd1485e27073ec96821d448b91b6d1ff1659cc3772449d19a762 \ No newline at end of file +516ca8945150bdc1363603e234be5f3f4a3861f581d7cc9455da3e87b9974309 \ No newline at end of file From bebea908b89552e9f744590b08a2d98df311b0af Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Apr 2019 16:13:52 +0000 Subject: [PATCH 035/132] Fix another instance in fts3 where a corrupt record can cause a buffer overflow. FossilOrigin-Name: e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550 --- ext/fts3/fts3_write.c | 2 +- manifest | 14 +-- manifest.uuid | 2 +- test/fts3corrupt4.test | 244 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 253 insertions(+), 9 deletions(-) diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 5d1198421b..8ad48a0125 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -3754,7 +3754,7 @@ static int nodeReaderNext(NodeReader *p){ } p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &nSuffix); - if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff ){ + if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){ return FTS_CORRUPT_VTAB; } blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); diff --git a/manifest b/manifest index fa4ef2e805..a87d4a6716 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sfts5\swhere\sa\scorrupt\sposition\slist\scould\slead\sto\sa\sbuffer\soverwrite. -D 2019-04-24T15:57:25.189 +C Fix\sanother\sinstance\sin\sfts3\swhere\sa\scorrupt\srecord\scan\scause\sa\sbuffer\soverflow. +D 2019-04-24T16:13:52.386 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -99,7 +99,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_unicode.c 4b9af6151c29b35ed09574937083cece7c31e911f69615e168a39677569b684d F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 23b932879837fdf375e1722f0491260bfbb66e11b9bb03f0707eb194bb2704b5 +F ext/fts3/fts3_write.c 766cfc4140c5609c5178b087697ccc5f5650bd915f3c6718f1547b3e994f674b F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 @@ -923,7 +923,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 470d1522d5539fe259f1f9087d420d393a093e340c1f30ded35d40d821b1234a +F test/fts3corrupt4.test 72d8f1269f3ee1eb76fdf6133618225f7fc1abeece2d02456b292c90c822d78e F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338 F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de @@ -1818,7 +1818,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 6e4a5f22811bcd1485e27073ec96821d448b91b6d1ff1659cc3772449d19a762 -R e4d9c0f0c0cba3c6b8fed93c5d3236d0 +P 516ca8945150bdc1363603e234be5f3f4a3861f581d7cc9455da3e87b9974309 +R 7412822ff3a00a816140932f44ebe070 U dan -Z a6576a71cacc25b1ec7ae9c9dd8ac9e4 +Z d1d0f4067be8582800abaf723a648e76 diff --git a/manifest.uuid b/manifest.uuid index ba745a62cc..0edb6004df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -516ca8945150bdc1363603e234be5f3f4a3861f581d7cc9455da3e87b9974309 \ No newline at end of file +e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index 43e0ffd7f5..1b85abba40 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -4156,6 +4156,250 @@ do_catchsql_test 24.5 { do_catchsql_test 24.7 { INSERT INTO t1(t1) SELECT x FROM t2; } {1 {database disk image is malformed}} + +#------------------------------------------------------------------------- +#------------------------------------------------------------------------- +reset_db +do_test 25.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-dde9e76ed8ab2d.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 03 10 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0e b1 00 06 0d a4 00 0f 8d 0f 21 ...............! +| 112: 0e b9 0d c8 0e 7e 0d a4 00 00 00 00 00 00 00 00 .....~.......... +| 3488: 00 00 00 00 22 07 06 17 11 11 01 31 74 61 62 6c ...........1tabl +| 3504: 65 74 32 74 32 07 43 52 45 41 54 45 20 54 41 42 et2t2.CREATE TAB +| 3520: 4c 45 20 74 32 28 78 29 81 33 05 07 17 1f 1f 01 LE t2(x).3...... +| 3536: 82 35 74 61 62 6c 65 74 31 5f 73 65 67 64 69 72 .5tablet1_segdir +| 3552: 74 31 5f 73 65 67 64 69 72 05 43 52 45 41 54 45 t1_segdir.CREATE +| 3568: 20 54 41 42 4c 45 20 27 74 31 5f 73 65 67 64 69 TABLE 't1_segdi +| 3584: 72 27 28 6c 65 76 65 6c 20 49 4e 54 45 47 45 52 r'(level INTEGER +| 3600: 2c 69 64 78 20 49 4e 54 45 47 45 52 2c 73 74 61 ,idx INTEGER,sta +| 3616: 72 74 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45 52 rt_block INTEGER +| 3632: 2c 6c 65 61 76 65 73 5f 65 6e 64 5f 62 6c 6f 63 ,leaves_end_bloc +| 3648: 6b 20 49 4e 54 45 47 45 52 2c 65 6e 64 5f 62 6c k INTEGER,end_bl +| 3664: 6f 63 6b 20 49 4e 54 45 47 45 52 2c 72 6f 6f 74 ock INTEGER,root +| 3680: 20 42 4c 4f 42 2c 50 52 49 4d 41 52 59 20 4b 45 BLOB,PRIMARY KE +| 3696: 59 28 6c 65 76 65 6c 2c 20 69 64 78 29 29 31 06 Y(level, idx))1. +| 3712: 06 17 45 1f 01 00 69 6e 64 65 78 73 71 6c 69 74 ..E...indexsqlit +| 3728: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 73 e_autoindex_t1_s +| 3744: 65 67 64 69 72 5f 31 74 31 5f 73 65 67 64 69 72 egdir_1t1_segdir +| 3760: 06 0f c7 00 08 00 00 00 00 66 04 07 17 23 23 01 .........f...##. +| 3776: 81 13 74 61 62 6c 65 74 31 5f 73 65 67 6d 65 6e ..tablet1_segmen +| 3792: 64 73 74 31 5f 73 65 67 6d 65 6e 74 73 04 43 52 dst1_segments.CR +| 3808: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 73 EATE TABLE 't1_s +| 3824: 65 67 6d 65 6e 74 73 27 28 62 6c 6f 63 6b 69 64 egments'(blockid +| 3840: 20 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 INTEGER PRIMARY +| 3856: 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 KEY, block BLOB +| 3872: 29 6a 03 07 17 21 21 01 81 1f 74 61 62 6c 65 74 )j...!!...tablet +| 3888: 31 5f 63 6f 6e 74 65 6e 74 74 31 5f 63 6f 6e 74 1_contentt1_cont +| 3904: 65 6e 74 03 43 52 45 41 54 45 20 54 41 42 4c 45 ent.CREATE TABLE +| 3920: 20 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64 6f 't1_content'(do +| 3936: 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 39 4d cid INTEGER PR9M +| 3952: 41 52 59 20 4b 45 59 2c 20 27 63 30 61 27 2c 20 ARY KEY, 'c0a', +| 3968: 27 63 31 62 27 2c 20 27 63 32 63 27 29 38 02 06 'c1b', 'c2c')8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33 LE t1 USING fts3 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 26 0b 48 0e 0f d8 0f af 0f 86 0f 74 ....&.H........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0e 94 03 28 0d 4f 0d 35 0d 1b 05 0b .......(.O.5.... +| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. +| 2880: 00 00 00 00 00 00 00 00 81 3f 25 06 00 72 7f 00 .........?%..r.. +| 2896: 00 43 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e .COMPILER=gcc-5. +| 2912: 34 2e 30 20 32 30 31 36 30 36 30 39 20 44 55 42 4.0 20160609 DUB +| 2928: 55 47 20 45 4e 41 e4 7c 45 20 44 42 53 54 41 54 UG ENA.|E DBSTAT +| 2944: e4 46 54 41 42 20 45 4e 41 42 4c 45 20 46 54 53 .FTAB ENABLE FTS +| 2960: 34 20 45 4e 41 42 4c 45 20 46 54 53 35 20 45 4e 4 ENABLE FTS5 EN +| 2976: 41 42 4c 45 20 47 45 4f 50 4f 4c 59 20 45 4e 41 ABLE GEOPOLY ENA +| 2992: 42 4c 45 20 4a 53 4f 4e 31 20 45 4e 41 42 4c 45 BLE JSON1 ENABLE +| 3008: 20 4d 45 4d 53 59 53 35 20 45 4e 41 42 4c 45 20 MEMSYS5 ENABLE +| 3024: 42 54 52 45 45 20 4d 41 58 20 4d 45 4d 4f 52 59 BTREE MAX MEMORY +| 3040: 3d 35 30 30 30 30 30 30 30 20 4f 4c 49 54 20 4c =50000000 OLIT L +| 3056: 4f 41 43 20 45 58 54 45 4e 53 49 4f 4e 21 54 48 OAC EXTENSION!TH +| 3072: 52 45 41 44 53 41 46 45 3d 30 18 24 05 00 25 0f READSAFE=0.$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 4b 75 3d 30 58 4d 4f 43 41 53 45 17 22 DSAKu=0XMOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 46 3d ..%..THREADSAFF= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 52 49 4f IT LOAD EXTENRIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 42 b8 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MB. MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 0d a5 0f 19 45 4e 41 42 INARY.......ENAB +| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE. +| 3408: 19 1c 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 14 05 01 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 12 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN.BLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 09 d9 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 3e 31 58 4e 4f 43 41 53 45 17 LE JSO>1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 40 42 4c 45 20 4a 53 4f ...%..EN@BLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 82 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 c9 29 e8 19 46 4e 41 42 4c NARY....)..FNABL +| 3632: 48 c0 47 45 4f 50 4f 4c 59 58 4e 74 43 41 53 45 H.GEOPOLYXNtCASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 30 46 54 53 35 58 42 49 ..ENABLE0FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0e 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 42 42 4c 45 20 44 42 53 ...1..ENBBLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 4a 4d 11 06 TAT VTABXRTRJM.. +| 3920: 05 f0 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0e 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 16 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 06 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4b 45 52 3d 67 63 63 2d 35 2e 34 2e OMPIKER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 40 39 58 29 54 52 49 4d 0 201606@9X)TRIM +| page 4 offset 12288 +| 0: 0d 00 10 00 00 10 00 00 00 00 00 00 00 01 00 00 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 02 0b a0 00 0c ad 0b a0 00 00 00 00 ................ +| 2976: 82 0a 02 08 08 09 08 08 17 84 06 30 20 32 35 33 ...........0 253 +| 2992: 00 01 30 04 25 06 1b 00 00 08 32 30 31 36 30 36 ..0.%.....201606 +| 3008: 30 39 03 25 07 00 00 01 34 03 25 05 00 00 01 35 09.%....4.%....5 +| 3024: 03 25 04 00 01 07 30 30 30 30 30 30 30 03 25 1a .%....0000000.%. +| 3040: 00 00 08 63 6f 6d 70 69 6c 65 72 03 25 02 00 00 ...compiler.%... +| 3056: 06 64 62 73 74 61 74 03 25 0a 00 01 04 65 62 75 .dbstat.%....ebu +| 3072: 67 03 25 08 00 00 06 65 6e 61 62 6c 65 09 25 09 g.%....enable.%. +| 3088: 05 04 04 04 04 04 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3104: 6e 03 25 1d 00 00 04 66 74 73 34 03 25 0d 00 03 n.%....fts4.%... +| 3120: 01 35 03 25 0f 00 00 03 67 63 63 03 25 03 00 01 .5.%....gcc.%... +| 3136: 06 65 6f 70 6f 6c 79 03 25 11 00 00 05 6a 73 6f .eopoly.%....jso +| 3152: 6e 31 03 25 13 00 00 04 6c 6f 61 64 03 25 1c 00 n1.%....load.%.. +| 3168: 00 03 6d 61 78 03 25 18 00 01 05 65 6e 6f 72 79 ..max.%....enory +| 3184: 03 25 19 00 03 04 ce 79 73 4d 03 25 15 00 00 04 .%.....ysM.%.... +| 3200: 6f 6d 69 74 03 25 1b 00 00 05 72 74 72 65 65 03 omit.%....rtree. +| 3216: 25 17 00 00 0a 74 68 72 65 61 64 73 61 66 65 03 %....threadsafe. +| 3232: 25 0e 00 00 04 76 74 61 62 03 25 0b 00 86 50 01 %....vtab.%...P. +| 3248: 08 08 08 08 08 17 8d 12 30 20 38 33 35 00 01 30 ........0 835..0 +| 3264: 12 01 06 00 01 06 00 01 06 00 1f 03 00 01 03 09 ................ +| 3280: 51 03 00 00 08 32 30 31 36 30 36 30 39 09 01 07 Q....20160609... +| 3296: 00 01 07 00 01 07 00 00 01 34 09 01 05 00 01 05 .........4...... +| 3312: 00 01 05 00 00 01 35 09 01 04 00 01 04 00 01 04 ......5......... +| 3328: 00 01 07 30 30 30 30 30 30 30 09 1c 04 00 01 04 ...0000000...... +| 3344: 00 01 04 00 00 06 62 69 6e 61 72 79 3c 03 01 02 ......binary<... +| 3360: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3376: 00 03 01 02 02 00 02 f1 02 02 00 03 01 02 02 00 ................ +| 3392: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 ................ +| 3408: 01 02 02 00 03 01 02 02 00 00 08 63 6f 6d 70 69 ...........compi +| 3424: 6c 65 72 09 01 02 00 01 02 00 01 02 00 00 06 67 ler............g +| 3440: d2 73 74 61 74 09 07 03 00 01 03 00 01 03 00 01 .stat........... +| 3456: 04 65 62 75 67 09 04 02 00 01 02 00 01 02 00 00 .ebug........... +| 3472: 06 65 6e 6f 82 6c 65 3f 07 02 00 01 02 00 01 02 .eno.le?........ +| 3488: b0 01 02 00 01 02 00 11 02 00 01 02 00 01 02 00 ................ +| 3504: 01 02 00 01 02 00 01 02 00 01 a6 00 01 02 00 01 ................ +| 3520: 02 05 51 02 00 01 02 00 01 02 00 01 02 00 01 02 ..Q............. +| 3536: 00 01 02 00 01 02 00 01 08 78 74 65 6e 73 69 6f .........xtensio +| 3552: 6e 09 1f 04 00 01 04 00 00 04 00 00 04 66 74 73 n............fts +| 3568: 34 09 0a 03 00 01 03 00 01 03 00 03 01 35 09 0d 4............5.. +| 3584: 03 00 01 03 00 01 03 00 00 03 67 63 63 09 01 03 ..........gcc... +| 3600: 00 01 03 00 01 03 00 01 06 65 6f 70 73 6c 79 09 .........eopsly. +| 3616: 10 03 00 01 03 00 01 03 00 00 05 6a 73 6f 6e 31 ...........json1 +| 3632: 09 13 03 00 01 03 00 01 03 00 00 04 6c 6f 61 64 ............load +| 3648: 09 1f 03 00 01 03 00 01 03 00 00 03 6d 61 78 09 ............max. +| 3664: 1c 02 00 01 02 00 01 02 00 01 05 65 6d 6f 72 79 ...........emory +| 3680: 09 1c 03 00 01 03 00 01 03 00 03 04 73 79 73 35 ............sys5 +| 3696: 09 16 03 00 01 03 00 01 03 00 00 06 6e 6f 63 61 ............noca +| 3712: 73 65 3c 02 01 02 02 00 03 01 12 02 00 03 01 02 se<............. +| 3728: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3744: 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 ................ +| 3760: 03 01 02 02 00 03 01 02 02 00 03 01 02 02 00 00 ................ +| 3776: 0e 9f 6d 69 74 09 1f 02 00 01 02 00 01 02 00 00 ..mit........... +| 3792: 05 72 74 72 65 65 09 19 03 00 01 03 00 01 03 00 .rtree.......... +| 3808: 03 02 69 6d 3c 01 01 02 02 00 03 01 02 02 00 03 ..im<........... +| 3824: 01 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 ................ +| 3840: 02 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 ................ +| 3856: 02 00 03 01 02 02 00 03 01 02 02 00 03 01 02 02 ................ +| 3872: 00 00 0a 74 68 72 65 61 64 73 61 66 65 09 22 02 ...threadsafe... +| 3888: 00 01 02 00 01 02 00 00 04 76 74 61 62 09 07 04 .........vtab... +| 3904: 00 01 04 00 01 04 00 00 01 78 b4 01 01 01 01 02 .........x...... +| 3920: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 3936: 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 ................ +| 3952: 01 01 02 00 01 01 01 07 30 01 01 01 02 00 01 01 ........0....... +| 3968: 01 02 00 11 01 01 02 00 01 01 01 02 00 11 01 01 ................ +| 3984: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4000: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| 4016: 01 01 01 01 ff 01 01 01 02 00 01 01 01 02 00 01 ................ +| 4032: 01 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 ................ +| 4048: 01 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 ................ +| 4064: 02 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 ................ +| 4080: 00 01 01 01 02 00 01 01 01 02 00 01 01 01 02 00 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 02 0f f5 00 0f fb 0f f5 00 00 00 00 ................ +| 4080: 00 00 00 00 00 05 04 08 09 01 02 04 04 08 08 09 ................ +| page 7 offset 24576 +| 0: 0d 00 00 00 05 0f b8 00 0e f4 0f e9 10 d6 0f c7 ................ +| 4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f ...........#auto +| 4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65 merge=5...#merge +| 4048: 3d 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =1.............. +| end crash-dde9e76ed8ab2d.db +}]} {} + +do_catchsql_test 25.1 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237) + INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; +} {0 {}} + +do_catchsql_test 25.2 { + UPDATE t1 SET b=quote((true) ) WHERE t1 MATCH 'h*'; +} {0 {}} + +do_catchsql_test 25.3 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x +x FROM c WHERE 72 Date: Wed, 24 Apr 2019 17:04:02 +0000 Subject: [PATCH 036/132] New test cases in test/fuzzdata8.db. FossilOrigin-Name: 7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzdata8.db | Bin 1062912 -> 1099776 bytes 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a87d4a6716..261ca06463 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sinstance\sin\sfts3\swhere\sa\scorrupt\srecord\scan\scause\sa\sbuffer\soverflow. -D 2019-04-24T16:13:52.386 +C New\stest\scases\sin\stest/fuzzdata8.db. +D 2019-04-24T17:04:02.548 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -997,7 +997,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db f46c9a5698c1ca75ca6280c7c879a3f46dc82fe4b1ce246827496b806488952d -F test/fuzzdata8.db 858795dc515318bc27b568d0f83cd766ba8f6c3f7095a331c3b099676cc40567 +F test/fuzzdata8.db 1786362da75b8696f804b0b4548b59830e148718bce827548c006031105e7783 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1818,7 +1818,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 516ca8945150bdc1363603e234be5f3f4a3861f581d7cc9455da3e87b9974309 -R 7412822ff3a00a816140932f44ebe070 -U dan -Z d1d0f4067be8582800abaf723a648e76 +P e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550 +R 3e1175ca2cd3d699a0989ce182ed2c32 +U drh +Z b7a4bb53a6677ebeb4f1be668326c373 diff --git a/manifest.uuid b/manifest.uuid index 0edb6004df..7b9871a25b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550 \ No newline at end of file +7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 777f734fc1a968c6f2c008d3254db13816487931..9ab060369920df286d1b89915830bc61b4916132 100644 GIT binary patch delta 21787 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 pyo_~n`qjRboHKEbD#g{{c?SB(VSh From efa363b84c43d63c706e7997085a2e5977aac64d Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 24 Apr 2019 20:48:55 +0000 Subject: [PATCH 037/132] Improve the performance of the .recover command. FossilOrigin-Name: a50768314d10d743a0cc013b434b516f0763e0a6c5b79655d8fefde7de53e869 --- ext/misc/dbdata.c | 60 +++++++++++++++++++++++++++++++++++------------ manifest | 14 +++++------ manifest.uuid | 2 +- src/shell.c.in | 42 ++++++++++++++++++++------------- 4 files changed, 79 insertions(+), 39 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 7662417ae5..13bb51f08b 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -106,6 +106,7 @@ struct DbdataCursor { struct DbdataTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database connection */ + sqlite3_stmt *pStmt; /* For fetching database pages */ int bPtr; /* True for sqlite3_dbptr table */ }; @@ -167,7 +168,11 @@ static int dbdataConnect( ** Disconnect from or destroy a dbdata virtual table. */ static int dbdataDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); + DbdataTable *pTab = (DbdataTable*)pVtab; + if( pTab ){ + sqlite3_finalize(pTab->pStmt); + sqlite3_free(pVtab); + } return SQLITE_OK; } @@ -185,15 +190,15 @@ static int dbdataDisconnect(sqlite3_vtab *pVtab){ ** If both parameters are present, schema is in position 0 and pgno in ** position 1. */ -static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ +static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){ DbdataTable *pTab = (DbdataTable*)tab; int i; int iSchema = -1; int iPgno = -1; int colSchema = (pTab->bPtr ? DBPTR_COLUMN_SCHEMA : DBDATA_COLUMN_SCHEMA); - for(i=0; inConstraint; i++){ - struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pIdx->aConstraint[i]; if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ if( p->iColumn==colSchema ){ if( p->usable==0 ) return SQLITE_CONSTRAINT; @@ -206,14 +211,29 @@ static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ } if( iSchema>=0 ){ - pIdxInfo->aConstraintUsage[iSchema].argvIndex = 1; - pIdxInfo->aConstraintUsage[iSchema].omit = 1; + pIdx->aConstraintUsage[iSchema].argvIndex = 1; + pIdx->aConstraintUsage[iSchema].omit = 1; } if( iPgno>=0 ){ - pIdxInfo->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0); - pIdxInfo->aConstraintUsage[iPgno].omit = 1; + pIdx->aConstraintUsage[iPgno].argvIndex = 1 + (iSchema>=0); + pIdx->aConstraintUsage[iPgno].omit = 1; + pIdx->estimatedCost = 100; + pIdx->estimatedRows = 50; + + if( pTab->bPtr==0 && pIdx->nOrderBy && pIdx->aOrderBy[0].desc==0 ){ + int iCol = pIdx->aOrderBy[0].iColumn; + if( pIdx->nOrderBy==1 ){ + pIdx->orderByConsumed = (iCol==0 || iCol==1); + }else if( pIdx->nOrderBy==2 && pIdx->aOrderBy[1].desc==0 && iCol==0 ){ + pIdx->orderByConsumed = (pIdx->aOrderBy[1].iColumn==1); + } + } + + }else{ + pIdx->estimatedCost = 100000000; + pIdx->estimatedRows = 1000000000; } - pIdxInfo->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00); + pIdx->idxNum = (iSchema>=0 ? 0x01 : 0x00) | (iPgno>=0 ? 0x02 : 0x00); return SQLITE_OK; } @@ -236,7 +256,12 @@ static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ } static void dbdataResetCursor(DbdataCursor *pCsr){ - sqlite3_finalize(pCsr->pStmt); + DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab); + if( pTab->pStmt==0 ){ + pTab->pStmt = pCsr->pStmt; + }else{ + sqlite3_finalize(pCsr->pStmt); + } pCsr->pStmt = 0; pCsr->iPgno = 1; pCsr->iCell = 0; @@ -558,7 +583,7 @@ static int dbdataFilter( ){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; DbdataTable *pTab = (DbdataTable*)pCursor->pVtab; - int rc; + int rc = SQLITE_OK; const char *zSchema = "main"; dbdataResetCursor(pCsr); @@ -571,10 +596,15 @@ static int dbdataFilter( pCsr->bOnePage = 1; } - rc = sqlite3_prepare_v2(pTab->db, - "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, - &pCsr->pStmt, 0 - ); + if( pTab->pStmt ){ + pCsr->pStmt = pTab->pStmt; + pTab->pStmt = 0; + }else{ + rc = sqlite3_prepare_v2(pTab->db, + "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, + &pCsr->pStmt, 0 + ); + } if( rc==SQLITE_OK ){ rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); }else{ diff --git a/manifest b/manifest index e3ab13575f..039fa63685 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\s".recover"\shandle\s"\\r"\sand\s"\\n"\sin\sthe\ssame\sway\sas\s".dump". -D 2019-04-23T20:48:32.366 +C Improve\sthe\sperformance\sof\sthe\s.recover\scommand. +D 2019-04-24T20:48:55.802 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 6a0ccc33e8c5ef3b6164eec7839cb4dff44e27bee0717f1660dbb8ee77ee4cf8 +F ext/misc/dbdata.c 0c80f0757c3a1b5c57027328ab0ccfe30fcef1a4875b41dd9ddc0f53c7087e97 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 6e56c60640410885a8c3c264971619407ae5c7f46165e2bfe5fb1ca1a6a58ad0 +F src/shell.c.in 569ee1f79236f19b44fb4fcb8a0a2f0b2dce9a3d856d41a196aaaaa5f0d37704 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 8dcc1d89d955bf58c80a8c30a37960f0cf95719953951a92626cc332cc75ec60 -R b9c18dd1095e3f7b028bdaea88f9fcb0 +P f95f0f02ab6c6cf45f25b613c7ab57f68249689d0a9eddf4c9518ddf0edad365 +R 0e7ee563b8599ed64c48e30038f5f99f U dan -Z edabfc3afbc2656b0ce1a8fb6b1e492b +Z f093e1d7a99537670d8620da5d0b299b diff --git a/manifest.uuid b/manifest.uuid index fdcc68f9a9..3f61303065 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f95f0f02ab6c6cf45f25b613c7ab57f68249689d0a9eddf4c9518ddf0edad365 \ No newline at end of file +a50768314d10d743a0cc013b434b516f0763e0a6c5b79655d8fefde7de53e869 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 7989c9dfde..05ce02d605 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6372,6 +6372,8 @@ static RecoverTable *recoverNewTable( static int recoverDatabaseCmd(ShellState *pState){ int rc = SQLITE_OK; sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ + sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ + sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ shellExec(pState->db, &rc, /* Attach an in-memory database named 'recovery'. Create an indexed @@ -6460,6 +6462,15 @@ static int recoverDatabaseCmd(ShellState *pState){ shellFinalize(&rc, pStmt); } + shellPrepare(pState->db, &rc, + "SELECT pgno FROM recovery.map WHERE root=?", &pPages + ); + shellPrepare(pState->db, &rc, + "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')" + "FROM sqlite_dbdata WHERE pgno = ? AND field != ?" + "GROUP BY cell", &pCells + ); + /* Loop through each root page. */ shellPrepare(pState->db, &rc, "SELECT root, intkey, max(maxlen) FROM recovery.map" @@ -6475,30 +6486,29 @@ static int recoverDatabaseCmd(ShellState *pState){ pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol); if( pTab ){ - sqlite3_stmt *pData = 0; if( 0==sqlite3_stricmp(pTab->zName, "sqlite_sequence") ){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); } - shellPreparePrintf(pState->db, &rc, &pData, - "SELECT max(field), group_concat(shell_escape_crnl(quote(value)),', ')" - "FROM sqlite_dbdata WHERE pgno IN (" - " SELECT pgno FROM recovery.map WHERE root=%d" - ")" - " AND field!=%d " - "GROUP BY pgno, cell;", iRoot, pTab->iPk - ); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pData) ){ - int iMax = sqlite3_column_int(pData, 0); - const char *zVal = (const char*)sqlite3_column_text(pData, 1); - raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", - pTab->zQuoted, pTab->azlCol[iMax>0?iMax:0], zVal - ); + sqlite3_bind_int(pPages, 1, iRoot); + sqlite3_bind_int(pCells, 2, pTab->iPk); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ + sqlite3_bind_int(pCells, 1, sqlite3_column_int(pPages, 0)); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ + int iMax = sqlite3_column_int(pCells, 0); + const char *zVal = (const char*)sqlite3_column_text(pCells, 1); + raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", + pTab->zQuoted, pTab->azlCol[iMax>0?iMax:0], zVal + ); + } + shellReset(&rc, pCells); } - shellFinalize(&rc, pData); + shellReset(&rc, pPages); } recoverFreeTable(pTab); } shellFinalize(&rc, pLoop); + shellFinalize(&rc, pPages); + shellFinalize(&rc, pCells); /* The rest of the schema */ if( rc==SQLITE_OK ){ From b9b71dbfd4066df5d62fd59c1f5350faca74fcd4 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Apr 2019 16:20:40 +0000 Subject: [PATCH 038/132] Fix a bug preventing .recover from working on databases where the final page of the db is corrupt. FossilOrigin-Name: 959bbd11e92cc789973daf20dfcb8a6d8dc724dd603b286cbdd59e5d1fdb2909 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 9 +++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 039fa63685..2701068663 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sthe\sperformance\sof\sthe\s.recover\scommand. -D 2019-04-24T20:48:55.802 +C Fix\sa\sbug\spreventing\s.recover\sfrom\sworking\son\sdatabases\swhere\sthe\sfinal\spage\sof\sthe\sdb\sis\scorrupt. +D 2019-04-25T16:20:40.499 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 569ee1f79236f19b44fb4fcb8a0a2f0b2dce9a3d856d41a196aaaaa5f0d37704 +F src/shell.c.in 2e9b6b05fd202499bbe233632f9e5a913d2afcd645b59a114bfeb440c3e5cd38 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 f95f0f02ab6c6cf45f25b613c7ab57f68249689d0a9eddf4c9518ddf0edad365 -R 0e7ee563b8599ed64c48e30038f5f99f +P a50768314d10d743a0cc013b434b516f0763e0a6c5b79655d8fefde7de53e869 +R 9da7af39576825c9e597192b24527e0d U dan -Z f093e1d7a99537670d8620da5d0b299b +Z 0de6a10b348dda1bb213a1119e4cc094 diff --git a/manifest.uuid b/manifest.uuid index 3f61303065..e18c3e1cac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a50768314d10d743a0cc013b434b516f0763e0a6c5b79655d8fefde7de53e869 \ No newline at end of file +959bbd11e92cc789973daf20dfcb8a6d8dc724dd603b286cbdd59e5d1fdb2909 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 05ce02d605..73bf9dff97 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6369,7 +6369,7 @@ static RecoverTable *recoverNewTable( ** to construct a new database containing all recovered data is output ** on stream pState->out. */ -static int recoverDatabaseCmd(ShellState *pState){ +static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ int rc = SQLITE_OK; sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ @@ -6406,8 +6406,9 @@ static int recoverDatabaseCmd(ShellState *pState){ ** database, the following adds all pages in such a loop to the map ** as individual root pages. This could be handled better. */ "WITH pages(i, maxlen) AS (" - " SELECT page_count, max(field+1) " - " FROM pragma_page_count, sqlite_dbdata WHERE pgno=page_count" + " SELECT page_count, (" + " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count" + " ) FROM pragma_page_count" " UNION ALL" " SELECT i-1, (" " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1" @@ -6831,7 +6832,7 @@ static int do_meta_command(char *zLine, ShellState *p){ if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){ open_db(p, 0); - rc = recoverDatabaseCmd(p); + rc = recoverDatabaseCmd(p, nArg, azArg); }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ From 9c014f8b0c63b3b8c8c2ae30dd9c9cbe1b883952 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 25 Apr 2019 19:23:15 +0000 Subject: [PATCH 039/132] Unless the "--freelist-corrupt" option is specified, do not have the .recover command attempt to recover data from pages that are on the database free-list. FossilOrigin-Name: 8d2f52bb640d6d0f84b18d746043e56f45a73ace93239be1d036701f7f4018fd --- manifest | 12 ++++---- manifest.uuid | 2 +- src/shell.c.in | 78 +++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2701068663..f7a1f6f81c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\spreventing\s.recover\sfrom\sworking\son\sdatabases\swhere\sthe\sfinal\spage\sof\sthe\sdb\sis\scorrupt. -D 2019-04-25T16:20:40.499 +C Unless\sthe\s"--freelist-corrupt"\soption\sis\sspecified,\sdo\snot\shave\sthe\s.recover\scommand\sattempt\sto\srecover\sdata\sfrom\spages\sthat\sare\son\sthe\sdatabase\sfree-list. +D 2019-04-25T19:23:15.197 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 9263f5c30dd44c7ac2eb29f40a7ec64322a96885b71c00de6bc30b756c2e1c49 -F src/shell.c.in 2e9b6b05fd202499bbe233632f9e5a913d2afcd645b59a114bfeb440c3e5cd38 +F src/shell.c.in a3b1bb23c3c3dde9aab1823dc37cb0f3e81debfd3937e40ee8fa69fe1f0e4c16 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 a50768314d10d743a0cc013b434b516f0763e0a6c5b79655d8fefde7de53e869 -R 9da7af39576825c9e597192b24527e0d +P 959bbd11e92cc789973daf20dfcb8a6d8dc724dd603b286cbdd59e5d1fdb2909 +R d86f5b916c733bd261b32efe2b58444b U dan -Z 0de6a10b348dda1bb213a1119e4cc094 +Z 3b2dfcc08d011cfeb383f50fbff24d3e diff --git a/manifest.uuid b/manifest.uuid index e18c3e1cac..37c6cf3c7d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -959bbd11e92cc789973daf20dfcb8a6d8dc724dd603b286cbdd59e5d1fdb2909 \ No newline at end of file +8d2f52bb640d6d0f84b18d746043e56f45a73ace93239be1d036701f7f4018fd \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 73bf9dff97..95c18ae4d1 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3934,6 +3934,35 @@ readHexDb_error: } #endif /* SQLITE_ENABLE_DESERIALIZE */ +/* +** Scalar function "shell_int32". The first argument to this function +** must be a blob. The second a non-negative integer. This function +** reads and returns a 32-bit big-endian integer from byte +** offset (4*) of the blob. +*/ +static void shellInt32( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *pBlob; + int nBlob; + int iInt; + + nBlob = sqlite3_value_bytes(argv[0]); + pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]); + iInt = sqlite3_value_int(argv[1]); + + if( iInt>=0 && (iInt+1)*4<=nBlob ){ + const unsigned char *a = &pBlob[iInt*4]; + sqlite3_int64 iVal = ((sqlite3_int64)a[0]<<24) + + ((sqlite3_int64)a[1]<<16) + + ((sqlite3_int64)a[2]<< 8) + + ((sqlite3_int64)a[3]<< 0); + sqlite3_result_int64(context, iVal); + } +} + /* ** Scalar function "shell_escape_crnl" used by the .recover command. ** The argument passed to this function is the output of built-in @@ -4105,6 +4134,8 @@ static void open_db(ShellState *p, int openFlags){ shellPutsFunc, 0, 0); sqlite3_create_function(p->db, "shell_escape_crnl", 1, SQLITE_UTF8, 0, shellEscapeCrnl, 0, 0); + sqlite3_create_function(p->db, "shell_int32", 2, SQLITE_UTF8, 0, + shellInt32, 0, 0); #ifndef SQLITE_NOHAVE_SYSTEM sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0, editFunc, 0, 0); @@ -6374,6 +6405,25 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ + int i; + + int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ + for(i=1; idb, &rc, /* Attach an in-memory database named 'recovery'. Create an indexed @@ -6395,6 +6445,32 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1" ");" + "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);" + ); + + if( bFreelist ){ + shellExec(pState->db, &rc, + "WITH trunk(pgno) AS (" + " SELECT shell_int32(" + " (SELECT data FROM sqlite_dbpage WHERE pgno=1), 8) AS x " + " WHERE x>0" + " UNION" + " SELECT shell_int32(" + " (SELECT data FROM sqlite_dbpage WHERE pgno=trunk.pgno), 0) AS x " + " FROM trunk WHERE x>0" + ")," + "freelist(data, n, freepgno) AS (" + " SELECT data, shell_int32(data, 1)-1, t.pgno " + " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno" + " UNION ALL" + " SELECT data, n-1, shell_int32(data, 2+n) " + " FROM freelist WHERE n>=0" + ")" + "REPLACE INTO recovery.freelist SELECT freepgno FROM freelist;" + ); + } + + shellExec(pState->db, &rc, /* Create the "map" table that will (eventually) contain instructions ** for dealing with each page in the db that contains one or more ** records. */ @@ -6424,7 +6500,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " )" " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" ") " - "FROM pages WHERE maxlen > 0;" + "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;" "UPDATE recovery.map AS o SET intkey = (" " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno" ");" From c0b42437ab69d01daa61bd77f74badb95c82bd40 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Apr 2019 15:14:53 +0000 Subject: [PATCH 040/132] Fix a locking-page related problem with the ".recover" command. FossilOrigin-Name: afdae10424f0f3d0f10a4b73e9732aa55c5ee664814d8ca0edd372cfb17c2445 --- ext/misc/dbdata.c | 66 +++++++++++++++++++++++++++++++++++------------ manifest | 14 +++++----- manifest.uuid | 2 +- src/shell.c.in | 42 ++++++++++++++++++++++++------ 4 files changed, 91 insertions(+), 33 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 13bb51f08b..a27f19dc7a 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -89,6 +89,7 @@ struct DbdataCursor { int nCell; /* Number of cells on aPage[] */ int iCell; /* Current cell number */ int bOnePage; /* True to stop after one page */ + int szDb; sqlite3_int64 iRowid; /* Only for the sqlite_dbdata table */ @@ -303,18 +304,21 @@ static int dbdataLoadPage( sqlite3_bind_int64(pStmt, 2, pgno); if( SQLITE_ROW==sqlite3_step(pStmt) ){ int nCopy = sqlite3_column_bytes(pStmt, 0); - u8 *pPage = (u8*)sqlite3_malloc64(nCopy); - if( pPage==0 ){ - rc = SQLITE_NOMEM; - }else{ - const u8 *pCopy = sqlite3_column_blob(pStmt, 0); - memcpy(pPage, pCopy, nCopy); + if( nCopy>0 ){ + u8 *pPage; + pPage = (u8*)sqlite3_malloc64(nCopy); + if( pPage==0 ){ + rc = SQLITE_NOMEM; + }else{ + const u8 *pCopy = sqlite3_column_blob(pStmt, 0); + memcpy(pPage, pCopy, nCopy); + } *ppPage = pPage; *pnPage = nCopy; } } rc2 = sqlite3_reset(pStmt); - if( *ppPage==0 ) rc = rc2; + if( rc==SQLITE_OK ) rc = rc2; return rc; } @@ -419,8 +423,13 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ int iOff = (pCsr->iPgno==1 ? 100 : 0); if( pCsr->aPage==0 ){ - rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); - if( rc!=SQLITE_OK || pCsr->aPage==0 ) return rc; + while( 1 ){ + if( pCsr->bOnePage==0 && pCsr->iPgno>pCsr->szDb ) return SQLITE_OK; + rc = dbdataLoadPage(pCsr, pCsr->iPgno, &pCsr->aPage, &pCsr->nPage); + if( rc!=SQLITE_OK ) return rc; + if( pCsr->aPage ) break; + pCsr->iPgno++; + } pCsr->iCell = pTab->bPtr ? -2 : 0; pCsr->nCell = get_uint16(&pCsr->aPage[iOff+3]); } @@ -574,6 +583,24 @@ static int dbdataEof(sqlite3_vtab_cursor *pCursor){ return pCsr->aPage==0; } +static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){ + DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab; + char *zSql = 0; + int rc, rc2; + sqlite3_stmt *pStmt = 0; + + zSql = sqlite3_mprintf("PRAGMA %Q.page_count", zSchema); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); + if( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){ + pCsr->szDb = sqlite3_column_int(pStmt, 0); + } + rc2 = sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ) rc = rc2; + return rc; +} + /* Position a cursor back to the beginning. */ static int dbdataFilter( @@ -594,16 +621,21 @@ static int dbdataFilter( if( idxNum & 0x02 ){ pCsr->iPgno = sqlite3_value_int(argv[(idxNum & 0x01)]); pCsr->bOnePage = 1; + }else{ + pCsr->nPage = dbdataDbsize(pCsr, zSchema); + rc = dbdataDbsize(pCsr, zSchema); } - if( pTab->pStmt ){ - pCsr->pStmt = pTab->pStmt; - pTab->pStmt = 0; - }else{ - rc = sqlite3_prepare_v2(pTab->db, - "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, - &pCsr->pStmt, 0 - ); + if( rc==SQLITE_OK ){ + if( pTab->pStmt ){ + pCsr->pStmt = pTab->pStmt; + pTab->pStmt = 0; + }else{ + rc = sqlite3_prepare_v2(pTab->db, + "SELECT data FROM sqlite_dbpage(?) WHERE pgno=?", -1, + &pCsr->pStmt, 0 + ); + } } if( rc==SQLITE_OK ){ rc = sqlite3_bind_text(pCsr->pStmt, 1, zSchema, -1, SQLITE_TRANSIENT); diff --git a/manifest b/manifest index c6b5a05076..d361dc7ebc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. -D 2019-04-25T20:06:34.069 +C Fix\sa\slocking-page\srelated\sproblem\swith\sthe\s".recover"\scommand. +D 2019-04-26T15:14:53.514 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 0c80f0757c3a1b5c57027328ab0ccfe30fcef1a4875b41dd9ddc0f53c7087e97 +F ext/misc/dbdata.c b7547f43906f9296e43be807ca78e2ef3f335ca26d6e91d178df30cd2fd46572 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 78004b100ed486695f4ff8bbc40b99c2e4d7b6d06278ce64b80ac1900bf356a3 +F src/shell.c.in 63b1075817997806d7f09c2a0433ffac854b6dee47836ef938d51531cdb8042f F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 8d2f52bb640d6d0f84b18d746043e56f45a73ace93239be1d036701f7f4018fd 7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf -R af342ccd780cc18bf46aaaf7890063fa +P 1da302d85d7ad4ba54f877117a45d667439fd2ef31dc70ea1d54dc1fba196e68 +R 981714fd52a70e51cf4586f924a49fdc U dan -Z 147b326af09d7b23ccf3f83204577057 +Z 303a0ea3c8fcc86a61370f3e12d83ec5 diff --git a/manifest.uuid b/manifest.uuid index 0d49487589..b5f67ee780 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1da302d85d7ad4ba54f877117a45d667439fd2ef31dc70ea1d54dc1fba196e68 \ No newline at end of file +afdae10424f0f3d0f10a4b73e9732aa55c5ee664814d8ca0edd372cfb17c2445 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 55f7964319..1884e7bfe2 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6165,6 +6165,22 @@ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){ } } +static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){ + char *z = 0; + if( *pRc==SQLITE_OK ){ + va_list ap; + va_start(ap, zFmt); + z = sqlite3_vmprintf(zFmt, ap); + va_end(ap); + if( z==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + shellExec(db, pRc, z); + } + sqlite3_free(z); + } +} + static void *shellMalloc(int *pRc, sqlite3_int64 nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ @@ -6405,6 +6421,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ sqlite3_stmt *pLoop = 0; /* Loop through all root pages */ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ + const char *zRecoveryDb = ""; /* Name of "recovery" database */ int i; int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ @@ -6416,23 +6433,32 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){ bFreelist = 0; } + if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){ + i++; + zRecoveryDb = azArg[i]; + } else{ - raw_printf(stderr, - "unexpected option: %s - expected \"--freelist-corrupt\"\n", - azArg[i] - ); + raw_printf(stderr, "unexpected option: %s\n", azArg[i]); + raw_printf(stderr, "options are:\n"); + raw_printf(stderr, " --freelist-corrupt\n"); + raw_printf(stderr, " --recovery-db DATABASE\n"); return 1; } } - shellExec(pState->db, &rc, + shellExecPrintf(pState->db, &rc, /* Attach an in-memory database named 'recovery'. Create an indexed ** cache of the sqlite_dbptr virtual table. */ - "ATTACH '' AS recovery;" + "ATTACH %Q AS recovery;" + "DROP TABLE IF EXISTS recovery.dbptr;" + "DROP TABLE IF EXISTS recovery.freelist;" + "DROP TABLE IF EXISTS recovery.map;" + "DROP TABLE IF EXISTS recovery.schema;" "CREATE TABLE recovery.dbptr(" " pgno, child, PRIMARY KEY(child, pgno)" ") WITHOUT ROWID;" - "INSERT OR IGNORE INTO dbptr(pgno, child) SELECT * FROM sqlite_dbptr;" + "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) " + " SELECT * FROM sqlite_dbptr;" /* Delete any pointer to page 1. This ensures that page 1 is considered ** a root page, regardless of how corrupt the db is. */ @@ -6445,7 +6471,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1" ");" - "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);" + "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb ); if( bFreelist ){ From ca424382613ed62e80b54734231a1d1d8dd916bd Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Apr 2019 15:40:27 +0000 Subject: [PATCH 041/132] Fix another problem with database freelist handling in the ".recover" command. FossilOrigin-Name: bee2652ac26370e612a8c81dd7554befc2d523442a2fbbc77dc73479e6a0d7fd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 35 ++++++++++++++++++----------------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index d361dc7ebc..2ea5b39962 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\slocking-page\srelated\sproblem\swith\sthe\s".recover"\scommand. -D 2019-04-26T15:14:53.514 +C Fix\sanother\sproblem\swith\sdatabase\sfreelist\shandling\sin\sthe\s".recover"\scommand. +D 2019-04-26T15:40:27.902 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 63b1075817997806d7f09c2a0433ffac854b6dee47836ef938d51531cdb8042f +F src/shell.c.in 44dce9f5b3c68c07e30db740aa4e635819ab6fa01a229a21356ddd4fa8f1e47e F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 1da302d85d7ad4ba54f877117a45d667439fd2ef31dc70ea1d54dc1fba196e68 -R 981714fd52a70e51cf4586f924a49fdc +P afdae10424f0f3d0f10a4b73e9732aa55c5ee664814d8ca0edd372cfb17c2445 +R 5b76306d65317b1b0fee3a74fc0359d7 U dan -Z 303a0ea3c8fcc86a61370f3e12d83ec5 +Z 068a6ba7f1f2eaa523c5f432cd2b8c0c diff --git a/manifest.uuid b/manifest.uuid index b5f67ee780..4c5a229461 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afdae10424f0f3d0f10a4b73e9732aa55c5ee664814d8ca0edd372cfb17c2445 \ No newline at end of file +bee2652ac26370e612a8c81dd7554befc2d523442a2fbbc77dc73479e6a0d7fd \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 1884e7bfe2..c417160d52 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6454,23 +6454,6 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ "DROP TABLE IF EXISTS recovery.freelist;" "DROP TABLE IF EXISTS recovery.map;" "DROP TABLE IF EXISTS recovery.schema;" - "CREATE TABLE recovery.dbptr(" - " pgno, child, PRIMARY KEY(child, pgno)" - ") WITHOUT ROWID;" - "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) " - " SELECT * FROM sqlite_dbptr;" - - /* Delete any pointer to page 1. This ensures that page 1 is considered - ** a root page, regardless of how corrupt the db is. */ - "DELETE FROM recovery.dbptr WHERE child = 1;" - - /* Delete all pointers to any pages that have more than one pointer - ** to them. Such pages will be treated as root pages when recovering - ** data. */ - "DELETE FROM recovery.dbptr WHERE child IN (" - " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1" - ");" - "CREATE TABLE recovery.freelist(pgno INTEGER PRIMARY KEY);", zRecoveryDb ); @@ -6497,6 +6480,24 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } shellExec(pState->db, &rc, + "CREATE TABLE recovery.dbptr(" + " pgno, child, PRIMARY KEY(child, pgno)" + ") WITHOUT ROWID;" + "INSERT OR IGNORE INTO recovery.dbptr(pgno, child) " + " SELECT * FROM sqlite_dbptr" + " WHERE pgno NOT IN freelist AND child NOT IN freelist;" + + /* Delete any pointer to page 1. This ensures that page 1 is considered + ** a root page, regardless of how corrupt the db is. */ + "DELETE FROM recovery.dbptr WHERE child = 1;" + + /* Delete all pointers to any pages that have more than one pointer + ** to them. Such pages will be treated as root pages when recovering + ** data. */ + "DELETE FROM recovery.dbptr WHERE child IN (" + " SELECT child FROM recovery.dbptr GROUP BY child HAVING count(*)>1" + ");" + /* Create the "map" table that will (eventually) contain instructions ** for dealing with each page in the db that contains one or more ** records. */ From db5ba5c385496191770a418e27607522474e611c Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 26 Apr 2019 17:08:50 +0000 Subject: [PATCH 042/132] Omit tests of the LIKE optimization in like3.test when SQLITE_ENABLE_ICU is defined. FossilOrigin-Name: af53c41a127c314c0608f3fd016d3a26896783745e46cd180976a188400cdb75 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/like3.test | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 261ca06463..158d60af72 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sin\stest/fuzzdata8.db. -D 2019-04-24T17:04:02.548 +C Omit\stests\sof\sthe\sLIKE\soptimization\sin\slike3.test\swhen\sSQLITE_ENABLE_ICU\sis\sdefined. +D 2019-04-26T17:08:50.839 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1085,7 +1085,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test 0ce2630e39e32e42ce02d171f0a315189ca71fec37c5ddfb0191eecc3fe9d4da +F test/like3.test d3684b5c60dd2d1f9574f9f296b31c995187c8c10c6ca573f9918c96af9ba642 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 @@ -1818,7 +1818,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 e1724f1d618cfbcfd1e495d8965a395656cfc1114e1bffd4bc3be0bd5cdb6550 -R 3e1175ca2cd3d699a0989ce182ed2c32 -U drh -Z b7a4bb53a6677ebeb4f1be668326c373 +P 7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf +R 1ba2bc865b250121afcb0af52a507e48 +U dan +Z 432d74fc77b640bcf830ac2298b92cb0 diff --git a/manifest.uuid b/manifest.uuid index 7b9871a25b..0646b8052e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf \ No newline at end of file +af53c41a127c314c0608f3fd016d3a26896783745e46cd180976a188400cdb75 \ No newline at end of file diff --git a/test/like3.test b/test/like3.test index 622f8335eb..89c9efa792 100644 --- a/test/like3.test +++ b/test/like3.test @@ -182,6 +182,7 @@ do_eqp_test like3-5.211 { # Verify that the LIKE optimization works with an ESCAPE clause when # using PRAGMA case_sensitive_like=ON. # +ifcapable !icu { do_execsql_test like3-6.100 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(path TEXT COLLATE nocase PRIMARY KEY,a,b,c) WITHOUT ROWID; @@ -229,5 +230,6 @@ do_eqp_test like3-6.240 { QUERY PLAN `--SEARCH TABLE t2 USING INDEX t2path2 (path>? AND path Date: Fri, 26 Apr 2019 21:11:37 +0000 Subject: [PATCH 043/132] Have .recover store all orphaned rows in a single table, with extra columns to indicate the orphaned page and sub-tree they were discovered within. FossilOrigin-Name: 7221f6e33ed6a5a96ec61e25f2a1f70b84aae66e503d897eb7b7ff1aec42355d --- manifest | 12 +-- manifest.uuid | 2 +- src/shell.c.in | 209 +++++++++++++++++++++++++++++-------------------- 3 files changed, 133 insertions(+), 90 deletions(-) diff --git a/manifest b/manifest index 2ea5b39962..8404fd782b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\sproblem\swith\sdatabase\sfreelist\shandling\sin\sthe\s".recover"\scommand. -D 2019-04-26T15:40:27.902 +C Have\s.recover\sstore\sall\sorphaned\srows\sin\sa\ssingle\stable,\swith\sextra\scolumns\sto\sindicate\sthe\sorphaned\spage\sand\ssub-tree\sthey\swere\sdiscovered\swithin. +D 2019-04-26T21:11:37.615 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 44dce9f5b3c68c07e30db740aa4e635819ab6fa01a229a21356ddd4fa8f1e47e +F src/shell.c.in 146dbc2708a314556710f8e8b13226d647fbb70778c973bb6fd655186811ce63 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 afdae10424f0f3d0f10a4b73e9732aa55c5ee664814d8ca0edd372cfb17c2445 -R 5b76306d65317b1b0fee3a74fc0359d7 +P bee2652ac26370e612a8c81dd7554befc2d523442a2fbbc77dc73479e6a0d7fd +R 52eb405413df1bbf1e7b369ddce62695 U dan -Z 068a6ba7f1f2eaa523c5f432cd2b8c0c +Z 87ebd735a2a8d2115b37082d2935a00e diff --git a/manifest.uuid b/manifest.uuid index 4c5a229461..3cfd1fa139 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bee2652ac26370e612a8c81dd7554befc2d523442a2fbbc77dc73479e6a0d7fd \ No newline at end of file +7221f6e33ed6a5a96ec61e25f2a1f70b84aae66e503d897eb7b7ff1aec42355d \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index c417160d52..0737a347a0 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6226,7 +6226,7 @@ static void recoverFreeTable(RecoverTable *pTab){ sqlite3_free(pTab->zQuoted); if( pTab->azlCol ){ int i; - for(i=0; inCol; i++){ + for(i=0; i<=pTab->nCol; i++){ sqlite3_free(pTab->azlCol[i]); } sqlite3_free(pTab->azlCol); @@ -6235,9 +6235,8 @@ static void recoverFreeTable(RecoverTable *pTab){ } } -static void recoverOldTable( +static RecoverTable *recoverOldTable( int *pRc, /* IN/OUT: Error code */ - RecoverTable *pTab, const char *zName, /* Name of table */ const char *zSql, /* CREATE TABLE statement */ int bIntkey, @@ -6245,12 +6244,14 @@ static void recoverOldTable( ){ sqlite3 *dbtmp = 0; /* sqlite3 handle for testing CREATE TABLE */ int rc = *pRc; + RecoverTable *pTab = 0; + pTab = (RecoverTable*)shellMalloc(&rc, sizeof(RecoverTable)); if( rc==SQLITE_OK ){ int nSqlCol = 0; int bSqlIntkey = 0; sqlite3_stmt *pStmt = 0; - + rc = sqlite3_open("", &dbtmp); if( rc==SQLITE_OK ){ rc = sqlite3_exec(dbtmp, "PRAGMA writable_schema = on", 0, 0, 0); @@ -6285,43 +6286,48 @@ static void recoverOldTable( shellFinalize(&rc, pStmt); if( bIntkey==bSqlIntkey ){ + int i; const char *zPk = "_rowid_"; sqlite3_stmt *pPkFinder = 0; - shellPreparePrintf(dbtmp, &rc, &pPkFinder, + pTab->iPk = -2; + if( bIntkey ){ + shellPreparePrintf(dbtmp, &rc, &pPkFinder, "SELECT cid, name FROM pragma_table_info(%Q) " " WHERE pk=1 AND type='integer' COLLATE nocase" - " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)", - zName, zName - ); - if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){ - pTab->iPk = sqlite3_column_int(pPkFinder, 0); - zPk = (const char*)sqlite3_column_text(pPkFinder, 1); + " AND NOT EXISTS (SELECT cid FROM pragma_table_info(%Q) WHERE pk=2)" + , zName, zName + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPkFinder) ){ + pTab->iPk = sqlite3_column_int(pPkFinder, 0); + zPk = (const char*)sqlite3_column_text(pPkFinder, 1); + } } pTab->zName = shellMPrintf(&rc, "%s", zName); pTab->zQuoted = shellMPrintf(&rc, "%Q", pTab->zName); - pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * nSqlCol); + pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1)); pTab->nCol = nSqlCol; - if( nSqlCol==1 && pTab->iPk==0 ){ + if( bIntkey ){ pTab->azlCol[0] = shellMPrintf(&rc, "%Q", zPk); }else{ - shellPreparePrintf(dbtmp, &rc, &pStmt, - "SELECT -1+row_number() OVER (ORDER BY cid)," - " %Q||%Q||group_concat(name, ', ') FILTER (WHERE cid!=%d) " - " OVER (ORDER BY cid) " - "FROM pragma_table_info(%Q)", - (bIntkey ? zPk : ""), (bIntkey ? ", " : ""), - pTab->iPk, zName - ); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - int idx = sqlite3_column_int(pStmt, 0); - const char *zText = (const char*)sqlite3_column_text(pStmt, 1); - pTab->azlCol[idx] = shellMPrintf(&rc, "%s", zText); - } - shellFinalize(&rc, pStmt); + pTab->azlCol[0] = shellMPrintf(&rc, ""); } + i = 1; + shellPreparePrintf(dbtmp, &rc, &pStmt, + "SELECT %Q || group_concat(name, ', ') " + " FILTER (WHERE cid!=%d) OVER (ORDER BY cid) " + "FROM pragma_table_info(%Q)", + bIntkey ? ", " : "", pTab->iPk, zName + ); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zText = (const char*)sqlite3_column_text(pStmt, 0); + pTab->azlCol[i] = shellMPrintf(&rc, "%s%s", pTab->azlCol[0], zText); + i++; + } + shellFinalize(&rc, pStmt); + shellFinalize(&rc, pPkFinder); } } @@ -6329,6 +6335,11 @@ static void recoverOldTable( finished: sqlite3_close(dbtmp); *pRc = rc; + if( rc!=SQLITE_OK ){ + recoverFreeTable(pTab); + pTab = 0; + } + return pTab; } static RecoverTable *recoverNewTable( @@ -6336,7 +6347,8 @@ static RecoverTable *recoverNewTable( int *pRc, int iRoot, int bIntkey, - int nCol + int nCol, + int *pbNoop ){ sqlite3_stmt *pStmt = 0; RecoverTable *pRet = 0; @@ -6344,8 +6356,6 @@ static RecoverTable *recoverNewTable( const char *zSql = 0; const char *zName = 0; - pRet = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); - if( pRet ) pRet->iPk = -2; /* Search the recovered schema for an object with root page iRoot. */ shellPreparePrintf(pState->db, pRc, &pStmt, @@ -6360,55 +6370,56 @@ static RecoverTable *recoverNewTable( if( sqlite3_stricmp(zType, "table")==0 ){ zName = (const char*)sqlite3_column_text(pStmt, 1); zSql = (const char*)sqlite3_column_text(pStmt, 2); - recoverOldTable(pRc, pRet, zName, zSql, bIntkey, nCol); + pRet = recoverOldTable(pRc, zName, zSql, bIntkey, nCol); break; } } + shellFinalize(pRc, pStmt); - if( bNoop ){ - sqlite3_free(pRet); - return 0; - } + *pbNoop = bNoop; + return pRet; +} - if( pRet && pRet->zName==0 ){ - sqlite3_stmt *pStmt = 0; - - pRet->zName = shellMPrintf(pRc, "orphan_%d_%d", nCol, iRoot); - pRet->zQuoted = shellMPrintf(pRc, "%Q", pRet->zName); - pRet->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * nCol); - pRet->nCol = nCol; - - shellPreparePrintf(pState->db, pRc, &pStmt, - "WITH s(i) AS (" - " SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<%d" - ")" - "SELECT i-1, %Q || group_concat('c' || i, ', ') OVER (ORDER BY i) FROM s", - nCol, (bIntkey ? "id, " : "") +static RecoverTable *recoverOrphanTable( + ShellState *pState, + int *pRc, + int nCol +){ + RecoverTable *pTab = 0; + if( nCol>=0 && *pRc==SQLITE_OK ){ + int i; + raw_printf(pState->out, + "CREATE TABLE recover_orphan(rootpgno INTEGER, " + "pgno INTEGER, nfield INTEGER, id INTEGER" ); - while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ - int idx = sqlite3_column_int(pStmt, 0); - const char *zText = (const char*)sqlite3_column_text(pStmt, 1); - pRet->azlCol[idx] = shellMPrintf(pRc, "%s", zText); + for(i=0; iout, ", c%d", i); } - shellFinalize(pRc, pStmt); + raw_printf(pState->out, ");\n"); - if( *pRc==SQLITE_OK ){ - char *zCreate = shellMPrintf(pRc, "CREATE TABLE %Q (%s)", - pRet->zName, pRet->azlCol[nCol-1] - ); - if( zCreate ){ - raw_printf(pState->out, "%s;\n", zCreate); - sqlite3_free(zCreate); + pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); + if( pTab ){ + pTab->zName = shellMPrintf(pRc, "%s", "recover_orphan"); + pTab->zQuoted = shellMPrintf(pRc, "%Q", pTab->zName); + pTab->nCol = nCol; + pTab->iPk = -2; + if( nCol>0 ){ + pTab->azlCol = (char**)shellMalloc(pRc, sizeof(char*) * (nCol+1)); + if( pTab->azlCol ){ + pTab->azlCol[nCol] = shellMPrintf(pRc, ""); + for(i=nCol-1; i>=0; i--){ + pTab->azlCol[i] = shellMPrintf(pRc, "%s, NULL", pTab->azlCol[i+1]); + } + } } } - } - if( *pRc!=SQLITE_OK ){ - recoverFreeTable(pRet); - pRet = 0; + if( *pRc!=SQLITE_OK ){ + recoverFreeTable(pTab); + pTab = 0; + } } - - return pRet; + return pTab; } /* @@ -6423,6 +6434,8 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ const char *zRecoveryDb = ""; /* Name of "recovery" database */ int i; + int nOrphan = -1; + RecoverTable *pOrphan = 0; int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ for(i=1; idb, &rc, + "SELECT coalesce(max(maxlen), -2) FROM recovery.map" + " WHERE root>1 AND root NOT IN (SELECT rootpage FROM recovery.schema)" + , &pLoop + ); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ + nOrphan = sqlite3_column_int(pLoop, 0); + } + shellFinalize(&rc, pLoop); + pLoop = 0; + pOrphan = recoverOrphanTable(pState, &rc, nOrphan); + shellPrepare(pState->db, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages ); @@ -6586,33 +6614,48 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ int iRoot = sqlite3_column_int(pLoop, 0); int bIntkey = sqlite3_column_int(pLoop, 1); int nCol = sqlite3_column_int(pLoop, 2); + int bNoop = 0; RecoverTable *pTab; - pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol); - if( pTab ){ - if( 0==sqlite3_stricmp(pTab->zName, "sqlite_sequence") ){ - raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); - } - sqlite3_bind_int(pPages, 1, iRoot); - sqlite3_bind_int(pCells, 2, pTab->iPk); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ - sqlite3_bind_int(pCells, 1, sqlite3_column_int(pPages, 0)); - while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ - int iMax = sqlite3_column_int(pCells, 0); - const char *zVal = (const char*)sqlite3_column_text(pCells, 1); + pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); + if( bNoop || rc ) continue; + if( pTab==0 ) pTab = pOrphan; + + if( 0==sqlite3_stricmp(pTab->zName, "sqlite_sequence") ){ + raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); + } + sqlite3_bind_int(pPages, 1, iRoot); + sqlite3_bind_int(pCells, 2, pTab->iPk); + + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ + int iPgno = sqlite3_column_int(pPages, 0); + sqlite3_bind_int(pCells, 1, iPgno); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ + int nField = sqlite3_column_int(pCells, 0); + const char *zVal = (const char*)sqlite3_column_text(pCells, 1); + + nField = nField+1; + if( pTab==pOrphan ){ + raw_printf(pState->out, + "INSERT INTO %s VALUES(%d, %d, %d, %s%s%s);\n", + pTab->zQuoted, iRoot, iPgno, nField, + bIntkey ? "" : "NULL, ", zVal, pTab->azlCol[nField] + ); + }else{ raw_printf(pState->out, "INSERT INTO %s(%s) VALUES( %s );\n", - pTab->zQuoted, pTab->azlCol[iMax>0?iMax:0], zVal + pTab->zQuoted, pTab->azlCol[nField], zVal ); } - shellReset(&rc, pCells); } - shellReset(&rc, pPages); + shellReset(&rc, pCells); } - recoverFreeTable(pTab); + shellReset(&rc, pPages); + if( pTab!=pOrphan ) recoverFreeTable(pTab); } shellFinalize(&rc, pLoop); shellFinalize(&rc, pPages); shellFinalize(&rc, pCells); + recoverFreeTable(pOrphan); /* The rest of the schema */ if( rc==SQLITE_OK ){ From f57bea31bad6081613945a4a344e6859cd189de1 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Apr 2019 15:35:45 +0000 Subject: [PATCH 044/132] Fix a problem in the .recover command with recovering WITHOUT ROWID tables where the PK columns are not the leftmost in the CREATE TABLE statement. FossilOrigin-Name: 91df4b8e0386105d01614921e8410994b621404a3d46ec4af8687b8743c52d52 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 11 +++++++++-- test/recover.test | 11 +++++++++++ 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8404fd782b..94b2e05ed0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\s.recover\sstore\sall\sorphaned\srows\sin\sa\ssingle\stable,\swith\sextra\scolumns\sto\sindicate\sthe\sorphaned\spage\sand\ssub-tree\sthey\swere\sdiscovered\swithin. -D 2019-04-26T21:11:37.615 +C Fix\sa\sproblem\sin\sthe\s.recover\scommand\swith\srecovering\sWITHOUT\sROWID\stables\swhere\sthe\sPK\scolumns\sare\snot\sthe\sleftmost\sin\sthe\sCREATE\sTABLE\sstatement. +D 2019-04-27T15:35:45.828 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 146dbc2708a314556710f8e8b13226d647fbb70778c973bb6fd655186811ce63 +F src/shell.c.in 3701177f3821330c8eb2af96f60123245cf42273abdae472bcb96bb120dcba8f F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1226,7 +1226,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/recover.test a8fed5acf2742268e366abb76a01de6ddce278aae01658488b950c968ebef638 +F test/recover.test bfeb5ab4574f9a264b3893ce0e41f04c2052b72b174e5dd9d847b6e7b8f4d15c F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 @@ -1821,7 +1821,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 bee2652ac26370e612a8c81dd7554befc2d523442a2fbbc77dc73479e6a0d7fd -R 52eb405413df1bbf1e7b369ddce62695 +P 7221f6e33ed6a5a96ec61e25f2a1f70b84aae66e503d897eb7b7ff1aec42355d +R e71b5bc56d773e53b87820c68d2be836 U dan -Z 87ebd735a2a8d2115b37082d2935a00e +Z d098c243e647f537ccde95cbf714168f diff --git a/manifest.uuid b/manifest.uuid index 3cfd1fa139..6b5834e3bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7221f6e33ed6a5a96ec61e25f2a1f70b84aae66e503d897eb7b7ff1aec42355d \ No newline at end of file +91df4b8e0386105d01614921e8410994b621404a3d46ec4af8687b8743c52d52 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 0737a347a0..f906205bff 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6290,6 +6290,11 @@ static RecoverTable *recoverOldTable( const char *zPk = "_rowid_"; sqlite3_stmt *pPkFinder = 0; + /* If this is an intkey table and there is an INTEGER PRIMARY KEY, + ** set zPk to the name of the PK column, and pTab->iPk to the index + ** of the column, where columns are 0-numbered from left to right. + ** Or, if this is a WITHOUT ROWID table or if there is no IPK column, + ** leave zPk as "_rowid_" and pTab->iPk at -2. */ pTab->iPk = -2; if( bIntkey ){ shellPreparePrintf(dbtmp, &rc, &pPkFinder, @@ -6317,9 +6322,11 @@ static RecoverTable *recoverOldTable( i = 1; shellPreparePrintf(dbtmp, &rc, &pStmt, "SELECT %Q || group_concat(name, ', ') " - " FILTER (WHERE cid!=%d) OVER (ORDER BY cid) " + " FILTER (WHERE cid!=%d) OVER (ORDER BY %s cid) " "FROM pragma_table_info(%Q)", - bIntkey ? ", " : "", pTab->iPk, zName + bIntkey ? ", " : "", pTab->iPk, + bIntkey ? "" : "(CASE WHEN pk=0 THEN 1000000 ELSE pk END), ", + zName ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ const char *zText = (const char*)sqlite3_column_text(pStmt, 0); diff --git a/test/recover.test b/test/recover.test index 6ee35054f8..4de7f503a5 100644 --- a/test/recover.test +++ b/test/recover.test @@ -85,4 +85,15 @@ do_execsql_test 1.3.1 " " do_recover_test 1.3.2 +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.1.0 { + CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID; + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} + +do_recover_test 2.1.1 + finish_test From 42ebb01e9fd94c94d4f90b0a59b46194aea28400 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Apr 2019 18:47:03 +0000 Subject: [PATCH 045/132] Add the "--lost-and-found" option to the ".recover" command. For setting the name of the orphaned rows table. FossilOrigin-Name: 67bb88e24c74d02ae0c4ac6ff2f873f6b0035ccefe5cccfc71c5686cbc76b4c3 --- ext/misc/dbdata.c | 131 ++++++++++++++++++++++++++-------------- manifest | 16 ++--- manifest.uuid | 2 +- src/shell.c.in | 150 ++++++++++++++++++++++++++++++++-------------- test/recover.test | 36 ++++++++++- 5 files changed, 234 insertions(+), 101 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index a27f19dc7a..786369ce0a 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -10,10 +10,14 @@ ** ****************************************************************************** ** -** This file contains an implementation of the eponymous "sqlite_dbdata" -** virtual table. sqlite_dbdata is used to extract data directly from a -** database b-tree page and its associated overflow pages, bypassing the b-tree -** layer. The table schema is equivalent to: +** This file contains an implementation of two eponymous virtual tables, +** "sqlite_dbdata" and "sqlite_dbptr". Both modules require that the +** "sqlite_dbpage" eponymous virtual table be available. +** +** SQLITE_DBDATA: +** sqlite_dbdata is used to extract data directly from a database b-tree +** page and its associated overflow pages, bypassing the b-tree layer. +** The table schema is equivalent to: ** ** CREATE TABLE sqlite_dbdata( ** pgno INTEGER, @@ -23,23 +27,25 @@ ** schema TEXT HIDDEN ** ); ** -** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE -** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND "schema". +** IMPORTANT: THE VIRTUAL TABLE SCHEMA ABOVE IS SUBJECT TO CHANGE. IN THE +** FUTURE NEW NON-HIDDEN COLUMNS MAY BE ADDED BETWEEN "value" AND +** "schema". ** -** Each page of the database is inspected. If it cannot be interpreted as a -** b-tree page, or if it is a b-tree page containing 0 entries, the -** sqlite_dbdata table contains no rows for that page. Otherwise, the table -** contains one row for each field in the record associated with each -** cell on the page. For intkey b-trees, the key value is stored in field -1. +** Each page of the database is inspected. If it cannot be interpreted as +** a b-tree page, or if it is a b-tree page containing 0 entries, the +** sqlite_dbdata table contains no rows for that page. Otherwise, the +** table contains one row for each field in the record associated with +** each cell on the page. For intkey b-trees, the key value is stored in +** field -1. ** -** For example, for the database: +** For example, for the database: ** ** CREATE TABLE t1(a, b); -- root page is page 2 ** INSERT INTO t1(rowid, a, b) VALUES(5, 'v', 'five'); ** INSERT INTO t1(rowid, a, b) VALUES(10, 'x', 'ten'); ** -** the sqlite_dbdata table contains, as well as from entries related to -** page 1, content equivalent to: +** the sqlite_dbdata table contains, as well as from entries related to +** page 1, content equivalent to: ** ** INSERT INTO sqlite_dbdata(pgno, cell, field, value) VALUES ** (2, 0, -1, 5 ), @@ -49,19 +55,21 @@ ** (2, 1, 0, 'x' ), ** (2, 1, 1, 'ten' ); ** -** If database corruption is encountered, this module does not report an -** error. Instead, it attempts to extract as much data as possible and -** ignores the corruption. -** -** This module requires that the "sqlite_dbpage" eponymous virtual table be -** available. +** If database corruption is encountered, this module does not report an +** error. Instead, it attempts to extract as much data as possible and +** ignores the corruption. ** +** SQLITE_DBPTR: +** The sqlite_dbptr table has the following schema: ** ** CREATE TABLE sqlite_dbptr( ** pgno INTEGER, ** child INTEGER, ** schema TEXT HIDDEN ** ); +** +** It contains one entry for each b-tree pointer between a parent and +** child page in the database. */ #if !defined(SQLITEINT_H) #include "sqlite3ext.h" @@ -77,8 +85,7 @@ SQLITE_EXTENSION_INIT1 typedef struct DbdataTable DbdataTable; typedef struct DbdataCursor DbdataCursor; - -/* A cursor for the sqlite_dbdata table */ +/* Cursor object */ struct DbdataCursor { sqlite3_vtab_cursor base; /* Base class. Must be first */ sqlite3_stmt *pStmt; /* For fetching database pages */ @@ -103,7 +110,7 @@ struct DbdataCursor { sqlite3_int64 iIntkey; /* Integer key value */ }; -/* The sqlite_dbdata table */ +/* Table object */ struct DbdataTable { sqlite3_vtab base; /* Base class. Must be first */ sqlite3 *db; /* The database connection */ @@ -111,16 +118,12 @@ struct DbdataTable { int bPtr; /* True for sqlite3_dbptr table */ }; +/* Column and schema definitions for sqlite_dbdata */ #define DBDATA_COLUMN_PGNO 0 #define DBDATA_COLUMN_CELL 1 #define DBDATA_COLUMN_FIELD 2 #define DBDATA_COLUMN_VALUE 3 #define DBDATA_COLUMN_SCHEMA 4 - -#define DBPTR_COLUMN_PGNO 0 -#define DBPTR_COLUMN_CHILD 1 -#define DBPTR_COLUMN_SCHEMA 2 - #define DBDATA_SCHEMA \ "CREATE TABLE x(" \ " pgno INTEGER," \ @@ -130,6 +133,10 @@ struct DbdataTable { " schema TEXT HIDDEN" \ ")" +/* Column and schema definitions for sqlite_dbptr */ +#define DBPTR_COLUMN_PGNO 0 +#define DBPTR_COLUMN_CHILD 1 +#define DBPTR_COLUMN_SCHEMA 2 #define DBPTR_SCHEMA \ "CREATE TABLE x(" \ " pgno INTEGER," \ @@ -138,7 +145,8 @@ struct DbdataTable { ")" /* -** Connect to the sqlite_dbdata virtual table. +** Connect to an sqlite_dbdata (pAux==0) or sqlite_dbptr (pAux!=0) virtual +** table. */ static int dbdataConnect( sqlite3 *db, @@ -166,7 +174,7 @@ static int dbdataConnect( } /* -** Disconnect from or destroy a dbdata virtual table. +** Disconnect from or destroy a sqlite_dbdata or sqlite_dbptr virtual table. */ static int dbdataDisconnect(sqlite3_vtab *pVtab){ DbdataTable *pTab = (DbdataTable*)pVtab; @@ -178,7 +186,6 @@ static int dbdataDisconnect(sqlite3_vtab *pVtab){ } /* -** ** This function interprets two types of constraints: ** ** schema=? @@ -239,7 +246,7 @@ static int dbdataBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdx){ } /* -** Open a new dbdata cursor. +** Open a new sqlite_dbdata or sqlite_dbptr cursor. */ static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ DbdataCursor *pCsr; @@ -256,6 +263,10 @@ static int dbdataOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return SQLITE_OK; } +/* +** Restore a cursor object to the state it was in when first allocated +** by dbdataOpen(). +*/ static void dbdataResetCursor(DbdataCursor *pCsr){ DbdataTable *pTab = (DbdataTable*)(pCsr->base.pVtab); if( pTab->pStmt==0 ){ @@ -271,7 +282,7 @@ static void dbdataResetCursor(DbdataCursor *pCsr){ } /* -** Close a dbdata cursor. +** Close an sqlite_dbdata or sqlite_dbptr cursor. */ static int dbdataClose(sqlite3_vtab_cursor *pCursor){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; @@ -280,8 +291,9 @@ static int dbdataClose(sqlite3_vtab_cursor *pCursor){ return SQLITE_OK; } - -/* Decode big-endian integers */ +/* +** Utility methods to decode 16 and 32-bit big-endian unsigned integers. +*/ static unsigned int get_uint16(unsigned char *a){ return (a[0]<<8)|a[1]; } @@ -289,11 +301,21 @@ static unsigned int get_uint32(unsigned char *a){ return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3]; } +/* +** Load page pgno from the database via the sqlite_dbpage virtual table. +** If successful, set (*ppPage) to point to a buffer containing the page +** data, (*pnPage) to the size of that buffer in bytes and return +** SQLITE_OK. In this case it is the responsibility of the caller to +** eventually free the buffer using sqlite3_free(). +** +** Or, if an error occurs, set both (*ppPage) and (*pnPage) to 0 and +** return an SQLite error code. +*/ static int dbdataLoadPage( - DbdataCursor *pCsr, - u32 pgno, - u8 **ppPage, - int *pnPage + DbdataCursor *pCsr, /* Cursor object */ + u32 pgno, /* Page number of page to load */ + u8 **ppPage, /* OUT: pointer to page buffer */ + int *pnPage /* OUT: Size of (*ppPage) in bytes */ ){ int rc2; int rc = SQLITE_OK; @@ -338,6 +360,10 @@ static int dbdataGetVarint(const u8 *z, sqlite3_int64 *pVal){ return 9; } +/* +** Return the number of bytes of space used by an SQLite value of type +** eType. +*/ static int dbdataValueBytes(int eType){ switch( eType ){ case 0: case 8: case 9: @@ -361,6 +387,10 @@ static int dbdataValueBytes(int eType){ } } +/* +** Load a value of type eType from buffer pData and use it to set the +** result of context object pCtx. +*/ static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ switch( eType ){ case 0: @@ -411,7 +441,7 @@ static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ /* -** Move a dbdata cursor to the next entry in the file. +** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry. */ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; @@ -575,14 +605,20 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ return SQLITE_OK; } -/* We have reached EOF if previous sqlite3_step() returned -** anything other than SQLITE_ROW; +/* +** Return true if the cursor is at EOF. */ static int dbdataEof(sqlite3_vtab_cursor *pCursor){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; return pCsr->aPage==0; } +/* +** Determine the size in pages of database zSchema (where zSchema is +** "main", "temp" or the name of an attached database) and set +** pCsr->szDb accordingly. If successful, return SQLITE_OK. Otherwise, +** an SQLite error code. +*/ static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){ DbdataTable *pTab = (DbdataTable*)pCsr->base.pVtab; char *zSql = 0; @@ -601,7 +637,8 @@ static int dbdataDbsize(DbdataCursor *pCsr, const char *zSchema){ return rc; } -/* Position a cursor back to the beginning. +/* +** xFilter method for sqlite_dbdata and sqlite_dbptr. */ static int dbdataFilter( sqlite3_vtab_cursor *pCursor, @@ -648,7 +685,9 @@ static int dbdataFilter( return rc; } -/* Return a column for the sqlite_dbdata table */ +/* +** Return a column for the sqlite_dbdata or sqlite_dbptr table. +*/ static int dbdataColumn( sqlite3_vtab_cursor *pCursor, sqlite3_context *ctx, @@ -699,7 +738,9 @@ static int dbdataColumn( return SQLITE_OK; } -/* Return the ROWID for the sqlite_dbdata table */ +/* +** Return the rowid for an sqlite_dbdata or sqlite_dptr table. +*/ static int dbdataRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ DbdataCursor *pCsr = (DbdataCursor*)pCursor; *pRowid = pCsr->iRowid; diff --git a/manifest b/manifest index 94b2e05ed0..2f2f86a8fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\s.recover\scommand\swith\srecovering\sWITHOUT\sROWID\stables\swhere\sthe\sPK\scolumns\sare\snot\sthe\sleftmost\sin\sthe\sCREATE\sTABLE\sstatement. -D 2019-04-27T15:35:45.828 +C Add\sthe\s"--lost-and-found"\soption\sto\sthe\s".recover"\scommand.\sFor\ssetting\sthe\sname\sof\sthe\sorphaned\srows\stable. +D 2019-04-27T18:47:03.466 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c b7547f43906f9296e43be807ca78e2ef3f335ca26d6e91d178df30cd2fd46572 +F ext/misc/dbdata.c fe978dad2df13dd4b377b5d38f4883282801b18711220a229d0fd266a5deab26 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 3701177f3821330c8eb2af96f60123245cf42273abdae472bcb96bb120dcba8f +F src/shell.c.in 51f027f6b48fab39e0745915d979747880b7c35827798535726ac44366a291f1 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1226,7 +1226,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/recover.test bfeb5ab4574f9a264b3893ce0e41f04c2052b72b174e5dd9d847b6e7b8f4d15c +F test/recover.test 52609c8cc24e72d3d8a20fb8bc32ba2ce8ca2093a7f4573bd4f2969f78f6d2b4 F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 @@ -1821,7 +1821,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 7221f6e33ed6a5a96ec61e25f2a1f70b84aae66e503d897eb7b7ff1aec42355d -R e71b5bc56d773e53b87820c68d2be836 +P 91df4b8e0386105d01614921e8410994b621404a3d46ec4af8687b8743c52d52 +R a9542f620433fc5d37a56caa32ea75c3 U dan -Z d098c243e647f537ccde95cbf714168f +Z 07c2469e7eeced685ce45289494bc94e diff --git a/manifest.uuid b/manifest.uuid index 6b5834e3bb..e6d0f63ea7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91df4b8e0386105d01614921e8410994b621404a3d46ec4af8687b8743c52d52 \ No newline at end of file +67bb88e24c74d02ae0c4ac6ff2f873f6b0035ccefe5cccfc71c5686cbc76b4c3 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index f906205bff..8c967a83d8 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1104,7 +1104,6 @@ struct ShellState { #define SHFLG_Newlines 0x00000010 /* .dump --newline flag */ #define SHFLG_CountChanges 0x00000020 /* .changes setting */ #define SHFLG_Echo 0x00000040 /* .echo or --echo setting */ -#define SHFLG_Recover 0x00000080 /* .dump is --recover */ /* ** Macros for testing and setting shellFlgs @@ -3577,6 +3576,7 @@ static const char *(azHelp[]) = { ".prompt MAIN CONTINUE Replace the standard prompts", ".quit Exit this program", ".read FILE Read input from FILE", + ".recover Recover as much data as possible from corrupt db.", ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".save FILE Write in-memory database into FILE", ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off", @@ -6153,6 +6153,12 @@ end_ar_command: **********************************************************************************/ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ +/* +** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, the SQL statement or statements in zSql are executed using +** database connection db and the error code written to *pRc before +** this function returns. +*/ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){ int rc = *pRc; if( rc==SQLITE_OK ){ @@ -6165,6 +6171,9 @@ static void shellExec(sqlite3 *db, int *pRc, const char *zSql){ } } +/* +** Like shellExec(), except that zFmt is a printf() style format string. +*/ static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){ char *z = 0; if( *pRc==SQLITE_OK ){ @@ -6181,6 +6190,12 @@ static void shellExecPrintf(sqlite3 *db, int *pRc, const char *zFmt, ...){ } } +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, an attempt is made to allocate, zero and return a pointer +** to a buffer nByte bytes in size. If an OOM error occurs, *pRc is set +** to SQLITE_NOMEM and NULL returned. +*/ static void *shellMalloc(int *pRc, sqlite3_int64 nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ @@ -6194,6 +6209,17 @@ static void *shellMalloc(int *pRc, sqlite3_int64 nByte){ return pRet; } +/* +** If *pRc is not SQLITE_OK when this function is called, it is a no-op. +** Otherwise, zFmt is treated as a printf() style string. The result of +** formatting it along with any trailing arguments is written into a +** buffer obtained from sqlite3_malloc(), and pointer to which is returned. +** It is the responsibility of the caller to eventually free this buffer +** using a call to sqlite3_free(). +** +** If an OOM error occurs, (*pRc) is set to SQLITE_NOMEM and a NULL +** pointer returned. +*/ static char *shellMPrintf(int *pRc, const char *zFmt, ...){ char *z = 0; if( *pRc==SQLITE_OK ){ @@ -6208,21 +6234,25 @@ static char *shellMPrintf(int *pRc, const char *zFmt, ...){ return z; } +/* +** When running the ".recover" command, each output table, and the special +** orphaned row table if it is required, is represented by an instance +** of the following struct. +*/ typedef struct RecoverTable RecoverTable; struct RecoverTable { - char *zName; /* Name of table */ - char *zQuoted; /* Quoted version of zName */ + char *zQuoted; /* Quoted version of table name */ int nCol; /* Number of columns in table */ char **azlCol; /* Array of column lists */ - int iPk; + int iPk; /* Index of IPK column */ }; /* -** Free a RecoverTable object allocated by recoverNewTable() +** Free a RecoverTable object allocated by recoverFindTable() or +** recoverOrphanTable(). */ static void recoverFreeTable(RecoverTable *pTab){ if( pTab ){ - sqlite3_free(pTab->zName); sqlite3_free(pTab->zQuoted); if( pTab->azlCol ){ int i; @@ -6235,7 +6265,14 @@ static void recoverFreeTable(RecoverTable *pTab){ } } -static RecoverTable *recoverOldTable( +/* +** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. +** Otherwise, it allocates and returns a RecoverTable object based on the +** final four arguments passed to this function. It is the responsibility +** of the caller to eventually free the returned object using +** recoverFreeTable(). +*/ +static RecoverTable *recoverNewTable( int *pRc, /* IN/OUT: Error code */ const char *zName, /* Name of table */ const char *zSql, /* CREATE TABLE statement */ @@ -6309,8 +6346,7 @@ static RecoverTable *recoverOldTable( } } - pTab->zName = shellMPrintf(&rc, "%s", zName); - pTab->zQuoted = shellMPrintf(&rc, "%Q", pTab->zName); + pTab->zQuoted = shellMPrintf(&rc, "%Q", zName); pTab->azlCol = (char**)shellMalloc(&rc, sizeof(char*) * (nSqlCol+1)); pTab->nCol = nSqlCol; @@ -6349,7 +6385,7 @@ static RecoverTable *recoverOldTable( return pTab; } -static RecoverTable *recoverNewTable( +static RecoverTable *recoverFindTable( ShellState *pState, int *pRc, int iRoot, @@ -6363,7 +6399,6 @@ static RecoverTable *recoverNewTable( const char *zSql = 0; const char *zName = 0; - /* Search the recovered schema for an object with root page iRoot. */ shellPreparePrintf(pState->db, pRc, &pStmt, "SELECT type, name, sql FROM recovery.schema WHERE rootpage=%d", iRoot @@ -6377,7 +6412,7 @@ static RecoverTable *recoverNewTable( if( sqlite3_stricmp(zType, "table")==0 ){ zName = (const char*)sqlite3_column_text(pStmt, 1); zSql = (const char*)sqlite3_column_text(pStmt, 2); - pRet = recoverOldTable(pRc, zName, zSql, bIntkey, nCol); + pRet = recoverNewTable(pRc, zName, zSql, bIntkey, nCol); break; } } @@ -6390,24 +6425,35 @@ static RecoverTable *recoverNewTable( static RecoverTable *recoverOrphanTable( ShellState *pState, int *pRc, + const char *zLostAndFound, int nCol ){ RecoverTable *pTab = 0; if( nCol>=0 && *pRc==SQLITE_OK ){ int i; - raw_printf(pState->out, - "CREATE TABLE recover_orphan(rootpgno INTEGER, " - "pgno INTEGER, nfield INTEGER, id INTEGER" + + /* This block determines the name of the orphan table. The prefered + ** name is zLostAndFound. But if that clashes with another name + ** in the recovered schema, try zLostAndFound_0, zLostAndFound_1 + ** and so on until a non-clashing name is found. */ + int iTab = 0; + char *zTab = shellMPrintf(pRc, "%s", zLostAndFound); + sqlite3_stmt *pTest = 0; + shellPrepare(pState->db, pRc, + "SELECT 1 FROM recovery.schema WHERE name=?", &pTest ); - for(i=0; iout, ", c%d", i); + if( pTest ) sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT); + while( *pRc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pTest) ){ + shellReset(pRc, pTest); + sqlite3_free(zTab); + zTab = shellMPrintf(pRc, "%s_%d", zLostAndFound, iTab++); + sqlite3_bind_text(pTest, 1, zTab, -1, SQLITE_TRANSIENT); } - raw_printf(pState->out, ");\n"); + shellFinalize(pRc, pTest); pTab = (RecoverTable*)shellMalloc(pRc, sizeof(RecoverTable)); if( pTab ){ - pTab->zName = shellMPrintf(pRc, "%s", "recover_orphan"); - pTab->zQuoted = shellMPrintf(pRc, "%Q", pTab->zName); + pTab->zQuoted = shellMPrintf(pRc, "%Q", zTab); pTab->nCol = nCol; pTab->iPk = -2; if( nCol>0 ){ @@ -6419,12 +6465,22 @@ static RecoverTable *recoverOrphanTable( } } } - } - if( *pRc!=SQLITE_OK ){ - recoverFreeTable(pTab); - pTab = 0; + if( *pRc!=SQLITE_OK ){ + recoverFreeTable(pTab); + pTab = 0; + }else{ + raw_printf(pState->out, + "CREATE TABLE %s(rootpgno INTEGER, " + "pgno INTEGER, nfield INTEGER, id INTEGER", pTab->zQuoted + ); + for(i=0; iout, ", c%d", i); + } + raw_printf(pState->out, ");\n"); + } } + sqlite3_free(zTab); } return pTab; } @@ -6440,6 +6496,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ sqlite3_stmt *pPages = 0; /* Loop through all pages in a group */ sqlite3_stmt *pCells = 0; /* Loop through all cells in a page */ const char *zRecoveryDb = ""; /* Name of "recovery" database */ + const char *zLostAndFound = "lost_and_found"; int i; int nOrphan = -1; RecoverTable *pOrphan = 0; @@ -6452,16 +6509,21 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ n = strlen(z); if( n<=17 && memcmp("-freelist-corrupt", z, n)==0 ){ bFreelist = 0; - } + }else if( n<=12 && memcmp("-recovery-db", z, n)==0 && i<(nArg-1) ){ i++; zRecoveryDb = azArg[i]; + }else + if( n<=15 && memcmp("-lost-and-found", z, n)==0 && i<(nArg-1) ){ + i++; + zLostAndFound = azArg[i]; } else{ raw_printf(stderr, "unexpected option: %s\n", azArg[i]); raw_printf(stderr, "options are:\n"); raw_printf(stderr, " --freelist-corrupt\n"); raw_printf(stderr, " --recovery-db DATABASE\n"); + raw_printf(stderr, " --lost-and-found TABLE-NAME\n"); return 1; } } @@ -6599,7 +6661,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } shellFinalize(&rc, pLoop); pLoop = 0; - pOrphan = recoverOrphanTable(pState, &rc, nOrphan); + pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan); shellPrepare(pState->db, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages @@ -6624,11 +6686,11 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ int bNoop = 0; RecoverTable *pTab; - pTab = recoverNewTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); + pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); if( bNoop || rc ) continue; if( pTab==0 ) pTab = pOrphan; - if( 0==sqlite3_stricmp(pTab->zName, "sqlite_sequence") ){ + if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); } sqlite3_bind_int(pPages, 1, iRoot); @@ -7042,30 +7104,30 @@ static int do_meta_command(char *zLine, ShellState *p){ p->nErr = 0; if( zLike==0 ){ run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" - ); + "SELECT name, type, sql FROM sqlite_master " + "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'" + ); run_schema_dump_query(p, - "SELECT name, type, sql FROM sqlite_master " - "WHERE name=='sqlite_sequence'" - ); + "SELECT name, type, sql FROM sqlite_master " + "WHERE name=='sqlite_sequence'" + ); run_table_dump_query(p, - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 - ); + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0 + ); }else{ char *zSql; zSql = sqlite3_mprintf( - "SELECT name, type, sql FROM sqlite_master " - "WHERE tbl_name LIKE %Q AND type=='table'" - " AND sql NOT NULL", zLike); + "SELECT name, type, sql FROM sqlite_master " + "WHERE tbl_name LIKE %Q AND type=='table'" + " AND sql NOT NULL", zLike); run_schema_dump_query(p,zSql); sqlite3_free(zSql); zSql = sqlite3_mprintf( - "SELECT sql FROM sqlite_master " - "WHERE sql NOT NULL" - " AND type IN ('index','trigger','view')" - " AND tbl_name LIKE %Q", zLike); + "SELECT sql FROM sqlite_master " + "WHERE sql NOT NULL" + " AND type IN ('index','trigger','view')" + " AND tbl_name LIKE %Q", zLike); run_table_dump_query(p, zSql, 0); sqlite3_free(zSql); } diff --git a/test/recover.test b/test/recover.test index 4de7f503a5..4dad0d646d 100644 --- a/test/recover.test +++ b/test/recover.test @@ -39,7 +39,7 @@ proc compare_dbs {db1 db2} { } } -proc do_recover_test {tn} { +proc do_recover_test {tn {tsql {}} {res {}}} { set fd [open "|$::CLI test.db .recover"] fconfigure $fd -encoding binary fconfigure $fd -translation binary @@ -48,9 +48,12 @@ proc do_recover_test {tn} { forcedelete test.db2 sqlite3 db2 test.db2 - breakpoint execsql $sql db2 - uplevel [list do_test $tn [list compare_dbs db db2] {}] + if {$tsql==""} { + uplevel [list do_test $tn [list compare_dbs db db2] {}] + } else { + uplevel [list do_execsql_test -db db2 $tn $tsql $res] + } db2 close } @@ -96,4 +99,31 @@ do_execsql_test 2.1.0 { do_recover_test 2.1.1 +do_execsql_test 2.2.0 { + PRAGMA writable_schema = 1; + DELETE FROM sqlite_master WHERE name='t1'; +} +do_recover_test 2.2.1 { + SELECT name FROM sqlite_master +} {lost_and_found} + +do_execsql_test 2.3.0 { + CREATE TABLE lost_and_found(a, b, c); +} +do_recover_test 2.3.1 { + SELECT name FROM sqlite_master +} {lost_and_found lost_and_found_0} + +do_execsql_test 2.4.0 { + CREATE TABLE lost_and_found_0(a, b, c); +} +do_recover_test 2.4.1 { + SELECT name FROM sqlite_master; + SELECT * FROM lost_and_found_1; +} {lost_and_found lost_and_found_0 lost_and_found_1 + 2 2 3 {} 2 3 1 + 2 2 3 {} 5 6 4 + 2 2 3 {} 8 9 7 +} + finish_test From 0aa01ee42cd9616fdca75f97b88e861651481d3c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Apr 2019 19:36:49 +0000 Subject: [PATCH 046/132] Add comments and fix formatting issues in new code in shell.c.in. FossilOrigin-Name: b91d819bd16de43fc99e379da0ba9c915b0c5afc68e804a50c3c1662c1f9a740 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 38 ++++++++++++++++++++++++++++---------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 2f2f86a8fc..c4c8fd8087 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"--lost-and-found"\soption\sto\sthe\s".recover"\scommand.\sFor\ssetting\sthe\sname\sof\sthe\sorphaned\srows\stable. -D 2019-04-27T18:47:03.466 +C Add\scomments\sand\sfix\sformatting\sissues\sin\snew\scode\sin\sshell.c.in. +D 2019-04-27T19:36:49.564 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 51f027f6b48fab39e0745915d979747880b7c35827798535726ac44366a291f1 +F src/shell.c.in 2316b9ee7a43e6f127e5abe8d74d69b92f6bbae1be38826ffb58384aab832013 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 91df4b8e0386105d01614921e8410994b621404a3d46ec4af8687b8743c52d52 -R a9542f620433fc5d37a56caa32ea75c3 +P 67bb88e24c74d02ae0c4ac6ff2f873f6b0035ccefe5cccfc71c5686cbc76b4c3 +R 1520b643c98e19ff415724ed970cd8b1 U dan -Z 07c2469e7eeced685ce45289494bc94e +Z 3d67e0e6129b0deb0a86f6c6a9eda8ce diff --git a/manifest.uuid b/manifest.uuid index e6d0f63ea7..73bfbb6ae3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67bb88e24c74d02ae0c4ac6ff2f873f6b0035ccefe5cccfc71c5686cbc76b4c3 \ No newline at end of file +b91d819bd16de43fc99e379da0ba9c915b0c5afc68e804a50c3c1662c1f9a740 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 8c967a83d8..1fc08662db 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6385,13 +6385,28 @@ static RecoverTable *recoverNewTable( return pTab; } +/* +** This function is called to search the schema recovered from the +** sqlite_master table of the (possibly) corrupt database as part +** of a ".recover" command. Specifically, for a table with root page +** iRoot and at least nCol columns. Additionally, if bIntkey is 0, the +** table must be a WITHOUT ROWID table, or if non-zero, not one of +** those. +** +** If a table is found, a (RecoverTable*) object is returned. Or, if +** no such table is found, but bIntkey is false and iRoot is the +** root page of an index in the recovered schema, then (*pbNoop) is +** set to true and NULL returned. Or, if there is no such table or +** index, NULL is returned and (*pbNoop) set to 0, indicating that +** the caller should write data to the orphans table. +*/ static RecoverTable *recoverFindTable( - ShellState *pState, - int *pRc, - int iRoot, - int bIntkey, - int nCol, - int *pbNoop + ShellState *pState, /* Shell state object */ + int *pRc, /* IN/OUT: Error code */ + int iRoot, /* Root page of table */ + int bIntkey, /* True for an intkey table */ + int nCol, /* Number of columns in table */ + int *pbNoop /* OUT: True if iRoot is root of index */ ){ sqlite3_stmt *pStmt = 0; RecoverTable *pRet = 0; @@ -6422,11 +6437,14 @@ static RecoverTable *recoverFindTable( return pRet; } +/* +** Return a RecoverTable object representing the orphans table. +*/ static RecoverTable *recoverOrphanTable( - ShellState *pState, - int *pRc, - const char *zLostAndFound, - int nCol + ShellState *pState, /* Shell state object */ + int *pRc, /* IN/OUT: Error code */ + const char *zLostAndFound, /* Base name for orphans table */ + int nCol /* Number of user data columns */ ){ RecoverTable *pTab = 0; if( nCol>=0 && *pRc==SQLITE_OK ){ From 1b16216f9eb297ddebc36fd83d3c3816baad0163 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 27 Apr 2019 20:15:15 +0000 Subject: [PATCH 047/132] Fix building the shell with SQLITE_OMIT_VIRTUAL_TABLE. And without SQLITE_ENABLE_DBPAGE_VTAB. FossilOrigin-Name: 425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 --- ext/misc/dbdata.c | 5 ++--- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 21 +++++++++++++++++---- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 786369ce0a..0e7f7d59cc 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -75,7 +75,6 @@ #include "sqlite3ext.h" typedef unsigned char u8; -typedef unsigned long u32; #endif SQLITE_EXTENSION_INIT1 @@ -313,7 +312,7 @@ static unsigned int get_uint32(unsigned char *a){ */ static int dbdataLoadPage( DbdataCursor *pCsr, /* Cursor object */ - u32 pgno, /* Page number of page to load */ + unsigned int pgno, /* Page number of page to load */ u8 **ppPage, /* OUT: pointer to page buffer */ int *pnPage /* OUT: Size of (*ppPage) in bytes */ ){ @@ -556,7 +555,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ /* Load content from overflow pages */ if( nPayload>nLocal ){ sqlite3_int64 nRem = nPayload - nLocal; - u32 pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); + unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); while( nRem>0 ){ u8 *aOvfl = 0; int nOvfl = 0; diff --git a/manifest b/manifest index c4c8fd8087..1abc30e6f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\scomments\sand\sfix\sformatting\sissues\sin\snew\scode\sin\sshell.c.in. -D 2019-04-27T19:36:49.564 +C Fix\sbuilding\sthe\sshell\swith\sSQLITE_OMIT_VIRTUAL_TABLE.\sAnd\swithout\sSQLITE_ENABLE_DBPAGE_VTAB. +D 2019-04-27T20:15:15.393 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c fe978dad2df13dd4b377b5d38f4883282801b18711220a229d0fd266a5deab26 +F ext/misc/dbdata.c 1b3751b02d8f575d25c6bda358670d2e39ace368a0d05595989c308a10c615f6 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 2316b9ee7a43e6f127e5abe8d74d69b92f6bbae1be38826ffb58384aab832013 +F src/shell.c.in 104bbae904a2b67bc6c0c95337447544d15d0594dc46468608aae769d5f51da9 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 67bb88e24c74d02ae0c4ac6ff2f873f6b0035ccefe5cccfc71c5686cbc76b4c3 -R 1520b643c98e19ff415724ed970cd8b1 +P b91d819bd16de43fc99e379da0ba9c915b0c5afc68e804a50c3c1662c1f9a740 +R dcbe5105dfc58103275280fa56f0f458 U dan -Z 3d67e0e6129b0deb0a86f6c6a9eda8ce +Z a7824dfb7c5c59a3dfb17eb398274a3e diff --git a/manifest.uuid b/manifest.uuid index 73bfbb6ae3..3985d129a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b91d819bd16de43fc99e379da0ba9c915b0c5afc68e804a50c3c1662c1f9a740 \ No newline at end of file +425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 1fc08662db..2f9a2456a1 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -948,7 +948,9 @@ INCLUDE ../ext/misc/sqlar.c INCLUDE ../ext/expert/sqlite3expert.h INCLUDE ../ext/expert/sqlite3expert.c +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) INCLUDE ../ext/misc/dbdata.c +#endif #if defined(SQLITE_ENABLE_SESSION) /* @@ -3576,7 +3578,9 @@ static const char *(azHelp[]) = { ".prompt MAIN CONTINUE Replace the standard prompts", ".quit Exit this program", ".read FILE Read input from FILE", +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) ".recover Recover as much data as possible from corrupt db.", +#endif ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".save FILE Write in-memory database into FILE", ".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off", @@ -4121,7 +4125,9 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_fileio_init(p->db, 0, 0); sqlite3_shathree_init(p->db, 0, 0); sqlite3_completion_init(p->db, 0, 0); +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) sqlite3_dbdata_init(p->db, 0, 0); +#endif #ifdef SQLITE_HAVE_ZLIB sqlite3_zipfile_init(p->db, 0, 0); sqlite3_sqlar_init(p->db, 0, 0); @@ -5390,10 +5396,7 @@ static int lintDotCommand( return SQLITE_ERROR; } -#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) -/********************************************************************************* -** The ".archive" or ".ar" command. -*/ +#if !defined SQLITE_OMIT_VIRTUALTABLE static void shellPrepare( sqlite3 *db, int *pRc, @@ -5464,6 +5467,12 @@ static void shellReset( *pRc = rc; } } +#endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) +/********************************************************************************* +** The ".archive" or ".ar" command. +*/ /* ** Structure representing a single ".ar" command. */ @@ -6153,6 +6162,7 @@ end_ar_command: **********************************************************************************/ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) /* ** If (*pRc) is not SQLITE_OK when this function is called, it is a no-op. ** Otherwise, the SQL statement or statements in zSql are executed using @@ -6775,6 +6785,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ sqlite3_exec(pState->db, "DETACH recovery", 0, 0, 0); return rc; } +#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */ /* @@ -7063,10 +7074,12 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = shell_dbinfo_command(p, nArg, azArg); }else +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) if( c=='r' && strncmp(azArg[0], "recover", n)==0 ){ open_db(p, 0); rc = recoverDatabaseCmd(p, nArg, azArg); }else +#endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */ if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ const char *zLike = 0; From 6c59136498547fefb69e3edaff4d949b0bf1113e Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 27 Apr 2019 20:16:42 +0000 Subject: [PATCH 048/132] Fix a minor typo in a comment. No changes to code. FossilOrigin-Name: 95209072176ff21a91e96d5bd014b35ef100da2b0b93958baf6df4294a8daa85 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 158d60af72..1b2109530a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\stests\sof\sthe\sLIKE\soptimization\sin\slike3.test\swhen\sSQLITE_ENABLE_ICU\sis\sdefined. -D 2019-04-26T17:08:50.839 +C Fix\sa\sminor\stypo\sin\sa\scomment.\s\sNo\schanges\sto\scode. +D 2019-04-27T20:16:42.497 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -462,7 +462,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 61655dad911a967a69fb49df57268fd15ce8f1af3fe0a1bd90c128ef2cacfb7a +F src/build.c e9d560fdc39e0f037b1ebd78fde0ff616963646c8d85a7afa18db064c52c5b75 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -1818,7 +1818,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 7be6222c9ec44596e4eddd906c831eb1272b90fbdf68641d791f216264feb7cf -R 1ba2bc865b250121afcb0af52a507e48 -U dan -Z 432d74fc77b640bcf830ac2298b92cb0 +P af53c41a127c314c0608f3fd016d3a26896783745e46cd180976a188400cdb75 +R 5d8e72521d268ff442af4eda367a86ab +U drh +Z c27e4c4c6167f0761ffa85b745f3dbd7 diff --git a/manifest.uuid b/manifest.uuid index 0646b8052e..9bb2a9c04f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -af53c41a127c314c0608f3fd016d3a26896783745e46cd180976a188400cdb75 \ No newline at end of file +95209072176ff21a91e96d5bd014b35ef100da2b0b93958baf6df4294a8daa85 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9ecd31b8e8..3e4101df92 100644 --- a/src/build.c +++ b/src/build.c @@ -1329,7 +1329,7 @@ void sqlite3AddDefaultValue( ** accept it. This routine does the necessary conversion. It converts ** the expression given in its argument from a TK_STRING into a TK_ID ** if the expression is just a TK_STRING with an optional COLLATE clause. -** If the epxression is anything other than TK_STRING, the expression is +** If the expression is anything other than TK_STRING, the expression is ** unchanged. */ static void sqlite3StringToId(Expr *p){ From f78d0f426c2ce84904823a087e3950e343c8e6ec Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 28 Apr 2019 19:27:02 +0000 Subject: [PATCH 049/132] Take collating sequence into account when removing redundant columns from indexes on WITHOUT ROWID tables. This is the first proof-of-concept fix for ticket [3182d3879020ef3]. More testing needed. FossilOrigin-Name: b34fa5bff40d3d364bd8c80e7de55c606ef3caac47b14b5265ebcb38857eb85e --- manifest | 18 +++++++++-------- manifest.uuid | 2 +- src/build.c | 54 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index ffbce1300f..dec5885b95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".recover"\scommand\sto\sthe\sshell\stool.\sFor\srecovering\sas\smuch\sdata\sas\spossible\sfrom\scorrupt\sdatabases. -D 2019-04-27T20:30:19.423 +C Take\scollating\ssequence\sinto\saccount\swhen\sremoving\sredundant\scolumns\sfrom\nindexes\son\sWITHOUT\sROWID\stables.\s\sThis\sis\sthe\sfirst\sproof-of-concept\sfix\nfor\sticket\s[3182d3879020ef3].\sMore\stesting\sneeded. +D 2019-04-28T19:27:02.781 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -463,7 +463,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c e9d560fdc39e0f037b1ebd78fde0ff616963646c8d85a7afa18db064c52c5b75 +F src/build.c 3fedab95ff7a9b3ed51eceb12aaa61de6bbd063dabd276767494cc448a151b7b F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -1821,8 +1821,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 95209072176ff21a91e96d5bd014b35ef100da2b0b93958baf6df4294a8daa85 425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 -R f359cf293ea45304e0ddadd16c7a1206 -T +closed 425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 -U dan -Z ee7f2d083d1fca64ba3bb33b40a19208 +P 50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 +R fa5b9567c2bc0a92e3c8181fab56d7f8 +T *branch * tkt-3182d38790 +T *sym-tkt-3182d38790 * +T -sym-trunk * +U drh +Z dd82847aa38c87860cc4ec05cc3ab230 diff --git a/manifest.uuid b/manifest.uuid index 55700b6967..6c45322202 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 \ No newline at end of file +b34fa5bff40d3d364bd8c80e7de55c606ef3caac47b14b5265ebcb38857eb85e \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3e4101df92..fac3163eba 100644 --- a/src/build.c +++ b/src/build.c @@ -1726,10 +1726,46 @@ static void estimateIndexWidth(Index *pIdx){ pIdx->szIdxRow = sqlite3LogEst(wIndex*4); } -/* Return true if value x is found any of the first nCol entries of aiCol[] +/* Return true if column number x is any of the first nCol entries of aiCol[]. +** This is used to determine if the column number x appears in any of the +** first nCol entries of an index. */ static int hasColumn(const i16 *aiCol, int nCol, int x){ - while( nCol-- > 0 ) if( x==*(aiCol++) ) return 1; + while( nCol-- > 0 ){ + assert( aiCol[0]>=0 ); + if( x==*(aiCol++) ){ + return 1; + } + } + return 0; +} + +/* +** Return true if any of the first nKey entries of index pIdx1 exactly +** match the iCol-th entry of pIdx2. +** +** The first nKey entries of pIdx1 are guaranteed to be ordinary columns, +** not a rowid or expression. +** +** This routine differs from hasColumn() in that both the column and the +** collating sequence must match for this routine, but for hasColumn() only +** the column name must match. +*/ +static int isDupColumn(Index *pIdx1, int nKey, Index *pIdx2, int iCol){ + int i, j; + assert( nKey<=pIdx1->nColumn ); + assert( iColnColumn,pIdx2->nKeyCol) ); + j = pIdx2->aiColumn[iCol]; + testcase( j==XN_EXPR ); + assert( j!=XN_ROWID ); + for(i=0; iaiColumn[i]>=0 || j>=0 ); + if( pIdx1->aiColumn[i]==j + && sqlite3StrICmp(pIdx1->azColl[i],pIdx2->azColl[iCol])==0 + ){ + return 1; + } + } return 0; } @@ -1835,9 +1871,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** code assumes the PRIMARY KEY contains no repeated columns. */ for(i=j=1; inKeyCol; i++){ - if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){ + if( isDupColumn(pPk, j, pPk, i) ){ pPk->nColumn--; }else{ + testcase( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ); pPk->aiColumn[j++] = pPk->aiColumn[i]; } } @@ -1867,7 +1904,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ int n; if( IsPrimaryKeyIndex(pIdx) ) continue; for(i=n=0; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ) n++; + if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); + n++; + } } if( n==0 ){ /* This index is a superset of the primary key */ @@ -1876,7 +1916,8 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ } if( resizeIndexObject(db, pIdx, pIdx->nKeyCol+n) ) return; for(i=0, j=pIdx->nKeyCol; iaiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ){ + if( !isDupColumn(pIdx, pIdx->nKeyCol, pPk, i) ){ + testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); pIdx->aiColumn[j] = pPk->aiColumn[i]; pIdx->azColl[j] = pPk->azColl[i]; j++; @@ -3392,9 +3433,10 @@ void sqlite3CreateIndex( for(j=0; jnKeyCol; j++){ int x = pPk->aiColumn[j]; assert( x>=0 ); - if( hasColumn(pIndex->aiColumn, pIndex->nKeyCol, x) ){ + if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){ pIndex->nColumn--; }else{ + testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) ); pIndex->aiColumn[i] = x; pIndex->azColl[i] = pPk->azColl[j]; pIndex->aSortOrder[i] = pPk->aSortOrder[j]; From 490e6f2506a1ebd37c2acdddcd2484d7b59d8071 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 29 Apr 2019 11:27:58 +0000 Subject: [PATCH 050/132] Fix a stack overflow that could occur when renaming a table that has a trigger containing a window function invocation that itself contains a specific syntax error. FossilOrigin-Name: c621fc668c6538f9f5bdac204f012c64998679a61aa8e224d212503820224c09 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/resolve.c | 4 +++- test/altertab3.test | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ffbce1300f..58229ddb68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s".recover"\scommand\sto\sthe\sshell\stool.\sFor\srecovering\sas\smuch\sdata\sas\spossible\sfrom\scorrupt\sdatabases. -D 2019-04-27T20:30:19.423 +C Fix\sa\sstack\soverflow\sthat\scould\soccur\swhen\srenaming\sa\stable\sthat\shas\sa\strigger\scontaining\sa\swindow\sfunction\sinvocation\sthat\sitself\scontains\sa\sspecific\ssyntax\serror. +D 2019-04-29T11:27:58.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -517,7 +517,7 @@ F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177 F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3 F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 567888ee3faec14dae06519b4306201771058364a37560186a3e0e755ebc4cb8 +F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 F src/shell.c.in 104bbae904a2b67bc6c0c95337447544d15d0594dc46468608aae769d5f51da9 @@ -629,7 +629,7 @@ F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b F test/altertab.test 372df7d8f09e1ee22d23551677cedff3b048b0059c1f1b9a01a6401b94a2367c F test/altertab2.test 5d423a2d1006085b05cc1b788863d5a860ea2da21c4f892d15e2f2a34c78348a -F test/altertab3.test 40f2ce9be675e354d3e55c72f8baf38813be975ff4dd9e6b3144493c3c5bc033 +F test/altertab3.test 2433d0cc6cb9cffe087f9138cd36818c7abd5c396804aa6e6dc8c2b80e2cd406 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 7168c8bffa5d5cbc53c05b7e9c7fcdd24b365a1bc5046ce80c45efa3c02e6b7c F test/analyze3.test ff62d9029e6deb2c914490c6b00caf7fae47cc85cdc046e4a0d0a4d4b87c71d8 @@ -1821,8 +1821,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 95209072176ff21a91e96d5bd014b35ef100da2b0b93958baf6df4294a8daa85 425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 -R f359cf293ea45304e0ddadd16c7a1206 -T +closed 425d708c3908fe74f69b62e6dd1722a0018088977e12f14b312dad1df0fbb804 +P 50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 +R 50f0438c4e5efd5bb6070c75e8184302 U dan -Z ee7f2d083d1fca64ba3bb33b40a19208 +Z dfacee40ac6434bcc0aa927bae743b38 diff --git a/manifest.uuid b/manifest.uuid index 55700b6967..16446b273a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 \ No newline at end of file +c621fc668c6538f9f5bdac204f012c64998679a61aa8e224d212503820224c09 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 50755e59f3..f6b6af1dfa 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -866,7 +866,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pExpr->y.pWin ){ Select *pSel = pNC->pWinSelect; - sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); + if( IN_RENAME_OBJECT==0 ){ + sqlite3WindowUpdate(pParse, pSel->pWinDefn, pExpr->y.pWin, pDef); + } sqlite3WalkExprList(pWalker, pExpr->y.pWin->pPartition); sqlite3WalkExprList(pWalker, pExpr->y.pWin->pOrderBy); sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); diff --git a/test/altertab3.test b/test/altertab3.test index 2bf6a9ddc1..b37d9ed1f9 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -142,6 +142,39 @@ do_execsql_test 6.1 { ALTER TABLE Table0 RENAME Col0 TO Col0; } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.1.0 { + CREATE TABLE t1(a,b,c); + CREATE TRIGGER AFTER INSERT ON t1 BEGIN + SELECT a, rank() OVER w1 FROM t1 + WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1); + END; +} + +do_execsql_test 7.1.2 { + ALTER TABLE t1 RENAME TO t1x; + SELECT sql FROM sqlite_master; +} { + {CREATE TABLE "t1x"(a,b,c)} + {CREATE TRIGGER AFTER INSERT ON "t1x" BEGIN + SELECT a, rank() OVER w1 FROM "t1x" + WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1); + END} +} + +do_execsql_test 7.2.1 { + DROP TRIGGER after; + CREATE TRIGGER AFTER INSERT ON t1x BEGIN + SELECT a, rank() OVER w1 FROM t1x + WINDOW w1 AS (PARTITION BY b, percent_rank() OVER w1 ORDER BY d); + END; +} + +do_catchsql_test 7.2.2 { + ALTER TABLE t1x RENAME TO t1; +} {1 {error in trigger AFTER: no such column: d}} + finish_test From 51f5ffa1a429bfdfe177e417482f1fbbf6685e76 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 29 Apr 2019 11:41:46 +0000 Subject: [PATCH 051/132] Fix a buffer overwrite in shell.c.in (part of the new .recover code). FossilOrigin-Name: 92facbc73a940d2844ac88fafd2d2dadb10886fb0b7c53e23f346d18fa6d6327 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 58229ddb68..cf4308824d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sstack\soverflow\sthat\scould\soccur\swhen\srenaming\sa\stable\sthat\shas\sa\strigger\scontaining\sa\swindow\sfunction\sinvocation\sthat\sitself\scontains\sa\sspecific\ssyntax\serror. -D 2019-04-29T11:27:58.967 +C Fix\sa\sbuffer\soverwrite\sin\sshell.c.in\s(part\sof\sthe\snew\s.recover\scode). +D 2019-04-29T11:41:46.359 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 104bbae904a2b67bc6c0c95337447544d15d0594dc46468608aae769d5f51da9 +F src/shell.c.in 567236da9ee68b1dfa363426858ee5e310976ffe422a7b7ae220c0315d7e8c53 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1821,7 +1821,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 50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 -R 50f0438c4e5efd5bb6070c75e8184302 +P c621fc668c6538f9f5bdac204f012c64998679a61aa8e224d212503820224c09 +R fab7a84bb2576871c69ae5af2474d189 U dan -Z dfacee40ac6434bcc0aa927bae743b38 +Z 238bfca672a6077522e49009580b426a diff --git a/manifest.uuid b/manifest.uuid index 16446b273a..491b1c92fc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c621fc668c6538f9f5bdac204f012c64998679a61aa8e224d212503820224c09 \ No newline at end of file +92facbc73a940d2844ac88fafd2d2dadb10886fb0b7c53e23f346d18fa6d6327 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 2f9a2456a1..e145a1547c 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4010,7 +4010,7 @@ static void shellEscapeCrnl( if( zNL || zCR ){ int iOut = 0; i64 nMax = (nNL > nCR) ? nNL : nCR; - i64 nAlloc = nMax * nText + (nMax+12)*2; + i64 nAlloc = nMax * nText + (nMax+64)*2; char *zOut = (char*)sqlite3_malloc64(nAlloc); if( zOut==0 ){ sqlite3_result_error_nomem(context); From c19b63c9a32f9de0830eb43f50c03aad3b351b51 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 29 Apr 2019 13:30:16 +0000 Subject: [PATCH 052/132] Improved header comment and precondition checking for the new isDupColumn() function. FossilOrigin-Name: 740d5ff6cc9bf7b151dfb8b27409e5923cfb2789b5398fe13d89563aff8ffc07 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/build.c | 29 +++++++++++++++++------------ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index dec5885b95..688c836776 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Take\scollating\ssequence\sinto\saccount\swhen\sremoving\sredundant\scolumns\sfrom\nindexes\son\sWITHOUT\sROWID\stables.\s\sThis\sis\sthe\sfirst\sproof-of-concept\sfix\nfor\sticket\s[3182d3879020ef3].\sMore\stesting\sneeded. -D 2019-04-28T19:27:02.781 +C Improved\sheader\scomment\sand\sprecondition\schecking\sfor\sthe\snew\sisDupColumn()\nfunction. +D 2019-04-29T13:30:16.066 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -463,7 +463,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 3fedab95ff7a9b3ed51eceb12aaa61de6bbd063dabd276767494cc448a151b7b +F src/build.c 2d9ddfeaf8e1dafc7e1fcc8a84e7a8b455199dac3b69037fc73af6279aa8447b F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -1821,10 +1821,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 50fe48458942fa7a6bcc76316c6321f95b23dc34f2f8e0a483826483b2fb16f6 -R fa5b9567c2bc0a92e3c8181fab56d7f8 -T *branch * tkt-3182d38790 -T *sym-tkt-3182d38790 * -T -sym-trunk * +P b34fa5bff40d3d364bd8c80e7de55c606ef3caac47b14b5265ebcb38857eb85e +R 4500a529c2eaff26172712aaa84d5151 U drh -Z dd82847aa38c87860cc4ec05cc3ab230 +Z 5d2313cdcb9e1838679491aff8b0ed48 diff --git a/manifest.uuid b/manifest.uuid index 6c45322202..e70eba18c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b34fa5bff40d3d364bd8c80e7de55c606ef3caac47b14b5265ebcb38857eb85e \ No newline at end of file +740d5ff6cc9bf7b151dfb8b27409e5923cfb2789b5398fe13d89563aff8ffc07 \ No newline at end of file diff --git a/src/build.c b/src/build.c index fac3163eba..8684e1ad69 100644 --- a/src/build.c +++ b/src/build.c @@ -1741,27 +1741,32 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){ } /* -** Return true if any of the first nKey entries of index pIdx1 exactly -** match the iCol-th entry of pIdx2. +** Return true if any of the first nKey entries of index pIdx exactly +** match the iCol-th entry of pPk. pPk is always a WITHOUT ROWID +** PRIMARY KEY index. pIdx is an index on the same table. pIdx may +** or may not be the same index as pPk. ** -** The first nKey entries of pIdx1 are guaranteed to be ordinary columns, +** The first nKey entries of pIdx are guaranteed to be ordinary columns, ** not a rowid or expression. ** ** This routine differs from hasColumn() in that both the column and the ** collating sequence must match for this routine, but for hasColumn() only ** the column name must match. */ -static int isDupColumn(Index *pIdx1, int nKey, Index *pIdx2, int iCol){ +static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ int i, j; - assert( nKey<=pIdx1->nColumn ); - assert( iColnColumn,pIdx2->nKeyCol) ); - j = pIdx2->aiColumn[iCol]; - testcase( j==XN_EXPR ); - assert( j!=XN_ROWID ); + assert( nKey<=pIdx->nColumn ); + assert( iColnColumn,pPk->nKeyCol) ); + assert( pPk->idxType==SQLITE_IDXTYPE_PRIMARYKEY ); + assert( pPk->pTable->tabFlags & TF_WithoutRowid ); + assert( pPk->pTable==pIdx->pTable ); + testcase( pPk==pIdx ); + j = pPk->aiColumn[iCol]; + assert( j!=XN_ROWID && j!=XN_EXPR ); for(i=0; iaiColumn[i]>=0 || j>=0 ); - if( pIdx1->aiColumn[i]==j - && sqlite3StrICmp(pIdx1->azColl[i],pIdx2->azColl[iCol])==0 + assert( pIdx->aiColumn[i]>=0 || j>=0 ); + if( pIdx->aiColumn[i]==j + && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 ){ return 1; } From 3af1b60e3a3963b70399320cdf59286537004f69 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 29 Apr 2019 16:44:11 +0000 Subject: [PATCH 053/132] Changes to oserror.test so that it works even on systems that allow an unusually large number of file descriptors. FossilOrigin-Name: a27b0b880d76c6838c0365f66bcd69b1b49b7594470993b608f4e490cbdc4882 --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/oserror.test | 32 +++++++++++++++++++++++--------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 0576b14f7c..7678e35d69 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sde-duplicate\scolumns\sindex\scolumns\sassociated\swith\sa\sWITHOUT\sROWID\stable\nif\sthe\scolumns\shave\sdifferent\scollating\ssequences.\s\sThis\sis\sthe\sfix\sfor\nticket\s[3182d3879020ef3b2].\s\sThere\sis\sone\stest\scase\sadded,\sbut\smost\sof\sthe\ntests\sare\sdone\sin\sTH3. -D 2019-04-29T13:48:45.899 +C Changes\sto\soserror.test\sso\sthat\sit\sworks\seven\son\ssystems\sthat\sallow\nan\sunusually\slarge\snumber\sof\sfile\sdescriptors. +D 2019-04-29T16:44:11.554 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1185,7 +1185,7 @@ F test/orderby6.test 8b38138ab0972588240b3fca0985d2e400432859 F test/orderby7.test 3d1383d52ade5b9eb3a173b3147fdd296f0202da F test/orderby8.test 23ef1a5d72bd3adcc2f65561c654295d1b8047bd F test/orderby9.test 87fb9548debcc2cd141c5299002dd94672fa76a3 -F test/oserror.test e7b3416be4b9d5dd2fe0b42dd394daaddbb6c83eeec1f0e47b120b53e0ad3ace +F test/oserror.test 1fc9746b83d778e70d115049747ba19c7fba154afce7cc165b09feb6ca6abbc5 F test/ossfuzz.c 18af635fa73d12a109b305faca727a734c1fa28a421b161d9d15c5a84a4998a2 F test/ossshell.c f125c5bd16e537a2549aa579b328dd1c59905e7ab1338dfc210e755bb7b69f17 F test/ovfl.test 199c482696defceacee8c8e0e0ef36da62726b2f @@ -1821,8 +1821,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 92facbc73a940d2844ac88fafd2d2dadb10886fb0b7c53e23f346d18fa6d6327 740d5ff6cc9bf7b151dfb8b27409e5923cfb2789b5398fe13d89563aff8ffc07 -R 202811e2e95855247d322c66d5116799 -T +closed 740d5ff6cc9bf7b151dfb8b27409e5923cfb2789b5398fe13d89563aff8ffc07 +P 1b1dd4d48cd79a585e1fa7ee79128e9f2a9ee9846339dc56bbd67b75112dcad5 +R 0bcdc9eac356966e584a16ee79a622df U drh -Z b55be1ccaf3a50c1a3ba7b999ad660d8 +Z e312b5e28707c934ce76aba346ace36f diff --git a/manifest.uuid b/manifest.uuid index e85adcff39..6158031446 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b1dd4d48cd79a585e1fa7ee79128e9f2a9ee9846339dc56bbd67b75112dcad5 \ No newline at end of file +a27b0b880d76c6838c0365f66bcd69b1b49b7594470993b608f4e490cbdc4882 \ No newline at end of file diff --git a/test/oserror.test b/test/oserror.test index 271163aaad..a51301cc52 100644 --- a/test/oserror.test +++ b/test/oserror.test @@ -52,18 +52,32 @@ proc do_re_test {tn script expression} { # an error may be reported for either open() or getcwd() here. # if {![clang_sanitize_address]} { + unset -nocomplain rc + unset -nocomplain nOpen + set nOpen 20000 do_test 1.1.1 { set ::log [list] - list [catch { - for {set i 0} {$i < 20000} {incr i} { sqlite3 dbh_$i test.db -readonly 1 } - } msg] $msg - } {1 {unable to open database file}} + set ::rc [catch { + for {set i 0} {$i < $::nOpen} {incr i} { sqlite3 dbh_$i test.db -readonly 1 } + } msg] + if {$::rc==0} { + # Some system (ex: Debian) are able to create 20000+ file descriptiors + # such systems will not fail here + set x ok + } elseif {$::rc==1 && $msg=="unable to open database file"} { + set x ok + } else { + set x [list $::rc $msg] + } + } {ok} do_test 1.1.2 { - catch { for {set i 0} {$i < 20000} {incr i} { dbh_$i close } } - } {1} - do_re_test 1.1.3 { - lindex $::log 0 - } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - } + catch { for {set i 0} {$i < $::nOpen} {incr i} { dbh_$i close } } + } $::rc + if {$rc} { + do_re_test 1.1.3 { + lindex $::log 0 + } {^os_unix.c:\d+: \(\d+\) (open|getcwd)\(.*test.db\) - } + } } From b70b0df8eb8cea79074289826079699a00a0aef4 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 30 Apr 2019 01:08:42 +0000 Subject: [PATCH 054/132] Slightly smaller and faster implementation of the OP_MakeRecord opcode. FossilOrigin-Name: 3bdce7ef1a6bb03affe978243fec603d5a55c071aa6d87c469a3c199d23f3b5e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 47 +++++++++++++++++++++++------------------------ 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 7678e35d69..6efd90d506 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Changes\sto\soserror.test\sso\sthat\sit\sworks\seven\son\ssystems\sthat\sallow\nan\sunusually\slarge\snumber\sof\sfile\sdescriptors. -D 2019-04-29T16:44:11.554 +C Slightly\ssmaller\sand\sfaster\simplementation\sof\sthe\sOP_MakeRecord\sopcode. +D 2019-04-30T01:08:42.471 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 711ef421b3bb3db3b2476067b2dc3c71ef5844d9b1a723026578f89f6da621e8 +F src/vdbe.c 2782da511932d17e45e128f04f73314e5f5d765f7a499f5ac4bb1e0a82e082cc F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 @@ -1821,7 +1821,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 1b1dd4d48cd79a585e1fa7ee79128e9f2a9ee9846339dc56bbd67b75112dcad5 -R 0bcdc9eac356966e584a16ee79a622df +P a27b0b880d76c6838c0365f66bcd69b1b49b7594470993b608f4e490cbdc4882 +R b12c0740e7e730a41b03261e6f060f1c U drh -Z e312b5e28707c934ce76aba346ace36f +Z b866775507213d2cd189ff81277fbb67 diff --git a/manifest.uuid b/manifest.uuid index 6158031446..cfd74f4be8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a27b0b880d76c6838c0365f66bcd69b1b49b7594470993b608f4e490cbdc4882 \ No newline at end of file +3bdce7ef1a6bb03affe978243fec603d5a55c071aa6d87c469a3c199d23f3b5e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c004137c47..faaf947308 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2791,7 +2791,6 @@ case OP_Affinity: { ** If P4 is NULL then all index fields have the affinity BLOB. */ case OP_MakeRecord: { - u8 *zNewRecord; /* A buffer to hold the data for the new record */ Mem *pRec; /* The new record */ u64 nData; /* Number of bytes of data space */ int nHdr; /* Number of bytes of header space */ @@ -2804,9 +2803,9 @@ case OP_MakeRecord: { int nField; /* Number of fields in the record */ char *zAffinity; /* The affinity string for the record */ int file_format; /* File format to use for encoding */ - int i; /* Space used in zNewRecord[] header */ - int j; /* Space used in zNewRecord[] content */ u32 len; /* Length of a field */ + u8 *zHdr; /* Where to write next byte of the header */ + u8 *zPayload; /* Where to write next byte of the payload */ /* Assuming the record contains N fields, the record format looks ** like this: @@ -2933,34 +2932,34 @@ case OP_MakeRecord: { goto no_mem; } } - zNewRecord = (u8 *)pOut->z; - - /* Write the record */ - i = putVarint32(zNewRecord, nHdr); - j = nHdr; - assert( pData0<=pLast ); - pRec = pData0; - do{ - serial_type = pRec->uTemp; - /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more - ** additional varints, one per column. */ - i += putVarint32(&zNewRecord[i], serial_type); /* serial type */ - /* EVIDENCE-OF: R-64536-51728 The values for each column in the record - ** immediately follow the header. */ - j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ - }while( (++pRec)<=pLast ); - assert( i==nHdr ); - assert( j==nByte ); - - assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pOut->n = (int)nByte; pOut->flags = MEM_Blob; if( nZero ){ pOut->u.nZero = nZero; pOut->flags |= MEM_Zero; } - REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); + zHdr = (u8 *)pOut->z; + zPayload = zHdr + nHdr; + + /* Write the record */ + zHdr += putVarint32(zHdr, nHdr); + assert( pData0<=pLast ); + pRec = pData0; + do{ + serial_type = pRec->uTemp; + /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more + ** additional varints, one per column. */ + zHdr += putVarint32(zHdr, serial_type); /* serial type */ + /* EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ + zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ + }while( (++pRec)<=pLast ); + assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); + assert( nByte==(int)(zPayload - (u8*)pOut->z) ); + + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); + REGISTER_TRACE(pOp->p3, pOut); break; } From cf83323936dccae4ccafa8c6d17d4a9d7c439e5a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 30 Apr 2019 11:54:36 +0000 Subject: [PATCH 055/132] Small performance increase and size reduction in the implementation of the LIKE and GLOB operators. FossilOrigin-Name: f97626f921dafe596b615a168ef31987f4a1c0b52956443e1a5c1148b49cab74 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/func.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6efd90d506..17f6e743ba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\simplementation\sof\sthe\sOP_MakeRecord\sopcode. -D 2019-04-30T01:08:42.471 +C Small\sperformance\sincrease\sand\ssize\sreduction\sin\sthe\simplementation\sof\sthe\nLIKE\sand\sGLOB\soperators. +D 2019-04-30T11:54:36.560 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -474,7 +474,7 @@ F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c f65db06a0fcff760cadfb79d579a41e3eb7eff38848d5d6359137822f4fa2ec9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 -F src/func.c 2ccf4ae12430b1ae7096be5f0675887e1bd0732828af0ac0f7496339b7c6edee +F src/func.c ac05ea6b47b407586ad2c0878c4c81c3acb08b67ecf86648830f91f40325ae37 F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -1821,7 +1821,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 a27b0b880d76c6838c0365f66bcd69b1b49b7594470993b608f4e490cbdc4882 -R b12c0740e7e730a41b03261e6f060f1c +P 3bdce7ef1a6bb03affe978243fec603d5a55c071aa6d87c469a3c199d23f3b5e +R 9a779d76ef4cdc16bf512841a59b2ab4 U drh -Z b866775507213d2cd189ff81277fbb67 +Z 487e34d77ec73a391deebf3b3507c69b diff --git a/manifest.uuid b/manifest.uuid index cfd74f4be8..c0c3e4bb99 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3bdce7ef1a6bb03affe978243fec603d5a55c071aa6d87c469a3c199d23f3b5e \ No newline at end of file +f97626f921dafe596b615a168ef31987f4a1c0b52956443e1a5c1148b49cab74 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 03595b70d2..dae85d60a8 100644 --- a/src/func.c +++ b/src/func.c @@ -843,8 +843,6 @@ static void likeFunc( return; } #endif - zB = sqlite3_value_text(argv[0]); - zA = sqlite3_value_text(argv[1]); /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). @@ -856,8 +854,6 @@ static void likeFunc( sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } - assert( zB==sqlite3_value_text(argv[0]) ); /* Encoding did not change */ - if( argc==3 ){ /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. @@ -873,6 +869,8 @@ static void likeFunc( }else{ escape = pInfo->matchSet; } + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); if( zA && zB ){ #ifdef SQLITE_TEST sqlite3_like_count++; From f135cb7d7f123a42940ddbb4dadc91e86f84cb35 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 30 Apr 2019 14:26:31 +0000 Subject: [PATCH 056/132] Fix an error message in the Lemon parser generator. FossilOrigin-Name: b6d7d42b7426622a26b67809cd1f21285fea120aa1897377b9946840463b41f1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 17f6e743ba..2b7a987399 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sincrease\sand\ssize\sreduction\sin\sthe\simplementation\sof\sthe\nLIKE\sand\sGLOB\soperators. -D 2019-04-30T11:54:36.560 +C Fix\san\serror\smessage\sin\sthe\sLemon\sparser\sgenerator. +D 2019-04-30T14:26:31.199 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1740,7 +1740,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 900a15b9efba9890d10e7959914db94c4ad5162912127f061c4328add122d6fb +F tool/lemon.c d02a276728c507a7007333944eeabafab1668033794af348389b1166075869ee F tool/lempar.c 61af95b8fac2bfd59c09d55330e78f3f5e352d7aa80bf37404b96ef795be3fdc F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1821,7 +1821,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 3bdce7ef1a6bb03affe978243fec603d5a55c071aa6d87c469a3c199d23f3b5e -R 9a779d76ef4cdc16bf512841a59b2ab4 +P f97626f921dafe596b615a168ef31987f4a1c0b52956443e1a5c1148b49cab74 +R 716d456c280daf5c4e086f08a5ceb68c U drh -Z 487e34d77ec73a391deebf3b3507c69b +Z 897d4bc356296ccb4d7eda6e238b1690 diff --git a/manifest.uuid b/manifest.uuid index c0c3e4bb99..ed0e54318a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f97626f921dafe596b615a168ef31987f4a1c0b52956443e1a5c1148b49cab74 \ No newline at end of file +b6d7d42b7426622a26b67809cd1f21285fea120aa1897377b9946840463b41f1 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 7ef99fd525..eb4adbbc69 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -3848,7 +3848,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){ ErrorMsg(lemp->filename,rp->ruleline, "%s(%s) has the same label as the LHS but is not the left-most " "symbol on the RHS.", - rp->rhs[i]->name, rp->rhsalias); + rp->rhs[i]->name, rp->rhsalias[i]); lemp->errorcnt++; } for(j=0; j Date: Tue, 30 Apr 2019 15:36:32 +0000 Subject: [PATCH 057/132] Fix a problem allowing a Table object to be deleted from within a call to the xDestroy method of the associated virtual table, causing a use-after-free error. FossilOrigin-Name: 1dbbb0101e8213b92b9a4c78c0fd2f9d0240a8ea3b40dff1033d1b8d71fb04ef --- manifest | 15 ++++++++------- manifest.uuid | 2 +- src/vtab.c | 2 ++ test/fts4rename.test | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 test/fts4rename.test diff --git a/manifest b/manifest index 2b7a987399..18cfa0b238 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\serror\smessage\sin\sthe\sLemon\sparser\sgenerator. -D 2019-04-30T14:26:31.199 +C Fix\sa\sproblem\sallowing\sa\sTable\sobject\sto\sbe\sdeleted\sfrom\swithin\sa\scall\sto\sthe\sxDestroy\smethod\sof\sthe\sassociated\svirtual\stable,\scausing\sa\suse-after-free\serror. +D 2019-04-30T15:36:32.034 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -600,7 +600,7 @@ F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c9419 F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 -F src/vtab.c 4c5959e00b7a142198d178e3a822f4e05f36f2d1a3c57657373f9487154fc06b +F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -975,6 +975,7 @@ F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b F test/fts4noti.test 5553d7bb2e20bf4a06b23e849352efc022ce6309 F test/fts4onepass.test d69ddc4ee3415e40b0c5d1d0408488a87614d4f63ba9c44f3e52db541d6b7cc7 F test/fts4opt.test 0fd0cc84000743ff2a883b9b84b4a5be07249f0ba790c8848a757164cdd46b2a +F test/fts4rename.test 6015a355ec3a11a51eb5b88802b3b2c1788786c54b77b17f3e077b7c93ff8611 F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d @@ -1821,7 +1822,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 f97626f921dafe596b615a168ef31987f4a1c0b52956443e1a5c1148b49cab74 -R 716d456c280daf5c4e086f08a5ceb68c -U drh -Z 897d4bc356296ccb4d7eda6e238b1690 +P b6d7d42b7426622a26b67809cd1f21285fea120aa1897377b9946840463b41f1 +R 6adb84036e04ae37c244138c75843359 +U dan +Z bb2c7686d9426e0e670050982240668c diff --git a/manifest.uuid b/manifest.uuid index ed0e54318a..3189f67ccc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6d7d42b7426622a26b67809cd1f21285fea120aa1897377b9946840463b41f1 \ No newline at end of file +1dbbb0101e8213b92b9a4c78c0fd2f9d0240a8ea3b40dff1033d1b8d71fb04ef \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 7806eb946f..41e26ef62f 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -841,6 +841,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ p = vtabDisconnectAll(db, pTab); xDestroy = p->pMod->pModule->xDestroy; assert( xDestroy!=0 ); /* Checked before the virtual table is created */ + pTab->nTabRef++; rc = xDestroy(p->pVtab); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ @@ -849,6 +850,7 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ pTab->pVTable = 0; sqlite3VtabUnlock(p); } + sqlite3DeleteTable(db, pTab); } return rc; diff --git a/test/fts4rename.test b/test/fts4rename.test new file mode 100644 index 0000000000..1c711e74e6 --- /dev/null +++ b/test/fts4rename.test @@ -0,0 +1,44 @@ +# 2019 April 30 +# +# 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. +# +#************************************************************************* +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/fts3_common.tcl +set ::testprefix fts4rename + +# If SQLITE_ENABLE_FTS3 is defined, omit this file. +ifcapable !fts3 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE temp.t1 USING fts3(a); + BEGIN; + CREATE TABLE t2(x); +} {} + +do_catchsql_test 1.1 { + ALTER TABLE t1_content RENAME c0a TO docid; +} {1 {duplicate column name: docid}} + +do_catchsql_test 1.2 { + UPDATE t1 SET Col0 = 1 ; +} {1 {no such column: Col0}} + +do_catchsql_test 1.3 { + ROLLBACK; + DROP TABLE t1; +} {0 {}} + +finish_test + From 919458923dd9ea81db155fce5976a42207be11c7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 30 Apr 2019 20:43:10 +0000 Subject: [PATCH 058/132] Update wapptest.tcl to use a simpler slave script. And to leave scripts wapptest_configure.sh and wapptest_make.sh in each test directory. FossilOrigin-Name: 07e527d781838412b2a434e64baaa49cbf7410a51c7393f54adc7b8eaffd5229 --- manifest | 13 ++--- manifest.uuid | 2 +- test/wapptest.tcl | 122 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 102 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 18cfa0b238..52011015d3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sallowing\sa\sTable\sobject\sto\sbe\sdeleted\sfrom\swithin\sa\scall\sto\sthe\sxDestroy\smethod\sof\sthe\sassociated\svirtual\stable,\scausing\sa\suse-after-free\serror. -D 2019-04-30T15:36:32.034 +C Update\swapptest.tcl\sto\suse\sa\ssimpler\sslave\sscript.\sAnd\sto\sleave\sscripts\swapptest_configure.sh\sand\swapptest_make.sh\sin\seach\stest\sdirectory. +D 2019-04-30T20:43:10.531 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1656,7 +1656,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec -F test/wapptest.tcl 78aff97afe76fd9728cf5f84710a772412735bc68a612b4789279072177a424e x +F test/wapptest.tcl 7cdac27ab7945b96719aea1afdeac5922b38657d488c676b91fff173552087e0 x F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c @@ -1822,7 +1822,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b6d7d42b7426622a26b67809cd1f21285fea120aa1897377b9946840463b41f1 -R 6adb84036e04ae37c244138c75843359 +P 1dbbb0101e8213b92b9a4c78c0fd2f9d0240a8ea3b40dff1033d1b8d71fb04ef +R f8f2ef19afa4c11d5a1036e92efd9ad2 +T +closed 9e849f25029b05b44220acd881356bcade9ba76f9d1308556850cd4d6b6a94d7 U dan -Z bb2c7686d9426e0e670050982240668c +Z 8ade123def7ea1f2c0a2e92932d92c90 diff --git a/manifest.uuid b/manifest.uuid index 3189f67ccc..0f16a1f690 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dbbb0101e8213b92b9a4c78c0fd2f9d0240a8ea3b40dff1033d1b8d71fb04ef \ No newline at end of file +07e527d781838412b2a434e64baaa49cbf7410a51c7393f54adc7b8eaffd5229 \ No newline at end of file diff --git a/test/wapptest.tcl b/test/wapptest.tcl index d12d8e7222..be6271a9c0 100755 --- a/test/wapptest.tcl +++ b/test/wapptest.tcl @@ -37,9 +37,6 @@ proc wapptest_init {} { # The root of the SQLite source tree. set G(srcdir) [file dirname [file dirname [info script]]] - # releasetest.tcl script - set G(releaseTest) [file join [file dirname [info script]] releasetest.tcl] - set G(sqlite_version) "unknown" # Either "config", "running" or "stopped": @@ -52,28 +49,20 @@ proc wapptest_init {} { append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)" } -# Check to see if there are uncommitted changes in the SQLite source -# directory. Return true if there are, or false otherwise. +# Generate the text for the box at the top of the UI. The current SQLite +# version, according to fossil, along with a warning if there are +# uncommitted changes in the checkout. # -proc check_uncommitted {} { - global G - set ret 0 - set pwd [pwd] - cd $G(srcdir) - if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} { - set ret 1 - } - cd $pwd - return $ret -} - proc generate_fossil_info {} { global G set pwd [pwd] cd $G(srcdir) - if {[catch {exec fossil info} r1]} return - if {[catch {exec fossil changes} r2]} return + set rc [catch { + set r1 [exec fossil info] + set r2 [exec fossil changes] + }] cd $pwd + if {$rc} return foreach line [split $r1 "\n"] { if {[regexp {^checkout: *(.*)$} $line -> co]} { @@ -239,6 +228,88 @@ proc slave_fileevent {name} { do_some_stuff } +proc wapptest_slave_script {} { + global G + set res { + proc readfile {filename} { + set fd [open $filename] + set data [read $fd] + close $fd + return $data + } + } + + if {$G(msvc)==0} { + append res { + set cfg [readfile wapptest_configure.sh] + set rc [catch { exec {*}$cfg >& test.log } msg] + if {$rc==0} { + set make [readfile wapptest_make.sh] + catch { exec {*}$make >>& test.log } + } + } + } else { + append res { + set make [readfile wapptest_make.sh] + catch { exec {*}$make >>& test.log } + } + } + + set res +} + + +# Launch a slave process to run a test. +# +proc slave_launch { + name wtcl title dir configOpts testtarget makeOpts cflags opts +} { + global G + + catch { file mkdir $dir } msg + foreach f [glob -nocomplain [file join $dir *]] { + catch { file delete -force $f } + } + + # Write the configure command to wapptest_configure.sh. This file + # is empty if using MSVC - MSVC does not use configure. + # + set fd1 [open [file join $dir wapptest_configure.sh] w] + if {$G(msvc)==0} { + puts $fd1 "[file join .. $G(srcdir) configure] $wtcl $configOpts" + } + close $fd1 + + # Write the make command to wapptest_make.sh. Using nmake for MSVC and + # make for all other systems. + # + set makecmd "make" + if {$G(msvc)} { + set nativedir [file nativename $G(srcdir)] + set nativedir [string map [list "\\" "\\\\"] $nativedir] + set makecmd "nmake /f [file join $nativedir Makefile.msc] TOP=$nativedir" + } + set fd2 [open [file join $dir wapptest_make.sh] w] + puts $fd2 "$makecmd $makeOpts $testtarget \"CFLAGS=$cflags\" \"OPTS=$opts\"" + close $fd2 + + # Write the wapptest_run.tcl script to the test directory. To run the + # commands in the other two files. + # + set fd3 [open [file join $dir wapptest_run.tcl] w] + puts $fd3 [wapptest_slave_script] + close $fd3 + + set pwd [pwd] + cd $dir + set fd [open "|[info nameofexecutable] wapptest_run.tcl" r+] + cd $pwd + + set G(test.$name.channel) $fd + fconfigure $fd -blocking 0 + fileevent $fd readable [list slave_fileevent $name] +} + proc do_some_stuff {} { global G @@ -275,15 +346,9 @@ proc do_some_stuff {} { if { ![info exists G(test.$name.channel)] && ![info exists G(test.$name.done)] } { + set target [dict get $j target] set G(test.$name.start) [clock seconds] - set fd [open "|[info nameofexecutable] $G(releaseTest) --slave" r+] - set G(test.$name.channel) $fd - fconfigure $fd -blocking 0 - fileevent $fd readable [list slave_fileevent $name] - - puts $fd [list 0 $G(msvc) 0 $G(keep)] - set wtcl "" if {$G(tcl)!=""} { set wtcl "--with-tcl=$G(tcl)" } @@ -303,8 +368,9 @@ proc do_some_stuff {} { } set L [make_test_suite $G(msvc) $wtcl $name $target $opts] - puts $fd $L - flush $fd + set G(test.$name.log) [file join [lindex $L 1] test.log] + slave_launch $name $wtcl {*}$L + set G(test.$name.log) [file join [lindex $L 1] test.log] incr nLaunch -1 } From a3e086d80362607fcee57c3e9d9a5c9eef9fbcfc Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 May 2019 08:48:44 +0000 Subject: [PATCH 059/132] Fix an incompatibility with auto-vacuum mode in new test script recover.test. FossilOrigin-Name: 36dd5b0804797a35d0dc596b6ca4f71813a155c5a470237ab6e3d1bcd9ccc6be --- manifest | 13 ++++++------- manifest.uuid | 2 +- test/recover.test | 1 + 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 52011015d3..30142ae07f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\swapptest.tcl\sto\suse\sa\ssimpler\sslave\sscript.\sAnd\sto\sleave\sscripts\swapptest_configure.sh\sand\swapptest_make.sh\sin\seach\stest\sdirectory. -D 2019-04-30T20:43:10.531 +C Fix\san\sincompatibility\swith\sauto-vacuum\smode\sin\snew\stest\sscript\srecover.test. +D 2019-05-01T08:48:44.061 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1227,7 +1227,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/recover.test 52609c8cc24e72d3d8a20fb8bc32ba2ce8ca2093a7f4573bd4f2969f78f6d2b4 +F test/recover.test 4c45b1519c11c6d10cc28bced260e2a18f3967fc6abccaace44af6c22b30280c F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 @@ -1822,8 +1822,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 1dbbb0101e8213b92b9a4c78c0fd2f9d0240a8ea3b40dff1033d1b8d71fb04ef -R f8f2ef19afa4c11d5a1036e92efd9ad2 -T +closed 9e849f25029b05b44220acd881356bcade9ba76f9d1308556850cd4d6b6a94d7 +P 07e527d781838412b2a434e64baaa49cbf7410a51c7393f54adc7b8eaffd5229 +R 5ef0ce02daac1f5b87f34d32f98b67b4 U dan -Z 8ade123def7ea1f2c0a2e92932d92c90 +Z 076daaf71d4826b61a79c8ff95610b0a diff --git a/manifest.uuid b/manifest.uuid index 0f16a1f690..795204fd4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07e527d781838412b2a434e64baaa49cbf7410a51c7393f54adc7b8eaffd5229 \ No newline at end of file +36dd5b0804797a35d0dc596b6ca4f71813a155c5a470237ab6e3d1bcd9ccc6be \ No newline at end of file diff --git a/test/recover.test b/test/recover.test index 4dad0d646d..75360bc86b 100644 --- a/test/recover.test +++ b/test/recover.test @@ -91,6 +91,7 @@ do_recover_test 1.3.2 #------------------------------------------------------------------------- reset_db do_execsql_test 2.1.0 { + PRAGMA auto_vacuum = 0; CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID; INSERT INTO t1 VALUES(1, 2, 3); INSERT INTO t1 VALUES(4, 5, 6); From 6fcc1ecc99dbf222394bbfe207496b1148ece800 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 May 2019 14:41:47 +0000 Subject: [PATCH 060/132] In "PRAGMA vdbe_trace" output, show the results of OP_Affinity opcodes. FossilOrigin-Name: 56604bb60a8ebac8d2854628d1b052d594d7effe14be8333977995dc07b65114 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 30142ae07f..9b557e68a4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincompatibility\swith\sauto-vacuum\smode\sin\snew\stest\sscript\srecover.test. -D 2019-05-01T08:48:44.061 +C In\s"PRAGMA\svdbe_trace"\soutput,\sshow\sthe\sresults\sof\sOP_Affinity\sopcodes. +D 2019-05-01T14:41:47.678 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 2782da511932d17e45e128f04f73314e5f5d765f7a499f5ac4bb1e0a82e082cc +F src/vdbe.c 74ee707ef31b74edc05923cddc04657d165c111fa9e6fe957df8fa7d5b63b8cf F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 @@ -1822,7 +1822,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 07e527d781838412b2a434e64baaa49cbf7410a51c7393f54adc7b8eaffd5229 -R 5ef0ce02daac1f5b87f34d32f98b67b4 -U dan -Z 076daaf71d4826b61a79c8ff95610b0a +P 36dd5b0804797a35d0dc596b6ca4f71813a155c5a470237ab6e3d1bcd9ccc6be +R ea64878fb21eadae4dca5f57318c8810 +U drh +Z 04e7e3cb0fe5e91830c8ba41df015203 diff --git a/manifest.uuid b/manifest.uuid index 795204fd4c..b8c0cbeaad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36dd5b0804797a35d0dc596b6ca4f71813a155c5a470237ab6e3d1bcd9ccc6be \ No newline at end of file +56604bb60a8ebac8d2854628d1b052d594d7effe14be8333977995dc07b65114 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index faaf947308..a5c339bdf5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2769,6 +2769,7 @@ case OP_Affinity: { assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); applyAffinity(pIn1, *(zAffinity++), encoding); + REGISTER_TRACE((int)(pIn1-aMem), pIn1); pIn1++; }while( zAffinity[0] ); break; From c97001fd55d61b5214fe91b764795d8f04360dae Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 May 2019 15:25:38 +0000 Subject: [PATCH 061/132] Update wapptest.tcl so that it deletes extra files if the "Keep files:" checkbox is clear. Set it by default. FossilOrigin-Name: 09623cc4cc82e3c123d1fd5d88b2f4b50ec5f2cc7e579a7203258bf0c246a74f --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/wapptest.tcl | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9b557e68a4..a50a5799d9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\s"PRAGMA\svdbe_trace"\soutput,\sshow\sthe\sresults\sof\sOP_Affinity\sopcodes. -D 2019-05-01T14:41:47.678 +C Update\swapptest.tcl\sso\sthat\sit\sdeletes\sextra\sfiles\sif\sthe\s"Keep\sfiles:"\scheckbox\sis\sclear.\sSet\sit\sby\sdefault. +D 2019-05-01T15:25:38.538 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1656,7 +1656,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec -F test/wapptest.tcl 7cdac27ab7945b96719aea1afdeac5922b38657d488c676b91fff173552087e0 x +F test/wapptest.tcl c4c32b89607f970500568cad83ed67a869beaf8c2f07bbc030a335ea6c7c750c x F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c @@ -1822,7 +1822,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 36dd5b0804797a35d0dc596b6ca4f71813a155c5a470237ab6e3d1bcd9ccc6be -R ea64878fb21eadae4dca5f57318c8810 -U drh -Z 04e7e3cb0fe5e91830c8ba41df015203 +P 56604bb60a8ebac8d2854628d1b052d594d7effe14be8333977995dc07b65114 +R 927c208fc5b5ee3c4c01e2595fed96f3 +U dan +Z 6871de4eaeba6ddd2436f9afc805bd1a diff --git a/manifest.uuid b/manifest.uuid index b8c0cbeaad..7af2ec6456 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56604bb60a8ebac8d2854628d1b052d594d7effe14be8333977995dc07b65114 \ No newline at end of file +09623cc4cc82e3c123d1fd5d88b2f4b50ec5f2cc7e579a7203258bf0c246a74f \ No newline at end of file diff --git a/test/wapptest.tcl b/test/wapptest.tcl index be6271a9c0..fe7ea202e8 100755 --- a/test/wapptest.tcl +++ b/test/wapptest.tcl @@ -20,8 +20,8 @@ source [file join [file dirname [info script]] releasetest_data.tcl] # set G(platform) $::tcl_platform(os)-$::tcl_platform(machine) set G(test) Normal -set G(keep) 0 -set G(msvc) 0 +set G(keep) 1 +set G(msvc) [expr {$::tcl_platform(platform)=="windows"}] set G(tcl) [::tcl::pkgconfig get libdir,install] set G(jobs) 3 set G(debug) 0 @@ -197,6 +197,10 @@ proc count_tests_and_errors {name logfile} { } } +# This command is invoked once a slave process has finished running its +# tests, successfully or otherwise. Parameter $name is the name of the +# test, $rc the exit code returned by the slave process. +# proc slave_test_done {name rc} { global G set G(test.$name.done) [clock seconds] @@ -209,8 +213,28 @@ proc slave_test_done {name rc} { if {[file exists $G(test.$name.log)]} { count_tests_and_errors $name $G(test.$name.log) } + + # If the "keep files" checkbox is clear, delete all files except for + # the executables and test logs. And any core file that is present. + if {$G(keep)==0} { + set keeplist { + testfixture testfixture.exe + sqlite3 sqlite3.exe + test.log test-out.txt + core + } + foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] { + set t [file tail $f] + if {[lsearch $keeplist $t]<0} { + catch { file delete -force $f } + } + } + } } +# This is a fileevent callback invoked each time a file-descriptor that +# connects this process to a slave process is readable. +# proc slave_fileevent {name} { global G set fd $G(test.$name.channel) @@ -228,6 +252,14 @@ proc slave_fileevent {name} { do_some_stuff } +# Return the contents of the "slave script" - the script run by slave +# processes to actually perform the test. It does two things: +# +# 1. Reads and [exec]s the contents of file wapptest_configure.sh. +# 2. Reads and [exec]s the contents of file wapptest_make.sh. +# +# Step 1 is omitted if the test uses MSVC (which does not use configure). +# proc wapptest_slave_script {} { global G set res { @@ -270,6 +302,7 @@ proc slave_launch { foreach f [glob -nocomplain [file join $dir *]] { catch { file delete -force $f } } + set G(test.$name.dir) $dir # Write the configure command to wapptest_configure.sh. This file # is empty if using MSVC - MSVC does not use configure. From 8a7e11fb7894e286ac9f66ff93a6c8b0668e954a Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 May 2019 15:32:40 +0000 Subject: [PATCH 062/132] Avoid unwelcomed side effects on the input operands in the OP_Concat operator. Fix for ticket [3be1295b264be2fac49b681] FossilOrigin-Name: 713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 37 ++++++++++++++++++++++++------------- test/index.test | 9 +++++++++ 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index a50a5799d9..12c2ec4d32 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\swapptest.tcl\sso\sthat\sit\sdeletes\sextra\sfiles\sif\sthe\s"Keep\sfiles:"\scheckbox\sis\sclear.\sSet\sit\sby\sdefault. -D 2019-05-01T15:25:38.538 +C Avoid\sunwelcomed\sside\seffects\son\sthe\sinput\soperands\sin\sthe\sOP_Concat\noperator.\s\sFix\sfor\sticket\s[3be1295b264be2fac49b681] +D 2019-05-01T15:32:40.553 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 74ee707ef31b74edc05923cddc04657d165c111fa9e6fe957df8fa7d5b63b8cf +F src/vdbe.c 57b0b697d349876716499e073fb5e2d20ebc6cc0f752327a4e54031ed7e062f3 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 @@ -1031,7 +1031,7 @@ F test/incrvacuum.test 2aaee202b1f230e55779f70d155f6ba67bbdff8481d650214d256ab0f F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 -F test/index.test df4cddf4435314a948237fdfa9acee67de21f7bebc789beab4b89b575b4f6a70 +F test/index.test 58d6fba7748b7c545080759b334e759b22a06b728aa68a2abd106b8065184bdd F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 @@ -1822,7 +1822,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 56604bb60a8ebac8d2854628d1b052d594d7effe14be8333977995dc07b65114 -R 927c208fc5b5ee3c4c01e2595fed96f3 -U dan -Z 6871de4eaeba6ddd2436f9afc805bd1a +P 09623cc4cc82e3c123d1fd5d88b2f4b50ec5f2cc7e579a7203258bf0c246a74f +R 36135537650a3222bb6001d7e31d8024 +U drh +Z 34e12fa35e79c97a2bb14481b73be0be diff --git a/manifest.uuid b/manifest.uuid index 7af2ec6456..566972896c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09623cc4cc82e3c123d1fd5d88b2f4b50ec5f2cc7e579a7203258bf0c246a74f \ No newline at end of file +713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index a5c339bdf5..455d2b618a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -195,14 +195,6 @@ int sqlite3_found_count = 0; } #endif -/* -** Convert the given register into a string if it isn't one -** already. Return non-zero if a malloc() fails. -*/ -#define Stringify(P, enc) \ - if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \ - { goto no_mem; } - /* ** An ephemeral string value (signified by the MEM_Ephem flag) contains ** a pointer to a dynamically allocated string where some other entity @@ -1463,19 +1455,34 @@ case OP_ResultRow: { ** to avoid a memcpy(). */ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ - i64 nByte; + i64 nByte; /* Total size of the output string or blob */ + u16 flags1; /* Initial flags for P1 */ + u16 flags2; /* Initial flags for P2 */ pIn1 = &aMem[pOp->p1]; pIn2 = &aMem[pOp->p2]; pOut = &aMem[pOp->p3]; + testcase( pIn1==pIn2 ); + testcase( pOut==pIn2 ); assert( pIn1!=pOut ); - if( (pIn1->flags | pIn2->flags) & MEM_Null ){ + flags1 = pIn1->flags; + testcase( flags1 & MEM_Null ); + testcase( pIn2->flags & MEM_Null ); + if( (flags1 | pIn2->flags) & MEM_Null ){ sqlite3VdbeMemSetNull(pOut); break; } - if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; - Stringify(pIn1, encoding); - Stringify(pIn2, encoding); + if( (flags1 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; + }else if( (flags1 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; + } + flags2 = pIn2->flags; + if( (flags2 & (MEM_Str|MEM_Blob))==0 ){ + if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; + }else if( (flags2 & MEM_Zero)!=0 ){ + if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; + } nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; @@ -1486,8 +1493,12 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ MemSetTypeFlag(pOut, MEM_Str); if( pOut!=pIn2 ){ memcpy(pOut->z, pIn2->z, pIn2->n); + assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) ); + pIn2->flags = flags2; } memcpy(&pOut->z[pIn2->n], pIn1->z, pIn1->n); + assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) ); + pIn1->flags = flags1; pOut->z[nByte]=0; pOut->z[nByte+1] = 0; pOut->flags |= MEM_Term; diff --git a/test/index.test b/test/index.test index ae16470570..e6c3d94eb5 100644 --- a/test/index.test +++ b/test/index.test @@ -738,6 +738,15 @@ do_test index-21.2 { } } {0 {9 5 1}} +# 2019-05-01 ticket https://www.sqlite.org/src/info/3be1295b264be2fa +do_execsql_test index-22.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a, b TEXT); + CREATE UNIQUE INDEX IF NOT EXISTS x1 ON t1(b==0); + CREATE INDEX IF NOT EXISTS x2 ON t1(a || 0) WHERE b; + INSERT INTO t1(a,b) VALUES('a',1),('a',0); + SELECT a, b, '|' FROM t1; +} {a 1 | a 0 |} finish_test From 0de0ab82074f1898fe1b7374683aeea6afae0675 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 May 2019 17:32:36 +0000 Subject: [PATCH 063/132] Fix a case in wapptest.tcl where a failed test might report 0 errors. FossilOrigin-Name: 2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/wapptest.tcl | 9 +++++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 12c2ec4d32..d503d5998c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunwelcomed\sside\seffects\son\sthe\sinput\soperands\sin\sthe\sOP_Concat\noperator.\s\sFix\sfor\sticket\s[3be1295b264be2fac49b681] -D 2019-05-01T15:32:40.553 +C Fix\sa\scase\sin\swapptest.tcl\swhere\sa\sfailed\stest\smight\sreport\s0\serrors. +D 2019-05-01T17:32:36.167 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1656,7 +1656,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec -F test/wapptest.tcl c4c32b89607f970500568cad83ed67a869beaf8c2f07bbc030a335ea6c7c750c x +F test/wapptest.tcl 32a23f9b4c9fa1126d29250368ba6d5689b7503aa0694df7edf9253f1d56f1d7 x F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c @@ -1822,7 +1822,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 09623cc4cc82e3c123d1fd5d88b2f4b50ec5f2cc7e579a7203258bf0c246a74f -R 36135537650a3222bb6001d7e31d8024 -U drh -Z 34e12fa35e79c97a2bb14481b73be0be +P 713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630 +R dc354a168f1bf70c2fd5f402743058b3 +U dan +Z 22ec1d29c68aeb8e171bdc1d1c0ccaa3 diff --git a/manifest.uuid b/manifest.uuid index 566972896c..fa703b3e9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630 \ No newline at end of file +2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc \ No newline at end of file diff --git a/test/wapptest.tcl b/test/wapptest.tcl index fe7ea202e8..88f0f074bf 100755 --- a/test/wapptest.tcl +++ b/test/wapptest.tcl @@ -222,6 +222,9 @@ proc slave_test_done {name rc} { sqlite3 sqlite3.exe test.log test-out.txt core + wapptest_make.sh + wapptest_configure.sh + wapptest_run.tcl } foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] { set t [file tail $f] @@ -277,16 +280,18 @@ proc wapptest_slave_script {} { set rc [catch { exec {*}$cfg >& test.log } msg] if {$rc==0} { set make [readfile wapptest_make.sh] - catch { exec {*}$make >>& test.log } + set rc [catch { exec {*}$make >>& test.log }] } } } else { append res { set make [readfile wapptest_make.sh] - catch { exec {*}$make >>& test.log } + set rc [catch { exec {*}$make >>& test.log }] } } + append res { exit $rc } + set res } From f78408c775274e7b01ed9f836ef4c5c52d9463e8 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 1 May 2019 17:36:56 +0000 Subject: [PATCH 064/132] Fix an incompatibility with -DSQLITE_OMIT_LOAD_EXTENSION=1 in dbdata.test. FossilOrigin-Name: a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/dbdata.test | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d503d5998c..16fb7d5c5c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scase\sin\swapptest.tcl\swhere\sa\sfailed\stest\smight\sreport\s0\serrors. -D 2019-05-01T17:32:36.167 +C Fix\san\sincompatibility\swith\s-DSQLITE_OMIT_LOAD_EXTENSION=1\sin\sdbdata.test. +D 2019-05-01T17:36:56.822 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -787,7 +787,7 @@ F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373 F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10 -F test/dbdata.test c8d97bafd1b2efb1e445871c4641208dcd91e686d2dfbb6463d83934adbd1ac5 +F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e F test/dbfuzz001.test e32d14465f1c77712896fda6a1ccc0f037b481c191c1696a9c44f6c9e4964faf F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee @@ -1822,7 +1822,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 713caa382cf7ddef872e510a76a5fca40be1a8d8876ce2f91b632bb0810a6630 -R dc354a168f1bf70c2fd5f402743058b3 +P 2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc +R ae90daf9628470675bc89644e7eb21cd U dan -Z 22ec1d29c68aeb8e171bdc1d1c0ccaa3 +Z 1604ae08830baf499595804bc5cb5239 diff --git a/manifest.uuid b/manifest.uuid index fa703b3e9a..96fada382a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc \ No newline at end of file +a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411 \ No newline at end of file diff --git a/test/dbdata.test b/test/dbdata.test index 391b278025..5b1150c78f 100644 --- a/test/dbdata.test +++ b/test/dbdata.test @@ -20,8 +20,9 @@ ifcapable !vtab||!compound { finish_test return } -db enable_load_extension 1 -if { [catch { db eval { SELECT load_extension('../dbdata') } }] } { +if { [catch { db enable_load_extension 1 }] + || [catch { db eval { SELECT load_extension('../dbdata') } }] +} { finish_test return } From 83a1dafb03af90f40c75e4839c81cf74b5cbfbc0 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 May 2019 18:59:33 +0000 Subject: [PATCH 065/132] When values have real affinity and are converted into strings for CHECK constraints or index expressions, do the conversions into a real-number format even if the values are stored as integers for efficiency. This appears to fix ticket [ae0f637bddc5290b446]. FossilOrigin-Name: 5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 15 ++++++++++++--- src/vdbeInt.h | 2 +- src/vdbemem.c | 51 +++++++++++++++++++++++++++------------------------ 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 16fb7d5c5c..fdae1f543e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sincompatibility\swith\s-DSQLITE_OMIT_LOAD_EXTENSION=1\sin\sdbdata.test. -D 2019-05-01T17:36:56.822 +C When\svalues\shave\sreal\saffinity\sand\sare\sconverted\sinto\sstrings\sfor\sCHECK\nconstraints\sor\sindex\sexpressions,\sdo\sthe\sconversions\sinto\sa\sreal-number\sformat\neven\sif\sthe\svalues\sare\sstored\sas\sintegers\sfor\sefficiency.\nThis\sappears\sto\sfix\sticket\s[ae0f637bddc5290b446]. +D 2019-05-01T18:59:33.898 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,13 +591,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 57b0b697d349876716499e073fb5e2d20ebc6cc0f752327a4e54031ed7e062f3 +F src/vdbe.c c15d6a105c41db6a166b0aa9650829bdc0d92918a8926a92332ea1feb27c33ba F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 -F src/vdbeInt.h 2c12704db9740c8e899786ecfc7a5797a9d067563496eb1b6ed03c592d7b8d90 +F src/vdbeInt.h 0e2c44958fb42d90a4eacb122d77e2d5b89b82f5e2b4b047b422962dc0346357 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 -F src/vdbemem.c dd2ee49255c4c5450f2b0887ef44cea8faa1cd7a46501b39a1a82b113ae418e3 +F src/vdbemem.c df36fd36c7585e42869f3a44f5da5dc70e13306bc97ba52eebe069e174ba55db F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 @@ -1822,7 +1822,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 2be1ed70df605663822d1afdde757f426ccf2ee38add8dc6b6bb4fc4d90a31dc -R ae90daf9628470675bc89644e7eb21cd -U dan -Z 1604ae08830baf499595804bc5cb5239 +P a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411 +R 24b657a2152d8497e843307e630b65a0 +U drh +Z 532f184e0e66c8f742c69b40ffa2c03e diff --git a/manifest.uuid b/manifest.uuid index 96fada382a..5fa0ea51e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411 \ No newline at end of file +5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 455d2b618a..7fa7bc2a71 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -514,6 +514,8 @@ static void memTracePrint(Mem *p){ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ printf(" si:%lld", p->u.i); + }else if( (p->flags & (MEM_Int|MEM_IntReal))==(MEM_Int|MEM_IntReal) ){ + printf(" ir:%lld", p->u.i); }else if( p->flags & MEM_Int ){ printf(" i:%lld", p->u.i); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -2776,13 +2778,20 @@ case OP_Affinity: { assert( pOp->p2>0 ); assert( zAffinity[pOp->p2]==0 ); pIn1 = &aMem[pOp->p1]; - do{ + while( 1 /*edit-by-break*/ ){ assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); - applyAffinity(pIn1, *(zAffinity++), encoding); + applyAffinity(pIn1, zAffinity[0], encoding); + if( zAffinity[0]==SQLITE_AFF_REAL && (pIn1->flags & MEM_Int)!=0 ){ + /* When applying REAL affinity, if the result is still MEM_Int, + ** indicate that REAL is actually desired */ + pIn1->flags |= MEM_IntReal; + } REGISTER_TRACE((int)(pIn1-aMem), pIn1); + zAffinity++; + if( zAffinity[0]==0 ) break; pIn1++; - }while( zAffinity[0] ); + } break; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 15a371d550..c84e4e4390 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -247,7 +247,7 @@ struct sqlite3_value { #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_AffMask 0x001f /* Mask of affinity bits */ #define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */ -/* Available 0x0040 */ +#define MEM_IntReal 0x0040 /* MEM_Int that stringifies like MEM_Real */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0xc1df /* Mask of type bits */ diff --git a/src/vdbemem.c b/src/vdbemem.c index 80d494867c..82f7f3e102 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -92,6 +92,25 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ } #endif +/* +** Render a Mem object which is either MEM_Int or MEM_Real into a +** buffer. +*/ +static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ + StrAccum acc; + assert( p->flags & (MEM_Int|MEM_Real) ); + sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); + if( p->flags & MEM_IntReal ){ + sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); + }else if( p->flags & MEM_Int ){ + sqlite3_str_appendf(&acc, "%lld", p->u.i); + }else{ + sqlite3_str_appendf(&acc, "%!.15g", p->u.r); + } + assert( acc.zText==zBuf && acc.mxAlloc<=0 ); + zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ +} + #ifdef SQLITE_DEBUG /* ** Check that string value of pMem agrees with its integer or real value. @@ -118,11 +137,7 @@ int sqlite3VdbeMemConsistentDualRep(Mem *p){ int i, j, incr; if( (p->flags & MEM_Str)==0 ) return 1; if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1; - if( p->flags & MEM_Int ){ - sqlite3_snprintf(sizeof(zBuf),zBuf,"%lld",p->u.i); - }else{ - sqlite3_snprintf(sizeof(zBuf),zBuf,"%!.15g",p->u.r); - } + vdbeMemRenderNum(sizeof(zBuf), zBuf, p); z = p->z; i = j = 0; incr = 1; @@ -248,7 +263,7 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ } assert( (pMem->flags & MEM_Dyn)==0 ); pMem->z = pMem->zMalloc; - pMem->flags &= (MEM_Null|MEM_Int|MEM_Real); + pMem->flags &= (MEM_Null|MEM_Int|MEM_Real|MEM_IntReal); return SQLITE_OK; } @@ -349,13 +364,12 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ ** user and the latter is an internal programming error. */ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ - int fg = pMem->flags; const int nByte = 32; assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); - assert( !(fg&MEM_Zero) ); - assert( !(fg&(MEM_Str|MEM_Blob)) ); - assert( fg&(MEM_Int|MEM_Real) ); + assert( !(pMem->flags&MEM_Zero) ); + assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); + assert( pMem->flags&(MEM_Int|MEM_Real) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -365,23 +379,12 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ return SQLITE_NOMEM_BKPT; } - /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8 - ** string representation of the value. Then, if the required encoding - ** is UTF-16le or UTF-16be do a translation. - ** - ** FIX ME: It would be better if sqlite3_snprintf() could do UTF-16. - */ - if( fg & MEM_Int ){ - sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i); - }else{ - assert( fg & MEM_Real ); - sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r); - } + vdbeMemRenderNum(nByte, pMem->z, pMem); assert( pMem->z!=0 ); pMem->n = sqlite3Strlen30NN(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; - if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real); + if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); sqlite3VdbeChangeEncoding(pMem, enc); return SQLITE_OK; } @@ -741,7 +744,7 @@ void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ pMem->flags |= (pMem->flags&MEM_Blob)>>3; sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); - pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero); + pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); break; } } From 7d0a3fd340b3a74d3811ccd70d9df58b4f772aac Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 1 May 2019 19:01:27 +0000 Subject: [PATCH 066/132] Add a test case for ticket [ae0f637bddc5290b44669e066a]. FossilOrigin-Name: ece481695fc3c959c3eba0fb485cdda43a10b06d17259b0121e15bfc5e8e8b9f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/index.test | 11 ++++++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index fdae1f543e..6979d5436c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\svalues\shave\sreal\saffinity\sand\sare\sconverted\sinto\sstrings\sfor\sCHECK\nconstraints\sor\sindex\sexpressions,\sdo\sthe\sconversions\sinto\sa\sreal-number\sformat\neven\sif\sthe\svalues\sare\sstored\sas\sintegers\sfor\sefficiency.\nThis\sappears\sto\sfix\sticket\s[ae0f637bddc5290b446]. -D 2019-05-01T18:59:33.898 +C Add\sa\stest\scase\sfor\sticket\s[ae0f637bddc5290b44669e066a]. +D 2019-05-01T19:01:27.714 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1031,7 +1031,7 @@ F test/incrvacuum.test 2aaee202b1f230e55779f70d155f6ba67bbdff8481d650214d256ab0f F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 -F test/index.test 58d6fba7748b7c545080759b334e759b22a06b728aa68a2abd106b8065184bdd +F test/index.test 05414fc7e1e128c327e089c2216d041ae7fb02232571f708f009a79a482cf1a3 F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 @@ -1822,7 +1822,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 a77cd85b1a8b86e71b511f05f8c67faa046d24a48684139d2f64e51249203411 -R 24b657a2152d8497e843307e630b65a0 +P 5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8 +R c6735d94da423c75a5fbf44f945ad851 U drh -Z 532f184e0e66c8f742c69b40ffa2c03e +Z bc6fd770927f38308301380ce5d36731 diff --git a/manifest.uuid b/manifest.uuid index 5fa0ea51e0..a535d6515f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8 \ No newline at end of file +ece481695fc3c959c3eba0fb485cdda43a10b06d17259b0121e15bfc5e8e8b9f \ No newline at end of file diff --git a/test/index.test b/test/index.test index e6c3d94eb5..4602041cd8 100644 --- a/test/index.test +++ b/test/index.test @@ -747,6 +747,15 @@ do_execsql_test index-22.0 { INSERT INTO t1(a,b) VALUES('a',1),('a',0); SELECT a, b, '|' FROM t1; } {a 1 | a 0 |} - + +# 2019-05-10 ticket https://www.sqlite.org/src/info/ae0f637bddc5290b +do_execsql_test index-23.0 { + DROP TABLE t1; + CREATE TABLE t1(a TEXT, b REAL); + CREATE UNIQUE INDEX t1x1 ON t1(a GLOB b); + INSERT INTO t1(a,b) VALUES('0.0','1'),('1.0','1'); + SELECT * FROM t1; + REINDEX; +} {0.0 1.0 1.0 1.0} finish_test From 01325a3f756501a8929c0642eb69734667f24289 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 May 2019 00:52:50 +0000 Subject: [PATCH 067/132] Fix an issue (discovered by OSSFuzz) in the enhanced OP_Concat operator from check-in [713caa382cf7dd] earlier today. FossilOrigin-Name: 3e897702f8f789fe5119b9042fb93eca3fbfcc44564fbfa66c65628725b1157d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6979d5436c..6e3dac55c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\stest\scase\sfor\sticket\s[ae0f637bddc5290b44669e066a]. -D 2019-05-01T19:01:27.714 +C Fix\san\sissue\s(discovered\sby\sOSSFuzz)\sin\sthe\senhanced\sOP_Concat\soperator\nfrom\scheck-in\s[713caa382cf7dd]\searlier\stoday. +D 2019-05-02T00:52:50.915 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c c15d6a105c41db6a166b0aa9650829bdc0d92918a8926a92332ea1feb27c33ba +F src/vdbe.c 36993059b87e7c2adf671aaa4ef5e0f826b6f4d95be15b019aee14308f0047b5 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 0e2c44958fb42d90a4eacb122d77e2d5b89b82f5e2b4b047b422962dc0346357 F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 @@ -1822,7 +1822,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 5997d075665faca6b70fa647e877ebc84c473b32887b96235865d59ce80247f8 -R c6735d94da423c75a5fbf44f945ad851 +P ece481695fc3c959c3eba0fb485cdda43a10b06d17259b0121e15bfc5e8e8b9f +R e11be1adfb0c3f0eaf3587a8d84226ea U drh -Z bc6fd770927f38308301380ce5d36731 +Z 373f392215a854f1484c07e1e5f7b6f0 diff --git a/manifest.uuid b/manifest.uuid index a535d6515f..27e888c142 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ece481695fc3c959c3eba0fb485cdda43a10b06d17259b0121e15bfc5e8e8b9f \ No newline at end of file +3e897702f8f789fe5119b9042fb93eca3fbfcc44564fbfa66c65628725b1157d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7fa7bc2a71..9bc5e4ee56 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1476,14 +1476,18 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ } if( (flags1 & (MEM_Str|MEM_Blob))==0 ){ if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; }else if( (flags1 & MEM_Zero)!=0 ){ if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; + flags1 = pIn1->flags & ~MEM_Str; } flags2 = pIn2->flags; if( (flags2 & (MEM_Str|MEM_Blob))==0 ){ if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; }else if( (flags2 & MEM_Zero)!=0 ){ if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; + flags2 = pIn2->flags & ~MEM_Str; } nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ From cf1747b78259462caad907eecb10750993ee7e4e Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 May 2019 01:41:53 +0000 Subject: [PATCH 068/132] The collating sequence of the column must be TEXT if the LIKE or GLOB pattern starts with a "+" sign. This is another case of ticket [c94369cae9b561b1f996d005] that was discovered by Manuel Rigger. FossilOrigin-Name: b043a54c3de54b286c4eae564eab6b99118a410d99bdb63480faba3123d2ca11 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 5 +++-- test/like3.test | 10 ++++++++++ 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6e3dac55c2..c5d7ac5c43 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sissue\s(discovered\sby\sOSSFuzz)\sin\sthe\senhanced\sOP_Concat\soperator\nfrom\scheck-in\s[713caa382cf7dd]\searlier\stoday. -D 2019-05-02T00:52:50.915 +C The\scollating\ssequence\sof\sthe\scolumn\smust\sbe\sTEXT\sif\sthe\sLIKE\sor\sGLOB\spattern\nstarts\swith\sa\s"+"\ssign.\s\sThis\sis\sanother\scase\sof\sticket\n[c94369cae9b561b1f996d005]\sthat\swas\sdiscovered\sby\sManuel\sRigger. +D 2019-05-02T01:41:53.006 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -608,7 +608,7 @@ F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/wherecode.c 0e76672930bea322eb3606d891a4744be55c09bcd3a995bfd501af62a46e0625 -F src/whereexpr.c 90859652920f153d2c03f075488744be2926625ebd36911bcbcb17d0d29c891c +F src/whereexpr.c 7fedf990999722dafda5ab8040feac93937a6f95f4671d8d629f2baf014b4b80 F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1088,7 +1088,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test d3684b5c60dd2d1f9574f9f296b31c995187c8c10c6ca573f9918c96af9ba642 +F test/like3.test b065d1ca38c03dd76caae1d4cc84ed3d6eb3f64b3ff6b0dfad6413a7b406cca4 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 @@ -1822,7 +1822,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 ece481695fc3c959c3eba0fb485cdda43a10b06d17259b0121e15bfc5e8e8b9f -R e11be1adfb0c3f0eaf3587a8d84226ea +P 3e897702f8f789fe5119b9042fb93eca3fbfcc44564fbfa66c65628725b1157d +R 9786e5fb7c74febd927aa84f3b72acbe U drh -Z 373f392215a854f1484c07e1e5f7b6f0 +Z a4cc8a25e8e445f4572d088b41336647 diff --git a/manifest.uuid b/manifest.uuid index 27e888c142..bbae2efd09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3e897702f8f789fe5119b9042fb93eca3fbfcc44564fbfa66c65628725b1157d \ No newline at end of file +b043a54c3de54b286c4eae564eab6b99118a410d99bdb63480faba3123d2ca11 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 961495c584..90e1b5be65 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -263,11 +263,11 @@ static int isLikeOrGlob( } zNew[iTo] = 0; - /* If the RHS begins with a digit or a minus sign, then the LHS must be + /* If the RHS begins with a digit or a +/- sign, then the LHS must be ** an ordinary column (not a virtual table column) with TEXT affinity. ** Otherwise the LHS might be numeric and "lhs >= rhs" would be false ** even though "lhs LIKE rhs" is true. But if the RHS does not start - ** with a digit or '-', then "lhs LIKE rhs" will always be false if + ** with a digit or +/-, then "lhs LIKE rhs" will always be false if ** the LHS is numeric and so the optimization still works. ** ** 2018-09-10 ticket c94369cae9b561b1f996d0054bfab11389f9d033 @@ -277,6 +277,7 @@ static int isLikeOrGlob( */ if( sqlite3Isdigit(zNew[0]) || zNew[0]=='-' + || zNew[0]=='+' || (zNew[0]+1=='0' && iTo==1) ){ if( pLeft->op!=TK_COLUMN diff --git a/test/like3.test b/test/like3.test index 89c9efa792..f9120e7384 100644 --- a/test/like3.test +++ b/test/like3.test @@ -178,6 +178,16 @@ do_eqp_test like3-5.211 { `--SEARCH TABLE t5b USING COVERING INDEX sqlite_autoindex_t5b_1 (x>? AND x Date: Thu, 2 May 2019 15:56:39 +0000 Subject: [PATCH 069/132] Earlier detection of a database corruption case in balance_nonroot(), to prevent a possible use of an uninitialized variable. FossilOrigin-Name: c509d8a8aebe0da4847e95cf737c21313a665de9a540da2db57b8ed22f98a402 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index c5d7ac5c43..e5b6b667a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\scollating\ssequence\sof\sthe\scolumn\smust\sbe\sTEXT\sif\sthe\sLIKE\sor\sGLOB\spattern\nstarts\swith\sa\s"+"\ssign.\s\sThis\sis\sanother\scase\sof\sticket\n[c94369cae9b561b1f996d005]\sthat\swas\sdiscovered\sby\sManuel\sRigger. -D 2019-05-02T01:41:53.006 +C Earlier\sdetection\sof\sa\sdatabase\scorruption\scase\sin\sbalance_nonroot(),\sto\nprevent\sa\spossible\suse\sof\san\suninitialized\svariable. +D 2019-05-02T15:56:39.144 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -460,7 +460,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ffe7101006aee2ab9e9dec2fc001998e57a8e59419c6ea4072d6c3935d3d50fb +F src/btree.c e048f240d9562ef0c6b87e9d8dfa31a08c262d6c8d52c1ac0d6ca340ed8188e0 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 2d9ddfeaf8e1dafc7e1fcc8a84e7a8b455199dac3b69037fc73af6279aa8447b @@ -1822,7 +1822,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 3e897702f8f789fe5119b9042fb93eca3fbfcc44564fbfa66c65628725b1157d -R 9786e5fb7c74febd927aa84f3b72acbe +P b043a54c3de54b286c4eae564eab6b99118a410d99bdb63480faba3123d2ca11 +R 18ab7c62d0e00aa10b61e04e6385c846 U drh -Z a4cc8a25e8e445f4572d088b41336647 +Z 008cd703689ead8de489aed4e8570f99 diff --git a/manifest.uuid b/manifest.uuid index bbae2efd09..c188b9ab55 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b043a54c3de54b286c4eae564eab6b99118a410d99bdb63480faba3123d2ca11 \ No newline at end of file +c509d8a8aebe0da4847e95cf737c21313a665de9a540da2db57b8ed22f98a402 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e282ff4ed4..e98cb7b05d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7636,6 +7636,7 @@ static int balance_nonroot( u16 maskPage = pOld->maskPage; u8 *piCell = aData + pOld->cellOffset; u8 *piEnd; + VVA_ONLY( int nCellAtStart = b.nCell; ) /* Verify that all sibling pages are of the same "type" (table-leaf, ** table-interior, index-leaf, or index-interior). @@ -7664,6 +7665,10 @@ static int balance_nonroot( */ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ + if( limitaiOvfl[0] ){ + rc = SQLITE_CORRUPT_BKPT; + goto balance_cleanup; + } limit = pOld->aiOvfl[0]; for(j=0; jnCell+pOld->nOverflow) ); cntOld[i] = b.nCell; if( i Date: Thu, 2 May 2019 17:06:01 +0000 Subject: [PATCH 070/132] Add options to wapptest.tcl similar to those supported by releasetest.tcl. Also add the -noui switch, for running without wapp altogether. FossilOrigin-Name: 005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 --- manifest | 14 ++-- manifest.uuid | 2 +- test/wapptest.tcl | 192 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 189 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index e5b6b667a6..3aedc4b097 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Earlier\sdetection\sof\sa\sdatabase\scorruption\scase\sin\sbalance_nonroot(),\sto\nprevent\sa\spossible\suse\sof\san\suninitialized\svariable. -D 2019-05-02T15:56:39.144 +C Add\soptions\sto\swapptest.tcl\ssimilar\sto\sthose\ssupported\sby\sreleasetest.tcl.\sAlso\sadd\sthe\s-noui\sswitch,\sfor\srunning\swithout\swapp\saltogether. +D 2019-05-02T17:06:01.169 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1656,7 +1656,7 @@ F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747 F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec -F test/wapptest.tcl 32a23f9b4c9fa1126d29250368ba6d5689b7503aa0694df7edf9253f1d56f1d7 x +F test/wapptest.tcl f387e81750b2938ccf445b8a061541626a4a31f55e9e500b3e38ef3ce177bc61 x F test/where.test 0607caa5a1fbfe7b93b95705981b463a3a0408038f22ae6e9dc11b36902b0e95 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c @@ -1822,7 +1822,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 b043a54c3de54b286c4eae564eab6b99118a410d99bdb63480faba3123d2ca11 -R 18ab7c62d0e00aa10b61e04e6385c846 -U drh -Z 008cd703689ead8de489aed4e8570f99 +P c509d8a8aebe0da4847e95cf737c21313a665de9a540da2db57b8ed22f98a402 +R ae122c629293e3edebd8b79e5ad2d64a +U dan +Z 2ff4926d40df66aaffbb2191925f93c2 diff --git a/manifest.uuid b/manifest.uuid index c188b9ab55..32b722ccd8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c509d8a8aebe0da4847e95cf737c21313a665de9a540da2db57b8ed22f98a402 \ No newline at end of file +005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 \ No newline at end of file diff --git a/test/wapptest.tcl b/test/wapptest.tcl index 88f0f074bf..62488a1eac 100755 --- a/test/wapptest.tcl +++ b/test/wapptest.tcl @@ -21,15 +21,19 @@ source [file join [file dirname [info script]] releasetest_data.tcl] set G(platform) $::tcl_platform(os)-$::tcl_platform(machine) set G(test) Normal set G(keep) 1 -set G(msvc) [expr {$::tcl_platform(platform)=="windows"}] +set G(msvc) 0 set G(tcl) [::tcl::pkgconfig get libdir,install] set G(jobs) 3 set G(debug) 0 +set G(noui) 0 +set G(stdout) 0 + + proc wapptest_init {} { global G - set lSave [list platform test keep msvc tcl jobs debug] + set lSave [list platform test keep msvc tcl jobs debug noui stdout] foreach k $lSave { set A($k) $G($k) } array unset G foreach k $lSave { set G($k) $A($k) } @@ -49,6 +53,22 @@ proc wapptest_init {} { append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)" } +proc wapptest_run {} { + global G + set_test_array + set G(state) "running" + + wapptest_openlog + + wapptest_output "Running the following for $G(platform). $G(jobs) jobs." + foreach t $G(test_array) { + set config [dict get $t config] + set target [dict get $t target] + wapptest_output [format " %-25s%s" $config $target] + } + wapptest_output [string repeat * 70] +} + # Generate the text for the box at the top of the UI. The current SQLite # version, according to fossil, along with a warning if there are # uncommitted changes in the checkout. @@ -197,6 +217,31 @@ proc count_tests_and_errors {name logfile} { } } +proc wapptest_output {str} { + global G + if {$G(stdout)} { puts $str } + if {[info exists G(log)]} { + puts $G(log) $str + flush $G(log) + } +} +proc wapptest_openlog {} { + global G + set G(log) [open wapptest-out.txt w+] +} +proc wapptest_closelog {} { + global G + close $G(log) + unset G(log) +} + +proc format_seconds {seconds} { + set min [format %.2d [expr ($seconds / 60) % 60]] + set hr [format %.2d [expr $seconds / 3600]] + set sec [format %.2d [expr $seconds % 60]] + return "$hr:$min:$sec" +} + # This command is invoked once a slave process has finished running its # tests, successfully or otherwise. Parameter $name is the name of the # test, $rc the exit code returned by the slave process. @@ -233,6 +278,18 @@ proc slave_test_done {name rc} { } } } + + # Format a message regarding the success or failure of hte test. + set t [format_seconds [expr $G(test.$name.done) - $G(test.$name.start)]] + set res "OK" + if {$G(test.$name.nError)} { set res "FAILED" } + set dots [string repeat . [expr 60 - [string length $name]]] + set msg "$name $dots $res ($t)" + + wapptest_output $msg + if {[info exists G(test.$name.errmsg)] && $G(test.$name.errmsg)!=""} { + wapptest_output " $G(test.$config.errmsg)" + } } # This is a fileevent callback invoked each time a file-descriptor that @@ -372,10 +429,15 @@ proc do_some_stuff {} { incr nConfig } set G(result) "$nError errors from $nTest tests in $nConfig configurations." + wapptest_output [string repeat * 70] + wapptest_output $G(result) catch { append G(result) " SQLite version $G(sqlite_version)" + wapptest_output " SQLite version $G(sqlite_version)" } set G(state) "stopped" + wapptest_closelog + if {$G(noui)} { exit 0 } } else { set nLaunch [expr $G(jobs) - $nRunning] foreach j $G(test_array) { @@ -543,11 +605,7 @@ proc wapp-page-tests {} { } set seconds [expr $G(test.$config.done) - $G(test.$config.start)] } - - set min [format %.2d [expr ($seconds / 60) % 60]] - set hr [format %.2d [expr $seconds / 3600]] - set sec [format %.2d [expr $seconds % 60]] - set seconds "$hr:$min:$sec" + set seconds [format_seconds $seconds] } wapp-trim { @@ -606,8 +664,7 @@ proc wapp-page-control {} { if {[wapp-param-exists control_run]} { # This is a "run test" command. - set_test_array - set ::G(state) "running" + wapptest_run } if {[wapp-param-exists control_stop]} { @@ -622,6 +679,7 @@ proc wapp-page-control {} { slave_test_done $name 1 } } + wapptest_closelog } if {[wapp-param-exists control_reset]} { @@ -773,6 +831,118 @@ proc wapp-page-log {} { } } -wapptest_init -wapp-start $argv +# Print out a usage message. Then do [exit 1]. +# +proc wapptest_usage {} { + puts stderr { +This Tcl script is used to test various configurations of SQLite. By +default it uses "wapp" to provide an interactive interface. Supported +command line options (all optional) are: + + --platform PLATFORM (which tests to run) + --smoketest (run "make smoketest" only) + --veryquick (run veryquick.test only) + --buildonly (build executables, do not run tests) + --jobs N (number of concurrent jobs) + --tcl DIR (where to find tclConfig.sh) + --deletefiles (delete extra files after each test) + --msvc (Use MS Visual C) + --debug (Also run [n]debugging versions of tests) + --noui (do not use wapp) + } + exit 1 +} + +# Sort command line arguments into two groups: those that belong to wapp, +# and those that belong to the application. +set WAPPARG(-server) 1 +set WAPPARG(-local) 1 +set WAPPARG(-scgi) 1 +set WAPPARG(-remote-scgi) 1 +set WAPPARG(-fromip) 1 +set WAPPARG(-nowait) 0 +set WAPPARG(-cgi) 0 +set lWappArg [list] +set lTestArg [list] +for {set i 0} {$i < [llength $argv]} {incr i} { + set arg [lindex $argv $i] + if {[string range $arg 0 1]=="--"} { + set arg [string range $arg 1 end] + } + if {[info exists WAPPARG($arg)]} { + lappend lWappArg $arg + if {$WAPPARG($arg)} { + incr i + lappend lWappArg [lindex $argv $i] + } + } else { + lappend lTestArg $arg + } +} + +for {set i 0} {$i < [llength $lTestArg]} {incr i} { + switch -- [lindex $lTestArg $i] { + -platform { + if {$i==[llength $lTestArg]-1} { wapptest_usage } + incr i + set arg [lindex $lTestArg $i] + set lPlatform [array names ::Platforms] + if {[lsearch $lPlatform $arg]<0} { + puts stderr "No such platform: $arg. Platforms are: $lPlatform" + exit -1 + } + set G(platform) $arg + } + + -smoketest { set G(test) Smoketest } + -veryquick { set G(test) Veryquick } + -buildonly { set G(test) Build-Only } + -jobs { + if {$i==[llength $lTestArg]-1} { wapptest_usage } + incr i + set G(jobs) [lindex $lTestArg $i] + } + + -tcl { + if {$i==[llength $lTestArg]-1} { wapptest_usage } + incr i + set G(tcl) [lindex $lTestArg $i] + } + + -deletefiles { + set G(keep) 0 + } + + -msvc { + set G(msvc) 1 + } + + -debug { + set G(debug) 1 + } + + -noui { + set G(noui) 1 + set G(stdout) 1 + } + + -stdout { + set G(stdout) 1 + } + + default { + puts stderr "Unrecognized option: [lindex $lTestArg $i]" + wapptest_usage + } + } +} + +wapptest_init +if {$G(noui)==0} { + wapp-start $lWappArg +} else { + wapptest_run + do_some_stuff + vwait forever +} From de7109e61b4ff3b632250cdcd962a1a440609549 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 May 2019 17:45:52 +0000 Subject: [PATCH 071/132] Ensure that the typeof() function always returns SQLITE_FLOAT for floating point values even when the value is stored as an integer to save space. FossilOrigin-Name: 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbeInt.h | 8 ++++---- src/vdbeapi.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ test/index.test | 8 ++++++++ 5 files changed, 69 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 3aedc4b097..381e157660 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\soptions\sto\swapptest.tcl\ssimilar\sto\sthose\ssupported\sby\sreleasetest.tcl.\sAlso\sadd\sthe\s-noui\sswitch,\sfor\srunning\swithout\swapp\saltogether. -D 2019-05-02T17:06:01.169 +C Ensure\sthat\sthe\stypeof()\sfunction\salways\sreturns\sSQLITE_FLOAT\sfor\sfloating\npoint\svalues\seven\swhen\sthe\svalue\sis\sstored\sas\san\sinteger\sto\ssave\sspace. +D 2019-05-02T17:45:52.902 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,8 +593,8 @@ F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf F src/vdbe.c 36993059b87e7c2adf671aaa4ef5e0f826b6f4d95be15b019aee14308f0047b5 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 -F src/vdbeInt.h 0e2c44958fb42d90a4eacb122d77e2d5b89b82f5e2b4b047b422962dc0346357 -F src/vdbeapi.c 2ddd60f4a351f15ee98d841e346af16111ad59dfa4d25d2dd4012e9875bf7d92 +F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 +F src/vdbeapi.c 5ef992332225d8b6151137fcaf33b4ba4d38db7e7c51f871d2e9ecb960f3709a F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c df36fd36c7585e42869f3a44f5da5dc70e13306bc97ba52eebe069e174ba55db @@ -1031,7 +1031,7 @@ F test/incrvacuum.test 2aaee202b1f230e55779f70d155f6ba67bbdff8481d650214d256ab0f F test/incrvacuum2.test 7d26cfda66c7e55898d196de54ac4ec7d86a4e3d F test/incrvacuum3.test 75256fb1377e7c39ef2de62bfc42bbff67be295a F test/incrvacuum_ioerr.test 6ae2f783424e47a0033304808fe27789cf93e635 -F test/index.test 05414fc7e1e128c327e089c2216d041ae7fb02232571f708f009a79a482cf1a3 +F test/index.test a2e948ed949e575487b5c1d521767d4584ac42d352f2dcd8e48004638e7bc7dc F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 @@ -1822,7 +1822,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 c509d8a8aebe0da4847e95cf737c21313a665de9a540da2db57b8ed22f98a402 -R ae122c629293e3edebd8b79e5ad2d64a -U dan -Z 2ff4926d40df66aaffbb2191925f93c2 +P 005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 +R 1a712fa3e334798d542297677e583b67 +U drh +Z 11e98b9b34589d0e8654b135f89f5a58 diff --git a/manifest.uuid b/manifest.uuid index 32b722ccd8..6808f0b46a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 \ No newline at end of file +48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index c84e4e4390..17e057b188 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -245,12 +245,12 @@ struct sqlite3_value { #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ -#define MEM_AffMask 0x001f /* Mask of affinity bits */ -#define MEM_FromBind 0x0020 /* Value originates from sqlite3_bind() */ -#define MEM_IntReal 0x0040 /* MEM_Int that stringifies like MEM_Real */ +#define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */ +#define MEM_AffMask 0x003f /* Mask of affinity bits */ +#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ -#define MEM_TypeMask 0xc1df /* Mask of type bits */ +#define MEM_TypeMask 0xc1bf /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 00eea75a45..65d4f9ae16 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -266,7 +266,54 @@ int sqlite3_value_type(sqlite3_value* pVal){ SQLITE_NULL, /* 0x1d */ SQLITE_INTEGER, /* 0x1e */ SQLITE_NULL, /* 0x1f */ + SQLITE_BLOB, /* 0x20 */ + SQLITE_NULL, /* 0x21 */ + SQLITE_TEXT, /* 0x22 */ + SQLITE_NULL, /* 0x23 */ + SQLITE_FLOAT, /* 0x24 */ + SQLITE_NULL, /* 0x25 */ + SQLITE_FLOAT, /* 0x26 */ + SQLITE_NULL, /* 0x27 */ + SQLITE_FLOAT, /* 0x28 */ + SQLITE_NULL, /* 0x29 */ + SQLITE_FLOAT, /* 0x2a */ + SQLITE_NULL, /* 0x2b */ + SQLITE_FLOAT, /* 0x2c */ + SQLITE_NULL, /* 0x2d */ + SQLITE_FLOAT, /* 0x2e */ + SQLITE_NULL, /* 0x2f */ + SQLITE_BLOB, /* 0x30 */ + SQLITE_NULL, /* 0x31 */ + SQLITE_TEXT, /* 0x32 */ + SQLITE_NULL, /* 0x33 */ + SQLITE_FLOAT, /* 0x34 */ + SQLITE_NULL, /* 0x35 */ + SQLITE_FLOAT, /* 0x36 */ + SQLITE_NULL, /* 0x37 */ + SQLITE_FLOAT, /* 0x38 */ + SQLITE_NULL, /* 0x39 */ + SQLITE_FLOAT, /* 0x3a */ + SQLITE_NULL, /* 0x3b */ + SQLITE_FLOAT, /* 0x3c */ + SQLITE_NULL, /* 0x3d */ + SQLITE_FLOAT, /* 0x3e */ + SQLITE_NULL, /* 0x3f */ }; +#ifdef SQLITE_DEBUG + { + int eType = SQLITE_BLOB; + if( pVal->flags & MEM_Null ){ + eType = SQLITE_NULL; + }else if( pVal->flags & MEM_Int ){ + eType = (pVal->flags & MEM_IntReal) ? SQLITE_FLOAT : SQLITE_INTEGER; + }else if( pVal->flags & MEM_Real ){ + eType = SQLITE_FLOAT; + }else if( pVal->flags & MEM_Str ){ + eType = SQLITE_TEXT; + } + assert( eType == aType[pVal->flags&MEM_AffMask] ); + } +#endif return aType[pVal->flags&MEM_AffMask]; } diff --git a/test/index.test b/test/index.test index 4602041cd8..15120a40c9 100644 --- a/test/index.test +++ b/test/index.test @@ -757,5 +757,13 @@ do_execsql_test index-23.0 { SELECT * FROM t1; REINDEX; } {0.0 1.0 1.0 1.0} +do_execsql_test index-23.1 { + DROP TABLE t1; + CREATE TABLE t1(a REAL); + CREATE UNIQUE INDEX index_0 ON t1(TYPEOF(a)); + INSERT OR IGNORE INTO t1(a) VALUES (0.1),(FALSE); + SELECT * FROM t1; + REINDEX; +} {0.1} finish_test From 169f077e07f312172cb0e5d6cb291b91b61d9164 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 2 May 2019 21:36:26 +0000 Subject: [PATCH 072/132] Make MEM_IntReal a completely independent type, meaning a floating point value stored as an integer. This fixes a problem with arithmetic within arguments to string functions on indexes of expressions. But it is a big change and needs lots of new testcase() macros for MC/DC and so it is initially put on this branch. FossilOrigin-Name: dba836e31cb29d339b4520acb06188a892a52e45c50aba9742966b01108e251a --- manifest | 23 +++++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 35 +++++++++++++++++++---------------- src/vdbeapi.c | 10 +++++----- src/vdbeaux.c | 22 ++++++++++++++-------- src/vdbemem.c | 49 +++++++++++++++++++++++++++---------------------- src/vdbetrace.c | 2 +- 7 files changed, 80 insertions(+), 63 deletions(-) diff --git a/manifest b/manifest index 381e157660..57dbaf3973 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\stypeof()\sfunction\salways\sreturns\sSQLITE_FLOAT\sfor\sfloating\npoint\svalues\seven\swhen\sthe\svalue\sis\sstored\sas\san\sinteger\sto\ssave\sspace. -D 2019-05-02T17:45:52.902 +C Make\sMEM_IntReal\sa\scompletely\sindependent\stype,\smeaning\sa\sfloating\spoint\nvalue\sstored\sas\san\sinteger.\s\sThis\sfixes\sa\sproblem\swith\sarithmetic\swithin\narguments\sto\sstring\sfunctions\son\sindexes\sof\sexpressions.\s\sBut\sit\sis\sa\sbig\nchange\sand\sneeds\slots\sof\snew\stestcase()\smacros\sfor\sMC/DC\sand\sso\sit\sis\ninitially\sput\son\sthis\sbranch. +D 2019-05-02T21:36:26.172 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,15 +591,15 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 36993059b87e7c2adf671aaa4ef5e0f826b6f4d95be15b019aee14308f0047b5 +F src/vdbe.c ddb6bb7289e017870636a60914bca64a545f70413e71c0e791513211b22f307c F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 -F src/vdbeapi.c 5ef992332225d8b6151137fcaf33b4ba4d38db7e7c51f871d2e9ecb960f3709a -F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 +F src/vdbeapi.c 76b8fcedce6d6299599580d98ce71f6d806e297c6e584d27d0356de44df3b307 +F src/vdbeaux.c 326e049995ca75ba158bbc09ef59347fd600c8e7bb3958db9e66d575fdcc243d F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 -F src/vdbemem.c df36fd36c7585e42869f3a44f5da5dc70e13306bc97ba52eebe069e174ba55db +F src/vdbemem.c e102c625dae2d5657a086b97f46ea7645cce23379fcae74737fbe00454399a81 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 -F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 +F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2 @@ -1822,7 +1822,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 005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 -R 1a712fa3e334798d542297677e583b67 +P 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 +R 5d33250f3b2797d2fce07efa1f0f1900 +T *branch * int-real +T *sym-int-real * +T -sym-trunk * U drh -Z 11e98b9b34589d0e8654b135f89f5a58 +Z 3590ba61495883d222cfb9f777b00293 diff --git a/manifest.uuid b/manifest.uuid index 6808f0b46a..10a2b8a3af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 \ No newline at end of file +dba836e31cb29d339b4520acb06188a892a52e45c50aba9742966b01108e251a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9bc5e4ee56..fa18db38d3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -295,7 +295,7 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ double rValue; i64 iValue; u8 enc = pRec->enc; - assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str ); + assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return; if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){ pRec->u.i = iValue; @@ -352,11 +352,11 @@ static void applyAffinity( ** there is already a string rep, but it is pointless to waste those ** CPU cycles. */ if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ - if( (pRec->flags&(MEM_Real|MEM_Int)) ){ + if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){ sqlite3VdbeMemStringify(pRec, enc, 1); } } - pRec->flags &= ~(MEM_Real|MEM_Int); + pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal); } } @@ -395,7 +395,7 @@ void sqlite3ValueApplyAffinity( ** accordingly. */ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ - assert( (pMem->flags & (MEM_Int|MEM_Real))==0 ); + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); ExpandBlob(pMem); if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){ @@ -415,8 +415,8 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ ** But it does set pMem->u.r and pMem->u.i appropriately. */ static u16 numericType(Mem *pMem){ - if( pMem->flags & (MEM_Int|MEM_Real) ){ - return pMem->flags & (MEM_Int|MEM_Real); + if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ + return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); } if( pMem->flags & (MEM_Str|MEM_Blob) ){ return computeNumericType(pMem); @@ -514,7 +514,7 @@ static void memTracePrint(Mem *p){ printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL"); }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ printf(" si:%lld", p->u.i); - }else if( (p->flags & (MEM_Int|MEM_IntReal))==(MEM_Int|MEM_IntReal) ){ + }else if( (p->flags & (MEM_IntReal))!=0 ){ printf(" ir:%lld", p->u.i); }else if( p->flags & MEM_Int ){ printf(" i:%lld", p->u.i); @@ -1630,7 +1630,7 @@ fp_math: } pOut->u.r = rB; MemSetTypeFlag(pOut, MEM_Real); - if( ((type1|type2)&MEM_Real)==0 && !bIntint ){ + if( ((type1|type2)&(MEM_Real|MEM_IntReal))==0 && !bIntint ){ sqlite3VdbeIntegerAffinity(pOut); } #endif @@ -1801,7 +1801,7 @@ case OP_MustBeInt: { /* jump, in1 */ */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; - if( pIn1->flags & MEM_Int ){ + if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ sqlite3VdbeMemRealify(pIn1); } break; @@ -1993,7 +1993,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ affinity = pOp->p5 & SQLITE_AFF_MASK; if( affinity>=SQLITE_AFF_NUMERIC ){ if( (flags1 | flags3)&MEM_Str ){ - if( (flags1 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn1,0); assert( flags3==pIn3->flags ); /* testcase( flags3!=pIn3->flags ); @@ -2003,7 +2003,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** in case our analysis is incorrect, so it is left in. */ flags3 = pIn3->flags; } - if( (flags3 & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3,0); } } @@ -2016,17 +2016,19 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ goto compare_op; } }else if( affinity==SQLITE_AFF_TEXT ){ - if( (flags1 & MEM_Str)==0 && (flags1 & (MEM_Int|MEM_Real))!=0 ){ + if( (flags1 & MEM_Str)==0 && (flags1&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); + testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); assert( pIn1!=pIn3 ); } - if( (flags3 & MEM_Str)==0 && (flags3 & (MEM_Int|MEM_Real))!=0 ){ + if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); + testcase( pIn3->flags & MEM_IntReal ); sqlite3VdbeMemStringify(pIn3, encoding, 1); testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); @@ -2790,6 +2792,7 @@ case OP_Affinity: { /* When applying REAL affinity, if the result is still MEM_Int, ** indicate that REAL is actually desired */ pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; } REGISTER_TRACE((int)(pIn1-aMem), pIn1); zAffinity++; @@ -3987,14 +3990,14 @@ case OP_SeekGT: { /* jump, in3, group */ ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){ + if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3, 0); } iKey = sqlite3VdbeIntValue(pIn3); /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ - if( (pIn3->flags & MEM_Int)==0 ){ + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ if( (pIn3->flags & MEM_Real)==0 ){ /* If the P3 value cannot be converted into any kind of a number, ** then the seek is not possible, so jump to P2 */ @@ -4379,7 +4382,7 @@ case OP_SeekRowid: { /* jump, in3 */ u64 iKey; pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & MEM_Int)==0 ){ + if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ /* Make sure pIn3->u.i contains a valid integer representation of ** the key value, but do not change the datatype of the register, as ** other parts of the perpared statement might be depending on the diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 65d4f9ae16..58dbdb5d51 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -266,7 +266,7 @@ int sqlite3_value_type(sqlite3_value* pVal){ SQLITE_NULL, /* 0x1d */ SQLITE_INTEGER, /* 0x1e */ SQLITE_NULL, /* 0x1f */ - SQLITE_BLOB, /* 0x20 */ + SQLITE_FLOAT, /* 0x20 */ SQLITE_NULL, /* 0x21 */ SQLITE_TEXT, /* 0x22 */ SQLITE_NULL, /* 0x23 */ @@ -304,10 +304,10 @@ int sqlite3_value_type(sqlite3_value* pVal){ int eType = SQLITE_BLOB; if( pVal->flags & MEM_Null ){ eType = SQLITE_NULL; - }else if( pVal->flags & MEM_Int ){ - eType = (pVal->flags & MEM_IntReal) ? SQLITE_FLOAT : SQLITE_INTEGER; - }else if( pVal->flags & MEM_Real ){ + }else if( pVal->flags & (MEM_Real|MEM_IntReal) ){ eType = SQLITE_FLOAT; + }else if( pVal->flags & MEM_Int ){ + eType = SQLITE_INTEGER; }else if( pVal->flags & MEM_Str ){ eType = SQLITE_TEXT; } @@ -1849,7 +1849,7 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ }else if( iIdx>=p->pUnpacked->nField ){ *ppValue = (sqlite3_value *)columnNullValue(); }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & MEM_Int ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ sqlite3VdbeMemRealify(pMem); } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 822c6fe60c..e2657ad40d 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1534,7 +1534,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ Mem *pMem = pOp->p4.pMem; if( pMem->flags & MEM_Str ){ zP4 = pMem->z; - }else if( pMem->flags & MEM_Int ){ + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ sqlite3_str_appendf(&x, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_str_appendf(&x, "%.16g", pMem->u.r); @@ -3432,7 +3432,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ *pLen = 0; return 0; } - if( flags&MEM_Int ){ + if( flags&(MEM_Int|MEM_IntReal) ){ /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */ # define MAX_6BYTE ((((i64)0x00008000)<<32)-1) i64 i = pMem->u.i; @@ -4111,8 +4111,8 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ /* At least one of the two values is a number */ - if( combined_flags&(MEM_Int|MEM_Real) ){ - if( (f1 & f2 & MEM_Int)!=0 ){ + if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){ + if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){ if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return +1; return 0; @@ -4122,15 +4122,19 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ if( pMem1->u.r > pMem2->u.r ) return +1; return 0; } - if( (f1&MEM_Int)!=0 ){ + if( (f1&(MEM_Int|MEM_IntReal))!=0 ){ if( (f2&MEM_Real)!=0 ){ return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); + }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + if( pMem1->u.i < pMem2->u.i ) return -1; + if( pMem1->u.i > pMem2->u.i ) return +1; + return 0; }else{ return -1; } } if( (f1&MEM_Real)!=0 ){ - if( (f2&MEM_Int)!=0 ){ + if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); }else{ return -1; @@ -4279,7 +4283,7 @@ int sqlite3VdbeRecordCompareWithSkip( u32 serial_type; /* RHS is an integer */ - if( pRhs->flags & MEM_Int ){ + if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ @@ -4624,7 +4628,9 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ testcase( flags & MEM_Real ); testcase( flags & MEM_Null ); testcase( flags & MEM_Blob ); - if( (flags & (MEM_Real|MEM_Null|MEM_Blob))==0 && p->pKeyInfo->aColl[0]==0 ){ + if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 + && p->pKeyInfo->aColl[0]==0 + ){ assert( flags & MEM_Str ); return vdbeRecordCompareString; } diff --git a/src/vdbemem.c b/src/vdbemem.c index 82f7f3e102..85d37513e5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -18,6 +18,11 @@ #include "sqliteInt.h" #include "vdbeInt.h" +/* True if X is a power of two. 0 is considered a power of two here. +** In other words, return true if X has at most one bit set. +*/ +#define ISPOWEROF2(X) (((X)&((X)-1))==0) + #ifdef SQLITE_DEBUG /* ** Check invariants on a Mem object. @@ -37,8 +42,8 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ ** That saves a few cycles in inner loops. */ assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 ); - /* Cannot be both MEM_Int and MEM_Real at the same time */ - assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) ); + /* Cannot have more than one of MEM_Int, MEM_Real, or MEM_IntReal */ + assert( ISPOWEROF2(p->flags & (MEM_Int|MEM_Real|MEM_IntReal)) ); if( p->flags & MEM_Null ){ /* Cannot be both MEM_Null and some other type */ @@ -93,17 +98,17 @@ int sqlite3VdbeCheckMemInvariants(Mem *p){ #endif /* -** Render a Mem object which is either MEM_Int or MEM_Real into a -** buffer. +** Render a Mem object which is one of MEM_Int, MEM_Real, or MEM_IntReal +** into a buffer. */ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ StrAccum acc; - assert( p->flags & (MEM_Int|MEM_Real) ); + assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); - if( p->flags & MEM_IntReal ){ - sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); - }else if( p->flags & MEM_Int ){ + if( p->flags & MEM_Int ){ sqlite3_str_appendf(&acc, "%lld", p->u.i); + }else if( p->flags & MEM_IntReal ){ + sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); }else{ sqlite3_str_appendf(&acc, "%!.15g", p->u.r); } @@ -136,7 +141,7 @@ int sqlite3VdbeMemConsistentDualRep(Mem *p){ char *z; int i, j, incr; if( (p->flags & MEM_Str)==0 ) return 1; - if( (p->flags & (MEM_Int|MEM_Real))==0 ) return 1; + if( (p->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ) return 1; vdbeMemRenderNum(sizeof(zBuf), zBuf, p); z = p->z; i = j = 0; @@ -249,8 +254,8 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ ** ** Any prior string or blob content in the pMem object may be discarded. ** The pMem->xDel destructor is called, if it exists. Though MEM_Str -** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null -** values are preserved. +** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, MEM_IntReal, +** and MEM_Null values are preserved. ** ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) ** if unable to complete the resizing. @@ -354,8 +359,8 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ ** are converted using sqlite3_snprintf(). Converting a BLOB to a string ** is a no-op. ** -** Existing representations MEM_Int and MEM_Real are invalidated if -** bForce is true but are retained if bForce is false. +** Existing representations MEM_Int, MEM_Real, or MEM_IntReal are invalidated +** if bForce is true but are retained if bForce is false. ** ** A MEM_Null value will never be passed to this function. This function is ** used for converting values to text for returning to the user (i.e. via @@ -369,7 +374,7 @@ int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !(pMem->flags&MEM_Zero) ); assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); - assert( pMem->flags&(MEM_Int|MEM_Real) ); + assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -558,7 +563,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem->flags; - if( flags & MEM_Int ){ + if( flags & (MEM_Int|MEM_IntReal) ){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); @@ -587,7 +592,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ return pMem->u.r; - }else if( pMem->flags & MEM_Int ){ + }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ return memRealValue(pMem); @@ -602,7 +607,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ ** Return the value ifNull if pMem is NULL. */ int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ - if( pMem->flags & MEM_Int ) return pMem->u.i!=0; + if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; if( pMem->flags & MEM_Null ) return ifNull; return sqlite3VdbeRealValue(pMem)!=0.0; } @@ -675,7 +680,7 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ } /* -** Convert pMem so that it has types MEM_Real or MEM_Int or both. +** Convert pMem so that it has type MEM_Real or MEM_Int. ** Invalidate any prior representations. ** ** Every effort is made to force the conversion, even if the input @@ -683,7 +688,7 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ - if( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))==0 ){ + if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ int rc; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -701,7 +706,7 @@ int sqlite3VdbeMemNumerify(Mem *pMem){ } } } - assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_Null))!=0 ); + assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))!=0 ); pMem->flags &= ~(MEM_Str|MEM_Blob|MEM_Zero); return SQLITE_OK; } @@ -928,7 +933,7 @@ void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ ** dual type, are allowed, as long as the underlying value is the ** same. */ u16 mFlags = pMem->flags & pX->flags & pX->mScopyFlags; - assert( (mFlags&MEM_Int)==0 || pMem->u.i==pX->u.i ); + assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i ); assert( (mFlags&MEM_Real)==0 || pMem->u.r==pX->u.r ); assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); @@ -1491,7 +1496,7 @@ static int valueFromExpr( }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } - if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; + if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ) pVal->flags &= ~MEM_Str; if( enc!=SQLITE_UTF8 ){ rc = sqlite3VdbeChangeEncoding(pVal, enc); } diff --git a/src/vdbetrace.c b/src/vdbetrace.c index b6d9381336..32c66af228 100644 --- a/src/vdbetrace.c +++ b/src/vdbetrace.c @@ -130,7 +130,7 @@ char *sqlite3VdbeExpandSql( pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ sqlite3_str_append(&out, "NULL", 4); - }else if( pVar->flags & MEM_Int ){ + }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){ sqlite3_str_appendf(&out, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); From 5bf4644f41336f85f066d009d9f67c446b439ed0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 May 2019 02:41:36 +0000 Subject: [PATCH 073/132] Fix the ".open --hexdb" command in the CLI so that it works even with terminal input. FossilOrigin-Name: 9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 381e157660..7214de0286 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\stypeof()\sfunction\salways\sreturns\sSQLITE_FLOAT\sfor\sfloating\npoint\svalues\seven\swhen\sthe\svalue\sis\sstored\sas\san\sinteger\sto\ssave\sspace. -D 2019-05-02T17:45:52.902 +C Fix\sthe\s".open\s--hexdb"\scommand\sin\sthe\sCLI\sso\sthat\sit\sworks\seven\swith\nterminal\sinput. +D 2019-05-03T02:41:36.666 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -520,7 +520,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 -F src/shell.c.in 567236da9ee68b1dfa363426858ee5e310976ffe422a7b7ae220c0315d7e8c53 +F src/shell.c.in 5470f08809ca5d9ac79f782f8f16d96a4299e584dbc456d8ef4aa6ca0824b5b3 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1822,7 +1822,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 005a169406ccea6e3cc42271620870d985e8bada1ad49a63656003db4911cb51 -R 1a712fa3e334798d542297677e583b67 +P 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 +R 6c4a08d775f402ededf164c110b85e69 U drh -Z 11e98b9b34589d0e8654b135f89f5a58 +Z 460ffd8bf743873ca175586bdb28c5f1 diff --git a/manifest.uuid b/manifest.uuid index 6808f0b46a..8b98d46674 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 \ No newline at end of file +9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index e145a1547c..fa8554ad76 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3877,6 +3877,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ }else{ in = p->in; nLine = p->lineno; + if( in==0 ) in = stdin; } *pnData = 0; nLine++; From f2566c4132bc85ec7a11bd2ce0bf012e24817cee Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 May 2019 17:08:16 +0000 Subject: [PATCH 074/132] Improved comments on the elements of the array constant used to implement the sqlite3_value_type() interface. FossilOrigin-Name: f73a7de7a53f6aa6517221550a9c9882893206edfd7433e80e5fc0f441db9fc4 --- manifest | 15 +++--- manifest.uuid | 2 +- src/vdbeapi.c | 128 +++++++++++++++++++++++++------------------------- 3 files changed, 71 insertions(+), 74 deletions(-) diff --git a/manifest b/manifest index 57dbaf3973..1348ae5aa5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sMEM_IntReal\sa\scompletely\sindependent\stype,\smeaning\sa\sfloating\spoint\nvalue\sstored\sas\san\sinteger.\s\sThis\sfixes\sa\sproblem\swith\sarithmetic\swithin\narguments\sto\sstring\sfunctions\son\sindexes\sof\sexpressions.\s\sBut\sit\sis\sa\sbig\nchange\sand\sneeds\slots\sof\snew\stestcase()\smacros\sfor\sMC/DC\sand\sso\sit\sis\ninitially\sput\son\sthis\sbranch. -D 2019-05-02T21:36:26.172 +C Improved\scomments\son\sthe\selements\sof\sthe\sarray\sconstant\sused\sto\simplement\nthe\ssqlite3_value_type()\sinterface. +D 2019-05-03T17:08:16.321 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -594,7 +594,7 @@ F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf F src/vdbe.c ddb6bb7289e017870636a60914bca64a545f70413e71c0e791513211b22f307c F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 -F src/vdbeapi.c 76b8fcedce6d6299599580d98ce71f6d806e297c6e584d27d0356de44df3b307 +F src/vdbeapi.c e9469b4097cd9fd0fc2045e4a219a3aeda141bf074abb49b5678554e3aad744b F src/vdbeaux.c 326e049995ca75ba158bbc09ef59347fd600c8e7bb3958db9e66d575fdcc243d F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c e102c625dae2d5657a086b97f46ea7645cce23379fcae74737fbe00454399a81 @@ -1822,10 +1822,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 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 -R 5d33250f3b2797d2fce07efa1f0f1900 -T *branch * int-real -T *sym-int-real * -T -sym-trunk * +P dba836e31cb29d339b4520acb06188a892a52e45c50aba9742966b01108e251a +R c4499152d6b5244a86bbe08fb4d56b35 U drh -Z 3590ba61495883d222cfb9f777b00293 +Z d1772b9a78cbf53bbe71ebce94e1a991 diff --git a/manifest.uuid b/manifest.uuid index 10a2b8a3af..d4493a3776 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dba836e31cb29d339b4520acb06188a892a52e45c50aba9742966b01108e251a \ No newline at end of file +f73a7de7a53f6aa6517221550a9c9882893206edfd7433e80e5fc0f441db9fc4 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 58dbdb5d51..df0bf65ebb 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -234,70 +234,70 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){ */ int sqlite3_value_type(sqlite3_value* pVal){ static const u8 aType[] = { - SQLITE_BLOB, /* 0x00 */ - SQLITE_NULL, /* 0x01 */ - SQLITE_TEXT, /* 0x02 */ - SQLITE_NULL, /* 0x03 */ - SQLITE_INTEGER, /* 0x04 */ - SQLITE_NULL, /* 0x05 */ - SQLITE_INTEGER, /* 0x06 */ - SQLITE_NULL, /* 0x07 */ - SQLITE_FLOAT, /* 0x08 */ - SQLITE_NULL, /* 0x09 */ - SQLITE_FLOAT, /* 0x0a */ - SQLITE_NULL, /* 0x0b */ - SQLITE_INTEGER, /* 0x0c */ - SQLITE_NULL, /* 0x0d */ - SQLITE_INTEGER, /* 0x0e */ - SQLITE_NULL, /* 0x0f */ - SQLITE_BLOB, /* 0x10 */ - SQLITE_NULL, /* 0x11 */ - SQLITE_TEXT, /* 0x12 */ - SQLITE_NULL, /* 0x13 */ - SQLITE_INTEGER, /* 0x14 */ - SQLITE_NULL, /* 0x15 */ - SQLITE_INTEGER, /* 0x16 */ - SQLITE_NULL, /* 0x17 */ - SQLITE_FLOAT, /* 0x18 */ - SQLITE_NULL, /* 0x19 */ - SQLITE_FLOAT, /* 0x1a */ - SQLITE_NULL, /* 0x1b */ - SQLITE_INTEGER, /* 0x1c */ - SQLITE_NULL, /* 0x1d */ - SQLITE_INTEGER, /* 0x1e */ - SQLITE_NULL, /* 0x1f */ - SQLITE_FLOAT, /* 0x20 */ - SQLITE_NULL, /* 0x21 */ - SQLITE_TEXT, /* 0x22 */ - SQLITE_NULL, /* 0x23 */ - SQLITE_FLOAT, /* 0x24 */ - SQLITE_NULL, /* 0x25 */ - SQLITE_FLOAT, /* 0x26 */ - SQLITE_NULL, /* 0x27 */ - SQLITE_FLOAT, /* 0x28 */ - SQLITE_NULL, /* 0x29 */ - SQLITE_FLOAT, /* 0x2a */ - SQLITE_NULL, /* 0x2b */ - SQLITE_FLOAT, /* 0x2c */ - SQLITE_NULL, /* 0x2d */ - SQLITE_FLOAT, /* 0x2e */ - SQLITE_NULL, /* 0x2f */ - SQLITE_BLOB, /* 0x30 */ - SQLITE_NULL, /* 0x31 */ - SQLITE_TEXT, /* 0x32 */ - SQLITE_NULL, /* 0x33 */ - SQLITE_FLOAT, /* 0x34 */ - SQLITE_NULL, /* 0x35 */ - SQLITE_FLOAT, /* 0x36 */ - SQLITE_NULL, /* 0x37 */ - SQLITE_FLOAT, /* 0x38 */ - SQLITE_NULL, /* 0x39 */ - SQLITE_FLOAT, /* 0x3a */ - SQLITE_NULL, /* 0x3b */ - SQLITE_FLOAT, /* 0x3c */ - SQLITE_NULL, /* 0x3d */ - SQLITE_FLOAT, /* 0x3e */ - SQLITE_NULL, /* 0x3f */ + SQLITE_BLOB, /* 0x00 (not possible) */ + SQLITE_NULL, /* 0x01 NULL */ + SQLITE_TEXT, /* 0x02 TEXT */ + SQLITE_NULL, /* 0x03 (not possible) */ + SQLITE_INTEGER, /* 0x04 INTEGER */ + SQLITE_NULL, /* 0x05 (not possible) */ + SQLITE_INTEGER, /* 0x06 INTEGER + TEXT */ + SQLITE_NULL, /* 0x07 (not possible) */ + SQLITE_FLOAT, /* 0x08 FLOAT */ + SQLITE_NULL, /* 0x09 (not possible) */ + SQLITE_FLOAT, /* 0x0a FLOAT + TEXT */ + SQLITE_NULL, /* 0x0b (not possible) */ + SQLITE_INTEGER, /* 0x0c (not possible) */ + SQLITE_NULL, /* 0x0d (not possible) */ + SQLITE_INTEGER, /* 0x0e (not possible) */ + SQLITE_NULL, /* 0x0f (not possible) */ + SQLITE_BLOB, /* 0x10 BLOB */ + SQLITE_NULL, /* 0x11 (not possible) */ + SQLITE_TEXT, /* 0x12 (not possible) */ + SQLITE_NULL, /* 0x13 (not possible) */ + SQLITE_INTEGER, /* 0x14 INTEGER + BLOB */ + SQLITE_NULL, /* 0x15 (not possible) */ + SQLITE_INTEGER, /* 0x16 (not possible) */ + SQLITE_NULL, /* 0x17 (not possible) */ + SQLITE_FLOAT, /* 0x18 FLOAT + BLOB */ + SQLITE_NULL, /* 0x19 (not possible) */ + SQLITE_FLOAT, /* 0x1a (not possible) */ + SQLITE_NULL, /* 0x1b (not possible) */ + SQLITE_INTEGER, /* 0x1c (not possible) */ + SQLITE_NULL, /* 0x1d (not possible) */ + SQLITE_INTEGER, /* 0x1e (not possible) */ + SQLITE_NULL, /* 0x1f (not possible) */ + SQLITE_FLOAT, /* 0x20 INTREAL */ + SQLITE_NULL, /* 0x21 (not possible) */ + SQLITE_TEXT, /* 0x22 INTREAL + TEXT */ + SQLITE_NULL, /* 0x23 (not possible) */ + SQLITE_FLOAT, /* 0x24 (not possible) */ + SQLITE_NULL, /* 0x25 (not possible) */ + SQLITE_FLOAT, /* 0x26 (not possible) */ + SQLITE_NULL, /* 0x27 (not possible) */ + SQLITE_FLOAT, /* 0x28 (not possible) */ + SQLITE_NULL, /* 0x29 (not possible) */ + SQLITE_FLOAT, /* 0x2a (not possible) */ + SQLITE_NULL, /* 0x2b (not possible) */ + SQLITE_FLOAT, /* 0x2c (not possible) */ + SQLITE_NULL, /* 0x2d (not possible) */ + SQLITE_FLOAT, /* 0x2e (not possible) */ + SQLITE_NULL, /* 0x2f (not possible) */ + SQLITE_BLOB, /* 0x30 (not possible) */ + SQLITE_NULL, /* 0x31 (not possible) */ + SQLITE_TEXT, /* 0x32 (not possible) */ + SQLITE_NULL, /* 0x33 (not possible) */ + SQLITE_FLOAT, /* 0x34 (not possible) */ + SQLITE_NULL, /* 0x35 (not possible) */ + SQLITE_FLOAT, /* 0x36 (not possible) */ + SQLITE_NULL, /* 0x37 (not possible) */ + SQLITE_FLOAT, /* 0x38 (not possible) */ + SQLITE_NULL, /* 0x39 (not possible) */ + SQLITE_FLOAT, /* 0x3a (not possible) */ + SQLITE_NULL, /* 0x3b (not possible) */ + SQLITE_FLOAT, /* 0x3c (not possible) */ + SQLITE_NULL, /* 0x3d (not possible) */ + SQLITE_FLOAT, /* 0x3e (not possible) */ + SQLITE_NULL, /* 0x3f (not possible) */ }; #ifdef SQLITE_DEBUG { From ac4085bc2c018c430c3f7d5bd21a5ad6bb64eabb Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 May 2019 17:19:10 +0000 Subject: [PATCH 075/132] Fix a problem where self-joins on views that are aggregate queries may return the wrong result. FossilOrigin-Name: 74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 4 +++- test/view.test | 15 +++++++++++++++ 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 7214de0286..4adcf5eb1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".open\s--hexdb"\scommand\sin\sthe\sCLI\sso\sthat\sit\sworks\seven\swith\nterminal\sinput. -D 2019-05-03T02:41:36.666 +C Fix\sa\sproblem\swhere\sself-joins\son\sviews\sthat\sare\saggregate\squeries\smay\sreturn\sthe\swrong\sresult. +D 2019-05-03T17:19:10.246 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -519,7 +519,7 @@ F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 +F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d F src/shell.c.in 5470f08809ca5d9ac79f782f8f16d96a4299e584dbc456d8ef4aa6ca0824b5b3 F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1597,7 +1597,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test 71e1bf4c0e2e0d37c84d7db5b33cd47eb4a7662c19d93ede4112b350b186f61f +F test/view.test ee9262cee79c7f4002fd2869887d3e8eccf70d9a4e1016f847242851edb18964 F test/vtab1.test 60b4f70aafa6078d6fdfc11417af3bd216d7ef5eafce16707a6ca3dae5166d20 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1822,7 +1822,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 48889530a9de22fee536edfd1627be62396ed18d842d5fd6d91e010b4337be95 -R 6c4a08d775f402ededf164c110b85e69 -U drh -Z 460ffd8bf743873ca175586bdb28c5f1 +P 9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 +R 3a762b6259a99ea92c807013215a2169 +U dan +Z a881ecc4521ccc109413c9747ca34901 diff --git a/manifest.uuid b/manifest.uuid index 8b98d46674..10ef7c5bdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 \ No newline at end of file +74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 2df79e2e6c..3754419092 100644 --- a/src/select.c +++ b/src/select.c @@ -5481,7 +5481,9 @@ static struct SrcList_item *isSelfJoinView( ** names in the same FROM clause. */ continue; } - if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){ + if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) + || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) + ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; diff --git a/test/view.test b/test/view.test index 59ff55c692..1107ecb365 100644 --- a/test/view.test +++ b/test/view.test @@ -701,4 +701,19 @@ do_test view-25.2 { set log } $res +#------------------------------------------------------------------------- +do_execsql_test view-26.0 { + CREATE TABLE t16(a, b, c UNIQUE); + INSERT INTO t16 VALUES(1, 1, 1); + INSERT INTO t16 VALUES(2, 2, 2); + INSERT INTO t16 VALUES(3, 3, 3); + CREATE VIEW v16 AS SELECT max(a) AS mx, min(b) AS mn FROM t16 GROUP BY c; + + SELECT * FROM v16 AS one, v16 AS two WHERE one.mx=1; +} { + 1 1 1 1 + 1 1 2 2 + 1 1 3 3 +} + finish_test From a51297200ff4c6825e299fab8f9debf25c3e6207 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 3 May 2019 18:50:24 +0000 Subject: [PATCH 076/132] Fix a memory-leak/segfault caused by using OP_OpenDup and OP_OpenEphemeral on the same VM cursor. FossilOrigin-Name: a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++++-- test/with3.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4adcf5eb1e..e6797fc705 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swhere\sself-joins\son\sviews\sthat\sare\saggregate\squeries\smay\sreturn\sthe\swrong\sresult. -D 2019-05-03T17:19:10.246 +C Fix\sa\smemory-leak/segfault\scaused\sby\susing\sOP_OpenDup\sand\sOP_OpenEphemeral\son\sthe\ssame\sVM\scursor. +D 2019-05-03T18:50:24.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 36993059b87e7c2adf671aaa4ef5e0f826b6f4d95be15b019aee14308f0047b5 +F src/vdbe.c 81aa6fe0b7eb6ecd05b04f7a4097cc188ba3a6b4944e9ff418331d4f026cac69 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c 5ef992332225d8b6151137fcaf33b4ba4d38db7e7c51f871d2e9ecb960f3709a @@ -1705,7 +1705,7 @@ F test/windowerr.test 675b5e6debfc9370bfacb0b91e2a93a8923512f92600b16f4ea70a1cd9 F test/windowfault.test 16e906a2c4110c88372ff4bd5de59ac7397ec2f025912eff8e5677eedd126898 F test/with1.test a07b5aad7f77acdf13e52e8814ea94606fcc72e9ea4c99baf293e9d7c63940be F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab -F test/with3.test 8d26920c88283e0a473ceebd3451554922108ce7b2a6a1157c47eb0a7011212c +F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test 7ac016d20317e36a2f142e960679e558e74f6809ce5f27bde668af01782500df @@ -1822,7 +1822,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 9b5d943426c9273162ecb4c561eb3b25e843318dd438239c882c9db50f788454 -R 3a762b6259a99ea92c807013215a2169 +P 74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 +R 5407b1be905c1bcf46d2ef60d3252201 U dan -Z a881ecc4521ccc109413c9747ca34901 +Z efe7ecc358ec0708b5835450f237d48e diff --git a/manifest.uuid b/manifest.uuid index 10ef7c5bdf..99fae280f7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 \ No newline at end of file +a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 9bc5e4ee56..93297418b3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -256,7 +256,7 @@ static VdbeCursor *allocateCursor( ** is clear. Otherwise, if this is an ephemeral cursor created by ** OP_OpenDup, the cursor will not be closed and will still be part ** of a BtShared.pCursor list. */ - p->apCsr[iCur]->isEphemeral = 0; + if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0; sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } @@ -3710,7 +3710,10 @@ case OP_OpenEphemeral: { if( pCx ){ /* If the ephermeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + assert( pCx->isEphemeral ); + if( pCx->pBtx ){ + rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + } }else{ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; diff --git a/test/with3.test b/test/with3.test index 0f49f06859..360d37f9b9 100644 --- a/test/with3.test +++ b/test/with3.test @@ -130,4 +130,40 @@ do_eqp_test 3.2.2 { `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?) } +do_execsql_test 4.0 { + WITH t5(t5col1) AS ( + SELECT ( + WITH t3(t3col1) AS ( + WITH t2 AS ( + WITH t1 AS (SELECT 1 AS c1 GROUP BY 1) + SELECT a.c1 FROM t1 AS a, t1 AS b + WHERE anoncol1 = 1 + ) + SELECT (SELECT 1 FROM t2) FROM t2 + ) + SELECT t3col1 FROM t3 WHERE t3col1 + ) FROM (SELECT 1 AS anoncol1) + ) + SELECT t5col1, t5col1 FROM t5 +} {1 1} +do_execsql_test 4.1 { + SELECT EXISTS ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0(Col0) AS (SELECT ALL 1 ) + SELECT ALL ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0 AS ( + WITH RECURSIVE Table0 AS (SELECT DISTINCT 1 GROUP BY 1 ) + SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0 + WHERE Col0 = 1 + ) + SELECT ALL (SELECT DISTINCT * FROM Table0) FROM Table0 WHERE Col0 = 1 + ) + SELECT ALL * FROM Table0 NATURAL INNER JOIN Table0 + ) FROM Table0 ) + SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0 + ); +} {1} + + finish_test From 30d3b0ceb55f4a1fcf661236dee0cd0437f35fcb Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 May 2019 19:34:41 +0000 Subject: [PATCH 077/132] Ensure that UTF16 strings are properly zero-terminated before returning them in an sqlite3_value_text16() request, even if the string is invalid UTF16 because it was formed from an arbitrary and/or odd-length BLOB. FossilOrigin-Name: 3a16ddf91f0c9c516a7fc2a9d4a4f69a8326f9b8ea66421e9ef1a2d663687b70 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbemem.c | 14 ++++++++++---- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e6797fc705..6b54f864de 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\smemory-leak/segfault\scaused\sby\susing\sOP_OpenDup\sand\sOP_OpenEphemeral\son\sthe\ssame\sVM\scursor. -D 2019-05-03T18:50:24.588 +C Ensure\sthat\sUTF16\sstrings\sare\sproperly\szero-terminated\sbefore\sreturning\sthem\nin\san\ssqlite3_value_text16()\srequest,\seven\sif\sthe\sstring\sis\sinvalid\sUTF16\nbecause\sit\swas\sformed\sfrom\san\sarbitrary\sand/or\sodd-length\sBLOB. +D 2019-05-03T19:34:41.227 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -597,7 +597,7 @@ F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c 5ef992332225d8b6151137fcaf33b4ba4d38db7e7c51f871d2e9ecb960f3709a F src/vdbeaux.c f873b5c2efcf8a4d6ecfc5b1a5b06fd810419198f3bd882175d371cc03801873 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 -F src/vdbemem.c df36fd36c7585e42869f3a44f5da5dc70e13306bc97ba52eebe069e174ba55db +F src/vdbemem.c 42a33c8f00728fcf141b05f9c4d1bc3a2d34ebc4427b8631898e31fc22ea944d F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c 79d6dbbc479267b255a7de8080eee6e729928a0ef93ed9b0bfa5618875b48392 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 @@ -1822,7 +1822,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 74ef97bf51dd531a277cf22fa4d42043d93799d5a5bd550812648834460fe0b7 -R 5407b1be905c1bcf46d2ef60d3252201 -U dan -Z efe7ecc358ec0708b5835450f237d48e +P a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 +R 0f91a6c43eba1f33d4776f7747589015 +U drh +Z 872a39f55a8963133e9f411eb3938cfd diff --git a/manifest.uuid b/manifest.uuid index 99fae280f7..450783c9a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269 \ No newline at end of file +3a16ddf91f0c9c516a7fc2a9d4a4f69a8326f9b8ea66421e9ef1a2d663687b70 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 82f7f3e102..96edebcdef 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -270,13 +270,19 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ /* ** It is already known that pMem contains an unterminated string. ** Add the zero terminator. +** +** Three bytes of zero are added. In this way, there is guaranteed +** to be a double-zero byte at an even byte boundary in order to +** terminate a UTF16 string, even if the initial size of the buffer +** is an odd number of bytes. */ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ - if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){ return SQLITE_NOMEM_BKPT; } pMem->z[pMem->n] = 0; pMem->z[pMem->n+1] = 0; + pMem->z[pMem->n+2] = 0; pMem->flags |= MEM_Term; return SQLITE_OK; } @@ -350,9 +356,9 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){ } /* -** Add MEM_Str to the set of representations for the given Mem. Numbers -** are converted using sqlite3_snprintf(). Converting a BLOB to a string -** is a no-op. +** Add MEM_Str to the set of representations for the given Mem. This +** routine is only called if pMem is a number of some kind, not a NULL +** or a BLOB. ** ** Existing representations MEM_Int and MEM_Real are invalidated if ** bForce is true but are retained if bForce is false. From 0c8f40389ea950077ec8e265b4d9cb7a15e2bc58 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 3 May 2019 21:17:28 +0000 Subject: [PATCH 078/132] Add the SQLITE_TESTCTRL_RESULT_INTREAL test-control and use it to create the intreal() SQL function in testfixture. Write a few simple tests to prove this all works. TH3 will hold most of the INTREAL tests, probably. FossilOrigin-Name: c9838731325e0ca73bd8784c10c74ae043fed7861e6de269fd90e29fa4a19955 --- manifest | 21 ++++++++++--------- manifest.uuid | 2 +- src/main.c | 16 +++++++++++++++ src/sqlite.h.in | 3 ++- src/sqliteInt.h | 3 +++ src/test1.c | 22 ++++++++++++++++++++ src/vdbeapi.c | 15 ++++++++++++++ test/intreal.test | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 test/intreal.test diff --git a/manifest b/manifest index 1348ae5aa5..315fac96c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\son\sthe\selements\sof\sthe\sarray\sconstant\sused\sto\simplement\nthe\ssqlite3_value_type()\sinterface. -D 2019-05-03T17:08:16.321 +C Add\sthe\sSQLITE_TESTCTRL_RESULT_INTREAL\stest-control\sand\suse\sit\sto\screate\nthe\sintreal()\sSQL\sfunction\sin\stestfixture.\s\sWrite\sa\sfew\ssimple\stests\sto\nprove\sthis\sall\sworks.\s\sTH3\swill\shold\smost\sof\sthe\sINTREAL\stests,\sprobably. +D 2019-05-03T21:17:28.623 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -483,7 +483,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c fc3cf5c371f9a400144e8c2f148ab29cd3f67f7da7eaf47e6a6959f8255fd92c F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 16eea1ab004331312da0538dafb497cc0ed82fd9bb2e67f7684b40bf2797b666 +F src/main.c 3c3925b0bcb4c45687fd52f54c79e98e379252e1d3393f8b7dcccfa26181b661 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -521,15 +521,15 @@ F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c b7304d2f491c11a03a7fbdf34bc218282ac54052377809d4dc3b4b1e7f4bfc93 F src/shell.c.in 567236da9ee68b1dfa363426858ee5e310976ffe422a7b7ae220c0315d7e8c53 -F src/sqlite.h.in 38390767acc1914d58930e03149595ee4710afa4e3c43ab6c3a8aea3f1a6b8cd +F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 866311ac436c0c2039fccc7ea976fbc79d40c1c2ea687161fa4ba64379b53ae6 +F src/sqliteInt.h 443270b81c96101914eadd4e649d2f8210f4bbed569a6ff5ca8facfc74e20f26 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 -F src/test1.c c02d8bc27bb61d987b6f696ef62ce583272dbdd03042a241bc5ac767d3558709 +F src/test1.c f4e0be5c344587b2beac474a58018a3833208fb6bbec35d37d58b1270a7a5917 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -594,7 +594,7 @@ F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf F src/vdbe.c ddb6bb7289e017870636a60914bca64a545f70413e71c0e791513211b22f307c F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 -F src/vdbeapi.c e9469b4097cd9fd0fc2045e4a219a3aeda141bf074abb49b5678554e3aad744b +F src/vdbeapi.c 3e8a5dacbce3375a967343d2aa4816121c9b1cd32ff6fc715e2d62afa5f6c456 F src/vdbeaux.c 326e049995ca75ba158bbc09ef59347fd600c8e7bb3958db9e66d575fdcc243d F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c e102c625dae2d5657a086b97f46ea7645cce23379fcae74737fbe00454399a81 @@ -1057,6 +1057,7 @@ F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 +F test/intreal.test 1d03e48c53224b69efc8cb7349f009e388c116790bfdb4d320b233d603aaba9a F test/io.test f95bca1783b01ea7761671560d023360d2dfa4cc F test/ioerr.test 470fcc78e9cd352d162baf782fe301ea807d764241f58a48fc58109c2dfcdb6b F test/ioerr2.test 2593563599e2cc6b6b4fcf5878b177bdd5d8df26 @@ -1822,7 +1823,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 dba836e31cb29d339b4520acb06188a892a52e45c50aba9742966b01108e251a -R c4499152d6b5244a86bbe08fb4d56b35 +P f73a7de7a53f6aa6517221550a9c9882893206edfd7433e80e5fc0f441db9fc4 +R 8eb9fb04cc1483ad2c0c96b5f3e94e7c U drh -Z d1772b9a78cbf53bbe71ebce94e1a991 +Z f5b7804d98a17ecda4dff9fb2344fde1 diff --git a/manifest.uuid b/manifest.uuid index d4493a3776..26b7aea845 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f73a7de7a53f6aa6517221550a9c9882893206edfd7433e80e5fc0f441db9fc4 \ No newline at end of file +c9838731325e0ca73bd8784c10c74ae043fed7861e6de269fd90e29fa4a19955 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 24f7f20f39..6358457c85 100644 --- a/src/main.c +++ b/src/main.c @@ -4104,6 +4104,22 @@ int sqlite3_test_control(int op, ...){ break; } #endif /* defined(YYCOVERAGE) */ + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*); + ** + ** This test-control causes the most recent sqlite3_result_int64() value + ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally, + ** MEM_IntReal values only arise during an INSERT operation of integer + ** values into a REAL column, so they can be challenging to test. This + ** test-control enables us to write an intreal() SQL function that can + ** inject an intreal() value at arbitrary places in an SQL statement, + ** for testing purposes. + */ + case SQLITE_TESTCTRL_RESULT_INTREAL: { + sqlite3_context *pCtx = va_arg(ap, sqlite3_context*); + sqlite3ResultIntReal(pCtx); + break; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index cf390ac372..b9c2330d46 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -7319,7 +7319,8 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_IMPOSTER 25 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26 -#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_RESULT_INTREAL 27 +#define SQLITE_TESTCTRL_LAST 27 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 00ac00274f..e6b3aeca18 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4272,6 +4272,9 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); void sqlite3ValueSetNull(sqlite3_value*); void sqlite3ValueFree(sqlite3_value*); +#ifndef SQLITE_UNTESTABLE +void sqlite3ResultIntReal(sqlite3_context*); +#endif sqlite3_value *sqlite3ValueNew(sqlite3 *); #ifndef SQLITE_OMIT_UTF16 char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); diff --git a/src/test1.c b/src/test1.c index dcbc9e613a..be31ee110b 100644 --- a/src/test1.c +++ b/src/test1.c @@ -998,6 +998,20 @@ static void nondeterministicFunction( sqlite3_result_int(context, cnt++); } +/* +** This SQL function returns the integer value of its argument as a MEM_IntReal +** value. +*/ +static void intrealFunction( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3_int64 v = sqlite3_value_int64(argv[0]); + sqlite3_result_int64(context, v); + sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, context); +} + /* ** Usage: sqlite3_create_function DB ** @@ -1062,6 +1076,14 @@ static int SQLITE_TCLAPI test_create_function( 0, nondeterministicFunction, 0, 0); } + /* The intreal() function converts its argument to an integer and returns + ** it as a MEM_IntReal. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "intreal", 1, SQLITE_UTF8, + 0, intrealFunction, 0, 0); + } + #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index df0bf65ebb..f145d035cf 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -563,6 +563,21 @@ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ sqlite3OomFault(pCtx->pOut->db); } +#ifndef SQLITE_UNTESTABLE +/* Force the INT64 value currently stored as the result to be +** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL +** test-control. +*/ +void sqlite3ResultIntReal(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + if( pCtx->pOut->flags & MEM_Int ){ + pCtx->pOut->flags &= ~MEM_Int; + pCtx->pOut->flags |= MEM_IntReal; + } +} +#endif + + /* ** This function is called after a transaction has been committed. It ** invokes callbacks registered with sqlite3_wal_hook() as required. diff --git a/test/intreal.test b/test/intreal.test new file mode 100644 index 0000000000..a99e23d430 --- /dev/null +++ b/test/intreal.test @@ -0,0 +1,52 @@ +# 2019-05-03 +# +# 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. +# +#*********************************************************************** +# Tests to exercise the MEM_IntReal representation of Mem objects. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set ::testprefix intreal + +sqlite3_create_function db +do_execsql_test 100 { + SELECT intreal(5); +} {5.0} +do_execsql_test 110 { + SELECT intreal(5)=5, 6=intreal(6); +} {1 1} +do_execsql_test 120 { + SELECT intreal(7)=7.0, 8.0=intreal(8); +} {1 1} +do_execsql_test 130 { + SELECT typeof(intreal(9)); +} {real} +do_execsql_test 140 { + SELECT 'a'||intreal(11)||'z'; +} {a11.0z} + +do_execsql_test 150 { + SELECT max(1.0,intreal(2),3.0), max(1,intreal(2),3); +} {3.0 3} +do_execsql_test 160 { + SELECT max(1.0,intreal(4),3.0), max(1,intreal(4),3); +} {4.0 4.0} +do_execsql_test 170 { + SELECT max(1.0,intreal(2),intreal(3),4.0), + max(1,intreal(2),intreal(3),4); +} {4.0 4} +do_execsql_test 180 { + SELECT max(1.0,intreal(5),intreal(3),4.0), + max(1,intreal(5),intreal(3),4); +} {5.0 5.0} + + + + +finish_test From 3242c69c9140d54d98b110b72055e17fd6ede5e0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 May 2019 01:29:13 +0000 Subject: [PATCH 079/132] New testcase macros to ensure that MEM_IntReal is fully tested. FossilOrigin-Name: 8b8ef445ccccc148af2cda5975986af0d134352fe16283f65d0f8a91c9ffa932 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 12 ++++++++++++ src/vdbeapi.c | 2 ++ src/vdbeaux.c | 13 +++++++++++++ src/vdbemem.c | 14 +++++++++++++- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 315fac96c6..4e83d71d95 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_TESTCTRL_RESULT_INTREAL\stest-control\sand\suse\sit\sto\screate\nthe\sintreal()\sSQL\sfunction\sin\stestfixture.\s\sWrite\sa\sfew\ssimple\stests\sto\nprove\sthis\sall\sworks.\s\sTH3\swill\shold\smost\sof\sthe\sINTREAL\stests,\sprobably. -D 2019-05-03T21:17:28.623 +C New\stestcase\smacros\sto\sensure\sthat\sMEM_IntReal\sis\sfully\stested. +D 2019-05-04T01:29:13.397 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,13 +591,13 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c ddb6bb7289e017870636a60914bca64a545f70413e71c0e791513211b22f307c +F src/vdbe.c b0c87760d0e2460a48aa7ff70d9e96fb845cd9af02cf7d7a66de4e2ac39a72bc F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 -F src/vdbeapi.c 3e8a5dacbce3375a967343d2aa4816121c9b1cd32ff6fc715e2d62afa5f6c456 -F src/vdbeaux.c 326e049995ca75ba158bbc09ef59347fd600c8e7bb3958db9e66d575fdcc243d +F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da +F src/vdbeaux.c 94f5bea5db40f6c26a2db320788745a3852202a2ab4472928247955619027906 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 -F src/vdbemem.c e102c625dae2d5657a086b97f46ea7645cce23379fcae74737fbe00454399a81 +F src/vdbemem.c 81dc93a8b6a02b874920bc20be7d529cfce84229ecbd53a7cd3170a0fa115440 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 @@ -1823,7 +1823,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 f73a7de7a53f6aa6517221550a9c9882893206edfd7433e80e5fc0f441db9fc4 -R 8eb9fb04cc1483ad2c0c96b5f3e94e7c +P c9838731325e0ca73bd8784c10c74ae043fed7861e6de269fd90e29fa4a19955 +R 90de5cd79636b0a1b576e1c339f26a72 U drh -Z f5b7804d98a17ecda4dff9fb2344fde1 +Z bb3da40e826b6604a073d2d31bc7ecda diff --git a/manifest.uuid b/manifest.uuid index 26b7aea845..389d168cc0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c9838731325e0ca73bd8784c10c74ae043fed7861e6de269fd90e29fa4a19955 \ No newline at end of file +8b8ef445ccccc148af2cda5975986af0d134352fe16283f65d0f8a91c9ffa932 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index fa18db38d3..7242b3b1bc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -353,6 +353,9 @@ static void applyAffinity( ** CPU cycles. */ if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ if( (pRec->flags&(MEM_Real|MEM_Int|MEM_IntReal)) ){ + testcase( pRec->flags & MEM_Int ); + testcase( pRec->flags & MEM_Real ); + testcase( pRec->flags & MEM_IntReal ); sqlite3VdbeMemStringify(pRec, enc, 1); } } @@ -416,9 +419,14 @@ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ */ static u16 numericType(Mem *pMem){ if( pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); return pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal); } if( pMem->flags & (MEM_Str|MEM_Blob) ){ + testcase( pMem->flags & MEM_Str ); + testcase( pMem->flags & MEM_Blob ); return computeNumericType(pMem); } return 0; @@ -1802,6 +1810,8 @@ case OP_MustBeInt: { /* jump, in1 */ case OP_RealAffinity: { /* in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pIn1->flags & MEM_Int ); + testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pIn1); } break; @@ -4382,6 +4392,8 @@ case OP_SeekRowid: { /* jump, in3 */ u64 iKey; pIn3 = &aMem[pOp->p3]; + testcase( pIn3->flags & MEM_Int ); + testcase( pIn3->flags & MEM_IntReal ); if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ /* Make sure pIn3->u.i contains a valid integer representation of ** the key value, but do not change the datatype of the register, as diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f145d035cf..83221d9724 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1865,6 +1865,8 @@ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ *ppValue = (sqlite3_value *)columnNullValue(); }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pMem); } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e2657ad40d..ddeeeecf20 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3437,6 +3437,8 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ # define MAX_6BYTE ((((i64)0x00008000)<<32)-1) i64 i = pMem->u.i; u64 u; + testcase( flags & MEM_Int ); + testcase( flags & MEM_IntReal ); if( i<0 ){ u = ~i; }else{ @@ -4112,7 +4114,12 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ /* At least one of the two values is a number */ if( combined_flags&(MEM_Int|MEM_Real|MEM_IntReal) ){ + testcase( combined_flags & MEM_Int ); + testcase( combined_flags & MEM_Real ); + testcase( combined_flags & MEM_IntReal ); if( (f1 & f2 & (MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & f2 & MEM_Int ); + testcase( f1 & f2 & MEM_IntReal ); if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return +1; return 0; @@ -4123,6 +4130,8 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ return 0; } if( (f1&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f1 & MEM_Int ); + testcase( f1 & MEM_IntReal ); if( (f2&MEM_Real)!=0 ){ return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ @@ -4135,6 +4144,8 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){ } if( (f1&MEM_Real)!=0 ){ if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ + testcase( f2 & MEM_Int ); + testcase( f2 & MEM_IntReal ); return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); }else{ return -1; @@ -4284,6 +4295,8 @@ int sqlite3VdbeRecordCompareWithSkip( /* RHS is an integer */ if( pRhs->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pRhs->flags & MEM_Int ); + testcase( pRhs->flags & MEM_IntReal ); serial_type = aKey1[idx1]; testcase( serial_type==12 ); if( serial_type>=10 ){ diff --git a/src/vdbemem.c b/src/vdbemem.c index 85d37513e5..d1e6ac4d77 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -564,6 +564,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem->flags; if( flags & (MEM_Int|MEM_IntReal) ){ + testcase( flags & MEM_IntReal ); return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); @@ -593,6 +594,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ if( pMem->flags & MEM_Real ){ return pMem->u.r; }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_IntReal ); return (double)pMem->u.i; }else if( pMem->flags & (MEM_Str|MEM_Blob) ){ return memRealValue(pMem); @@ -607,6 +609,7 @@ double sqlite3VdbeRealValue(Mem *pMem){ ** Return the value ifNull if pMem is NULL. */ int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ + testcase( pMem->flags & MEM_IntReal ); if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; if( pMem->flags & MEM_Null ) return ifNull; return sqlite3VdbeRealValue(pMem)!=0.0; @@ -688,6 +691,10 @@ static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ ** as much of the string as we can and ignore the rest. */ int sqlite3VdbeMemNumerify(Mem *pMem){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_Real ); + testcase( pMem->flags & MEM_IntReal ); + testcase( pMem->flags & MEM_Null ); if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ int rc; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); @@ -1496,7 +1503,12 @@ static int valueFromExpr( }else{ sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } - if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ) pVal->flags &= ~MEM_Str; + assert( (pVal->flags & MEM_IntReal)==0 ); + if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){ + testcase( pVal->flags & MEM_Int ); + testcase( pVal->flags & MEM_Real ); + pVal->flags &= ~MEM_Str; + } if( enc!=SQLITE_UTF8 ){ rc = sqlite3VdbeChangeEncoding(pVal, enc); } From bc8b231098ae2cbc7528370ab722579f5d3b23fc Mon Sep 17 00:00:00 2001 From: mistachkin Date: Sat, 4 May 2019 03:56:47 +0000 Subject: [PATCH 080/132] Fix harmless compiler warning seen with MSVC. FossilOrigin-Name: 5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/backup.c | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f4b5d2c9bb..e79729866a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\ssqlite3_value\sor\sMem\sobject,\smake\sthe\sMEM_IntReal\stype\scompletely\nindependent\sfrom\sMEM_Int\sand\sMEM_Real.\sThis\shelps\savoid\sproblems\swhen\ninserting\snon-float\svalues\sinto\sa\s"REAL"\scolumn. -D 2019-05-04T01:41:18.778 +C Fix\sharmless\scompiler\swarning\sseen\swith\sMSVC. +D 2019-05-04T03:56:47.610 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -457,7 +457,7 @@ F src/alter.c 85b41586b2527c8288b249fb0beb96f25860e5b2bf94c02f788b3d0f686354ee F src/analyze.c 58db66344a5c58dcabb57f26696f6f2993956c830446da40b444051d2fdaf644 F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df -F src/backup.c 78d3cecfbe28230a3a9a1793e2ead609f469be43e8f486ca996006be551857ab +F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e048f240d9562ef0c6b87e9d8dfa31a08c262d6c8d52c1ac0d6ca340ed8188e0 @@ -1823,8 +1823,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 3a16ddf91f0c9c516a7fc2a9d4a4f69a8326f9b8ea66421e9ef1a2d663687b70 8b8ef445ccccc148af2cda5975986af0d134352fe16283f65d0f8a91c9ffa932 -R 5ebe49882e1d0bab8f5a82c53795cea5 -T +closed 8b8ef445ccccc148af2cda5975986af0d134352fe16283f65d0f8a91c9ffa932 -U drh -Z b24c2d1d6f04cff04fe0a08f3591f34a +P 5a8a23ee5f60a31dbd167a0966d1ab3d0f1c07df2251906cb73f23d1f5466b46 +R 29fe64c5387c71445cd8a73a2e3fad84 +U mistachkin +Z 07cacb21f6144af7a617e9e62f40ea51 diff --git a/manifest.uuid b/manifest.uuid index d8c4094625..1418d3575c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a8a23ee5f60a31dbd167a0966d1ab3d0f1c07df2251906cb73f23d1f5466b46 \ No newline at end of file +5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 \ No newline at end of file diff --git a/src/backup.c b/src/backup.c index 4200940b24..2090b49782 100644 --- a/src/backup.c +++ b/src/backup.c @@ -274,7 +274,7 @@ static int backupOnePage( if( nSrcReserve!=nDestReserve ){ u32 newPgsz = nSrcPgsz; rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); - if( rc==SQLITE_OK && newPgsz!=nSrcPgsz ) rc = SQLITE_READONLY; + if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY; } #endif From 664d6d139eb0ed6ec51aef76db4e22e7f41bc31c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 4 May 2019 17:32:07 +0000 Subject: [PATCH 081/132] Fix the NOT NULL logic in the theorem prover that determines when a partial index can be used. Ticket [5c6955204c392ae763a95]. FossilOrigin-Name: c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 6 +++++- test/index6.test | 13 +++++++++++++ test/index7.test | 2 +- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e79729866a..427d778b07 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarning\sseen\swith\sMSVC. -D 2019-05-04T03:56:47.610 +C Fix\sthe\sNOT\sNULL\slogic\sin\sthe\stheorem\sprover\sthat\sdetermines\swhen\sa\spartial\nindex\scan\sbe\sused.\s\sTicket\s[5c6955204c392ae763a95]. +D 2019-05-04T17:32:07.463 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -471,7 +471,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c f65db06a0fcff760cadfb79d579a41e3eb7eff38848d5d6359137822f4fa2ec9 +F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c ac05ea6b47b407586ad2c0878c4c81c3acb08b67ecf86648830f91f40325ae37 @@ -1036,8 +1036,8 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 6b3e6cd4bef343ed4541e74c55936ed112962a6552c085242612b598e12910a4 -F test/index7.test 72b59b8ddc5c13f4962886b4011eb9975014317d17ef36c6297921362fb7dd98 +F test/index6.test 448fa05f5d78f5feee4832fe4017dede4ccbc660601fb7e84d02329389cb638c +F test/index7.test be02a0b4e53ac4ad7db4995fe02b428597a2e104c4f574b0d4b2f6b082e96b28 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e @@ -1823,7 +1823,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 5a8a23ee5f60a31dbd167a0966d1ab3d0f1c07df2251906cb73f23d1f5466b46 -R 29fe64c5387c71445cd8a73a2e3fad84 -U mistachkin -Z 07cacb21f6144af7a617e9e62f40ea51 +P 5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 +R 2a4f7414ec472ef9ce3b0f33b024a5f6 +U drh +Z dbe61bccc5333ce6e53e70d9eca235ed diff --git a/manifest.uuid b/manifest.uuid index 1418d3575c..d5f918aef2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 \ No newline at end of file +c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ca63eb66c0..940abc1ae0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4943,7 +4943,11 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ ){ return 1; } - if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){ + if( pE2->op==TK_NOTNULL + && pE1->op!=TK_ISNULL + && pE1->op!=TK_IS + && pE1->op!=TK_OR + ){ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); testcase( pX!=pE1->pLeft ); if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1; diff --git a/test/index6.test b/test/index6.test index 29b73f72d4..bb3f629cc2 100644 --- a/test/index6.test +++ b/test/index6.test @@ -410,4 +410,17 @@ do_execsql_test index6-12.1 { do_execsql_test index6-12.2 { SELECT x FROM t2 WHERE x IN (SELECT a FROM t1) ORDER BY +x; } {1 2} + +# 2019-05-04 +# Ticket https://www.sqlite.org/src/tktview/5c6955204c392ae763a95 +# Theorem prover error +# +do_execsql_test index6-13.1 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0); + CREATE INDEX index_0 ON t0(c0) WHERE c0 NOT NULL; + INSERT INTO t0(c0) VALUES (NULL); + SELECT * FROM t0 WHERE c0 OR 1; +} {{}} + finish_test diff --git a/test/index7.test b/test/index7.test index aa0cf8c1f7..bd529dfbcd 100644 --- a/test/index7.test +++ b/test/index7.test @@ -186,7 +186,7 @@ do_test index7-1.15 { } } {t1 {15 1} t1a {10 1} t1b {8 1} t1c {15 1} ok} -# Queries use partial indices as appropriate times. +# Queries use partial indices at appropriate times. # do_test index7-2.1 { execsql { From c24585570269bd4712ec13e747aa7f26739dd792 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 4 May 2019 20:04:42 +0000 Subject: [PATCH 082/132] Optimize some cases of restarting an RBU vacuum. FossilOrigin-Name: cdc09867ed6522026ae7bfac1f59cd79b60fba6d07d49b99b030a501a7059ee4 --- ext/rbu/rbu_common.tcl | 8 +-- ext/rbu/rbupartial.test | 4 ++ ext/rbu/sqlite3rbu.c | 131 +++++++++++++++++++++++++++++++++++++--- manifest | 21 ++++--- manifest.uuid | 2 +- 5 files changed, 142 insertions(+), 24 deletions(-) diff --git a/ext/rbu/rbu_common.tcl b/ext/rbu/rbu_common.tcl index b5e63aafe5..c4e98784a4 100644 --- a/ext/rbu/rbu_common.tcl +++ b/ext/rbu/rbu_common.tcl @@ -89,16 +89,16 @@ proc step_rbu_legacy {target rbu} { proc do_rbu_vacuum_test {tn step {statedb state.db}} { forcedelete $statedb if {$statedb=="" && $step==1} breakpoint - uplevel [list do_test $tn.1 [string map [list %state% $statedb] { - if {$step==0} { sqlite3rbu_vacuum rbu test.db {%state%}} + uplevel [list do_test $tn.1 [string map [list %state% $statedb %step% $step] { + if {%step%==0} { sqlite3rbu_vacuum rbu test.db {%state%}} while 1 { - if {$step==1} { sqlite3rbu_vacuum rbu test.db {%state%}} + if {%step%==1} { sqlite3rbu_vacuum rbu test.db {%state%}} set state [rbu state] check_prestep_state test.db $state set rc [rbu step] check_poststep_state $rc test.db $state if {$rc!="SQLITE_OK"} break - if {$step==1} { rbu close } + if {%step%==1} { rbu close } } rbu close }] {SQLITE_DONE}] diff --git a/ext/rbu/rbupartial.test b/ext/rbu/rbupartial.test index 3cb076f22e..9b0dce6109 100644 --- a/ext/rbu/rbupartial.test +++ b/ext/rbu/rbupartial.test @@ -80,6 +80,10 @@ foreach {tn without_rowid a b c d} { set step 0 do_rbu_vacuum_test $tn.1.5 0 + + do_test $tn.1.6 { + execsql { PRAGMA integrity_check } + } {ok} }] } diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 0160b83188..0551706a67 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -1381,7 +1381,8 @@ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ } pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); - pIter->abTblPk[iOrder] = (iPk!=0); + assert( iPk>=0 ); + pIter->abTblPk[iOrder] = (u8)iPk; pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); iOrder++; } @@ -1416,6 +1417,92 @@ static char *rbuObjIterGetCollist( return zList; } +static char *rbuObjIterGetPkList( + sqlite3rbu *p, /* RBU object */ + RbuObjIter *pIter, /* Object iterator for column names */ + const char *zExtra +){ + int iPk = 1; + char *zRet = 0; + const char *zSep = ""; + while( 1 ){ + int i; + for(i=0; inTblCol; i++){ + if( (int)pIter->abTblPk[i]==iPk ){ + const char *zCol = pIter->azTblCol[i]; + zRet = rbuMPrintf(p, "%z%s\"%w\"%s", zRet, zSep, zCol, zExtra); + zSep = ", "; + } + } + if( i==pIter->nTblCol ) break; + iPk++; + } + return zRet; +} + +static char *rbuVacuumTableStart( + sqlite3rbu *p, + RbuObjIter *pIter, + int bRowid, + const char *zWrite +){ + sqlite3_stmt *pMax = 0; + char *zRet = 0; + if( bRowid ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0); + zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax); + } + rbuFinalize(p, pMax); + }else{ + char *zOrder = 0; + char *zSelect = 0; + char *zList = 0; + int iPk = 1; + const char *zSep = ""; + const char *zSep2 = ""; + while( 1 ){ + int i; + for(i=0; inTblCol; i++){ + if( (int)pIter->abTblPk[i]==iPk ){ + const char *zCol = pIter->azTblCol[i]; + zOrder = rbuMPrintf(p, "%z%s\"%w\" DESC", zOrder, zSep, zCol); + zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, zCol); + zSelect = rbuMPrintf(p, "%z%squote(\"%w\")", zSelect, zSep2, zCol); + zSep = ", "; + zSep2 = "||','||"; + } + } + if( i==pIter->nTblCol ) break; + iPk++; + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, + sqlite3_mprintf( + "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", + zSelect, zWrite, pIter->zTbl, zOrder + ) + ); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + const char *zVal = (const char*)sqlite3_column_text(pMax, 0); + zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal); + } + rbuFinalize(p, pMax); + } + + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zList); + } + return zRet; +} + /* ** This function is used to create a SELECT list (the list of SQL ** expressions that follows a SELECT keyword) for a SELECT statement @@ -2220,18 +2307,42 @@ static int rbuObjIterPrepareAll( /* Create the SELECT statement to read keys from data_xxx */ if( p->rc==SQLITE_OK ){ const char *zRbuRowid = ""; + char *zStart = 0; + char *zOrder = 0; if( bRbuRowid ){ zRbuRowid = rbuIsVacuum(p) ? ",_rowid_ " : ",rbu_rowid"; } - p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, - sqlite3_mprintf( - "SELECT %s,%s rbu_control%s FROM '%q'%s", - zCollist, - (rbuIsVacuum(p) ? "0 AS " : ""), - zRbuRowid, - pIter->zDataTbl, zLimit - ) - ); + + if( rbuIsVacuum(p) ){ + if( nOffset ){ + zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + if( bRbuRowid ){ + zOrder = rbuMPrintf(p, "_rowid_"); + }else{ + zOrder = rbuObjIterGetPkList(p, pIter, ""); + } + } + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, + sqlite3_mprintf( + "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s", + zCollist, + (rbuIsVacuum(p) ? "0 AS " : ""), + zRbuRowid, + pIter->zDataTbl, (zStart ? zStart : ""), + (zOrder ? "ORDER BY" : ""), zOrder, + zLimit + ) + ); + } + sqlite3_free(zStart); + sqlite3_free(zOrder); } sqlite3_free(zWhere); diff --git a/manifest b/manifest index 427d778b07..9b38b304da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sNOT\sNULL\slogic\sin\sthe\stheorem\sprover\sthat\sdetermines\swhen\sa\spartial\nindex\scan\sbe\sused.\s\sTicket\s[5c6955204c392ae763a95]. -D 2019-05-04T17:32:07.463 +C Optimize\ssome\scases\sof\srestarting\san\sRBU\svacuum. +D 2019-05-04T20:04:42.728 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -338,7 +338,7 @@ F ext/rbu/rbu9.test 0e4d985e25620d61920597e8ea69c871c9e8c1f5a0be2ae9fa70bb641d74 F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4f5b3 F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b -F ext/rbu/rbu_common.tcl 4b3d033b3e3844292ae3a1aefc0e524e64b0db5a0e4310657919e4504ac3073f +F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9 F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197 F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4 F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41 @@ -350,7 +350,7 @@ F ext/rbu/rbufault3.test e0052ccba428ffdd2bb989d3ae84716f058ec5ab5f7196c64ba407b F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9 -F ext/rbu/rbupartial.test 73baf12a5941fe6891a829106a6f2e0a973f89aa49bd8659b12f547beb29b482 +F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4 F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9 F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1 F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926 @@ -359,7 +359,7 @@ F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc -F ext/rbu/sqlite3rbu.c f222350c33f063cbc754001cd4e9683164c6cb06be76ae43f15b396ec6fc1993 +F ext/rbu/sqlite3rbu.c 03d4acabf6a51e0714eb4119379e06464f0158ca1d6a0ebd73769b82e7477a11 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1823,7 +1823,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 5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 -R 2a4f7414ec472ef9ce3b0f33b024a5f6 -U drh -Z dbe61bccc5333ce6e53e70d9eca235ed +P c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 +R 837402c2e896349b349ad51f4a993cdf +T *branch * rbu-opt +T *sym-rbu-opt * +T -sym-trunk * +U dan +Z 5640124653d86c97ac59112e02d029e7 diff --git a/manifest.uuid b/manifest.uuid index d5f918aef2..ebf5ce1b08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 \ No newline at end of file +cdc09867ed6522026ae7bfac1f59cd79b60fba6d07d49b99b030a501a7059ee4 \ No newline at end of file From f9b0c45161346f64478167a599f0bbcec7801a4d Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 6 May 2019 16:15:28 +0000 Subject: [PATCH 083/132] Fix a problem with renaming an INTEGER PRIMARY KEY column of a WITHOUT ROWID table using ALTER TABLE. FossilOrigin-Name: 91f701d39852ef1ddb29d1527d1520867c5efea110333315c55d8b08084384e7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 5 ++++- test/altertab.test | 25 +++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 427d778b07..2be5afb694 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sNOT\sNULL\slogic\sin\sthe\stheorem\sprover\sthat\sdetermines\swhen\sa\spartial\nindex\scan\sbe\sused.\s\sTicket\s[5c6955204c392ae763a95]. -D 2019-05-04T17:32:07.463 +C Fix\sa\sproblem\swith\srenaming\san\sINTEGER\sPRIMARY\sKEY\scolumn\sof\sa\sWITHOUT\sROWID\stable\susing\sALTER\sTABLE. +D 2019-05-06T16:15:28.529 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -463,7 +463,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c e048f240d9562ef0c6b87e9d8dfa31a08c262d6c8d52c1ac0d6ca340ed8188e0 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 2d9ddfeaf8e1dafc7e1fcc8a84e7a8b455199dac3b69037fc73af6279aa8447b +F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -627,7 +627,7 @@ F test/altercol.test 54374d2ba18af25bb24e23acf18a60270d4ec120b7ec0558078b59d5aa1 F test/alterlegacy.test 82022721ce0de29cedc9a7af63bc9fcc078b0ee000f8283b4b6ea9c3eab2f44b F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b -F test/altertab.test 372df7d8f09e1ee22d23551677cedff3b048b0059c1f1b9a01a6401b94a2367c +F test/altertab.test b6901287474841cffbd8f90b098d3bd7d8445868b42caeb01b27034698f7245f F test/altertab2.test 5d423a2d1006085b05cc1b788863d5a860ea2da21c4f892d15e2f2a34c78348a F test/altertab3.test 2433d0cc6cb9cffe087f9138cd36818c7abd5c396804aa6e6dc8c2b80e2cd406 F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f @@ -1823,7 +1823,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 5862b83eb36b93016d37e5b86ebb183d891bb553901facab1e5d83e114a38ec3 -R 2a4f7414ec472ef9ce3b0f33b024a5f6 -U drh -Z dbe61bccc5333ce6e53e70d9eca235ed +P c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 +R 7ba20988fc908649bb79cc600d524699 +U dan +Z c4cd27021c89d31b393f236a10b2a3a7 diff --git a/manifest.uuid b/manifest.uuid index d5f918aef2..bf849f4d39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 \ No newline at end of file +91f701d39852ef1ddb29d1527d1520867c5efea110333315c55d8b08084384e7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8684e1ad69..935f132d6c 100644 --- a/src/build.c +++ b/src/build.c @@ -1859,13 +1859,16 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; + if( IN_RENAME_OBJECT ){ + sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); + } pList->a[0].sortOrder = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); + pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); if( db->mallocFailed || pParse->nErr ) return; pPk = sqlite3PrimaryKeyIndex(pTab); - pTab->iPKey = -1; }else{ pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); diff --git a/test/altertab.test b/test/altertab.test index 91ad66d732..602f75345d 100644 --- a/test/altertab.test +++ b/test/altertab.test @@ -569,4 +569,29 @@ do_execsql_test 17.0 { User {CREATE TABLE "User" (id integer)} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 18.1.0 { + CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)) WITHOUT ROWID; +} +breakpoint +do_execsql_test 18.1.1 { + ALTER TABLE t0 RENAME COLUMN c0 TO c1; +} +do_execsql_test 18.1.2 { + SELECT sql FROM sqlite_master; +} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1)) WITHOUT ROWID}} + +reset_db +do_execsql_test 18.2.0 { + CREATE TABLE t0 (c0 INTEGER, PRIMARY KEY(c0)); +} +do_execsql_test 18.2.1 { + ALTER TABLE t0 RENAME COLUMN c0 TO c1; +} +do_execsql_test 18.2.2 { + SELECT sql FROM sqlite_master; +} {{CREATE TABLE t0 (c1 INTEGER, PRIMARY KEY(c1))}} + finish_test + From 57c45147207fcf1d94a8a3a324ecf4d19922dfa1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 6 May 2019 20:40:23 +0000 Subject: [PATCH 084/132] Optimize further cases of restarting an RBU vacuum. FossilOrigin-Name: 6b3261bfa1d762aa29a57244a30cf5e35655f1fe9c30ee682c186dec29d7a2c2 --- ext/rbu/rbuvacuum4.test | 86 +++++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 117 ++++++++++++++++++++++++++++++++++++++-- manifest | 16 +++--- manifest.uuid | 2 +- 4 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 ext/rbu/rbuvacuum4.test diff --git a/ext/rbu/rbuvacuum4.test b/ext/rbu/rbuvacuum4.test new file mode 100644 index 0000000000..751d9e9250 --- /dev/null +++ b/ext/rbu/rbuvacuum4.test @@ -0,0 +1,86 @@ +# 2019 Jan 3 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the RBU module. More specifically, it +# contains tests to ensure that the sqlite3rbu_vacuum() API works as +# expected. +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set testprefix rbuvacuum4 + +set step 1 + +do_execsql_test 1.0 { + CREATE TABLE t1(a PRIMARY KEY, b, c) WITHOUT ROWID; + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} +do_rbu_vacuum_test 1.1 1 + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b, c)) WITHOUT ROWID; + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} +do_rbu_vacuum_test 2.1 1 +do_execsql_test 2.2 { + SELECT * FROM t1; +} {1 2 3 4 5 6 7 8 9} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 oN t1(b, c); + INSERT INTO t1 VALUES(1, 2, 3); + INSERT INTO t1 VALUES(4, 5, 6); + INSERT INTO t1 VALUES(7, 8, 9); +} + +do_rbu_vacuum_test 3.1 1 + +do_execsql_test 3.2 { + SELECT * FROM t1; +} {1 2 3 4 5 6 7 8 9} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE x1(a, b, c, d, PRIMARY KEY(c, b)) WITHOUT ROWID; + INSERT INTO x1 VALUES(1, 1, 1, 1); + INSERT INTO x1 VALUES(1, 1, 2, 1); + INSERT INTO x1 VALUES(1, 2, 2, 1); + + INSERT INTO x1 VALUES(NULL, 2, 3, NULL); + INSERT INTO x1 VALUES(NULL, 2, 4, NULL); + INSERT INTO x1 VALUES(NULL, 2, 5, NULL); + + CREATE INDEX x1ad ON x1(d, a); +} + +do_rbu_vacuum_test 4.1.1 1 + +do_execsql_test 4.2 { + SELECT count(*) fROM x1 +} 6 + +do_rbu_vacuum_test 4.1.2 0 + +finish_test + + diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 0551706a67..37acecff00 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -1476,6 +1476,7 @@ static char *rbuVacuumTableStart( zSelect = rbuMPrintf(p, "%z%squote(\"%w\")", zSelect, zSep2, zCol); zSep = ", "; zSep2 = "||','||"; + break; } } if( i==pIter->nTblCol ) break; @@ -1503,6 +1504,100 @@ static char *rbuVacuumTableStart( return zRet; } +char *rbuVacuumIndexStart( + sqlite3rbu *p, + RbuObjIter *pIter +){ + char *zOrder = 0; + char *zLhs = 0; + char *zSelect = 0; + char *zVector = 0; + char *zRet = 0; + int bFailed = 0; + + if( p->rc==SQLITE_OK ){ + const char *zSep = ""; + int iCol = 0; + sqlite3_stmt *pXInfo = 0; + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol; + if( sqlite3_column_int(pXInfo, 3) ){ + bFailed = 1; + break; + } + + if( iCid<0 ){ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else{ + zCol = "_rowid_"; + } + }else{ + zCol = pIter->azTblCol[iCid]; + } + + zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q", + zLhs, zSep, zCol, zCollate + ); + zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC", + zOrder, zSep, iCol, zCol, zCollate + ); + zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")", + zSelect, zSep, iCol, zCol + ); + zSep = ", "; + iCol++; + } + rbuFinalize(p, pXInfo); + } + if( bFailed ) goto index_start_out; + + if( p->rc==SQLITE_OK ){ + int iCol; + sqlite3_stmt *pSel = 0; + + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, + sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", + zSelect, pIter->zTbl, zOrder + ) + ); + } + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){ + const char *zSep = ""; + for(iCol=0; iColnCol; iCol++){ + const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); + if( zQuoted[0]=='N' ){ + bFailed = 1; + break; + } + zVector = rbuMPrintf(p, "%z%s%s", zVector, zSep, zQuoted); + zSep = ", "; + } + + if( !bFailed ){ + zRet = rbuMPrintf(p, "(%s) > (%s)", zLhs, zVector); + } + } + rbuFinalize(p, pSel); + } + + index_start_out: + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zVector); + sqlite3_free(zLhs); + return zRet; +} + /* ** This function is used to create a SELECT list (the list of SQL ** expressions that follows a SELECT keyword) for a SELECT statement @@ -2179,12 +2274,24 @@ static int rbuObjIterPrepareAll( if( p->rc==SQLITE_OK ){ char *zSql; if( rbuIsVacuum(p) ){ + const char *zStart = 0; + if( nOffset ){ + zStart = rbuVacuumIndexStart(p, pIter); + if( zStart ){ + sqlite3_free(zLimit); + zLimit = 0; + } + } + zSql = sqlite3_mprintf( - "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s", + "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s", zCollist, pIter->zDataTbl, - zPart, zCollist, zLimit + zPart, + (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart, + zCollist, zLimit ); + sqlite3_free(zStart); }else if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ @@ -2207,7 +2314,11 @@ static int rbuObjIterPrepareAll( zCollist, zLimit ); } - p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql); + if( p->rc==SQLITE_OK ){ + p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql); + }else{ + sqlite3_free(zSql); + } } sqlite3_free(zImposterCols); diff --git a/manifest b/manifest index 9b38b304da..44ed7b69ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\ssome\scases\sof\srestarting\san\sRBU\svacuum. -D 2019-05-04T20:04:42.728 +C Optimize\sfurther\scases\sof\srestarting\san\sRBU\svacuum. +D 2019-05-06T20:40:23.801 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -359,7 +359,8 @@ F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc -F ext/rbu/sqlite3rbu.c 03d4acabf6a51e0714eb4119379e06464f0158ca1d6a0ebd73769b82e7477a11 +F ext/rbu/rbuvacuum4.test fcae689344a28acf1013c9e2563d334f15ef741f5a16396945701ab90799e877 +F ext/rbu/sqlite3rbu.c e2669fb2a716615f38628a0477ecd665a040970501cba2511e9dffe066e2c9c8 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1823,10 +1824,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 c2e439bccc40825e211bfa9a88e6a251ff066ca7453d4e7cb5eab56ce7332635 -R 837402c2e896349b349ad51f4a993cdf -T *branch * rbu-opt -T *sym-rbu-opt * -T -sym-trunk * +P cdc09867ed6522026ae7bfac1f59cd79b60fba6d07d49b99b030a501a7059ee4 +R aeb9fedb3c4f55c16b474638fcef63d3 U dan -Z 5640124653d86c97ac59112e02d029e7 +Z ccdab55de99d2c516e9414504dca1a30 diff --git a/manifest.uuid b/manifest.uuid index ebf5ce1b08..049d28edef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cdc09867ed6522026ae7bfac1f59cd79b60fba6d07d49b99b030a501a7059ee4 \ No newline at end of file +6b3261bfa1d762aa29a57244a30cf5e35655f1fe9c30ee682c186dec29d7a2c2 \ No newline at end of file From 126537e1dccc5f9006679ebcde202de36a8df636 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 May 2019 16:28:50 +0000 Subject: [PATCH 085/132] Remove some redundant code from sqlite3rbu.c. Add test cases for RBU vacuum. FossilOrigin-Name: 7b051698d8a763d9db190fd662931266d24a4982f34f100a28641934c222e37b --- ext/rbu/rbuvacuum4.test | 23 ++++++++- ext/rbu/sqlite3rbu.c | 100 ++++++++++++++++++++++++++-------------- manifest | 14 +++--- manifest.uuid | 2 +- 4 files changed, 96 insertions(+), 43 deletions(-) diff --git a/ext/rbu/rbuvacuum4.test b/ext/rbu/rbuvacuum4.test index 751d9e9250..9984c9120a 100644 --- a/ext/rbu/rbuvacuum4.test +++ b/ext/rbu/rbuvacuum4.test @@ -71,6 +71,7 @@ do_execsql_test 4.0 { INSERT INTO x1 VALUES(NULL, 2, 5, NULL); CREATE INDEX x1ad ON x1(d, a); + CREATE INDEX x1null ON x1(d, a) WHERE d>15; } do_rbu_vacuum_test 4.1.1 1 @@ -81,6 +82,26 @@ do_execsql_test 4.2 { do_rbu_vacuum_test 4.1.2 0 +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE TABLE "a b c"(a, "b b" PRIMARY KEY, "c c"); + CREATE INDEX abc1 ON "a b c"(a, "c c"); + + INSERT INTO "a b c" VALUES(NULL, 'a', NULL); + INSERT INTO "a b c" VALUES(NULL, 'b', NULL); + INSERT INTO "a b c" VALUES(NULL, 'c', NULL); + + INSERT INTO "a b c" VALUES(1, 2, 3); + INSERT INTO "a b c" VALUES(3, 9, 1); + INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc'); + + CREATE TABLE x(a); + INSERT INTO x VALUES('a'), ('b'), ('d'); + CREATE UNIQUE INDEX y ON x(a); +} + +do_rbu_vacuum_test 5.1 1 + finish_test - diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 37acecff00..0ed2837ca7 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -930,7 +930,8 @@ static void rbuTargetNameFunc( zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn ){ if( rbuIsVacuum(p) ){ - if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ + assert( argc==2 ); + if( 0==sqlite3_value_int(argv[1]) ){ sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); } }else{ @@ -1417,10 +1418,18 @@ static char *rbuObjIterGetCollist( return zList; } +/* +** Return a comma separated list of the quoted PRIMARY KEY column names, +** in order, for the current table. Before each column name, add the text +** zPre. After each column name, add the zPost text. Use zSeparator as +** the separator text (usually ", "). +*/ static char *rbuObjIterGetPkList( sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter, /* Object iterator for column names */ - const char *zExtra + const char *zPre, /* Before each quoted column name */ + const char *zSeparator, /* Separator to use between columns */ + const char *zPost /* After each quoted column name */ ){ int iPk = 1; char *zRet = 0; @@ -1430,8 +1439,9 @@ static char *rbuObjIterGetPkList( for(i=0; inTblCol; i++){ if( (int)pIter->abTblPk[i]==iPk ){ const char *zCol = pIter->azTblCol[i]; - zRet = rbuMPrintf(p, "%z%s\"%w\"%s", zRet, zSep, zCol, zExtra); - zSep = ", "; + zRet = rbuMPrintf(p, "%z%s%s\"%w\"%s", zRet, zSep, zPre, zCol, zPost); + zSep = zSeparator; + break; } } if( i==pIter->nTblCol ) break; @@ -1440,11 +1450,30 @@ static char *rbuObjIterGetPkList( return zRet; } +/* +** This function is called as part of restarting an RBU vacuum within +** stage 1 of the process (while the *-oal file is being built) while +** updating a table (not an index). The table may be a rowid table or +** a WITHOUT ROWID table. It queries the target database to find the +** largest key that has already been written to the target table and +** constructs a WHERE clause that can be used to extract the remaining +** rows from the source table. For a rowid table, the WHERE clause +** is of the form: +** +** "WHERE _rowid_ > ?" +** +** and for WITHOUT ROWID tables: +** +** "WHERE (key1, key2) > (?, ?)" +** +** Instead of "?" placeholders, the actual WHERE clauses created by +** this function contain literal SQL values. +*/ static char *rbuVacuumTableStart( - sqlite3rbu *p, - RbuObjIter *pIter, - int bRowid, - const char *zWrite + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter, /* RBU iterator object */ + int bRowid, /* True for a rowid table */ + const char *zWrite /* Target table name prefix */ ){ sqlite3_stmt *pMax = 0; char *zRet = 0; @@ -1460,28 +1489,9 @@ static char *rbuVacuumTableStart( } rbuFinalize(p, pMax); }else{ - char *zOrder = 0; - char *zSelect = 0; - char *zList = 0; - int iPk = 1; - const char *zSep = ""; - const char *zSep2 = ""; - while( 1 ){ - int i; - for(i=0; inTblCol; i++){ - if( (int)pIter->abTblPk[i]==iPk ){ - const char *zCol = pIter->azTblCol[i]; - zOrder = rbuMPrintf(p, "%z%s\"%w\" DESC", zOrder, zSep, zCol); - zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, zCol); - zSelect = rbuMPrintf(p, "%z%squote(\"%w\")", zSelect, zSep2, zCol); - zSep = ", "; - zSep2 = "||','||"; - break; - } - } - if( i==pIter->nTblCol ) break; - iPk++; - } + char *zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", " DESC"); + char *zSelect = rbuObjIterGetPkList(p, pIter, "quote(", "||','||", ")"); + char *zList = rbuObjIterGetPkList(p, pIter, "", ", ", ""); if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, @@ -1504,9 +1514,31 @@ static char *rbuVacuumTableStart( return zRet; } +/* +** This function is called as part of restating an RBU vacuum when the +** current operation is writing content to an index. If possible, it +** queries the target index b-tree for the largest key already written to +** it, then composes and returns an expression that can be used in a WHERE +** clause to select the remaining required rows from the source table. +** It is only possible to return such an expression if: +** +** * The index contains no DESC columns, and +** * The last key written to the index before the operation was +** suspended does not contain any NULL values. +** +** The expression is of the form: +** +** (index-field1, index-field2, ...) > (?, ?, ...) +** +** except that the "?" placeholders are replaced with literal values. +** +** If the expression cannot be created, NULL is returned. In this case, +** the caller has to use an OFFSET clause to extract only the required +** rows from the sourct table, just as it does for an RBU update operation. +*/ char *rbuVacuumIndexStart( - sqlite3rbu *p, - RbuObjIter *pIter + sqlite3rbu *p, /* RBU handle */ + RbuObjIter *pIter /* RBU iterator object */ ){ char *zOrder = 0; char *zLhs = 0; @@ -2274,7 +2306,7 @@ static int rbuObjIterPrepareAll( if( p->rc==SQLITE_OK ){ char *zSql; if( rbuIsVacuum(p) ){ - const char *zStart = 0; + char *zStart = 0; if( nOffset ){ zStart = rbuVacuumIndexStart(p, pIter); if( zStart ){ @@ -2435,7 +2467,7 @@ static int rbuObjIterPrepareAll( if( bRbuRowid ){ zOrder = rbuMPrintf(p, "_rowid_"); }else{ - zOrder = rbuObjIterGetPkList(p, pIter, ""); + zOrder = rbuObjIterGetPkList(p, pIter, "", ", ", ""); } } diff --git a/manifest b/manifest index 44ed7b69ca..69f1d68b6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\sfurther\scases\sof\srestarting\san\sRBU\svacuum. -D 2019-05-06T20:40:23.801 +C Remove\ssome\sredundant\scode\sfrom\ssqlite3rbu.c.\sAdd\stest\scases\sfor\sRBU\svacuum. +D 2019-05-07T16:28:50.534 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -359,8 +359,8 @@ F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc -F ext/rbu/rbuvacuum4.test fcae689344a28acf1013c9e2563d334f15ef741f5a16396945701ab90799e877 -F ext/rbu/sqlite3rbu.c e2669fb2a716615f38628a0477ecd665a040970501cba2511e9dffe066e2c9c8 +F ext/rbu/rbuvacuum4.test 08abd9e18d8aee5bb812de0d6a928cc8bbacae58ecb1f150637e80f4c93c8afa +F ext/rbu/sqlite3rbu.c ec93d28c5cef16ccef7ed76c2b6c410e8eb078c73705b6e7b683f88f722228f2 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1824,7 +1824,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 cdc09867ed6522026ae7bfac1f59cd79b60fba6d07d49b99b030a501a7059ee4 -R aeb9fedb3c4f55c16b474638fcef63d3 +P 6b3261bfa1d762aa29a57244a30cf5e35655f1fe9c30ee682c186dec29d7a2c2 +R 4a715a784b4b470a8ebf2ddbf655a0cc U dan -Z ccdab55de99d2c516e9414504dca1a30 +Z c393b32565e9671e4034603b54f16352 diff --git a/manifest.uuid b/manifest.uuid index 049d28edef..366634c67e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6b3261bfa1d762aa29a57244a30cf5e35655f1fe9c30ee682c186dec29d7a2c2 \ No newline at end of file +7b051698d8a763d9db190fd662931266d24a4982f34f100a28641934c222e37b \ No newline at end of file From dd2d9a3d5a2648c3b0d2053db9e9aa60cc2be3e7 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 May 2019 17:47:43 +0000 Subject: [PATCH 086/132] Strive to prevent harmless compiler warnings in GCC 4.8.5. FossilOrigin-Name: 8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/btree.c | 1 + src/wherecode.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 1a7c97fbfa..2177c1210d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimize\sthe\srestarting\sof\san\sRBU\svacuum. -D 2019-05-07T16:37:37.162 +C Strive\sto\sprevent\sharmless\scompiler\swarnings\sin\sGCC\s4.8.5. +D 2019-05-07T17:47:43.636 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -461,7 +461,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c e048f240d9562ef0c6b87e9d8dfa31a08c262d6c8d52c1ac0d6ca340ed8188e0 +F src/btree.c 096a98aae7b57a0f6d119076f45e281e8b337100a304857b85986a59c6d606d1 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -608,7 +608,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 -F src/wherecode.c 0e76672930bea322eb3606d891a4744be55c09bcd3a995bfd501af62a46e0625 +F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a F src/whereexpr.c 7fedf990999722dafda5ab8040feac93937a6f95f4671d8d629f2baf014b4b80 F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1824,8 +1824,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 91f701d39852ef1ddb29d1527d1520867c5efea110333315c55d8b08084384e7 7b051698d8a763d9db190fd662931266d24a4982f34f100a28641934c222e37b -R 8e0011462278f668f3cc12d5a8c4e1e9 -T +closed 7b051698d8a763d9db190fd662931266d24a4982f34f100a28641934c222e37b -U dan -Z a1edb1bdf5023ec77a1208563fa197ca +P 82062351a62f4ccc438a2b47a22ee581bd030dec952fecd610f360a25002a5ea +R 4f39e2e7a0d63e22242e3f88eda624cc +U drh +Z 38298ab91e1e4b87a848f20cfed8bc7a diff --git a/manifest.uuid b/manifest.uuid index ad4d935e1a..974d456905 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82062351a62f4ccc438a2b47a22ee581bd030dec952fecd610f360a25002a5ea \ No newline at end of file +8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index e98cb7b05d..d0be549900 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7989,6 +7989,7 @@ static int balance_nonroot( while( i==cntOldNext ){ iOld++; assert( iOld=0 && iOldnCell + pOld->nOverflow + !leafData; } diff --git a/src/wherecode.c b/src/wherecode.c index 6aadb24142..a625448459 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2115,7 +2115,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeGoto(v, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); - if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab); + if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ From a7c3b93fa634109dafd4170373d838faf6008d8a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 7 May 2019 19:13:42 +0000 Subject: [PATCH 087/132] On an INSERT or UPDATE, generate the new table record prior to running foreign key checks, in case the foreign key checks changes datatypes on the registers holding column values. Proposed fix for ticket [e63cbcfd3378afe6980d626]. FossilOrigin-Name: 3f1c8051648a341db4dffad66d3b1f9980d8a2b314cb0ce879cb2a10d1779b84 --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/insert.c | 34 +++++++++++++++++++++------------- src/update.c | 7 ++++--- 4 files changed, 36 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 2177c1210d..243d45027f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strive\sto\sprevent\sharmless\scompiler\swarnings\sin\sGCC\s4.8.5. -D 2019-05-07T17:47:43.636 +C On\san\sINSERT\sor\sUPDATE,\sgenerate\sthe\snew\stable\srecord\sprior\sto\srunning\nforeign\skey\schecks,\sin\scase\sthe\sforeign\skey\schecks\schanges\sdatatypes\son\nthe\sregisters\sholding\scolumn\svalues.\s\sProposed\sfix\sfor\sticket\n[e63cbcfd3378afe6980d626]. +D 2019-05-07T19:13:42.131 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -481,7 +481,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c fc3cf5c371f9a400144e8c2f148ab29cd3f67f7da7eaf47e6a6959f8255fd92c +F src/insert.c 4ffc3aa5d2aed178b501533428a76e150907e92a1e4bf7af4ffbcb0d77e99823 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c F src/main.c 3c3925b0bcb4c45687fd52f54c79e98e379252e1d3393f8b7dcccfa26181b661 @@ -587,7 +587,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c 56724725c62a0d0f408f7c257475dc33309198afee36a1d18be1bc268b09055e F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 -F src/update.c 0b973357d88092140531e07ff641139c26fb4380b0b9f5ed98c5f7691b4604d1 +F src/update.c fb29c2eb1f52a5009fd0e00f5041fb6ae14a7f9a5048da220e45e804c61b3559 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 @@ -1824,7 +1824,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 82062351a62f4ccc438a2b47a22ee581bd030dec952fecd610f360a25002a5ea -R 4f39e2e7a0d63e22242e3f88eda624cc +P 8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa +R ac9c1b91c829d87b45248e874c9bfe36 +T *branch * tkt-e63cbcfd +T *sym-tkt-e63cbcfd * +T -sym-trunk * U drh -Z 38298ab91e1e4b87a848f20cfed8bc7a +Z 017803aae35252cbb0229aaaad801bc4 diff --git a/manifest.uuid b/manifest.uuid index 974d456905..3b6ab441bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa \ No newline at end of file +3f1c8051648a341db4dffad66d3b1f9980d8a2b314cb0ce879cb2a10d1779b84 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index ee63eeda56..094b98351e 100644 --- a/src/insert.c +++ b/src/insert.c @@ -814,7 +814,7 @@ void sqlite3Insert( int nIdx; nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); - aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+1)); + aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2)); if( aRegIdx==0 ){ goto insert_cleanup; } @@ -823,6 +823,7 @@ void sqlite3Insert( aRegIdx[i] = ++pParse->nMem; pParse->nMem += pIdx->nColumn; } + aRegIdx[i] = ++pParse->nMem; /* Register to store the table record */ } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ @@ -1226,6 +1227,14 @@ int sqlite3ExprReferencesUpdatedColumn( ** the same as the order of indices on the linked list of indices ** at pTab->pIndex. ** +** (2019-05-07) The generated code also creates a new record for the +** main table, if pTab is a rowid table, and stores that record in the +** register identified by aRegIdx[nIdx] - in other words in the first +** entry of aRegIdx[] past the last index. It is important that the +** record be generated during constraint checks to avoid affinity changes +** to the register content that occur after constraint checks but before +** the new record is inserted. +** ** The caller must have already opened writeable cursors on the main ** table and all applicable indices (that is to say, all indices for which ** aRegIdx[] is not zero). iDataCur is the cursor for the main table when @@ -1845,6 +1854,16 @@ void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, ipkBottom); } + /* Generate the table record */ + if( HasRowid(pTab) ){ + int regRec = aRegIdx[ix]; + sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nCol, regRec); + sqlite3SetMakeRecordP5(v, pTab); + if( !bAffinityDone ){ + sqlite3TableAffinity(v, pTab, 0); + } + } + *pbMayReplace = seenReplace; VdbeModuleComment((v, "END: GenCnstCks(%d)", seenReplace)); } @@ -1894,10 +1913,7 @@ void sqlite3CompleteInsertion( Vdbe *v; /* Prepared statements under construction */ Index *pIdx; /* An index being inserted or updated */ u8 pik_flags; /* flag values passed to the btree insert */ - int regData; /* Content registers (after the rowid) */ - int regRec; /* Register holding assembled record for the table */ int i; /* Loop counter */ - u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ assert( update_flags==0 || update_flags==OPFLAG_ISUPDATE @@ -1909,7 +1925,6 @@ void sqlite3CompleteInsertion( assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( aRegIdx[i]==0 ) continue; - bAffinityDone = 1; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); @@ -1937,13 +1952,6 @@ void sqlite3CompleteInsertion( sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; - regData = regNewData + 1; - regRec = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); - sqlite3SetMakeRecordP5(v, pTab); - if( !bAffinityDone ){ - sqlite3TableAffinity(v, pTab, 0); - } if( pParse->nested ){ pik_flags = 0; }else{ @@ -1956,7 +1964,7 @@ void sqlite3CompleteInsertion( if( useSeekResult ){ pik_flags |= OPFLAG_USESEEKRESULT; } - sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, regRec, regNewData); + sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData); if( !pParse->nested ){ sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } diff --git a/src/update.c b/src/update.c index 132837d44f..8bb9f8466a 100644 --- a/src/update.c +++ b/src/update.c @@ -159,7 +159,7 @@ void sqlite3Update( int iDataCur; /* Cursor for the canonical data btree */ int iIdxCur; /* Cursor for the first index */ sqlite3 *db; /* The database structure */ - int *aRegIdx = 0; /* First register in array assigned to each index */ + int *aRegIdx = 0; /* Registers for to each index and the main table */ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the ** an expression for the i-th column of the table. ** aXRef[i]==-1 if the i-th column is not changed. */ @@ -273,10 +273,10 @@ void sqlite3Update( /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ - aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx) + nIdx+2 ); + aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); if( aXRef==0 ) goto update_cleanup; aRegIdx = aXRef+pTab->nCol; - aToOpen = (u8*)(aRegIdx+nIdx); + aToOpen = (u8*)(aRegIdx+nIdx+1); memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; for(i=0; inCol; i++) aXRef[i] = -1; @@ -378,6 +378,7 @@ void sqlite3Update( if( reg==0 ) aToOpen[j+1] = 0; aRegIdx[j] = reg; } + aRegIdx[j] = ++pParse->nMem; /* Register storing the table record */ if( bReplace ){ /* If REPLACE conflict resolution might be invoked, open cursors on all ** indexes in case they are needed to delete records. */ From 244edd01d32b4081086982d5f3c5a93b7a2b6f18 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 May 2019 19:21:58 +0000 Subject: [PATCH 088/132] Add test cases for the fix on this branch. FossilOrigin-Name: 2e31abe0ae5937a8ce10179e0ae045ee4c5ed8b7e2622ab41243226c6d3f5425 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- test/fkey8.test | 31 +++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 243d45027f..1260899fa6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C On\san\sINSERT\sor\sUPDATE,\sgenerate\sthe\snew\stable\srecord\sprior\sto\srunning\nforeign\skey\schecks,\sin\scase\sthe\sforeign\skey\schecks\schanges\sdatatypes\son\nthe\sregisters\sholding\scolumn\svalues.\s\sProposed\sfix\sfor\sticket\n[e63cbcfd3378afe6980d626]. -D 2019-05-07T19:13:42.131 +C Add\stest\scases\sfor\sthe\sfix\son\sthis\sbranch. +D 2019-05-07T19:21:58.832 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -859,7 +859,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 F test/fkey7.test 24076d43d3449f12f25503909ca4bfb5fc5fefd5af1f930723a496343eb28454 -F test/fkey8.test 863c6d84f0d289fd2c1a1c293abb9803f77efd35211d9012c0986c8f6ccf5d5a +F test/fkey8.test 1d44df25d3b9cba72db4b4324201daf6ae1fc8a85cb68146bd6669a977d8867d F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff F test/format4.test 1f0cac8ff3895e9359ed87e41aaabee982a812eb @@ -1824,10 +1824,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 8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa -R ac9c1b91c829d87b45248e874c9bfe36 -T *branch * tkt-e63cbcfd -T *sym-tkt-e63cbcfd * -T -sym-trunk * -U drh -Z 017803aae35252cbb0229aaaad801bc4 +P 3f1c8051648a341db4dffad66d3b1f9980d8a2b314cb0ce879cb2a10d1779b84 +R 2d97d9191e7764860c32bedf82b06a8b +U dan +Z 37627195381a6f7ef79ed6ec381c9c3a diff --git a/manifest.uuid b/manifest.uuid index 3b6ab441bb..35ac028a5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3f1c8051648a341db4dffad66d3b1f9980d8a2b314cb0ce879cb2a10d1779b84 \ No newline at end of file +2e31abe0ae5937a8ce10179e0ae045ee4c5ed8b7e2622ab41243226c6d3f5425 \ No newline at end of file diff --git a/test/fkey8.test b/test/fkey8.test index f38e835aef..42f997f06f 100644 --- a/test/fkey8.test +++ b/test/fkey8.test @@ -197,5 +197,36 @@ do_execsql_test 4.2 { INSERT OR REPLACE INTO t1 VALUES(20000, 20000); } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + PRAGMA foreign_keys = true; + CREATE TABLE parent( + p TEXT PRIMARY KEY + ); + CREATE TABLE child( + c INTEGER UNIQUE, + FOREIGN KEY(c) REFERENCES parent(p) DEFERRABLE INITIALLY DEFERRED + ); + BEGIN; + INSERT INTO child VALUES(123); + INSERT INTO parent VALUES('123'); + COMMIT; +} +do_execsql_test 5.1 { + PRAGMA integrity_check; +} {ok} + +do_execsql_test 5.2 { + INSERT INTO parent VALUES(1200); + BEGIN; + INSERT INTO child VALUES(456); + UPDATE parent SET p = '456' WHERE p=1200; + COMMIT; +} +do_execsql_test 5.3 { + PRAGMA integrity_check; +} {ok} + finish_test From f116ad8527ccbe57356d5ba95a94a4fa711621e7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 7 May 2019 19:44:11 +0000 Subject: [PATCH 089/132] Do not commit an "OR FAIL" statement that causes foriegn key constraint violations. FossilOrigin-Name: 659c551dcc374a0d349ba9419f692e3363839e11d791a17cc35fa1854a674a51 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 2 +- test/fkey7.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2177c1210d..c28a412851 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strive\sto\sprevent\sharmless\scompiler\swarnings\sin\sGCC\s4.8.5. -D 2019-05-07T17:47:43.636 +C Do\snot\scommit\san\s"OR\sFAIL"\sstatement\sthat\scauses\sforiegn\skey\sconstraint\sviolations. +D 2019-05-07T19:44:11.323 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -596,7 +596,7 @@ F src/vdbe.c 20e6098518581719ffc0ff0f5378d9bf9976fe5e7df029caf2a3d938a7375680 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da -F src/vdbeaux.c 94f5bea5db40f6c26a2db320788745a3852202a2ab4472928247955619027906 +F src/vdbeaux.c f9fb1f71e216850267744fde8a6a0b2d3822235d6f85568af368be4722e8da13 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c b76b42ac9d6a36fc55a0797929fc94cc33e1334eea2792f5ee1eef868ce13320 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 @@ -858,7 +858,7 @@ F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 24dd28eb3d9f1b5a174f47e9899ace5facb08373a4223593c8c631e6cf9f7d5a F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 -F test/fkey7.test 24076d43d3449f12f25503909ca4bfb5fc5fefd5af1f930723a496343eb28454 +F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031 F test/fkey8.test 863c6d84f0d289fd2c1a1c293abb9803f77efd35211d9012c0986c8f6ccf5d5a F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test eb93a2f34137bb87bdab88fcab06c0bd92719aff @@ -1824,7 +1824,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 82062351a62f4ccc438a2b47a22ee581bd030dec952fecd610f360a25002a5ea -R 4f39e2e7a0d63e22242e3f88eda624cc -U drh -Z 38298ab91e1e4b87a848f20cfed8bc7a +P 8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa +R f2edd00aa596a467ac6bf1c6aa5d2bbb +U dan +Z 61f5f496efda33a1a9f7b2adc6f41ef1 diff --git a/manifest.uuid b/manifest.uuid index 974d456905..b98c38f4a0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8b6691f619ed9a56f6aecbd878ebb447c40984f8767508b248494fd9ec68fbaa \ No newline at end of file +659c551dcc374a0d349ba9419f692e3363839e11d791a17cc35fa1854a674a51 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ddeeeecf20..a96f195573 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2896,7 +2896,7 @@ int sqlite3VdbeHalt(Vdbe *p){ } /* Check for immediate foreign key violations. */ - if( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ sqlite3VdbeCheckFk(p, 0); } diff --git a/test/fkey7.test b/test/fkey7.test index e86fc5c57b..77870a7505 100644 --- a/test/fkey7.test +++ b/test/fkey7.test @@ -82,4 +82,40 @@ ifcapable stat4 { } } + +do_execsql_test 4.0 { + PRAGMA foreign_keys = true; + CREATE TABLE parent( + p PRIMARY KEY + ); + CREATE TABLE child( + c UNIQUE REFERENCES parent(p) + ); +} + +do_catchsql_test 4.1 { + INSERT OR FAIL INTO child VALUES(123), (123); +} {1 {FOREIGN KEY constraint failed}} + +do_execsql_test 4.2 { + SELECT * FROM child; +} {} + +do_execsql_test 4.3 { + PRAGMA foreign_key_check; +} {} + +do_catchsql_test 4.4 { + INSERT INTO parent VALUES(123); + INSERT OR FAIL INTO child VALUES(123), (123); +} {1 {UNIQUE constraint failed: child.c}} + +do_execsql_test 4.5 { + SELECT * FROM child; +} {123} + +do_execsql_test 4.6 { + PRAGMA foreign_key_check; +} {} + finish_test From dfcecdfea8e0c4260109a38bb0f5d14b4b8cc9ca Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 00:17:45 +0000 Subject: [PATCH 090/132] Earlier detections of errors in the byte-offset-to-cell-content integer at offset 5 in the header of a btree page. FossilOrigin-Name: a0819086a521fb0ca4ffd12f959b168a89ea2e30a2844bbbd39831b2b9ecf29b --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/btree.c | 8 ++++---- test/fuzzdata7.db | Bin 16793600 -> 16807936 bytes 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 52577a29ed..cbd5fdce9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Generate\sall\srecords\sfor\sINSERT\sor\sUPDATE\sprior\sto\srunning\sforeign\skey\nconstraint\schecks,\ssince\sthe\sFK\schecks\smight\smodify\sthe\sdatatype\sof\sregisters\nused\sto\sgenerate\sthe\srecords.\s\sFix\sfor\sticket\s[e63cbcfd3378afe6980d6]. -D 2019-05-07T20:06:41.906 +C Earlier\sdetections\sof\serrors\sin\sthe\sbyte-offset-to-cell-content\sinteger\sat\s\noffset\s5\sin\sthe\sheader\sof\sa\sbtree\spage. +D 2019-05-08T00:17:45.328 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -461,7 +461,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 096a98aae7b57a0f6d119076f45e281e8b337100a304857b85986a59c6d606d1 +F src/btree.c 3fe1f1b3cd623a0cad788dfbd90ce200c3d522d608ae688fc8ee002d59924414 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -1000,7 +1000,7 @@ F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 -F test/fuzzdata7.db f46c9a5698c1ca75ca6280c7c879a3f46dc82fe4b1ce246827496b806488952d +F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca F test/fuzzdata8.db 1786362da75b8696f804b0b4548b59830e148718bce827548c006031105e7783 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 @@ -1824,8 +1824,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 659c551dcc374a0d349ba9419f692e3363839e11d791a17cc35fa1854a674a51 2e31abe0ae5937a8ce10179e0ae045ee4c5ed8b7e2622ab41243226c6d3f5425 -R fa2fed430d13a58c5e4ca86a2cdaef6a -T +closed 2e31abe0ae5937a8ce10179e0ae045ee4c5ed8b7e2622ab41243226c6d3f5425 +P 3c75605b4652ae88659465d832953ac9d467369f9cb417f73b3d8599ec60b18b +R b0847795ba7312dd769390f52a23c18c U drh -Z 73823319e7fa571b2383dfdc2d83370b +Z 9c745365e239320fd6fda1cfdfad4d1f diff --git a/manifest.uuid b/manifest.uuid index 967645dbf3..67413b6578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3c75605b4652ae88659465d832953ac9d467369f9cb417f73b3d8599ec60b18b \ No newline at end of file +a0819086a521fb0ca4ffd12f959b168a89ea2e30a2844bbbd39831b2b9ecf29b \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d0be549900..42867168ea 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1628,9 +1628,9 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ top = get2byte(&data[hdr+5]); - assert( top<=(int)pPage->pBt->usableSize ); /* Prevent by getAndInitPage() */ + assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ if( gap>top ){ - if( top==0 && pPage->pBt->usableSize==65536 ){ + if( top==0 && ALWAYS(pPage->pBt->usableSize==65536) ){ top = 65536; }else{ return SQLITE_CORRUPT_PAGE(pPage); @@ -1925,7 +1925,7 @@ static int btreeComputeFreeSpace(MemPage *pPage){ ** serves to verify that the offset to the start of the cell-content ** area, according to the page header, lies within the page. */ - if( nFree>usableSize ){ + if( nFree>usableSize || nFreenFree = (u16)(nFree - iCellFirst); @@ -8068,7 +8068,7 @@ static int balance_nonroot( assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); - if( rc!=SQLITE_OK ) goto balance_cleanup; + if( NEVER(rc!=SQLITE_OK) ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } diff --git a/test/fuzzdata7.db b/test/fuzzdata7.db index f24add2b58e4937c0dfa1ae316695999f9d1e4d6..fb111d865fddf4da32fe8faeeb7e3830696846d4 100644 GIT binary patch delta 445001 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

Vv&(H^dBtE=DU;`d8 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 delta 440564 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ⅆ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

#so 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 F{{a&#?$`hT From d2cfbea2a4ce631957554e480e90b711ef681249 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 03:34:53 +0000 Subject: [PATCH 091/132] Remove a NEVER() that was added in the previous check-in because it is in fact reachable. FossilOrigin-Name: 74eba2558a81f9e790d95a12a0c5379d4f80b43c8698ef9d6a31ff8d160a53d8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- test/fuzzdata8.db | Bin 1099776 -> 1102848 bytes 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index cbd5fdce9a..5222bb56e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Earlier\sdetections\sof\serrors\sin\sthe\sbyte-offset-to-cell-content\sinteger\sat\s\noffset\s5\sin\sthe\sheader\sof\sa\sbtree\spage. -D 2019-05-08T00:17:45.328 +C Remove\sa\sNEVER()\sthat\swas\sadded\sin\sthe\sprevious\scheck-in\sbecause\sit\sis\sin\sfact\nreachable. +D 2019-05-08T03:34:53.523 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -461,7 +461,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 3fe1f1b3cd623a0cad788dfbd90ce200c3d522d608ae688fc8ee002d59924414 +F src/btree.c fcfd6b960e56d017364e1d602145d462292ef4820662901209dc286ec0d1b7a8 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -1001,7 +1001,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca -F test/fuzzdata8.db 1786362da75b8696f804b0b4548b59830e148718bce827548c006031105e7783 +F test/fuzzdata8.db bd3fe8efb575482574290939fc370e1c05be411540d641b2c5a685556a7774c9 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1824,7 +1824,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 3c75605b4652ae88659465d832953ac9d467369f9cb417f73b3d8599ec60b18b -R b0847795ba7312dd769390f52a23c18c +P a0819086a521fb0ca4ffd12f959b168a89ea2e30a2844bbbd39831b2b9ecf29b +R 4ae1172cfb69c4ca388f7f6898beb261 U drh -Z 9c745365e239320fd6fda1cfdfad4d1f +Z 935e74436fa8db0279dd403af1580bb6 diff --git a/manifest.uuid b/manifest.uuid index 67413b6578..f127cb2d5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a0819086a521fb0ca4ffd12f959b168a89ea2e30a2844bbbd39831b2b9ecf29b \ No newline at end of file +74eba2558a81f9e790d95a12a0c5379d4f80b43c8698ef9d6a31ff8d160a53d8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 42867168ea..9f265d2d09 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8068,7 +8068,7 @@ static int balance_nonroot( assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); - if( NEVER(rc!=SQLITE_OK) ) goto balance_cleanup; + if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 9ab060369920df286d1b89915830bc61b4916132..0843ffaf12bf0e71b7d55cb329f55254a96b325f 100644 GIT binary patch delta 5758 zcmZ{o349bq*1+d=_ssOnbX9jGA%P@hfPiwDo-30mM#J_R|}0~O?ZJz&U3w0~1?x~sZg z{p-C~ue!UoZgB1MgX_|h?s7Pkh~vtUxv*~t?%Ghc+O1B7rBts(>NWMa1WW5TB-Pa4 ziT;r-~}oY6`6`c#Yx3Q#Z5(};-O;S=Mx29?Trt*L_@)R(~Ms_ zOfz7bUOG4Fpwj>*9nt*$@?g*mT)rh9kJycLgs3iY;>F?uNKFr4))6v;iE3Neb!JsL z7WRkUy(4i_bGhk?lHku(=FfG(eB74Ix=XP?id`H$t zij`yFLp~@iXvV!Ip?Ex6YDS4V6bP8X+=@_;EW*1$6*l~!rC`%-ER-HFV=*(HZ!5{O z^_r2WNqr(-o8U*SAKpHU4S@(IrLmiRmn>$tmt)H?)}?o)nSinT(FCf@N^eQT%*!L* zP^B5Bi(oXjG-yXFzLv&1cc+@%NVqf*&yUh+UN}@5sPdN3X;r{14TkJ)xb3v7vlNaa ze8SV?c@>w99=7f4Eg^54rSumLnYK|XL%~2em`6sbu+@}bYAwIi8VH4R17XuP8BH%- zW%u`%*ubSWXywm3yd_vOnkB2{aWWcN3cIGW6qQbGhm~SrKI_;m6tDVu@>EG}VY(zW zbYUL>GmL(dU5B;Pn6J=VVn%=V8r^E!_5a-(w8zN{2jitNv%E4d5URR@nNW@gGuS{c zg;qj;oNVzK@8Y9tJKF8x@QzH@H{T49p7MMO1^U@xTWZG4Sd^wr(HM-9iK(_#kUN6G zieR8LP=O6cdEc>g9kQKehI4c6bLwF`jvNvs%SB3qu@DUq4A~wFR@fd3hG<@7{vd@` zywsjXFhaxAAN{KGEAvXrsdvc4*m+kfnkSSDJT>0MmFxWFehi#Y(i4~1_=((CZdaA= zrTpOlNO3^QrVU9xa4#;gKyj?a;wA1uxNkly;n8e0k6D8ni zo^ADL9+hw)i0hMBCgfppvsNO7^D(wjz7|g(<2PY}TXtf>jjWRzh~|c=PY?@Rw2dmI zp?oR>gwm{ClwqK#{a!l+IO!w42%Cp7znGE6dH}98+(Yd2H3(}jXrr-qfaDRC$F&tQ z6ksi|AXXpZQC#tXc87TRgckCGBu;&+8Q|0=7qn-(t;Yar`JhC#qc6#c)=y^9?KfQM?0!K z&bCY>iVfAQJ2qA`X6NupLeww?(Co`I3-9|u>n&b;gw3MZbjYQm;g~j_ zqT+

;EZ^e)E*t>vb?`s3_hWo_WBWx9jUGK24 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 delta 4631 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 aWS(E@h;o;DnSy_|_5;qFDi%8Lcl|fv*&d|; From 291508f62b9906adf7be3058b296d56edcc5b01f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 04:33:17 +0000 Subject: [PATCH 092/132] Remove an ALWAYS() that was previously added by check-in [a0819086] but which turns out can sometimes be false. FossilOrigin-Name: ad8fc5d8b440c49df95328df0408be699dde5a1dbd195b3f1f32e5f765578032 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- test/fuzzdata8.db | Bin 1102848 -> 1105920 bytes 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5222bb56e4..aeff91dc45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sNEVER()\sthat\swas\sadded\sin\sthe\sprevious\scheck-in\sbecause\sit\sis\sin\sfact\nreachable. -D 2019-05-08T03:34:53.523 +C Remove\san\sALWAYS()\sthat\swas\spreviously\sadded\sby\scheck-in\s[a0819086]\sbut\nwhich\sturns\sout\scan\ssometimes\sbe\sfalse. +D 2019-05-08T04:33:17.529 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -461,7 +461,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c fcfd6b960e56d017364e1d602145d462292ef4820662901209dc286ec0d1b7a8 +F src/btree.c 9177613eeef0fdbfcdc3f380e82c5c743a6d506bfa3faaf88077aa7104de53aa F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -1001,7 +1001,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca -F test/fuzzdata8.db bd3fe8efb575482574290939fc370e1c05be411540d641b2c5a685556a7774c9 +F test/fuzzdata8.db 7f1ad0a0cc9918529e7b16f48f2449ce6e7871babd71c79492bbe020fb3a63ae F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1824,7 +1824,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 a0819086a521fb0ca4ffd12f959b168a89ea2e30a2844bbbd39831b2b9ecf29b -R 4ae1172cfb69c4ca388f7f6898beb261 +P 74eba2558a81f9e790d95a12a0c5379d4f80b43c8698ef9d6a31ff8d160a53d8 +R b44cef3f4f230de0233e4f2d76b5b9bd U drh -Z 935e74436fa8db0279dd403af1580bb6 +Z 1b034307f2a838fd2dfaed7d5015e616 diff --git a/manifest.uuid b/manifest.uuid index f127cb2d5a..b4de1aec81 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -74eba2558a81f9e790d95a12a0c5379d4f80b43c8698ef9d6a31ff8d160a53d8 \ No newline at end of file +ad8fc5d8b440c49df95328df0408be699dde5a1dbd195b3f1f32e5f765578032 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9f265d2d09..92bafffbd4 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1630,7 +1630,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ top = get2byte(&data[hdr+5]); assert( top<=(int)pPage->pBt->usableSize ); /* by btreeComputeFreeSpace() */ if( gap>top ){ - if( top==0 && ALWAYS(pPage->pBt->usableSize==65536) ){ + if( top==0 && pPage->pBt->usableSize==65536 ){ top = 65536; }else{ return SQLITE_CORRUPT_PAGE(pPage); diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 0843ffaf12bf0e71b7d55cb329f55254a96b325f..b6440aa3cc824cc787d3980cf9685d2c9ecc3dff 100644 GIT binary patch delta 4727 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 delta 3828 zcmZ{n3shBQ7RT>C=iGbFeVp$*B#0u&MbOexE()S6ACN02YZ^gq<&;kNs+LM}Q=9As z$H&;1Aq285U!de;)Dd6oOf4x(3skN-W;z;}nVBYN=3{J}@7!E)2lTA9_geSd^L_jG z?Y+PMcTV2!L3wKi6?6z2ZnG&Vw&p9Q@PS@1d{fps6;if%v_iIh5xr1E&L&~gYf&zDB(Xc+YA4J*-rR%W~A`%n-RjlYlaJ7 zVulGn&oqReY3jmHGd;pjHeJGxH=V*iGb`FPH`)clBw?~JMVMWfLzpT|6Xq0VJ?9qY zp=g(W*3=~16&sAVT`AfW_M^JmZ#os*K`hHq24d;6dS}XdTQ6^mnFpi@98f0Bpm!?t zNT=PU*w(f$+VpIH`f0l!F4-pvh8K#$CbpyKo%#h)v^kAJG)2RZ1! z=?ur5YOMhCX2}jTUesL3Zt0ik;P?7Ffc^IBd%?fZ?`lKY5-S4A+onwgjH%Yoz>D;h zgRKJ0+pamNV!u9If~lC%-FX^~!P=XY6VT5&>>kDTYkvWiLd8e*nc$qh<6+aS*sk*6 zy%ERsbzsjHpf6!ul9q0f9s`O!sh-LHMq1eh$r3_QM9 z?~JtzwSJVgPxs5{cCc=WnDG_dMB4qB=#7(SaI;2a8=c1ZQ2Z;kdI z>22As0CUick?+NfT$x*Z@j#>7vsDuOjT%qs9IR3{0|qPCDTp%{8_(!DRt=j$=Svpo zo7i|x&&0eAE^ia;mF7xD2Z#Ti8h^H?52AY;bOUH$H+EXJ8;WhkR8c=4j_k?uwYL}e zO|ICMTMgP1y}ek9^R4X;lPR`KVOEu`Wlpxw5@F|)lFV+YkdO7*n*I8ONm`wmEM1QgCX5|nj%kU2R7rDN}*ymgiQm4mRy#z(%U*h@_Fm{wP5=)LI%og^qnZ=L&oN-SnaH7!E1{nS5YwS-kA z>R`O+(Za|*hNS{6UBwzc3@n!uaX}W?@!Lc>mY&?n*2}Pw%=h&Ku_1@(DkWC2!xB_rpc)d< zw-y{&kRm@p`Fq%O6*gn_EJ&fgHS9|nwqVXA5!=&Wehp*K$R}xffaOcD6${f{k<{TZ zJ1a}uyhVTL*qwSFWdYe;nVQ@;IXPvVFUg06?;G84Z81zLIptVF15dC$5)dhMEZga5 zr`WEKNx`ra#zU9^N^i{BB6~1zCFIbgbF3Kbo5boq#B{Hohz0qOiUs{(J+-~SE=aHg z>z>rTn46$i)5QiBF2hbtzsf$wJY9VjbFQ;KH0BChA;B&zd)g6&b=N(Av~G{4z1P?V z)zx0HotTtzOI#Q@EhTN+$TMX7b`ftkj(Nq=eM?376F_xac_dVJ(Z&V$Z556=1<%tI zA1{>EvAz3>hd;qFEA26uwV7|ES`Y6f!>2`oq4C&bo*GY&_u*S)wRg|n;=w%__6v-s z=fnA889u}MEIFC_wByw>e2(57Yyf7+s!l_r`BoYBV&*B$iy2?3<+RVsXKN5ek9Xyp zCHu!>rZ0=k@W0U52Y8tb)o4a*L(n^ub+WLEWvHR557mJ{X*%B(RHXey>G55fcq(N$ zfQ_5fSFyp)AHgO2jCUz3g0Ga|U?@{Ua+p;hvF^bVw-iO0j2z9aQ#pdW5%@1=Lx}l7L#7()m!qy=iCM_ z>7p&P6zfNcs|JP*@0^Mh7%jt%z1PiQPQ z8nF93HNk4ov%#C^F|G}d!)|+xBk1eL5li1tC(zYx+#|sS40}dsN$n+YVa8P{0Y%&H z$BIXwCuME7vhy<*24I@iyH5cf+QpM3xQLnO)R(ZdGoOs2gGbXUFD;94<<7|E{0z@u|rIQ+yIB@zlsPx6q=k{5k9BnPDB~)FFm&2 zc*qF}l)ugJOLptiuX|Ba#Nno+a;<1(aU9{TwtTQPwg<+&>k7XuuywnPcnK0|lZRIZ zS%*mA!@yfw%zonfH6XXWDI*4>4Ij?N;}i#ww@sg{zj(x?H Date: Wed, 8 May 2019 11:42:49 +0000 Subject: [PATCH 093/132] Fix VDBE opcodes OP_SeekLT and OP_SeekLE so that they work on intkey tables with non-numeric text values. FossilOrigin-Name: a870c196d78d8b72c7353fa0015e96b2abd4be154541d76328e3a4f9e5da5d04 --- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 15 +++++++++------ test/rowid.test | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index aeff91dc45..cf4d94da2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sALWAYS()\sthat\swas\spreviously\sadded\sby\scheck-in\s[a0819086]\sbut\nwhich\sturns\sout\scan\ssometimes\sbe\sfalse. -D 2019-05-08T04:33:17.529 +C Fix\sVDBE\sopcodes\sOP_SeekLT\sand\sOP_SeekLE\sso\sthat\sthey\swork\son\sintkey\stables\swith\snon-numeric\stext\svalues. +D 2019-05-08T11:42:49.245 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -592,7 +592,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 20e6098518581719ffc0ff0f5378d9bf9976fe5e7df029caf2a3d938a7375680 +F src/vdbe.c 02d6df64c03e6c69b94d8e53699b0ab4e4d6bc74ef88484b48970864dbf0cce7 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da @@ -1242,7 +1242,7 @@ F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 -F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d +F test/rowid.test 6d43c560e212f99499c31d3f75caacd0b9e059baf88b5fc31fba6b0e280f8b4c F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 @@ -1824,7 +1824,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 74eba2558a81f9e790d95a12a0c5379d4f80b43c8698ef9d6a31ff8d160a53d8 -R b44cef3f4f230de0233e4f2d76b5b9bd -U drh -Z 1b034307f2a838fd2dfaed7d5015e616 +P ad8fc5d8b440c49df95328df0408be699dde5a1dbd195b3f1f32e5f765578032 +R d9e7e64dfe9317c90386891973a71fc2 +T *branch * tkt-9cf6c9bb +T *sym-tkt-9cf6c9bb * +T -sym-trunk * +U dan +Z 8415596bc13788788419c7a2f45ee67b diff --git a/manifest.uuid b/manifest.uuid index b4de1aec81..59d1ca6c5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad8fc5d8b440c49df95328df0408be699dde5a1dbd195b3f1f32e5f765578032 \ No newline at end of file +a870c196d78d8b72c7353fa0015e96b2abd4be154541d76328e3a4f9e5da5d04 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1fd49a9312..fbcdca851d 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4012,11 +4012,14 @@ case OP_SeekGT: { /* jump, in3, group */ ** loss of information, then special processing is required... */ if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ if( (pIn3->flags & MEM_Real)==0 ){ - /* If the P3 value cannot be converted into any kind of a number, - ** then the seek is not possible, so jump to P2 */ - VdbeBranchTaken(1,2); goto jump_to_p2; - break; - } + if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){ + VdbeBranchTaken(1,2); goto jump_to_p2; + break; + }else{ + sqlite3BtreeLast(pC->uc.pCursor, &res); + goto seek_not_found; + } + }else /* If the approximation iKey is larger than the actual real search ** term, substitute >= for > and < for <=. e.g. if the search term @@ -4040,7 +4043,7 @@ case OP_SeekGT: { /* jump, in3, group */ assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; } - } + } rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ if( rc!=SQLITE_OK ){ diff --git a/test/rowid.test b/test/rowid.test index 56336453fa..69f3519a31 100644 --- a/test/rowid.test +++ b/test/rowid.test @@ -659,6 +659,32 @@ do_test rowid-11.4 { execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc'} } {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} +do_test rowid-11.asc.1 { + execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 ASC} +} {} +do_test rowid-11.asc.2 { + execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 ASC} +} {} +do_test rowid-11.asc.3 { + execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 ASC} +} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} +do_test rowid-11.asc.4 { + execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 ASC} +} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} + +do_test rowid-11.desc.1 { + execsql {SELECT rowid, a FROM t5 WHERE rowid>'abc' ORDER BY 1 DESC} +} {} +do_test rowid-11.desc.2 { + execsql {SELECT rowid, a FROM t5 WHERE rowid>='abc' ORDER BY 1 DESC} +} {} +do_test rowid-11.desc.3 { + execsql {SELECT rowid, a FROM t5 WHERE rowid<'abc' ORDER BY 1 DESC} +} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1} +do_test rowid-11.desc.4 { + execsql {SELECT rowid, a FROM t5 WHERE rowid<='abc' ORDER BY 1 DESC} +} {8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1} + # Test the automatic generation of rowids when the table already contains # a rowid with the maximum value. # @@ -719,4 +745,24 @@ do_execsql_test rowid-13.1 { SELECT last_insert_rowid(); } {1234 5 2234 | 2234 4990756 3234 | 3234 10458756 4234 | 4234} +#------------------------------------------------------------------------- +do_execsql_test rowid-14.0 { + CREATE TABLE t14(x INTEGER PRIMARY KEY); + INSERT INTO t14(x) VALUES (100); +} +do_execsql_test rowid-14.1 { + SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC; +} {100} +do_execsql_test rowid-14.2 { + SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC; +} {100} + +do_execsql_test rowid-14.3 { + DELETE FROM t14; + SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid ASC; +} {} +do_execsql_test rowid-14.4 { + SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC; +} {} + finish_test From 08652b5ea00316539c913fc936e2966c8d58d283 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 17:27:18 +0000 Subject: [PATCH 094/132] Provide the SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA compile-time option to omit the case_sensitive_like pragma. This change, in combination with documentation changes, is the current solution to ticket [a340eef47b0cad5]. FossilOrigin-Name: eabe7f2d4ff0e0dd868dcab7ec1d4a9168a25f80d3a52f0eeea2f90bd33782f2 --- manifest | 21 ++++++++++----------- manifest.uuid | 2 +- src/func.c | 7 ++----- src/pragma.c | 2 ++ src/pragma.h | 2 ++ tool/mkpragmatab.tcl | 1 + 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index b7088a52b6..cf25773aa5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sVDBE\sopcodes\sOP_SeekLT\sand\sOP_SeekLE\sso\sthat\sthey\swork\son\sintkey\stables\swith\snon-numeric\stext\svalues. -D 2019-05-08T11:52:13.065 +C Provide\sthe\sSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA\scompile-time\soption\sto\nomit\sthe\scase_sensitive_like\spragma.\s\sThis\schange,\sin\scombination\swith\ndocumentation\schanges,\sis\sthe\scurrent\ssolution\sto\sticket\n[a340eef47b0cad5]. +D 2019-05-08T17:27:18.827 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 -F src/func.c ac05ea6b47b407586ad2c0878c4c81c3acb08b67ecf86648830f91f40325ae37 +F src/func.c 1d010f0babe7ab1b74dc2314fa00385c13ea59977bdad5a9890404df8d527fc5 F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -513,8 +513,8 @@ F src/parse.y 22f64d8a8910acd17580450513b58d64187b0962848380c7f0a39376b8a48cee F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c be64b2f3908a7f97c56c963676eb12f0d6254c95b28cdc1d73a186eff213219d -F src/pragma.c af67dedaad8bafe9a5f9adcec32a0da6dd118617dd8220ad1d118f5a6bf83a02 -F src/pragma.h a776bb9c915207e9d1117b5754743ddf1bf6a39cc092a4a44e74e6cb5fab1177 +F src/pragma.c 2e9fbfcb23cb72eabb38ab6fa84c36a65f9c4839ce1e9bb3dd982ab26b67a5a8 +F src/pragma.h 482c26f352efd7a4ed1354d83ffa992e13004f6528edeee44cdbfd5025a490bd F src/prepare.c 78027c6231fbb19ca186a5f5f0c0a1375d9c2cec0655273f9bd90d9ff74a34b3 F src/printf.c 67f79227273a9009d86a017619717c3f554f50b371294526da59faa6014ed2cd F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 @@ -1757,7 +1757,7 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl 49039adedafbc430d2959400da2e0e8f20ef8dcf6898e447c946e7d50ef5906b +F tool/mkpragmatab.tcl d8887dfbd5a40c9e5de2c011db989af52152b9bcc64059d9e93b28edf38af9b9 F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1824,8 +1824,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 ad8fc5d8b440c49df95328df0408be699dde5a1dbd195b3f1f32e5f765578032 a870c196d78d8b72c7353fa0015e96b2abd4be154541d76328e3a4f9e5da5d04 -R d9e7e64dfe9317c90386891973a71fc2 -T +closed a870c196d78d8b72c7353fa0015e96b2abd4be154541d76328e3a4f9e5da5d04 -U dan -Z 54955d931d09bcd0b00fd21b389345ba +P 658b84d7f4a0886591c5aab30ed9e31c4a0f56db303eb863f24833ca37085d14 +R 1aacbe8635fd2d86ce3c1e661cee2fa2 +U drh +Z 3ad5497a837c2c025e871372e9c65994 diff --git a/manifest.uuid b/manifest.uuid index 35eccd1c6c..36d1783772 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -658b84d7f4a0886591c5aab30ed9e31c4a0f56db303eb863f24833ca37085d14 \ No newline at end of file +eabe7f2d4ff0e0dd868dcab7ec1d4a9168a25f80d3a52f0eeea2f90bd33782f2 \ No newline at end of file diff --git a/src/func.c b/src/func.c index dae85d60a8..15f648ab5e 100644 --- a/src/func.c +++ b/src/func.c @@ -1811,9 +1811,9 @@ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ } /* -** Register the built-in LIKE and GLOB functions. The caseSensitive +** Re-register the built-in LIKE functions. The caseSensitive ** parameter determines whether or not the LIKE operator is case -** sensitive. GLOB is always case sensitive. +** sensitive. */ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ struct compareInfo *pInfo; @@ -1824,9 +1824,6 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ } sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, - (struct compareInfo*)&globInfo, likeFunc, 0, 0, 0, 0, 0); - setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE); setLikeOptFlag(db, "like", caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); } diff --git a/src/pragma.c b/src/pragma.c index 1dcd21400c..90ecdfcc5d 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1421,6 +1421,7 @@ void sqlite3Pragma( #endif /* !defined(SQLITE_OMIT_TRIGGER) */ #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ +#ifndef SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA /* Reinstall the LIKE and GLOB functions. The variant of LIKE ** used will be case sensitive or not depending on the RHS. */ @@ -1430,6 +1431,7 @@ void sqlite3Pragma( } } break; +#endif /* SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA */ #ifndef SQLITE_INTEGRITY_CHECK_ERROR_MAX # define SQLITE_INTEGRITY_CHECK_ERROR_MAX 100 diff --git a/src/pragma.h b/src/pragma.h index c156e3a4fb..d72e8cc949 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -178,11 +178,13 @@ static const PragmaName aPragmaName[] = { /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif +#if !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA) {/* zName: */ "case_sensitive_like", /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE, /* ePragFlg: */ PragFlg_NoColumns, /* ColNames: */ 0, 0, /* iArg: */ 0 }, +#endif {/* zName: */ "cell_size_check", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index b236bdd5d5..eb62d089b2 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -301,6 +301,7 @@ set pragma_def { NAME: case_sensitive_like FLAG: NoColumns + IF: !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA) NAME: integrity_check FLAG: NeedSchema Result0 Result1 From 42e84ae1ab2774a881aa271660ec79889bf761d4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 May 2019 18:49:51 +0000 Subject: [PATCH 095/132] Add tests to improve code coverage of the RBU module. FossilOrigin-Name: ecb56b75a0e66462acdcce285b93f9fc56944c42902d886d6bada419059519a9 --- ext/rbu/rbufault3.test | 2 - ext/rbu/rbumisc.test | 53 ++++++++++++++++++++++ ext/rbu/rbutemplimit.test | 1 + ext/rbu/rbuvacuum4.test | 11 ++++- ext/rbu/sqlite3rbu.c | 95 +++++++++++++++++++-------------------- manifest | 21 ++++----- manifest.uuid | 2 +- 7 files changed, 121 insertions(+), 64 deletions(-) create mode 100644 ext/rbu/rbumisc.test diff --git a/ext/rbu/rbufault3.test b/ext/rbu/rbufault3.test index 5d44885e9e..4f690284a2 100644 --- a/ext/rbu/rbufault3.test +++ b/ext/rbu/rbufault3.test @@ -83,7 +83,6 @@ foreach {fault errlist} { do_faultsim_test 3 -faults $fault -prep { faultsim_restore_and_reopen - forcedelete test.db2 } -body { sqlite3rbu_vacuum rbu test.db test.db2 rbu step @@ -91,7 +90,6 @@ foreach {fault errlist} { } -test { eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist] } - } finish_test diff --git a/ext/rbu/rbumisc.test b/ext/rbu/rbumisc.test new file mode 100644 index 0000000000..6378104b21 --- /dev/null +++ b/ext/rbu/rbumisc.test @@ -0,0 +1,53 @@ +# 2014 August 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbumisc + +db close +sqlite3_shutdown +sqlite3_config_uri 1 +reset_db + +#------------------------------------------------------------------------- +# Ensure that RBU is not confused by oddly named tables in an RBU +# database. +# +do_execsql_test 1.0 { + CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY); +} +do_test 1.1 { + forcedelete rbu.db + sqlite3 rbu rbu.db + rbu eval { + CREATE TABLE data_x1(a, b, c, rbu_control); + INSERT INTO data_x1 VALUES(1, 1, 1, 0); + INSERT INTO data_x1 VALUES(2, 2, 2, 0); + + CREATE TABLE dat(a, b, c, rbu_control); + CREATE TABLE "data x1"(a, b, c, rbu_control); + CREATE TABLE datax1(a, b, c, rbu_control); + CREATE TABLE data_(a, b, c, rbu_control); + + INSERT INTO "data x1" VALUES(3, 3, 3, 0); + INSERT INTO datax1 VALUES(3, 3, 3, 0); + INSERT INTO data_ VALUES(3, 3, 3, 0); + INSERT INTO dat VALUES(3, 3, 3, 0); + } +} {} + +do_test 1.2 { + step_rbu test.db rbu.db + db eval { SELECT * FROM x1 } +} {1 1 1 2 2 2} + +finish_test diff --git a/ext/rbu/rbutemplimit.test b/ext/rbu/rbutemplimit.test index 9397b568df..958b2bfcbc 100644 --- a/ext/rbu/rbutemplimit.test +++ b/ext/rbu/rbutemplimit.test @@ -65,6 +65,7 @@ proc step_rbu_cachesize {target rbu stepsize cachesize temp_limit} { while 1 { sqlite3rbu rbu $target $rbu rbu temp_size_limit $temp_limit + if { [rbu temp_size_limit -1]!=$temp_limit } { error "round trip problem!" } sqlite3_exec_nr [rbu db 1] "PRAGMA cache_size = $cachesize" for {set i 0} {$i < $stepsize} {incr i} { set rc [rbu step] diff --git a/ext/rbu/rbuvacuum4.test b/ext/rbu/rbuvacuum4.test index 9984c9120a..5cf33d6765 100644 --- a/ext/rbu/rbuvacuum4.test +++ b/ext/rbu/rbuvacuum4.test @@ -50,13 +50,20 @@ do_execsql_test 3.0 { INSERT INTO t1 VALUES(1, 2, 3); INSERT INTO t1 VALUES(4, 5, 6); INSERT INTO t1 VALUES(7, 8, 9); + + CREATE TABLE t2(a, b, c INTEGER, PRIMARY KEY(c)); + CREATE INDEX i2 oN t2(b, a); + INSERT INTO t2 VALUES('a', 'b', -1); + INSERT INTO t2 VALUES('c', 'd', -2); + INSERT INTO t2 VALUES('e', 'f', -3); } do_rbu_vacuum_test 3.1 1 do_execsql_test 3.2 { SELECT * FROM t1; -} {1 2 3 4 5 6 7 8 9} + SELECT * FROM t2; +} {1 2 3 4 5 6 7 8 9 e f -3 c d -2 a b -1} #------------------------------------------------------------------------- reset_db @@ -96,6 +103,8 @@ do_execsql_test 5.0 { INSERT INTO "a b c" VALUES(3, 9, 1); INSERT INTO "a b c" VALUES('aaa', 'bbb', 'ccc'); + CREATE INDEX abc2 ON "a b c"("c c" DESC, a); + CREATE TABLE x(a); INSERT INTO x VALUES('a'), ('b'), ('d'); CREATE UNIQUE INDEX y ON x(a); diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 0ed2837ca7..170505ca0b 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -1546,65 +1546,60 @@ char *rbuVacuumIndexStart( char *zVector = 0; char *zRet = 0; int bFailed = 0; + const char *zSep = ""; + int iCol = 0; + sqlite3_stmt *pXInfo = 0; - if( p->rc==SQLITE_OK ){ - const char *zSep = ""; - int iCol = 0; - sqlite3_stmt *pXInfo = 0; - p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) - ); - while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ - int iCid = sqlite3_column_int(pXInfo, 1); - const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); - const char *zCol; - if( sqlite3_column_int(pXInfo, 3) ){ - bFailed = 1; - break; - } - - if( iCid<0 ){ - if( pIter->eType==RBU_PK_IPK ){ - int i; - for(i=0; pIter->abTblPk[i]==0; i++); - assert( inTblCol ); - zCol = pIter->azTblCol[i]; - }else{ - zCol = "_rowid_"; - } - }else{ - zCol = pIter->azTblCol[iCid]; - } - - zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q", - zLhs, zSep, zCol, zCollate - ); - zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC", - zOrder, zSep, iCol, zCol, zCollate - ); - zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")", - zSelect, zSep, iCol, zCol - ); - zSep = ", "; - iCol++; + p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + ); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); + const char *zCol; + if( sqlite3_column_int(pXInfo, 3) ){ + bFailed = 1; + break; } - rbuFinalize(p, pXInfo); + + if( iCid<0 ){ + if( pIter->eType==RBU_PK_IPK ){ + int i; + for(i=0; pIter->abTblPk[i]==0; i++); + assert( inTblCol ); + zCol = pIter->azTblCol[i]; + }else{ + zCol = "_rowid_"; + } + }else{ + zCol = pIter->azTblCol[iCid]; + } + + zLhs = rbuMPrintf(p, "%z%s \"%w\" COLLATE %Q", + zLhs, zSep, zCol, zCollate + ); + zOrder = rbuMPrintf(p, "%z%s \"rbu_imp_%d%w\" COLLATE %Q DESC", + zOrder, zSep, iCol, zCol, zCollate + ); + zSelect = rbuMPrintf(p, "%z%s quote(\"rbu_imp_%d%w\")", + zSelect, zSep, iCol, zCol + ); + zSep = ", "; + iCol++; } + rbuFinalize(p, pXInfo); if( bFailed ) goto index_start_out; if( p->rc==SQLITE_OK ){ - int iCol; sqlite3_stmt *pSel = 0; - if( p->rc==SQLITE_OK ){ - p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, - sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", - zSelect, pIter->zTbl, zOrder - ) - ); - } + p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, + sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", + zSelect, pIter->zTbl, zOrder + ) + ); if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){ - const char *zSep = ""; + zSep = ""; for(iCol=0; iColnCol; iCol++){ const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); if( zQuoted[0]=='N' ){ diff --git a/manifest b/manifest index cf25773aa5..de029bebe7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sthe\sSQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA\scompile-time\soption\sto\nomit\sthe\scase_sensitive_like\spragma.\s\sThis\schange,\sin\scombination\swith\ndocumentation\schanges,\sis\sthe\scurrent\ssolution\sto\sticket\n[a340eef47b0cad5]. -D 2019-05-08T17:27:18.827 +C Add\stests\sto\simprove\scode\scoverage\sof\sthe\sRBU\smodule. +D 2019-05-08T18:49:51.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -346,21 +346,22 @@ F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20 F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8 F ext/rbu/rbufault2.test 06e735c002c17802d93debca41f59b027e7429db7de17f2a81318ecfd3c651d4 -F ext/rbu/rbufault3.test e0052ccba428ffdd2bb989d3ae84716f058ec5ab5f7196c64ba407b9d23c7255 +F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179 F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d +F ext/rbu/rbumisc.test 0988f5e24df5c38067a97586cb24da68c80409651dedc958dbeec3dfe0c6ad11 F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9 F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4 F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9 F ext/rbu/rburesume.test dbdc4ca504e9c76375a69e5f0d91205db967dcc509a5166ca80231f8fda49eb1 F ext/rbu/rbusave.test f4190a1a86fccf84f723af5c93813365ae33feda35845ba107b59683d1cdd926 F ext/rbu/rbusplit.test b37e7b40b38760881dc9c854bd40b4744c6b6cd74990754eca3bda0f407051e8 -F ext/rbu/rbutemplimit.test 7f408f49b90fa0a720d7599f3aec74a3c85e6cd78e56fdf726ce00af9147a341 +F ext/rbu/rbutemplimit.test 05ceefa90a2e26a99f40dd48282ed63a00df5e59c1f2bfd479c143e201a1b0ba F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697d79f73534 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc -F ext/rbu/rbuvacuum4.test 08abd9e18d8aee5bb812de0d6a928cc8bbacae58ecb1f150637e80f4c93c8afa -F ext/rbu/sqlite3rbu.c ec93d28c5cef16ccef7ed76c2b6c410e8eb078c73705b6e7b683f88f722228f2 +F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 +F ext/rbu/sqlite3rbu.c 65794a321345f00232ffc113159272d3a6934fd5a65e09df8b86d6bf2485246f F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1824,7 +1825,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 658b84d7f4a0886591c5aab30ed9e31c4a0f56db303eb863f24833ca37085d14 -R 1aacbe8635fd2d86ce3c1e661cee2fa2 -U drh -Z 3ad5497a837c2c025e871372e9c65994 +P eabe7f2d4ff0e0dd868dcab7ec1d4a9168a25f80d3a52f0eeea2f90bd33782f2 +R f38629c2df688919c2eea086352e406a +U dan +Z 0dea2404f0db0801946b811401465571 diff --git a/manifest.uuid b/manifest.uuid index 36d1783772..8af2174662 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eabe7f2d4ff0e0dd868dcab7ec1d4a9168a25f80d3a52f0eeea2f90bd33782f2 \ No newline at end of file +ecb56b75a0e66462acdcce285b93f9fc56944c42902d886d6bada419059519a9 \ No newline at end of file From 9e9374b2e20a2221f8fdfb940d6d82064d641283 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 19:06:59 +0000 Subject: [PATCH 096/132] Avoid an excess register allocation in UPDATE, when possible. This improves speed (slightly) and reduces the code footprint. FossilOrigin-Name: 8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/update.c | 19 ++++++++++++++----- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index de029bebe7..d67ef530f4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\simprove\scode\scoverage\sof\sthe\sRBU\smodule. -D 2019-05-08T18:49:51.870 +C Avoid\san\sexcess\sregister\sallocation\sin\sUPDATE,\swhen\spossible.\s\sThis\simproves\nspeed\s(slightly)\sand\sreduces\sthe\scode\sfootprint. +D 2019-05-08T19:06:59.709 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -588,7 +588,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c 56724725c62a0d0f408f7c257475dc33309198afee36a1d18be1bc268b09055e F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 -F src/update.c fb29c2eb1f52a5009fd0e00f5041fb6ae14a7f9a5048da220e45e804c61b3559 +F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 @@ -1825,7 +1825,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 eabe7f2d4ff0e0dd868dcab7ec1d4a9168a25f80d3a52f0eeea2f90bd33782f2 -R f38629c2df688919c2eea086352e406a -U dan -Z 0dea2404f0db0801946b811401465571 +P ecb56b75a0e66462acdcce285b93f9fc56944c42902d886d6bada419059519a9 +R 2b2161dc021eeafc304f534286be079c +U drh +Z 70eeee98b674ce1a62d7db850c161190 diff --git a/manifest.uuid b/manifest.uuid index 8af2174662..d30e6c6835 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ecb56b75a0e66462acdcce285b93f9fc56944c42902d886d6bada419059519a9 \ No newline at end of file +8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4 \ No newline at end of file diff --git a/src/update.c b/src/update.c index 8bb9f8466a..bbeaa3d5ce 100644 --- a/src/update.c +++ b/src/update.c @@ -155,6 +155,7 @@ void sqlite3Update( Index *pIdx; /* For looping over indices */ Index *pPk; /* The PRIMARY KEY index for WITHOUT ROWID tables */ int nIdx; /* Number of indices that need updating */ + int nAllIdx; /* Total number of indexes */ int iBaseCur; /* Base cursor number */ int iDataCur; /* Cursor for the canonical data btree */ int iIdxCur; /* Cursor for the first index */ @@ -355,7 +356,7 @@ void sqlite3Update( ** the key for accessing each index. */ if( onError==OE_Replace ) bReplace = 1; - for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ + for(nAllIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nAllIdx++){ int reg; if( chngKey || hasFK>1 || pIdx==pPk || indexWhereClauseMightChange(pIdx,aXRef,chngRowid) @@ -375,10 +376,10 @@ void sqlite3Update( } } } - if( reg==0 ) aToOpen[j+1] = 0; - aRegIdx[j] = reg; + if( reg==0 ) aToOpen[nAllIdx+1] = 0; + aRegIdx[nAllIdx] = reg; } - aRegIdx[j] = ++pParse->nMem; /* Register storing the table record */ + aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */ if( bReplace ){ /* If REPLACE conflict resolution might be invoked, open cursors on all ** indexes in case they are needed to delete records. */ @@ -393,7 +394,13 @@ void sqlite3Update( /* Allocate required registers. */ if( !IsVirtual(pTab) ){ - regRowSet = ++pParse->nMem; + /* For now, regRowSet and aRegIdx[nAllIdx] share the same register. + ** If regRowSet turns out to be needed, then aRegIdx[nAllIdx] will be + ** reallocated. aRegIdx[nAllIdx] is the register in which the main + ** table record is written. regRowSet holds the RowSet for the + ** two-pass update algorithm. */ + assert( aRegIdx[nAllIdx]==pParse->nMem ); + regRowSet = aRegIdx[nAllIdx]; regOldRowid = regNewRowid = ++pParse->nMem; if( chngPk || pTrigger || hasFK ){ regOld = pParse->nMem + 1; @@ -523,6 +530,8 @@ void sqlite3Update( ** leave it in register regOldRowid. */ sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); if( eOnePass==ONEPASS_OFF ){ + /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */ + aRegIdx[nAllIdx] = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); } }else{ From ea5c040f878dbe8416cc85ece8d16fdec412e059 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 19:32:33 +0000 Subject: [PATCH 097/132] Simplification to the logic underlying PRAGMA case_sensitive_like. FossilOrigin-Name: ef0015fde4c87e992ffd3d7dea8586951bdd65ff98d30d436b126b85b1cc9c74 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/func.c | 22 +++++----------------- test/e_expr.test | 19 ++++++++++++------- 4 files changed, 25 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index d67ef530f4..536e47c434 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sexcess\sregister\sallocation\sin\sUPDATE,\swhen\spossible.\s\sThis\simproves\nspeed\s(slightly)\sand\sreduces\sthe\scode\sfootprint. -D 2019-05-08T19:06:59.709 +C Simplification\sto\sthe\slogic\sunderlying\sPRAGMA\scase_sensitive_like. +D 2019-05-08T19:32:33.786 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 -F src/func.c 1d010f0babe7ab1b74dc2314fa00385c13ea59977bdad5a9890404df8d527fc5 +F src/func.c 8c075dd8ba770bf48a4297c6ab6a520842d0d7711a7b6d9065246d50507597da F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -819,7 +819,7 @@ F test/e_createtable.test 1c602347e73ab80b11b9fa083f47155861aaafcff8054aac9e0b76 F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 3cd080807622c13e5bbb61fc9a57bd7754da2412 F test/e_dropview.test 21ce09c361227ddbc9819a5608ee2700c276bdd5 -F test/e_expr.test ca8896601ade1e27c6559614c7f32c63d44636fdfa720436a160f09b8bf66c89 +F test/e_expr.test 698c8c6e9b4b737f494c39b2210a3eb7af0efd8167137844483b7add5c76a951 F test/e_fkey.test 2febb2084aef9b0186782421c07bc9d377abf067c9cb4efd49d9647ae31f5afe F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e @@ -1825,7 +1825,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 ecb56b75a0e66462acdcce285b93f9fc56944c42902d886d6bada419059519a9 -R 2b2161dc021eeafc304f534286be079c +P 8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4 +R 2a03805a01d2e55ce8878d993088a328 U drh -Z 70eeee98b674ce1a62d7db850c161190 +Z c59eafe33a9b24be06876b542e867244 diff --git a/manifest.uuid b/manifest.uuid index d30e6c6835..572c921e66 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4 \ No newline at end of file +ef0015fde4c87e992ffd3d7dea8586951bdd65ff98d30d436b126b85b1cc9c74 \ No newline at end of file diff --git a/src/func.c b/src/func.c index 15f648ab5e..b0a3169213 100644 --- a/src/func.c +++ b/src/func.c @@ -1795,21 +1795,6 @@ void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ } } -/* -** Set the LIKEOPT flag on the 2-argument function with the given name. -*/ -static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ - FuncDef *pDef; - pDef = sqlite3FindFunction(db, zName, 2, SQLITE_UTF8, 0); - if( ALWAYS(pDef) ){ - pDef->funcFlags |= flagVal; - } - pDef = sqlite3FindFunction(db, zName, 3, SQLITE_UTF8, 0); - if( pDef ){ - pDef->funcFlags |= flagVal; - } -} - /* ** Re-register the built-in LIKE functions. The caseSensitive ** parameter determines whether or not the LIKE operator is case @@ -1817,15 +1802,18 @@ static void setLikeOptFlag(sqlite3 *db, const char *zName, u8 flagVal){ */ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ struct compareInfo *pInfo; + int flags; if( caseSensitive ){ pInfo = (struct compareInfo*)&likeInfoAlt; + flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; }else{ pInfo = (struct compareInfo*)&likeInfoNorm; + flags = SQLITE_FUNC_LIKE; } sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - setLikeOptFlag(db, "like", - caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE); + sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; + sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; } /* diff --git a/test/e_expr.test b/test/e_expr.test index 1cac31948b..6e3a8d9608 100644 --- a/test/e_expr.test +++ b/test/e_expr.test @@ -1013,13 +1013,18 @@ sqlite3 db test.db # EVIDENCE-OF: R-22868-25880 The LIKE operator can be made case # sensitive using the case_sensitive_like pragma. # -do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1 -do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {} -do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0 -do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1 -do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {} -do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1 -do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1 +do_execsql_test e_expr-16.1.1 { SELECT 'abcxyz' LIKE 'ABC%' } 1 +do_execsql_test e_expr-16.1.1b { SELECT 'abc%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1 +do_execsql_test e_expr-16.1.2 { PRAGMA case_sensitive_like = 1 } {} +do_execsql_test e_expr-16.1.3 { SELECT 'abcxyz' LIKE 'ABC%' } 0 +do_execsql_test e_expr-16.1.3b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 0 +do_execsql_test e_expr-16.1.4 { SELECT 'ABCxyz' LIKE 'ABC%' } 1 +do_execsql_test e_expr-16.1.4b { SELECT 'ABC%xyz' LIKE 'ABC\%x%' ESCAPE '\' } 1 +do_execsql_test e_expr-16.1.5 { PRAGMA case_sensitive_like = 0 } {} +do_execsql_test e_expr-16.1.6 { SELECT 'abcxyz' LIKE 'ABC%' } 1 +do_execsql_test e_expr-16.1.6b { SELECT 'abc%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1 +do_execsql_test e_expr-16.1.7 { SELECT 'ABCxyz' LIKE 'ABC%' } 1 +do_execsql_test e_expr-16.1.7b { SELECT 'ABC%xyz' LIKE 'ABC\%X%' ESCAPE '\' } 1 # EVIDENCE-OF: R-52087-12043 The GLOB operator is similar to LIKE but # uses the Unix file globbing syntax for its wildcards. From 97afa309d7bf31ec6856a74c13d41f118c780809 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 19:55:24 +0000 Subject: [PATCH 098/132] Fix another pattern for which the LIKE optimization does not work for a non-TEXT affinity. Case found by Manuel Rigger. FossilOrigin-Name: 740201107ae802c12b678e388ea524db01ad0eb70601c78490ad63eae0fe6cf1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 2 +- test/like3.test | 13 ++++++++++++- 4 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 536e47c434..cb3c9fbe3a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sto\sthe\slogic\sunderlying\sPRAGMA\scase_sensitive_like. -D 2019-05-08T19:32:33.786 +C Fix\sanother\spattern\sfor\swhich\sthe\sLIKE\soptimization\sdoes\snot\swork\sfor\sa\nnon-TEXT\saffinity.\s\sCase\sfound\sby\sManuel\sRigger. +D 2019-05-08T19:55:24.788 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -610,7 +610,7 @@ F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a -F src/whereexpr.c 7fedf990999722dafda5ab8040feac93937a6f95f4671d8d629f2baf014b4b80 +F src/whereexpr.c 3a8abba627bffcd930c181bbd78cf5d31c5ef496126d49d0ba94874db16efa33 F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1091,7 +1091,7 @@ F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 F test/like.test 11cfd7d4ef8625389df9efc46735ff0b0b41d5e62047ef0f3bc24c380d28a7a6 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da -F test/like3.test b065d1ca38c03dd76caae1d4cc84ed3d6eb3f64b3ff6b0dfad6413a7b406cca4 +F test/like3.test ac61947ef35bde9d97718bcfa04659a17d9218f1fffc4104b135b3f82ed43836 F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e F test/limit2.test 9409b033284642a859fafc95f29a5a6a557bd57c1f0d7c3f554bd64ed69df77e F test/loadext.test faa4f6eed07a5aac35d57fdd7bc07f8fc82464cfd327567c10cf0ba3c86cde04 @@ -1825,7 +1825,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 8658574e3f435f03a87c04f398bd05078ebc53ecb4a477d3b24902d701d935c4 -R 2a03805a01d2e55ce8878d993088a328 +P ef0015fde4c87e992ffd3d7dea8586951bdd65ff98d30d436b126b85b1cc9c74 +R 76ed0b382d531a90e41c3e087ed11622 U drh -Z c59eafe33a9b24be06876b542e867244 +Z e9e0cda4b886af13a74fd7aa63325365 diff --git a/manifest.uuid b/manifest.uuid index 572c921e66..14f3592fe1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ef0015fde4c87e992ffd3d7dea8586951bdd65ff98d30d436b126b85b1cc9c74 \ No newline at end of file +740201107ae802c12b678e388ea524db01ad0eb70601c78490ad63eae0fe6cf1 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 90e1b5be65..39c4ba3c94 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -278,7 +278,7 @@ static int isLikeOrGlob( if( sqlite3Isdigit(zNew[0]) || zNew[0]=='-' || zNew[0]=='+' - || (zNew[0]+1=='0' && iTo==1) + || (iTo>0 && zNew[iTo-1]=='0'-1) ){ if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT diff --git a/test/like3.test b/test/like3.test index f9120e7384..5e75571b61 100644 --- a/test/like3.test +++ b/test/like3.test @@ -179,7 +179,7 @@ do_eqp_test like3-5.211 { } # 2019-05-01 -# another case of the above reported on the mailing list by Manual Rigger. +# another case of the above reported on the mailing list by Manuel Rigger. # do_execsql_test like3-5.300 { CREATE TABLE t5c (c0 REAL); @@ -188,6 +188,17 @@ do_execsql_test like3-5.300 { SELECT * FROM t5c WHERE (c0 LIKE '+/'); } {+/} +# 2019-05-08 +# Yet another case for the above from Manuel Rigger. +# +do_execsql_test like3-5.400 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 INT UNIQUE COLLATE NOCASE); + INSERT INTO t0(c0) VALUES ('./'); + SELECT * FROM t0 WHERE t0.c0 LIKE './'; +} {./} + + # 2019-02-27 # Verify that the LIKE optimization works with an ESCAPE clause when # using PRAGMA case_sensitive_like=ON. From ad5536fca15959addf7f6a87785140d30cfc8b65 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 8 May 2019 21:14:48 +0000 Subject: [PATCH 099/132] Add another test case to cover a previously uncovered branch in the RBU module. FossilOrigin-Name: 30392985612c51d4583a905f8fe766f08cd31b86d0e30a977adc6a6705649e00 --- ext/rbu/rbumisc.test | 27 +++++++++++++++++++++++++++ ext/rbu/sqlite3rbu.c | 3 ++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/ext/rbu/rbumisc.test b/ext/rbu/rbumisc.test index 6378104b21..d8fe030b48 100644 --- a/ext/rbu/rbumisc.test +++ b/ext/rbu/rbumisc.test @@ -43,6 +43,7 @@ do_test 1.1 { INSERT INTO data_ VALUES(3, 3, 3, 0); INSERT INTO dat VALUES(3, 3, 3, 0); } + rbu close } {} do_test 1.2 { @@ -50,4 +51,30 @@ do_test 1.2 { db eval { SELECT * FROM x1 } } {1 1 1 2 2 2} +do_test 1.3 { + db eval { DELETE FROM x1 } + sqlite3 rbu rbu.db + rbu eval { DELETE FROM rbu_state } + rbu close + step_rbu test.db rbu.db + db eval { SELECT * FROM x1 } +} {1 1 1 2 2 2} + +do_test 1.4 { + db eval { DELETE FROM x1 } + sqlite3 rbu rbu.db + rbu eval { DELETE FROM rbu_state } + rbu close + + sqlite3rbu rbu test.db rbu.db + rbu step + rbu step + rbu close + + forcecopy test.db-oal test.db-wal + sqlite3rbu rbu test.db rbu.db + rbu step + list [catch { rbu close } msg] $msg +} {1 {SQLITE_ERROR - cannot update wal mode database}} + finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 170505ca0b..481d01eafc 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -5050,7 +5050,8 @@ static int rbuVfsAccess( */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath, 1); - if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ + if( pDb && pDb->pRbu->eStage==RBU_STAGE_OAL ){ + assert( pDb->pRbu ); if( *pResOut ){ rc = SQLITE_CANTOPEN; }else{ diff --git a/manifest b/manifest index cb3c9fbe3a..0685f4118d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\spattern\sfor\swhich\sthe\sLIKE\soptimization\sdoes\snot\swork\sfor\sa\nnon-TEXT\saffinity.\s\sCase\sfound\sby\sManuel\sRigger. -D 2019-05-08T19:55:24.788 +C Add\sanother\stest\scase\sto\scover\sa\spreviously\suncovered\sbranch\sin\sthe\sRBU\smodule. +D 2019-05-08T21:14:48.819 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -349,7 +349,7 @@ F ext/rbu/rbufault2.test 06e735c002c17802d93debca41f59b027e7429db7de17f2a81318ec F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179 F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d -F ext/rbu/rbumisc.test 0988f5e24df5c38067a97586cb24da68c80409651dedc958dbeec3dfe0c6ad11 +F ext/rbu/rbumisc.test df6201ac3263ac8c68c4f1a4803d8c006c241102eb1d30d8074b0c14e59de335 F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9 F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4 F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9 @@ -361,7 +361,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c 65794a321345f00232ffc113159272d3a6934fd5a65e09df8b86d6bf2485246f +F ext/rbu/sqlite3rbu.c 311fe2c2bc73e2ddb9ee8eb10be35aca90f6074869734671f615270b1a1ce283 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -1825,7 +1825,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 ef0015fde4c87e992ffd3d7dea8586951bdd65ff98d30d436b126b85b1cc9c74 -R 76ed0b382d531a90e41c3e087ed11622 -U drh -Z e9e0cda4b886af13a74fd7aa63325365 +P 740201107ae802c12b678e388ea524db01ad0eb70601c78490ad63eae0fe6cf1 +R ff7ca0f394a79f92ff440e2186231855 +U dan +Z 1ece81ab31ff84ed46fe80ddad119ab3 diff --git a/manifest.uuid b/manifest.uuid index 14f3592fe1..4e997e1826 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -740201107ae802c12b678e388ea524db01ad0eb70601c78490ad63eae0fe6cf1 \ No newline at end of file +30392985612c51d4583a905f8fe766f08cd31b86d0e30a977adc6a6705649e00 \ No newline at end of file From 6f7f5d95f84e7f3fc4196e25736bd9659b1fdf21 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 23:53:50 +0000 Subject: [PATCH 100/132] This is part of the previous check-in that didn't get committed for some reason - probably because I failed to press the "Save" button on the text editor. FossilOrigin-Name: 51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/whereexpr.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 0685f4118d..4f7862aa5b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sanother\stest\scase\sto\scover\sa\spreviously\suncovered\sbranch\sin\sthe\sRBU\smodule. -D 2019-05-08T21:14:48.819 +C This\sis\spart\sof\sthe\sprevious\scheck-in\sthat\sdidn't\sget\scommitted\sfor\ssome\nreason\s-\sprobably\sbecause\sI\sfailed\sto\spress\sthe\s"Save"\sbutton\son\sthe\stext\neditor. +D 2019-05-08T23:53:50.194 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -610,7 +610,7 @@ F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a -F src/whereexpr.c 3a8abba627bffcd930c181bbd78cf5d31c5ef496126d49d0ba94874db16efa33 +F src/whereexpr.c 4219bdd5d310ba6424166d918efef301c21e1b7f6444e964b415c4a5b877a8fe F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1825,7 +1825,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 740201107ae802c12b678e388ea524db01ad0eb70601c78490ad63eae0fe6cf1 -R ff7ca0f394a79f92ff440e2186231855 -U dan -Z 1ece81ab31ff84ed46fe80ddad119ab3 +P 30392985612c51d4583a905f8fe766f08cd31b86d0e30a977adc6a6705649e00 +R 527f1e4ee0ee395de6eadc091c1777d2 +U drh +Z 591de9be94bcabeead88d40aa6c4161a diff --git a/manifest.uuid b/manifest.uuid index 4e997e1826..1ae08995d3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -30392985612c51d4583a905f8fe766f08cd31b86d0e30a977adc6a6705649e00 \ No newline at end of file +51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 39c4ba3c94..f216b848e3 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -262,6 +262,7 @@ static int isLikeOrGlob( zNew[iTo++] = zNew[iFrom]; } zNew[iTo] = 0; + assert( iTo>0 ); /* If the RHS begins with a digit or a +/- sign, then the LHS must be ** an ordinary column (not a virtual table column) with TEXT affinity. @@ -278,7 +279,7 @@ static int isLikeOrGlob( if( sqlite3Isdigit(zNew[0]) || zNew[0]=='-' || zNew[0]=='+' - || (iTo>0 && zNew[iTo-1]=='0'-1) + || zNew[iTo-1]=='0'-1 ){ if( pLeft->op!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT From eb265343a9d10264ba4410dcc8fed2f467ebbb44 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 8 May 2019 23:55:04 +0000 Subject: [PATCH 101/132] Ensure that the sqlite3BtreeLast() interface initializes the *pRes return to zero if the cursor is already sitting on the last entry of the table. FossilOrigin-Name: ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4f7862aa5b..c2b1660846 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C This\sis\spart\sof\sthe\sprevious\scheck-in\sthat\sdidn't\sget\scommitted\sfor\ssome\nreason\s-\sprobably\sbecause\sI\sfailed\sto\spress\sthe\s"Save"\sbutton\son\sthe\stext\neditor. -D 2019-05-08T23:53:50.194 +C Ensure\sthat\sthe\ssqlite3BtreeLast()\sinterface\sinitializes\sthe\s*pRes\sreturn\nto\szero\sif\sthe\scursor\sis\salready\ssitting\son\sthe\slast\sentry\sof\sthe\stable. +D 2019-05-08T23:55:04.921 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -462,7 +462,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 9177613eeef0fdbfcdc3f380e82c5c743a6d506bfa3faaf88077aa7104de53aa +F src/btree.c 0a276df3f912569bb8a5aac31af333dd238a72dc8e506f590555d68b2885f98e F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -1825,7 +1825,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 30392985612c51d4583a905f8fe766f08cd31b86d0e30a977adc6a6705649e00 -R 527f1e4ee0ee395de6eadc091c1777d2 +P 51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c +R 18700b334a433dab3b562877ac4a0a65 U drh -Z 591de9be94bcabeead88d40aa6c4161a +Z f8fe35a5ae505a0883dbd5eaecee59b1 diff --git a/manifest.uuid b/manifest.uuid index 1ae08995d3..031f7c1037 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c \ No newline at end of file +ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 92bafffbd4..2b322122a8 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5294,6 +5294,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ assert( pCur->ix==pCur->pPage->nCell-1 ); assert( pCur->pPage->leaf ); #endif + *pRes = 0; return SQLITE_OK; } From 68feae52a9c5052b10e80a933b6c8998b3bb6715 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 May 2019 11:18:41 +0000 Subject: [PATCH 102/132] Improved error handling for the ".open --hexdb" command of the CLI. FossilOrigin-Name: 4fa831d5cd5861f6a0a8f08a738b2d4d371fb2a788178ce86482c5bba761f9de --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index c2b1660846..b835f636fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\ssqlite3BtreeLast()\sinterface\sinitializes\sthe\s*pRes\sreturn\nto\szero\sif\sthe\scursor\sis\salready\ssitting\son\sthe\slast\sentry\sof\sthe\stable. -D 2019-05-08T23:55:04.921 +C Improved\serror\shandling\sfor\sthe\s".open\s--hexdb"\scommand\sof\sthe\sCLI. +D 2019-05-09T11:18:41.366 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 5470f08809ca5d9ac79f782f8f16d96a4299e584dbc456d8ef4aa6ca0824b5b3 +F src/shell.c.in 5d0e2b03f977a475700c4c535df74e753171d27ec4a50e1a5ec0090357008f05 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c -R 18700b334a433dab3b562877ac4a0a65 +P ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 +R 8e29ce757aa66674b46f1ad295c560b5 U drh -Z f8fe35a5ae505a0883dbd5eaecee59b1 +Z 58b67e014ab5b3e97fafa9cfec65dfaa diff --git a/manifest.uuid b/manifest.uuid index 031f7c1037..adb46ef5c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 \ No newline at end of file +4fa831d5cd5861f6a0a8f08a738b2d4d371fb2a788178ce86482c5bba761f9de \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index fa8554ad76..d4c6019f1f 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3884,8 +3884,8 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; - if( n<=0 ) goto readHexDb_error; - a = sqlite3_malloc( n ); + if( n<0 ) goto readHexDb_error; + a = sqlite3_malloc( n ? n : 1 ); if( a==0 ){ utf8_printf(stderr, "Out of memory!\n"); goto readHexDb_error; @@ -3924,7 +3924,7 @@ static unsigned char *readHexDb(ShellState *p, int *pnData){ return a; readHexDb_error: - if( in!=stdin ){ + if( in!=p->in ){ fclose(in); }else{ while( fgets(zLine, sizeof(zLine), p->in)!=0 ){ @@ -4166,7 +4166,6 @@ static void open_db(ShellState *p, int openFlags){ }else{ aData = readHexDb(p, &nData); if( aData==0 ){ - utf8_printf(stderr, "Error in hexdb input\n"); return; } } From 873b019826a77a1f25f8b2e7a62fac49577a9057 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 11:19:27 +0000 Subject: [PATCH 103/132] Fix a problem in the new code introduced by [658b84d7] causing corruption and other errors to be ignored. FossilOrigin-Name: 7ccf2e7d413adb109c61456a5f46e87d38884801dbaab93297a17e3050014b59 --- manifest | 16 ++--- manifest.uuid | 2 +- src/vdbe.c | 3 +- test/corruptL.test | 142 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c2b1660846..a1dabe9380 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\ssqlite3BtreeLast()\sinterface\sinitializes\sthe\s*pRes\sreturn\nto\szero\sif\sthe\scursor\sis\salready\ssitting\son\sthe\slast\sentry\sof\sthe\stable. -D 2019-05-08T23:55:04.921 +C Fix\sa\sproblem\sin\sthe\snew\scode\sintroduced\sby\s[658b84d7]\scausing\scorruption\sand\sother\serrors\sto\sbe\signored. +D 2019-05-09T11:19:27.227 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,7 +593,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 02d6df64c03e6c69b94d8e53699b0ab4e4d6bc74ef88484b48970864dbf0cce7 +F src/vdbe.c 5612b064d4c5d59efa0be7209ba8b631a534b16cebc63f2899eb887505dfcf2f F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da @@ -765,7 +765,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test 13763e4769eeef308badfcc95dea5d5e00e61a1732a1214a48ff24d3f5db8cbc +F test/corruptL.test b6ea0f657b26a8fe10405a9f5970f94de47fdfcc02fce2a635954aef13e55a88 F test/cost.test 51f4fcaae6e78ad5a57096831259ed6c760e2ac6876836e91c00030fad385b34 F test/count.test cb2e0f934c6eb33670044520748d2ecccd46259c F test/countofview.test e3d4cd6900e4e4f074968ab24b8b87d3671cd624961bef40fd3a6b8f574343cf @@ -1825,7 +1825,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 51d32173ff1f610b5d75a50f20fa1e0e4e22046299869e3b82e0bb446dba890c -R 18700b334a433dab3b562877ac4a0a65 -U drh -Z f8fe35a5ae505a0883dbd5eaecee59b1 +P ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 +R e44f7e65f3b14237b84a8559c540124d +U dan +Z 0f9cf99179363aae6d38e9c8478ef975 diff --git a/manifest.uuid b/manifest.uuid index 031f7c1037..8f3c0024f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ebe4845cd0ffb96b30be3c69eb399d58e93149886bc2fa60a7ebd7b4fbe447a4 \ No newline at end of file +7ccf2e7d413adb109c61456a5f46e87d38884801dbaab93297a17e3050014b59 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index fbcdca851d..e43f2229f2 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4016,7 +4016,8 @@ case OP_SeekGT: { /* jump, in3, group */ VdbeBranchTaken(1,2); goto jump_to_p2; break; }else{ - sqlite3BtreeLast(pC->uc.pCursor, &res); + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); + if( rc!=SQLITE_OK ) goto abort_due_to_error; goto seek_not_found; } }else diff --git a/test/corruptL.test b/test/corruptL.test index 6f129e8408..61b582d0ab 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -866,4 +866,146 @@ do_execsql_test 9.3 { ROLLBACK TO one; } +#------------------------------------------------------------------------- +reset_db +do_test 10.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 180224 pagesize 4096 filename crash-41390d95d613b6.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 00 00 00 04 0e e2 00 0f 96 0f 44 ...............D +| 112: 0f 10 0e e2 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3808: 00 00 2c 14 06 17 15 11 01 41 69 6e 64 65 78 74 ..,......Aindext +| 3824: 41 78 33 74 31 06 43 52 45 41 54 45 20 49 4e 44 Ax3t1.CREATE IND +| 3840: 45 58 20 74 31 78 32 20 4f 4e 20 74 31 28 62 29 EX t1x2 ON t1(b) +| 3856: 32 03 06 17 15 11 01 4d 69 6e 64 65 78 74 31 88 2......Mindext1. +| 3872: 31 74 31 05 43 52 45 41 54 45 20 49 4e 44 45 58 1t1.CREATE INDEX +| 3888: 20 74 31 78 31 20 4f 4e 20 74 31 28 67 2b 68 2c t1x1 ON t1(g+h, +| 3904: 6a 2d 6b 29 50 02 06 17 2b 2b 01 59 74 61 62 6c j-k)P...++.Ytabl +| 3920: 65 73 71 6c 69 74 65 5e 73 65 71 74 65 6e 63 65 esqlite^seqtence +| 3936: 73 71 6c 69 74 65 5f 73 65 71 75 65 6e 63 65 04 sqlite_sequence. +| 3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c CREATE TABLE sql +| 3968: 69 74 65 5f 73 65 71 75 65 6e 63 65 28 6e 61 6d ite_sequence(nam +| 3984: 65 2c 73 65 71 29 68 00 07 17 11 11 01 81 3b 74 e,seq)h.......;t +| 4000: 61 62 6c 65 74 31 74 31 03 43 52 45 41 54 45 20 ablet1t1.CREATE +| 4016: 54 41 42 4c 45 20 74 31 28 61 20 49 4e 54 45 47 TABLE t1(a INTEG +| 4032: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 20 41 ER PRIMARY KEY A +| 4048: 55 54 4f 49 4e 43 52 45 4d 45 4e 54 2c 0a 62 2c UTOINCREMENT,.b, +| 4064: 63 2c 64 2c 65 2c 66 2c 67 2c 68 2c 6a 2c 6b 2c c,d,e,f,g,h,j,k, +| 4080: 6c 2c 6d 2c 6e 2c 6f 2c 70 2c 71 2c 72 2c 73 29 l,m,n,o,p,q,r,s) +| page 2 offset 4096 +| 0: 01 00 00 00 00 01 00 00 10 00 01 00 00 00 00 01 ................ +| 16: 00 00 00 00 02 00 0f f0 00 15 00 00 00 03 02 00 ................ +| 32: 00 00 d9 05 00 00 00 03 02 00 00 00 00 05 00 00 ................ +| 48: 10 03 02 00 00 00 00 05 00 00 00 03 02 00 00 00 ................ +| 64: 00 05 00 00 00 02 62 00 00 00 00 05 00 00 00 03 ......b......... +| 80: 02 00 00 00 00 05 00 00 00 03 02 00 00 00 00 05 ................ +| 96: 00 00 00 03 02 00 00 00 00 05 00 00 00 03 05 00 ................ +| 112: 00 00 03 03 01 00 00 23 02 00 00 4f 00 02 00 00 .......#...O.... +| 128: 10 25 02 00 00 00 00 03 00 00 00 23 02 00 00 00 .%.........#.... +| 144: 00 03 00 00 00 23 02 00 00 00 00 03 00 00 00 23 .....#.........# +| 160: 05 00 08 90 06 05 00 00 00 06 01 ff 00 00 00 03 ................ +| 176: 00 00 00 06 02 00 00 00 00 02 ff 00 00 00 00 00 ................ +| page 3 offset 8192 +| 0: 05 00 00 00 09 0f d0 00 00 00 00 19 0f fb 0f f6 ................ +| 16: 0f f1 10 ec ec e7 0f e2 0f dc 0f d6 0f 00 00 00 ................ +| 1072: 00 97 4c 0a 24 00 ae 00 00 00 00 00 00 00 00 00 ..L.$........... +| 4048: 00 00 00 16 83 39 ff ff ff 14 81 16 00 00 00 12 .....9.......... +| 4064: 81 02 00 00 00 10 6e 00 00 00 0e 5a 00 00 00 0c ......n....Z.... +| 4080: 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F............... +| page 4 offset 12288 +| 1072: 97 4d 32 14 00 ae 00 00 00 00 00 00 00 00 00 00 .M2............. +| 4080: 00 00 00 00 00 00 00 07 01 03 11 02 74 31 00 bd ............t1.. +| page 5 offset 16384 +| 0: fa 0f 7c 00 0a 0f 74 00 0f f9 0f eb 0f dd 0f cf ..|...t......... +| 16: 0f c1 0f b3 0f a4 0e 94 0f 84 0f 74 0f 74 0f 74 ...........t.t.t +| 32: 0f 74 0f 64 0f 00 00 00 00 00 00 00 00 00 00 00 .t.d............ +| 3952: 00 00 00 00 07 05 00 00 00 02 00 be 0f 8c 10 07 ................ +| 3968: ff ff 00 00 07 05 00 00 00 02 00 aa 0f 9b f0 08 ................ +| 3984: c8 00 00 00 37 06 00 00 00 01 00 96 0f ac 00 08 ....7........... +| 4000: 00 00 00 b3 07 15 00 10 00 02 00 82 0f ba 00 07 ................ +| 4016: 00 00 00 06 05 00 00 00 01 6e 0f c8 00 07 00 00 .........n...... +| 4032: 00 06 05 00 00 00 01 5a 03 f6 00 07 00 00 00 06 .......Z........ +| 4048: 05 00 00 00 01 46 0f e4 00 07 00 00 10 06 05 00 .....F.......... +| 4064: 00 00 01 32 10 02 00 07 00 00 00 07 05 00 00 00 ...2............ +| 4080: 01 1d ff ff ff 07 10 00 00 06 05 00 00 00 01 0a ................ +| page 6 offset 20480 +| 624: 00 00 00 00 00 21 97 00 00 00 00 00 00 00 00 00 .....!.......... +| 1120: 00 00 00 00 00 24 57 3e 00 00 00 00 00 00 00 00 .....$W>........ +| 1616: 00 00 00 00 1f 97 00 00 00 00 00 00 00 00 00 00 ................ +| 2112: 00 00 00 1e 97 3d 00 00 00 00 00 00 00 00 00 00 .....=.......... +| 2608: 00 1d 97 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| page 8 offset 28672 +| 1184: 00 00 00 00 00 00 00 00 00 97 4d 1e 13 ff ae 7c ..........M....| +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 ................ +| page 9 offset 32768 +| 256: 0d 01 c0 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| page 10 offset 36864 +| 0: 0d 00 22 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 ................ +| page 12 offset 45056 +| 0: 0d 00 00 00 01 04 30 00 00 00 00 00 00 00 00 00 ......0......... +| page 14 offset 53248 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 96 4d 5a 14 00 00 00 00 00 00 00 00 00 00 00 00 .MZ............. +| page 16 offset 61440 +| 0: 0d 00 00 00 01 04 30 00 04 30 00 00 00 00 00 00 ......0..0...... +| 1072: 97 4d 6e 14 00 ae 7b ff ff ff ff 00 00 00 00 00 .Mn............. +| page 18 offset 69632 +| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................ +| 1072: 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 M............... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................ +| page 20 offset 77824 +| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................ +| 1072: 4d 81 16 14 00 ae 00 00 00 00 00 00 00 00 00 00 M............... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f ................ +| page 22 offset 86016 +| 0: 0d 00 00 00 01 04 2f 00 04 2f 01 00 00 00 00 00 ....../../...... +| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................ +| 1072: 4d 81 2a 14 00 00 00 00 00 00 00 00 00 00 00 00 M.*............. +| page 24 offset 94208 +| 1072: 00 97 4c 0a 14 00 ae 7c 00 00 00 00 00 00 00 00 ..L....|........ +| page 25 offset 98304 +| 1056: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 97 ................ +| 1072: 4d 81 3e 14 00 ae 7c 00 00 18 ff 00 00 00 00 00 M.>...|......... +| page 27 offset 106496 +| 0: 00 00 00 00 00 00 00 12 00 00 00 07 00 00 00 1d ................ +| 16: 00 00 00 09 00 00 00 1f 00 00 00 0b 00 00 00 21 ...............! +| 32: 00 00 00 0d 00 10 00 25 00 00 00 0f 00 00 00 27 .......%.......' +| 48: 00 00 00 11 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| page 32 offset 126976 +| 2512: 00 00 00 00 00 00 00 45 21 00 00 00 00 00 00 00 .......E!....... +| page 35 offset 139264 +| 0: 00 0a 08 44 00 05 02 77 00 0e 11 0a 92 00 00 00 ...D...w........ +| 1120: 00 00 00 00 00 20 97 00 00 00 00 00 00 00 00 00 ..... .......... +| 1616: 00 00 00 00 22 00 00 00 00 00 00 00 00 00 00 00 ................ +| 2608: 00 00 00 97 3d 04 00 00 00 00 00 00 00 00 00 00 ....=........... +| 3104: 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3600: 00 97 3d 04 ae 7c 00 00 00 00 00 00 00 00 00 00 ..=..|.......... +| 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a ................ +| page 36 offset 143360 +| 0: 0a 08 44 00 04 02 00 00 00 00 00 00 00 00 00 00 ..D............. +| 1120: 00 00 00 00 00 2a 97 3e 04 00 00 00 00 00 00 00 .....*.>........ +| 1616: 00 00 00 00 2c 97 3e 00 00 00 00 00 00 00 00 00 ....,.>......... +| 2112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 38 ...............8 +| 2128: 00 00 05 cd 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3600: 00 97 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| page 38 offset 151552 +| 2464: 00 00 00 00 00 00 00 00 00 6e 00 00 00 00 00 00 .........n...... +| page 40 offset 159744 +| 2512: 00 00 00 00 00 00 00 00 82 00 00 00 00 00 00 00 ................ +| page 42 offset 167936 +| 2512: 00 00 00 00 00 00 00 96 00 00 00 00 00 00 00 00 ................ +| page 44 offset 176128 +| 2512: 00 00 00 00 00 00 00 00 aa 00 00 00 00 00 00 00 ................ +| end crash-41390d95d613b6.db +}]} {} + +do_catchsql_test 10.1 { + SELECT * FROM t1 WHERE a<='2019-05-09' ORDER BY a DESC; +} {1 {database disk image is malformed}} + + finish_test From b3e3a5bb5714b10a98212139280aa976a3fbbd4c Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 11:34:31 +0000 Subject: [PATCH 104/132] Avoid reading outside a record buffer when extracting an SQL value in the sqlite_dbdata virtual table code. FossilOrigin-Name: d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25 --- ext/misc/dbdata.c | 101 +++++++++++++++++++++++++--------------------- manifest | 13 +++--- manifest.uuid | 2 +- 3 files changed, 63 insertions(+), 53 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 0e7f7d59cc..88906513a7 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -382,7 +382,10 @@ static int dbdataValueBytes(int eType){ case 7: return 8; default: - return ((eType-12) / 2); + if( eType>0 ){ + return ((eType-12) / 2); + } + return 0; } } @@ -390,55 +393,61 @@ static int dbdataValueBytes(int eType){ ** Load a value of type eType from buffer pData and use it to set the ** result of context object pCtx. */ -static void dbdataValue(sqlite3_context *pCtx, int eType, u8 *pData){ - switch( eType ){ - case 0: - case 10: - case 11: - sqlite3_result_null(pCtx); - break; - - case 8: - sqlite3_result_int(pCtx, 0); - break; - case 9: - sqlite3_result_int(pCtx, 1); - break; - - case 1: case 2: case 3: case 4: case 5: case 6: case 7: { - sqlite3_uint64 v = (signed char)pData[0]; - pData++; - switch( eType ){ - case 7: - case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; - case 4: v = (v<<8) + pData[0]; pData++; - case 3: v = (v<<8) + pData[0]; pData++; - case 2: v = (v<<8) + pData[0]; pData++; +static void dbdataValue( + sqlite3_context *pCtx, + int eType, + u8 *pData, + int nData +){ + if( eType>=0 && dbdataValueBytes(eType)<=nData ){ + switch( eType ){ + case 0: + case 10: + case 11: + sqlite3_result_null(pCtx); + break; + + case 8: + sqlite3_result_int(pCtx, 0); + break; + case 9: + sqlite3_result_int(pCtx, 1); + break; + + case 1: case 2: case 3: case 4: case 5: case 6: case 7: { + sqlite3_uint64 v = (signed char)pData[0]; + pData++; + switch( eType ){ + case 7: + case 6: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 5: v = (v<<16) + (pData[0]<<8) + pData[1]; pData += 2; + case 4: v = (v<<8) + pData[0]; pData++; + case 3: v = (v<<8) + pData[0]; pData++; + case 2: v = (v<<8) + pData[0]; pData++; + } + + if( eType==7 ){ + double r; + memcpy(&r, &v, sizeof(r)); + sqlite3_result_double(pCtx, r); + }else{ + sqlite3_result_int64(pCtx, (sqlite3_int64)v); + } + break; } - - if( eType==7 ){ - double r; - memcpy(&r, &v, sizeof(r)); - sqlite3_result_double(pCtx, r); - }else{ - sqlite3_result_int64(pCtx, (sqlite3_int64)v); - } - break; - } - - default: { - int n = ((eType-12) / 2); - if( eType % 2 ){ - sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT); - }else{ - sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); + + default: { + int n = ((eType-12) / 2); + if( eType % 2 ){ + sqlite3_result_text(pCtx, (const char*)pData, n, SQLITE_TRANSIENT); + }else{ + sqlite3_result_blob(pCtx, pData, n, SQLITE_TRANSIENT); + } } } } } - /* ** Move an sqlite_dbdata or sqlite_dbptr cursor to the next entry. */ @@ -728,7 +737,9 @@ static int dbdataColumn( }else{ sqlite3_int64 iType; dbdataGetVarint(pCsr->pHdrPtr, &iType); - dbdataValue(ctx, iType, pCsr->pPtr); + dbdataValue( + ctx, iType, pCsr->pPtr, &pCsr->pRec[pCsr->nRec] - pCsr->pPtr + ); } break; } diff --git a/manifest b/manifest index b2fada1f60..1fc0540f89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\saccidental\sfork\sin\strunk. -D 2019-05-09T11:21:32.067 +C Avoid\sreading\soutside\sa\srecord\sbuffer\swhen\sextracting\san\sSQL\svalue\sin\sthe\ssqlite_dbdata\svirtual\stable\scode. +D 2019-05-09T11:34:31.409 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 1b3751b02d8f575d25c6bda358670d2e39ace368a0d05595989c308a10c615f6 +F ext/misc/dbdata.c 1d3d1ebd23d3e4e5debbc54719376781e146626c2ee0b989b412b1a9c8ccdd37 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -1825,8 +1825,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 7ccf2e7d413adb109c61456a5f46e87d38884801dbaab93297a17e3050014b59 4fa831d5cd5861f6a0a8f08a738b2d4d371fb2a788178ce86482c5bba761f9de -R 1ba7996ce03dd9a1187260e95804fc29 -T +closed 4fa831d5cd5861f6a0a8f08a738b2d4d371fb2a788178ce86482c5bba761f9de +P ec9373031d76b34163a45d0ed05e43c0c9d585c8d47aa255f670340673bc7875 +R 792bbcbe6e2a990555a162dba387f00d U dan -Z e19c180b1a7fc00850ba36320f2fd4c8 +Z f6d6e605cd200b1a74018499a0dcfaa6 diff --git a/manifest.uuid b/manifest.uuid index 44520985b9..5c57049f08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec9373031d76b34163a45d0ed05e43c0c9d585c8d47aa255f670340673bc7875 \ No newline at end of file +d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25 \ No newline at end of file From 13b876773cea566018aa76c820971709445c8ec5 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 11:45:21 +0000 Subject: [PATCH 105/132] Fix a problem with running the ".recover" command on a database that is zero pages in size. FossilOrigin-Name: 47fa65343e46c7782a173174952c637c5621e16229ece258dc7e7a556683ca0c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 +- test/recover.test | 4 ++++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1fc0540f89..96481ec49b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sreading\soutside\sa\srecord\sbuffer\swhen\sextracting\san\sSQL\svalue\sin\sthe\ssqlite_dbdata\svirtual\stable\scode. -D 2019-05-09T11:34:31.409 +C Fix\sa\sproblem\swith\srunning\sthe\s".recover"\scommand\son\sa\sdatabase\sthat\sis\szero\spages\sin\ssize. +D 2019-05-09T11:45:21.441 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 5d0e2b03f977a475700c4c535df74e753171d27ec4a50e1a5ec0090357008f05 +F src/shell.c.in 517b3e2aa15329f391bde567c5a4a5aa8d1eeb9d12f175cbc4b89a9dc136a4d3 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1230,7 +1230,7 @@ F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 -F test/recover.test 4c45b1519c11c6d10cc28bced260e2a18f3967fc6abccaace44af6c22b30280c +F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 @@ -1825,7 +1825,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 ec9373031d76b34163a45d0ed05e43c0c9d585c8d47aa255f670340673bc7875 -R 792bbcbe6e2a990555a162dba387f00d +P d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25 +R 4c080fc5e9ab944c47b4a994674f6f12 U dan -Z f6d6e605cd200b1a74018499a0dcfaa6 +Z 26f5a39683d1a25b78fcdb707e769b6d diff --git a/manifest.uuid b/manifest.uuid index 5c57049f08..e1ca85ea2b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25 \ No newline at end of file +47fa65343e46c7782a173174952c637c5621e16229ece258dc7e7a556683ca0c \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index d4c6019f1f..8edf33f381 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6621,7 +6621,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ "WITH pages(i, maxlen) AS (" " SELECT page_count, (" " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=page_count" - " ) FROM pragma_page_count" + " ) FROM pragma_page_count WHERE page_count>0" " UNION ALL" " SELECT i-1, (" " SELECT max(field+1) FROM sqlite_dbdata WHERE pgno=i-1" diff --git a/test/recover.test b/test/recover.test index 75360bc86b..469c43b115 100644 --- a/test/recover.test +++ b/test/recover.test @@ -127,4 +127,8 @@ do_recover_test 2.4.1 { 2 2 3 {} 8 9 7 } +#------------------------------------------------------------------------- +reset_db +do_recover_test 3.0 + finish_test From 9877965f56dd0391242dab7617f2d8f06f3b4549 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 14:15:19 +0000 Subject: [PATCH 106/132] Have ".recover" handle cases where the sqlite_master table contains malformed SQL statements. FossilOrigin-Name: e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 96481ec49b..4b83c71c58 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\srunning\sthe\s".recover"\scommand\son\sa\sdatabase\sthat\sis\szero\spages\sin\ssize. -D 2019-05-09T11:45:21.441 +C Have\s".recover"\shandle\scases\swhere\sthe\ssqlite_master\stable\scontains\smalformed\sSQL\sstatements. +D 2019-05-09T14:15:19.691 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 517b3e2aa15329f391bde567c5a4a5aa8d1eeb9d12f175cbc4b89a9dc136a4d3 +F src/shell.c.in f5d3a1f3f99a198bb8335461f1426eec72092786c20f4937d842b6f4988a8f1a F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 d99bb0c11d62f629bf59da037827af73a9b814e65815006e0cbca1bc41f42e25 -R 4c080fc5e9ab944c47b4a994674f6f12 +P 47fa65343e46c7782a173174952c637c5621e16229ece258dc7e7a556683ca0c +R be79b692a16f80cd3224bf9c098d5fd5 U dan -Z 26f5a39683d1a25b78fcdb707e769b6d +Z 9d48ce941293959626321b38e8342e0f diff --git a/manifest.uuid b/manifest.uuid index e1ca85ea2b..5faf9c5ba6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47fa65343e46c7782a173174952c637c5621e16229ece258dc7e7a556683ca0c \ No newline at end of file +e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 8edf33f381..1fe216557e 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6388,7 +6388,7 @@ static RecoverTable *recoverNewTable( finished: sqlite3_close(dbtmp); *pRc = rc; - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_OK || (pTab && pTab->zQuoted==0) ){ recoverFreeTable(pTab); pTab = 0; } @@ -6680,8 +6680,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ /* Figure out if an orphan table will be required. And if so, how many ** user columns it should contain */ shellPrepare(pState->db, &rc, - "SELECT coalesce(max(maxlen), -2) FROM recovery.map" - " WHERE root>1 AND root NOT IN (SELECT rootpage FROM recovery.schema)" + "SELECT coalesce(max(maxlen), -2) FROM recovery.map WHERE root>1" , &pLoop ); if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pLoop) ){ @@ -6689,7 +6688,6 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } shellFinalize(&rc, pLoop); pLoop = 0; - pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan); shellPrepare(pState->db, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages @@ -6716,7 +6714,13 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ pTab = recoverFindTable(pState, &rc, iRoot, bIntkey, nCol, &bNoop); if( bNoop || rc ) continue; - if( pTab==0 ) pTab = pOrphan; + if( pTab==0 ){ + if( pOrphan==0 ){ + pOrphan = recoverOrphanTable(pState, &rc, zLostAndFound, nOrphan); + } + pTab = pOrphan; + if( pTab==0 ) break; + } if( 0==sqlite3_stricmp(pTab->zQuoted, "'sqlite_sequence'") ){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); From e216ae0a3e334f6ca51ca0d1d11cf07c380dd0ea Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 15:07:46 +0000 Subject: [PATCH 107/132] Fix further buffer overreads triggered by passing corrupt records to the sqlite_dbdata module. FossilOrigin-Name: dbc6a9f7f67256dea96d3245e7bec145ba65d64adf322e18f1f3ac9556b4e0b6 --- ext/misc/dbdata.c | 163 ++++++++++++++++++++++++++-------------------- manifest | 12 ++-- manifest.uuid | 2 +- 3 files changed, 100 insertions(+), 77 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 88906513a7..4cbb96691f 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -495,6 +495,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ int iHdr; int U, X; int nLocal; + int bNextPage = 0; switch( pCsr->aPage[iOff] ){ case 0x02: @@ -512,82 +513,104 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ } if( pCsr->iCell>=pCsr->nCell ){ + bNextPage = 1; + }else{ + + iOff += 8 + nPointer + pCsr->iCell*2; + if( iOff>pCsr->nPage ){ + bNextPage = 1; + }else{ + iOff = get_uint16(&pCsr->aPage[iOff]); + } + + /* For an interior node cell, skip past the child-page number */ + iOff += nPointer; + + /* Load the "byte of payload including overflow" field */ + if( bNextPage || iOff>pCsr->nPage ){ + bNextPage = 1; + }else{ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload); + } + + /* If this is a leaf intkey cell, load the rowid */ + if( bHasRowid && !bNextPage && iOffnPage ){ + iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); + } + + /* Figure out how much data to read from the local page */ + U = pCsr->nPage; + if( bHasRowid ){ + X = U-35; + }else{ + X = ((U-12)*64/255)-23; + } + if( nPayload<=X ){ + nLocal = nPayload; + }else{ + int M, K; + M = ((U-12)*32/255)-23; + K = M+((nPayload-M)%(U-4)); + if( K<=X ){ + nLocal = K; + }else{ + nLocal = M; + } + } + + if( bNextPage || nLocal+iOff>pCsr->nPage ){ + bNextPage = 1; + }else{ + + /* Allocate space for payload. And a bit more to catch small buffer + ** overruns caused by attempting to read a varint or similar from + ** near the end of a corrupt record. */ + pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+100); + if( pCsr->pRec==0 ) return SQLITE_NOMEM; + memset(pCsr->pRec, 0, nPayload+100); + pCsr->nRec = nPayload; + + /* Load the nLocal bytes of payload */ + memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); + iOff += nLocal; + + /* Load content from overflow pages */ + if( nPayload>nLocal ){ + sqlite3_int64 nRem = nPayload - nLocal; + unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); + while( nRem>0 ){ + u8 *aOvfl = 0; + int nOvfl = 0; + int nCopy; + rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); + assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); + if( rc!=SQLITE_OK ) return rc; + + nCopy = U-4; + if( nCopy>nRem ) nCopy = nRem; + memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); + nRem -= nCopy; + + pgnoOvfl = get_uint32(aOvfl); + sqlite3_free(aOvfl); + } + } + + iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); + pCsr->nHdr = nHdr; + pCsr->pHdrPtr = &pCsr->pRec[iHdr]; + pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; + pCsr->iField = (bHasRowid ? -1 : 0); + } + } + + if( bNextPage ){ sqlite3_free(pCsr->aPage); pCsr->aPage = 0; if( pCsr->bOnePage ) return SQLITE_OK; pCsr->iPgno++; continue; } - - iOff += 8 + nPointer + pCsr->iCell*2; - iOff = get_uint16(&pCsr->aPage[iOff]); - - /* For an interior node cell, skip past the child-page number */ - iOff += nPointer; - - /* Load the "byte of payload including overflow" field */ - iOff += dbdataGetVarint(&pCsr->aPage[iOff], &nPayload); - - /* If this is a leaf intkey cell, load the rowid */ - if( bHasRowid ){ - iOff += dbdataGetVarint(&pCsr->aPage[iOff], &pCsr->iIntkey); - } - - /* Allocate space for payload */ - pCsr->pRec = (u8*)sqlite3_malloc64(nPayload); - if( pCsr->pRec==0 ) return SQLITE_NOMEM; - pCsr->nRec = nPayload; - - U = pCsr->nPage; - if( bHasRowid ){ - X = U-35; - }else{ - X = ((U-12)*64/255)-23; - } - if( nPayload<=X ){ - nLocal = nPayload; - }else{ - int M, K; - M = ((U-12)*32/255)-23; - K = M+((nPayload-M)%(U-4)); - if( K<=X ){ - nLocal = K; - }else{ - nLocal = M; - } - } - - /* Load the nLocal bytes of payload */ - memcpy(pCsr->pRec, &pCsr->aPage[iOff], nLocal); - iOff += nLocal; - - /* Load content from overflow pages */ - if( nPayload>nLocal ){ - sqlite3_int64 nRem = nPayload - nLocal; - unsigned int pgnoOvfl = get_uint32(&pCsr->aPage[iOff]); - while( nRem>0 ){ - u8 *aOvfl = 0; - int nOvfl = 0; - int nCopy; - rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); - assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); - if( rc!=SQLITE_OK ) return rc; - - nCopy = U-4; - if( nCopy>nRem ) nCopy = nRem; - memcpy(&pCsr->pRec[nPayload-nRem], &aOvfl[4], nCopy); - nRem -= nCopy; - - pgnoOvfl = get_uint32(aOvfl); - sqlite3_free(aOvfl); - } - } - - iHdr = dbdataGetVarint(pCsr->pRec, &nHdr); - pCsr->nHdr = nHdr; - pCsr->pHdrPtr = &pCsr->pRec[iHdr]; - pCsr->pPtr = &pCsr->pRec[pCsr->nHdr]; - pCsr->iField = (bHasRowid ? -1 : 0); }else{ pCsr->iField++; if( pCsr->iField>0 ){ diff --git a/manifest b/manifest index 4b83c71c58..83937eb82e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\s".recover"\shandle\scases\swhere\sthe\ssqlite_master\stable\scontains\smalformed\sSQL\sstatements. -D 2019-05-09T14:15:19.691 +C Fix\sfurther\sbuffer\soverreads\striggered\sby\spassing\scorrupt\srecords\sto\sthe\ssqlite_dbdata\smodule. +D 2019-05-09T15:07:46.363 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 1d3d1ebd23d3e4e5debbc54719376781e146626c2ee0b989b412b1a9c8ccdd37 +F ext/misc/dbdata.c db2674c3a5913a784a75a11d1e7905b14f6b81de1879d6e5fde4f0887f08decf F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -1825,7 +1825,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 47fa65343e46c7782a173174952c637c5621e16229ece258dc7e7a556683ca0c -R be79b692a16f80cd3224bf9c098d5fd5 +P e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2 +R 32f00eab291c2d8cfb2d8bb909898960 U dan -Z 9d48ce941293959626321b38e8342e0f +Z f672687cf39d09ecc13e261b2e491ea1 diff --git a/manifest.uuid b/manifest.uuid index 5faf9c5ba6..85b050179e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2 \ No newline at end of file +dbc6a9f7f67256dea96d3245e7bec145ba65d64adf322e18f1f3ac9556b4e0b6 \ No newline at end of file From 9c34bc0ad53a05cb4ea4b59e64e956564404b5c7 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 15:51:27 +0000 Subject: [PATCH 108/132] Fix another corruption related buffer overread in the sqlite_dbdata module. FossilOrigin-Name: 5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a --- ext/misc/dbdata.c | 52 +++++++++++++++++++++++++++++------------------ manifest | 12 +++++------ manifest.uuid | 2 +- 3 files changed, 39 insertions(+), 27 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 4cbb96691f..d73f4f1a28 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -278,6 +278,10 @@ static void dbdataResetCursor(DbdataCursor *pCsr){ pCsr->iCell = 0; pCsr->iField = 0; pCsr->bOnePage = 0; + sqlite3_free(pCsr->aPage); + sqlite3_free(pCsr->pRec); + pCsr->pRec = 0; + pCsr->aPage = 0; } /* @@ -459,6 +463,7 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ while( 1 ){ int rc; int iOff = (pCsr->iPgno==1 ? 100 : 0); + int bNextPage = 0; if( pCsr->aPage==0 ){ while( 1 ){ @@ -495,7 +500,6 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ int iHdr; int U, X; int nLocal; - int bNextPage = 0; switch( pCsr->aPage[iOff] ){ case 0x02: @@ -603,32 +607,37 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ pCsr->iField = (bHasRowid ? -1 : 0); } } - - if( bNextPage ){ - sqlite3_free(pCsr->aPage); - pCsr->aPage = 0; - if( pCsr->bOnePage ) return SQLITE_OK; - pCsr->iPgno++; - continue; - } }else{ pCsr->iField++; if( pCsr->iField>0 ){ sqlite3_int64 iType; - pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType); - pCsr->pPtr += dbdataValueBytes(iType); + if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){ + bNextPage = 1; + }else{ + pCsr->pHdrPtr += dbdataGetVarint(pCsr->pHdrPtr, &iType); + pCsr->pPtr += dbdataValueBytes(iType); + } } } - if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ - return SQLITE_OK; + if( bNextPage ){ + sqlite3_free(pCsr->aPage); + sqlite3_free(pCsr->pRec); + pCsr->aPage = 0; + pCsr->pRec = 0; + if( pCsr->bOnePage ) return SQLITE_OK; + pCsr->iPgno++; + }else{ + if( pCsr->iField<0 || pCsr->pHdrPtr<&pCsr->pRec[pCsr->nHdr] ){ + return SQLITE_OK; + } + + /* Advance to the next cell. The next iteration of the loop will load + ** the record and so on. */ + sqlite3_free(pCsr->pRec); + pCsr->pRec = 0; + pCsr->iCell++; } - - /* Advance to the next cell. The next iteration of the loop will load - ** the record and so on. */ - sqlite3_free(pCsr->pRec); - pCsr->pRec = 0; - pCsr->iCell++; } } @@ -737,9 +746,12 @@ static int dbdataColumn( iOff += 8; }else{ iOff += 12 + pCsr->iCell*2; + if( iOff>pCsr->nPage ) return SQLITE_OK; iOff = get_uint16(&pCsr->aPage[iOff]); } - sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff])); + if( iOff<=pCsr->nPage ){ + sqlite3_result_int64(ctx, get_uint32(&pCsr->aPage[iOff])); + } break; } } diff --git a/manifest b/manifest index 83937eb82e..bde30235f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfurther\sbuffer\soverreads\striggered\sby\spassing\scorrupt\srecords\sto\sthe\ssqlite_dbdata\smodule. -D 2019-05-09T15:07:46.363 +C Fix\sanother\scorruption\srelated\sbuffer\soverread\sin\sthe\ssqlite_dbdata\smodule. +D 2019-05-09T15:51:27.509 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c db2674c3a5913a784a75a11d1e7905b14f6b81de1879d6e5fde4f0887f08decf +F ext/misc/dbdata.c e2b007604b58a6f2d10b247c4b381cab1d20a530165bc49474b11e48fe680877 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -1825,7 +1825,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 e736da9c18fad138c5502d354c3553373cba15358b69e44b257f60def59422e2 -R 32f00eab291c2d8cfb2d8bb909898960 +P dbc6a9f7f67256dea96d3245e7bec145ba65d64adf322e18f1f3ac9556b4e0b6 +R 125e456f1f71a5717f889e188e54ba04 U dan -Z f672687cf39d09ecc13e261b2e491ea1 +Z c2cff423821faf29bb80557b4a1985e5 diff --git a/manifest.uuid b/manifest.uuid index 85b050179e..18f9e77132 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbc6a9f7f67256dea96d3245e7bec145ba65d64adf322e18f1f3ac9556b4e0b6 \ No newline at end of file +5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a \ No newline at end of file From 5ad1251a60ae792b58de473a0bd22e67224ea3ec Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 May 2019 16:22:51 +0000 Subject: [PATCH 109/132] Improved debugging output from the OP_MakeRecord opcode. FossilOrigin-Name: ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bde30235f2..df8dca63d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\scorruption\srelated\sbuffer\soverread\sin\sthe\ssqlite_dbdata\smodule. -D 2019-05-09T15:51:27.509 +C Improved\sdebugging\soutput\sfrom\sthe\sOP_MakeRecord\sopcode. +D 2019-05-09T16:22:51.204 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,7 +593,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 5612b064d4c5d59efa0be7209ba8b631a534b16cebc63f2899eb887505dfcf2f +F src/vdbe.c d4efd6e5ecff8eeef280ce5d622dc2c0cfe085014e5813401b346517574adb18 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da @@ -1825,7 +1825,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 dbc6a9f7f67256dea96d3245e7bec145ba65d64adf322e18f1f3ac9556b4e0b6 -R 125e456f1f71a5717f889e188e54ba04 -U dan -Z c2cff423821faf29bb80557b4a1985e5 +P 5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a +R 94a11799ce99547c8388638d55d2efb8 +U drh +Z 61ac47a2d0ae07669269cf3a1070857c diff --git a/manifest.uuid b/manifest.uuid index 18f9e77132..52e69a97db 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a \ No newline at end of file +ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e43f2229f2..28916100df 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2882,7 +2882,10 @@ case OP_MakeRecord: { if( zAffinity ){ pRec = pData0; do{ - applyAffinity(pRec++, *(zAffinity++), encoding); + applyAffinity(pRec, zAffinity[0], encoding); + REGISTER_TRACE((int)(pRec-aMem), pRec); + zAffinity++; + pRec++; assert( zAffinity[0]==0 || pRec<=pLast ); }while( zAffinity[0] ); } From f6099e9b401438b24bf273229c6f0f872cb46cee Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 16:57:39 +0000 Subject: [PATCH 110/132] Avoid long delays that can occur when ".recover"ing data from a database with a corrupt freelist. FossilOrigin-Name: 20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index df8dca63d0..18555bfa0a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdebugging\soutput\sfrom\sthe\sOP_MakeRecord\sopcode. -D 2019-05-09T16:22:51.204 +C Avoid\slong\sdelays\sthat\scan\soccur\swhen\s".recover"ing\sdata\sfrom\sa\sdatabase\swith\sa\scorrupt\sfreelist. +D 2019-05-09T16:57:39.190 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in f5d3a1f3f99a198bb8335461f1426eec72092786c20f4937d842b6f4988a8f1a +F src/shell.c.in 6aa1d26eb46ec11ed1ca300e425e7a0d36f915ca94f07f6e47f13d390e897823 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 5cd728fb6b3a70f795306d4d6e12151a4de327f801733a8558139e3cd76fe66a -R 94a11799ce99547c8388638d55d2efb8 -U drh -Z 61ac47a2d0ae07669269cf3a1070857c +P ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885 +R 6e5edbee3c41d65385191dd600b1b4bf +U dan +Z 90af5c9a4f9287285acd46f3e2e8c7ab diff --git a/manifest.uuid b/manifest.uuid index 52e69a97db..7a6c89caea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885 \ No newline at end of file +20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 1fe216557e..78f1cd9df0 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6579,7 +6579,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " FROM trunk WHERE x>0" ")," "freelist(data, n, freepgno) AS (" - " SELECT data, shell_int32(data, 1)-1, t.pgno " + " SELECT data, min(16384, shell_int32(data, 1)-1), t.pgno " " FROM trunk t, sqlite_dbpage s WHERE s.pgno=t.pgno" " UNION ALL" " SELECT data, n-1, shell_int32(data, 2+n) " From 6bab6f2b4d4acc11ed8b4f420b84bcdc7d95799c Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 May 2019 17:10:30 +0000 Subject: [PATCH 111/132] Disable the optimization where a REAL value with no fractional part is stored as an INTEGER when the integer uses as much space as the real value it proposes to stand in for (8 bytes). This avoids corner cases of comparing integers against real values that are beyond the resolution of an IEEE 754 double. Fix for ticket [6c1d3febc00b22d457c78c2] FossilOrigin-Name: 9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbeaux.c | 11 +++++++++++ test/select3.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 18555bfa0a..90f70486fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\slong\sdelays\sthat\scan\soccur\swhen\s".recover"ing\sdata\sfrom\sa\sdatabase\swith\sa\scorrupt\sfreelist. -D 2019-05-09T16:57:39.190 +C Disable\sthe\soptimization\swhere\sa\sREAL\svalue\swith\sno\sfractional\spart\nis\sstored\sas\san\sINTEGER\swhen\sthe\sinteger\suses\sas\smuch\sspace\sas\sthe\sreal\nvalue\sit\sproposes\sto\sstand\sin\sfor\s(8\sbytes).\s\sThis\savoids\scorner\scases\nof\scomparing\sintegers\sagainst\sreal\svalues\sthat\sare\sbeyond\sthe\sresolution\nof\san\sIEEE\s754\sdouble.\s\sFix\sfor\sticket\s[6c1d3febc00b22d457c78c2] +D 2019-05-09T17:10:30.104 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -597,7 +597,7 @@ F src/vdbe.c d4efd6e5ecff8eeef280ce5d622dc2c0cfe085014e5813401b346517574adb18 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da -F src/vdbeaux.c f9fb1f71e216850267744fde8a6a0b2d3822235d6f85568af368be4722e8da13 +F src/vdbeaux.c d444f4a3ff9c571965329a186701a57fe445e4c3f4c42f87402aca75386ba358 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191 F src/vdbemem.c b76b42ac9d6a36fc55a0797929fc94cc33e1334eea2792f5ee1eef868ce13320 F src/vdbesort.c 66592d478dbb46f19aed0b42222325eadb84deb40a90eebe25c6e7c1d8468f47 @@ -1275,7 +1275,7 @@ F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2f F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 F test/select1.test 7d41f354998524070317207d4e2b68e725e4cf14a57835fc746d4bea686a8714 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 -F test/select3.test 2ce595f8fb8e2ac10071d3b4e424cadd4634a054 +F test/select3.test 3905450067c28766bc83ee397f6d87342de868baa60f2bcfd00f286dfbd62cb9 F test/select4.test 5389d9895968d1196c457d59b3ee6515d771d328 F test/select5.test df9ec0d218cedceb4fe7b63262025b547b50a55e59148c6f40b60ca25f1d4546 F test/select6.test 39eac4a5c03650b2b473c532882273283ee8b7a0 @@ -1825,7 +1825,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 ac790729d9c8f8612936bab56dca6061408007bc2150ac8c7089132403d7f885 -R 6e5edbee3c41d65385191dd600b1b4bf -U dan -Z 90af5c9a4f9287285acd46f3e2e8c7ab +P 20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630 +R 1e923a6ef9e14ab60fd1515804aac862 +U drh +Z c06fe0d1d976fd970296d42fc604ced0 diff --git a/manifest.uuid b/manifest.uuid index 7a6c89caea..32f36ff730 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630 \ No newline at end of file +9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a96f195573..ec8f6b9955 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3422,6 +3422,8 @@ int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ /* ** Return the serial-type for the value stored in pMem. +** +** This routine might convert a large MEM_IntReal value into MEM_Real. */ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ int flags = pMem->flags; @@ -3458,6 +3460,15 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ if( u<=2147483647 ){ *pLen = 4; return 4; } if( u<=MAX_6BYTE ){ *pLen = 6; return 5; } *pLen = 8; + if( flags&MEM_IntReal ){ + /* If the value is IntReal and is going to take up 8 bytes to store + ** as an integer, then we might as well make it an 8-byte floating + ** point value */ + pMem->u.r = (double)pMem->u.i; + pMem->flags &= ~MEM_IntReal; + pMem->flags |= MEM_Real; + return 7; + } return 6; } if( flags&MEM_Real ){ diff --git a/test/select3.test b/test/select3.test index b5dbef5fb4..e15464ff5a 100644 --- a/test/select3.test +++ b/test/select3.test @@ -261,4 +261,49 @@ do_test select3-8.2 { } } {real} +# 2019-05-09 ticket https://www.sqlite.org/src/tktview/6c1d3febc00b22d457c7 +# +unset -nocomplain x +foreach {id x} { + 100 127 + 101 128 + 102 -127 + 103 -128 + 104 -129 + 110 32767 + 111 32768 + 112 -32767 + 113 -32768 + 114 -32769 + 120 2147483647 + 121 2147483648 + 122 -2147483647 + 123 -2147483648 + 124 -2147483649 + 130 140737488355327 + 131 140737488355328 + 132 -140737488355327 + 133 -140737488355328 + 134 -140737488355329 + 140 9223372036854775807 + 141 -9223372036854775807 + 142 -9223372036854775808 + 143 9223372036854775806 + 144 9223372036854775805 + 145 -9223372036854775806 + 146 -9223372036854775805 + +} { + set x [expr {$x+0}] + do_execsql_test select3-8.$id { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1 (c0, c1 REAL PRIMARY KEY); + INSERT INTO t1(c0, c1) VALUES (0, $x), (0, 0); + UPDATE t1 SET c0 = NULL; + UPDATE OR REPLACE t1 SET c1 = 1; + SELECT DISTINCT * FROM t1 WHERE (t1.c0 IS NULL); + PRAGMA integrity_check; + } {{} 1.0 ok} +} + finish_test From 4d2175613f4eb065482a514edb34d2a7604b84a7 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 17:54:27 +0000 Subject: [PATCH 112/132] Fix a crash in the sqlite_dbdata module that could occur if a pointer within an overflow chain in a corrupt database pointed past the end of the db. FossilOrigin-Name: 3eae4e301e3e4bcf14e96066f77be1434c5d4b3daadb10153cd36382589ac128 --- ext/misc/dbdata.c | 3 ++- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index d73f4f1a28..60c2296c91 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -587,8 +587,9 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ int nOvfl = 0; int nCopy; rc = dbdataLoadPage(pCsr, pgnoOvfl, &aOvfl, &nOvfl); - assert( rc!=SQLITE_OK || nOvfl==pCsr->nPage ); + assert( rc!=SQLITE_OK || aOvfl==0 || nOvfl==pCsr->nPage ); if( rc!=SQLITE_OK ) return rc; + if( aOvfl==0 ) break; nCopy = U-4; if( nCopy>nRem ) nCopy = nRem; diff --git a/manifest b/manifest index 90f70486fb..8808e2eda8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\soptimization\swhere\sa\sREAL\svalue\swith\sno\sfractional\spart\nis\sstored\sas\san\sINTEGER\swhen\sthe\sinteger\suses\sas\smuch\sspace\sas\sthe\sreal\nvalue\sit\sproposes\sto\sstand\sin\sfor\s(8\sbytes).\s\sThis\savoids\scorner\scases\nof\scomparing\sintegers\sagainst\sreal\svalues\sthat\sare\sbeyond\sthe\sresolution\nof\san\sIEEE\s754\sdouble.\s\sFix\sfor\sticket\s[6c1d3febc00b22d457c78c2] -D 2019-05-09T17:10:30.104 +C Fix\sa\scrash\sin\sthe\ssqlite_dbdata\smodule\sthat\scould\soccur\sif\sa\spointer\swithin\san\soverflow\schain\sin\sa\scorrupt\sdatabase\spointed\spast\sthe\send\sof\sthe\sdb. +D 2019-05-09T17:54:27.219 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c e2b007604b58a6f2d10b247c4b381cab1d20a530165bc49474b11e48fe680877 +F ext/misc/dbdata.c 4b73a0a5218a411752441896b68252ba3ced4d452e7dd419fdb3b92ae6ecada0 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -1825,7 +1825,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 20f06bf2e659212a68dcf138e444da7bd4220548ec15a97cfd7eb82e028b3630 -R 1e923a6ef9e14ab60fd1515804aac862 -U drh -Z c06fe0d1d976fd970296d42fc604ced0 +P 9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a +R 3d82445208a5a3c73a72b531756f0e8c +U dan +Z a691bf3746dae50fcaa6578b32c34fe1 diff --git a/manifest.uuid b/manifest.uuid index 32f36ff730..6c26510299 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a \ No newline at end of file +3eae4e301e3e4bcf14e96066f77be1434c5d4b3daadb10153cd36382589ac128 \ No newline at end of file From 0a0536ab0faa89601c2bf14bc192746fc23d09d1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 9 May 2019 18:13:30 +0000 Subject: [PATCH 113/132] Make the ".schema" command in the CLI resistant to corrupt database files. FossilOrigin-Name: f22c7e229ea4626c5268d61de3964521cf6a2735290cbd1518d68731ba6cca90 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 ++ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8808e2eda8..c0104c17a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sin\sthe\ssqlite_dbdata\smodule\sthat\scould\soccur\sif\sa\spointer\swithin\san\soverflow\schain\sin\sa\scorrupt\sdatabase\spointed\spast\sthe\send\sof\sthe\sdb. -D 2019-05-09T17:54:27.219 +C Make\sthe\s".schema"\scommand\sin\sthe\sCLI\sresistant\sto\scorrupt\sdatabase\sfiles. +D 2019-05-09T18:13:30.290 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 6aa1d26eb46ec11ed1ca300e425e7a0d36f915ca94f07f6e47f13d390e897823 +F src/shell.c.in 332af8613687d1fcf89ff072c2dfecda74b260a54f850230fc82d6757a3a4904 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 9b0915272f4d4052aa31e9297424a7db9a0234b676e8e2a44c3f2dc54236705a -R 3d82445208a5a3c73a72b531756f0e8c -U dan -Z a691bf3746dae50fcaa6578b32c34fe1 +P 3eae4e301e3e4bcf14e96066f77be1434c5d4b3daadb10153cd36382589ac128 +R bb866c6c75a817d20565e49f7d81970f +U drh +Z 706d1f89fe233a2fdcafaa2e0adbab1c diff --git a/manifest.uuid b/manifest.uuid index 6c26510299..dc5ed0a422 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3eae4e301e3e4bcf14e96066f77be1434c5d4b3daadb10153cd36382589ac128 \ No newline at end of file +f22c7e229ea4626c5268d61de3964521cf6a2735290cbd1518d68731ba6cca90 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 78f1cd9df0..33556c24fe 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1681,6 +1681,8 @@ static int shellAuth( ** in FTS3/4/5 into CREATE TABLE IF NOT EXISTS statements. */ static void printSchemaLine(FILE *out, const char *z, const char *zTail){ + if( z==0 ) return; + if( zTail==0 ) return; if( sqlite3_strglob("CREATE TABLE ['\"]*", z)==0 ){ utf8_printf(out, "CREATE TABLE IF NOT EXISTS %s%s", z+13, zTail); }else{ From 39e04f83b95f9ab6b2f579c1da716ab051c5b054 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 18:33:32 +0000 Subject: [PATCH 114/132] Fix a problem in the ".recover" command allowing a circular loop of b-tree pages in a database file to cause an infinite loop. FossilOrigin-Name: 8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1 --- ext/misc/dbdata.c | 5 ++++- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index 60c2296c91..a77519a1c3 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -301,7 +301,10 @@ static unsigned int get_uint16(unsigned char *a){ return (a[0]<<8)|a[1]; } static unsigned int get_uint32(unsigned char *a){ - return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|a[3]; + return ((unsigned int)a[0]<<24) + | ((unsigned int)a[1]<<16) + | ((unsigned int)a[2]<<8) + | ((unsigned int)a[3]); } /* diff --git a/manifest b/manifest index c0104c17a6..14e04a3cba 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\s".schema"\scommand\sin\sthe\sCLI\sresistant\sto\scorrupt\sdatabase\sfiles. -D 2019-05-09T18:13:30.290 +C Fix\sa\sproblem\sin\sthe\s".recover"\scommand\sallowing\sa\scircular\sloop\sof\sb-tree\spages\sin\sa\sdatabase\sfile\sto\scause\san\sinfinite\sloop. +D 2019-05-09T18:33:32.129 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c 4b73a0a5218a411752441896b68252ba3ced4d452e7dd419fdb3b92ae6ecada0 +F ext/misc/dbdata.c f779a2e95ecc4fd05b97707bd972746bd851abfcd49316e92ff2da3a14aa690c F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 332af8613687d1fcf89ff072c2dfecda74b260a54f850230fc82d6757a3a4904 +F src/shell.c.in 1f3e8c7032f54d3aef8653cfa5d0289afe3a08d112be8c4e69dc56c4100ac144 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 3eae4e301e3e4bcf14e96066f77be1434c5d4b3daadb10153cd36382589ac128 -R bb866c6c75a817d20565e49f7d81970f -U drh -Z 706d1f89fe233a2fdcafaa2e0adbab1c +P f22c7e229ea4626c5268d61de3964521cf6a2735290cbd1518d68731ba6cca90 +R 70c45f240fec796aded79e59d457750f +U dan +Z 7501180db88c65f34b6ae32d14e8f948 diff --git a/manifest.uuid b/manifest.uuid index dc5ed0a422..1f3b052a7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f22c7e229ea4626c5268d61de3964521cf6a2735290cbd1518d68731ba6cca90 \ No newline at end of file +8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 33556c24fe..86a21c4ee3 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6633,7 +6633,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " SELECT i, maxlen, NULL, (" " WITH p(orig, pgno, parent) AS (" " SELECT 0, i, (SELECT pgno FROM recovery.dbptr WHERE child=i)" - " UNION ALL" + " UNION " " SELECT i, p.parent, " " (SELECT pgno FROM recovery.dbptr WHERE child=p.parent) FROM p" " )" From 5985dcbf5e04fdc2e2312be0c5f9889691967e8a Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 9 May 2019 18:37:37 +0000 Subject: [PATCH 115/132] Fix another small buffer overread in sqlite_dbdata triggered by a corrupt database page. FossilOrigin-Name: 1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380 --- ext/misc/dbdata.c | 9 ++++++--- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/ext/misc/dbdata.c b/ext/misc/dbdata.c index a77519a1c3..7405e7c890 100644 --- a/ext/misc/dbdata.c +++ b/ext/misc/dbdata.c @@ -81,6 +81,8 @@ SQLITE_EXTENSION_INIT1 #include #include +#define DBDATA_PADDING_BYTES 100 + typedef struct DbdataTable DbdataTable; typedef struct DbdataCursor DbdataCursor; @@ -334,12 +336,13 @@ static int dbdataLoadPage( int nCopy = sqlite3_column_bytes(pStmt, 0); if( nCopy>0 ){ u8 *pPage; - pPage = (u8*)sqlite3_malloc64(nCopy); + pPage = (u8*)sqlite3_malloc64(nCopy + DBDATA_PADDING_BYTES); if( pPage==0 ){ rc = SQLITE_NOMEM; }else{ const u8 *pCopy = sqlite3_column_blob(pStmt, 0); memcpy(pPage, pCopy, nCopy); + memset(&pPage[nCopy], 0, DBDATA_PADDING_BYTES); } *ppPage = pPage; *pnPage = nCopy; @@ -572,9 +575,9 @@ static int dbdataNext(sqlite3_vtab_cursor *pCursor){ /* Allocate space for payload. And a bit more to catch small buffer ** overruns caused by attempting to read a varint or similar from ** near the end of a corrupt record. */ - pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+100); + pCsr->pRec = (u8*)sqlite3_malloc64(nPayload+DBDATA_PADDING_BYTES); if( pCsr->pRec==0 ) return SQLITE_NOMEM; - memset(pCsr->pRec, 0, nPayload+100); + memset(pCsr->pRec, 0, nPayload+DBDATA_PADDING_BYTES); pCsr->nRec = nPayload; /* Load the nLocal bytes of payload */ diff --git a/manifest b/manifest index 14e04a3cba..dbc56151c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sthe\s".recover"\scommand\sallowing\sa\scircular\sloop\sof\sb-tree\spages\sin\sa\sdatabase\sfile\sto\scause\san\sinfinite\sloop. -D 2019-05-09T18:33:32.129 +C Fix\sanother\ssmall\sbuffer\soverread\sin\ssqlite_dbdata\striggered\sby\sa\scorrupt\sdatabase\spage. +D 2019-05-09T18:37:37.967 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -284,7 +284,7 @@ F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c8 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 F ext/misc/csv.c 7f047aeb68f5802e7ce6639292095d622a488bb43526ed04810e0649faa71ceb -F ext/misc/dbdata.c f779a2e95ecc4fd05b97707bd972746bd851abfcd49316e92ff2da3a14aa690c +F ext/misc/dbdata.c e316fba936571584e55abd5b974a32a191727a6b746053a0c9d439bd2cf93940 F ext/misc/dbdump.c baf6e37447c9d6968417b1cd34cbedb0b0ab3f91b5329501d8a8d5be3287c336 F ext/misc/eval.c 4b4757592d00fd32e44c7a067e6a0e4839c81a4d57abc4131ee7806d1be3104e F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f @@ -1825,7 +1825,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 f22c7e229ea4626c5268d61de3964521cf6a2735290cbd1518d68731ba6cca90 -R 70c45f240fec796aded79e59d457750f +P 8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1 +R 2de2a3768dbf383fc97e924a35530746 U dan -Z 7501180db88c65f34b6ae32d14e8f948 +Z 9056fece1b5cad0dc370fe823762d792 diff --git a/manifest.uuid b/manifest.uuid index 1f3b052a7b..72b414a6e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1 \ No newline at end of file +1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380 \ No newline at end of file From 05d7bfd0bbc884da273bc6cf9862236b80390974 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 May 2019 12:06:47 +0000 Subject: [PATCH 116/132] Fix the round() SQL function so that it handles infinities correctly. FossilOrigin-Name: db9acef14d49212108c8082cc15a9b9b4a56b8afe4fe1104ddf62783739c1fbe --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 6 +++++- test/func.test | 3 +++ 4 files changed, 17 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index dbc56151c5..3d96d7b08e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\ssmall\sbuffer\soverread\sin\ssqlite_dbdata\striggered\sby\sa\scorrupt\sdatabase\spage. -D 2019-05-09T18:37:37.967 +C Fix\sthe\sround()\sSQL\sfunction\sso\sthat\sit\shandles\sinfinities\scorrectly. +D 2019-05-10T12:06:47.844 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 -F src/func.c 8c075dd8ba770bf48a4297c6ab6a520842d0d7711a7b6d9065246d50507597da +F src/func.c 08d6d07d138735dd79f12a2b0c623d1dc9270d0eea61b8be584625391ef84475 F src/global.c 0dea3065ea72a65ae941559b6686aad6516d4913e76fa4f79a95ff7787f624ec F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 @@ -981,7 +981,7 @@ F test/fts4rename.test 6015a355ec3a11a51eb5b88802b3b2c1788786c54b77b17f3e077b7c9 F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 150270b6e2e0281697c116e5ca0e46b41ace8d34b1c92461d88fdd9968c9b03c +F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test d202a7606d23f90988a664e88e268aed1087c11c F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1825,7 +1825,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 8d2a062eb8a3e6fdc6a61b571c8da0070382bf208c53e797151eac8679c975a1 -R 2de2a3768dbf383fc97e924a35530746 -U dan -Z 9056fece1b5cad0dc370fe823762d792 +P 1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380 +R 1f6028dc117986e4cb94c6a37ac54229 +U drh +Z e3e8a7ace76308cd59f6bff482696fb7 diff --git a/manifest.uuid b/manifest.uuid index 72b414a6e0..9134298226 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380 \ No newline at end of file +db9acef14d49212108c8082cc15a9b9b4a56b8afe4fe1104ddf62783739c1fbe \ No newline at end of file diff --git a/src/func.c b/src/func.c index b0a3169213..313a14018b 100644 --- a/src/func.c +++ b/src/func.c @@ -16,6 +16,7 @@ #include "sqliteInt.h" #include #include +#include #include "vdbeInt.h" /* @@ -396,7 +397,10 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ sqlite3_result_error_nomem(context); return; } - sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); + if( !sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8) ){ + assert( sqlite3_strglob("*Inf", zBuf)==0 ); + r = zBuf[0]=='-' ? -HUGE_VAL : +HUGE_VAL; + } sqlite3_free(zBuf); } sqlite3_result_double(context, r); diff --git a/test/func.test b/test/func.test index ab719388af..579bad8e44 100644 --- a/test/func.test +++ b/test/func.test @@ -315,6 +315,9 @@ ifcapable floatingpoint { do_test func-4.38 { execsql {SELECT round(9999999999999.556,2);} } {9999999999999.56} + do_execsql_test func-4.39 { + SELECT round(1e500), round(-1e500); + } {Inf -Inf} } # Test the upper() and lower() functions From 7e6dc5d9081f20a52ae38d6f5009cbfaf3bf72dc Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 May 2019 12:14:51 +0000 Subject: [PATCH 117/132] Fix the previous check-in [db9acef14d492121] so that the amalgamation build works for systems for which lack HAVE_ISNAN. FossilOrigin-Name: 3cc55e09e6c1de2059d97bdddf2fdfbdcc62c584b513f56faf9d3a39ef80cddd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/util.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3d96d7b08e..a9cc2d9f39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sround()\sSQL\sfunction\sso\sthat\sit\shandles\sinfinities\scorrectly. -D 2019-05-10T12:06:47.844 +C Fix\sthe\sprevious\scheck-in\s[db9acef14d492121]\sso\sthat\sthe\samalgamation\sbuild\nworks\sfor\ssystems\sfor\swhich\slack\sHAVE_ISNAN. +D 2019-05-10T12:14:51.652 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/trigger.c bb034c08eca111e66a19cda045903a12547c1be2294b5570d794b869d9c44a73 F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 -F src/util.c 5061987401c2e8003177fa30d73196aa036727c8f04bf36a2df0c82b1904a236 +F src/util.c 4c0669e042b4e50a08a9e5fd14cecc76e5f877efa288533dccddb6fe98f4d6b5 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf F src/vdbe.c d4efd6e5ecff8eeef280ce5d622dc2c0cfe085014e5813401b346517574adb18 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 @@ -1825,7 +1825,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 1dfc95b8673b0e8c9ef5040c2fa0fbe9846e430d104e9b83f3f1f3ad63446380 -R 1f6028dc117986e4cb94c6a37ac54229 +P db9acef14d49212108c8082cc15a9b9b4a56b8afe4fe1104ddf62783739c1fbe +R 2ae89586bd0923bfda8598a9d4f487b2 U drh -Z e3e8a7ace76308cd59f6bff482696fb7 +Z c5db4a9c420d2bf9fb0aafb4f42e2d4b diff --git a/manifest.uuid b/manifest.uuid index 9134298226..71fd3f249e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db9acef14d49212108c8082cc15a9b9b4a56b8afe4fe1104ddf62783739c1fbe \ No newline at end of file +3cc55e09e6c1de2059d97bdddf2fdfbdcc62c584b513f56faf9d3a39ef80cddd \ No newline at end of file diff --git a/src/util.c b/src/util.c index d12e55516f..6d619e231c 100644 --- a/src/util.c +++ b/src/util.c @@ -17,9 +17,7 @@ */ #include "sqliteInt.h" #include -#if HAVE_ISNAN || SQLITE_HAVE_ISNAN -# include -#endif +#include /* ** Routine needed to support the testcase() macro. From 2ce9b6bcd500c8836748aa5b34bcb02b7f145e90 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 May 2019 14:03:07 +0000 Subject: [PATCH 118/132] Improved comments and extra assert() statements on the OP_Savepoint opcode, just to make the code a little easier to read and reason about. FossilOrigin-Name: e80b2d9fcbc82ae5dc8a1fc13196f9a30bdb504eb5a5c131d136a78bbd5bbe7b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 ++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a9cc2d9f39..f2b1f27f7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sprevious\scheck-in\s[db9acef14d492121]\sso\sthat\sthe\samalgamation\sbuild\nworks\sfor\ssystems\sfor\swhich\slack\sHAVE_ISNAN. -D 2019-05-10T12:14:51.652 +C Improved\scomments\sand\sextra\sassert()\sstatements\son\sthe\sOP_Savepoint\sopcode,\njust\sto\smake\sthe\scode\sa\slittle\seasier\sto\sread\sand\sreason\sabout. +D 2019-05-10T14:03:07.714 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,7 +593,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 4c0669e042b4e50a08a9e5fd14cecc76e5f877efa288533dccddb6fe98f4d6b5 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c d4efd6e5ecff8eeef280ce5d622dc2c0cfe085014e5813401b346517574adb18 +F src/vdbe.c 4ab7c36d29e156835b23b6b797107f0dbdf6d729798d8cf0d33e40e411f02d68 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da @@ -1825,7 +1825,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 db9acef14d49212108c8082cc15a9b9b4a56b8afe4fe1104ddf62783739c1fbe -R 2ae89586bd0923bfda8598a9d4f487b2 +P 3cc55e09e6c1de2059d97bdddf2fdfbdcc62c584b513f56faf9d3a39ef80cddd +R 91d5b0019aab212ae793ae1752395d8d U drh -Z c5db4a9c420d2bf9fb0aafb4f42e2d4b +Z b0a1c28086400bbd580accea280a3220 diff --git a/manifest.uuid b/manifest.uuid index 71fd3f249e..41ff632437 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3cc55e09e6c1de2059d97bdddf2fdfbdcc62c584b513f56faf9d3a39ef80cddd \ No newline at end of file +e80b2d9fcbc82ae5dc8a1fc13196f9a30bdb504eb5a5c131d136a78bbd5bbe7b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 28916100df..90a000d32a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3030,8 +3030,9 @@ case OP_Count: { /* out2 */ /* Opcode: Savepoint P1 * * P4 * ** ** Open, release or rollback the savepoint named by parameter P4, depending -** on the value of P1. To open a new savepoint, P1==0. To release (commit) an -** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. +** on the value of P1. To open a new savepoint set P1==0 (SAVEPOINT_BEGIN). +** To release (commit) an existing savepoint set P1==1 (SAVEPOINT_RELEASE). +** To rollback an existing savepoint set P1==2 (SAVEPOINT_ROLLBACK). */ case OP_Savepoint: { int p1; /* Value of P1 operand */ @@ -3099,6 +3100,7 @@ case OP_Savepoint: { } } }else{ + assert( p1==SAVEPOINT_RELEASE || p1==SAVEPOINT_ROLLBACK ); iSavepoint = 0; /* Find the named savepoint. If there is no such savepoint, then an @@ -3152,6 +3154,7 @@ case OP_Savepoint: { if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ + assert( p1==SAVEPOINT_RELEASE ); isSchemaChange = 0; } for(ii=0; iinDb; ii++){ @@ -3188,6 +3191,7 @@ case OP_Savepoint: { db->nSavepoint--; } }else{ + assert( p1==SAVEPOINT_ROLLBACK ); db->nDeferredCons = pSavepoint->nDeferredCons; db->nDeferredImmCons = pSavepoint->nDeferredImmCons; } From 08f6de7f314ad6b15d34cc5f27c3e737fcd99268 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 10 May 2019 14:26:32 +0000 Subject: [PATCH 119/132] Treat integer values in window definition ORDER BY clauses as constants, not as references to another expression. FossilOrigin-Name: 7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 --- manifest | 18 +- manifest.uuid | 2 +- src/window.c | 15 +- test/window2.tcl | 7 + test/window2.test | 496 ++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 506 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index f2b1f27f7b..5e85198239 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomments\sand\sextra\sassert()\sstatements\son\sthe\sOP_Savepoint\sopcode,\njust\sto\smake\sthe\scode\sa\slittle\seasier\sto\sread\sand\sreason\sabout. -D 2019-05-10T14:03:07.714 +C Treat\sinteger\svalues\sin\swindow\sdefinition\sORDER\sBY\sclauses\sas\sconstants,\snot\sas\sreferences\sto\sanother\sexpression. +D 2019-05-10T14:26:32.252 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a F src/whereexpr.c 4219bdd5d310ba6424166d918efef301c21e1b7f6444e964b415c4a5b877a8fe -F src/window.c 038c248267e74ff70a2bb9b1884d40fd145c5183b017823ecb6cbb14bc781478 +F src/window.c 5be2cf7d8763cc97137fc44d015aed8a1a4a56fe9700d7933ed560172617c756 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1691,8 +1691,8 @@ F test/win32lock.test fbf107c91d8f5512be5a5b87c4c42ab9fdd54972 F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc F test/window1.test 8d453bfaa3f8f0873ba16ca1270c7368f18445065a0003a1b5954ac4e95797b4 -F test/window2.tcl 9bfa842d8a62b0d36dc8c1b5972206393c43847433c6d75940b87fec93ce3143 -F test/window2.test 8e6d2a1b9f54dfebee1cde961c8590cd87b4db45c50f44947a211e1b63c2a05e +F test/window2.tcl 0c2918ef2a1640553fd791972d458356808a608418c64c02a0a379cecfc7fb0d +F test/window2.test 96ef949f0197c025652f6c6e5812cdbfb948989bd40cf79cbb02104249a89513 F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb F test/window4.tcl 5fbaab489677914ee5686b2008426e336daf88a2f58be7df92757f780a5ebf91 @@ -1825,7 +1825,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 3cc55e09e6c1de2059d97bdddf2fdfbdcc62c584b513f56faf9d3a39ef80cddd -R 91d5b0019aab212ae793ae1752395d8d -U drh -Z b0a1c28086400bbd580accea280a3220 +P e80b2d9fcbc82ae5dc8a1fc13196f9a30bdb504eb5a5c131d136a78bbd5bbe7b +R 5d10e80b168be165319a3925a198d45f +U dan +Z 3dc3f887bf15d65a8af6e96bb64729d0 diff --git a/manifest.uuid b/manifest.uuid index 41ff632437..b22fb68e87 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e80b2d9fcbc82ae5dc8a1fc13196f9a30bdb504eb5a5c131d136a78bbd5bbe7b \ No newline at end of file +7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 \ No newline at end of file diff --git a/src/window.c b/src/window.c index 4b5184d918..737261e85c 100644 --- a/src/window.c +++ b/src/window.c @@ -868,13 +868,18 @@ static void selectWindowRewriteEList( static ExprList *exprListAppendList( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ - ExprList *pAppend /* List of values to append. Might be NULL */ + ExprList *pAppend, /* List of values to append. Might be NULL */ + int bIntToNull ){ if( pAppend ){ int i; int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ + pDup->op = TK_NULL; + pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder; } @@ -914,7 +919,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** of the window PARTITION and ORDER BY clauses. Then, if this makes it ** redundant, remove the ORDER BY from the parent SELECT. */ pSort = sqlite3ExprListDup(db, pMWin->pPartition, 0); - pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy); + pSort = exprListAppendList(pParse, pSort, pMWin->pOrderBy, 1); if( pSort && p->pOrderBy ){ if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ sqlite3ExprListDelete(db, p->pOrderBy); @@ -935,8 +940,8 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ /* Append the PARTITION BY and ORDER BY expressions to the to the ** sub-select expression list. They are required to figure out where ** boundaries for partitions and sets of peer rows lie. */ - pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition); - pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0); + pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); /* Append the arguments passed to each window function to the ** sub-select expression list. Also allocate two registers for each @@ -944,7 +949,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); - pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList); + pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0); if( pWin->pFilter ){ Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); diff --git a/test/window2.tcl b/test/window2.tcl index 48fcdaea40..093d693b62 100644 --- a/test/window2.tcl +++ b/test/window2.tcl @@ -417,6 +417,13 @@ execsql_test 4.8.4 { ) FROM t2 ORDER BY 1, 2; } +execsql_float_test 4.9 { + SELECT + rank() OVER win AS rank, + cume_dist() OVER win AS cume_dist FROM t1 + WINDOW win AS (ORDER BY 1); +} + finish_test diff --git a/test/window2.test b/test/window2.test index 086e56603d..4bed0cdcc9 100644 --- a/test/window2.test +++ b/test/window2.test @@ -326,7 +326,32 @@ do_execsql_test 4.1 { PARTITION BY (b%10) ORDER BY b ) FROM t2 ORDER BY a; -} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21} +} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 + 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 + 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 + 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 + 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 + 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 + 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 + 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 + 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 + 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 + 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 + 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 + 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 + 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 + 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 + 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 + 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 + 140 754 141 133 142 340 143 535 144 46 145 250 146 132 + 147 132 148 354 149 500 150 770 151 276 152 360 153 354 + 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 + 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 + 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 + 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 + 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 + 190 250 191 266 192 360 193 120 194 128 195 178 196 770 + 197 92 198 634 199 38 200 21} do_execsql_test 4.2 { SELECT a, sum(b) OVER ( @@ -334,101 +359,538 @@ do_execsql_test 4.2 { ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 ORDER BY a; -} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 140 754 141 133 142 340 143 535 144 46 145 250 146 132 147 132 148 354 149 500 150 770 151 276 152 360 153 354 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 190 250 191 266 192 360 193 120 194 128 195 178 196 770 197 92 198 634 199 38 200 21} +} {1 0 2 754 3 251 4 754 5 101 6 1247 7 132 8 266 9 6 10 950 + 11 667 12 1052 13 535 14 128 15 428 16 250 17 336 18 1122 + 19 368 20 6 21 1247 22 1000 23 92 24 368 25 584 26 320 + 27 1000 28 24 29 478 30 133 31 1049 32 1090 33 632 34 101 + 35 54 36 54 37 1049 38 450 39 145 40 354 41 21 42 764 + 43 754 44 424 45 1122 46 930 47 42 48 930 49 352 50 535 + 51 42 52 118 53 536 54 6 55 1122 56 86 57 770 58 255 59 50 + 60 52 61 950 62 75 63 354 64 2 65 536 66 160 67 352 68 536 + 69 54 70 675 71 276 72 950 73 868 74 678 75 667 76 4 + 77 1184 78 160 79 120 80 584 81 266 82 133 83 405 84 468 + 85 6 86 806 87 166 88 500 89 1090 90 552 91 251 92 27 + 93 424 94 687 95 1215 96 450 97 32 98 360 99 1052 100 868 + 101 2 102 66 103 754 104 450 105 145 106 5 107 687 108 24 + 109 302 110 806 111 251 112 42 113 24 114 30 115 128 116 128 + 117 50 118 1215 119 86 120 687 121 683 122 672 123 178 124 24 + 125 24 126 299 127 178 128 770 129 535 130 1052 131 270 + 132 255 133 675 134 632 135 266 136 6 137 21 138 930 139 411 + 140 754 141 133 142 340 143 535 144 46 145 250 146 132 + 147 132 148 354 149 500 150 770 151 276 152 360 153 354 + 154 27 155 552 156 552 157 602 158 266 159 1049 160 675 + 161 384 162 667 163 27 164 101 165 166 166 32 167 42 168 18 + 169 336 170 1122 171 276 172 1122 173 266 174 50 175 178 + 176 276 177 1247 178 6 179 1215 180 604 181 360 182 212 + 183 120 184 210 185 1090 186 10 187 1090 188 266 189 66 + 190 250 191 266 192 360 193 120 194 128 195 178 196 770 + 197 92 198 634 199 38 200 21} do_execsql_test 4.3 { SELECT b, sum(b) OVER ( ORDER BY b ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 ORDER BY b; -} {0 0 1 1 1 2 2 4 2 6 2 8 3 11 3 14 4 18 5 23 6 29 7 36 7 43 7 50 8 58 8 66 8 74 9 83 9 92 9 101 10 111 11 122 11 133 12 145 12 157 12 169 13 182 13 195 14 209 15 224 15 239 15 254 16 270 16 286 16 302 17 319 19 338 20 358 21 379 21 400 22 422 22 444 23 467 23 490 23 513 24 537 25 562 26 588 26 614 26 640 27 667 27 694 28 722 29 751 29 780 29 809 30 839 30 869 30 899 31 930 31 961 32 993 33 1026 33 1059 33 1092 33 1125 33 1158 34 1192 34 1226 34 1260 34 1294 35 1329 35 1364 36 1400 36 1436 36 1472 36 1508 37 1545 37 1582 38 1620 38 1658 39 1697 39 1736 39 1775 40 1815 41 1856 41 1897 41 1938 42 1980 43 2023 43 2066 44 2110 44 2154 46 2200 46 2246 47 2293 47 2340 47 2387 47 2434 49 2483 50 2533 51 2584 52 2636 53 2689 54 2743 55 2798 55 2853 56 2909 56 2965 56 3021 57 3078 58 3136 58 3194 58 3252 58 3310 59 3369 59 3428 59 3487 59 3546 60 3606 61 3667 61 3728 62 3790 62 3852 63 3915 64 3979 65 4044 65 4109 65 4174 66 4240 67 4307 68 4375 69 4444 70 4514 72 4586 72 4658 72 4730 73 4803 73 4876 73 4949 74 5023 74 5097 74 5171 74 5245 74 5319 75 5394 75 5469 75 5544 76 5620 77 5697 77 5774 78 5852 78 5930 79 6009 80 6089 80 6169 81 6250 81 6331 81 6412 82 6494 83 6577 84 6661 84 6745 84 6829 84 6913 85 6998 85 7083 85 7168 86 7254 87 7341 87 7428 88 7516 89 7605 89 7694 89 7783 90 7873 90 7963 90 8053 91 8144 91 8235 91 8326 91 8417 91 8508 93 8601 93 8694 93 8787 94 8881 95 8976 95 9071 95 9166 96 9262 96 9358 96 9454 97 9551 97 9648 98 9746 98 9844 99 9943 99 10042 99 10141} +} {0 0 1 1 1 2 2 4 2 6 2 8 3 11 3 14 4 18 5 23 6 29 7 36 + 7 43 7 50 8 58 8 66 8 74 9 83 9 92 9 101 10 111 11 122 + 11 133 12 145 12 157 12 169 13 182 13 195 14 209 15 224 + 15 239 15 254 16 270 16 286 16 302 17 319 19 338 20 358 + 21 379 21 400 22 422 22 444 23 467 23 490 23 513 24 537 + 25 562 26 588 26 614 26 640 27 667 27 694 28 722 29 751 + 29 780 29 809 30 839 30 869 30 899 31 930 31 961 32 993 + 33 1026 33 1059 33 1092 33 1125 33 1158 34 1192 34 1226 + 34 1260 34 1294 35 1329 35 1364 36 1400 36 1436 36 1472 + 36 1508 37 1545 37 1582 38 1620 38 1658 39 1697 39 1736 + 39 1775 40 1815 41 1856 41 1897 41 1938 42 1980 43 2023 + 43 2066 44 2110 44 2154 46 2200 46 2246 47 2293 47 2340 + 47 2387 47 2434 49 2483 50 2533 51 2584 52 2636 53 2689 + 54 2743 55 2798 55 2853 56 2909 56 2965 56 3021 57 3078 + 58 3136 58 3194 58 3252 58 3310 59 3369 59 3428 59 3487 + 59 3546 60 3606 61 3667 61 3728 62 3790 62 3852 63 3915 + 64 3979 65 4044 65 4109 65 4174 66 4240 67 4307 68 4375 + 69 4444 70 4514 72 4586 72 4658 72 4730 73 4803 73 4876 + 73 4949 74 5023 74 5097 74 5171 74 5245 74 5319 75 5394 + 75 5469 75 5544 76 5620 77 5697 77 5774 78 5852 78 5930 + 79 6009 80 6089 80 6169 81 6250 81 6331 81 6412 82 6494 + 83 6577 84 6661 84 6745 84 6829 84 6913 85 6998 85 7083 + 85 7168 86 7254 87 7341 87 7428 88 7516 89 7605 89 7694 + 89 7783 90 7873 90 7963 90 8053 91 8144 91 8235 91 8326 + 91 8417 91 8508 93 8601 93 8694 93 8787 94 8881 95 8976 + 95 9071 95 9166 96 9262 96 9358 96 9454 97 9551 97 9648 + 98 9746 98 9844 99 9943 99 10042 99 10141} do_execsql_test 4.4 { SELECT b, sum(b) OVER ( ORDER BY b RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY b; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.5 { SELECT b, sum(b) OVER ( ORDER BY b RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 ORDER BY b; -} {0 0 1 2 1 2 2 6 2 6 2 6 3 6 3 6 4 4 5 5 6 6 7 21 7 21 7 21 8 24 8 24 8 24 9 27 9 27 9 27 10 10 11 22 11 22 12 36 12 36 12 36 13 26 13 26 14 14 15 45 15 45 15 45 16 48 16 48 16 48 17 17 19 19 20 20 21 42 21 42 22 44 22 44 23 69 23 69 23 69 24 24 25 25 26 78 26 78 26 78 27 54 27 54 28 28 29 87 29 87 29 87 30 90 30 90 30 90 31 62 31 62 32 32 33 165 33 165 33 165 33 165 33 165 34 136 34 136 34 136 34 136 35 70 35 70 36 144 36 144 36 144 36 144 37 74 37 74 38 76 38 76 39 117 39 117 39 117 40 40 41 123 41 123 41 123 42 42 43 86 43 86 44 88 44 88 46 92 46 92 47 188 47 188 47 188 47 188 49 49 50 50 51 51 52 52 53 53 54 54 55 110 55 110 56 168 56 168 56 168 57 57 58 232 58 232 58 232 58 232 59 236 59 236 59 236 59 236 60 60 61 122 61 122 62 124 62 124 63 63 64 64 65 195 65 195 65 195 66 66 67 67 68 68 69 69 70 70 72 216 72 216 72 216 73 219 73 219 73 219 74 370 74 370 74 370 74 370 74 370 75 225 75 225 75 225 76 76 77 154 77 154 78 156 78 156 79 79 80 160 80 160 81 243 81 243 81 243 82 82 83 83 84 336 84 336 84 336 84 336 85 255 85 255 85 255 86 86 87 174 87 174 88 88 89 267 89 267 89 267 90 270 90 270 90 270 91 455 91 455 91 455 91 455 91 455 93 279 93 279 93 279 94 94 95 285 95 285 95 285 96 288 96 288 96 288 97 194 97 194 98 196 98 196 99 297 99 297 99 297} +} {0 0 1 2 1 2 2 6 2 6 2 6 3 6 3 6 4 4 5 5 6 6 7 21 + 7 21 7 21 8 24 8 24 8 24 9 27 9 27 9 27 10 10 11 22 + 11 22 12 36 12 36 12 36 13 26 13 26 14 14 15 45 15 45 + 15 45 16 48 16 48 16 48 17 17 19 19 20 20 21 42 21 42 + 22 44 22 44 23 69 23 69 23 69 24 24 25 25 26 78 26 78 + 26 78 27 54 27 54 28 28 29 87 29 87 29 87 30 90 30 90 + 30 90 31 62 31 62 32 32 33 165 33 165 33 165 33 165 33 165 + 34 136 34 136 34 136 34 136 35 70 35 70 36 144 36 144 + 36 144 36 144 37 74 37 74 38 76 38 76 39 117 39 117 39 117 + 40 40 41 123 41 123 41 123 42 42 43 86 43 86 44 88 44 88 + 46 92 46 92 47 188 47 188 47 188 47 188 49 49 50 50 51 51 + 52 52 53 53 54 54 55 110 55 110 56 168 56 168 56 168 57 57 + 58 232 58 232 58 232 58 232 59 236 59 236 59 236 59 236 + 60 60 61 122 61 122 62 124 62 124 63 63 64 64 65 195 65 195 + 65 195 66 66 67 67 68 68 69 69 70 70 72 216 72 216 72 216 + 73 219 73 219 73 219 74 370 74 370 74 370 74 370 74 370 + 75 225 75 225 75 225 76 76 77 154 77 154 78 156 78 156 + 79 79 80 160 80 160 81 243 81 243 81 243 82 82 83 83 84 336 + 84 336 84 336 84 336 85 255 85 255 85 255 86 86 87 174 + 87 174 88 88 89 267 89 267 89 267 90 270 90 270 90 270 + 91 455 91 455 91 455 91 455 91 455 93 279 93 279 93 279 + 94 94 95 285 95 285 95 285 96 288 96 288 96 288 97 194 + 97 194 98 196 98 196 99 297 99 297 99 297} do_execsql_test 4.6.1 { SELECT b, sum(b) OVER ( RANGE BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 ORDER BY b; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.6.2 { SELECT b, sum(b) OVER () FROM t2 ORDER BY b; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.6.3 { SELECT b, sum(b) OVER ( RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY b; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.6.4 { SELECT b, sum(b) OVER ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY b; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.7.1 { SELECT b, sum(b) OVER ( ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 ORDER BY 1, 2; -} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99} +} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 + 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 + 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 + 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 + 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 + 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 + 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 + 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 + 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 + 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 + 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 + 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 + 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 + 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 + 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 + 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 + 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 + 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 + 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 + 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 + 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 + 98 98 98 98 99 99 99 99 99 99} do_execsql_test 4.7.2 { SELECT b, sum(b) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 ORDER BY 1, 2; -} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093} +} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 + 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 + 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 + 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 + 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 + 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 + 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 + 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 + 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 + 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 + 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 + 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 + 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 + 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 + 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 + 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 + 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 + 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 + 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 + 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 + 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 + 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 + 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 + 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 + 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 + 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 + 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 + 98 3888 98 5442 99 311 99 1146 99 9093} do_execsql_test 4.7.3 { SELECT b, sum(b) OVER ( ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY 1, 2; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.7.4 { SELECT b, sum(b) OVER ( ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY 1, 2; -} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} +} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 + 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 + 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 + 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 + 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 + 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 + 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 + 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 + 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 + 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 + 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 + 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 + 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 + 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 + 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 + 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 + 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 + 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 + 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 + 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 + 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 + 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 + 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 + 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 + 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 + 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 + 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} do_execsql_test 4.8.1 { SELECT b, sum(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t2 ORDER BY 1, 2; -} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 98 98 98 98 99 99 99 99 99 99} +} {0 0 1 1 1 1 2 2 2 2 2 2 3 3 3 3 4 4 5 5 6 6 7 7 7 7 + 7 7 8 8 8 8 8 8 9 9 9 9 9 9 10 10 11 11 11 11 12 12 + 12 12 12 12 13 13 13 13 14 14 15 15 15 15 15 15 16 16 + 16 16 16 16 17 17 19 19 20 20 21 21 21 21 22 22 22 22 + 23 23 23 23 23 23 24 24 25 25 26 26 26 26 26 26 27 27 + 27 27 28 28 29 29 29 29 29 29 30 30 30 30 30 30 31 31 + 31 31 32 32 33 33 33 33 33 33 33 33 33 33 34 34 34 34 + 34 34 34 34 35 35 35 35 36 36 36 36 36 36 36 36 37 37 + 37 37 38 38 38 38 39 39 39 39 39 39 40 40 41 41 41 41 + 41 41 42 42 43 43 43 43 44 44 44 44 46 46 46 46 47 47 + 47 47 47 47 47 47 49 49 50 50 51 51 52 52 53 53 54 54 + 55 55 55 55 56 56 56 56 56 56 57 57 58 58 58 58 58 58 + 58 58 59 59 59 59 59 59 59 59 60 60 61 61 61 61 62 62 + 62 62 63 63 64 64 65 65 65 65 65 65 66 66 67 67 68 68 + 69 69 70 70 72 72 72 72 72 72 73 73 73 73 73 73 74 74 + 74 74 74 74 74 74 74 74 75 75 75 75 75 75 76 76 77 77 + 77 77 78 78 78 78 79 79 80 80 80 80 81 81 81 81 81 81 + 82 82 83 83 84 84 84 84 84 84 84 84 85 85 85 85 85 85 + 86 86 87 87 87 87 88 88 89 89 89 89 89 89 90 90 90 90 + 90 90 91 91 91 91 91 91 91 91 91 91 93 93 93 93 93 93 + 94 94 95 95 95 95 95 95 96 96 96 96 96 96 97 97 97 97 + 98 98 98 98 99 99 99 99 99 99} do_execsql_test 4.8.2 { SELECT b, sum(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 ORDER BY 1, 2; -} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 98 3888 98 5442 99 311 99 1146 99 9093} +} {0 0 1 3379 1 5443 2 372 2 4473 2 7074 3 2916 3 9096 4 4049 + 5 5643 6 1047 7 2205 7 7081 7 10141 8 1553 8 5926 8 6422 + 9 4883 9 7932 9 8497 10 9544 11 5727 11 6433 12 2825 12 5918 + 12 8582 13 5190 13 8570 14 8596 15 3189 15 6023 15 8924 + 16 1942 16 1958 16 3590 17 10134 19 7474 20 5946 21 5464 + 21 9682 22 3029 22 6140 23 212 23 1926 23 8520 24 2626 + 25 3331 26 337 26 7539 26 7565 27 1270 27 10035 28 3217 + 29 1649 29 4355 29 7326 30 4215 30 9400 30 9853 31 5977 + 31 6008 32 2857 33 370 33 4326 33 8175 33 8909 33 9661 + 34 6414 34 6516 34 8958 34 9925 35 2151 35 5638 36 3701 + 36 7818 36 8785 36 8994 37 4597 37 8557 38 735 38 9891 39 842 + 39 7513 39 9721 40 3475 41 115 41 4874 41 5906 42 4185 + 43 2754 43 3518 44 7072 44 9765 46 1041 46 1316 47 2198 + 47 3378 47 7612 47 7923 49 6482 50 9450 51 5778 52 9370 + 53 4408 54 1448 55 3174 55 6876 56 2913 56 3435 56 3574 + 57 7223 58 5248 58 7876 58 9318 58 9823 59 697 59 2813 + 59 6665 59 7455 60 6821 61 2426 61 4944 62 904 62 8658 + 63 4471 64 8407 65 2116 65 5177 65 5603 66 8142 67 1620 + 68 803 69 9260 70 7396 72 4833 72 8004 72 8076 73 5017 + 73 5716 73 6213 74 74 74 189 74 2365 74 5538 74 7297 75 3665 + 75 6951 75 8343 76 3964 77 1903 77 7028 78 1394 78 4293 + 79 6292 80 4677 80 7692 81 542 81 4045 81 8488 82 10117 + 83 10008 84 1826 84 4761 84 9534 84 9628 85 2602 85 2711 + 85 7166 86 2291 87 4560 87 5865 88 6380 89 461 89 3306 + 89 3790 90 3119 90 6606 90 7782 91 995 91 2517 91 3007 + 91 8749 91 8876 93 1742 93 2051 93 8268 94 4143 95 5112 + 95 6118 95 9191 96 638 96 5344 96 6761 97 1243 97 1545 + 98 3888 98 5442 99 311 99 1146 99 9093} do_execsql_test 4.8.3 { SELECT b, sum(b) OVER ( ORDER BY a ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY 1, 2; -} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 98 10141 99 10141 99 10141 99 10141} +} {0 10141 1 10141 1 10141 2 10141 2 10141 2 10141 3 10141 + 3 10141 4 10141 5 10141 6 10141 7 10141 7 10141 7 10141 + 8 10141 8 10141 8 10141 9 10141 9 10141 9 10141 10 10141 + 11 10141 11 10141 12 10141 12 10141 12 10141 13 10141 13 10141 + 14 10141 15 10141 15 10141 15 10141 16 10141 16 10141 16 10141 + 17 10141 19 10141 20 10141 21 10141 21 10141 22 10141 22 10141 + 23 10141 23 10141 23 10141 24 10141 25 10141 26 10141 26 10141 + 26 10141 27 10141 27 10141 28 10141 29 10141 29 10141 29 10141 + 30 10141 30 10141 30 10141 31 10141 31 10141 32 10141 33 10141 + 33 10141 33 10141 33 10141 33 10141 34 10141 34 10141 34 10141 + 34 10141 35 10141 35 10141 36 10141 36 10141 36 10141 36 10141 + 37 10141 37 10141 38 10141 38 10141 39 10141 39 10141 39 10141 + 40 10141 41 10141 41 10141 41 10141 42 10141 43 10141 43 10141 + 44 10141 44 10141 46 10141 46 10141 47 10141 47 10141 47 10141 + 47 10141 49 10141 50 10141 51 10141 52 10141 53 10141 54 10141 + 55 10141 55 10141 56 10141 56 10141 56 10141 57 10141 58 10141 + 58 10141 58 10141 58 10141 59 10141 59 10141 59 10141 59 10141 + 60 10141 61 10141 61 10141 62 10141 62 10141 63 10141 64 10141 + 65 10141 65 10141 65 10141 66 10141 67 10141 68 10141 69 10141 + 70 10141 72 10141 72 10141 72 10141 73 10141 73 10141 73 10141 + 74 10141 74 10141 74 10141 74 10141 74 10141 75 10141 75 10141 + 75 10141 76 10141 77 10141 77 10141 78 10141 78 10141 79 10141 + 80 10141 80 10141 81 10141 81 10141 81 10141 82 10141 83 10141 + 84 10141 84 10141 84 10141 84 10141 85 10141 85 10141 85 10141 + 86 10141 87 10141 87 10141 88 10141 89 10141 89 10141 89 10141 + 90 10141 90 10141 90 10141 91 10141 91 10141 91 10141 91 10141 + 91 10141 93 10141 93 10141 93 10141 94 10141 95 10141 95 10141 + 95 10141 96 10141 96 10141 96 10141 97 10141 97 10141 98 10141 + 98 10141 99 10141 99 10141 99 10141} do_execsql_test 4.8.4 { SELECT b, sum(b) OVER ( ORDER BY a ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING ) FROM t2 ORDER BY 1, 2; -} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} +} {0 10141 1 4699 1 6763 2 3069 2 5670 2 9771 3 1048 3 7228 + 4 6096 5 4503 6 9100 7 7 7 3067 7 7943 8 3727 8 4223 8 8596 + 9 1653 9 2218 9 5267 10 607 11 3719 11 4425 12 1571 12 4235 + 12 7328 13 1584 13 4964 14 1559 15 1232 15 4133 15 6967 + 16 6567 16 8199 16 8215 17 24 19 2686 20 4215 21 480 21 4698 + 22 4023 22 7134 23 1644 23 8238 23 9952 24 7539 25 6835 + 26 2602 26 2628 26 9830 27 133 27 8898 28 6952 29 2844 + 29 5815 29 8521 30 318 30 771 30 5956 31 4164 31 4195 32 7316 + 33 513 33 1265 33 1999 33 5848 33 9804 34 250 34 1217 34 3659 + 34 3761 35 4538 35 8025 36 1183 36 1392 36 2359 36 6476 + 37 1621 37 5581 38 288 38 9444 39 459 39 2667 39 9338 40 6706 + 41 4276 41 5308 41 10067 42 5998 43 6666 43 7430 44 420 + 44 3113 46 8871 46 9146 47 2265 47 2576 47 6810 47 7990 + 49 3708 50 741 51 4414 52 823 53 5786 54 8747 55 3320 55 7022 + 56 6623 56 6762 56 7284 57 2975 58 376 58 881 58 2323 58 4951 + 59 2745 59 3535 59 7387 59 9503 60 3380 61 5258 61 7776 + 62 1545 62 9299 63 5733 64 1798 65 4603 65 5029 65 8090 + 66 2065 67 8588 68 9406 69 950 70 2815 72 2137 72 2209 + 72 5380 73 4001 73 4498 73 5197 74 2918 74 4677 74 7850 + 74 10026 74 10141 75 1873 75 3265 75 6551 76 6253 77 3190 + 77 8315 78 5926 78 8825 79 3928 80 2529 80 5544 81 1734 + 81 6177 81 9680 82 106 83 216 84 597 84 691 84 5464 84 8399 + 85 3060 85 7515 85 7624 86 7936 87 4363 87 5668 88 3849 + 89 6440 89 6924 89 9769 90 2449 90 3625 90 7112 91 1356 + 91 1483 91 7225 91 7715 91 9237 93 1966 93 8183 93 8492 + 94 6092 95 1045 95 4118 95 5124 96 3476 96 4893 96 9599 + 97 8693 97 8995 98 4797 98 6351 99 1147 99 9094 99 9929} + + +do_test 4.9 { + set myres {} + foreach r [db eval {SELECT + rank() OVER win AS rank, + cume_dist() OVER win AS cume_dist FROM t1 + WINDOW win AS (ORDER BY 1);}] { + lappend myres [format %.4f [set r]] + } + set res2 {1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000} + set i 0 + foreach r [set myres] r2 [set res2] { + if {[set r]<([set r2]-0.0001) || [set r]>([set r2]+0.0001)} { + error "list element [set i] does not match: got=[set r] expected=[set r2]" + } + incr i + } + set {} {} +} {} finish_test From 41422656450bed94abee2edf1df83660325afc5c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 May 2019 14:34:18 +0000 Subject: [PATCH 120/132] Ensure that the BtShared.nPage value is reset correctly on a SAVEPOINT ROLLBACK. FossilOrigin-Name: e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/btree.c | 20 ++++++++++++++------ test/fuzzdata8.db | Bin 1105920 -> 1108992 bytes 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5e85198239..0b1618cd64 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Treat\sinteger\svalues\sin\swindow\sdefinition\sORDER\sBY\sclauses\sas\sconstants,\snot\sas\sreferences\sto\sanother\sexpression. -D 2019-05-10T14:26:32.252 +C Ensure\sthat\sthe\sBtShared.nPage\svalue\sis\sreset\scorrectly\son\sa\sSAVEPOINT\s\nROLLBACK. +D 2019-05-10T14:34:18.772 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -462,7 +462,7 @@ F src/auth.c 0fac71038875693a937e506bceb492c5f136dd7b1249fbd4ae70b4e8da14f9df F src/backup.c b1d37f6f7f5913944583733ed0f9e182f3ece0d42c27f46701142141a6e6fd33 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 0a276df3f912569bb8a5aac31af333dd238a72dc8e506f590555d68b2885f98e +F src/btree.c 5e15f903fd44b076b864a8d2449d63b44a546efabb66fca7dfed90f106f5c756 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b @@ -1002,7 +1002,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca -F test/fuzzdata8.db 7f1ad0a0cc9918529e7b16f48f2449ce6e7871babd71c79492bbe020fb3a63ae +F test/fuzzdata8.db 038627908808f88bad9c3ac90f3b7865766f92b2cfed585c7e083a792d554ade F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1825,7 +1825,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 e80b2d9fcbc82ae5dc8a1fc13196f9a30bdb504eb5a5c131d136a78bbd5bbe7b -R 5d10e80b168be165319a3925a198d45f -U dan -Z 3dc3f887bf15d65a8af6e96bb64729d0 +P 7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 +R 268b58938fd6d4d4d8851725d5098438 +U drh +Z 721183bcdc81f44fe0374ed072896b4f diff --git a/manifest.uuid b/manifest.uuid index b22fb68e87..2320774bf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 \ No newline at end of file +e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2b322122a8..47c5dd9f70 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4153,6 +4153,18 @@ int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ return rc; } +/* +** Set the pBt->nPage field correctly, according to the current +** state of the database. Assume pBt->pPage1 is valid. +*/ +static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ + int nPage = get4byte(&pPage1->aData[28]); + testcase( nPage==0 ); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); + testcase( pBt->nPage!=nPage ); + pBt->nPage = nPage; +} + /* ** Rollback the transaction in progress. ** @@ -4198,11 +4210,7 @@ int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ ** call btreeGetPage() on page 1 again to make ** sure pPage1->aData is set correctly. */ if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ - int nPage = get4byte(28+(u8*)pPage1->aData); - testcase( nPage==0 ); - if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); - testcase( pBt->nPage!=nPage ); - pBt->nPage = nPage; + btreeSetNPage(pBt, pPage1); releasePageOne(pPage1); } assert( countValidCursors(pBt, 1)==0 ); @@ -4282,7 +4290,7 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ pBt->nPage = 0; } rc = newDatabase(pBt); - pBt->nPage = get4byte(28 + pBt->pPage1->aData); + btreeSetNPage(pBt, pBt->pPage1); /* pBt->nPage might be zero if the database was corrupt when ** the transaction was started. Otherwise, it must be at least 1. */ diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index b6440aa3cc824cc787d3980cf9685d2c9ecc3dff..1a7ef8bb923d68c877a79962c2041ba1ddbe4362 100644 GIT binary patch delta 20085 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 delta 18137 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 MXCyk`wBHZ=e@LAjR{#J2 From d9bc6e8973e9bedadf51bb8fb50f143afdeb497a Mon Sep 17 00:00:00 2001 From: mistachkin Date: Fri, 10 May 2019 16:16:19 +0000 Subject: [PATCH 121/132] Fix some harmless compiler warnings. FossilOrigin-Name: ca068d82387fc3cda9d2050cedb4f9c61b6d9dc54f89015b4b2ee492243ed5c9 --- manifest | 19 +++++++------ manifest.uuid | 2 +- src/whereInt.h | 4 +++ tool/lemon.c | 74 +++++++++++++++++++++++++------------------------- 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/manifest b/manifest index 0b1618cd64..535ef4f8bc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sBtShared.nPage\svalue\sis\sreset\scorrectly\son\sa\sSAVEPOINT\s\nROLLBACK. -D 2019-05-10T14:34:18.772 +C Fix\ssome\sharmless\scompiler\swarnings. +D 2019-05-10T16:16:19.390 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -608,7 +608,7 @@ F src/wal.c b09a2a9cab50efa08451a8c81d47052120ad5da174048c6d0b08d405384abdf2 F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c 7607f1a68130c028255d8d56094ea602fc402c79e1e35a46e6282849d90d5fe4 F src/where.c 99c7b718ef846ac952016083aaf4e22ede2290beceaf4730a2df55c023251369 -F src/whereInt.h 5f14db426ca46a83eabab1ae9aa6d4b8f27504ad35b64c290916289b1ddb2e88 +F src/whereInt.h 1b728f71654ebf8421a1715497a587f02d6f538e819af58dc826908f8577e810 F src/wherecode.c 37a1004237d630d785c47bba2290eac652a7a8b0047518eba3cb7c808b604c4a F src/whereexpr.c 4219bdd5d310ba6424166d918efef301c21e1b7f6444e964b415c4a5b877a8fe F src/window.c 5be2cf7d8763cc97137fc44d015aed8a1a4a56fe9700d7933ed560172617c756 @@ -1744,7 +1744,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c d02a276728c507a7007333944eeabafab1668033794af348389b1166075869ee +F tool/lemon.c dbcb617f0d815a60c2cb5fedc09ac575af0ba7026b48726c7f80a5a20a5ba345 F tool/lempar.c 61af95b8fac2bfd59c09d55330e78f3f5e352d7aa80bf37404b96ef795be3fdc F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1825,7 +1825,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 7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 -R 268b58938fd6d4d4d8851725d5098438 -U drh -Z 721183bcdc81f44fe0374ed072896b4f +P e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 +R 18dbde46f443280c6eecde54f8c54e7b +T *branch * warnings +T *sym-warnings * +T -sym-trunk * +U mistachkin +Z b2da933afeced894c61f5f453a40ac1b diff --git a/manifest.uuid b/manifest.uuid index 2320774bf9..9a7675cc2c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 \ No newline at end of file +ca068d82387fc3cda9d2050cedb4f9c61b6d9dc54f89015b4b2ee492243ed5c9 \ No newline at end of file diff --git a/src/whereInt.h b/src/whereInt.h index 07876f4353..090bbc287c 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -14,6 +14,8 @@ ** planner logic in "where.c". These definitions are broken out into ** a separate source file for easier editing. */ +#ifndef SQLITE_WHEREINT_H +#define SQLITE_WHEREINT_H /* ** Trace output macros @@ -584,3 +586,5 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ + +#endif /* !defined(SQLITE_WHEREINT_H) */ diff --git a/tool/lemon.c b/tool/lemon.c index eb4adbbc69..d92da870d2 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -483,22 +483,22 @@ void Configtable_clear(int(*)(struct config *)); /* Allocate a new parser action */ static struct action *Action_new(void){ - static struct action *freelist = 0; + static struct action *actionfreelist = 0; struct action *newaction; - if( freelist==0 ){ + if( actionfreelist==0 ){ int i; int amt = 100; - freelist = (struct action *)calloc(amt, sizeof(struct action)); - if( freelist==0 ){ + actionfreelist = (struct action *)calloc(amt, sizeof(struct action)); + if( actionfreelist==0 ){ fprintf(stderr,"Unable to allocate memory for a new parser action."); exit(1); } - for(i=0; inext; + newaction = actionfreelist; + actionfreelist = actionfreelist->next; return newaction; } @@ -1907,7 +1907,7 @@ static char *msort( return ep; } /************************ From the file "option.c" **************************/ -static char **argv; +static char **g_argv; static struct s_options *op; static FILE *errstream; @@ -1920,14 +1920,14 @@ static FILE *errstream; static void errline(int n, int k, FILE *err) { int spcnt, i; - if( argv[0] ) fprintf(err,"%s",argv[0]); - spcnt = lemonStrlen(argv[0]) + 1; - for(i=1; i=0 ? argv[i] : 0; + return i>=0 ? g_argv[i] : 0; } void OptErr(int n) @@ -2728,7 +2728,7 @@ to follow the previous rule."); case WAITING_FOR_CLASS_ID: if( !ISLOWER(x[0]) ){ ErrorMsg(psp->filename, psp->tokenlineno, - "%%token_class must be followed by an identifier: ", x); + "%%token_class must be followed by an identifier: %s", x); psp->errorcnt++; psp->state = RESYNC_AFTER_DECL_ERROR; }else if( Symbol_find(x) ){ From 9546c766567d11937cf1bccd98c80bc969fb9ae8 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 10 May 2019 17:50:33 +0000 Subject: [PATCH 122/132] Fix harmless compiler warnings in the CLI. FossilOrigin-Name: 2846bc0429c0956473bfe99dde135f2c206720f0be4c2800118b280e446ce325 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 29 +++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 0b1618cd64..c703f77bb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sBtShared.nPage\svalue\sis\sreset\scorrectly\son\sa\sSAVEPOINT\s\nROLLBACK. -D 2019-05-10T14:34:18.772 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sCLI. +D 2019-05-10T17:50:33.253 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 408632d9531ca8f1df8591f00530797daaa7bde3fe0d3211de4d431cbb99347e F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c ef860c7e5882c89c030432a6d2cf13c67d1d51fd511cf45cbdfd5c2faf44d51d -F src/shell.c.in 1f3e8c7032f54d3aef8653cfa5d0289afe3a08d112be8c4e69dc56c4100ac144 +F src/shell.c.in 6c992809abf20dbb4aad89299d7c15c98ddf2504b23c83ef71eb435ad392cdc3 F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1825,7 +1825,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 7e4809eadfe99ebfd797a7c63501421021a720bbeed9fba81bebf630c58bb791 -R 268b58938fd6d4d4d8851725d5098438 +P e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 +R 39a4f6792e1723be8e92f3f5d380b658 U drh -Z 721183bcdc81f44fe0374ed072896b4f +Z 2060dcc1522889afcf20aa419b980197 diff --git a/manifest.uuid b/manifest.uuid index 2320774bf9..17dda45a39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e6d5fee8cdbdce8515957e8288e4d1e7b06f417fd3f9deeeb636fbf5b995af51 \ No newline at end of file +2846bc0429c0956473bfe99dde135f2c206720f0be4c2800118b280e446ce325 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 86a21c4ee3..f9f82b01ca 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3955,7 +3955,8 @@ static void shellInt32( const unsigned char *pBlob; int nBlob; int iInt; - + + UNUSED_PARAMETER(argc); nBlob = sqlite3_value_bytes(argv[0]); pBlob = (const unsigned char*)sqlite3_value_blob(argv[0]); iInt = sqlite3_value_int(argv[1]); @@ -3989,6 +3990,7 @@ static void shellEscapeCrnl( sqlite3_value **argv ){ const char *zText = (const char*)sqlite3_value_text(argv[0]); + UNUSED_PARAMETER(argc); if( zText[0]=='\'' ){ int nText = sqlite3_value_bytes(argv[0]); int i; @@ -5417,7 +5419,14 @@ static void shellPrepare( } } -static void shellPreparePrintf( +/* +** Create a prepared statement using printf-style arguments for the SQL. +** +** This routine is could be marked "static". But it is not always used, +** depending on compile-time options. By omitting the "static", we avoid +** nuisance compiler warnings about "defined but not used". +*/ +void shellPreparePrintf( sqlite3 *db, int *pRc, sqlite3_stmt **ppStmt, @@ -5440,7 +5449,13 @@ static void shellPreparePrintf( } } -static void shellFinalize( +/* Finalize the prepared statement created using shellPreparePrintf(). +** +** This routine is could be marked "static". But it is not always used, +** depending on compile-time options. By omitting the "static", we avoid +** nuisance compiler warnings about "defined but not used". +*/ +void shellFinalize( int *pRc, sqlite3_stmt *pStmt ){ @@ -5456,7 +5471,13 @@ static void shellFinalize( } } -static void shellReset( +/* Reset the prepared statement created using shellPreparePrintf(). +** +** This routine is could be marked "static". But it is not always used, +** depending on compile-time options. By omitting the "static", we avoid +** nuisance compiler warnings about "defined but not used". +*/ +void shellReset( int *pRc, sqlite3_stmt *pStmt ){ From 90255b814923d03eb68c33f60ed29fbbbe977e31 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 10 May 2019 20:44:10 +0000 Subject: [PATCH 123/132] Add tests for the RBU module. FossilOrigin-Name: a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf --- ext/rbu/rbufault2.test | 9 +++ ext/rbu/rbumisc.test | 122 +++++++++++++++++++++++++++++++++++++---- ext/rbu/sqlite3rbu.c | 37 ++++++------- manifest | 21 ++++--- manifest.uuid | 2 +- src/test_vfs.c | 4 +- 6 files changed, 152 insertions(+), 43 deletions(-) diff --git a/ext/rbu/rbufault2.test b/ext/rbu/rbufault2.test index 5b006f78ea..36f2b6b6f2 100644 --- a/ext/rbu/rbufault2.test +++ b/ext/rbu/rbufault2.test @@ -52,6 +52,15 @@ do_faultsim_test 1 -faults oom* -prep { } +sqlite3rbu_create_vfs -default rbu "" +sqlite3 db test.db +set ::vfsname [file_control_vfsname db] +do_faultsim_test 2 -faults oom* -prep { +} -body { + file_control_vfsname db +} +db close +sqlite3rbu_destroy_vfs rbu finish_test diff --git a/ext/rbu/rbumisc.test b/ext/rbu/rbumisc.test index d8fe030b48..c2a3906c09 100644 --- a/ext/rbu/rbumisc.test +++ b/ext/rbu/rbumisc.test @@ -18,14 +18,7 @@ sqlite3_shutdown sqlite3_config_uri 1 reset_db -#------------------------------------------------------------------------- -# Ensure that RBU is not confused by oddly named tables in an RBU -# database. -# -do_execsql_test 1.0 { - CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY); -} -do_test 1.1 { +proc populate_rbu_db {} { forcedelete rbu.db sqlite3 rbu rbu.db rbu eval { @@ -44,6 +37,17 @@ do_test 1.1 { INSERT INTO dat VALUES(3, 3, 3, 0); } rbu close +} + +#------------------------------------------------------------------------- +# Ensure that RBU is not confused by oddly named tables in an RBU +# database. +# +do_execsql_test 1.0 { + CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY); +} +do_test 1.1 { + populate_rbu_db } {} do_test 1.2 { @@ -62,9 +66,7 @@ do_test 1.3 { do_test 1.4 { db eval { DELETE FROM x1 } - sqlite3 rbu rbu.db - rbu eval { DELETE FROM rbu_state } - rbu close + populate_rbu_db sqlite3rbu rbu test.db rbu.db rbu step @@ -77,4 +79,102 @@ do_test 1.4 { list [catch { rbu close } msg] $msg } {1 {SQLITE_ERROR - cannot update wal mode database}} +#------------------------------------------------------------------------- +# Test the effect of a wal file appearing after the target database has +# been opened, but before it has been locked. +# +catch { db close } +testvfs tvfs -default 1 + +for {set N 1} {$N < 10} {incr N} { + reset_db + populate_rbu_db + do_execsql_test 2.$N.0 { + CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY); + } + + set nAccessCnt 0 + do_test 2.$N.1 { + sqlite3rbu rbu test.db rbu.db + rbu step + rbu step + rbu close + } {SQLITE_OK} + + tvfs script xAccess + tvfs filter xAccess + set nAccessCnt 0 + proc xAccess {method file args} { + global nAccessCnt + if {[file tail $file]=="test.db-wal"} { + incr nAccessCnt -1 + if {$nAccessCnt==0} { + set fd [open test.db-wal w] + puts -nonewline $fd [string repeat 0 2000] + close $fd + } + } + return SQLITE_OK + } + + foreach r { + {1 {SQLITE_ERROR - cannot update wal mode database}} + {0 SQLITE_OK} + {1 {SQLITE_CANTOPEN - unable to open database file}} + } { + set RES($r) 1 + } + do_test 2.$N.2 { + set ::nAccessCnt $N + set res [list [catch { + sqlite3rbu rbu test.db rbu.db + rbu step + rbu close + } msg ] $msg] + set RES($res) + } {1} + catch {rbu close} +} +catch {db close} +catch {tvfs delete} + +#------------------------------------------------------------------------- +testvfs tvfs -default 1 +reset_db +populate_rbu_db +do_execsql_test 3.0 { + CREATE TABLE x1(a, b, c INTEGER PRIMARY KEY); +} + +tvfs script xFileControl +tvfs filter xFileControl + +proc xFileControl {method file verb args} { + if {$verb=="ZIPVFS" && [info exists ::zipvfs_filecontrol]} { + return $::zipvfs_filecontrol + } + return "SQLITE_NOTFOUND" +} + +breakpoint +foreach {tn ret err} { + 1 SQLITE_OK 0 + 2 SQLITE_ERROR 1 + 3 SQLITE_NOTFOUND 0 + 4 SQLITE_OMIT 1 +} { + set ::zipvfs_filecontrol $ret + do_test 3.$tn.1 { + catch { + sqlite3rbu rbu test.db rbu.db + rbu step + rbu close + } + } $err +} +catch {db close} +catch {tvfs delete} + +#------------------------------------------------------------------------- + finish_test diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 481d01eafc..a4fbeb614e 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -4707,9 +4707,7 @@ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; - if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ - rbuMainlistAdd(p); - } + rbuMainlistAdd(p); if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } @@ -4772,10 +4770,7 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY; }else{ int bCapture = 0; - if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE) - && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE - && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0) - ){ + if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ bCapture = 1; } @@ -4808,20 +4803,24 @@ static int rbuVfsShmMap( ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space ** instead of a file on disk. */ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); - if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){ - if( iRegion<=p->nShm ){ - sqlite3_int64 nByte = (iRegion+1) * sizeof(char*); - char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte); - if( apNew==0 ){ - rc = SQLITE_NOMEM; - }else{ - memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm)); - p->apShm = apNew; - p->nShm = iRegion+1; - } + if( eStage==RBU_STAGE_OAL ){ + sqlite3_int64 nByte = (iRegion+1) * sizeof(char*); + char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte); + + /* This is an RBU connection that uses its own heap memory for the + ** pages of the *-shm file. Since no other process can have run + ** recovery, the connection must request *-shm pages in order + ** from start to finish. */ + assert( iRegion==p->nShm ); + if( apNew==0 ){ + rc = SQLITE_NOMEM; + }else{ + memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm)); + p->apShm = apNew; + p->nShm = iRegion+1; } - if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){ + if( rc==SQLITE_OK ){ char *pNew = (char*)sqlite3_malloc64(szRegion); if( pNew==0 ){ rc = SQLITE_NOMEM; diff --git a/manifest b/manifest index bf5bd20228..05c19cba8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2019-05-10T17:54:58.895 +C Add\stests\sfor\sthe\sRBU\smodule. +D 2019-05-10T20:44:10.289 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -345,11 +345,11 @@ F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b F ext/rbu/rbudiff.test 156957851136b63c143478518dc1bda6c832103cdbe8ac1d7cdd47edb3cbe0a3 F ext/rbu/rbudor.test e3e8623926012f43eebe51fedf06a102df2640750d971596b052495f2536db20 F ext/rbu/rbufault.test 2d7f567b79d558f6e093c58808cab4354f8a174e3802f69e7790a9689b3c09f8 -F ext/rbu/rbufault2.test 06e735c002c17802d93debca41f59b027e7429db7de17f2a81318ecfd3c651d4 +F ext/rbu/rbufault2.test c81327a3ac2c385b9b954db3644d4e0df93eeebfc3de9f1f29975a1e73fd3d0c F ext/rbu/rbufault3.test b2fcc9db5c982b869f67d1d4688d8cb515d5b92f58011fff95665f2e62cec179 F ext/rbu/rbufault4.test 03d2849c3df7d7bd14a622e789ff049e5080edd34a79cd432e01204db2a5930a F ext/rbu/rbufts.test 0ae8d1da191c75bd776b86e24456db0fb6e97b7c944259fae5407ea55d23c31d -F ext/rbu/rbumisc.test df6201ac3263ac8c68c4f1a4803d8c006c241102eb1d30d8074b0c14e59de335 +F ext/rbu/rbumisc.test 329986cf5dd51890c4eb906c2f960ebb773a79a64bed90f506b7c417825b37eb F ext/rbu/rbumulti.test 5fb139058f37ddc5a113c5b93238de915b769b7792de41b44c983bc7c18cf5b9 F ext/rbu/rbupartial.test 1c8bd6d42615b94caf08f129f5817fa26975523f0f51bceda1dca90e8114c7c4 F ext/rbu/rbuprogress.test 04614ff8820bab9c1ec1b7dbec1edc4b45474421d4fe7abbd2a879a9c02884f9 @@ -361,7 +361,7 @@ F ext/rbu/rbuvacuum.test 55e101e90168c2b31df6c9638fe73dc7f7cc666b6142266d1563697 F ext/rbu/rbuvacuum2.test b8e5b51dc8b2c0153373d024c0936be3f66f9234acbd6d0baab0869d56b14e6b F ext/rbu/rbuvacuum3.test 8addd82e4b83b4c93fa47428eae4fd0dbf410f8512c186f38e348feb49ba03dc F ext/rbu/rbuvacuum4.test a78898e438a44803eb2bc897ba3323373c9f277418e2d6d76e90f2f1dbccfd10 -F ext/rbu/sqlite3rbu.c 311fe2c2bc73e2ddb9ee8eb10be35aca90f6074869734671f615270b1a1ce283 +F ext/rbu/sqlite3rbu.c 8741c0ee1496b41ff888b983a1a32547bc8822602603c68b3e524e5e0e287395 F ext/rbu/sqlite3rbu.h 1dc88ab7bd32d0f15890ea08d23476c4198d3da3056985403991f8c9cd389812 F ext/rbu/test_rbu.c 03f6f177096a5f822d68d8e4069ad8907fe572c62ff2d19b141f59742821828a F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 @@ -578,7 +578,7 @@ F src/test_tclsh.c eeafce33ad2136d57e5dec10f1e9a4347447eb72ffd504a1c7b9c6bfe2e71 F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858 F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 -F src/test_vfs.c 0868f1d4d7cdc7c6df60e895ca26b19e4f433dd1be0fc9c18c3ee63755804039 +F src/test_vfs.c 32618cbd953963278804bb47e97be7085d9e0d8755b1e734c3e54e9b9e115277 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215 @@ -1825,8 +1825,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 2846bc0429c0956473bfe99dde135f2c206720f0be4c2800118b280e446ce325 ca068d82387fc3cda9d2050cedb4f9c61b6d9dc54f89015b4b2ee492243ed5c9 -R a374a86e729efdadd775e6bfeb83ab34 -T +closed ca068d82387fc3cda9d2050cedb4f9c61b6d9dc54f89015b4b2ee492243ed5c9 -U drh -Z 58072126b73b126150a44fa2fc1abfc6 +P 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362 +R aedd4a737d702eedb0953d5c2736092f +U dan +Z e9d784d22aa55b9ee9b4a684291d2b0b diff --git a/manifest.uuid b/manifest.uuid index 366b7cbb62..27d0a83e5a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362 \ No newline at end of file +a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf \ No newline at end of file diff --git a/src/test_vfs.c b/src/test_vfs.c index 43e872bb3b..3357a0a27d 100644 --- a/src/test_vfs.c +++ b/src/test_vfs.c @@ -235,6 +235,7 @@ static int tvfsResultCode(Testvfs *p, int *pRc){ { SQLITE_BUSY, "SQLITE_BUSY" }, { SQLITE_READONLY, "SQLITE_READONLY" }, { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT" }, + { SQLITE_NOTFOUND, "SQLITE_NOTFOUND" }, { -1, "SQLITE_OMIT" }, }; @@ -552,6 +553,7 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){ } aF[] = { { SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, "BEGIN_ATOMIC_WRITE" }, { SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, "COMMIT_ATOMIC_WRITE" }, + { SQLITE_FCNTL_ZIPVFS, "ZIPVFS" }, }; int i; for(i=0; ipReal, op, pArg); From 8f2b1e4c909df912209c34816ae33bf31cbb20b8 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 11 May 2019 13:04:33 +0000 Subject: [PATCH 124/132] Do not assume that "x IS NOT ?" implies "x NOT NULL" when considering partial indexes. Fix for ticket [8025674847]. FossilOrigin-Name: 0ba6d709b50d92db1542f2ff30535a80184b00dadf759d51e5cae7a6e37b1764 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 1 + test/index6.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 05c19cba8b..4f454bd521 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\sthe\sRBU\smodule. -D 2019-05-10T20:44:10.289 +C Do\snot\sassume\sthat\s"x\sIS\sNOT\s?"\simplies\s"x\sNOT\sNULL"\swhen\sconsidering\spartial\sindexes.\sFix\sfor\sticket\s[8025674847]. +D 2019-05-11T13:04:33.943 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -473,7 +473,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 55e71df830d43bfedd2910e45b097c445a493978b21a0544a54011db1d2fa933 +F src/expr.c ff970039f7225f3693b27e5430581d1b85fd0f4c4c1c6fa2feb2886a4ed8bb38 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 08d6d07d138735dd79f12a2b0c623d1dc9270d0eea61b8be584625391ef84475 @@ -1038,7 +1038,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 448fa05f5d78f5feee4832fe4017dede4ccbc660601fb7e84d02329389cb638c +F test/index6.test f9359034f186a531af03ca803aa59ff50924b8dddc21c154b4c68a26793e06b8 F test/index7.test be02a0b4e53ac4ad7db4995fe02b428597a2e104c4f574b0d4b2f6b082e96b28 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1825,7 +1825,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 956ca2a452aa3707bca553007a7ef221af3d4f6b0af747d17070926e000f2362 -R aedd4a737d702eedb0953d5c2736092f +P a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf +R 1eaf665d4f98aadb9f3ca769035a618a U dan -Z e9d784d22aa55b9ee9b4a684291d2b0b +Z c47b7568ffb329afbb8bfb66234d0550 diff --git a/manifest.uuid b/manifest.uuid index 27d0a83e5a..75e75c75a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf \ No newline at end of file +0ba6d709b50d92db1542f2ff30535a80184b00dadf759d51e5cae7a6e37b1764 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 940abc1ae0..c69fb4a565 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4946,6 +4946,7 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS + && pE1->op!=TK_ISNOT && pE1->op!=TK_OR ){ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); diff --git a/test/index6.test b/test/index6.test index bb3f629cc2..db75ffb522 100644 --- a/test/index6.test +++ b/test/index6.test @@ -423,4 +423,15 @@ do_execsql_test index6-13.1 { SELECT * FROM t0 WHERE c0 OR 1; } {{}} +# 2019-05-11 +# Ticket https://sqlite.org/src/tktview/8025674847 +reset_db +do_execsql_test index6-14.1 { + CREATE TABLE IF NOT EXISTS t0 (c0, c1); + CREATE INDEX IF NOT EXISTS i0 ON t0(c0, c1) WHERE c0 NOT NULL; + INSERT INTO t0(c0, c1) VALUES(NULL, 'row'); + SELECT * FROM t0 WHERE t0.c0 IS NOT 1; +} {{} row} + finish_test + From c6824c8d6c2def197044cad984481eb981d38998 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 11 May 2019 16:14:42 +0000 Subject: [PATCH 125/132] When considering partial indexes, do not assume that a "CASE x ..." expression implies "x IS NOT NULL". FossilOrigin-Name: 1b24303220b7b4f59520176a0150fc619c668865450b4fdaa9ce4113a56e9687 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 1 + test/index6.test | 4 ++++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4f454bd521..2f69eeca87 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sassume\sthat\s"x\sIS\sNOT\s?"\simplies\s"x\sNOT\sNULL"\swhen\sconsidering\spartial\sindexes.\sFix\sfor\sticket\s[8025674847]. -D 2019-05-11T13:04:33.943 +C When\sconsidering\spartial\sindexes,\sdo\snot\sassume\sthat\sa\s"CASE\sx\s..."\sexpression\simplies\s"x\sIS\sNOT\sNULL". +D 2019-05-11T16:14:42.493 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -473,7 +473,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c ff970039f7225f3693b27e5430581d1b85fd0f4c4c1c6fa2feb2886a4ed8bb38 +F src/expr.c de746e2fc5ee48441b1210fba9a39160981718430e6a75b3a2ba29a99957cb71 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 08d6d07d138735dd79f12a2b0c623d1dc9270d0eea61b8be584625391ef84475 @@ -1038,7 +1038,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test f9359034f186a531af03ca803aa59ff50924b8dddc21c154b4c68a26793e06b8 +F test/index6.test a6cf96bb70bf57b2221e102060a18af46bc366f704722f410d6f42c13a75534a F test/index7.test be02a0b4e53ac4ad7db4995fe02b428597a2e104c4f574b0d4b2f6b082e96b28 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1825,7 +1825,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 a194e53670e25a48c2bb51b54755abff88ed6ae2596c5858fb4aac16cb452bdf -R 1eaf665d4f98aadb9f3ca769035a618a +P 0ba6d709b50d92db1542f2ff30535a80184b00dadf759d51e5cae7a6e37b1764 +R eed45e78e88ca93286620dd3277355ae U dan -Z c47b7568ffb329afbb8bfb66234d0550 +Z 697971a2288076e83fc4830e959d8147 diff --git a/manifest.uuid b/manifest.uuid index 75e75c75a5..a33bef3c01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ba6d709b50d92db1542f2ff30535a80184b00dadf759d51e5cae7a6e37b1764 \ No newline at end of file +1b24303220b7b4f59520176a0150fc619c668865450b4fdaa9ce4113a56e9687 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c69fb4a565..05b50c1e62 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4948,6 +4948,7 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ && pE1->op!=TK_IS && pE1->op!=TK_ISNOT && pE1->op!=TK_OR + && pE1->op!=TK_CASE ){ Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); testcase( pX!=pE1->pLeft ); diff --git a/test/index6.test b/test/index6.test index db75ffb522..b271954b28 100644 --- a/test/index6.test +++ b/test/index6.test @@ -433,5 +433,9 @@ do_execsql_test index6-14.1 { SELECT * FROM t0 WHERE t0.c0 IS NOT 1; } {{} row} +do_execsql_test index6-14.2 { + SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END; +} {{} row} + finish_test From c51cf8642f867050c8cb9e330582605dabeff76c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 11 May 2019 19:36:03 +0000 Subject: [PATCH 126/132] A new implementation for the sqlite3ExprImpliesExpr() theorem prover that does a better job of answering TRUE to "(NOT A) OR B" when B is a NOT NULL expression. FossilOrigin-Name: b3413197f57711f04102d8cc6ff1e8ddbe0f5f2bcb6e1989cf314fa97f0ff7f1 --- manifest | 14 ++++----- manifest.uuid | 2 +- src/expr.c | 80 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 2f69eeca87..2b05533af9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sconsidering\spartial\sindexes,\sdo\snot\sassume\sthat\sa\s"CASE\sx\s..."\sexpression\simplies\s"x\sIS\sNOT\sNULL". -D 2019-05-11T16:14:42.493 +C A\snew\simplementation\sfor\sthe\ssqlite3ExprImpliesExpr()\stheorem\sprover\sthat\ndoes\sa\sbetter\sjob\sof\sanswering\sTRUE\sto\s"(NOT\sA)\sOR\sB"\swhen\sB\sis\sa\sNOT\sNULL\nexpression. +D 2019-05-11T19:36:03.376 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -473,7 +473,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c de746e2fc5ee48441b1210fba9a39160981718430e6a75b3a2ba29a99957cb71 +F src/expr.c a41e5a03d60e2d99a8eac1535f21258e3833b29a3f52789e76284d97b54bed5f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 0e14d4bef8eac2d87bbd517e492d9084c65008d117823f8922c5e7b2b599bd33 F src/func.c 08d6d07d138735dd79f12a2b0c623d1dc9270d0eea61b8be584625391ef84475 @@ -1825,7 +1825,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 0ba6d709b50d92db1542f2ff30535a80184b00dadf759d51e5cae7a6e37b1764 -R eed45e78e88ca93286620dd3277355ae -U dan -Z 697971a2288076e83fc4830e959d8147 +P 1b24303220b7b4f59520176a0150fc619c668865450b4fdaa9ce4113a56e9687 +R a0d6bf1f0575775c4809b4d1861fc898 +U drh +Z 5104434a3315d7327fcd08f55bb43328 diff --git a/manifest.uuid b/manifest.uuid index a33bef3c01..dad98559cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b24303220b7b4f59520176a0150fc619c668865450b4fdaa9ce4113a56e9687 \ No newline at end of file +b3413197f57711f04102d8cc6ff1e8ddbe0f5f2bcb6e1989cf314fa97f0ff7f1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 05b50c1e62..a905c28c9b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4908,6 +4908,76 @@ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ iTab); } +/* +** Return non-zero if Expr p can only be true if pNN is not NULL. +*/ +static int exprImpliesNotNull( + Parse *pParse, /* Parsing context */ + Expr *p, /* The expression to be checked */ + Expr *pNN, /* The expression that is NOT NULL */ + int iTab, /* Table being evaluated */ + int seenNot /* True if p is an operand of NOT */ +){ + assert( p ); + assert( pNN ); + if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ) return 1; + switch( p->op ){ + case TK_IN: { + if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; + assert( ExprHasProperty(p,EP_xIsSelect) + || (p->x.pList!=0 && p->x.pList->nExpr>0) ); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_BETWEEN: { + ExprList *pList = p->x.pList; + assert( pList!=0 ); + assert( pList->nExpr==2 ); + if( seenNot ) return 0; + if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot) + || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot) + ){ + return 1; + } + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_EQ: + case TK_NE: + case TK_LT: + case TK_LE: + case TK_GT: + case TK_GE: + case TK_PLUS: + case TK_MINUS: + case TK_STAR: + case TK_REM: + case TK_BITAND: + case TK_BITOR: + case TK_SLASH: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: { + if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1; + /* Fall thru into the next case */ + } + case TK_SPAN: + case TK_COLLATE: + case TK_BITNOT: + case TK_UPLUS: + case TK_UMINUS: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_TRUTH: { + if( seenNot ) return 0; + if( p->op2!=TK_IS ) return 0; + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + } + case TK_NOT: { + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); + } + } + return 0; +} + /* ** Return true if we can prove the pE2 will always be true if pE1 is ** true. Return false if we cannot complete the proof or if pE2 might @@ -4944,15 +5014,9 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ return 1; } if( pE2->op==TK_NOTNULL - && pE1->op!=TK_ISNULL - && pE1->op!=TK_IS - && pE1->op!=TK_ISNOT - && pE1->op!=TK_OR - && pE1->op!=TK_CASE + && exprImpliesNotNull(pParse, pE1, pE2->pLeft, iTab, 0) ){ - Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); - testcase( pX!=pE1->pLeft ); - if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1; + return 1; } return 0; } From d6712f363895e8634c396aae55a1257500337c34 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 13 May 2019 11:52:19 +0000 Subject: [PATCH 127/132] Fix an assert() failure in fts5 that could occur when processing a corrupt database. FossilOrigin-Name: f158c048be1dc7c80d38787a20495caa55b86416967efd57f4888548d42b4819 --- ext/fts5/fts5_buffer.c | 5 + ext/fts5/fts5_index.c | 3 + ext/fts5/test/fts5corrupt3.test | 207 ++++++++++++++++++++++++++++++++ manifest | 18 +-- manifest.uuid | 2 +- 5 files changed, 225 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_buffer.c b/ext/fts5/fts5_buffer.c index 84bdf63189..cb768ebb15 100644 --- a/ext/fts5/fts5_buffer.c +++ b/ext/fts5/fts5_buffer.c @@ -186,6 +186,11 @@ int sqlite3Fts5PoslistNext64( fts5FastGetVarint32(a, i, iVal); iOff = ((i64)iVal) << 32; fts5FastGetVarint32(a, i, iVal); + if( iVal<2 ){ + /* This is a corrupt record. So stop parsing it here. */ + *piOff = -1; + return 1; + } } *piOff = iOff + ((iVal-2) & 0x7FFFFFFF); *pi = i; diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 2bdeab1868..723306b4ce 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4965,6 +4965,7 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); fts5DoclistIterNext(&i1); if( i1.aPoslist==0 ) break; + assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); } else if( i2.iRowid!=i1.iRowid ){ /* Copy entry from i2 */ @@ -4972,6 +4973,7 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); fts5DoclistIterNext(&i2); if( i2.aPoslist==0 ) break; + assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); } else{ /* Merge the two position lists. */ @@ -5045,6 +5047,7 @@ static void fts5MergePrefixLists( fts5DoclistIterNext(&i2); assert( out.n<=(p1->n+p2->n+9) ); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; + assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); } } diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 6c3767bbc0..7b052aac91 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -25,6 +25,8 @@ ifcapable !fts5 { sqlite3_fts5_may_be_corrupt 1 database_may_be_corrupt +if 0 { + proc create_t1 {} { expr srand(0) db func rnddoc fts5_rnddoc @@ -8338,6 +8340,211 @@ do_execsql_test 58.1 { SELECT * FROM t1('t*'); } {{} {} {} {} {} {}} +} + +#------------------------------------------------------------------------- +do_test 59.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-96b136358d01ec.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..= +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N..... +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 02 01 02 01 f1 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 00 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase........... +| 3680: 06 01 02 02 13 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 0a 22 74 72 65 65 19 02 03 01 02 03 01 02 03 ...tree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 45 ed 0XRTRIM.!..3..E. +| 3168: 49 54 20 4c 4f 41 44 21 45 58 54 45 4e 53 49 4f IT LOAD!EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 5a 29 MIT LOAD EXTENZ) +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2 +| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE. +| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 76 35 58 52 54 52 49 4d 18 15 05 10 25 MSYv5XRTRIM....% +| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 5f 81 42 4c NARY....)..E_.BL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 1a 45 4e 41 42 4c 45 20 56 54 43 35 58 42 49 ..ENABLE VTC5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE... +| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?. +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 00 E.`YLER=gcc-5.4. +| page 6 offset 20480 +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 10 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 07 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 4048: 00 00 00 00 00 00 5d 03 02 2b 69 6e 74 00 00 00 ......]..+int... +| end crash-96b136358d01ec.db +}]} {} + +do_catchsql_test 59.1 { + SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ' +} {0 {}} + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 2b05533af9..cb1cc848a0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\snew\simplementation\sfor\sthe\ssqlite3ExprImpliesExpr()\stheorem\sprover\sthat\ndoes\sa\sbetter\sjob\sof\sanswering\sTRUE\sto\s"(NOT\sA)\sOR\sB"\swhen\sB\sis\sa\sNOT\sNULL\nexpression. -D 2019-05-11T19:36:03.376 +C Fix\san\sassert()\sfailure\sin\sfts5\sthat\scould\soccur\swhen\sprocessing\sa\scorrupt\sdatabase. +D 2019-05-13T11:52:19.622 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -112,11 +112,11 @@ F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7 F ext/fts5/fts5Int.h 5c26dce0ec9272fca726c6fddb92f634d0c912d4ca170330270d488a94b80416 F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa -F ext/fts5/fts5_buffer.c 43eecc62f191138815211c411481ef327e1d8b555b212b3039e631e7ecc2fb1a +F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c 9146da94d0b9f62217c6ad234342fda3fbac3c254455d0b3f53957ad85262e08 +F ext/fts5/fts5_index.c eb6064265d602939e5dbf74da6dd64940a651927d6b42f2e86885fca25e38831 F ext/fts5/fts5_main.c abd04720e2729ba5bab2648d9d541faab18f45d481ae21fc30f125b55e979d6b F ext/fts5/fts5_storage.c b24f6916fcdd68989a549f25962f286bdba9d9d59c7581567a6a0eb647cd07cc F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test fcf7963940e85d4d2e581b7804280215759377d94c03c4dcd5ed35e596b15989 +F ext/fts5/test/fts5corrupt3.test 954042e7e2ba7171ee50eac04e8533e4b0592cfd899c8118242bdb3251e74137 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -1825,7 +1825,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 1b24303220b7b4f59520176a0150fc619c668865450b4fdaa9ce4113a56e9687 -R a0d6bf1f0575775c4809b4d1861fc898 -U drh -Z 5104434a3315d7327fcd08f55bb43328 +P b3413197f57711f04102d8cc6ff1e8ddbe0f5f2bcb6e1989cf314fa97f0ff7f1 +R 2a4c6e150dd099a09e162eacd298a0cc +U dan +Z a4a14890a7c8c850f9b05b5bdb4389a1 diff --git a/manifest.uuid b/manifest.uuid index dad98559cb..90437d6c8e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3413197f57711f04102d8cc6ff1e8ddbe0f5f2bcb6e1989cf314fa97f0ff7f1 \ No newline at end of file +f158c048be1dc7c80d38787a20495caa55b86416967efd57f4888548d42b4819 \ No newline at end of file From bf9ff256fe17526a995ac3e470aa120c3c173414 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 May 2019 00:43:13 +0000 Subject: [PATCH 128/132] Disable index seek optimizations on REINDEX when the order of primary keys in the index differs from the main table. Fix for ticket [bba7b69f9849b5bf11b4]. FossilOrigin-Name: f7aadfab3bb8eb8eb2cd62dc8a6823538387b3329f1efc23ef75482488109478 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/build.c | 15 ++++++++++++++- src/sqliteInt.h | 1 + test/without_rowid1.test | 10 ++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index cb1cc848a0..d457c8b8a2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sfailure\sin\sfts5\sthat\scould\soccur\swhen\sprocessing\sa\scorrupt\sdatabase. -D 2019-05-13T11:52:19.622 +C Disable\sindex\sseek\soptimizations\son\sREINDEX\swhen\sthe\sorder\sof\sprimary\skeys\nin\sthe\sindex\sdiffers\sfrom\sthe\smain\stable.\nFix\sfor\sticket\s[bba7b69f9849b5bf11b4]. +D 2019-05-14T00:43:13.593 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -465,7 +465,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 5e15f903fd44b076b864a8d2449d63b44a546efabb66fca7dfed90f106f5c756 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 23e9332b260cd0e45f6cbfabe711957a0776ea3ff836746378868fdfa64d267b +F src/build.c aead3d74794ed4dac396fdd9323ba2272e3734f07c5d7f1f57389e5afbd99f3f F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b @@ -526,7 +526,7 @@ F src/shell.c.in 6c992809abf20dbb4aad89299d7c15c98ddf2504b23c83ef71eb435ad392cdc F src/sqlite.h.in 0605c88d98c85fbcba8bbd9716e7cc10b361e7b21cf2375171130f577388c943 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 443270b81c96101914eadd4e649d2f8210f4bbed569a6ff5ca8facfc74e20f26 +F src/sqliteInt.h b78a1f0bdc46582f33876932f8b45a264be7ee4f3f6c31102f924d33fa6177ee F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1711,7 +1711,7 @@ F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1 F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 -F test/without_rowid1.test 7ac016d20317e36a2f142e960679e558e74f6809ce5f27bde668af01782500df +F test/without_rowid1.test 89d101a7c6e0802882002cf3713f405319ddb6b9f08449dcc08c6082c995cab1 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 F test/without_rowid3.test ea4b59dd1b0d7f5f5e4b7cca978cdb905752a9d7c57dc4344a591dba765a3691 F test/without_rowid4.test 4e08bcbaee0399f35d58b5581881e7a6243d458a @@ -1825,7 +1825,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 b3413197f57711f04102d8cc6ff1e8ddbe0f5f2bcb6e1989cf314fa97f0ff7f1 -R 2a4c6e150dd099a09e162eacd298a0cc -U dan -Z a4a14890a7c8c850f9b05b5bdb4389a1 +P f158c048be1dc7c80d38787a20495caa55b86416967efd57f4888548d42b4819 +R 404403301e9bcfd1f3d9ba51048e4c01 +U drh +Z 42029a898fbfd7e561e50bfc3fb1e10f diff --git a/manifest.uuid b/manifest.uuid index 90437d6c8e..7398d5e16f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f158c048be1dc7c80d38787a20495caa55b86416967efd57f4888548d42b4819 \ No newline at end of file +f7aadfab3bb8eb8eb2cd62dc8a6823538387b3329f1efc23ef75482488109478 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 935f132d6c..ac6789ee80 100644 --- a/src/build.c +++ b/src/build.c @@ -1928,6 +1928,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ testcase( hasColumn(pIdx->aiColumn, pIdx->nKeyCol, pPk->aiColumn[i]) ); pIdx->aiColumn[j] = pPk->aiColumn[i]; pIdx->azColl[j] = pPk->azColl[i]; + if( pPk->aSortOrder[i] ){ + /* See ticket https://www.sqlite.org/src/info/bba7b69f9849b5bf */ + pIdx->bAscKeyBug = 1; + } j++; } } @@ -3049,7 +3053,16 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ addr2 = sqlite3VdbeCurrentAddr(v); } sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); - sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); + if( !pIndex->bAscKeyBug ){ + /* This OP_SeekEnd opcode makes index insert for a REINDEX go much + ** faster by avoiding unnecessary seeks. But the optimization does + ** not work for UNIQUE constraint indexes on WITHOUT ROWID tables + ** with DESC primary keys, since those indexes have there keys in + ** a different order from the main table. + ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf + */ + sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); + } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3ReleaseTempReg(pParse, regRecord); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e6b3aeca18..2056d5a5a5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2253,6 +2253,7 @@ struct Index { unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ + unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 int nSample; /* Number of elements in aSample[] */ int nSampleCol; /* Size of IndexSample.anEq[] and so on */ diff --git a/test/without_rowid1.test b/test/without_rowid1.test index 4dd967234c..3832239a41 100644 --- a/test/without_rowid1.test +++ b/test/without_rowid1.test @@ -399,5 +399,15 @@ do_execsql_test 11.1 { PRAGMA integrity_check; SELECT a FROM t11 ORDER BY a COLLATE binary; } {ok A a} + +# 2019-05-13 ticket https://www.sqlite.org/src/info/bba7b69f9849b5b +do_execsql_test 12.1 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0 (c0 INTEGER PRIMARY KEY DESC, c1 UNIQUE DEFAULT NULL) WITHOUT ROWID; + INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5); + REINDEX; + PRAGMA integrity_check; +} {ok} + finish_test From c12655df87805b40eb6cf203a17ff3bc977f3574 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2019 11:33:09 +0000 Subject: [PATCH 129/132] Fix an assert() and potential buffer overrun in fts5 that could occur if the database was corrupt. FossilOrigin-Name: 8be8bd0d562e571b73a93f4ed18258ebd114bbab67ee3cdcd66a4c8f2987f8dc --- ext/fts5/fts5_index.c | 25 ++-- ext/fts5/test/fts5corrupt3.test | 228 ++++++++++++++++++++++++++++++-- manifest | 18 +-- manifest.uuid | 2 +- test/reindex.test | 34 +++++ 5 files changed, 277 insertions(+), 30 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 723306b4ce..da5293a194 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4953,8 +4953,14 @@ static void fts5MergePrefixLists( ** first rowid in one input is a large negative number, and the first in ** the other a non-negative number, the delta for the non-negative ** number will be larger on disk than the literal integer value - ** was. */ - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return; + ** was. + ** + ** Or, if the input position-lists are corrupt, then the output might + ** include up to 2 extra 10-byte positions created by interpreting -1 + ** (the value PoslistNext64() uses for EOF) as a position and appending + ** it to the output. This can happen at most once for each input + ** position-list, hence two 10 byte paddings. */ + if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); @@ -4965,7 +4971,7 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize); fts5DoclistIterNext(&i1); if( i1.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); + assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); } else if( i2.iRowid!=i1.iRowid ){ /* Copy entry from i2 */ @@ -4973,7 +4979,7 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); fts5DoclistIterNext(&i2); if( i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); + assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); } else{ /* Merge the two position lists. */ @@ -4997,7 +5003,7 @@ static void fts5MergePrefixLists( sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert( iPos1>=0 && iPos2>=0 ); + assert_nc( iPos1>=0 && iPos2>=0 ); if( iPos1=0 && iPos2>=0 ){ while( 1 ){ if( iPos1=0 && iPos2!=iPrev ); + assert_nc( iPos2>=0 && iPos2!=iPrev ); sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); aCopy = &a2[iOff2]; nCopy = i2.nPoslist - iOff2; @@ -5045,9 +5050,9 @@ static void fts5MergePrefixLists( fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); fts5DoclistIterNext(&i2); - assert( out.n<=(p1->n+p2->n+9) ); + assert_nc( out.n<=(p1->n+p2->n+9) ); if( i1.aPoslist==0 || i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist - p1->p) + (i2.aPoslist - p2->p) + 9) ); + assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); } } @@ -5059,7 +5064,7 @@ static void fts5MergePrefixLists( fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); } - assert( out.n<=(p1->n+p2->n+9) ); + assert_nc( out.n<=(p1->n+p2->n+9) ); fts5BufferSet(&p->rc, p1, out.n, out.p); fts5BufferFree(&tmp); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 7b052aac91..532464495d 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -25,8 +25,6 @@ ifcapable !fts5 { sqlite3_fts5_may_be_corrupt 1 database_may_be_corrupt -if 0 { - proc create_t1 {} { expr srand(0) db func rnddoc fts5_rnddoc @@ -5815,12 +5813,12 @@ do_execsql_test 44.1 { } {} do_catchsql_test 44.2 { -INSERT INTO t1(t1) VALUES('integrity-check'); + INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} -do_catchsql_test 44.2 { +do_catchsql_test 44.3 { SELECT snippet(t1, -1, '.', '..', '', 2 ) FROM t1('g h') ORDER BY rank; -} {1 {database disk image is malformed}} +} {0 {{.g.. .h..} {.g.. h} {.g.. .h..}}} #-------------------------------------------------------------------------- reset_db @@ -6420,11 +6418,17 @@ do_test 47.0 { }]} {} do_catchsql_test 47.1 { - SELECT snippet(t1, -1, '.', '..', '[', 50), - highlight(t1, 2, '[', ']') FROM t1('g h') - WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank; + INSERT INTO t1(t1) VALUES('integrity-check'); } {1 {database disk image is malformed}} +do_catchsql_test 47.2 { + SELECT count(*) FROM ( + SELECT snippet(t1, -1, '.', '..', '[', 50), + highlight(t1, 2, '[', ']') FROM t1('g h') + WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank + ) +} {0 3} + #-------------------------------------------------------------------------- reset_db do_test 48.0 { @@ -8340,8 +8344,6 @@ do_execsql_test 58.1 { SELECT * FROM t1('t*'); } {{} {} {} {} {} {}} -} - #------------------------------------------------------------------------- do_test 59.0 { sqlite3 db {} @@ -8545,6 +8547,212 @@ do_catchsql_test 59.1 { SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ' } {0 {}} +#------------------------------------------------------------------------- +do_test 60.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-c77b90b929dc92.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..= +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N..... +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase........... +| 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 01 0f 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 0f 00 00 00 00 00 00 00 ....$........... +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2 +| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE. +| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE... +| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?. +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2e E.`YLER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 30 39 68 52 54 52 49 4d 0 20160609hRTRIM +| page 6 offset 20480 +| 0: 0d 00 00 00 24 0e 00 00 00 00 00 00 00 00 00 00 ....$........... +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 4048: 00 00 00 00 00 00 5d 03 00 00 00 00 00 00 00 00 ......]......... +| end crash-c77b90b929dc92.db +}]} {} + + +do_catchsql_test 60.2 { + SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' +} {0 {}} + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index d457c8b8a2..8681022447 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sindex\sseek\soptimizations\son\sREINDEX\swhen\sthe\sorder\sof\sprimary\skeys\nin\sthe\sindex\sdiffers\sfrom\sthe\smain\stable.\nFix\sfor\sticket\s[bba7b69f9849b5bf11b4]. -D 2019-05-14T00:43:13.593 +C Fix\san\sassert()\sand\spotential\sbuffer\soverrun\sin\sfts5\sthat\scould\soccur\sif\sthe\sdatabase\swas\scorrupt. +D 2019-05-14T11:33:09.246 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -116,7 +116,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c eb6064265d602939e5dbf74da6dd64940a651927d6b42f2e86885fca25e38831 +F ext/fts5/fts5_index.c f417615c657e5869649c605baaf38b1343e12f9556f9472159c3f837f856e4e8 F ext/fts5/fts5_main.c abd04720e2729ba5bab2648d9d541faab18f45d481ae21fc30f125b55e979d6b F ext/fts5/fts5_storage.c b24f6916fcdd68989a549f25962f286bdba9d9d59c7581567a6a0eb647cd07cc F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 954042e7e2ba7171ee50eac04e8533e4b0592cfd899c8118242bdb3251e74137 +F ext/fts5/test/fts5corrupt3.test f39c345e397e9944ad4297f1e4c98770c98a1b424956f1de3a09747a0c98a537 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -1233,7 +1233,7 @@ F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8 F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d F test/regexp1.test 497ea812f264d12b6198d6e50a76be4a1973a9d8 F test/regexp2.test 40e894223b3d6672655481493f1be12012f2b33c -F test/reindex.test 44edd3966b474468b823d481eafef0c305022254 +F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d F test/releasetest.tcl 204efd3a87ec1d62da2efde42c673b18b955350a9d3c6ac0b4dbba5bc8595808 x F test/releasetest_data.tcl c3746248b5ad8f99a29020f83501bb25e024156ecc37e05c71c76da4fc8601c6 F test/resetdb.test 8062cf10a09d8c048f8de7711e94571c38b38168db0e5877ba7561789e5eeb2b @@ -1825,7 +1825,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 f158c048be1dc7c80d38787a20495caa55b86416967efd57f4888548d42b4819 -R 404403301e9bcfd1f3d9ba51048e4c01 -U drh -Z 42029a898fbfd7e561e50bfc3fb1e10f +P f7aadfab3bb8eb8eb2cd62dc8a6823538387b3329f1efc23ef75482488109478 +R c40ab242b742c2ab3032c340e3dd1b28 +U dan +Z a64fcb6cb643358df987a25d84c7c8e3 diff --git a/manifest.uuid b/manifest.uuid index 7398d5e16f..ca218f3491 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7aadfab3bb8eb8eb2cd62dc8a6823538387b3329f1efc23ef75482488109478 \ No newline at end of file +8be8bd0d562e571b73a93f4ed18258ebd114bbab67ee3cdcd66a4c8f2987f8dc \ No newline at end of file diff --git a/test/reindex.test b/test/reindex.test index 9d5ecd9ee2..88e489b0b1 100644 --- a/test/reindex.test +++ b/test/reindex.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix reindex # There is nothing to test if REINDEX is disable for this build. # @@ -168,4 +169,37 @@ do_test reindex-3.99 { db2 close } {} +#------------------------------------------------------------------------- +foreach {tn wo} {1 "" 2 "WITHOUT ROWID"} { + reset_db + eval [string map [list %without_rowid% $wo] { + do_execsql_test 4.$tn.0 { + CREATE TABLE t0 ( + c0 INTEGER PRIMARY KEY DESC, + c1 UNIQUE DEFAULT NULL + ) %without_rowid% ; + INSERT INTO t0(c0) VALUES (1), (2), (3), (4), (5); + SELECT c0 FROM t0 WHERE c1 IS NULL ORDER BY 1; + } {1 2 3 4 5} + + do_execsql_test 4.$tn.1 { + REINDEX; + } + + do_execsql_test 4.$tn.2 { + SELECT c0 FROM t0 WHERE c1 IS NULL ORDER BY 1; + } {1 2 3 4 5} + + do_execsql_test 4.$tn.3 { + SELECT c0 FROM t0 WHERE c1 IS NULL AND c0 IN (1,2,3,4,5); + } {1 2 3 4 5} + + do_execsql_test 4.$tn.4 { + PRAGMA integrity_check; + } {ok} + }] +} + + + finish_test From 2a71b17f2f879d89cb2dd5e6515d28e87d0fc316 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2019 18:33:58 +0000 Subject: [PATCH 130/132] Fix a problem with corrupt db handling in the fts5_vocab module. FossilOrigin-Name: 456ced57774a92acff23cad975b78ff0e5cbbf5204ea48599fe1761a018a92e4 --- ext/fts5/fts5_vocab.c | 6 +- ext/fts5/test/fts5corrupt3.test | 205 ++++++++++++++++++++++++++++++++ manifest | 14 +-- manifest.uuid | 2 +- 4 files changed, 217 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_vocab.c b/ext/fts5/fts5_vocab.c index 2550c9d6eb..36a3673814 100644 --- a/ext/fts5/fts5_vocab.c +++ b/ext/fts5/fts5_vocab.c @@ -573,8 +573,10 @@ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ } if( rc==SQLITE_OK && pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ - while( pCsr->aDoc[pCsr->iCol]==0 ) pCsr->iCol++; - assert( pCsr->iColpFts5->pConfig->nCol ); + for(/* noop */; pCsr->iColaDoc[pCsr->iCol]==0; pCsr->iCol++); + if( pCsr->iCol==nCol ){ + rc = FTS5_CORRUPT; + } } return rc; } diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 532464495d..7c8a0f57f6 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -8753,6 +8753,211 @@ do_catchsql_test 60.2 { SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' } {0 {}} +#------------------------------------------------------------------------- +do_test 61.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-e5fa281edabddf.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0f c7 00 06 0d b6 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 00 00 00 00 00 00 00 00 ...k............ +| 3504: 00 00 00 00 00 00 56 07 06 17 1f 1f 01 7d 74 61 ......V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 51 62 6c 65 74 31 5f 64 ..!!...tQblet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 63 6f 63 73 69 7a 65 ocsizet1_cocsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 ea 74 31 43 52 ...._tablet.t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 13 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 34 01 609...........4. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000... +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 11 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase........... +| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 01 13 05 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 01 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 0e 16 01 01 02 01 06 01 01 02 01 06 01 02 02 ................ +| 3888: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 07 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 e2 05 00 25 0f 19 54 48 52 45 41 NARY....%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 40 52 59 1f 20 05 00 33 0f 19 4f NXBIN@RY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4e 45 4d 4f 52 59 3d 35 30 30 30 30 MAX NEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 45 30 30 30 .MAX MEMORY=E000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 58 4e 4f 43 41 53 45 17 LE RTREEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 20 54 52 ...%..ENABLE TR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 41 53 45 E GEOPOLYXNOCASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 20 e5 54 53 35 58 42 49 ..ENABLE .TS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4d NARY....#..ENABM +| 3712: 45 b5 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E.FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 b7 4e 41 52 59 17 0b LE FTS4XB.NARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 53 9XNOCASE&...C..S +| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4. +| 4080: 30 20 32 2f 31 00 00 00 00 00 00 00 00 00 00 00 0 2/1........... +| page 6 offset 20480 +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 10 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 01 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-e5fa281edabddf.db +}]} {} + +do_execsql_test 61.1 { + CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' ); +} + +do_catchsql_test 62.2 { + SELECT * FROM t3 ORDER BY rowid; +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 8681022447..86cc341ce0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sand\spotential\sbuffer\soverrun\sin\sfts5\sthat\scould\soccur\sif\sthe\sdatabase\swas\scorrupt. -D 2019-05-14T11:33:09.246 +C Fix\sa\sproblem\swith\scorrupt\sdb\shandling\sin\sthe\sfts5_vocab\smodule. +D 2019-05-14T18:33:58.863 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -125,7 +125,7 @@ F ext/fts5/fts5_test_tok.c f96c6e193c466711d6d7828d5f190407fe7ab897062d371426dd3 F ext/fts5/fts5_tokenize.c 2e508c6a3bd8ee56c48e98a38052e1a650e49b32a484cce9b189984114bc3b88 F ext/fts5/fts5_unicode2.c 8bd0cd07396b74c1a05590e4070d635bccfc849812c305619f109e6c0485e250 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c 906dff069840347e68f654b12ca60a53a27cd1780daf155fbe7dd331f27c2329 +F ext/fts5/fts5_vocab.c c3f12188570abb423303cd193b16dd19ba54e21c2e930e9b748d743de3b385f5 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl b01c584144b5064f30e6c648145a2dd6bc440841 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test f39c345e397e9944ad4297f1e4c98770c98a1b424956f1de3a09747a0c98a537 +F ext/fts5/test/fts5corrupt3.test 9f64bc23eff5c89d01fdbf2214bf05109d5759ebb32c07d9740175fb80e2f89d F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 @@ -1825,7 +1825,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 f7aadfab3bb8eb8eb2cd62dc8a6823538387b3329f1efc23ef75482488109478 -R c40ab242b742c2ab3032c340e3dd1b28 +P 8be8bd0d562e571b73a93f4ed18258ebd114bbab67ee3cdcd66a4c8f2987f8dc +R ae1326fe299d3abb84fbb1e2ecc5f8dc U dan -Z a64fcb6cb643358df987a25d84c7c8e3 +Z da5a01c829807f2a55f0112dd5ff6c3a diff --git a/manifest.uuid b/manifest.uuid index ca218f3491..a3ee3372ad 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8be8bd0d562e571b73a93f4ed18258ebd114bbab67ee3cdcd66a4c8f2987f8dc \ No newline at end of file +456ced57774a92acff23cad975b78ff0e5cbbf5204ea48599fe1761a018a92e4 \ No newline at end of file From 9252966b3c67f90e265394a597297908fccf691b Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 14 May 2019 19:20:52 +0000 Subject: [PATCH 131/132] New test cases in test/fuzzdata8.db. FossilOrigin-Name: 228e1087c0602470e450586499de5a3e87e266c688bc828f20e3bad2fdc65ff1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fuzzdata8.db | Bin 1108992 -> 1204224 bytes 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 86cc341ce0..bb55f9a986 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\scorrupt\sdb\shandling\sin\sthe\sfts5_vocab\smodule. -D 2019-05-14T18:33:58.863 +C New\stest\scases\sin\stest/fuzzdata8.db. +D 2019-05-14T19:20:52.966 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1002,7 +1002,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db 2b13f8d7a4e475f164c733e64c9ebc459424ec58d0876ef103de62c1a99e2fca -F test/fuzzdata8.db 038627908808f88bad9c3ac90f3b7865766f92b2cfed585c7e083a792d554ade +F test/fuzzdata8.db ae3f4f364f798cd73b1769ca701878e40cbaa6fb8726a94148bce8062fada5c3 F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1825,7 +1825,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 8be8bd0d562e571b73a93f4ed18258ebd114bbab67ee3cdcd66a4c8f2987f8dc -R ae1326fe299d3abb84fbb1e2ecc5f8dc -U dan -Z da5a01c829807f2a55f0112dd5ff6c3a +P 456ced57774a92acff23cad975b78ff0e5cbbf5204ea48599fe1761a018a92e4 +R a35d827c3489311c2def9cf07d71c738 +U drh +Z 27e3b81356a63ddc975524d759c0b049 diff --git a/manifest.uuid b/manifest.uuid index a3ee3372ad..a951d6df08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -456ced57774a92acff23cad975b78ff0e5cbbf5204ea48599fe1761a018a92e4 \ No newline at end of file +228e1087c0602470e450586499de5a3e87e266c688bc828f20e3bad2fdc65ff1 \ No newline at end of file diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 1a7ef8bb923d68c877a79962c2041ba1ddbe4362..6505d563e744fe7417785090419cf82066cb06cb 100644 GIT binary patch delta 26590 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 IzhC@+0Q%R8wEzGB delta 18829 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 J+t&9D{vT%ho-+Ud From a40cb96a4c6f1313d076c0314925412c556d2e48 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 14 May 2019 20:25:22 +0000 Subject: [PATCH 132/132] Fix a problem with the fix for [9cf6c9bb51] (commit [658b84d7]) that could cause a cursor to be left in an invalid state following a (rowid < text-value) search. FossilOrigin-Name: bc7d2c1656396bb4f5f1f814e60dbf816cc91c5a521b54ad593cd3da0fe8dcb4 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 4 ++-- test/rowid.test | 22 ++++++++++++++++++++++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bb55f9a986..5cd70b117f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sin\stest/fuzzdata8.db. -D 2019-05-14T19:20:52.966 +C Fix\sa\sproblem\swith\sthe\sfix\sfor\s[9cf6c9bb51]\s(commit\s[658b84d7])\sthat\scould\scause\sa\scursor\sto\sbe\sleft\sin\san\sinvalid\sstate\sfollowing\sa\s(rowid\s<\stext-value)\ssearch. +D 2019-05-14T20:25:22.199 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -593,7 +593,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c 4c0669e042b4e50a08a9e5fd14cecc76e5f877efa288533dccddb6fe98f4d6b5 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 4ab7c36d29e156835b23b6b797107f0dbdf6d729798d8cf0d33e40e411f02d68 +F src/vdbe.c d14841dc77e5b0cbd5cb857dee026f17b07a9d1ab147c1c2c9557227be6a52c9 F src/vdbe.h 712bca562eaed1c25506b9faf9680bdc75fc42e2f4a1cd518d883fa79c7a4237 F src/vdbeInt.h 3ba14553508d66f58753952d6dd287dce4ec735de02c6440858b4891aed51c17 F src/vdbeapi.c f9161e5c77f512fbb80091ce8af621d19c9556bda5e734cffaac1198407400da @@ -1243,7 +1243,7 @@ F test/rollback2.test bc868d57899dc6972e2b4483faae0e03365a0556941474eec487ae21d8 F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 -F test/rowid.test 6d43c560e212f99499c31d3f75caacd0b9e059baf88b5fc31fba6b0e280f8b4c +F test/rowid.test bfbd7b97d9267660be3c8f28507c4ed7f205196b8877c0db42df347c2e8845e3 F test/rowvalue.test b8680f07d19c8c5223b808bba998faffcec6d505f5689ff6070280119173bb51 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 @@ -1825,7 +1825,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 456ced57774a92acff23cad975b78ff0e5cbbf5204ea48599fe1761a018a92e4 -R a35d827c3489311c2def9cf07d71c738 -U drh -Z 27e3b81356a63ddc975524d759c0b049 +P 228e1087c0602470e450586499de5a3e87e266c688bc828f20e3bad2fdc65ff1 +R d132bb7525b36863c7f0dbefbbac4ccc +U dan +Z 61ab05a485e7c528107861afc63f60a9 diff --git a/manifest.uuid b/manifest.uuid index a951d6df08..a58fb53a14 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -228e1087c0602470e450586499de5a3e87e266c688bc828f20e3bad2fdc65ff1 \ No newline at end of file +bc7d2c1656396bb4f5f1f814e60dbf816cc91c5a521b54ad593cd3da0fe8dcb4 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 90a000d32a..c5452c5a89 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4001,6 +4001,8 @@ case OP_SeekGT: { /* jump, in3, group */ pC->seekOp = pOp->opcode; #endif + pC->deferredMoveto = 0; + pC->cacheStatus = CACHE_STALE; if( pC->isTable ){ /* The BTREE_SEEK_EQ flag is only set on index cursors */ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 @@ -4105,8 +4107,6 @@ case OP_SeekGT: { /* jump, in3, group */ goto seek_not_found; } } - pC->deferredMoveto = 0; - pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif diff --git a/test/rowid.test b/test/rowid.test index 69f3519a31..f4fa1ce8dc 100644 --- a/test/rowid.test +++ b/test/rowid.test @@ -765,4 +765,26 @@ do_execsql_test rowid-14.4 { SELECT * FROM t14 WHERE x < 'a' ORDER BY rowid DESC; } {} +reset_db +do_execsql_test rowid-15.0 { + PRAGMA reverse_unordered_selects=true; + CREATE TABLE t1 (c0, c1); + CREATE TABLE t2 (c0 INT UNIQUE); + INSERT INTO t1(c0, c1) VALUES (0, 0), (0, NULL); + INSERT INTO t2(c0) VALUES (1); +} + +do_execsql_test rowid-15.1 { + SELECT t2.c0, t1.c1 FROM t1, t2 + WHERE (t2.rowid <= 'a') OR (t1.c0 <= t2.c0) LIMIT 100 +} {1 {} 1 0} + +do_execsql_test rowid-15.2 { + SELECT 1, NULL INTERSECT SELECT * FROM ( + SELECT t2.c0, t1.c1 FROM t1, t2 + WHERE ((t2.rowid <= 'a')) OR (t1.c0 <= t2.c0) ORDER BY 'a' DESC LIMIT 100 + ); +} {1 {}} + + finish_test