OLD | NEW |
(Empty) | |
| 1 # 2014 July 15 |
| 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. |
| 12 # |
| 13 |
| 14 set testdir [file dirname $argv0] |
| 15 source $testdir/tester.tcl |
| 16 set testprefix cursorhint |
| 17 |
| 18 ifcapable !cursorhints { |
| 19 finish_test |
| 20 return |
| 21 } |
| 22 |
| 23 do_execsql_test 1.0 { |
| 24 CREATE TABLE t1(a,b,c,d); |
| 25 CREATE TABLE t2(x,y,z); |
| 26 INSERT INTO t1(a,b) VALUES(10, 15); |
| 27 INSERT INTO t1(a,b) VALUES(20, 25); |
| 28 INSERT INTO t2(x,y) VALUES('ten', 'fifteen'); |
| 29 INSERT INTO t2(x,y) VALUES('twenty', 'twentyfive'); |
| 30 CREATE TABLE t3(id TEXT PRIMARY KEY, a, b, c, d) WITHOUT ROWID; |
| 31 INSERT INTO t3(id,a,b,c,d) SELECT rowid, a, b, c, d FROM t1; |
| 32 PRAGMA automatic_index = 0; |
| 33 } |
| 34 |
| 35 # Run EXPLAIN on $sql. Return a list of P4 values for all $opcode |
| 36 # opcodes. |
| 37 # |
| 38 proc p4_of_opcode {db opcode sql} { |
| 39 set res {} |
| 40 $db eval "EXPLAIN $sql" x { |
| 41 if {$x(opcode)==$opcode} {lappend res $x(p4)} |
| 42 } |
| 43 return $res |
| 44 } |
| 45 |
| 46 # Run EXPLAIN on $sql. Return a list of P5 values for all $opcode |
| 47 # opcodes that contain regexp $comment in their comment |
| 48 # |
| 49 proc p5_of_opcode {db opcode sql} { |
| 50 set res {} |
| 51 $db eval "EXPLAIN $sql" x { |
| 52 if {$x(opcode)==$opcode} { |
| 53 lappend res $x(p5) |
| 54 } |
| 55 } |
| 56 return $res |
| 57 } |
| 58 |
| 59 # Verify that when t1 is in the outer loop and t2 is in the inner loop, |
| 60 # no cursor hints occur for t1 (since it is a full table scan) but that |
| 61 # each t2 access has a cursor hint based on the current t1.a value. |
| 62 # |
| 63 do_test 1.1 { |
| 64 p4_of_opcode db CursorHint { |
| 65 SELECT * FROM t1 CROSS JOIN t2 WHERE a=x |
| 66 } |
| 67 } {{EQ(r[1],c0)}} |
| 68 do_test 1.2 { |
| 69 p5_of_opcode db OpenRead { |
| 70 SELECT * FROM t1 CROSS JOIN t2 WHERE a=x |
| 71 } |
| 72 } {00 00} |
| 73 |
| 74 # Do the same test the other way around. |
| 75 # |
| 76 do_test 2.1 { |
| 77 p4_of_opcode db CursorHint { |
| 78 SELECT * FROM t2 CROSS JOIN t1 WHERE a=x |
| 79 } |
| 80 } {{EQ(c0,r[1])}} |
| 81 do_test 2.2 { |
| 82 p5_of_opcode db OpenRead { |
| 83 SELECT * FROM t2 CROSS JOIN t1 WHERE a=x |
| 84 } |
| 85 } {00 00} |
| 86 |
| 87 # Various expressions captured by CursorHint |
| 88 # |
| 89 do_test 3.1 { |
| 90 p4_of_opcode db CursorHint { |
| 91 SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98 |
| 92 } |
| 93 } {AND(AND(EQ(c0,15),EQ(c2,22)),NE(rowid,98))} |
| 94 do_test 3.2 { |
| 95 p4_of_opcode db CursorHint { |
| 96 SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98 |
| 97 } |
| 98 } {AND(AND(LT(c1,15),GT(c2,22)),NE(c0,98))} |
| 99 |
| 100 # Indexed queries |
| 101 # |
| 102 do_test 4.1asc { |
| 103 db eval { |
| 104 CREATE INDEX t1bc ON t1(b,c); |
| 105 CREATE INDEX t2yz ON t2(y,z); |
| 106 } |
| 107 p4_of_opcode db CursorHint { |
| 108 SELECT * FROM t1 WHERE b>11 ORDER BY b ASC; |
| 109 } |
| 110 } {} |
| 111 do_test 4.1desc { |
| 112 p4_of_opcode db CursorHint { |
| 113 SELECT * FROM t1 WHERE b>11 ORDER BY b DESC; |
| 114 } |
| 115 } {GT(c0,11)} |
| 116 do_test 4.2 { |
| 117 p5_of_opcode db OpenRead { |
| 118 SELECT * FROM t1 WHERE b>11; |
| 119 } |
| 120 } {02 00} |
| 121 do_test 4.3asc { |
| 122 p4_of_opcode db CursorHint { |
| 123 SELECT c FROM t1 WHERE b<11 ORDER BY b ASC; |
| 124 } |
| 125 } {LT(c0,11)} |
| 126 do_test 4.3desc { |
| 127 p4_of_opcode db CursorHint { |
| 128 SELECT c FROM t1 WHERE b<11 ORDER BY b DESC; |
| 129 } |
| 130 } {} |
| 131 do_test 4.4 { |
| 132 p5_of_opcode db OpenRead { |
| 133 SELECT c FROM t1 WHERE b<11; |
| 134 } |
| 135 } {00} |
| 136 |
| 137 do_test 4.5asc { |
| 138 p4_of_opcode db CursorHint { |
| 139 SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC; |
| 140 } |
| 141 } {LE(c0,20)} |
| 142 do_test 4.5desc { |
| 143 p4_of_opcode db CursorHint { |
| 144 SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC; |
| 145 } |
| 146 } {GE(c0,10)} |
| 147 |
| 148 # If there are any equality terms used in the constraint, then all terms |
| 149 # should be hinted. |
| 150 # |
| 151 do_test 4.6asc { |
| 152 p4_of_opcode db CursorHint { |
| 153 SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC; |
| 154 } |
| 155 } {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))} |
| 156 do_test 4.6desc { |
| 157 p4_of_opcode db CursorHint { |
| 158 SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC; |
| 159 } |
| 160 } {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))} |
| 161 |
| 162 finish_test |
OLD | NEW |