Index: VERSION ================================================================== --- VERSION +++ VERSION @@ -1,1 +1,1 @@ -3.6.14 +3.6.14.2 Index: configure ================================================================== --- configure +++ configure @@ -1,8 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.62 for sqlite 3.6.13. +# Generated by GNU Autoconf 2.62 for sqlite 3.6.14.2. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. @@ -741,12 +741,12 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='sqlite' PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.6.13' -PACKAGE_STRING='sqlite 3.6.13' +PACKAGE_VERSION='3.6.14.2' +PACKAGE_STRING='sqlite 3.6.14.2' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. ac_includes_default="\ #include @@ -1485,11 +1485,11 @@ # 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.6.13 to adapt to many kinds of systems. +\`configure' configures sqlite 3.6.14.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. @@ -1550,11 +1550,11 @@ _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.6.13:";; + short | recursive ) echo "Configuration of sqlite 3.6.14.2:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options @@ -1668,11 +1668,11 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sqlite configure 3.6.13 +sqlite configure 3.6.14.2 generated by GNU Autoconf 2.62 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation @@ -1682,11 +1682,11 @@ fi 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.6.13, which was +It was created by sqlite $as_me 3.6.14.2, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ _ACEOF @@ -2049,11 +2049,11 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -sqlite_version_sanity_check=`cat VERSION | tr -d '\n'` +sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then { { $as_echo "$as_me:$LINENO: error: configure script is out of date: configure \$PACKAGE_VERSION = $PACKAGE_VERSION top level VERSION file = $sqlite_version_sanity_check please regen with autoconf" >&5 @@ -2063,11 +2063,11 @@ please regen with autoconf" >&2;} { (exit 1); exit 1; }; } fi # The following RCS revision string applies to configure.in -# $Revision: 1.71 $ +# $Revision: 1.71.2.2 $ ######### # Programs needed # case `pwd` in @@ -13970,11 +13970,11 @@ # Save the log message, to keep $[0] and so on meaningful, and to # 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.6.13, which was +This file was extended by sqlite $as_me 3.6.14.2, which was generated by GNU Autoconf 2.62. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS @@ -14023,11 +14023,11 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -sqlite config.status 3.6.13 +sqlite config.status 3.6.14.2 configured by $0, generated by GNU Autoconf 2.62, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation Index: src/backup.c ================================================================== --- src/backup.c +++ src/backup.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** -** $Id: backup.c,v 1.13 2009/03/16 13:19:36 danielk1977 Exp $ +** $Id: backup.c,v 1.13.2.1 2009/05/18 17:11:31 drh Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" /* Macro to find the minimum of two numeric values. @@ -42,10 +42,11 @@ ** read by calls to backup_remaining() and backup_pagecount(). */ Pgno nRemaining; /* Number of pages left to copy */ Pgno nPagecount; /* Total number of pages to copy */ + int isAttached; /* True once backup has been registered with pager */ sqlite3_backup *pNext; /* Next backup associated with source pager */ }; /* ** THREAD SAFETY NOTES: @@ -155,10 +156,11 @@ p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); p->pDest = findBtree(pDestDb, pDestDb, zDestDb); p->pDestDb = pDestDb; p->pSrcDb = pSrcDb; p->iNext = 1; + p->isAttached = 0; if( 0==p->pSrc || 0==p->pDest ){ /* One (or both) of the named databases did not exist. An error has ** already been written into the pDestDb handle. All that is left ** to do here is free the sqlite3_backup structure. @@ -165,22 +167,11 @@ */ sqlite3_free(p); p = 0; } } - - /* If everything has gone as planned, attach the backup object to the - ** source pager. The source pager calls BackupUpdate() and BackupRestart() - ** to notify this module if the source file is modified mid-backup. - */ if( p ){ - sqlite3_backup **pp; /* Pointer to head of pagers backup list */ - sqlite3BtreeEnter(p->pSrc); - pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); - p->pNext = *pp; - *pp = p; - sqlite3BtreeLeave(p->pSrc); p->pSrc->nBackup++; } sqlite3_mutex_leave(pDestDb->mutex); sqlite3_mutex_leave(pSrcDb->mutex); @@ -268,10 +259,23 @@ if( rc==SQLITE_OK && iCurrent>iSize ){ rc = sqlite3OsTruncate(pFile, iSize); } return rc; } + +/* +** Register this backup object with the associated source pager for +** callbacks when pages are changed or the cache invalidated. +*/ +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); + p->pNext = *pp; + *pp = p; + p->isAttached = 1; +} /* ** Copy nPage pages from the source b-tree to the destination. */ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ @@ -338,10 +342,12 @@ if( rc==SQLITE_OK ){ p->nPagecount = nSrcPage; p->nRemaining = nSrcPage+1-p->iNext; if( p->iNext>(Pgno)nSrcPage ){ rc = SQLITE_DONE; + }else if( !p->isAttached ){ + attachBackupObject(p); } } if( rc==SQLITE_DONE ){ const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc); @@ -470,16 +476,18 @@ sqlite3_mutex_enter(p->pDestDb->mutex); } /* Detach this backup from the source pager. */ if( p->pDestDb ){ + p->pSrc->nBackup--; + } + if( p->isAttached ){ pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); while( *pp!=p ){ pp = &(*pp)->pNext; } *pp = p->pNext; - p->pSrc->nBackup--; } /* If a transaction is still open on the Btree, roll it back. */ sqlite3BtreeRollback(p->pDest); Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.432 2009/05/06 18:57:10 shane Exp $ +** $Id: expr.c,v 1.432.2.1 2009/05/25 12:02:24 drh Exp $ */ #include "sqliteInt.h" /* ** Return the 'affinity' of the expression pExpr if any. @@ -1799,10 +1799,26 @@ cacheEntryClear(pParse, p); p->iReg = 0; } } } + +/* +** When a cached column is reused, make sure that its register is +** no longer available as a temp register. ticket #3879: that same +** register might be in the cache in multiple places, so be sure to +** get them all. +*/ +static void sqlite3ExprCachePinRegister(Parse *pParse, int iReg){ + int i; + struct yColCache *p; + for(i=0, p=pParse->aColCache; iiReg==iReg ){ + p->tempReg = 0; + } + } +} /* ** Generate code that will extract the iColumn-th column from ** table pTab and store the column value in a register. An effort ** is made to store the column value in register iReg, but this is @@ -1835,11 +1851,11 @@ #if 0 sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "OPT: tab%d.col%d -> r%d", iTable, iColumn, p->iReg)); #endif p->lru = pParse->iCacheCnt++; - p->tempReg = 0; /* This pins the register, but also leaks it */ + sqlite3ExprCachePinRegister(pParse, p->iReg); return p->iReg; } } assert( v!=0 ); if( iColumn<0 ){ Index: src/pager.c ================================================================== --- src/pager.c +++ src/pager.c @@ -16,11 +16,11 @@ ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.586 2009/05/06 18:57:10 shane Exp $ +** @(#) $Id: pager.c,v 1.586.2.1 2009/05/18 17:11:31 drh Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* @@ -3620,11 +3620,11 @@ assert( (pPager->state==PAGER_SHARED) || (pPager->exclusiveMode && pPager->state>PAGER_SHARED) ); } - if( sqlite3PcachePagecount(pPager->pPCache)>0 ){ + if( pPager->pBackup || sqlite3PcachePagecount(pPager->pPCache)>0 ){ /* The shared-lock has just been acquired on the database file ** and there are already pages in the cache (from a previous ** read or write transaction). Check to see if the database ** has been modified. If the database has changed, flush the ** cache. Index: src/pcache1.c ================================================================== --- src/pcache1.c +++ src/pcache1.c @@ -14,11 +14,11 @@ ** sqlite3_pcache interface). It also contains part of the implementation ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. ** If the default page cache implementation is overriden, then neither of ** these two features are available. ** -** @(#) $Id: pcache1.c,v 1.11 2009/04/14 18:44:39 aswift Exp $ +** @(#) $Id: pcache1.c,v 1.11.2.1 2009/05/18 16:14:25 drh Exp $ */ #include "sqliteInt.h" typedef struct PCache1 PCache1; @@ -358,25 +358,29 @@ */ static void pcache1TruncateUnsafe( PCache1 *pCache, unsigned int iLimit ){ + TESTONLY( int nPage = 0; ) /* Used to assert pCache->nPage is correct */ unsigned int h; assert( sqlite3_mutex_held(pcache1.mutex) ); for(h=0; hnHash; h++){ PgHdr1 **pp = &pCache->apHash[h]; PgHdr1 *pPage; while( (pPage = *pp)!=0 ){ if( pPage->iKey>=iLimit ){ - pcache1PinPage(pPage); + pCache->nPage--; *pp = pPage->pNext; + pcache1PinPage(pPage); pcache1FreePage(pPage); }else{ pp = &pPage->pNext; + TESTONLY( nPage++ ); } } } + assert( pCache->nPage==nPage ); } /******************************************************************************/ /******** sqlite3_pcache Methods **********************************************/ Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -41,11 +41,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.842 2009/05/06 18:57:10 shane Exp $ +** $Id: vdbe.c,v 1.842.2.1 2009/05/18 16:14:25 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" /* @@ -674,10 +674,11 @@ assert( pOp->p2>0 ); assert( pOp->p2<=p->nMem ); pOut = &p->aMem[pOp->p2]; sqlite3VdbeMemReleaseExternal(pOut); pOut->flags = MEM_Null; + pOut->n = 0; }else /* Do common setup for opcodes marked with one of the following ** combinations of properties. ** Index: test/backup.test ================================================================== --- test/backup.test +++ test/backup.test @@ -9,11 +9,11 @@ # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the sqlite3_backup_XXX API. # -# $Id: backup.test,v 1.9 2009/03/16 13:19:36 danielk1977 Exp $ +# $Id: backup.test,v 1.9.2.1 2009/05/18 17:11:31 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl #--------------------------------------------------------------------- @@ -856,8 +856,54 @@ } {0} do_test backup-9.2.3 { B finish } {SQLITE_OK} catch {db2 close} + +ifcapable memorymanage { + db close + file delete -force test.db + file delete -force bak.db + + sqlite3 db test.db + sqlite3 db2 test.db + sqlite3 db3 bak.db + + do_test backup-10.1.1 { + execsql { + BEGIN; + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, randstr(1000,1000)); + INSERT INTO t1 VALUES(2, randstr(1000,1000)); + INSERT INTO t1 VALUES(3, randstr(1000,1000)); + INSERT INTO t1 VALUES(4, randstr(1000,1000)); + INSERT INTO t1 VALUES(5, randstr(1000,1000)); + CREATE INDEX i1 ON t1(a, b); + COMMIT; + } + } {} + do_test backup-10.1.2 { + sqlite3_backup B db3 main db2 main + B step 5 + } {SQLITE_OK} + do_test backup-10.1.3 { + execsql { + UPDATE t1 SET b = randstr(500,500); + } + } {} + sqlite3_release_memory [expr 1024*1024] + do_test backup-10.1.3 { + B step 50 + } {SQLITE_DONE} + do_test backup-10.1.4 { + B finish + } {SQLITE_OK} + do_test backup-10.1.5 { + execsql { PRAGMA integrity_check } db3 + } {ok} + + db2 close + db3 close +} finish_test Index: test/pcache.test ================================================================== --- test/pcache.test +++ test/pcache.test @@ -9,11 +9,11 @@ # #*********************************************************************** # # This file is focused on testing the pcache module. # -# $Id: pcache.test,v 1.4 2009/03/05 14:59:40 danielk1977 Exp $ +# $Id: pcache.test,v 1.4.2.1 2009/05/18 16:14:26 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -143,6 +143,27 @@ do_test pcache-1.13 { execsql { PRAGMA cache_size = 15 } pcache_stats } {current 15 max 15 min 10 recyclable 15} +do_test pcache-1.14 { + hexio_write test.db 24 [hexio_render_int32 1000] + execsql { SELECT * FROM sqlite_master } + pcache_stats +} {current 2 max 15 min 10 recyclable 2} + +do_test pcache-1.15 { + execsql { + SELECT * FROM t1 ORDER BY a; SELECT * FROM t1; + SELECT * FROM t2 ORDER BY a; SELECT * FROM t2; + SELECT * FROM t3 ORDER BY a; SELECT * FROM t3; + SELECT * FROM t4 ORDER BY a; SELECT * FROM t4; + SELECT * FROM t5 ORDER BY a; SELECT * FROM t5; + SELECT * FROM t6 ORDER BY a; SELECT * FROM t6; + SELECT * FROM t7 ORDER BY a; SELECT * FROM t7; + SELECT * FROM t8 ORDER BY a; SELECT * FROM t8; + SELECT * FROM t9 ORDER BY a; SELECT * FROM t9; + } + pcache_stats +} {current 14 max 15 min 10 recyclable 14} + finish_test Index: test/tkt2942.test ================================================================== --- test/tkt2942.test +++ test/tkt2942.test @@ -19,11 +19,11 @@ # to not matter because aggregate functions sum(), min(), max(), avg(), # and so forth give the same result regardless of the order of inputs. # But with the addition of the group_concat() function, suddenly the # order does matter. # -# $Id: tkt2942.test,v 1.1 2008/02/15 14:33:04 drh Exp $ +# $Id: tkt2942.test,v 1.1.4.1 2009/05/18 16:14:26 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -56,7 +56,29 @@ execsql { SELECT group_concat(num) FROM (SELECT num FROM t1 ORDER BY rowid DESC); } } {4,3,1,2} +do_test tkt2942-3841.1 { + execsql { + CREATE TABLE table2 (key TEXT, x TEXT); + CREATE TABLE list (key TEXT, value TEXT); + + INSERT INTO table2 VALUES ("a", "alist"); + INSERT INTO table2 VALUES ("b", "blist"); + INSERT INTO list VALUES ("a", 1); + INSERT INTO list VALUES ("a", 2); + INSERT INTO list VALUES ("a", 3); + INSERT INTO list VALUES ("b", 4); + INSERT INTO list VALUES ("b", 5); + INSERT INTO list VALUES ("b", 6); + + SELECT + table2.x, + (SELECT group_concat(list.value) + FROM list + WHERE list.key = table2.key) + FROM table2; + } +} {alist 1,2,3 blist 4,5,6} finish_test