-C Carry\stable\scolumn\stypes\sthrough\sinto\sVIEW\sdefinitions,\swhere\spossible.
-D 2016-04-05T20:59:12.069
+C Defer\sopening\sthe\sfile\sused\sfor\sthe\stemp\sdatabase\s(where\sCREATE\sTEMP\sTABLE\stables\sare\sstored)\suntil\sthe\sdatabase\sis\stoo\slarge\sto\sreside\sentirely\swithin\sthe\scache.\sThere\sare\slikely\sstill\sproblems\son\sthis\sbranch.
+D 2016-04-05T21:07:58.179
F Makefile.in eba680121821b8a60940a81454316f47a341487a
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 1f123a0757f6f04f0341accb46457e116817159a
F src/os_unix.c b1ccb273771f41dbdbe0ba7c1ad63c38ad5972ec
F src/os_win.c b3ba9573d8d893e70a6a8015bbee572ecf7ffbef
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
-F src/pager.c 38718a019ca762ba4f6795425d5a54db70d1790d
+F src/pager.c 123dbae47bf27915a4b567915ff8dcc27cfcd369
F src/pager.h e1d38a2f14849e219df0f91f8323504d134c8a56
F src/parse.y 5ea8c81c5c41b27887f41b4a7e1c58470d7d3821
-F src/pcache.c 647bb53a86b7bbcf55ad88089b3ea5a9170b90df
+F src/pcache.c e9c00846d3dcdaa75b288c6f16238c2fe2177823
F src/pcache.h 4d0ccaad264d360981ec5e6a2b596d6e85242545
F src/pcache1.c c40cdb93586e21b5dd826b5e671240bd91c26b05
F src/pragma.c faf42922bb7ab2f6672cb550356c1967abae3c84
F test/tclsqlite.test e1306001a0ca92250b691ea6d3cecaca5b6342aa
F test/tempdb.test bd92eba8f20e16a9136e434e20b280794de3cdb6
F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
+F test/temptable2.test f3b198e386f6494082c87accc8780cdf84b36e6d
F test/temptrigger.test 8ec228b0db5d7ebc4ee9b458fc28cb9e7873f5e1
F test/tester.tcl 7b740ee852c55e1e72b6ebe5044acee7aa4e5553
F test/thread001.test 9f22fd3525a307ff42a326b6bc7b0465be1745a5
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 0bf9926c7a7865694edd48535777248e73d86bbf
-R c7f5a7683cc4a0d14362e20e6891847a
-U drh
-Z ec8e2cff7764d808576889c190bbf60c
+P fb555c3c2af7f5e62ff839658f4fba7b645d3a68
+R f511e5baaeaad693345498b91b98e90f
+T *branch * tempfiles-lazy-open
+T *sym-tempfiles-lazy-open *
+T -sym-trunk *
+U dan
+Z 505ba6148fb8f2c79237e86b07655c1c
-fb555c3c2af7f5e62ff839658f4fba7b645d3a68
\ No newline at end of file
+be5a549eba6cf8e29cb6b9824fd6d0db9d03ca7f
\ No newline at end of file
sqlite3BitvecDestroy(pPager->pInJournal);
pPager->pInJournal = 0;
pPager->nRec = 0;
- sqlite3PcacheCleanAll(pPager->pPCache);
+ if( pPager->tempFile==0 || MEMDB ){
+ sqlite3PcacheCleanAll(pPager->pPCache);
+ }else{
+ sqlite3PcacheClearWritable(pPager->pPCache);
+ }
sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
if( pagerUseWal(pPager) ){
** be written out into the database file before its journal file
** segment is synced. If a crash occurs during or following this,
** database corruption may ensue.
+ **
+ ** Update: Another exception is for temp files that are not
+ ** in-memory databases. In this case the page may have been dirty
+ ** at the start of the transaction.
*/
assert( !pagerUseWal(pPager) );
- sqlite3PcacheMakeClean(pPg);
+ if( pPager->tempFile==0 ) sqlite3PcacheMakeClean(pPg);
}
pager_set_pagehash(pPg);
/* This function is only called for rollback pagers in WRITER_DBMOD state. */
assert( !pagerUseWal(pPager) );
- assert( pPager->eState==PAGER_WRITER_DBMOD );
+ assert( pPager->tempFile || pPager->eState==PAGER_WRITER_DBMOD );
assert( pPager->eLock==EXCLUSIVE_LOCK );
+ assert( pPager->tempFile==0 || pList->pDirty==0 );
/* If the file is a temp-file has not yet been opened, open it now. It
** is not possible for rc to be other than SQLITE_OK if this branch
if( pPager->nSavepoint ) return subjournalPageIfRequired(pPg);
return SQLITE_OK;
}else if( pPager->sectorSize > (u32)pPager->pageSize ){
+ assert( pPager->tempFile==0 );
return pagerWriteLargeSector(pPg);
}else{
return pager_write(pPg);
/* If no database changes have been made, return early. */
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
- if( MEMDB ){
+ assert( MEMDB==0 || pPager->tempFile );
+ if( pPager->tempFile ){
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is mostly a no-op. However, any
- ** backup in progress needs to be restarted.
- */
+ ** backup in progress needs to be restarted. */
sqlite3BackupRestart(pPager->pBackup);
}else{
if( pagerUseWal(pPager) ){
** the journal needs to be sync()ed before database page pPg->pgno
** can be written to. The caller has already promised not to write to it.
*/
- if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
+ if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit && pPager->tempFile==0 ){
needSyncPgno = pPg->pgno;
assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
/*
** If the sqlite3PcacheFetch() routine is unable to allocate a new
-** page because new clean pages are available for reuse and the cache
+** page because no clean pages are available for reuse and the cache
** size limit has been reached, then this routine can be invoked to
** try harder to allocate a page. This routine might invoke the stress
** callback to spill dirty pages to the journal. It will then try to
}
}
+/*
+** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages.
+*/
+void sqlite3PcacheClearWritable(PCache *pCache){
+ PgHdr *p;
+ for(p=pCache->pDirty; p; p=p->pDirtyNext){
+ p->flags &= ~(PGHDR_NEED_SYNC|PGHDR_WRITEABLE);
+ }
+ pCache->pSynced = pCache->pDirtyTail;
+}
+
/*
** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
*/
** it must be that pgno==0.
*/
assert( p->pgno>0 );
- if( ALWAYS(p->pgno>pgno) ){
+ if( p->pgno>pgno ){
assert( p->flags&PGHDR_DIRTY );
sqlite3PcacheMakeClean(p);
}
--- /dev/null
+# 2016 March 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.
+#
+#***********************************************************************
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix temptable2
+
+do_execsql_test 1.1 {
+ CREATE TEMP TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a, b);
+}
+
+do_execsql_test 1.2 {
+ WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<100000 )
+ INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM X;
+} {}
+
+do_execsql_test 1.3 {
+ PRAGMA temp.integrity_check;
+} {ok}
+
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 2.1 {
+ CREATE TEMP TABLE t2(a, b);
+ INSERT INTO t2 VALUES(1, 2);
+} {}
+
+do_execsql_test 2.2 {
+ BEGIN;
+ INSERT INTO t2 VALUES(3, 4);
+ SELECT * FROM t2;
+} {1 2 3 4}
+
+do_execsql_test 2.3 {
+ ROLLBACK;
+ SELECT * FROM t2;
+} {1 2}
+
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 3.1.1 {
+ PRAGMA main.cache_size = 10;
+ PRAGMA temp.cache_size = 10;
+
+ CREATE TEMP TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a, b);
+
+ WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 )
+ INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
+
+ SELECT count(*) FROM t1;
+} {1000}
+do_execsql_test 3.1.2 {
+ BEGIN;
+ UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
+ ROLLBACK;
+}
+do_execsql_test 3.1.3 {
+ SELECT count(*) FROM t1;
+} {1000}
+do_execsql_test 3.1.4 { PRAGMA temp.integrity_check } {ok}
+
+do_execsql_test 3.2.1 {
+ BEGIN;
+ UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==0;
+ SAVEPOINT abc;
+ UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==1;
+ ROLLBACK TO abc;
+ UPDATE t1 SET b=randomblob(100) WHERE (rowid%10)==2;
+ COMMIT;
+}
+do_execsql_test 3.2.2 { PRAGMA temp.integrity_check } {ok}
+
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 4.1.1 {
+ PRAGMA main.cache_size = 10;
+ PRAGMA temp.cache_size = 10;
+
+ CREATE TEMP TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a, b);
+
+ WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<10 )
+ INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x;
+
+ SELECT count(*) FROM t1;
+ PRAGMA temp.page_count;
+} {10 9}
+
+do_execsql_test 4.1.2 {
+ BEGIN;
+ UPDATE t1 SET b=randomblob(100);
+ ROLLBACK;
+}
+
+do_execsql_test 4.1.3 {
+ CREATE TEMP TABLE t2(a, b);
+ CREATE INDEX i2 ON t2(a, b);
+ WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
+ INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
+
+ SELECT count(*) FROM t2;
+ SELECT count(*) FROM t1;
+ PRAGMA temp.page_count;
+} {500 10 292}
+
+do_execsql_test 4.1.4 { PRAGMA temp.integrity_check } {ok}
+
+#-------------------------------------------------------------------------
+#
+reset_db
+do_execsql_test 5.1.1 {
+ PRAGMA main.cache_size = 10;
+ PRAGMA temp.cache_size = 10;
+
+ CREATE TEMP TABLE t2(a, b);
+ CREATE INDEX i2 ON t2(a, b);
+ WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 )
+ INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM x;
+
+ CREATE TEMP TABLE t1(a, b);
+ CREATE INDEX i1 ON t1(a, b);
+ INSERT INTO t1 VALUES(1, 2);
+
+ PRAGMA temp.page_count;
+} {286}
+
+do_execsql_test 5.1.2 {
+ BEGIN;
+ UPDATE t1 SET a=2;
+ UPDATE t2 SET a=randomblob(100);
+ SELECT count(*) FROM t1;
+ ROLLBACK;
+} {1}
+
+do_execsql_test 5.1.3 {
+ UPDATE t2 SET a=randomblob(100);
+
+ SELECT * FROM t1;
+} {1 2}
+
+do_execsql_test 5.1.4 { PRAGMA temp.integrity_check } {ok}
+
+finish_test
+