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 |