]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem reading from temp databases in SQLITE_DIRECT_OVERFLOW_READ
authordan <dan@noemail.net>
Thu, 22 Nov 2018 19:10:14 +0000 (19:10 +0000)
committerdan <dan@noemail.net>
Thu, 22 Nov 2018 19:10:14 +0000 (19:10 +0000)
builds.

FossilOrigin-Name: 81629ba91475938b6ad528e7b1dbef4ad22239782bb2e9c1bb59413aba11da87

manifest
manifest.uuid
src/btree.c
src/pager.c
src/pager.h
src/pcache.c
src/pcache.h
test/tempdb2.test

index e01a494ed511e1fdfc0608457ce74f76ca995f0b..5cfd9beb1985936619b0a7b8e4e8944961cf626b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improvements\sto\sthe\sossfuzz.c\sfuzz-testing\smodule\sso\sthat\sit\sworks\swith\n-DSQLITE_OMIT_PROGRESS_CALLBACK\sand\swith\s-DSQLITE_OMIT_INIT.
-D 2018-11-21T14:27:34.439
+C Fix\sa\sproblem\sreading\sfrom\stemp\sdatabases\sin\sSQLITE_DIRECT_OVERFLOW_READ\nbuilds.
+D 2018-11-22T19:10:14.702
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in b730006b54c990461d864c5387f2e6f13aadb0236804555fb010ed6865a5f058
@@ -447,7 +447,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 3ef104ecae8b1b5f0458be1f5fa7c1ecf25fdc322a9d63bb8151f89eb32d381e
+F src/btree.c ba7c7eef4461790f37c309936bfc5d0d6ba9b194b02d3c8ff1fd53b420ea6d3b
 F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
 F src/build.c 5bc91901b05ac7a33a324854bd2aa892311e71b82a887f99f390bead39e29175
@@ -493,11 +493,11 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c f6e91b8fd82af7afbfd073c4974ad6cdb8e62d9f65ceddb45167835a0567fdc0
 F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c f803ffcd8440b5249549ea103158a1c659bf060961b2389f9fede66a3a352d0b
-F src/pager.h ecc554a55bc55d1c4ba5e17137b72e238e00bd81e72ff2662d8b9c8c10ae3963
+F src/pager.c ff1757f5bb5adb756f22e44c02b235e1d228c6d2c14ae4ea405f2eac7bb0f046
+F src/pager.h 1bffa1ba8a742f8b6485ace9fdbceb0924a15c589a0fb86338ce7ed75130b232
 F src/parse.y 6840fe7c0b5eb4dd25ee5d075213bc8255ed4c0678d71bfb6744d0520d91c179
-F src/pcache.c 4196eb6ed3bbf00b80596c8e0b4f50e57eb7d890c19fb27a7354306abb7f983d
-F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
+F src/pcache.c 696a01f1a6370c1b50a09c15972bc3bee3333f8fcd1f2da8e9a76b1b062c59ee
+F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
 F src/pragma.c a2eab23fbf7c70c28f3a22629de2662d052c22853649430be302b910719574de
 F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
@@ -1348,7 +1348,7 @@ F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f
 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
 F test/tclsqlite.test dca8aa30d84175e7d8c8fc43d3ffa11fa56e23fbdac2679d03833a0f326edf34
 F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08
-F test/tempdb2.test 4749545409c6d7438b435c3f05cdd139cf4145a954a6908d19e3443ffd8724b3
+F test/tempdb2.test 2479226e4cb96f4c663eccd2d12c077cf6bda29ca5cc69a8a58a06127105dd62
 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900
 F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a
@@ -1778,7 +1778,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 6982f52f579d20b8a2965373731d41622bda7f09fbf82cc005bb378321829f4c
-R d459f84253c279be6188e702b14ed458
-U drh
-Z 45091bf780cc926790d09ac151175f43
+P d343f7d6b05865c282eb73a0e39dc396f2927982af45b3d045de03ef73715693
+R e9643d97327d908ba9efaa761eaca8f1
+U dan
+Z a87a4268f4dff99394f9c0686b78940e
index 74d94a99da0e6be332802b77b359c1a1aa04e069..0e648f0ba5be97f537900bd857dc14e8db6272d9 100644 (file)
@@ -1 +1 @@
-d343f7d6b05865c282eb73a0e39dc396f2927982af45b3d045de03ef73715693
\ No newline at end of file
+81629ba91475938b6ad528e7b1dbef4ad22239782bb2e9c1bb59413aba11da87
\ No newline at end of file
index 7224fe7f41266062b3596386a071e4e22030859c..137500eedcb33d1935ad9a82562310d837b00ff5 100644 (file)
@@ -4758,9 +4758,6 @@ static int accessPayload(
         /* Need to read this page properly. It contains some of the
         ** range of data that is being read (eOp==0) or written (eOp!=0).
         */
-#ifdef SQLITE_DIRECT_OVERFLOW_READ
-        sqlite3_file *fd;      /* File from which to do direct overflow read */
-#endif
         int a = amt;
         if( a + offset > ovflSize ){
           a = ovflSize - offset;
@@ -4771,7 +4768,7 @@ static int accessPayload(
         **
         **   1) this is a read operation, and 
         **   2) data is required from the start of this overflow page, and
-        **   3) there is no open write-transaction, and
+        **   3) there are no dirty pages in the page-cache
         **   4) the database is file-backed, and
         **   5) the page is not in the WAL file
         **   6) at least 4 bytes have already been read into the output buffer 
