1# 2001 September 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 the DELETE FROM statement. 13# 14# $Id: delete.test,v 1.15 2004/06/10 05:59:25 danielk1977 Exp $ 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18 19# Try to delete from a non-existant table. 20# 21do_test delete-1.1 { 22 set v [catch {execsql {DELETE FROM test1}} msg] 23 lappend v $msg 24} {1 {no such table: test1}} 25 26# Try to delete from sqlite_master 27# 28do_test delete-2.1 { 29 set v [catch {execsql {DELETE FROM sqlite_master}} msg] 30 lappend v $msg 31} {1 {table sqlite_master may not be modified}} 32 33# Delete selected entries from a table with and without an index. 34# 35do_test delete-3.1.1 { 36 execsql {CREATE TABLE table1(f1 int, f2 int)} 37 execsql {INSERT INTO table1 VALUES(1,2)} 38 execsql {INSERT INTO table1 VALUES(2,4)} 39 execsql {INSERT INTO table1 VALUES(3,8)} 40 execsql {INSERT INTO table1 VALUES(4,16)} 41 execsql {SELECT * FROM table1 ORDER BY f1} 42} {1 2 2 4 3 8 4 16} 43do_test delete-3.1.2 { 44 execsql {DELETE FROM table1 WHERE f1=3} 45} {} 46do_test delete-3.1.3 { 47 execsql {SELECT * FROM table1 ORDER BY f1} 48} {1 2 2 4 4 16} 49do_test delete-3.1.4 { 50 execsql {CREATE INDEX index1 ON table1(f1)} 51 execsql {PRAGMA count_changes=on} 52 execsql {DELETE FROM 'table1' WHERE f1=3} 53} {0} 54do_test delete-3.1.5 { 55 execsql {SELECT * FROM table1 ORDER BY f1} 56} {1 2 2 4 4 16} 57do_test delete-3.1.6 { 58 execsql {DELETE FROM table1 WHERE f1=2} 59} {1} 60do_test delete-3.1.7 { 61 execsql {SELECT * FROM table1 ORDER BY f1} 62} {1 2 4 16} 63integrity_check delete-3.2 64 65 66# Semantic errors in the WHERE clause 67# 68do_test delete-4.1 { 69 execsql {CREATE TABLE table2(f1 int, f2 int)} 70 set v [catch {execsql {DELETE FROM table2 WHERE f3=5}} msg] 71 lappend v $msg 72} {1 {no such column: f3}} 73 74do_test delete-4.2 { 75 set v [catch {execsql {DELETE FROM table2 WHERE xyzzy(f1+4)}} msg] 76 lappend v $msg 77} {1 {no such function: xyzzy}} 78integrity_check delete-4.3 79 80# Lots of deletes 81# 82do_test delete-5.1.1 { 83 execsql {DELETE FROM table1} 84} {2} 85do_test delete-5.1.2 { 86 execsql {SELECT count(*) FROM table1} 87} {0} 88do_test delete-5.2.1 { 89 execsql {BEGIN TRANSACTION} 90 for {set i 1} {$i<=200} {incr i} { 91 execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])" 92 } 93 execsql {COMMIT} 94 execsql {SELECT count(*) FROM table1} 95} {200} 96do_test delete-5.2.2 { 97 execsql {DELETE FROM table1} 98} {200} 99do_test delete-5.2.3 { 100 execsql {BEGIN TRANSACTION} 101 for {set i 1} {$i<=200} {incr i} { 102 execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])" 103 } 104 execsql {COMMIT} 105 execsql {SELECT count(*) FROM table1} 106} {200} 107do_test delete-5.2.4 { 108 execsql {PRAGMA count_changes=off} 109 execsql {DELETE FROM table1} 110} {} 111do_test delete-5.2.5 { 112 execsql {SELECT count(*) FROM table1} 113} {0} 114do_test delete-5.2.6 { 115 execsql {BEGIN TRANSACTION} 116 for {set i 1} {$i<=200} {incr i} { 117 execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])" 118 } 119 execsql {COMMIT} 120 execsql {SELECT count(*) FROM table1} 121} {200} 122do_test delete-5.3 { 123 for {set i 1} {$i<=200} {incr i 4} { 124 execsql "DELETE FROM table1 WHERE f1==$i" 125 } 126 execsql {SELECT count(*) FROM table1} 127} {150} 128do_test delete-5.4 { 129 execsql "DELETE FROM table1 WHERE f1>50" 130 execsql {SELECT count(*) FROM table1} 131} {37} 132do_test delete-5.5 { 133 for {set i 1} {$i<=70} {incr i 3} { 134 execsql "DELETE FROM table1 WHERE f1==$i" 135 } 136 execsql {SELECT f1 FROM table1 ORDER BY f1} 137} {2 3 6 8 11 12 14 15 18 20 23 24 26 27 30 32 35 36 38 39 42 44 47 48 50} 138do_test delete-5.6 { 139 for {set i 1} {$i<40} {incr i} { 140 execsql "DELETE FROM table1 WHERE f1==$i" 141 } 142 execsql {SELECT f1 FROM table1 ORDER BY f1} 143} {42 44 47 48 50} 144do_test delete-5.7 { 145 execsql "DELETE FROM table1 WHERE f1!=48" 146 execsql {SELECT f1 FROM table1 ORDER BY f1} 147} {48} 148integrity_check delete-5.8 149 150 151# Delete large quantities of data. We want to test the List overflow 152# mechanism in the vdbe. 153# 154do_test delete-6.1 { 155 execsql {BEGIN; DELETE FROM table1} 156 for {set i 1} {$i<=3000} {incr i} { 157 execsql "INSERT INTO table1 VALUES($i,[expr {$i*$i}])" 158 } 159 execsql {DELETE FROM table2} 160 for {set i 1} {$i<=3000} {incr i} { 161 execsql "INSERT INTO table2 VALUES($i,[expr {$i*$i}])" 162 } 163 execsql {COMMIT} 164 execsql {SELECT count(*) FROM table1} 165} {3000} 166do_test delete-6.2 { 167 execsql {SELECT count(*) FROM table2} 168} {3000} 169do_test delete-6.3 { 170 execsql {SELECT f1 FROM table1 WHERE f1<10 ORDER BY f1} 171} {1 2 3 4 5 6 7 8 9} 172do_test delete-6.4 { 173 execsql {SELECT f1 FROM table2 WHERE f1<10 ORDER BY f1} 174} {1 2 3 4 5 6 7 8 9} 175do_test delete-6.5 { 176 execsql {DELETE FROM table1 WHERE f1>7} 177 execsql {SELECT f1 FROM table1 ORDER BY f1} 178} {1 2 3 4 5 6 7} 179do_test delete-6.6 { 180 execsql {DELETE FROM table2 WHERE f1>7} 181 execsql {SELECT f1 FROM table2 ORDER BY f1} 182} {1 2 3 4 5 6 7} 183do_test delete-6.7 { 184 execsql {DELETE FROM table1} 185 execsql {SELECT f1 FROM table1} 186} {} 187do_test delete-6.8 { 188 execsql {INSERT INTO table1 VALUES(2,3)} 189 execsql {SELECT f1 FROM table1} 190} {2} 191do_test delete-6.9 { 192 execsql {DELETE FROM table2} 193 execsql {SELECT f1 FROM table2} 194} {} 195do_test delete-6.10 { 196 execsql {INSERT INTO table2 VALUES(2,3)} 197 execsql {SELECT f1 FROM table2} 198} {2} 199integrity_check delete-6.11 200 201do_test delete-7.1 { 202 execsql { 203 CREATE TABLE t3(a); 204 INSERT INTO t3 VALUES(1); 205 INSERT INTO t3 SELECT a+1 FROM t3; 206 INSERT INTO t3 SELECT a+2 FROM t3; 207 SELECT * FROM t3; 208 } 209} {1 2 3 4} 210do_test delete-7.2 { 211 execsql { 212 CREATE TABLE cnt(del); 213 INSERT INTO cnt VALUES(0); 214 CREATE TRIGGER r1 AFTER DELETE ON t3 FOR EACH ROW BEGIN 215 UPDATE cnt SET del=del+1; 216 END; 217 DELETE FROM t3 WHERE a<2; 218 SELECT * FROM t3; 219 } 220} {2 3 4} 221do_test delete-7.3 { 222 execsql { 223 SELECT * FROM cnt; 224 } 225} {1} 226do_test delete-7.4 { 227 execsql { 228 DELETE FROM t3; 229 SELECT * FROM t3; 230 } 231} {} 232do_test delete-7.5 { 233 execsql { 234 SELECT * FROM cnt; 235 } 236} {4} 237do_test delete-7.6 { 238 execsql { 239 INSERT INTO t3 VALUES(1); 240 INSERT INTO t3 SELECT a+1 FROM t3; 241 INSERT INTO t3 SELECT a+2 FROM t3; 242 CREATE TABLE t4 AS SELECT * FROM t3; 243 PRAGMA count_changes=ON; 244 DELETE FROM t3; 245 DELETE FROM t4; 246 } 247} {4 4} 248integrity_check delete-7.7 249 250# Make sure error messages are consistent when attempting to delete 251# from a read-only database. Ticket #304. 252# 253do_test delete-8.0 { 254 execsql { 255 PRAGMA count_changes=OFF; 256 INSERT INTO t3 VALUES(123); 257 SELECT * FROM t3; 258 } 259} {123} 260db close 261catch {file attributes test.db -permissions 0444} 262catch {file attributes test.db -readonly 1} 263sqlite db test.db 264do_test delete-8.1 { 265 catchsql { 266 DELETE FROM t3; 267 } 268} {1 {attempt to write a readonly database}} 269do_test delete-8.2 { 270 execsql {SELECT * FROM t3} 271} {123} 272do_test delete-8.3 { 273 catchsql { 274 DELETE FROM t3 WHERE 1; 275 } 276} {1 {attempt to write a readonly database}} 277do_test delete-8.4 { 278 execsql {SELECT * FROM t3} 279} {123} 280 281# Update for v3: In v2 the DELETE statement would succeed because no 282# database writes actually occur. Version 3 refuses to open a transaction 283# on a read-only file, so the statement fails. 284do_test delete-8.5 { 285 catchsql { 286 DELETE FROM t3 WHERE a<100; 287 } 288# v2 result: {0 {}} 289} {1 {attempt to write a readonly database}} 290do_test delete-8.6 { 291 execsql {SELECT * FROM t3} 292} {123} 293integrity_check delete-8.7 294 295finish_test 296