Merge trunk changes with experimental branch.

FossilOrigin-Name: acd26b8b746980c344db017a0e96dbd92c89acdf
This commit is contained in:
dan 2010-08-05 16:22:49 +00:00
commit 4557b92cdb
10 changed files with 262 additions and 24 deletions

View File

@ -1,5 +1,5 @@
C Catch\san\serror\scode\sthat\swas\snot\sbeing\spropagated\sback\sto\sthe\scaller.
D 2010-08-05T16:08:26
C Merge\strunk\schanges\swith\sexperimental\sbranch.
D 2010-08-05T16:22:50
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in ec08dc838fd8110fe24c92e5130bcd91cbb1ff2e
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -111,9 +111,9 @@ F src/analyze.c 3642ebcd13f1ffb5773b9e08910e0492ec4cf946
F src/attach.c 17bec1f18254d9341369f20f90ba24ce35d20d10
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c 51d83300fe0baee39405c416ceb19a58ed30a8ed
F src/bitvec.c 06ad2c36a9c3819c0b9cbffec7b15f58d5d834e0
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
F src/btmutex.c 96a12f50f7a17475155971a241d85ec5171573ff
F src/btree.c 2b122b7d7dec94670ecaa70f92397406100036aa
F src/btree.c 63eebba7bd87207556670139eae5ef6c1f8bb416
F src/btree.h b4ba2fdf6b64c7c376bdfffa826af6b786b151d9
F src/btreeInt.h b0c87f6725b06a0aa194a6d25d54b16ce9d6e291
F src/build.c 0018d49629fc4807100c988dd191dd95e185bb38
@ -230,7 +230,7 @@ F src/vtab.c 82200af3881fa4e1c9cf07cf31d98c09d437e3ab
F src/wal.c 6e04bccccd75acf86725cc8cb4b107cd245e018c
F src/wal.h 96669b645e27cd5a111ba59f0cae7743a207bc3c
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
F src/where.c 79202ca81e740eeb1f54512147e29b6c518d84ca
F src/where.c a4b2cb14dbd727ff277be3f52851425191a87f66
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
F test/all.test 6745008c144bd2956d58864d21f7b304689c1cce
@ -353,7 +353,7 @@ F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/fallocate.test 0594314eb04268f7d0779d054fa850a36a5ae8bc
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
F test/filefmt.test 5d271bf467e6557fe7499dcc8203069c9dc5825e
F test/filefmt.test f77c92141960b7933bc6691631d2ad62257ef40a
F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
F test/fkey2.test e028cd80aa0bd38541c99214e3ba2dfccadffe6f
F test/fkey3.test 42f88d6048d8dc079e2a8cf7baad1cc1483a7620
@ -446,7 +446,7 @@ F test/incrvacuum_ioerr.test 57d2f5777ab13fa03b87b262a4ea1bad5cfc0291
F test/index.test cbf301cdb2da43e4eac636c3400c2439af1834ad
F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6
F test/index3.test 423a25c789fc8cc51aaf2a4370bbdde2d9e9eed7
F test/indexedby.test 946ca2628a521f4ced0520421a0788345abaf3dc
F test/indexedby.test 5a1180602f2e72c481467bd4cae05dae5dc36f47
F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7
F test/insert.test aef273dd1cee84cc92407469e6bd1b3cdcb76908
F test/insert2.test 4f3a04d168c728ed5ec2c88842e772606c7ce435
@ -541,7 +541,7 @@ F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
F test/pager1.test d8e4b2bc8164c920e6ea0572c9e13576d6e4f3fa
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
F test/pagerfault.test a4c0bb8900b8dbf5fcbe41ee2a96148e22174bcb
F test/pagerfault.test c1d176326ce244db157ce9c3ba128be2a9b172d6
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
@ -620,7 +620,7 @@ F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
F test/tempdb.test 800c36623d67a2ad1f58784b9c5644e0405af6e6
F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
F test/tester.tcl bc01480bbf2e948b52da8943fedc4237b0735961
F test/tester.tcl 36552bcc93adb3a932a487da84da6597cdc5871b
F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
@ -799,7 +799,7 @@ F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
F test/where3.test 3bf8006d441b66a57bee02bb420423f84eb8fde3
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
@ -842,7 +842,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P f99a902f9b3d0bf6f607c4ba641b4096fbbef5d5
R 619c44a049e165e5bdd234c179e111ef
P 800f496929fb0d45d16c573c5dca0197ac922e2b ca479f3de2927ccc05dc76d10e40c00b8e0c88d1
R 5a6390c995b69a7f924deee65f1b7dc5
U dan
Z 4f4c91f530cb0822ccee88049df426ee
Z 434bd8bfb5691e86b993c0ccfbfc4d4c

