1ed378006Sdrh# 2005 July 28 2ed378006Sdrh# 3ed378006Sdrh# The author disclaims copyright to this source code. In place of 4ed378006Sdrh# a legal notice, here is a blessing: 5ed378006Sdrh# 6ed378006Sdrh# May you do good and not evil. 7ed378006Sdrh# May you find forgiveness for yourself and forgive others. 8ed378006Sdrh# May you share freely, never taking more than you give. 9ed378006Sdrh# 10ed378006Sdrh#*********************************************************************** 11ed378006Sdrh# This file implements regression tests for SQLite library. The 12ed378006Sdrh# focus of this file is testing the use of indices in WHERE clauses 13ed378006Sdrh# when the WHERE clause contains the BETWEEN operator. 14ed378006Sdrh# 153bdca9c9Sdanielk1977# $Id: between.test,v 1.2 2006/01/17 09:35:02 danielk1977 Exp $ 16ed378006Sdrh 17ed378006Sdrhset testdir [file dirname $argv0] 18ed378006Sdrhsource $testdir/tester.tcl 19ed378006Sdrh 20ed378006Sdrh# Build some test data 21ed378006Sdrh# 22ed378006Sdrhdo_test between-1.0 { 23ed378006Sdrh execsql { 24ed378006Sdrh BEGIN; 25ed378006Sdrh CREATE TABLE t1(w int, x int, y int, z int); 26ed378006Sdrh } 27ed378006Sdrh for {set i 1} {$i<=100} {incr i} { 28ed378006Sdrh set w $i 29ed378006Sdrh set x [expr {int(log($i)/log(2))}] 30ed378006Sdrh set y [expr {$i*$i + 2*$i + 1}] 31ed378006Sdrh set z [expr {$x+$y}] 323bdca9c9Sdanielk1977 ifcapable tclvar { 333bdca9c9Sdanielk1977 # Random unplanned test of the $varname variable syntax. 34ed378006Sdrh execsql {INSERT INTO t1 VALUES($::w,$::x,$::y,$::z)} 353bdca9c9Sdanielk1977 } else { 363bdca9c9Sdanielk1977 # If the $varname syntax is not available, use the regular variable 373bdca9c9Sdanielk1977 # declaration syntax. 383bdca9c9Sdanielk1977 execsql {INSERT INTO t1 VALUES(:w,:x,:y,:z)} 393bdca9c9Sdanielk1977 } 40ed378006Sdrh } 41ed378006Sdrh execsql { 42ed378006Sdrh CREATE UNIQUE INDEX i1w ON t1(w); 43ed378006Sdrh CREATE INDEX i1xy ON t1(x,y); 44ed378006Sdrh CREATE INDEX i1zyx ON t1(z,y,x); 45ed378006Sdrh COMMIT; 46ed378006Sdrh } 47ed378006Sdrh} {} 48ed378006Sdrh 49ed378006Sdrh# This procedure executes the SQL. Then it appends to the result the 50ed378006Sdrh# "sort" or "nosort" keyword depending on whether or not any sorting 517c171098Sdrh# is done. Then it appends the names of the table and index used. 52ed378006Sdrh# 53ed378006Sdrhproc queryplan {sql} { 54ed378006Sdrh set ::sqlite_sort_count 0 55ed378006Sdrh set data [execsql $sql] 56ed378006Sdrh if {$::sqlite_sort_count} {set x sort} {set x nosort} 57ed378006Sdrh lappend data $x 58d2b113bcSdrh set eqp [execsql "EXPLAIN QUERY PLAN $sql"] 59d2b113bcSdrh # puts eqp=$eqp 60d2b113bcSdrh foreach {a b c x} $eqp { 61*8210233cSdrh if {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+) USING.* INDEX (\w+)\y} \ 62*8210233cSdrh $x all ss as tab idx]} { 63d2b113bcSdrh lappend data $tab $idx 64*8210233cSdrh } elseif {[regexp {(SCAN|SEARCH) (\w+ AS )?(\w+)\y} $x all ss as tab]} { 65d2b113bcSdrh lappend data $tab * 66d2b113bcSdrh } 67d2b113bcSdrh } 68d2b113bcSdrh return $data 69ed378006Sdrh} 70ed378006Sdrh 71ed378006Sdrhdo_test between-1.1.1 { 72ed378006Sdrh queryplan { 73ed378006Sdrh SELECT * FROM t1 WHERE w BETWEEN 5 AND 6 ORDER BY +w 74ed378006Sdrh } 75ed378006Sdrh} {5 2 36 38 6 2 49 51 sort t1 i1w} 76ed378006Sdrhdo_test between-1.1.2 { 77ed378006Sdrh queryplan { 78ed378006Sdrh SELECT * FROM t1 WHERE +w BETWEEN 5 AND 6 ORDER BY +w 79ed378006Sdrh } 80d2b113bcSdrh} {5 2 36 38 6 2 49 51 sort t1 *} 81ed378006Sdrhdo_test between-1.2.1 { 82ed378006Sdrh queryplan { 83ed378006Sdrh SELECT * FROM t1 WHERE w BETWEEN 5 AND 65-y ORDER BY +w 84ed378006Sdrh } 85ed378006Sdrh} {5 2 36 38 6 2 49 51 sort t1 i1w} 86ed378006Sdrhdo_test between-1.2.2 { 87ed378006Sdrh queryplan { 88ed378006Sdrh SELECT * FROM t1 WHERE +w BETWEEN 5 AND 65-y ORDER BY +w 89ed378006Sdrh } 90d2b113bcSdrh} {5 2 36 38 6 2 49 51 sort t1 *} 91ed378006Sdrhdo_test between-1.3.1 { 92ed378006Sdrh queryplan { 93ed378006Sdrh SELECT * FROM t1 WHERE w BETWEEN 41-y AND 6 ORDER BY +w 94ed378006Sdrh } 95ed378006Sdrh} {5 2 36 38 6 2 49 51 sort t1 i1w} 96ed378006Sdrhdo_test between-1.3.2 { 97ed378006Sdrh queryplan { 98ed378006Sdrh SELECT * FROM t1 WHERE +w BETWEEN 41-y AND 6 ORDER BY +w 99ed378006Sdrh } 100d2b113bcSdrh} {5 2 36 38 6 2 49 51 sort t1 *} 101ed378006Sdrhdo_test between-1.4 { 102ed378006Sdrh queryplan { 103ed378006Sdrh SELECT * FROM t1 WHERE w BETWEEN 41-y AND 65-y ORDER BY +w 104ed378006Sdrh } 105d2b113bcSdrh} {5 2 36 38 6 2 49 51 sort t1 *} 106ed378006Sdrhdo_test between-1.5.1 { 107ed378006Sdrh queryplan { 108ed378006Sdrh SELECT * FROM t1 WHERE 26 BETWEEN y AND z ORDER BY +w 109ed378006Sdrh } 110ed378006Sdrh} {4 2 25 27 sort t1 i1zyx} 111ed378006Sdrhdo_test between-1.5.2 { 112ed378006Sdrh queryplan { 113ed378006Sdrh SELECT * FROM t1 WHERE 26 BETWEEN +y AND z ORDER BY +w 114ed378006Sdrh } 115ed378006Sdrh} {4 2 25 27 sort t1 i1zyx} 116ed378006Sdrhdo_test between-1.5.3 { 117ed378006Sdrh queryplan { 118ed378006Sdrh SELECT * FROM t1 WHERE 26 BETWEEN y AND +z ORDER BY +w 119ed378006Sdrh } 120d2b113bcSdrh} {4 2 25 27 sort t1 *} 121ed378006Sdrh 122069d1b1fSdan#------------------------------------------------------------------------- 123069d1b1fSdanreset_db 124069d1b1fSdando_execsql_test between-2.0 { 125069d1b1fSdan CREATE TABLE t1(x TEXT, y TEXT COLLATE nocase); 126069d1b1fSdan INSERT INTO t1 VALUES('0', 'abc'); 127069d1b1fSdan} 128069d1b1fSdan 129069d1b1fSdanforeach {tn expr res} { 130069d1b1fSdan 1 "x BETWEEN 1 AND '5'" 0 131069d1b1fSdan 2 "x COLLATE binary BETWEEN 1 AND '5'" 0 132069d1b1fSdan 3 "x COLLATE nocase BETWEEN 1 AND '5'" 0 133069d1b1fSdan 134069d1b1fSdan 4 "y BETWEEN 'A' AND 'B'" 1 135069d1b1fSdan 5 "y COLLATE nocase BETWEEN 'A' AND 'B'" 1 136069d1b1fSdan 6 "y COLLATE binary BETWEEN 'A' AND 'B'" 0 137069d1b1fSdan 7 "(y COLLATE binary) BETWEEN 'A' AND 'B'" 0 138069d1b1fSdan} { 139069d1b1fSdan set sql "SELECT $expr FROM t1" 140069d1b1fSdan do_execsql_test between-2.1.$tn $sql $res 141069d1b1fSdan} 142ed378006Sdrh 143ed378006Sdrhfinish_test 144