Fix a bug in the multi-index OR cost estimator. Remove leftover "breakpoint"

commands from test scripts. (CVS 6086)

FossilOrigin-Name: b090d5736d7eaec17a39d3133e1587b1d2a42acb
This commit is contained in:
drh 2008-12-30 17:55:00 +00:00
parent eb9441eb06
commit 04bbcd5ce9
10 changed files with 151 additions and 29 deletions

View File

@ -1,5 +1,5 @@
C Add\sLEFT\sJOIN\stest\scases\sfor\smulti-index\sOR\sin\swhere9.test.\s(CVS\s6085)
D 2008-12-30T16:35:53
C Fix\sa\sbug\sin\sthe\smulti-index\sOR\scost\sestimator.\s\sRemove\sleftover\s"breakpoint"\ncommands\sfrom\stest\sscripts.\s(CVS\s6086)
D 2008-12-30T17:55:00
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 77635d0909c2067cee03889a1e04ce910d8fb809
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@ -207,7 +207,7 @@ F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
F src/vdbemem.c f9c859ac17e2e05a0f249868ce4f191f69edd31d
F src/vtab.c e39e011d7443a8d574b1b9cde207a35522e6df43
F src/walker.c 488c2660e13224ff70c0c82761118efb547f8f0d
F src/where.c bb4f4f607f914563889802dbc135a4b828a54bb7
F src/where.c b25a7ecf75cfdd7de430934f62f9e17083b9b806
F tclinstaller.tcl 4356d9d94d2b5ed5e68f9f0c80c4df3048dd7617
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
@ -249,7 +249,7 @@ F test/boundary4.tcl 66ca93ab8bbca9d75648dcd6c5cfaea1f629cd53
F test/boundary4.test 6cc878c9f31852b5962b1ed4ecae3726a5ae681c
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
F test/capi2.test 36f87803c811b5986dd31eb5492cb704552776b4
F test/capi2.test 172c717ed101e78e0798dd21b9896a22366f35b4
F test/capi3.test 4d9c110e8c78fdfe0ea61171a17609e627630ca6
F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
F test/capi3c.test ce0fcbbaccfc9703fb247ea9ac5ada96dc9ca047
@ -308,7 +308,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test cb991e44aa7cf744976143afce18586920f6696a
F test/exclusive2.test 6bdf254770a843c2933b54bee9ed239934f0a183
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 135ed46c049916688171e618c5c14312811618d4
F test/expr.test bc1e6997c27238f6de539f1079ff93e5078ea7c3
F test/filectrl.test 8923a6dc7630f31c8a9dd3d3d740aa0922df7bf8
F test/filefmt.test 053b622009fbbb74dd37921ffad374d852c13cd8
F test/fkey1.test c373e4f1ec43416957e0591c4a5cebb63b8a12e7
@ -430,7 +430,7 @@ F test/main.test 187a9a1b5248ed74a83838c581c15ec6023b555b
F test/malloc.test 6bfb1b95188b103b69536effa943ad195c7655d1
F test/malloc3.test 4bc57f850b212f706f3e1b37c4eced1d5a727cd1
F test/malloc4.test 957337613002b7058a85116493a262f679f3a261
F test/malloc5.test c8d0f7673337e8a29afa558735ae937a0d629751
F test/malloc5.test 20d1a0884b03edf811bfd7005faade028367e7c8
F test/malloc6.test 2f039d9821927eacae43e1831f815e157659a151
F test/malloc7.test 7c68a32942858bc715284856c5507446bba88c3a
F test/malloc8.test 9b7a3f8cb9cf0b12fff566e80a980b1767bd961d
@ -470,14 +470,14 @@ F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df
F test/pager.test fd3f5009985728ef7bf0dfe32a1bbc112e6895c5
F test/pager2.test d84c59ae4a803e03d19d72cbb5b14c71850c6163
F test/pager2.test d4b7f6b70ff018b9995e622a32526b275f515042
F test/pager3.test 2323bf27fd5bd887b580247e5bce500ceee994b4
F test/pageropt.test 3ee6578891baaca967f0bd349e4abfa736229e1a
F test/pagesize.test 0d9ff3fedfce6e5ffe8fa7aca9b6d3433a2e843b
F test/pcache.test 515b4c26e9f57660357dfff5b6b697acac1abc5f
F test/pcache2.test 46efd980a89f737847b99327bda19e08fe11e402
F test/permutations.test 4d1546196eeb642611514f68d074c6e779466973
F test/pragma.test 0f299601c3b15e8941eb48d2f7a43e6678e3f735
F test/pragma.test 325aa0833d483b8e0c98e8196f1cc49fa5d8c336
F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
F test/printf.test 262a5acd3158f788e9bdf7f18d718f3af32ff6ef
F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x
@ -655,10 +655,10 @@ F test/where3.test 97d3936e6a443b968f1a61cdcc0f673252000e94
F test/where4.test e9b9e2f2f98f00379e6031db6a6fca29bae782a2
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 42c4373595f4409d9c6a9987b4a60000ad664faf
F test/where7.test c56c34e84f2bf8d4c787cf8ee6ce8b705468b8cb
F test/where7.test 88eb7c53bdbd900cfd130e8f40bb3036bfab031d
F test/where8.test 1b9152a086408ee789166d0a954abc597372f868
F test/where8m.test c1010d61826412ff66abd29bfb32e5d6b37d965c
F test/where9.test 3115a2f703c016749666e632e372a190274b14f2
F test/where9.test 57c444e957c7c5065e9110e071e182e5b3ce8edc
F test/wherelimit.test 5e9fd41e79bb2b2d588ed999d641d9c965619b31
F test/zeroblob.test 792124852ec61458a2eb527b5091791215e0be95
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
@ -689,7 +689,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
P 4b6460221011e02bedb724169e8e4793e539e65a
R 2cc1de2de75d01575a76221c12614ec0
P 96f3b62914adde34079f08428b4e2fe81c193612
R a587871f2078cbde0dc075e778eb076c
U drh
Z 6391d47122122bc1f091deaa9ddd4b9b
Z 599df2fe0ed8072247fd99ebe901d866