@@ -4782,11 +4779,10 @@ static int accessPayload(
         */
         if( eOp==0                                             /* (1) */
          && offset==0                                          /* (2) */
-         && pBt->inTransaction==TRANS_READ                     /* (3) */
-         && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (4) */
-         && 0==sqlite3PagerUseWal(pBt->pPager, nextPage)       /* (5) */
+         && sqlite3PagerDirectReadOk(pBt->pPager, nextPage)    /* (3,4,5) */
          && &pBuf[-4]>=pBufStart                               /* (6) */
         ){
+          sqlite3_file *fd = sqlite3PagerFile(pBt->pPager);
           u8 aSave[4];
           u8 *aWrite = &pBuf[-4];
           assert( aWrite>=pBufStart );                         /* due to (6) */
index e59cdfcb62a4b28f48c2d6df462b1e800c411e67..5d5c2e3fb5d93c049b3aa26d17fe65f0782b7a39 100644 (file)
@@ -825,6 +825,30 @@ static const unsigned char aJournalMagic[] = {
 */
 #define isOpen(pFd) ((pFd)->pMethods!=0)
 
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+/*
+** Return true if page pgno can be read directly from the database file
+** by the b-tree layer. This is the case if:
+**
+**   * the database file is open,
+**   * there are no dirty pages in the cache, and
+**   * the desired page is not currently in the wal file.
+*/
+int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
+  if( pPager->fd->pMethods==0 ) return 0;
+  if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;
+#ifndef SQLITE_OMIT_WAL
+  if( pPager->pWal ){
+    u32 iRead = 0;
+    int rc;
+    rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
+    return (rc==SQLITE_OK && iRead==0);
+  }
+#endif
+  return 1;
+}
+#endif
+
 /*
 ** Return true if this pager uses a write-ahead log to read page pgno.
 ** Return false if the pager reads pgno directly from the database.
index 5b07a226b8223575475b9ef17713aa82349975f2..1b8136e7459eaaddfa555779ef2a2189117a93c6 100644 (file)
@@ -193,6 +193,10 @@ int sqlite3PagerSharedLock(Pager *pPager);
 # define sqlite3PagerUseWal(x,y) 0
 #endif
 
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+  int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
+#endif
+
 #ifdef SQLITE_ENABLE_ZIPVFS
   int sqlite3PagerWalFramesize(Pager *pPager);
 #endif
index 7415378b4f66bcf7729961449e6f4d4ab6c91e8b..8311049c5e596371d62c607a88d4ead302afead7 100644 (file)
@@ -856,6 +856,15 @@ int sqlite3PCachePercentDirty(PCache *pCache){
   return nCache ? (int)(((i64)nDirty * 100) / nCache) : 0;
 }
 
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+/* 
+** Return true if there are one or more dirty pages in the cache. Else false.
+*/
+int sqlite3PCacheIsDirty(PCache *pCache){
+  return (pCache->pDirty!=0);
+}
+#endif
+
 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
 /*
 ** For all dirty pages currently in the cache, invoke the specified
index bbc2cb453984e1e7c732b8a7672dc026998a295c..eb55396afaa812140ba62997323f0d0abc4965ee 100644 (file)
@@ -183,4 +183,8 @@ int sqlite3HeaderSizePcache1(void);
 /* Number of dirty pages as a percentage of the configured cache size */
 int sqlite3PCachePercentDirty(PCache*);
 
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
+int sqlite3PCacheIsDirty(PCache *pCache);
+#endif
+
 #endif /* _PCACHE_H_ */
index a854a49aa175f96eda8c9481e80b750d5554a26d..d814f842bfd62a8cfcf02cd03ee3471664be6c46 100644 (file)
@@ -76,4 +76,25 @@ do_execsql_test 1.4 {
   SELECT b=int2str(2) FROM t1
 } {1 1 1}
 
+#-------------------------------------------------------------------------
+db close
+sqlite3 db ""
+db func int2str int2str
+
+do_execsql_test 2.0 {
+  PRAGMA cache_size = -100;
+  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
+  WITH c(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100 ) 
+    INSERT INTO t1 SELECT x, int2str(x) FROM c;
+}
+
+do_execsql_test 2.1 {
+  INSERT INTO t1 VALUES(10001, int2str(1001) || int2str(1001) || int2str(1001));
+}
+
+do_execsql_test 2.2 {
+  SELECT b FROM t1 WHERE a = 10001;
+} "[int2str 1001][int2str 1001][int2str 1001]"
+
 finish_test
+