summaryrefslogtreecommitdiffstats
path: root/test/notnull2.test
blob: 12fffe28ce32ce0f24c1bdf415104649ea1c735f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 2021 February 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing optimizations associated with "IS NULL"
# and "IS NOT NULL" operators on columns with NOT NULL constraints.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix notnull2

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(c, d NOT NULL);

  WITH x(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000
  )
  INSERT INTO t1 SELECT i, i FROM x;
  INSERT INTO t2 SELECT * FROM t1;
}

proc do_vmstep_test {tn sql nstep {res {}}} {
  uplevel [list do_execsql_test $tn.0 $sql $res]

  set vmstep [db status vmstep]
  if {[string range $nstep 0 0]=="+"} {
    set body "if {$vmstep<$nstep} {
      error \"got $vmstep, expected more than [string range $nstep 1 end]\"
    }"
  } else {
    set body "if {$vmstep>$nstep} {
      error \"got $vmstep, expected less than $nstep\"
    }"
  }

  # set name "$tn.vmstep=$vmstep,expect=$nstep"
  set name "$tn.1"
  uplevel [list do_test $name $body {}]
}

do_vmstep_test 1.1.1 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND d IS NULL;
} 100 {}
do_vmstep_test 1.1.2 {
  SELECT * FROM t1 LEFT JOIN t2 WHERE a=c AND c IS NULL;
} +1000 {}

do_vmstep_test 1.2.1 {
  SELECT * FROM ( SELECT * FROM t2 ) WHERE d IS NULL
} 100 {}
do_vmstep_test 1.2.2 {
  SELECT * FROM ( SELECT * FROM t2 ) WHERE c IS NULL
} +1000 {}

do_vmstep_test 1.3.1 {
  SELECT * FROM t2 WHERE d IS NULL
} 100 {}
do_vmstep_test 1.3.2 {
  SELECT * FROM t2 WHERE c IS NULL
} +1000 {}

do_vmstep_test 1.4.1 {
  SELECT (d IS NOT NULL) FROM t2 WHERE 0==( d IS NOT NULL )
} 100 {}
do_vmstep_test 1.4.2 {
  SELECT * FROM t2 WHERE 0==( c IS NOT NULL )
} +1000 {}

do_vmstep_test 1.5.1 {
  SELECT count(*) FROM t2 WHERE EXISTS(
    SELECT t2.d IS NULL FROM t1 WHERE t1.a=450
  )
} 10000 {1000}
do_vmstep_test 1.5.2 {
  SELECT count(*) FROM t2 WHERE EXISTS(
    SELECT t2.c IS NULL FROM t1 WHERE t1.a=450
  )
} +100000 {1000}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 2.0 {
  CREATE TABLE T1(a INTEGER PRIMARY KEY, b);
  CREATE TABLE T3(k, v);
}

do_execsql_test 2.1 {
  SELECT * FROM (SELECT a, b FROM t1) LEFT JOIN t3 ON a IS NULL;
}



#-------------------------------------------------------------------------
reset_db
do_execsql_test 3.0 {
  CREATE TABLE t0(c0 PRIMARY KEY);
  INSERT INTO t0(c0) VALUES (0);
}
do_execsql_test 3.1 {
  SELECT * FROM t0 WHERE ((c0 NOT NULL) AND 1) OR (c0 == NULL);
} {0}

# 2021-07-22 https://sqlite.org/forum/forumpost/2078b7edd2
#
reset_db
do_execsql_test 4.0 {
  SELECT *, '/'
  FROM (
      SELECT NULL val FROM (SELECT 1)
      UNION ALL
      SELECT 'missing' FROM (SELECT 1)
  ) a
  LEFT JOIN (SELECT 1)
      ON a.val IS NULL;
} {{} 1 / missing {} /}
do_execsql_test 4.1 {
  CREATE TABLE t1(a INT);
  INSERT INTO t1(a) VALUES(1);
  CREATE TABLE t2(b INT);
  SELECT * FROM (SELECT 3 AS c FROM t1) AS t3 LEFT JOIN t2 ON c IS NULL;
} {3 {}}

finish_test