xref: /sqlite-3.40.0/test/cursorhint.test (revision a796de83)
191d3a61fSdan# 2014 July 15
291d3a61fSdan#
391d3a61fSdan# The author disclaims copyright to this source code.  In place of
491d3a61fSdan# a legal notice, here is a blessing:
591d3a61fSdan#
691d3a61fSdan#    May you do good and not evil.
791d3a61fSdan#    May you find forgiveness for yourself and forgive others.
891d3a61fSdan#    May you share freely, never taking more than you give.
991d3a61fSdan#
1091d3a61fSdan#***********************************************************************
1191d3a61fSdan# This file implements regression tests for SQLite library.
1291d3a61fSdan#
1391d3a61fSdan
1491d3a61fSdanset testdir [file dirname $argv0]
1591d3a61fSdansource $testdir/tester.tcl
1691d3a61fSdanset testprefix cursorhint
1791d3a61fSdan
18f7854c73Sdrhifcapable !cursorhints {
19f7854c73Sdrh  finish_test
20f7854c73Sdrh  return
21f7854c73Sdrh}
22f7854c73Sdrh
2391d3a61fSdando_execsql_test 1.0 {
241eb6eeb8Sdrh  CREATE TABLE t1(a,b,c,d);
251eb6eeb8Sdrh  CREATE TABLE t2(x,y,z);
261eb6eeb8Sdrh  INSERT INTO t1(a,b) VALUES(10, 15);
271eb6eeb8Sdrh  INSERT INTO t1(a,b) VALUES(20, 25);
281eb6eeb8Sdrh  INSERT INTO t2(x,y) VALUES('ten', 'fifteen');
291eb6eeb8Sdrh  INSERT INTO t2(x,y) VALUES('twenty', 'twentyfive');
301eb6eeb8Sdrh  CREATE TABLE t3(id TEXT PRIMARY KEY, a, b, c, d) WITHOUT ROWID;
311eb6eeb8Sdrh  INSERT INTO t3(id,a,b,c,d) SELECT rowid, a, b, c, d FROM t1;
3291d3a61fSdan  PRAGMA automatic_index = 0;
3391d3a61fSdan}
3491d3a61fSdan
351eb6eeb8Sdrh# Run EXPLAIN on $sql.  Return a list of P4 values for all $opcode
361eb6eeb8Sdrh# opcodes.
371eb6eeb8Sdrh#
381eb6eeb8Sdrhproc p4_of_opcode {db opcode sql} {
391eb6eeb8Sdrh  set res {}
401eb6eeb8Sdrh  $db eval "EXPLAIN $sql" x {
411eb6eeb8Sdrh    if {$x(opcode)==$opcode} {lappend res $x(p4)}
421eb6eeb8Sdrh  }
431eb6eeb8Sdrh  return $res
4491d3a61fSdan}
4591d3a61fSdan
461eb6eeb8Sdrh# Run EXPLAIN on $sql.  Return a list of P5 values for all $opcode
471eb6eeb8Sdrh# opcodes that contain regexp $comment in their comment
481eb6eeb8Sdrh#
497f10579aSdrhproc p5_of_opcode {db opcode sql} {
501eb6eeb8Sdrh  set res {}
511eb6eeb8Sdrh  $db eval "EXPLAIN $sql" x {
527f10579aSdrh    if {$x(opcode)==$opcode} {
531eb6eeb8Sdrh      lappend res $x(p5)
541eb6eeb8Sdrh    }
551eb6eeb8Sdrh  }
561eb6eeb8Sdrh  return $res
5791d3a61fSdan}
5891d3a61fSdan
591eb6eeb8Sdrh# Verify that when t1 is in the outer loop and t2 is in the inner loop,
601eb6eeb8Sdrh# no cursor hints occur for t1 (since it is a full table scan) but that
611eb6eeb8Sdrh# each t2 access has a cursor hint based on the current t1.a value.
621eb6eeb8Sdrh#
631eb6eeb8Sdrhdo_test 1.1 {
641eb6eeb8Sdrh  p4_of_opcode db CursorHint {
651eb6eeb8Sdrh     SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
6691d3a61fSdan  }
67a67a3162Sdrh} {{EQ(r[1],c0)}}
681eb6eeb8Sdrhdo_test 1.2 {
697f10579aSdrh  p5_of_opcode db OpenRead {
701eb6eeb8Sdrh     SELECT * FROM t1 CROSS JOIN t2 WHERE a=x
7191d3a61fSdan  }
72*a796de83Sdan} {0 0}
7391d3a61fSdan
741eb6eeb8Sdrh# Do the same test the other way around.
751eb6eeb8Sdrh#
761eb6eeb8Sdrhdo_test 2.1 {
771eb6eeb8Sdrh  p4_of_opcode db CursorHint {
781eb6eeb8Sdrh     SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
7991d3a61fSdan  }
80a67a3162Sdrh} {{EQ(c0,r[1])}}
811eb6eeb8Sdrhdo_test 2.2 {
827f10579aSdrh  p5_of_opcode db OpenRead {
831eb6eeb8Sdrh     SELECT * FROM t2 CROSS JOIN t1 WHERE a=x
841eb6eeb8Sdrh  }
85*a796de83Sdan} {0 0}
8691d3a61fSdan
871eb6eeb8Sdrh# Various expressions captured by CursorHint
881eb6eeb8Sdrh#
891eb6eeb8Sdrhdo_test 3.1 {
901eb6eeb8Sdrh  p4_of_opcode db CursorHint {
911eb6eeb8Sdrh    SELECT * FROM t1 WHERE a=15 AND c=22 AND rowid!=98
9291d3a61fSdan  }
93a67a3162Sdrh} {AND(AND(EQ(c0,15),EQ(c2,22)),NE(rowid,98))}
941eb6eeb8Sdrhdo_test 3.2 {
951eb6eeb8Sdrh  p4_of_opcode db CursorHint {
961eb6eeb8Sdrh    SELECT * FROM t3 WHERE a<15 AND b>22 AND id!=98
971eb6eeb8Sdrh  }
98a67a3162Sdrh} {AND(AND(LT(c1,15),GT(c2,22)),NE(c0,98))}
991eb6eeb8Sdrh
1001eb6eeb8Sdrh# Indexed queries
1011eb6eeb8Sdrh#
102b413a546Sdrhdo_test 4.1asc {
1031eb6eeb8Sdrh  db eval {
1041eb6eeb8Sdrh    CREATE INDEX t1bc ON t1(b,c);
1051eb6eeb8Sdrh    CREATE INDEX t2yz ON t2(y,z);
1061eb6eeb8Sdrh  }
1071eb6eeb8Sdrh  p4_of_opcode db CursorHint {
108b413a546Sdrh    SELECT * FROM t1 WHERE b>11 ORDER BY b ASC;
109b413a546Sdrh  }
110b413a546Sdrh} {}
111b413a546Sdrhdo_test 4.1desc {
112b413a546Sdrh  p4_of_opcode db CursorHint {
113b413a546Sdrh    SELECT * FROM t1 WHERE b>11 ORDER BY b DESC;
1141eb6eeb8Sdrh  }
115a67a3162Sdrh} {GT(c0,11)}
1161eb6eeb8Sdrhdo_test 4.2 {
1177f10579aSdrh  p5_of_opcode db OpenRead {
1181eb6eeb8Sdrh    SELECT * FROM t1 WHERE b>11;
1191eb6eeb8Sdrh  }
120*a796de83Sdan} {2 0}
121b413a546Sdrhdo_test 4.3asc {
1221eb6eeb8Sdrh  p4_of_opcode db CursorHint {
123b413a546Sdrh    SELECT c FROM t1 WHERE b<11 ORDER BY b ASC;
1241eb6eeb8Sdrh  }
125b413a546Sdrh} {LT(c0,11)}
126b413a546Sdrhdo_test 4.3desc {
127b413a546Sdrh  p4_of_opcode db CursorHint {
128b413a546Sdrh    SELECT c FROM t1 WHERE b<11 ORDER BY b DESC;
129b413a546Sdrh  }
130b413a546Sdrh} {}
1311eb6eeb8Sdrhdo_test 4.4 {
1327f10579aSdrh  p5_of_opcode db OpenRead {
133b413a546Sdrh    SELECT c FROM t1 WHERE b<11;
1341eb6eeb8Sdrh  }
135*a796de83Sdan} {0}
13691d3a61fSdan
137b413a546Sdrhdo_test 4.5asc {
138b413a546Sdrh  p4_of_opcode db CursorHint {
139b413a546Sdrh    SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b ASC;
140b413a546Sdrh  }
141b413a546Sdrh} {LE(c0,20)}
142b413a546Sdrhdo_test 4.5desc {
143b413a546Sdrh  p4_of_opcode db CursorHint {
144b413a546Sdrh    SELECT c FROM t1 WHERE b>=10 AND b<=20 ORDER BY b DESC;
145b413a546Sdrh  }
146b413a546Sdrh} {GE(c0,10)}
147bcf40a7fSdrh
148bcf40a7fSdrh# If there are any equality terms used in the constraint, then all terms
149bcf40a7fSdrh# should be hinted.
150bcf40a7fSdrh#
151b413a546Sdrhdo_test 4.6asc {
152b413a546Sdrh  p4_of_opcode db CursorHint {
153b413a546Sdrh    SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c ASC;
154b413a546Sdrh  }
155bcf40a7fSdrh} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
156b413a546Sdrhdo_test 4.6desc {
157b413a546Sdrh  p4_of_opcode db CursorHint {
158b413a546Sdrh    SELECT rowid FROM t1 WHERE b=22 AND c>=10 AND c<=20 ORDER BY b,c DESC;
159b413a546Sdrh  }
160bcf40a7fSdrh} {AND(AND(EQ(c0,22),GE(c1,10)),LE(c1,20))}
16191d3a61fSdan
16291d3a61fSdanfinish_test
163