| OLD | NEW |
| 1 # 2009 August 24 | 1 # 2009 August 24 |
| 2 # | 2 # |
| 3 # The author disclaims copyright to this source code. In place of | 3 # The author disclaims copyright to this source code. In place of |
| 4 # a legal notice', here is a blessing: | 4 # a legal notice', here is a blessing: |
| 5 # | 5 # |
| 6 # May you do good and not evil. | 6 # May you do good and not evil. |
| 7 # May you find forgiveness for yourself and forgive others. | 7 # May you find forgiveness for yourself and forgive others. |
| 8 # May you share freely, never taking more than you give. | 8 # May you share freely, never taking more than you give. |
| 9 # | 9 # |
| 10 #*********************************************************************** | 10 #*********************************************************************** |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c, d, e); | 150 CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c, d, e); |
| 151 CREATE INDEX t1cd ON t1(c,d); | 151 CREATE INDEX t1cd ON t1(c,d); |
| 152 CREATE TRIGGER t1r1 AFTER UPDATE ON t1 BEGIN UPDATE cnt SET n=n+1; END; | 152 CREATE TRIGGER t1r1 AFTER UPDATE ON t1 BEGIN UPDATE cnt SET n=n+1; END; |
| 153 INSERT INTO t1 VALUES(1,2,3,4,5); | 153 INSERT INTO t1 VALUES(1,2,3,4,5); |
| 154 INSERT INTO t1 VALUES(6,7,8,9,10); | 154 INSERT INTO t1 VALUES(6,7,8,9,10); |
| 155 INSERT INTO t1 VALUES(11,12,13,14,15); | 155 INSERT INTO t1 VALUES(11,12,13,14,15); |
| 156 } | 156 } |
| 157 } {} | 157 } {} |
| 158 do_test triggerC-1.15 { | 158 do_test triggerC-1.15 { |
| 159 catchsql { UPDATE OR ROLLBACK t1 SET a=100 } | 159 catchsql { UPDATE OR ROLLBACK t1 SET a=100 } |
| 160 } {1 {PRIMARY KEY must be unique}} | 160 } {1 {UNIQUE constraint failed: t1.a}} |
| 161 | 161 |
| 162 | 162 |
| 163 #------------------------------------------------------------------------- | 163 #------------------------------------------------------------------------- |
| 164 # This block of tests, triggerC-2.*, tests that recursive trigger | 164 # This block of tests, triggerC-2.*, tests that recursive trigger |
| 165 # programs (triggers that fire themselves) work. More specifically, | 165 # programs (triggers that fire themselves) work. More specifically, |
| 166 # this block focuses on recursive INSERT triggers. | 166 # this block focuses on recursive INSERT triggers. |
| 167 # | 167 # |
| 168 do_test triggerC-2.1.0 { | 168 do_test triggerC-2.1.0 { |
| 169 execsql { | 169 execsql { |
| 170 CREATE TABLE t2(a PRIMARY KEY); | 170 CREATE TABLE t2(a PRIMARY KEY); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 INSERT OR IGNORE INTO t2 VALUES(new.a); | 215 INSERT OR IGNORE INTO t2 VALUES(new.a); |
| 216 END; | 216 END; |
| 217 } {1 {too many levels of trigger recursion}} | 217 } {1 {too many levels of trigger recursion}} |
| 218 } { | 218 } { |
| 219 do_test triggerC-2.1.$n { | 219 do_test triggerC-2.1.$n { |
| 220 catchsql { DROP TRIGGER t2_trig } | 220 catchsql { DROP TRIGGER t2_trig } |
| 221 execsql { DELETE FROM t2 } | 221 execsql { DELETE FROM t2 } |
| 222 execsql $tdefn | 222 execsql $tdefn |
| 223 catchsql { | 223 catchsql { |
| 224 INSERT INTO t2 VALUES(10); | 224 INSERT INTO t2 VALUES(10); |
| 225 SELECT * FROM t2; | 225 SELECT * FROM t2 ORDER BY rowid; |
| 226 } | 226 } |
| 227 } $rc | 227 } $rc |
| 228 } | 228 } |
| 229 | 229 |
| 230 do_test triggerC-2.2 { | 230 do_test triggerC-2.2 { |
| 231 execsql { | 231 execsql " |
| 232 CREATE TABLE t22(x); | 232 CREATE TABLE t22(x); |
| 233 | 233 |
| 234 CREATE TRIGGER t22a AFTER INSERT ON t22 BEGIN | 234 CREATE TRIGGER t22a AFTER INSERT ON t22 BEGIN |
| 235 INSERT INTO t22 SELECT x + (SELECT max(x) FROM t22) FROM t22; | 235 INSERT INTO t22 SELECT x + (SELECT max(x) FROM t22) FROM t22; |
| 236 END; | 236 END; |
| 237 CREATE TRIGGER t22b BEFORE INSERT ON t22 BEGIN | 237 CREATE TRIGGER t22b BEFORE INSERT ON t22 BEGIN |
| 238 SELECT CASE WHEN (SELECT count(*) FROM t22) >= 100 | 238 SELECT CASE WHEN (SELECT count(*) FROM t22) >= [expr $SQLITE_MAX_TRIGGER_D
EPTH / 2] |
| 239 THEN RAISE(IGNORE) | 239 THEN RAISE(IGNORE) |
| 240 ELSE NULL END; | 240 ELSE NULL END; |
| 241 END; | 241 END; |
| 242 | 242 |
| 243 INSERT INTO t22 VALUES(1); | 243 INSERT INTO t22 VALUES(1); |
| 244 SELECT count(*) FROM t22; | 244 SELECT count(*) FROM t22; |
| 245 } | 245 " |
| 246 } {100} | 246 } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]] |
| 247 | 247 |
| 248 do_test triggerC-2.3 { | 248 do_test triggerC-2.3 { |
| 249 execsql { | 249 execsql " |
| 250 CREATE TABLE t23(x PRIMARY KEY); | 250 CREATE TABLE t23(x PRIMARY KEY); |
| 251 | 251 |
| 252 CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN | 252 CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN |
| 253 INSERT INTO t23 VALUES(new.x + 1); | 253 INSERT INTO t23 VALUES(new.x + 1); |
| 254 END; | 254 END; |
| 255 | 255 |
| 256 CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN | 256 CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN |
| 257 SELECT CASE WHEN new.x>500 | 257 SELECT CASE WHEN new.x>[expr $SQLITE_MAX_TRIGGER_DEPTH / 2] |
| 258 THEN RAISE(IGNORE) | 258 THEN RAISE(IGNORE) |
| 259 ELSE NULL END; | 259 ELSE NULL END; |
| 260 END; | 260 END; |
| 261 | 261 |
| 262 INSERT INTO t23 VALUES(1); | 262 INSERT INTO t23 VALUES(1); |
| 263 SELECT count(*) FROM t23; | 263 SELECT count(*) FROM t23; |
| 264 } | 264 " |
| 265 } {500} | 265 } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]] |
| 266 | 266 |
| 267 | 267 |
| 268 #----------------------------------------------------------------------- | 268 #----------------------------------------------------------------------- |
| 269 # This block of tests, triggerC-3.*, test that SQLite throws an exception | 269 # This block of tests, triggerC-3.*, test that SQLite throws an exception |
| 270 # when it detects excessive recursion. | 270 # when it detects excessive recursion. |
| 271 # | 271 # |
| 272 do_test triggerC-3.1.1 { | 272 do_test triggerC-3.1.1 { |
| 273 execsql { | 273 execsql { |
| 274 CREATE TABLE t3(a, b); | 274 CREATE TABLE t3(a, b); |
| 275 CREATE TRIGGER t3i AFTER INSERT ON t3 BEGIN | 275 CREATE TRIGGER t3i AFTER INSERT ON t3 BEGIN |
| 276 DELETE FROM t3 WHERE rowid = new.rowid; | 276 DELETE FROM t3 WHERE rowid = new.rowid; |
| 277 END; | 277 END; |
| 278 CREATE TRIGGER t3d AFTER DELETE ON t3 BEGIN | 278 CREATE TRIGGER t3d AFTER DELETE ON t3 BEGIN |
| 279 INSERT INTO t3 VALUES(old.a, old.b); | 279 INSERT INTO t3 VALUES(old.a, old.b); |
| 280 END; | 280 END; |
| 281 } | 281 } |
| 282 } {} | 282 } {} |
| 283 do_test triggerC-3.1.2 { | 283 do_test triggerC-3.1.2 { |
| 284 catchsql { INSERT INTO t3 VALUES(0,0) } | 284 catchsql { INSERT INTO t3 VALUES(0,0) } |
| 285 } {1 {too many levels of trigger recursion}} | 285 } {1 {too many levels of trigger recursion}} |
| 286 do_test triggerC-3.1.3 { | 286 do_test triggerC-3.1.3 { |
| 287 execsql { SELECT * FROM t3 } | 287 execsql { SELECT * FROM t3 } |
| 288 } {} | 288 } {} |
| 289 | 289 |
| 290 do_test triggerC-3.2.1 { | 290 do_test triggerC-3.2.1 { |
| 291 execsql { | 291 execsql " |
| 292 CREATE TABLE t3b(x); | 292 CREATE TABLE t3b(x); |
| 293 CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<2000 BEGIN | 293 CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<[expr $SQLITE_MAX_TRIGGER
_DEPTH * 2] BEGIN |
| 294 INSERT INTO t3b VALUES(new.x+1); | 294 INSERT INTO t3b VALUES(new.x+1); |
| 295 END; | 295 END; |
| 296 } | 296 " |
| 297 catchsql { | 297 catchsql { |
| 298 INSERT INTO t3b VALUES(1); | 298 INSERT INTO t3b VALUES(1); |
| 299 } | 299 } |
| 300 } {1 {too many levels of trigger recursion}} | 300 } {1 {too many levels of trigger recursion}} |
| 301 do_test triggerC-3.2.2 { | 301 do_test triggerC-3.2.2 { |
| 302 db eval {SELECT * FROM t3b} | 302 db eval {SELECT * FROM t3b} |
| 303 } {} | 303 } {} |
| 304 | 304 |
| 305 do_test triggerC-3.3.1 { | 305 do_test triggerC-3.3.1 { |
| 306 catchsql { | 306 catchsql " |
| 307 INSERT INTO t3b VALUES(1001); | 307 INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH + 1]); |
| 308 } | 308 " |
| 309 } {0 {}} | 309 } {0 {}} |
| 310 do_test triggerC-3.3.2 { | 310 do_test triggerC-3.3.2 { |
| 311 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 311 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 312 } {1000 2000 1001} | 312 } [list $SQLITE_MAX_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQ
LITE_MAX_TRIGGER_DEPTH + 1]] |
| 313 | 313 |
| 314 do_test triggerC-3.4.1 { | 314 do_test triggerC-3.4.1 { |
| 315 catchsql { | 315 catchsql " |
| 316 DELETE FROM t3b; | 316 DELETE FROM t3b; |
| 317 INSERT INTO t3b VALUES(999); | 317 INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH - 1]); |
| 318 } | 318 " |
| 319 } {1 {too many levels of trigger recursion}} | 319 } {1 {too many levels of trigger recursion}} |
| 320 do_test triggerC-3.4.2 { | 320 do_test triggerC-3.4.2 { |
| 321 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 321 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 322 } {0 {} {}} | 322 } {0 {} {}} |
| 323 | 323 |
| 324 do_test triggerC-3.5.1 { | 324 do_test triggerC-3.5.1 { |
| 325 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 100 | 325 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH /
10] |
| 326 catchsql { | 326 catchsql " |
| 327 INSERT INTO t3b VALUES(1901); | 327 INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_
TRIGGER_DEPTH / 10) + 1]); |
| 328 } | 328 " |
| 329 } {0 {}} | 329 } {0 {}} |
| 330 do_test triggerC-3.5.2 { | 330 do_test triggerC-3.5.2 { |
| 331 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 331 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 332 } {100 2000 1901} | 332 } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 10] [expr $SQLITE_MAX_TRIGGER_DEPTH *
2] [expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]
] |
| 333 | 333 |
| 334 do_test triggerC-3.5.3 { | 334 do_test triggerC-3.5.3 { |
| 335 catchsql { | 335 catchsql " |
| 336 DELETE FROM t3b; | 336 DELETE FROM t3b; |
| 337 INSERT INTO t3b VALUES(1900); | 337 INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_
TRIGGER_DEPTH / 10)]); |
| 338 } | 338 " |
| 339 } {1 {too many levels of trigger recursion}} | 339 } {1 {too many levels of trigger recursion}} |
| 340 do_test triggerC-3.5.4 { | 340 do_test triggerC-3.5.4 { |
| 341 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 341 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 342 } {0 {} {}} | 342 } {0 {} {}} |
| 343 | 343 |
| 344 do_test triggerC-3.6.1 { | 344 do_test triggerC-3.6.1 { |
| 345 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1 | 345 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1 |
| 346 catchsql { | 346 catchsql " |
| 347 INSERT INTO t3b VALUES(2000); | 347 INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH * 2]); |
| 348 } | 348 " |
| 349 } {0 {}} | 349 } {0 {}} |
| 350 do_test triggerC-3.6.2 { | 350 do_test triggerC-3.6.2 { |
| 351 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 351 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 352 } {1 2000 2000} | 352 } [list 1 [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQLITE_MAX_TRIGGER_DEPTH *
2]] |
| 353 | 353 |
| 354 do_test triggerC-3.6.3 { | 354 do_test triggerC-3.6.3 { |
| 355 catchsql { | 355 catchsql " |
| 356 DELETE FROM t3b; | 356 DELETE FROM t3b; |
| 357 INSERT INTO t3b VALUES(1999); | 357 INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - 1]); |
| 358 } | 358 " |
| 359 } {1 {too many levels of trigger recursion}} | 359 } {1 {too many levels of trigger recursion}} |
| 360 do_test triggerC-3.6.4 { | 360 do_test triggerC-3.6.4 { |
| 361 db eval {SELECT count(*), max(x), min(x) FROM t3b} | 361 db eval {SELECT count(*), max(x), min(x) FROM t3b} |
| 362 } {0 {} {}} | 362 } {0 {} {}} |
| 363 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000 | 363 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH $SQLITE_MAX_TRIGGER_DEPTH |
| 364 | 364 |
| 365 | 365 |
| 366 #----------------------------------------------------------------------- | 366 #----------------------------------------------------------------------- |
| 367 # This next block of tests, triggerC-4.*, checks that affinity | 367 # This next block of tests, triggerC-4.*, checks that affinity |
| 368 # transformations and constraint processing is performed at the correct | 368 # transformations and constraint processing is performed at the correct |
| 369 # times relative to BEFORE and AFTER triggers. | 369 # times relative to BEFORE and AFTER triggers. |
| 370 # | 370 # |
| 371 # For an INSERT statement, for each row to be inserted: | 371 # For an INSERT statement, for each row to be inserted: |
| 372 # | 372 # |
| 373 # 1. Apply affinities to non-rowid values to be inserted. | 373 # 1. Apply affinities to non-rowid values to be inserted. |
| 374 # 2. Fire BEFORE triggers. | 374 # 2. Fire BEFORE triggers. |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 2 integer 9 text 9 integer 9.0 real | 540 2 integer 9 text 9 integer 9.0 real |
| 541 2 integer 9.1 text 9.1 real 9.1 real | 541 2 integer 9.1 text 9.1 real 9.1 real |
| 542 2 integer 9 text 9 integer 9.0 real | 542 2 integer 9 text 9 integer 9.0 real |
| 543 2 integer 9.1 text 9.1 real 9.1 real | 543 2 integer 9.1 text 9.1 real 9.1 real |
| 544 } | 544 } |
| 545 } { | 545 } { |
| 546 do_test triggerC-4.1.$n { | 546 do_test triggerC-4.1.$n { |
| 547 eval concat [execsql " | 547 eval concat [execsql " |
| 548 DELETE FROM log; | 548 DELETE FROM log; |
| 549 $insert ; | 549 $insert ; |
| 550 SELECT * FROM log; | 550 SELECT * FROM log ORDER BY rowid; |
| 551 "] | 551 "] |
| 552 } [join $log " "] | 552 } [join $log " "] |
| 553 } | 553 } |
| 554 | 554 |
| 555 #------------------------------------------------------------------------- | 555 #------------------------------------------------------------------------- |
| 556 # This block of tests, triggerC-5.*, test that DELETE triggers are fired | 556 # This block of tests, triggerC-5.*, test that DELETE triggers are fired |
| 557 # if a row is deleted as a result of OR REPLACE conflict resolution. | 557 # if a row is deleted as a result of OR REPLACE conflict resolution. |
| 558 # | 558 # |
| 559 do_test triggerC-5.1.0 { | 559 do_test triggerC-5.1.0 { |
| 560 execsql { | 560 execsql { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 577 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {2 b 3} {1 a 2 c} | 577 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {2 b 3} {1 a 2 c} |
| 578 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {2 b 3} {1 a 3 c 4 b} | 578 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {2 b 3} {1 a 3 c 4 b} |
| 579 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {2 b 3} {1 a 3 b} | 579 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {2 b 3} {1 a 3 b} |
| 580 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {2 b 3 3 c 2} {1 a 2 c} | 580 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {2 b 3 3 c 2} {1 a 2 c} |
| 581 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 3 2 b 2} {1 b} | 581 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 3 2 b 2} {1 b} |
| 582 } { | 582 } { |
| 583 do_test triggerC-5.1.$n { | 583 do_test triggerC-5.1.$n { |
| 584 execsql " | 584 execsql " |
| 585 BEGIN; | 585 BEGIN; |
| 586 $dml ; | 586 $dml ; |
| 587 SELECT * FROM t5g; | 587 SELECT * FROM t5g ORDER BY rowid; |
| 588 SELECT * FROM t5; | 588 SELECT * FROM t5 ORDER BY rowid; |
| 589 ROLLBACK; | 589 ROLLBACK; |
| 590 " | 590 " |
| 591 } [concat $t5g $t5] | 591 } [concat $t5g $t5] |
| 592 } | 592 } |
| 593 do_test triggerC-5.2.0 { | 593 do_test triggerC-5.2.0 { |
| 594 execsql { | 594 execsql { |
| 595 DROP TRIGGER t5t; | 595 DROP TRIGGER t5t; |
| 596 CREATE TRIGGER t5t AFTER DELETE ON t5 BEGIN | 596 CREATE TRIGGER t5t AFTER DELETE ON t5 BEGIN |
| 597 INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5)); | 597 INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5)); |
| 598 END; | 598 END; |
| 599 } | 599 } |
| 600 } {} | 600 } {} |
| 601 foreach {n dml t5g t5} { | 601 foreach {n dml t5g t5} { |
| 602 1 "DELETE FROM t5 WHERE a=2" {2 b 2} {1 a 3 c} | 602 1 "DELETE FROM t5 WHERE a=2" {2 b 2} {1 a 3 c} |
| 603 2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')" {2 b 2} {1 a 2 d 3 c} | 603 2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')" {2 b 2} {1 a 2 d 3 c} |
| 604 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {2 b 2} {1 a 2 c} | 604 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {2 b 2} {1 a 2 c} |
| 605 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {2 b 2} {1 a 3 c 4 b} | 605 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {2 b 2} {1 a 3 c 4 b} |
| 606 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {2 b 2} {1 a 3 b} | 606 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {2 b 2} {1 a 3 b} |
| 607 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {2 b 2 3 c 1} {1 a 2 c} | 607 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {2 b 2 3 c 1} {1 a 2 c} |
| 608 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 2 2 b 1} {1 b} | 608 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 2 2 b 1} {1 b} |
| 609 } { | 609 } { |
| 610 do_test triggerC-5.2.$n { | 610 do_test triggerC-5.2.$n { |
| 611 execsql " | 611 execsql " |
| 612 BEGIN; | 612 BEGIN; |
| 613 $dml ; | 613 $dml ; |
| 614 SELECT * FROM t5g; | 614 SELECT * FROM t5g ORDER BY rowid; |
| 615 SELECT * FROM t5; | 615 SELECT * FROM t5 ORDER BY rowid; |
| 616 ROLLBACK; | 616 ROLLBACK; |
| 617 " | 617 " |
| 618 } [concat $t5g $t5] | 618 } [concat $t5g $t5] |
| 619 } | 619 } |
| 620 do_test triggerC-5.3.0 { | 620 do_test triggerC-5.3.0 { |
| 621 execsql { PRAGMA recursive_triggers = off } | 621 execsql { PRAGMA recursive_triggers = off } |
| 622 } {} | 622 } {} |
| 623 foreach {n dml t5g t5} { | 623 foreach {n dml t5g t5} { |
| 624 1 "DELETE FROM t5 WHERE a=2" {2 b 2} {1 a 3 c} | 624 1 "DELETE FROM t5 WHERE a=2" {2 b 2} {1 a 3 c} |
| 625 2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')" {} {1 a 2 d 3 c} | 625 2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')" {} {1 a 2 d 3 c} |
| 626 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {} {1 a 2 c} | 626 3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3" {} {1 a 2 c} |
| 627 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {} {1 a 3 c 4 b} | 627 4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')" {} {1 a 3 c 4 b} |
| 628 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {} {1 a 3 b} | 628 5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'" {} {1 a 3 b} |
| 629 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {} {1 a 2 c} | 629 6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')" {} {1 a 2 c} |
| 630 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {} {1 b} | 630 7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {} {1 b} |
| 631 } { | 631 } { |
| 632 do_test triggerC-5.3.$n { | 632 do_test triggerC-5.3.$n { |
| 633 execsql " | 633 execsql " |
| 634 BEGIN; | 634 BEGIN; |
| 635 $dml ; | 635 $dml ; |
| 636 SELECT * FROM t5g; | 636 SELECT * FROM t5g ORDER BY rowid; |
| 637 SELECT * FROM t5; | 637 SELECT * FROM t5 ORDER BY rowid; |
| 638 ROLLBACK; | 638 ROLLBACK; |
| 639 " | 639 " |
| 640 } [concat $t5g $t5] | 640 } [concat $t5g $t5] |
| 641 } | 641 } |
| 642 do_test triggerC-5.3.8 { | 642 do_test triggerC-5.3.8 { |
| 643 execsql { PRAGMA recursive_triggers = on } | 643 execsql { PRAGMA recursive_triggers = on } |
| 644 } {} | 644 } {} |
| 645 | 645 |
| 646 #------------------------------------------------------------------------- | 646 #------------------------------------------------------------------------- |
| 647 # This block of tests, triggerC-6.*, tests that "PRAGMA recursive_triggers" | 647 # This block of tests, triggerC-6.*, tests that "PRAGMA recursive_triggers" |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 CREATE TRIGGER tv2 INSTEAD OF INSERT ON v2 BEGIN | 911 CREATE TRIGGER tv2 INSTEAD OF INSERT ON v2 BEGIN |
| 912 INSERT INTO log VALUES(new.a, new.b); | 912 INSERT INTO log VALUES(new.a, new.b); |
| 913 END; | 913 END; |
| 914 INSERT INTO v2 DEFAULT VALUES; | 914 INSERT INTO v2 DEFAULT VALUES; |
| 915 SELECT a, b, a IS NULL, b IS NULL FROM log; | 915 SELECT a, b, a IS NULL, b IS NULL FROM log; |
| 916 } | 916 } |
| 917 } {{} {} 1 1} | 917 } {{} {} 1 1} |
| 918 | 918 |
| 919 do_test triggerC-12.1 { | 919 do_test triggerC-12.1 { |
| 920 db close | 920 db close |
| 921 file delete -force test.db | 921 forcedelete test.db |
| 922 sqlite3 db test.db | 922 sqlite3 db test.db |
| 923 | 923 |
| 924 execsql { | 924 execsql { |
| 925 CREATE TABLE t1(a, b); | 925 CREATE TABLE t1(a, b); |
| 926 INSERT INTO t1 VALUES(1, 2); | 926 INSERT INTO t1 VALUES(1, 2); |
| 927 INSERT INTO t1 VALUES(3, 4); | 927 INSERT INTO t1 VALUES(3, 4); |
| 928 INSERT INTO t1 VALUES(5, 6); | 928 INSERT INTO t1 VALUES(5, 6); |
| 929 CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1 ; END ; | 929 CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1 ; END ; |
| 930 SELECT count(*) FROM sqlite_master; | 930 SELECT count(*) FROM sqlite_master; |
| 931 } | 931 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 942 CREATE TABLE t12(a, b); | 942 CREATE TABLE t12(a, b); |
| 943 INSERT INTO t12 VALUES(1, 2); | 943 INSERT INTO t12 VALUES(1, 2); |
| 944 CREATE TRIGGER tr12 AFTER UPDATE ON t12 BEGIN | 944 CREATE TRIGGER tr12 AFTER UPDATE ON t12 BEGIN |
| 945 UPDATE t12 SET a=new.a+1, b=new.b+1; | 945 UPDATE t12 SET a=new.a+1, b=new.b+1; |
| 946 END; | 946 END; |
| 947 } {} | 947 } {} |
| 948 do_catchsql_test triggerC-13.2 { | 948 do_catchsql_test triggerC-13.2 { |
| 949 UPDATE t12 SET a=a+1, b=b+1; | 949 UPDATE t12 SET a=a+1, b=b+1; |
| 950 } {1 {too many levels of trigger recursion}} | 950 } {1 {too many levels of trigger recursion}} |
| 951 | 951 |
| 952 #------------------------------------------------------------------------- |
| 953 # The following tests seek to verify that constant values (i.e. literals) |
| 954 # are not factored out of loops within trigger programs. SQLite does |
| 955 # not factor constants out of loops within trigger programs as it may only |
| 956 # do so in code generated before the first table or index is opened. And |
| 957 # by the time a trigger program is coded, at least one table or index has |
| 958 # always been opened. |
| 959 # |
| 960 # At one point, due to a bug allowing constant factoring within triggers, |
| 961 # the following SQL would produce the wrong result. |
| 962 # |
| 963 set SQL { |
| 964 CREATE TABLE t1(a, b, c); |
| 965 CREATE INDEX i1 ON t1(a, c); |
| 966 CREATE INDEX i2 ON t1(b, c); |
| 967 INSERT INTO t1 VALUES(1, 2, 3); |
| 952 | 968 |
| 969 CREATE TABLE t2(e, f); |
| 970 CREATE INDEX i3 ON t2(e); |
| 971 INSERT INTO t2 VALUES(1234567, 3); |
| 972 |
| 973 CREATE TABLE empty(x); |
| 974 CREATE TABLE not_empty(x); |
| 975 INSERT INTO not_empty VALUES(2); |
| 976 |
| 977 CREATE TABLE t4(x); |
| 978 CREATE TABLE t5(g, h, i); |
| 979 |
| 980 CREATE TRIGGER trig BEFORE INSERT ON t4 BEGIN |
| 981 INSERT INTO t5 SELECT * FROM t1 WHERE |
| 982 (a IN (SELECT x FROM empty) OR b IN (SELECT x FROM not_empty)) |
| 983 AND c IN (SELECT f FROM t2 WHERE e=1234567); |
| 984 END; |
| 985 |
| 986 INSERT INTO t4 VALUES(0); |
| 987 SELECT * FROM t5; |
| 988 } |
| 989 |
| 990 reset_db |
| 991 do_execsql_test triggerC-14.1 $SQL {1 2 3} |
| 992 reset_db |
| 993 optimization_control db factor-constants 0 |
| 994 do_execsql_test triggerC-14.2 $SQL {1 2 3} |
| 953 | 995 |
| 954 finish_test | 996 finish_test |
| OLD | NEW |