Index: VERSION ================================================================== --- VERSION +++ VERSION @@ -1,1 +1,1 @@ -3.7.0 +3.7.0.1 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.7.0. +# Generated by GNU Autoconf 2.62 for sqlite 3.7.0.1. # # 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.7.0' -PACKAGE_STRING='sqlite 3.7.0' +PACKAGE_VERSION='3.7.0.1' +PACKAGE_STRING='sqlite 3.7.0.1' 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.7.0 to adapt to many kinds of systems. +\`configure' configures sqlite 3.7.0.1 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.7.0:";; + short | recursive ) echo "Configuration of sqlite 3.7.0.1:";; 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.7.0 +sqlite configure 3.7.0.1 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.7.0, which was +It was created by sqlite $as_me 3.7.0.1, which was generated by GNU Autoconf 2.62. Invocation command line was $ $0 $@ _ACEOF @@ -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.7.0, which was +This file was extended by sqlite $as_me 3.7.0.1, 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.7.0 +sqlite config.status 3.7.0.1 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 @@ -14456,12 +14456,11 @@ # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then -ac_cr=' -' +ac_cr=' ' ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr Index: src/btree.c ================================================================== --- src/btree.c +++ src/btree.c @@ -2567,17 +2567,31 @@ } p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); if( p->inTrans>pBt->inTransaction ){ pBt->inTransaction = p->inTrans; } -#ifndef SQLITE_OMIT_SHARED_CACHE if( wrflag ){ + MemPage *pPage1 = pBt->pPage1; +#ifndef SQLITE_OMIT_SHARED_CACHE assert( !pBt->pWriter ); pBt->pWriter = p; pBt->isExclusive = (u8)(wrflag>1); - } #endif + + /* If the db-size header field is incorrect (as it may be if an old + ** client has been writing the database file), update it now. Doing + ** this sooner rather than later means the database size can safely + ** re-read the database size from page 1 if a savepoint or transaction + ** rollback occurs within the transaction. + */ + if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ + rc = sqlite3PagerWrite(pPage1->pDbPage); + if( rc==SQLITE_OK ){ + put4byte(&pPage1->aData[28], pBt->nPage); + } + } + } } trans_begun: if( rc==SQLITE_OK && wrflag ){ Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -1503,18 +1503,24 @@ if( eType==0 ){ /* Could not found an existing table or index to use as the RHS b-tree. ** We will have to generate an ephemeral table to do the job. */ + double savedNQueryLoop = pParse->nQueryLoop; int rMayHaveNull = 0; eType = IN_INDEX_EPH; if( prNotFound ){ *prNotFound = rMayHaveNull = ++pParse->nMem; - }else if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ - eType = IN_INDEX_ROWID; + }else{ + testcase( pParse->nQueryLoop>(double)1 ); + pParse->nQueryLoop = (double)1; + if( pX->pLeft->iColumn<0 && !ExprHasAnyProperty(pX, EP_xIsSelect) ){ + eType = IN_INDEX_ROWID; + } } sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID); + pParse->nQueryLoop = savedNQueryLoop; }else{ pX->iTable = iTab; } return eType; } Index: src/os_os2.c ================================================================== --- src/os_os2.c +++ src/os_os2.c @@ -777,11 +777,11 @@ } memset( pFile, 0, sizeof(*pFile) ); - OSTRACE( "OPEN want %d\n", flags )); + OSTRACE(( "OPEN want %d\n", flags )); if( flags & SQLITE_OPEN_READWRITE ){ ulOpenMode |= OPEN_ACCESS_READWRITE; OSTRACE(( "OPEN read/write\n" )); }else{ Index: test/autoindex1.test ================================================================== --- test/autoindex1.test +++ test/autoindex1.test @@ -133,7 +133,37 @@ JOIN t4 AS x8 ON x8.a=x7.b JOIN t4 AS x9 ON x9.a=x8.b JOIN t4 AS x10 ON x10.a=x9.b; } } {4087} + +# Ticket [8011086c85c6c404014c947fcf3eb9f42b184a0d] from 2010-07-08 +# Make sure automatic indices are not created for the RHS of an IN expression +# that is not a correlated subquery. +# +do_test autoindex1-500 { + db eval { + CREATE TABLE t501(a INTEGER PRIMARY KEY, b); + CREATE TABLE t502(x INTEGER PRIMARY KEY, y); + EXPLAIN QUERY PLAN + SELECT b FROM t501 + WHERE t501.a IN (SELECT x FROM t502 WHERE y=?); + } +} {0 0 {TABLE t501 USING PRIMARY KEY} 0 0 {TABLE t502}} +do_test autoindex1-501 { + db eval { + EXPLAIN QUERY PLAN + SELECT b FROM t501 + WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b); + } +} {0 0 {TABLE t501} 0 0 {TABLE t502 WITH AUTOMATIC INDEX}} +do_test autoindex1-502 { + db eval { + EXPLAIN QUERY PLAN + SELECT b FROM t501 + WHERE t501.a=123 + AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b); + } +} {0 0 {TABLE t501 USING PRIMARY KEY} 0 0 {TABLE t502}} + finish_test Index: test/filefmt.test ================================================================== --- test/filefmt.test +++ test/filefmt.test @@ -115,7 +115,82 @@ SELECT count(*) FROM sqlite_master } } {1 {file is encrypted or is not a database}} } +#------------------------------------------------------------------------- +# The following block of tests - filefmt-2.* - test that versions 3.7.0 +# and later can read and write databases that have been modified or created +# by 3.6.23.1 and earlier. The difference difference is that 3.7.0 stores +# the size of the database in the database file header, whereas 3.6.23.1 +# always derives this from the size of the file. +# +db close +file delete -force test.db + +set a_string_counter 1 +proc a_string {n} { + incr ::a_string_counter + string range [string repeat "${::a_string_counter}." $n] 1 $n +} +sqlite3 db test.db +db func a_string a_string + +do_execsql_test filefmt-2.1.1 { + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(a_string(3000)); + CREATE TABLE t2(a); + INSERT INTO t2 VALUES(1); +} {} +do_test filefmt-2.1.2 { + hexio_read test.db 28 4 +} {00000009} + +do_test filefmt-2.1.3 { + sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } +} {} + +do_execsql_test filefmt-2.1.4 { INSERT INTO t2 VALUES(2) } {} +integrity_check filefmt-2.1.5 +do_test filefmt-2.1.6 { hexio_read test.db 28 4 } {00000010} + +db close +file delete -force test.db +sqlite3 db test.db +db func a_string a_string + +do_execsql_test filefmt-2.2.1 { + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(a_string(3000)); + CREATE TABLE t2(a); + INSERT INTO t2 VALUES(1); +} {} +do_test filefmt-2.2.2 { + hexio_read test.db 28 4 +} {00000009} + +do_test filefmt-2.2.3 { + sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } +} {} + +do_execsql_test filefmt-2.2.4 { + PRAGMA integrity_check; + BEGIN; + INSERT INTO t2 VALUES(2); + SAVEPOINT a; + INSERT INTO t2 VALUES(3); + ROLLBACK TO a; +} {ok} + +integrity_check filefmt-2.2.5 +do_execsql_test filefmt-2.2.6 { COMMIT } {} +db close +sqlite3 db test.db +integrity_check filefmt-2.2.7 finish_test Index: test/pagerfault.test ================================================================== --- test/pagerfault.test +++ test/pagerfault.test @@ -1043,6 +1043,39 @@ } {ok} db close } } + +#------------------------------------------------------------------------- +# When a 3.7.0 client opens a write-transaction on a database file that +# has been appended to or truncated by a pre-370 client, it updates +# the db-size in the file header immediately. This test case provokes +# errors during that operation. +# +do_test pagerfault-22-pre1 { + faultsim_delete_and_reopen + db func a_string a_string + execsql { + PRAGMA page_size = 1024; + PRAGMA auto_vacuum = 0; + CREATE TABLE t1(a); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(a_string(3000)); + CREATE TABLE t2(a); + INSERT INTO t2 VALUES(1); + } + db close + sql36231 { INSERT INTO t1 VALUES(a_string(3000)) } + faultsim_save_and_close +} {} +do_faultsim_test pagerfault-22 -prep { + faultsim_restore_and_reopen +} -body { + execsql { INSERT INTO t2 VALUES(2) } + execsql { SELECT * FROM t2 } +} -test { + faultsim_test_result {0 {1 2}} + faultsim_integrity_check +} + finish_test Index: test/tester.tcl ================================================================== --- test/tester.tcl +++ test/tester.tcl @@ -1223,10 +1223,27 @@ # puts "Time: $tail $ms ms" show_memstats } +# Open a new connection on database test.db and execute the SQL script +# supplied as an argument. Before returning, close the new conection and +# restore the 4 byte fields starting at header offsets 28, 92 and 96 +# to the values they held before the SQL was executed. This simulates +# a write by a pre-3.7.0 client. +# +proc sql36231 {sql} { + set B [hexio_read test.db 92 8] + set A [hexio_read test.db 28 4] + sqlite3 db36231 test.db + catch { db36231 func a_string a_string } + execsql $sql db36231 + db36231 close + hexio_write test.db 28 $A + hexio_write test.db 92 $B + return "" +} # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum)