1# 2021 February 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. The 12# focus of this file is testing optimizations associated with "IS NULL" 13# and "IS NOT NULL" operators on columns with NOT NULL constraints. 14# 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18set testprefix notnull2 19 20do_execsql_test 1.0 { 21 CREATE TABLE t1(a, b); 22 CREATE TABLE t2(c, d NOT NULL); 23 24 WITH x(i) AS ( 25 SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 26 ) 27 INSERT INTO t1 SELECT i, i FROM x; 28 INSERT INTO t2 SELECT * FROM t1; 29} 30 31proc do_vmstep_test {tn sql nstep {res {}}} { 32 uplevel [list do_execsql_test $tn.0 $sql $res] 33 34 set vmstep [db status vmstep] 35 if {[string range $nstep 0 0]=="+"} { 36 set body "if {$vmstep<$nstep} { 37 error \"got $vmstep, expected more than [string range $nstep 1 end]\" 38 }" 39 } else { 40 set body "if {$vmstep>$nstep} { 41 error \"got $vmstep, expected less than $nstep\" 42 }" 43 } 44 45 # set name "$tn.vmstep=$vmstep,expect=$nstep" 46 set name "$tn.1" 47 uplevel [list do_test $name $body {}] 48} 49 50do_vmstep_test 1.1.1 { 51 SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND d IS NULL; 52} 100 {} 53do_vmstep_test 1.1.2 { 54 SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND c IS NULL; 55} +1000 {} 56 57do_vmstep_test 1.2.1 { 58 SELECT * FROM ( SELECT * FROM t2 ) WHERE d IS NULL 59} 100 {} 60do_vmstep_test 1.2.2 { 61 SELECT * FROM ( SELECT * FROM t2 ) WHERE c IS NULL 62} +1000 {} 63 64do_vmstep_test 1.3.1 { 65 SELECT * FROM t2 WHERE d IS NULL 66} 100 {} 67do_vmstep_test 1.3.2 { 68 SELECT * FROM t2 WHERE c IS NULL 69} +1000 {} 70 71do_vmstep_test 1.4.1 { 72 SELECT (d IS NOT NULL) FROM t2 WHERE 0==( d IS NOT NULL ) 73} 100 {} 74do_vmstep_test 1.4.2 { 75 SELECT * FROM t2 WHERE 0==( c IS NOT NULL ) 76} +1000 {} 77 78do_vmstep_test 1.5.1 { 79 SELECT count(*) FROM t2 WHERE EXISTS( 80 SELECT t2.d IS NULL FROM t1 WHERE t1.a=450 81 ) 82} 10000 {1000} 83do_vmstep_test 1.5.2 { 84 SELECT count(*) FROM t2 WHERE EXISTS( 85 SELECT t2.c IS NULL FROM t1 WHERE t1.a=450 86 ) 87} +100000 {1000} 88 89#------------------------------------------------------------------------- 90reset_db 91do_execsql_test 2.0 { 92 CREATE TABLE T1(a INTEGER PRIMARY KEY, b); 93 CREATE TABLE T3(k, v); 94} 95 96do_execsql_test 2.1 { 97 SELECT * FROM (SELECT a, b FROM t1) LEFT JOIN t3 ON a IS NULL; 98} 99 100 101 102#------------------------------------------------------------------------- 103reset_db 104do_execsql_test 3.0 { 105 CREATE TABLE t0(c0 PRIMARY KEY); 106 INSERT INTO t0(c0) VALUES (0); 107} 108do_execsql_test 3.1 { 109 SELECT * FROM t0 WHERE ((c0 NOT NULL) AND 1) OR (c0 == NULL); 110} {0} 111 112# 2021-07-22 https://sqlite.org/forum/forumpost/2078b7edd2 113# 114reset_db 115do_execsql_test 4.0 { 116 SELECT *, '/' 117 FROM ( 118 SELECT NULL val FROM (SELECT 1) 119 UNION ALL 120 SELECT 'missing' FROM (SELECT 1) 121 ) a 122 LEFT JOIN (SELECT 1) 123 ON a.val IS NULL; 124} {{} 1 / missing {} /} 125do_execsql_test 4.1 { 126 CREATE TABLE t1(a INT); 127 INSERT INTO t1(a) VALUES(1); 128 CREATE TABLE t2(b INT); 129 SELECT * FROM (SELECT 3 AS c FROM t1) AS t3 LEFT JOIN t2 ON c IS NULL; 130} {3 {}} 131 132finish_test 133