Merge trunk changes with experimental branch.
FossilOrigin-Name: acd26b8b746980c344db017a0e96dbd92c89acdf
This commit is contained in:
commit
4557b92cdb
26
manifest
26
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
800f496929fb0d45d16c573c5dca0197ac922e2b
|
||||
acd26b8b746980c344db017a0e96dbd92c89acdf
|
@ -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. */
|
||||
|
26
src/btree.c
26
src/btree.c
@ -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);
|
||||
}
|
||||
|
47
src/where.c
47
src/where.c
@ -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¬Ready)==0 );
|
||||
|
||||
if( (sCost.used¬Ready)==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¬Ready)==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));
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user