3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library.
14 set testdir [file dirname $argv0]
15 source $testdir/tester.tcl
16 set testprefix cursorhint
18 ifcapable !cursorhints {
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;
35 # Run EXPLAIN on $sql. Return a list of P4 values for all $opcode
38 proc p4_of_opcode {db opcode sql} {
40 $db eval "EXPLAIN $sql" x {
41 if {$x(opcode)==$opcode} {lappend res $x(p4)}
46 # Run EXPLAIN on $sql. Return a list of P5 values for all $opcode
47 # opcodes that contain regexp $comment in their comment
49 proc p5_of_opcode {db opcode sql} {
51 $db eval "EXPLAIN $sql" x {
52 if {$x(opcode)==$opcode} {
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.
64 p4_of_opcode db CursorHint {
65 SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
69 p5_of_opcode db OpenRead {
70 SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
74 # Do the same test the other way around.
77 p4_of_opcode db CursorHint {
78 SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
82 p5_of_opcode db OpenRead {
83 SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
87 # Various expressions captured by CursorHint
90 p4_of_opcode db CursorHint {
91 SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98
93 } {AND(AND(EQ(c0,15),EQ(c2,22)),NE(rowid,98))}
95 p4_of_opcode db CursorHint {
96 SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98
98 } {AND(AND(LT(c1,15),GT(c2,22)),NE(c0,98))}
104 CREATE INDEX t1bc ON t1(b,c);
105 CREATE INDEX t2yz ON t2(y,z);
107 p4_of_opcode db CursorHint {
108 SELECT * FROM t1 WHERE b>11 ORDER BY b ASC;
112 p4_of_opcode db CursorHint {
113 SELECT * FROM t1 WHERE b>11 ORDER BY b DESC;
117 p5_of_opcode db OpenRead {
118 SELECT * FROM t1 WHERE b>11;
122 p4_of_opcode db CursorHint {
123 SELECT c FROM t1 WHERE b<11 ORDER BY b ASC;
127 p4_of_opcode db CursorHint {
128 SELECT c FROM t1 WHERE b<11 ORDER BY b DESC;
132 p5_of_opcode db OpenRead {
133 SELECT c FROM t1 WHERE b<11;
138 p4_of_opcode db CursorHint {
139 SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC;
143 p4_of_opcode db CursorHint {
144 SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC;
148 # If there are any equality terms used in the constraint, then all terms
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;
155 } {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
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;
160 } {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}