18ddf6862Sdan# 2021 February 15 28ddf6862Sdan# 38ddf6862Sdan# The author disclaims copyright to this source code. In place of 48ddf6862Sdan# a legal notice, here is a blessing: 58ddf6862Sdan# 68ddf6862Sdan# May you do good and not evil. 78ddf6862Sdan# May you find forgiveness for yourself and forgive others. 88ddf6862Sdan# May you share freely, never taking more than you give. 98ddf6862Sdan# 108ddf6862Sdan#*********************************************************************** 118ddf6862Sdan# This file implements regression tests for SQLite library. The 128ddf6862Sdan# focus of this file is testing optimizations associated with "IS NULL" 138ddf6862Sdan# and "IS NOT NULL" operators on columns with NOT NULL constraints. 148ddf6862Sdan# 158ddf6862Sdan 168ddf6862Sdanset testdir [file dirname $argv0] 178ddf6862Sdansource $testdir/tester.tcl 188ddf6862Sdanset testprefix notnull2 198ddf6862Sdan 208ddf6862Sdando_execsql_test 1.0 { 218ddf6862Sdan CREATE TABLE t1(a, b); 228ddf6862Sdan CREATE TABLE t2(c, d NOT NULL); 238ddf6862Sdan 248ddf6862Sdan WITH x(i) AS ( 258ddf6862Sdan SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000 268ddf6862Sdan ) 278ddf6862Sdan INSERT INTO t1 SELECT i, i FROM x; 288ddf6862Sdan INSERT INTO t2 SELECT * FROM t1; 298ddf6862Sdan} 308ddf6862Sdan 318ddf6862Sdanproc do_vmstep_test {tn sql nstep {res {}}} { 328ddf6862Sdan uplevel [list do_execsql_test $tn.0 $sql $res] 338ddf6862Sdan 348ddf6862Sdan set vmstep [db status vmstep] 358ddf6862Sdan if {[string range $nstep 0 0]=="+"} { 368ddf6862Sdan set body "if {$vmstep<$nstep} { 378ddf6862Sdan error \"got $vmstep, expected more than [string range $nstep 1 end]\" 388ddf6862Sdan }" 398ddf6862Sdan } else { 408ddf6862Sdan set body "if {$vmstep>$nstep} { 418ddf6862Sdan error \"got $vmstep, expected less than $nstep\" 428ddf6862Sdan }" 438ddf6862Sdan } 448ddf6862Sdan 458ddf6862Sdan # set name "$tn.vmstep=$vmstep,expect=$nstep" 468ddf6862Sdan set name "$tn.1" 478ddf6862Sdan uplevel [list do_test $name $body {}] 488ddf6862Sdan} 498ddf6862Sdan 508ddf6862Sdando_vmstep_test 1.1.1 { 518ddf6862Sdan SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND d IS NULL; 528ddf6862Sdan} 100 {} 538ddf6862Sdando_vmstep_test 1.1.2 { 548ddf6862Sdan SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND c IS NULL; 558ddf6862Sdan} +1000 {} 568ddf6862Sdan 578ddf6862Sdando_vmstep_test 1.2.1 { 588ddf6862Sdan SELECT * FROM ( SELECT * FROM t2 ) WHERE d IS NULL 598ddf6862Sdan} 100 {} 608ddf6862Sdando_vmstep_test 1.2.2 { 618ddf6862Sdan SELECT * FROM ( SELECT * FROM t2 ) WHERE c IS NULL 628ddf6862Sdan} +1000 {} 638ddf6862Sdan 648ddf6862Sdando_vmstep_test 1.3.1 { 658ddf6862Sdan SELECT * FROM t2 WHERE d IS NULL 668ddf6862Sdan} 100 {} 678ddf6862Sdando_vmstep_test 1.3.2 { 688ddf6862Sdan SELECT * FROM t2 WHERE c IS NULL 698ddf6862Sdan} +1000 {} 708ddf6862Sdan 718ddf6862Sdando_vmstep_test 1.4.1 { 728ddf6862Sdan SELECT (d IS NOT NULL) FROM t2 WHERE 0==( d IS NOT NULL ) 738ddf6862Sdan} 100 {} 748ddf6862Sdando_vmstep_test 1.4.2 { 758ddf6862Sdan SELECT * FROM t2 WHERE 0==( c IS NOT NULL ) 768ddf6862Sdan} +1000 {} 778ddf6862Sdan 788ddf6862Sdando_vmstep_test 1.5.1 { 798ddf6862Sdan SELECT count(*) FROM t2 WHERE EXISTS( 808ddf6862Sdan SELECT t2.d IS NULL FROM t1 WHERE t1.a=450 818ddf6862Sdan ) 828ddf6862Sdan} 10000 {1000} 838ddf6862Sdando_vmstep_test 1.5.2 { 848ddf6862Sdan SELECT count(*) FROM t2 WHERE EXISTS( 858ddf6862Sdan SELECT t2.c IS NULL FROM t1 WHERE t1.a=450 868ddf6862Sdan ) 878ddf6862Sdan} +100000 {1000} 888ddf6862Sdan 8915de3ce9Sdan#------------------------------------------------------------------------- 9015de3ce9Sdanreset_db 9115de3ce9Sdando_execsql_test 2.0 { 9215de3ce9Sdan CREATE TABLE T1(a INTEGER PRIMARY KEY, b); 9315de3ce9Sdan CREATE TABLE T3(k, v); 9415de3ce9Sdan} 9515de3ce9Sdan 9615de3ce9Sdando_execsql_test 2.1 { 9715de3ce9Sdan SELECT * FROM (SELECT a, b FROM t1) LEFT JOIN t3 ON a IS NULL; 9815de3ce9Sdan} 998ddf6862Sdan 100677e62aaSdan 101677e62aaSdan 102677e62aaSdan#------------------------------------------------------------------------- 103677e62aaSdanreset_db 104677e62aaSdando_execsql_test 3.0 { 105677e62aaSdan CREATE TABLE t0(c0 PRIMARY KEY); 106677e62aaSdan INSERT INTO t0(c0) VALUES (0); 107677e62aaSdan} 108677e62aaSdando_execsql_test 3.1 { 109677e62aaSdan SELECT * FROM t0 WHERE ((c0 NOT NULL) AND 1) OR (c0 == NULL); 110677e62aaSdan} {0} 111677e62aaSdan 112*348e002eSdrh# 2021-07-22 https://sqlite.org/forum/forumpost/2078b7edd2 113*348e002eSdrh# 114*348e002eSdrhreset_db 115*348e002eSdrhdo_execsql_test 4.0 { 116*348e002eSdrh SELECT *, '/' 117*348e002eSdrh FROM ( 118*348e002eSdrh SELECT NULL val FROM (SELECT 1) 119*348e002eSdrh UNION ALL 120*348e002eSdrh SELECT 'missing' FROM (SELECT 1) 121*348e002eSdrh ) a 122*348e002eSdrh LEFT JOIN (SELECT 1) 123*348e002eSdrh ON a.val IS NULL; 124*348e002eSdrh} {{} 1 / missing {} /} 125*348e002eSdrhdo_execsql_test 4.1 { 126*348e002eSdrh CREATE TABLE t1(a INT); 127*348e002eSdrh INSERT INTO t1(a) VALUES(1); 128*348e002eSdrh CREATE TABLE t2(b INT); 129*348e002eSdrh SELECT * FROM (SELECT 3 AS c FROM t1) AS t3 LEFT JOIN t2 ON c IS NULL; 130*348e002eSdrh} {3 {}} 131*348e002eSdrh 1328ddf6862Sdanfinish_test 133