1b324cf75Sdan# 2016 June 17 2b324cf75Sdan# 3b324cf75Sdan# The author disclaims copyright to this source code. In place of 4b324cf75Sdan# a legal notice, here is a blessing: 5b324cf75Sdan# 6b324cf75Sdan# May you do good and not evil. 7b324cf75Sdan# May you find forgiveness for yourself and forgive others. 8b324cf75Sdan# May you share freely, never taking more than you give. 9b324cf75Sdan# 10b324cf75Sdan#*********************************************************************** 11b324cf75Sdan# This file implements regression tests for SQLite library. The 12b324cf75Sdan# focus is on testing that cursor-hints are correct for queries 13b324cf75Sdan# involving LEFT JOIN. 14b324cf75Sdan# 15b324cf75Sdan 16b324cf75Sdan 17b324cf75Sdanset testdir [file dirname $argv0] 18b324cf75Sdansource $testdir/tester.tcl 19b324cf75Sdanset ::testprefix cursorhint2 20b324cf75Sdan 21b324cf75Sdanifcapable !cursorhints { 22b324cf75Sdan finish_test 23b324cf75Sdan return 24b324cf75Sdan} 25b324cf75Sdan 26b324cf75Sdanproc extract_hints {sql} { 27b324cf75Sdan 28b324cf75Sdan db eval "SELECT tbl_name, rootpage FROM sqlite_master where rootpage" { 29b324cf75Sdan set lookup($rootpage) $tbl_name 30b324cf75Sdan } 31b324cf75Sdan 32b324cf75Sdan set ret [list] 33b324cf75Sdan db eval "EXPLAIN $sql" a { 34b324cf75Sdan switch -- $a(opcode) { 35b324cf75Sdan OpenRead { 36b324cf75Sdan set csr($a(p1)) $lookup($a(p2)) 37b324cf75Sdan } 38b324cf75Sdan CursorHint { 39b324cf75Sdan lappend ret $csr($a(p1)) $a(p4) 40b324cf75Sdan } 41b324cf75Sdan } 42b324cf75Sdan } 43b324cf75Sdan 44b324cf75Sdan set ret 45b324cf75Sdan} 46b324cf75Sdan 47b324cf75Sdanproc do_extract_hints_test {tn sql ret} { 48b324cf75Sdan uplevel [list do_test $tn [list extract_hints $sql] [list {*}$ret]] 49b324cf75Sdan} 50b324cf75Sdan 51b324cf75Sdando_execsql_test 1.0 { 52b324cf75Sdan PRAGMA automatic_index = 0; 53b324cf75Sdan CREATE TABLE t1(a, b); 54b324cf75Sdan CREATE TABLE t2(c, d); 55b324cf75Sdan CREATE TABLE t3(e, f); 56b324cf75Sdan} 57b324cf75Sdan 58419b03c1Sdando_extract_hints_test 1.1 { 59b324cf75Sdan SELECT * FROM t1 WHERE a=1; 60b324cf75Sdan} { 61b324cf75Sdan t1 EQ(c0,1) 62b324cf75Sdan} 63b324cf75Sdan 64419b03c1Sdando_extract_hints_test 1.2 { 65b324cf75Sdan SELECT * FROM t1 CROSS JOIN t2 ON (a=c) WHERE d IS NULL; 66b324cf75Sdan} { 67b324cf75Sdan t2 {AND(ISNULL(c1),EQ(r[1],c0))} 68b324cf75Sdan} 69b324cf75Sdan 70419b03c1Sdando_extract_hints_test 1.3 { 71b324cf75Sdan SELECT * FROM t1 LEFT JOIN t2 ON (a=c) WHERE d IS NULL; 72b324cf75Sdan} { 73b324cf75Sdan t2 {EQ(r[2],c0)} 74b324cf75Sdan} 75b324cf75Sdan 76419b03c1Sdando_extract_hints_test 1.4 { 77b324cf75Sdan SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; 78b324cf75Sdan} { 79b324cf75Sdan t2 {AND(EQ(r[2],c0),EQ(r[3],10))} 80b324cf75Sdan} 81b324cf75Sdan 82419b03c1Sdando_extract_hints_test 1.5 { 83b324cf75Sdan SELECT * FROM t1 CROSS JOIN t2 ON (a=c AND a=10) WHERE d IS NULL; 84b324cf75Sdan} { 85b324cf75Sdan t1 EQ(c0,10) t2 {AND(ISNULL(c1),EQ(r[3],c0))} 86b324cf75Sdan} 87b324cf75Sdan 88419b03c1Sdando_extract_hints_test 1.6 { 89b324cf75Sdan SELECT * FROM t1 LEFT JOIN t2 ON (a=c) LEFT JOIN t3 ON (d=f); 90b324cf75Sdan} { 91b324cf75Sdan t2 {EQ(r[2],c0)} t3 {EQ(r[6],c1)} 92b324cf75Sdan} 93b324cf75Sdan 9424be5493Sdrhif 0 { 95c4974414Sdan do_extract_hints_test 1.7 { 96b324cf75Sdan SELECT * FROM t1 LEFT JOIN t2 ON (a=c AND d=e) LEFT JOIN t3 ON (d=f); 97b324cf75Sdan } { 98e6912fd8Sdan t2 {EQ(r[2],c0)} t3 {AND(EQ(r[6],c0),EQ(r[7],c1))} 99e6912fd8Sdan } 10024be5493Sdrh} 101e6912fd8Sdan 102e6912fd8Sdan#------------------------------------------------------------------------- 103e6912fd8Sdan# 104e6912fd8Sdando_execsql_test 2.0 { 105e6912fd8Sdan CREATE TABLE x1(x, y); 106e6912fd8Sdan CREATE TABLE x2(a, b); 107e6912fd8Sdan} 108e6912fd8Sdan 109e6912fd8Sdando_extract_hints_test 2.1 { 110e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NULL; 111e6912fd8Sdan} { 112e6912fd8Sdan x2 {EQ(c0,r[2])} 113e6912fd8Sdan} 114e6912fd8Sdan 115e6912fd8Sdando_extract_hints_test 2.2 { 116e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS +NULL; 117e6912fd8Sdan} { 118e6912fd8Sdan x2 {EQ(c0,r[2])} 119e6912fd8Sdan} 120e6912fd8Sdan 121e6912fd8Sdando_extract_hints_test 2.3 { 122e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = (b IS NULL) 123e6912fd8Sdan} { 124e6912fd8Sdan x2 {EQ(c0,r[2])} 125e6912fd8Sdan} 126e6912fd8Sdan 127e6912fd8Sdando_extract_hints_test 2.4 { 128e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1) 129e6912fd8Sdan} { 130e6912fd8Sdan x2 {EQ(c0,r[2])} 131e6912fd8Sdan} 132e6912fd8Sdan 133e6912fd8Sdando_extract_hints_test 2.5 { 134e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1) 135e6912fd8Sdan} { 136e6912fd8Sdan x2 {EQ(c0,r[2])} 137e6912fd8Sdan} 138e6912fd8Sdan 139efce69deSdrhif {0} { 140efce69deSdrh # These tests no longer work due to the LEFT-JOIN strength reduction 141efce69deSdrh # optimization 142e6912fd8Sdan do_extract_hints_test 2.6 { 143efce69deSdrh SELECT * FROM x1 CROSS JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) 144e6912fd8Sdan } { 145e6912fd8Sdan x2 {EQ(c0,r[2])} 146e6912fd8Sdan } 147e6912fd8Sdan 148e6912fd8Sdan do_extract_hints_test 2.7 { 149e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) 150e6912fd8Sdan } { 151e6912fd8Sdan x2 {EQ(c0,r[2])} 152e6912fd8Sdan } 153e6912fd8Sdan 154e6912fd8Sdan do_extract_hints_test 2.8 { 155e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL 156e6912fd8Sdan } { 157e6912fd8Sdan x2 {EQ(c0,r[2])} 158e6912fd8Sdan } 159e6912fd8Sdan 160e6912fd8Sdan do_extract_hints_test 2.9 { 161efce69deSdrh SELECT * FROM x1 LEFT JOIN x2 ON (a=x) 162efce69deSdrh WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; 163e6912fd8Sdan } { 164e6912fd8Sdan x2 {EQ(c0,r[2])} 165e6912fd8Sdan } 166e6912fd8Sdan 167e6912fd8Sdan do_extract_hints_test 2.10 { 168e6912fd8Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 169e6912fd8Sdan } { 170e6912fd8Sdan x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} 171b324cf75Sdan } 172b324cf75Sdan 173b1c96334Sdrh ifcapable !icu { 174b1c96334Sdrh # This test only works using the built-in LIKE, not the ICU LIKE extension. 1752b693d63Sdan do_extract_hints_test 2.11 { 1762b693d63Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' 1772b693d63Sdan } { 1782b693d63Sdan x2 {AND(expr,EQ(c0,r[2]))} 1792b693d63Sdan } 180b1c96334Sdrh } 181efce69deSdrh} 1822b693d63Sdan 183b1c96334Sdrhdo_extract_hints_test 2.12 { 1842b693d63Sdan SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1) 1852b693d63Sdan} { 1862b693d63Sdan x2 {EQ(c0,r[2])} 1872b693d63Sdan} 1882b693d63Sdan 189*e3e79213Sdanreset_db 190*e3e79213Sdando_execsql_test 3.0 { 191*e3e79213Sdan CREATE TABLE t1 (i1 TEXT); 192*e3e79213Sdan CREATE TABLE t2 (i2 TEXT UNIQUE); 193*e3e79213Sdan INSERT INTO t1 VALUES('0'); 194*e3e79213Sdan INSERT INTO t2 VALUES('0'); 195*e3e79213Sdan} 196*e3e79213Sdan 197*e3e79213Sdando_extract_hints_test 3.1 { 198*e3e79213Sdan SELECT * FROM t1 CROSS JOIN t2 WHERE (t1.i1 = t2.i2) AND t2.i2 = 1; 199*e3e79213Sdan} { 200*e3e79213Sdan t1 {EQ(c0,r[1])} t2 EQ(c0,1) 201*e3e79213Sdan} 202*e3e79213Sdan 203*e3e79213Sdan 204b324cf75Sdanfinish_test 205