Annotation of embedaddon/sqlite3/test/where2.test, revision 1.1
1.1 ! misho 1: # 2005 July 28
! 2: #
! 3: # The author disclaims copyright to this source code. In place of
! 4: # a legal notice, here is a blessing:
! 5: #
! 6: # May you do good and not evil.
! 7: # May you find forgiveness for yourself and forgive others.
! 8: # May you share freely, never taking more than you give.
! 9: #
! 10: #***********************************************************************
! 11: # This file implements regression tests for SQLite library. The
! 12: # focus of this file is testing the use of indices in WHERE clauses
! 13: # based on recent changes to the optimizer.
! 14: #
! 15: # $Id: where2.test,v 1.15 2009/02/02 01:50:40 drh Exp $
! 16:
! 17: set testdir [file dirname $argv0]
! 18: source $testdir/tester.tcl
! 19:
! 20: # Build some test data
! 21: #
! 22: do_test where2-1.0 {
! 23: execsql {
! 24: BEGIN;
! 25: CREATE TABLE t1(w int, x int, y int, z int);
! 26: }
! 27: for {set i 1} {$i<=100} {incr i} {
! 28: set w $i
! 29: set x [expr {int(log($i)/log(2))}]
! 30: set y [expr {$i*$i + 2*$i + 1}]
! 31: set z [expr {$x+$y}]
! 32: ifcapable tclvar {
! 33: execsql {INSERT INTO t1 VALUES($::w,$::x,$::y,$::z)}
! 34: } else {
! 35: execsql {INSERT INTO t1 VALUES(:w,:x,:y,:z)}
! 36: }
! 37: }
! 38: execsql {
! 39: CREATE UNIQUE INDEX i1w ON t1(w);
! 40: CREATE INDEX i1xy ON t1(x,y);
! 41: CREATE INDEX i1zyx ON t1(z,y,x);
! 42: COMMIT;
! 43: }
! 44: } {}
! 45:
! 46: # Do an SQL statement. Append the search count to the end of the result.
! 47: #
! 48: proc count sql {
! 49: set ::sqlite_search_count 0
! 50: return [concat [execsql $sql] $::sqlite_search_count]
! 51: }
! 52:
! 53: # This procedure executes the SQL. Then it checks to see if the OP_Sort
! 54: # opcode was executed. If an OP_Sort did occur, then "sort" is appended
! 55: # to the result. If no OP_Sort happened, then "nosort" is appended.
! 56: #
! 57: # This procedure is used to check to make sure sorting is or is not
! 58: # occurring as expected.
! 59: #
! 60: proc cksort {sql} {
! 61: set data [execsql $sql]
! 62: if {[db status sort]} {set x sort} {set x nosort}
! 63: lappend data $x
! 64: return $data
! 65: }
! 66:
! 67: # This procedure executes the SQL. Then it appends to the result the
! 68: # "sort" or "nosort" keyword (as in the cksort procedure above) then
! 69: # it appends the ::sqlite_query_plan variable.
! 70: #
! 71: proc queryplan {sql} {
! 72: set ::sqlite_sort_count 0
! 73: set data [execsql $sql]
! 74: if {$::sqlite_sort_count} {set x sort} {set x nosort}
! 75: lappend data $x
! 76: return [concat $data $::sqlite_query_plan]
! 77: }
! 78:
! 79:
! 80: # Prefer a UNIQUE index over another index.
! 81: #
! 82: do_test where2-1.1 {
! 83: queryplan {
! 84: SELECT * FROM t1 WHERE w=85 AND x=6 AND y=7396
! 85: }
! 86: } {85 6 7396 7402 nosort t1 i1w}
! 87:
! 88: # Always prefer a rowid== constraint over any other index.
! 89: #
! 90: do_test where2-1.3 {
! 91: queryplan {
! 92: SELECT * FROM t1 WHERE w=85 AND x=6 AND y=7396 AND rowid=85
! 93: }
! 94: } {85 6 7396 7402 nosort t1 *}
! 95:
! 96: # When constrained by a UNIQUE index, the ORDER BY clause is always ignored.
! 97: #
! 98: do_test where2-2.1 {
! 99: queryplan {
! 100: SELECT * FROM t1 WHERE w=85 ORDER BY random();
! 101: }
! 102: } {85 6 7396 7402 nosort t1 i1w}
! 103: do_test where2-2.2 {
! 104: queryplan {
! 105: SELECT * FROM t1 WHERE x=6 AND y=7396 ORDER BY random();
! 106: }
! 107: } {85 6 7396 7402 sort t1 i1xy}
! 108: do_test where2-2.3 {
! 109: queryplan {
! 110: SELECT * FROM t1 WHERE rowid=85 AND x=6 AND y=7396 ORDER BY random();
! 111: }
! 112: } {85 6 7396 7402 nosort t1 *}
! 113:
! 114:
! 115: # Efficient handling of forward and reverse table scans.
! 116: #
! 117: do_test where2-3.1 {
! 118: queryplan {
! 119: SELECT * FROM t1 ORDER BY rowid LIMIT 2
! 120: }
! 121: } {1 0 4 4 2 1 9 10 nosort t1 *}
! 122: do_test where2-3.2 {
! 123: queryplan {
! 124: SELECT * FROM t1 ORDER BY rowid DESC LIMIT 2
! 125: }
! 126: } {100 6 10201 10207 99 6 10000 10006 nosort t1 *}
! 127:
! 128: # The IN operator can be used by indices at multiple layers
! 129: #
! 130: ifcapable subquery {
! 131: do_test where2-4.1 {
! 132: queryplan {
! 133: SELECT * FROM t1 WHERE z IN (10207,10006) AND y IN (10000,10201)
! 134: AND x>0 AND x<10
! 135: ORDER BY w
! 136: }
! 137: } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx}
! 138: do_test where2-4.2 {
! 139: queryplan {
! 140: SELECT * FROM t1 WHERE z IN (10207,10006) AND y=10000
! 141: AND x>0 AND x<10
! 142: ORDER BY w
! 143: }
! 144: } {99 6 10000 10006 sort t1 i1zyx}
! 145: do_test where2-4.3 {
! 146: queryplan {
! 147: SELECT * FROM t1 WHERE z=10006 AND y IN (10000,10201)
! 148: AND x>0 AND x<10
! 149: ORDER BY w
! 150: }
! 151: } {99 6 10000 10006 sort t1 i1zyx}
! 152: ifcapable compound {
! 153: do_test where2-4.4 {
! 154: queryplan {
! 155: SELECT * FROM t1 WHERE z IN (SELECT 10207 UNION SELECT 10006)
! 156: AND y IN (10000,10201)
! 157: AND x>0 AND x<10
! 158: ORDER BY w
! 159: }
! 160: } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx}
! 161: do_test where2-4.5 {
! 162: queryplan {
! 163: SELECT * FROM t1 WHERE z IN (SELECT 10207 UNION SELECT 10006)
! 164: AND y IN (SELECT 10000 UNION SELECT 10201)
! 165: AND x>0 AND x<10
! 166: ORDER BY w
! 167: }
! 168: } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx}
! 169: }
! 170: do_test where2-4.6 {
! 171: queryplan {
! 172: SELECT * FROM t1
! 173: WHERE x IN (1,2,3,4,5,6,7,8)
! 174: AND y IN (10000,10001,10002,10003,10004,10005)
! 175: ORDER BY 2
! 176: }
! 177: } {99 6 10000 10006 sort t1 i1xy}
! 178:
! 179: # Duplicate entires on the RHS of an IN operator do not cause duplicate
! 180: # output rows.
! 181: #
! 182: do_test where2-4.6 {
! 183: queryplan {
! 184: SELECT * FROM t1 WHERE z IN (10207,10006,10006,10207)
! 185: ORDER BY w
! 186: }
! 187: } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx}
! 188: ifcapable compound {
! 189: do_test where2-4.7 {
! 190: queryplan {
! 191: SELECT * FROM t1 WHERE z IN (
! 192: SELECT 10207 UNION ALL SELECT 10006
! 193: UNION ALL SELECT 10006 UNION ALL SELECT 10207)
! 194: ORDER BY w
! 195: }
! 196: } {99 6 10000 10006 100 6 10201 10207 sort t1 i1zyx}
! 197: }
! 198:
! 199: } ;# ifcapable subquery
! 200:
! 201: # The use of an IN operator disables the index as a sorter.
! 202: #
! 203: do_test where2-5.1 {
! 204: queryplan {
! 205: SELECT * FROM t1 WHERE w=99 ORDER BY w
! 206: }
! 207: } {99 6 10000 10006 nosort t1 i1w}
! 208:
! 209: ifcapable subquery {
! 210: do_test where2-5.2 {
! 211: queryplan {
! 212: SELECT * FROM t1 WHERE w IN (99) ORDER BY w
! 213: }
! 214: } {99 6 10000 10006 sort t1 i1w}
! 215: }
! 216:
! 217: # Verify that OR clauses get translated into IN operators.
! 218: #
! 219: set ::idx {}
! 220: ifcapable subquery {set ::idx i1w}
! 221: do_test where2-6.1.1 {
! 222: queryplan {
! 223: SELECT * FROM t1 WHERE w=99 OR w=100 ORDER BY +w
! 224: }
! 225: } [list 99 6 10000 10006 100 6 10201 10207 sort t1 $::idx]
! 226: do_test where2-6.1.2 {
! 227: queryplan {
! 228: SELECT * FROM t1 WHERE 99=w OR 100=w ORDER BY +w
! 229: }
! 230: } [list 99 6 10000 10006 100 6 10201 10207 sort t1 $::idx]
! 231: do_test where2-6.2 {
! 232: queryplan {
! 233: SELECT * FROM t1 WHERE w=99 OR w=100 OR 6=w ORDER BY +w
! 234: }
! 235: } [list 6 2 49 51 99 6 10000 10006 100 6 10201 10207 sort t1 $::idx]
! 236:
! 237: do_test where2-6.3 {
! 238: queryplan {
! 239: SELECT * FROM t1 WHERE w=99 OR w=100 OR 6=+w ORDER BY +w
! 240: }
! 241: } {6 2 49 51 99 6 10000 10006 100 6 10201 10207 sort t1 {}}
! 242: do_test where2-6.4 {
! 243: queryplan {
! 244: SELECT * FROM t1 WHERE w=99 OR +w=100 OR 6=w ORDER BY +w
! 245: }
! 246: } {6 2 49 51 99 6 10000 10006 100 6 10201 10207 sort t1 {}}
! 247:
! 248: set ::idx {}
! 249: ifcapable subquery {set ::idx i1zyx}
! 250: do_test where2-6.5 {
! 251: queryplan {
! 252: SELECT b.* FROM t1 a, t1 b
! 253: WHERE a.w=1 AND (a.y=b.z OR b.z=10)
! 254: ORDER BY +b.w
! 255: }
! 256: } [list 1 0 4 4 2 1 9 10 sort a i1w b $::idx]
! 257: do_test where2-6.6 {
! 258: queryplan {
! 259: SELECT b.* FROM t1 a, t1 b
! 260: WHERE a.w=1 AND (b.z=10 OR a.y=b.z OR b.z=10)
! 261: ORDER BY +b.w
! 262: }
! 263: } [list 1 0 4 4 2 1 9 10 sort a i1w b $::idx]
! 264:
! 265: # Ticket #2249. Make sure the OR optimization is not attempted if
! 266: # comparisons between columns of different affinities are needed.
! 267: #
! 268: do_test where2-6.7 {
! 269: execsql {
! 270: CREATE TABLE t2249a(a TEXT UNIQUE);
! 271: CREATE TABLE t2249b(b INTEGER);
! 272: INSERT INTO t2249a VALUES('0123');
! 273: INSERT INTO t2249b VALUES(123);
! 274: }
! 275: queryplan {
! 276: -- Because a is type TEXT and b is type INTEGER, both a and b
! 277: -- will attempt to convert to NUMERIC before the comparison.
! 278: -- They will thus compare equal.
! 279: --
! 280: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a=b;
! 281: }
! 282: } {123 0123 nosort t2249b {} t2249a {}}
! 283: do_test where2-6.9 {
! 284: queryplan {
! 285: -- The + operator removes affinity from the rhs. No conversions
! 286: -- occur and the comparison is false. The result is an empty set.
! 287: --
! 288: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a=+b;
! 289: }
! 290: } {nosort t2249b {} {} sqlite_autoindex_t2249a_1}
! 291: do_test where2-6.9.2 {
! 292: # The same thing but with the expression flipped around.
! 293: queryplan {
! 294: SELECT * FROM t2249b CROSS JOIN t2249a WHERE +b=a
! 295: }
! 296: } {nosort t2249b {} {} sqlite_autoindex_t2249a_1}
! 297: do_test where2-6.10 {
! 298: queryplan {
! 299: -- Use + on both sides of the comparison to disable indices
! 300: -- completely. Make sure we get the same result.
! 301: --
! 302: SELECT * FROM t2249b CROSS JOIN t2249a WHERE +a=+b;
! 303: }
! 304: } {nosort t2249b {} t2249a {}}
! 305: do_test where2-6.11 {
! 306: # This will not attempt the OR optimization because of the a=b
! 307: # comparison.
! 308: queryplan {
! 309: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a=b OR a='hello';
! 310: }
! 311: } {123 0123 nosort t2249b {} t2249a {}}
! 312: do_test where2-6.11.2 {
! 313: # Permutations of the expression terms.
! 314: queryplan {
! 315: SELECT * FROM t2249b CROSS JOIN t2249a WHERE b=a OR a='hello';
! 316: }
! 317: } {123 0123 nosort t2249b {} t2249a {}}
! 318: do_test where2-6.11.3 {
! 319: # Permutations of the expression terms.
! 320: queryplan {
! 321: SELECT * FROM t2249b CROSS JOIN t2249a WHERE 'hello'=a OR b=a;
! 322: }
! 323: } {123 0123 nosort t2249b {} t2249a {}}
! 324: do_test where2-6.11.4 {
! 325: # Permutations of the expression terms.
! 326: queryplan {
! 327: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR b=a;
! 328: }
! 329: } {123 0123 nosort t2249b {} t2249a {}}
! 330: ifcapable explain&&subquery {
! 331: # These tests are not run if subquery support is not included in the
! 332: # build. This is because these tests test the "a = 1 OR a = 2" to
! 333: # "a IN (1, 2)" optimisation transformation, which is not enabled if
! 334: # subqueries and the IN operator is not available.
! 335: #
! 336: do_test where2-6.12 {
! 337: # In this case, the +b disables the affinity conflict and allows
! 338: # the OR optimization to be used again. The result is now an empty
! 339: # set, the same as in where2-6.9.
! 340: queryplan {
! 341: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a=+b OR a='hello';
! 342: }
! 343: } {nosort t2249b {} {} sqlite_autoindex_t2249a_1}
! 344: do_test where2-6.12.2 {
! 345: # In this case, the +b disables the affinity conflict and allows
! 346: # the OR optimization to be used again. The result is now an empty
! 347: # set, the same as in where2-6.9.
! 348: queryplan {
! 349: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a='hello' OR +b=a;
! 350: }
! 351: } {nosort t2249b {} {} sqlite_autoindex_t2249a_1}
! 352: do_test where2-6.12.3 {
! 353: # In this case, the +b disables the affinity conflict and allows
! 354: # the OR optimization to be used again. The result is now an empty
! 355: # set, the same as in where2-6.9.
! 356: queryplan {
! 357: SELECT * FROM t2249b CROSS JOIN t2249a WHERE +b=a OR a='hello';
! 358: }
! 359: } {nosort t2249b {} {} sqlite_autoindex_t2249a_1}
! 360: do_test where2-6.13 {
! 361: # The addition of +a on the second term disabled the OR optimization.
! 362: # But we should still get the same empty-set result as in where2-6.9.
! 363: queryplan {
! 364: SELECT * FROM t2249b CROSS JOIN t2249a WHERE a=+b OR +a='hello';
! 365: }
! 366: } {nosort t2249b {} t2249a {}}
! 367: }
! 368:
! 369: # Variations on the order of terms in a WHERE clause in order
! 370: # to make sure the OR optimizer can recognize them all.
! 371: do_test where2-6.20 {
! 372: queryplan {
! 373: SELECT * FROM t2249a x CROSS JOIN t2249a y WHERE x.a=y.a
! 374: }
! 375: } {0123 0123 nosort x {} {} sqlite_autoindex_t2249a_1}
! 376: ifcapable explain&&subquery {
! 377: # These tests are not run if subquery support is not included in the
! 378: # build. This is because these tests test the "a = 1 OR a = 2" to
! 379: # "a IN (1, 2)" optimisation transformation, which is not enabled if
! 380: # subqueries and the IN operator is not available.
! 381: #
! 382: do_test where2-6.21 {
! 383: queryplan {
! 384: SELECT * FROM t2249a x CROSS JOIN t2249a y WHERE x.a=y.a OR y.a='hello'
! 385: }
! 386: } {0123 0123 nosort x {} {} sqlite_autoindex_t2249a_1}
! 387: do_test where2-6.22 {
! 388: queryplan {
! 389: SELECT * FROM t2249a x CROSS JOIN t2249a y WHERE y.a=x.a OR y.a='hello'
! 390: }
! 391: } {0123 0123 nosort x {} {} sqlite_autoindex_t2249a_1}
! 392: do_test where2-6.23 {
! 393: queryplan {
! 394: SELECT * FROM t2249a x CROSS JOIN t2249a y WHERE y.a='hello' OR x.a=y.a
! 395: }
! 396: } {0123 0123 nosort x {} {} sqlite_autoindex_t2249a_1}
! 397: }
! 398:
! 399: # Unique queries (queries that are guaranteed to return only a single
! 400: # row of result) do not call the sorter. But all tables must give
! 401: # a unique result. If any one table in the join does not give a unique
! 402: # result then sorting is necessary.
! 403: #
! 404: do_test where2-7.1 {
! 405: cksort {
! 406: create table t8(a unique, b, c);
! 407: insert into t8 values(1,2,3);
! 408: insert into t8 values(2,3,4);
! 409: create table t9(x,y);
! 410: insert into t9 values(2,4);
! 411: insert into t9 values(2,3);
! 412: select y from t8, t9 where a=1 order by a, y;
! 413: }
! 414: } {3 4 sort}
! 415: do_test where2-7.2 {
! 416: cksort {
! 417: select * from t8 where a=1 order by b, c
! 418: }
! 419: } {1 2 3 nosort}
! 420: do_test where2-7.3 {
! 421: cksort {
! 422: select * from t8, t9 where a=1 and y=3 order by b, x
! 423: }
! 424: } {1 2 3 2 3 sort}
! 425: do_test where2-7.4 {
! 426: cksort {
! 427: create unique index i9y on t9(y);
! 428: select * from t8, t9 where a=1 and y=3 order by b, x
! 429: }
! 430: } {1 2 3 2 3 nosort}
! 431:
! 432: # Ticket #1807. Using IN constrains on multiple columns of
! 433: # a multi-column index.
! 434: #
! 435: ifcapable subquery {
! 436: do_test where2-8.1 {
! 437: execsql {
! 438: SELECT * FROM t1 WHERE x IN (20,21) AND y IN (1,2)
! 439: }
! 440: } {}
! 441: do_test where2-8.2 {
! 442: execsql {
! 443: SELECT * FROM t1 WHERE x IN (1,2) AND y IN (-5,-6)
! 444: }
! 445: } {}
! 446: execsql {CREATE TABLE tx AS SELECT * FROM t1}
! 447: do_test where2-8.3 {
! 448: execsql {
! 449: SELECT w FROM t1
! 450: WHERE x IN (SELECT x FROM tx WHERE rowid<0)
! 451: AND +y IN (SELECT y FROM tx WHERE rowid=1)
! 452: }
! 453: } {}
! 454: do_test where2-8.4 {
! 455: execsql {
! 456: SELECT w FROM t1
! 457: WHERE x IN (SELECT x FROM tx WHERE rowid=1)
! 458: AND y IN (SELECT y FROM tx WHERE rowid<0)
! 459: }
! 460: } {}
! 461: #set sqlite_where_trace 1
! 462: do_test where2-8.5 {
! 463: execsql {
! 464: CREATE INDEX tx_xyz ON tx(x, y, z, w);
! 465: SELECT w FROM tx
! 466: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 467: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 468: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 12 AND 14)
! 469: }
! 470: } {12 13 14}
! 471: do_test where2-8.6 {
! 472: execsql {
! 473: SELECT w FROM tx
! 474: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 475: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 12 AND 14)
! 476: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 477: }
! 478: } {12 13 14}
! 479: do_test where2-8.7 {
! 480: execsql {
! 481: SELECT w FROM tx
! 482: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 12 AND 14)
! 483: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 484: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 485: }
! 486: } {10 11 12 13 14 15}
! 487: do_test where2-8.8 {
! 488: execsql {
! 489: SELECT w FROM tx
! 490: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 491: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 492: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 493: }
! 494: } {10 11 12 13 14 15 16 17 18 19 20}
! 495: do_test where2-8.9 {
! 496: execsql {
! 497: SELECT w FROM tx
! 498: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 499: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 500: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 2 AND 4)
! 501: }
! 502: } {}
! 503: do_test where2-8.10 {
! 504: execsql {
! 505: SELECT w FROM tx
! 506: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 507: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 2 AND 4)
! 508: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 509: }
! 510: } {}
! 511: do_test where2-8.11 {
! 512: execsql {
! 513: SELECT w FROM tx
! 514: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 2 AND 4)
! 515: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 516: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 517: }
! 518: } {}
! 519: do_test where2-8.12 {
! 520: execsql {
! 521: SELECT w FROM tx
! 522: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 523: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 524: AND z IN (SELECT z FROM t1 WHERE w BETWEEN -4 AND -2)
! 525: }
! 526: } {}
! 527: do_test where2-8.13 {
! 528: execsql {
! 529: SELECT w FROM tx
! 530: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 531: AND y IN (SELECT y FROM t1 WHERE w BETWEEN -4 AND -2)
! 532: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 533: }
! 534: } {}
! 535: do_test where2-8.14 {
! 536: execsql {
! 537: SELECT w FROM tx
! 538: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN -4 AND -2)
! 539: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 540: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 541: }
! 542: } {}
! 543: do_test where2-8.15 {
! 544: execsql {
! 545: SELECT w FROM tx
! 546: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 547: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 548: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 200 AND 300)
! 549: }
! 550: } {}
! 551: do_test where2-8.16 {
! 552: execsql {
! 553: SELECT w FROM tx
! 554: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 10 AND 20)
! 555: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 200 AND 300)
! 556: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 557: }
! 558: } {}
! 559: do_test where2-8.17 {
! 560: execsql {
! 561: SELECT w FROM tx
! 562: WHERE x IN (SELECT x FROM t1 WHERE w BETWEEN 200 AND 300)
! 563: AND y IN (SELECT y FROM t1 WHERE w BETWEEN 10 AND 20)
! 564: AND z IN (SELECT z FROM t1 WHERE w BETWEEN 10 AND 20)
! 565: }
! 566: } {}
! 567: do_test where2-8.18 {
! 568: execsql {
! 569: SELECT w FROM tx
! 570: WHERE x IN (SELECT x FROM t1 WHERE +w BETWEEN 10 AND 20)
! 571: AND y IN (SELECT y FROM t1 WHERE +w BETWEEN 10 AND 20)
! 572: AND z IN (SELECT z FROM t1 WHERE +w BETWEEN 200 AND 300)
! 573: }
! 574: } {}
! 575: do_test where2-8.19 {
! 576: execsql {
! 577: SELECT w FROM tx
! 578: WHERE x IN (SELECT x FROM t1 WHERE +w BETWEEN 10 AND 20)
! 579: AND y IN (SELECT y FROM t1 WHERE +w BETWEEN 200 AND 300)
! 580: AND z IN (SELECT z FROM t1 WHERE +w BETWEEN 10 AND 20)
! 581: }
! 582: } {}
! 583: do_test where2-8.20 {
! 584: execsql {
! 585: SELECT w FROM tx
! 586: WHERE x IN (SELECT x FROM t1 WHERE +w BETWEEN 200 AND 300)
! 587: AND y IN (SELECT y FROM t1 WHERE +w BETWEEN 10 AND 20)
! 588: AND z IN (SELECT z FROM t1 WHERE +w BETWEEN 10 AND 20)
! 589: }
! 590: } {}
! 591: }
! 592:
! 593: # Make sure WHERE clauses of the form A=1 AND (B=2 OR B=3) are optimized
! 594: # when we have an index on A and B.
! 595: #
! 596: ifcapable or_opt&&tclvar {
! 597: do_test where2-9.1 {
! 598: execsql {
! 599: BEGIN;
! 600: CREATE TABLE t10(a,b,c);
! 601: INSERT INTO t10 VALUES(1,1,1);
! 602: INSERT INTO t10 VALUES(1,2,2);
! 603: INSERT INTO t10 VALUES(1,3,3);
! 604: }
! 605: for {set i 4} {$i<=1000} {incr i} {
! 606: execsql {INSERT INTO t10 VALUES(1,$i,$i)}
! 607: }
! 608: execsql {
! 609: CREATE INDEX i10 ON t10(a,b);
! 610: COMMIT;
! 611: SELECT count(*) FROM t10;
! 612: }
! 613: } 1000
! 614: ifcapable subquery {
! 615: do_test where2-9.2 {
! 616: count {
! 617: SELECT * FROM t10 WHERE a=1 AND (b=2 OR b=3)
! 618: }
! 619: } {1 2 2 1 3 3 7}
! 620: }
! 621: }
! 622:
! 623: # Indices with redundant columns
! 624: #
! 625: do_test where2-11.1 {
! 626: execsql {
! 627: CREATE TABLE t11(a,b,c,d);
! 628: CREATE INDEX i11aba ON t11(a,b,a,c); -- column A occurs twice.
! 629: INSERT INTO t11 VALUES(1,2,3,4);
! 630: INSERT INTO t11 VALUES(5,6,7,8);
! 631: INSERT INTO t11 VALUES(1,2,9,10);
! 632: INSERT INTO t11 VALUES(5,11,12,13);
! 633: SELECT c FROM t11 WHERE a=1 AND b=2 ORDER BY c;
! 634: }
! 635: } {3 9}
! 636: do_test where2-11.2 {
! 637: execsql {
! 638: CREATE INDEX i11cccccccc ON t11(c,c,c,c,c,c,c,c); -- repeated column
! 639: SELECT d FROM t11 WHERE c=9;
! 640: }
! 641: } {10}
! 642: do_test where2-11.3 {
! 643: execsql {
! 644: SELECT d FROM t11 WHERE c IN (1,2,3,4,5);
! 645: }
! 646: } {4}
! 647: do_test where2-11.4 {
! 648: execsql {
! 649: SELECT d FROM t11 WHERE c=7 OR (a=1 AND b=2) ORDER BY d;
! 650: }
! 651: } {4 8 10}
! 652:
! 653:
! 654: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>