View File

@ -1 +1 @@
800f496929fb0d45d16c573c5dca0197ac922e2b
acd26b8b746980c344db017a0e96dbd92c89acdf

View File

@ -37,7 +37,7 @@
#include "sqliteInt.h"
/* Size of the Bitvec structure in bytes. */
#define BITVEC_SZ (sizeof(void*)*128) /* 512 on 32bit. 1024 on 64bit */
#define BITVEC_SZ 512
/* Round the union size down to the nearest pointer boundary, since that's how
** it will be aligned within the Bitvec struct. */

View File

@ -2569,13 +2569,27 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
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);
}
}
}
}
@ -3314,9 +3328,11 @@ int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){
if( iSavepoint<0 && pBt->initiallyEmpty ) pBt->nPage = 0;
rc = newDatabase(pBt);
pBt->nPage = get4byte(28 + pBt->pPage1->aData);
if( pBt->nPage==0 ){
sqlite3PagerPagecount(pBt->pPager, (int*)&pBt->nPage);
}
/* 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 );
}
sqlite3BtreeLeave(p);
}

View File

@ -4064,6 +4064,8 @@ WhereInfo *sqlite3WhereBegin(
int bestJ = -1; /* The value of j */
Bitmask m; /* Bitmask value for j or bestJ */
int isOptimal; /* Iterator for optimal/non-optimal search */
int nUnconstrained; /* Number tables without INDEXED BY */
Bitmask notIndexed; /* Mask of tables that cannot use an index */
memset(&bestPlan, 0, sizeof(bestPlan));
bestPlan.rCost = SQLITE_BIG_DBL;
@ -4105,8 +4107,10 @@ WhereInfo *sqlite3WhereBegin(
** algorithm may choose to use t2 for the outer loop, which is a much
** costlier approach.
*/
nUnconstrained = 0;
notIndexed = 0;
for(isOptimal=(iFrom<nTabList-1); isOptimal>=0; isOptimal--){
Bitmask mask; /* Mask of tables not yet ready */
Bitmask mask; /* Mask of tables not yet ready */
for(j=iFrom, pTabItem=&pTabList->a[j]; j<nTabList; j++, pTabItem++){
int doNotReorder; /* True if this table should not be reordered */
WhereCost sCost; /* Cost information from best[Virtual]Index() */
@ -4121,6 +4125,7 @@ WhereInfo *sqlite3WhereBegin(
}
mask = (isOptimal ? m : notReady);
pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0);
if( pTabItem->pIndex==0 ) nUnconstrained++;
assert( pTabItem->pTab );
#ifndef SQLITE_OMIT_VIRTUALTABLE
@ -4134,9 +4139,43 @@ WhereInfo *sqlite3WhereBegin(
}
assert( isOptimal || (sCost.used&notReady)==0 );
if( (sCost.used&notReady)==0
&& (bestJ<0 || sCost.rCost<bestPlan.rCost
|| (sCost.rCost<=bestPlan.rCost && sCost.nRow<bestPlan.nRow))
/* If an INDEXED BY clause is present, then the plan must use that
** index if it uses any index at all */
assert( pTabItem->pIndex==0
|| (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0
|| sCost.plan.u.pIdx==pTabItem->pIndex );
if( isOptimal && (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)==0 ){
notIndexed |= m;
}
/* Conditions under which this table becomes the best so far:
**
** (1) The table must not depend on other tables that have not
** yet run.
**
** (2) A full-table-scan plan cannot supercede another plan unless
** it is an "optimal" plan as defined above.
**
** (3) All tables have an INDEXED BY clause or this table lacks an
** INDEXED BY clause or this table uses the specific
** index specified by its INDEXED BY clause. This rule ensures
** that a best-so-far is always selected even if an impossible
** combination of INDEXED BY clauses are given. The error
** will be detected and relayed back to the application later.
** The NEVER() comes about because rule (2) above prevents
** An indexable full-table-scan from reaching rule (3).
**
** (4) The plan cost must be lower than prior plans or else the
** cost must be the same and the number of rows must be lower.
*/
if( (sCost.used&notReady)==0 /* (1) */
&& (bestJ<0 || (notIndexed&m)!=0 /* (2) */
|| (sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0)
&& (nUnconstrained==0 || pTabItem->pIndex==0 /* (3) */
|| NEVER((sCost.plan.wsFlags & WHERE_NOT_FULLSCAN)!=0))
&& (bestJ<0 || sCost.rCost<bestPlan.rCost /* (4) */
|| (sCost.rCost<=bestPlan.rCost && sCost.nRow<bestPlan.nRow))
){
WHERETRACE(("... best so far with cost=%g and nRow=%g\n",
sCost.rCost, sCost.nRow));

View File

@ -117,5 +117,80 @@ ifcapable pager_pragmas {
} {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

View File

@ -123,6 +123,16 @@ do_test indexedby-4.1 {
do_test indexedby-4.2 {
EQP { SELECT * FROM t1 INDEXED BY i1, t2 WHERE a = c }
} {0 1 {TABLE t2} 1 0 {TABLE t1 WITH INDEX i1}}
do_test indexedby-4.3 {
catchsql {
SELECT * FROM t1 INDEXED BY i1, t2 INDEXED BY i3 WHERE a=c
}
} {1 {cannot use index: i1}}
do_test indexedby-4.4 {
catchsql {
SELECT * FROM t2 INDEXED BY i3, t1 INDEXED BY i1 WHERE a=c
}
} {1 {cannot use index: i3}}
# Test embedding an INDEXED BY in a CREATE VIEW statement. This block
# also tests that nothing bad happens if an index refered to by

View File

@ -1045,4 +1045,37 @@ ifcapable crashtest {
}
}
#-------------------------------------------------------------------------
# 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

View File

@ -1230,6 +1230,23 @@ proc slave_test_file {zFile} {
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.

View File

@ -212,5 +212,53 @@ do_test where3-2.7 {
}
} {tB {} tC * tA * tD *}
# Ticket [13f033c865f878953]
# If the outer loop must be a full table scan, do not let ANALYZE trick
# the planner into use a table for the outer loop that might be indexable
# if held until an inner loop.
#
do_test where3-3.0 {
execsql {
CREATE TABLE t301(a INTEGER PRIMARY KEY,b,c);
CREATE INDEX t301c ON t301(c);
INSERT INTO t301 VALUES(1,2,3);
CREATE TABLE t302(x, y);
ANALYZE;
explain query plan
SELECT * FROM t302, t301 WHERE t302.x=5 AND t301.a=t302.y;
}
} {0 0 {TABLE t302} 1 1 {TABLE t301 USING PRIMARY KEY}}
do_test where3-3.1 {
execsql {
explain query plan
SELECT * FROM t301, t302 WHERE t302.x=5 AND t301.a=t302.y;
}
} {0 1 {TABLE t302} 1 0 {TABLE t301 USING PRIMARY KEY}}
# Verify that when there are multiple tables in a join which must be
# full table scans that the query planner attempts put the table with
# the fewest number of output rows as the outer loop.
#
do_test where3-4.0 {
execsql {
CREATE TABLE t400(a INTEGER PRIMARY KEY, b, c);
CREATE TABLE t401(p INTEGER PRIMARY KEY, q, r);
CREATE TABLE t402(x INTEGER PRIMARY KEY, y, z);
EXPLAIN QUERY PLAN
SELECT * FROM t400, t401, t402 WHERE t402.z GLOB 'abc*';
}
} {0 2 {TABLE t402} 1 0 {TABLE t400} 2 1 {TABLE t401}}
do_test where3-4.1 {
execsql {
EXPLAIN QUERY PLAN
SELECT * FROM t400, t401, t402 WHERE t401.r GLOB 'abc*';
}
} {0 1 {TABLE t401} 1 0 {TABLE t400} 2 2 {TABLE t402}}
do_test where3-4.2 {
execsql {
EXPLAIN QUERY PLAN
SELECT * FROM t400, t401, t402 WHERE t400.c GLOB 'abc*';
}
} {0 0 {TABLE t400} 1 1 {TABLE t401} 2 2 {TABLE t402}}
finish_test