3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the various schema modification statements
13 # that feature "IF EXISTS" or "IF NOT EXISTS" clauses.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
18 source $testdir/lock_common.tcl
21 foreach jm {rollback wal} {
22 if {![wal_is_capable] && $jm=="wal"} continue
24 set testprefix exists-$jm
26 # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements.
28 do_multiclient_test tn {
33 if {$jm == "wal"} { sql2 { PRAGMA journal_mode = WAL } }
34 sql2 { CREATE TABLE t1(x) }
35 sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
36 sql2 { DROP TABLE t1 }
37 sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) }
38 sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
42 sql2 { CREATE TABLE t2(x) }
43 sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
44 sql2 { DROP TABLE t2 }
45 sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 }
46 sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
53 sql2 { CREATE INDEX i1 ON t1(a) }
54 sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
55 sql2 { DROP INDEX i1 }
56 sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) }
57 sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
63 sql2 { CREATE VIEW v1 AS SELECT * FROM t1 }
64 sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
66 sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 }
67 sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
73 sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
74 sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
75 sql2 { DROP TRIGGER tr1 }
76 sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END }
77 sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
81 # This block of tests is targeted at DROP XXX IF EXISTS statements.
83 do_multiclient_test tn {
88 if {$jm == "wal"} { sql1 { PRAGMA journal_mode = WAL } }
89 sql1 { DROP TABLE IF EXISTS t1 }
90 sql2 { CREATE TABLE t1(x) }
91 sql1 { DROP TABLE IF EXISTS t1 }
92 sql2 { SELECT name FROM sqlite_master WHERE type = 'table' }
98 sql1 { CREATE TABLE t2(x) }
99 sql1 { DROP INDEX IF EXISTS i2 }
100 sql2 { CREATE INDEX i2 ON t2(x) }
101 sql1 { DROP INDEX IF EXISTS i2 }
102 sql2 { SELECT name FROM sqlite_master WHERE type = 'index' }
108 sql1 { DROP VIEW IF EXISTS v1 }
109 sql2 { CREATE VIEW v1 AS SELECT * FROM t2 }
110 sql1 { DROP VIEW IF EXISTS v1 }
111 sql2 { SELECT name FROM sqlite_master WHERE type = 'view' }
117 sql1 { DROP TRIGGER IF EXISTS tr1 }
118 sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
119 sql1 { DROP TRIGGER IF EXISTS tr1 }
120 sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' }
124 # This block of tests is targeted at DROP XXX IF EXISTS statements with
125 # attached databases.
127 do_multiclient_test tn {
131 sql1 { ATTACH 'test.db2' AS aux }
132 sql2 { ATTACH 'test.db2' AS aux }
138 sql1 { DROP TABLE IF EXISTS aux.t1 }
139 sql2 { CREATE TABLE aux.t1(x) }
140 sql1 { DROP TABLE IF EXISTS aux.t1 }
141 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
144 sql1 { DROP TABLE IF EXISTS t1 }
145 sql2 { CREATE TABLE aux.t1(x) }
146 sql1 { DROP TABLE IF EXISTS t1 }
147 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' }
153 sql1 { CREATE TABLE aux.t2(x) }
154 sql1 { DROP INDEX IF EXISTS aux.i2 }
155 sql2 { CREATE INDEX aux.i2 ON t2(x) }
156 sql1 { DROP INDEX IF EXISTS aux.i2 }
157 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
160 sql1 { DROP INDEX IF EXISTS i2 }
161 sql2 { CREATE INDEX aux.i2 ON t2(x) }
162 sql1 { DROP INDEX IF EXISTS i2 }
163 sql2 { SELECT * FROM aux.sqlite_master WHERE type = 'index' }
169 sql1 { DROP VIEW IF EXISTS aux.v1 }
170 sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
171 sql1 { DROP VIEW IF EXISTS aux.v1 }
172 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
175 sql1 { DROP VIEW IF EXISTS v1 }
176 sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 }
177 sql1 { DROP VIEW IF EXISTS v1 }
178 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' }
184 sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
185 sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
186 sql1 { DROP TRIGGER IF EXISTS aux.tr1 }
187 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }
190 sql1 { DROP TRIGGER IF EXISTS tr1 }
191 sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END }
192 sql1 { DROP TRIGGER IF EXISTS tr1 }
193 sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' }