-C Test\scases\sand\stuning\sof\sthe\snew\soptimizer\scode.\s(CVS\s2567)
-D 2005-07-28T20:51:19
+C The\sBETWEEN\soperator\sin\sa\sWHERE\sclause\sis\snow\sable\sto\suse\sindices.\s(CVS\s2568)
+D 2005-07-28T23:12:08
F Makefile.in 22ea9c0fe748f591712d8fe3c6d972c6c173a165
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
F src/vdbeaux.c 3732a86566a6be4da4c606e9334baf3fd98667af
F src/vdbefifo.c b8805850afe13b43f1de78d58088cb5d66f88e1e
F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
-F src/where.c 6c3de6ee253256d58ef07acb0f07458605477cd4
+F src/where.c c37799a796f490695211189608e1d5abeb01eea8
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
F test/alter.test 9d6837a3d946b73df692b7cef2a7644d2e2f6bc6
F test/autovacuum_crash.test 05a63b8805b20cfba7ace82856ce4ccdda075a31
F test/autovacuum_ioerr.test 9cf27275ca47b72e188a47c53b61b6d583a01d24
F test/autovacuum_ioerr2.test 2f8a3fb31f833fd0ca86ad4ad98913c73e807572
+F test/between.test ca092fa28b665ca92172b182c6c360a92f7ca348
F test/bigfile.test d3744a8821ce9abb8697f2826a3e3d22b719e89f
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
F test/bind.test 3169339a9fb7aaa8244d0ed8651fe6b6796d809c
F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102
F test/view.test 3c79232a2ee45918c62a0cf90411525899404a76
F test/where.test b6ab0f64adc5fbb4259f284b19da6cd9aeadc711
-F test/where2.test 6427619390385bf4fc357b3907b8733012964a92
+F test/where2.test 8696c35cd31b0a298de046f3fb6b684486a8b472
F tool/diffdb.c 7524b1b5df217c20cd0431f6789851a4e0cb191b
F tool/lemon.c c88936c67f6411608db8fa4254d254f509fa40f6
F tool/lempar.c f0c30abcae762a7d1eb37cd88b2232ab8dd625fb
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P a21212843359fb9fdbd60799ae50ad3566f4399a
-R b3b6fd7089d32b94d5badcc51bbe97b5
+P 4b02703dec71aa78e5f8d8cab5b950966a4c6abc
+R 5cec6ff48a1212708f6b9493ee851780
U drh
-Z 603aecf655d7fb47a89068df78f35d0c
+Z 6e3389c38b1260ced7a3d44c47196b06
-4b02703dec71aa78e5f8d8cab5b950966a4c6abc
\ No newline at end of file
+cdf8c9584b945212e065e044df801c207aedb675
\ No newline at end of file
** 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.155 2005/07/28 20:51:19 drh Exp $
+** $Id: where.c,v 1.156 2005/07/28 23:12:08 drh Exp $
*/
#include "sqliteInt.h"
i16 leftCursor; /* Cursor number of X in "X <op> <expr>" */
i16 leftColumn; /* Column number of X in "X <op> <expr>" */
u16 operator; /* A WO_xx value describing <op> */
+ u8 nPartner; /* Number of partners that must disable us */
WhereClause *pWC; /* The clause this term is part of */
Bitmask prereqRight; /* Bitmask of tables used by pRight */
Bitmask prereqAll; /* Bitmask of tables referenced by p */
pNew = whereClauseInsert(pTerm->pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
if( pNew==0 ) return;
pNew->iPartner = pTerm->idx;
+ pTerm->nPartner = 1;
}else{
pDup = pExpr;
pNew = pTerm;
pNew->operator = operatorMask(pDup->op);
}
}
+
+ /* If a term is the BETWEEN operator, create two new virtual terms
+ ** that define the range that the BETWEEN implements.
+ */
+ else if( pExpr->op==TK_BETWEEN ){
+ ExprList *pList = pExpr->pList;
+ int i;
+ static const u8 ops[] = {TK_GE, TK_LE};
+ assert( pList!=0 );
+ assert( pList->nExpr==2 );
+ for(i=0; i<2; i++){
+ Expr *pNewExpr;
+ WhereTerm *pNewTerm;
+ pNewExpr = sqlite3Expr(ops[i], sqlite3ExprDup(pExpr->pLeft),
+ sqlite3ExprDup(pList->a[i].pExpr), 0);
+ pNewTerm = whereClauseInsert(pTerm->pWC, pNewExpr,
+ TERM_VIRTUAL|TERM_DYNAMIC);
+ exprAnalyze(pSrc, pMaskSet, pNewTerm);
+ pNewTerm->iPartner = pTerm->idx;
+ }
+ pTerm->nPartner = 2;
+ }
+
+
}
){
pTerm->flags |= TERM_CODED;
if( pTerm->iPartner>=0 ){
- disableTerm(pLevel, &pTerm->pWC->a[pTerm->iPartner]);
+ WhereTerm *pOther = &pTerm->pWC->a[pTerm->iPartner];
+ if( (--pOther->nPartner)<=0 ){
+ disableTerm(pLevel, pOther);
+ }
}
}
}
--- /dev/null
+# 2005 July 28
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this file is testing the use of indices in WHERE clauses
+# when the WHERE clause contains the BETWEEN operator.
+#
+# $Id: between.test,v 1.1 2005/07/28 23:12:08 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Build some test data
+#
+do_test between-1.0 {
+ execsql {
+ BEGIN;
+ CREATE TABLE t1(w int, x int, y int, z int);
+ }
+ for {set i 1} {$i<=100} {incr i} {
+ set w $i
+ set x [expr {int(log($i)/log(2))}]
+ set y [expr {$i*$i + 2*$i + 1}]
+ set z [expr {$x+$y}]
+ execsql {INSERT INTO t1 VALUES($::w,$::x,$::y,$::z)}
+ }
+ execsql {
+ CREATE UNIQUE INDEX i1w ON t1(w);
+ CREATE INDEX i1xy ON t1(x,y);
+ CREATE INDEX i1zyx ON t1(z,y,x);
+ COMMIT;
+ }
+} {}
+
+# This procedure executes the SQL. Then it appends to the result the
+# "sort" or "nosort" keyword depending on whether or not any sorting
+# is done. Then it appends the ::sqlite_query_plan variable.
+#
+proc queryplan {sql} {
+ set ::sqlite_sort_count 0
+ set data [execsql $sql]
+ if {$::sqlite_sort_count} {set x sort} {set x nosort}
+ lappend data $x
+ return [concat $data $::sqlite_query_plan]
+}
+
+do_test between-1.1.1 {
+ queryplan {
+ SELECT * FROM t1 WHERE w BETWEEN 5 AND 6 ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 i1w}
+do_test between-1.1.2 {
+ queryplan {
+ SELECT * FROM t1 WHERE +w BETWEEN 5 AND 6 ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 {}}
+do_test between-1.2.1 {
+ queryplan {
+ SELECT * FROM t1 WHERE w BETWEEN 5 AND 65-y ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 i1w}
+do_test between-1.2.2 {
+ queryplan {
+ SELECT * FROM t1 WHERE +w BETWEEN 5 AND 65-y ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 {}}
+do_test between-1.3.1 {
+ queryplan {
+ SELECT * FROM t1 WHERE w BETWEEN 41-y AND 6 ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 i1w}
+do_test between-1.3.2 {
+ queryplan {
+ SELECT * FROM t1 WHERE +w BETWEEN 41-y AND 6 ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 {}}
+do_test between-1.4 {
+ queryplan {
+ SELECT * FROM t1 WHERE w BETWEEN 41-y AND 65-y ORDER BY +w
+ }
+} {5 2 36 38 6 2 49 51 sort t1 {}}
+do_test between-1.5.1 {
+ queryplan {
+ SELECT * FROM t1 WHERE 26 BETWEEN y AND z ORDER BY +w
+ }
+} {4 2 25 27 sort t1 i1zyx}
+do_test between-1.5.2 {
+ queryplan {
+ SELECT * FROM t1 WHERE 26 BETWEEN +y AND z ORDER BY +w
+ }
+} {4 2 25 27 sort t1 i1zyx}
+do_test between-1.5.3 {
+ queryplan {
+ SELECT * FROM t1 WHERE 26 BETWEEN y AND +z ORDER BY +w
+ }
+} {4 2 25 27 sort t1 {}}
+
+
+finish_test
# focus of this file is testing the use of indices in WHERE clauses
# based on recent changes to the optimizer.
#
-# $Id: where2.test,v 1.1 2005/07/28 20:51:19 drh Exp $
+# $Id: where2.test,v 1.2 2005/07/28 23:12:08 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {99 6 10000 10006 sort t1 i1w}
-
integrity_check {where2-99.0}
finish_test