17687c83dSdan# 2011 April 9 27687c83dSdan# 37687c83dSdan# The author disclaims copyright to this source code. In place of 47687c83dSdan# a legal notice, here is a blessing: 57687c83dSdan# 67687c83dSdan# May you do good and not evil. 77687c83dSdan# May you find forgiveness for yourself and forgive others. 87687c83dSdan# May you share freely, never taking more than you give. 97687c83dSdan# 107687c83dSdan#*********************************************************************** 117687c83dSdan# This file implements regression tests for SQLite library. The 127687c83dSdan# focus of this file is testing the various schema modification statements 137687c83dSdan# that feature "IF EXISTS" or "IF NOT EXISTS" clauses. 147687c83dSdan# 157687c83dSdan 167687c83dSdanset testdir [file dirname $argv0] 177687c83dSdansource $testdir/tester.tcl 187687c83dSdansource $testdir/lock_common.tcl 197687c83dSdan 209020de6aSdan 219020de6aSdanforeach jm {rollback wal} { 22*05accd22Sdan if {![wal_is_capable] && $jm=="wal"} continue 239020de6aSdan 249020de6aSdan set testprefix exists-$jm 257687c83dSdan 2657966753Sdan # This block of tests is targeted at CREATE XXX IF NOT EXISTS statements. 2757966753Sdan # 287687c83dSdan do_multiclient_test tn { 297687c83dSdan 307687c83dSdan # TABLE objects. 317687c83dSdan # 3257966753Sdan do_test 1.$tn.1.1 { 339020de6aSdan if {$jm == "wal"} { sql2 { PRAGMA journal_mode = WAL } } 347687c83dSdan sql2 { CREATE TABLE t1(x) } 357687c83dSdan sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) } 367687c83dSdan sql2 { DROP TABLE t1 } 377687c83dSdan sql1 { CREATE TABLE IF NOT EXISTS t1(a, b) } 387687c83dSdan sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } 397687c83dSdan } {t1} 407687c83dSdan 4157966753Sdan do_test 1.$tn.1.2 { 427687c83dSdan sql2 { CREATE TABLE t2(x) } 437687c83dSdan sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } 447687c83dSdan sql2 { DROP TABLE t2 } 457687c83dSdan sql1 { CREATE TABLE IF NOT EXISTS t2 AS SELECT * FROM t1 } 467687c83dSdan sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } 477687c83dSdan } {t1 t2} 487687c83dSdan 497687c83dSdan 507687c83dSdan # INDEX objects. 517687c83dSdan # 5257966753Sdan do_test 1.$tn.2 { 537687c83dSdan sql2 { CREATE INDEX i1 ON t1(a) } 547687c83dSdan sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) } 557687c83dSdan sql2 { DROP INDEX i1 } 567687c83dSdan sql1 { CREATE INDEX IF NOT EXISTS i1 ON t1(a, b) } 577687c83dSdan sql2 { SELECT name FROM sqlite_master WHERE type = 'index' } 587687c83dSdan } {i1} 597687c83dSdan 607687c83dSdan # VIEW objects. 617687c83dSdan # 6257966753Sdan do_test 1.$tn.3 { 637687c83dSdan sql2 { CREATE VIEW v1 AS SELECT * FROM t1 } 647687c83dSdan sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 } 657687c83dSdan sql2 { DROP VIEW v1 } 667687c83dSdan sql1 { CREATE VIEW IF NOT EXISTS v1 AS SELECT * FROM t1 } 677687c83dSdan sql2 { SELECT name FROM sqlite_master WHERE type = 'view' } 687687c83dSdan } {v1} 697687c83dSdan 707687c83dSdan # TRIGGER objects. 717687c83dSdan # 727687c83dSdan do_test $tn.4 { 737687c83dSdan sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } 747687c83dSdan sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } 757687c83dSdan sql2 { DROP TRIGGER tr1 } 767687c83dSdan sql1 { CREATE TRIGGER IF NOT EXISTS tr1 AFTER INSERT ON t1 BEGIN SELECT 1; END } 777687c83dSdan sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' } 787687c83dSdan } {tr1} 7957966753Sdan } 807687c83dSdan 8157966753Sdan # This block of tests is targeted at DROP XXX IF EXISTS statements. 8257966753Sdan # 8357966753Sdan do_multiclient_test tn { 8457966753Sdan 8557966753Sdan # TABLE objects. 8657966753Sdan # 8757966753Sdan do_test 2.$tn.1 { 889020de6aSdan if {$jm == "wal"} { sql1 { PRAGMA journal_mode = WAL } } 8957966753Sdan sql1 { DROP TABLE IF EXISTS t1 } 9057966753Sdan sql2 { CREATE TABLE t1(x) } 9157966753Sdan sql1 { DROP TABLE IF EXISTS t1 } 9257966753Sdan sql2 { SELECT name FROM sqlite_master WHERE type = 'table' } 9357966753Sdan } {} 9457966753Sdan 9557966753Sdan # INDEX objects. 9657966753Sdan # 9757966753Sdan do_test 2.$tn.2 { 9857966753Sdan sql1 { CREATE TABLE t2(x) } 9957966753Sdan sql1 { DROP INDEX IF EXISTS i2 } 10057966753Sdan sql2 { CREATE INDEX i2 ON t2(x) } 10157966753Sdan sql1 { DROP INDEX IF EXISTS i2 } 10257966753Sdan sql2 { SELECT name FROM sqlite_master WHERE type = 'index' } 10357966753Sdan } {} 10457966753Sdan 10557966753Sdan # VIEW objects. 10657966753Sdan # 10757966753Sdan do_test 2.$tn.3 { 10857966753Sdan sql1 { DROP VIEW IF EXISTS v1 } 10957966753Sdan sql2 { CREATE VIEW v1 AS SELECT * FROM t2 } 11057966753Sdan sql1 { DROP VIEW IF EXISTS v1 } 11157966753Sdan sql2 { SELECT name FROM sqlite_master WHERE type = 'view' } 11257966753Sdan } {} 11357966753Sdan 11457966753Sdan # TRIGGER objects. 11557966753Sdan # 11657966753Sdan do_test 2.$tn.4 { 11757966753Sdan sql1 { DROP TRIGGER IF EXISTS tr1 } 11857966753Sdan sql2 { CREATE TRIGGER tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } 11957966753Sdan sql1 { DROP TRIGGER IF EXISTS tr1 } 12057966753Sdan sql2 { SELECT name FROM sqlite_master WHERE type = 'trigger' } 12157966753Sdan } {} 12257966753Sdan } 12357966753Sdan 12457966753Sdan # This block of tests is targeted at DROP XXX IF EXISTS statements with 12557966753Sdan # attached databases. 12657966753Sdan # 12757966753Sdan do_multiclient_test tn { 12857966753Sdan 12957966753Sdan forcedelete test.db2 13057966753Sdan do_test 3.$tn.0 { 13157966753Sdan sql1 { ATTACH 'test.db2' AS aux } 13257966753Sdan sql2 { ATTACH 'test.db2' AS aux } 13357966753Sdan } {} 13457966753Sdan 13557966753Sdan # TABLE objects. 13657966753Sdan # 13757966753Sdan do_test 3.$tn.1.1 { 13857966753Sdan sql1 { DROP TABLE IF EXISTS aux.t1 } 13957966753Sdan sql2 { CREATE TABLE aux.t1(x) } 14057966753Sdan sql1 { DROP TABLE IF EXISTS aux.t1 } 14157966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' } 14257966753Sdan } {} 14357966753Sdan do_test 3.$tn.1.2 { 14457966753Sdan sql1 { DROP TABLE IF EXISTS t1 } 14557966753Sdan sql2 { CREATE TABLE aux.t1(x) } 14657966753Sdan sql1 { DROP TABLE IF EXISTS t1 } 14757966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'table' } 14857966753Sdan } {} 14957966753Sdan 15057966753Sdan # INDEX objects. 15157966753Sdan # 15257966753Sdan do_test 3.$tn.2.1 { 15357966753Sdan sql1 { CREATE TABLE aux.t2(x) } 15457966753Sdan sql1 { DROP INDEX IF EXISTS aux.i2 } 15557966753Sdan sql2 { CREATE INDEX aux.i2 ON t2(x) } 15657966753Sdan sql1 { DROP INDEX IF EXISTS aux.i2 } 15757966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' } 15857966753Sdan } {} 15957966753Sdan do_test 3.$tn.2.2 { 16057966753Sdan sql1 { DROP INDEX IF EXISTS i2 } 16157966753Sdan sql2 { CREATE INDEX aux.i2 ON t2(x) } 16257966753Sdan sql1 { DROP INDEX IF EXISTS i2 } 163c431fd55Sdan sql2 { SELECT * FROM aux.sqlite_master WHERE type = 'index' } 16457966753Sdan } {} 16557966753Sdan 16657966753Sdan # VIEW objects. 16757966753Sdan # 16857966753Sdan do_test 3.$tn.3.1 { 16957966753Sdan sql1 { DROP VIEW IF EXISTS aux.v1 } 17057966753Sdan sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 } 17157966753Sdan sql1 { DROP VIEW IF EXISTS aux.v1 } 17257966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' } 17357966753Sdan } {} 17457966753Sdan do_test 3.$tn.3.2 { 17557966753Sdan sql1 { DROP VIEW IF EXISTS v1 } 17657966753Sdan sql2 { CREATE VIEW aux.v1 AS SELECT * FROM t2 } 17757966753Sdan sql1 { DROP VIEW IF EXISTS v1 } 17857966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'view' } 17957966753Sdan } {} 18057966753Sdan 18157966753Sdan # TRIGGER objects. 18257966753Sdan # 18357966753Sdan do_test 3.$tn.4.1 { 18457966753Sdan sql1 { DROP TRIGGER IF EXISTS aux.tr1 } 18557966753Sdan sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } 18657966753Sdan sql1 { DROP TRIGGER IF EXISTS aux.tr1 } 18757966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' } 18857966753Sdan } {} 18957966753Sdan do_test 3.$tn.4.2 { 19057966753Sdan sql1 { DROP TRIGGER IF EXISTS tr1 } 19157966753Sdan sql2 { CREATE TRIGGER aux.tr1 AFTER INSERT ON t2 BEGIN SELECT 1; END } 19257966753Sdan sql1 { DROP TRIGGER IF EXISTS tr1 } 19357966753Sdan sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'trigger' } 19457966753Sdan } {} 1957687c83dSdan } 1969020de6aSdan} 1977687c83dSdan 1987687c83dSdan 1997687c83dSdanfinish_test 200