View File

@ -1 +1 @@
96f3b62914adde34079f08428b4e2fe81c193612
b090d5736d7eaec17a39d3133e1587b1d2a42acb

View File

@ -16,7 +16,7 @@
** so is applicable. Because this module is responsible for selecting
** indices, you might also think of this module as the "query optimizer".
**
** $Id: where.c,v 1.354 2008/12/30 16:18:48 drh Exp $
** $Id: where.c,v 1.355 2008/12/30 17:55:00 drh Exp $
*/
#include "sqliteInt.h"
@ -1840,7 +1840,6 @@ static void bestIndex(
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
WhereClause tempWC;
tempWC = *pWC;
tempWC.nSlot = 1;
if( pTerm->eOperator==WO_OR
&& ((pTerm->prereqAll & ~maskSrc) & notReady)==0
&& (pTerm->u.pOrInfo->indexable & maskSrc)!=0 ){
@ -1851,11 +1850,13 @@ static void bestIndex(
double nRow = 0;
for(j=0, pOrTerm=pOrWC->a; j<pOrWC->nTerm; j++, pOrTerm++){
WhereCost sTermCost;
WHERETRACE(("... Multi-index OR testing for term %d of %d....\n", j,i));
if( pOrTerm->eOperator==WO_AND ){
WhereClause *pAndWC = &pOrTerm->u.pAndInfo->wc;
bestIndex(pParse, pAndWC, pSrc, notReady, 0, &sTermCost);
}else if( pOrTerm->leftCursor==iCur ){
tempWC.a = pOrTerm;
tempWC.nTerm = 1;
bestIndex(pParse, &tempWC, pSrc, notReady, 0, &sTermCost);
}else{
continue;
@ -1867,6 +1868,8 @@ static void bestIndex(
rTotal += sTermCost.rCost;
nRow += sTermCost.nRow;
}
WHERETRACE(("... multi-index OR cost=%.9g nrow=%.9g\n",
rTotal, nRow));
if( rTotal<pCost->rCost ){
pCost->rCost = rTotal;
pCost->nRow = nRow;

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.36 2008/09/01 15:52:11 drh Exp $
# $Id: capi2.test,v 1.37 2008/12/30 17:55:00 drh Exp $
#
set testdir [file dirname $argv0]
@ -722,7 +722,6 @@ ifcapable view&&subquery {
check_origins {SELECT b, a FROM (SELECT col1 AS a, col2 AS b FROM view1)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.5 {
breakpoint
check_origins {SELECT (SELECT col2 FROM view1), (SELECT col1 FROM view1)}
} [list {main tab1 col2} {main tab1 col1}]
do_test capi2-12.6 {

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing expressions.
#
# $Id: expr.test,v 1.65 2008/08/22 16:29:51 drh Exp $
# $Id: expr.test,v 1.66 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -606,8 +606,6 @@ test_expr2 expr-7.60 {LIKE('_4',b)} {6}
test_expr2 expr-7.61 {GLOB('1?',a)} {10 11 12 13 14 15 16 17 18 19}
test_expr2 expr-7.62 {GLOB('1*4',b)} {10 14}
test_expr2 expr-7.63 {GLOB('*1[456]',b)} {4}
breakpoint
test_expr2 expr-7.64 {b = abs(-2)} {1}
test_expr2 expr-7.65 {b = abs(+-2)} {1}
test_expr2 expr-7.66 {b = abs(++-2)} {1}

View File

@ -18,7 +18,7 @@
# no longer the case. In version 3.6.2, sqlite3_release_memory() only
# reclaims clean pages. This test file has been updated accordingly.
#
# $Id: malloc5.test,v 1.20 2008/08/27 16:38:57 danielk1977 Exp $
# $Id: malloc5.test,v 1.21 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -314,7 +314,6 @@ do_test malloc5-6.1.2 {
} {10 10}
do_test malloc5-6.2.1 {
breakpoint
execsql {SELECT * FROM abc} db2
execsql {SELECT * FROM abc} db
expr [nPage db] + [nPage db2]

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem.
#
# $Id: pager2.test,v 1.8 2008/10/17 18:51:53 danielk1977 Exp $
# $Id: pager2.test,v 1.9 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
@ -342,7 +342,6 @@ for {set i 1} {$i<20} {incr i} {
}
set res
} {}
breakpoint
do_test pager2-4.5.$i.5 {
page_write $g1 "Page-1 v$i"
lrange [pager_stats $p1] 8 9

View File

@ -12,7 +12,7 @@
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.70 2008/11/21 00:10:35 aswift Exp $
# $Id: pragma.test,v 1.71 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -570,7 +570,6 @@ ifcapable tempdb {
} {0 col_main {} 0 {} 0}
}
breakpoint
do_test pragma-6.7 {
execsql {
CREATE TABLE test_table(

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the multi-index OR clause optimizer.
#
# $Id: where7.test,v 1.5 2008/12/30 14:40:07 drh Exp $
# $Id: where7.test,v 1.6 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -106,6 +106,17 @@ do_test where7-1.13 {
}
} {5 4 1 scan 0 sort 1}
do_test where7-1.14 {
count_steps {
SELECT a FROM t1 WHERE (d=8 OR c=6 OR b=4) AND +a>0
}
} {3 scan 4 sort 0}
do_test where7-1.15 {
count_steps {
SELECT a FROM t1 WHERE +a>=0 AND (d=8 OR c=6 OR b=4)
}
} {3 scan 4 sort 0}
do_test where7-1.20 {
set sql "SELECT a FROM t1 WHERE a=11 OR b=11"
for {set i 12} {$i<400} {incr i} {

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the multi-index OR clause optimizer.
#
# $Id: where9.test,v 1.2 2008/12/30 16:35:53 drh Exp $
# $Id: where9.test,v 1.3 2008/12/30 17:55:00 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@ -338,4 +338,118 @@ ifcapable explain {
} {1 1 1}
}
# Make sure that INDEXED BY and multi-index OR clauses play well with
# one another.
#
do_test where9-4.1 {
count_steps {
SELECT a FROM t1
WHERE b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {92 93 97 scan 0 sort 1}
do_test where9-4.2 {
count_steps {
SELECT a FROM t1
WHERE b>1000
AND (c=31031 OR +d IS NULL)
ORDER BY +a
}
} {92 93 97 scan 0 sort 1}
do_test where9-4.3 {
count_steps {
SELECT a FROM t1
WHERE +b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {92 93 97 scan 0 sort 1}
do_test where9-4.4 {
count_steps {
SELECT a FROM t1 INDEXED BY t1b
WHERE b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {92 93 97 scan 0 sort 1}
do_test where9-4.5 {
catchsql {
SELECT a FROM t1 INDEXED BY t1b
WHERE +b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {1 {cannot use index: t1b}}
do_test where9-4.6 {
count_steps {
SELECT a FROM t1 NOT INDEXED
WHERE b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {92 93 97 scan 98 sort 1}
do_test where9-4.7 {
catchsql {
SELECT a FROM t1 INDEXED BY t1c
WHERE b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {1 {cannot use index: t1c}}
do_test where9-4.8 {
catchsql {
SELECT a FROM t1 INDEXED BY t1d
WHERE b>1000
AND (c=31031 OR d IS NULL)
ORDER BY +a
}
} {1 {cannot use index: t1d}}
ifcapable explain {
# The (c=31031 OR d IS NULL) clause is preferred over b>1000 because
# the former is an equality test which is expected to return fewer rows.
#
do_test where9-5.1 {
set r [db eval {
EXPLAIN QUERY PLAN
SELECT a FROM t1
WHERE b>1000
AND (c=31031 OR d IS NULL)
}]
set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
concat $a $b
} {1 0}
# In contrast, b=1000 is preferred over any OR-clause.
#
do_test where9-5.2 {
set r [db eval {
EXPLAIN QUERY PLAN
SELECT a FROM t1
WHERE b=1000
AND (c=31031 OR d IS NULL)
}]
set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
concat $a $b
} {0 1}
# Likewise, inequalities in an AND are preferred over inequalities in
# an OR.
#
do_test where9-5.3 {
set r [db eval {
EXPLAIN QUERY PLAN
SELECT a FROM t1
WHERE b>1000
AND (c>=31031 OR d IS NULL)
}]
set a [expr {[lsearch $r {TABLE t1 VIA MULTI-INDEX UNION}]>=0}]
set b [expr {[lsearch $r {TABLE t1 WITH INDEX t1b}]>=0}]
concat $a $b
} {0 1}
}
finish_test