1# The author disclaims copyright to this source code. In place of 2# a legal notice, here is a blessing: 3# 4# May you do good and not evil. 5# May you find forgiveness for yourself and forgive others. 6# May you share freely, never taking more than you give. 7# 8#*********************************************************************** 9# 10# This file tests creating and dropping triggers, and interaction thereof 11# with the database COMMIT/ROLLBACK logic. 12# 13# 1. CREATE and DROP TRIGGER tests 14# trig-1.1: Error if table does not exist 15# trig-1.2: Error if trigger already exists 16# trig-1.3: Created triggers are deleted if the transaction is rolled back 17# trig-1.4: DROP TRIGGER removes trigger 18# trig-1.5: Dropped triggers are restored if the transaction is rolled back 19# trig-1.6: Error if dropped trigger doesn't exist 20# trig-1.7: Dropping the table automatically drops all triggers 21# trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master 22# trig-1.9: Ensure that we cannot create a trigger on sqlite_master 23# trig-1.10: 24# trig-1.11: 25# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables 26# trig-1.13: Ensure that AFTER triggers cannot be created on views 27# trig-1.14: Ensure that BEFORE triggers cannot be created on views 28# 29 30set testdir [file dirname $argv0] 31source $testdir/tester.tcl 32ifcapable !trigger||!compound { 33 finish_test 34 return 35} 36 37do_test trigger1-1.1.1 { 38 catchsql { 39 CREATE TRIGGER trig UPDATE ON no_such_table BEGIN 40 SELECT * from sqlite_master; 41 END; 42 } 43} {1 {no such table: main.no_such_table}} 44 45ifcapable tempdb { 46 do_test trigger1-1.1.2 { 47 catchsql { 48 CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN 49 SELECT * from sqlite_master; 50 END; 51 } 52 } {1 {no such table: no_such_table}} 53} 54 55execsql { 56 CREATE TABLE t1(a); 57} 58do_test trigger1-1.1.3 { 59 catchsql { 60 CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN 61 SELECT * FROM sqlite_master; 62 END; 63 } 64} {1 {near "STATEMENT": syntax error}} 65execsql { 66 CREATE TRIGGER tr1 INSERT ON t1 BEGIN 67 INSERT INTO t1 values(1); 68 END; 69} 70do_test trigger1-1.2.0 { 71 catchsql { 72 CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN 73 SELECT * FROM sqlite_master; 74 END 75 } 76} {0 {}} 77do_test trigger1-1.2.1 { 78 catchsql { 79 CREATE TRIGGER tr1 DELETE ON t1 BEGIN 80 SELECT * FROM sqlite_master; 81 END 82 } 83} {1 {trigger tr1 already exists}} 84do_test trigger1-1.2.2 { 85 catchsql { 86 CREATE TRIGGER "tr1" DELETE ON t1 BEGIN 87 SELECT * FROM sqlite_master; 88 END 89 } 90} {1 {trigger "tr1" already exists}} 91do_test trigger1-1.2.3 { 92 catchsql { 93 CREATE TRIGGER [tr1] DELETE ON t1 BEGIN 94 SELECT * FROM sqlite_master; 95 END 96 } 97} {1 {trigger [tr1] already exists}} 98 99do_test trigger1-1.3 { 100 catchsql { 101 BEGIN; 102 CREATE TRIGGER tr2 INSERT ON t1 BEGIN 103 SELECT * from sqlite_master; END; 104 ROLLBACK; 105 CREATE TRIGGER tr2 INSERT ON t1 BEGIN 106 SELECT * from sqlite_master; END; 107 } 108} {0 {}} 109 110do_test trigger1-1.4 { 111 catchsql { 112 DROP TRIGGER IF EXISTS tr1; 113 CREATE TRIGGER tr1 DELETE ON t1 BEGIN 114 SELECT * FROM sqlite_master; 115 END 116 } 117} {0 {}} 118 119do_test trigger1-1.5 { 120 execsql { 121 BEGIN; 122 DROP TRIGGER tr2; 123 ROLLBACK; 124 DROP TRIGGER tr2; 125 } 126} {} 127 128do_test trigger1-1.6.1 { 129 catchsql { 130 DROP TRIGGER IF EXISTS biggles; 131 } 132} {0 {}} 133 134do_test trigger1-1.6.2 { 135 catchsql { 136 DROP TRIGGER biggles; 137 } 138} {1 {no such trigger: biggles}} 139 140do_test trigger1-1.7 { 141 catchsql { 142 DROP TABLE t1; 143 DROP TRIGGER tr1; 144 } 145} {1 {no such trigger: tr1}} 146 147ifcapable tempdb { 148 execsql { 149 CREATE TEMP TABLE temp_table(a); 150 } 151 do_test trigger1-1.8 { 152 execsql { 153 CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN 154 SELECT * from sqlite_master; 155 END; 156 SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig'; 157 } 158 } {0} 159} 160 161do_test trigger1-1.9 { 162 catchsql { 163 CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN 164 SELECT * FROM sqlite_master; 165 END; 166 } 167} {1 {cannot create trigger on system table}} 168 169# Check to make sure that a DELETE statement within the body of 170# a trigger does not mess up the DELETE that caused the trigger to 171# run in the first place. 172# 173do_test trigger1-1.10 { 174 execsql { 175 create table t1(a,b); 176 insert into t1 values(1,'a'); 177 insert into t1 values(2,'b'); 178 insert into t1 values(3,'c'); 179 insert into t1 values(4,'d'); 180 create trigger r1 after delete on t1 for each row begin 181 delete from t1 WHERE a=old.a+2; 182 end; 183 delete from t1 where a=1 OR a=3; 184 select * from t1; 185 drop table t1; 186 } 187} {2 b 4 d} 188 189do_test trigger1-1.11 { 190 execsql { 191 create table t1(a,b); 192 insert into t1 values(1,'a'); 193 insert into t1 values(2,'b'); 194 insert into t1 values(3,'c'); 195 insert into t1 values(4,'d'); 196 create trigger r1 after update on t1 for each row begin 197 delete from t1 WHERE a=old.a+2; 198 end; 199 update t1 set b='x-' || b where a=1 OR a=3; 200 select * from t1; 201 drop table t1; 202 } 203} {1 x-a 2 b 4 d} 204 205# Ensure that we cannot create INSTEAD OF triggers on tables 206do_test trigger1-1.12 { 207 catchsql { 208 create table t1(a,b); 209 create trigger t1t instead of update on t1 for each row begin 210 delete from t1 WHERE a=old.a+2; 211 end; 212 } 213} {1 {cannot create INSTEAD OF trigger on table: main.t1}} 214 215ifcapable view { 216# Ensure that we cannot create BEFORE triggers on views 217do_test trigger1-1.13 { 218 catchsql { 219 create view v1 as select * from t1; 220 create trigger v1t before update on v1 for each row begin 221 delete from t1 WHERE a=old.a+2; 222 end; 223 } 224} {1 {cannot create BEFORE trigger on view: main.v1}} 225# Ensure that we cannot create AFTER triggers on views 226do_test trigger1-1.14 { 227 catchsql { 228 drop view v1; 229 create view v1 as select * from t1; 230 create trigger v1t AFTER update on v1 for each row begin 231 delete from t1 WHERE a=old.a+2; 232 end; 233 } 234} {1 {cannot create AFTER trigger on view: main.v1}} 235} ;# ifcapable view 236 237# Check for memory leaks in the trigger parser 238# 239do_test trigger1-2.1 { 240 catchsql { 241 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 242 SELECT * FROM; -- Syntax error 243 END; 244 } 245} {1 {near ";": syntax error}} 246do_test trigger1-2.2 { 247 catchsql { 248 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 249 SELECT * FROM t1; 250 SELECT * FROM; -- Syntax error 251 END; 252 } 253} {1 {near ";": syntax error}} 254 255# Create a trigger that refers to a table that might not exist. 256# 257ifcapable tempdb { 258 do_test trigger1-3.1 { 259 execsql { 260 CREATE TEMP TABLE t2(x,y); 261 } 262 catchsql { 263 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN 264 INSERT INTO t2 VALUES(NEW.a,NEW.b); 265 END; 266 } 267 } {0 {}} 268 do_test trigger-3.2 { 269 catchsql { 270 INSERT INTO t1 VALUES(1,2); 271 SELECT * FROM t2; 272 } 273 } {1 {no such table: main.t2}} 274 do_test trigger-3.3 { 275 db close 276 set rc [catch {sqlite3 db test.db} err] 277 if {$rc} {lappend rc $err} 278 set rc 279 } {0} 280 do_test trigger-3.4 { 281 catchsql { 282 INSERT INTO t1 VALUES(1,2); 283 SELECT * FROM t2; 284 } 285 } {1 {no such table: main.t2}} 286 do_test trigger-3.5 { 287 catchsql { 288 CREATE TEMP TABLE t2(x,y); 289 INSERT INTO t1 VALUES(1,2); 290 SELECT * FROM t2; 291 } 292 } {1 {no such table: main.t2}} 293 do_test trigger-3.6.1 { 294 catchsql { 295 DROP TRIGGER r1; 296 CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN 297 INSERT INTO t2 VALUES(NEW.a,NEW.b), (NEW.b*100, NEW.a*100); 298 END; 299 INSERT INTO t1 VALUES(1,2); 300 SELECT * FROM t2; 301 } 302 } {0 {1 2 200 100}} 303 do_test trigger-3.6.2 { 304 catchsql { 305 DROP TRIGGER r1; 306 DELETE FROM t1; 307 DELETE FROM t2; 308 CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN 309 INSERT INTO t2 VALUES(NEW.a,NEW.b); 310 END; 311 INSERT INTO t1 VALUES(1,2); 312 SELECT * FROM t2; 313 } 314 } {0 {1 2}} 315 do_test trigger-3.7 { 316 execsql { 317 DROP TABLE t2; 318 CREATE TABLE t2(x,y); 319 SELECT * FROM t2; 320 } 321 } {} 322 323 # There are two versions of trigger-3.8 and trigger-3.9. One that uses 324 # compound SELECT statements, and another that does not. 325 ifcapable compound { 326 do_test trigger1-3.8 { 327 execsql { 328 INSERT INTO t1 VALUES(3,4); 329 SELECT * FROM t1 UNION ALL SELECT * FROM t2; 330 } 331 } {1 2 3 4 3 4} 332 do_test trigger1-3.9 { 333 db close 334 sqlite3 db test.db 335 execsql { 336 INSERT INTO t1 VALUES(5,6); 337 SELECT * FROM t1 UNION ALL SELECT * FROM t2; 338 } 339 } {1 2 3 4 5 6 3 4} 340 } ;# ifcapable compound 341 ifcapable !compound { 342 do_test trigger1-3.8 { 343 execsql { 344 INSERT INTO t1 VALUES(3,4); 345 SELECT * FROM t1; 346 SELECT * FROM t2; 347 } 348 } {1 2 3 4 3 4} 349 do_test trigger1-3.9 { 350 db close 351 sqlite3 db test.db 352 execsql { 353 INSERT INTO t1 VALUES(5,6); 354 SELECT * FROM t1; 355 SELECT * FROM t2; 356 } 357 } {1 2 3 4 5 6 3 4} 358 } ;# ifcapable !compound 359 360 do_test trigger1-4.1 { 361 execsql { 362 CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN 363 INSERT INTO t2 VALUES(NEW.a,NEW.b); 364 END; 365 INSERT INTO t1 VALUES(7,8); 366 SELECT * FROM t2; 367 } 368 } {3 4 7 8} 369 do_test trigger1-4.2 { 370 sqlite3 db2 test.db 371 execsql { 372 INSERT INTO t1 VALUES(9,10); 373 } db2; 374 db2 close 375 execsql { 376 SELECT * FROM t2; 377 } 378 } {3 4 7 8} 379 do_test trigger1-4.3 { 380 execsql { 381 DROP TABLE t1; 382 SELECT * FROM t2; 383 }; 384 } {3 4 7 8} 385 do_test trigger1-4.4 { 386 db close 387 sqlite3 db test.db 388 execsql { 389 SELECT * FROM t2; 390 }; 391 } {3 4 7 8} 392} else { 393 execsql { 394 CREATE TABLE t2(x,y); 395 DROP TABLE t1; 396 INSERT INTO t2 VALUES(3, 4); 397 INSERT INTO t2 VALUES(7, 8); 398 } 399} 400 401 402integrity_check trigger1-5.1 403 404# Create a trigger with the same name as a table. Make sure the 405# trigger works. Then drop the trigger. Make sure the table is 406# still there. 407# 408set view_v1 {} 409ifcapable view { 410 set view_v1 {view v1} 411} 412do_test trigger1-6.1 { 413 execsql {SELECT type, name FROM sqlite_master} 414} [concat $view_v1 {table t2}] 415do_test trigger1-6.2 { 416 execsql { 417 CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN 418 SELECT RAISE(ABORT,'deletes are not permitted'); 419 END; 420 SELECT type, name FROM sqlite_master; 421 } 422} [concat $view_v1 {table t2 trigger t2}] 423do_test trigger1-6.3 { 424 catchsql {DELETE FROM t2} 425} {1 {deletes are not permitted}} 426do_test trigger1-6.4 { 427 execsql {SELECT * FROM t2} 428} {3 4 7 8} 429do_test trigger1-6.5 { 430 db close 431 sqlite3 db test.db 432 execsql {SELECT type, name FROM sqlite_master} 433} [concat $view_v1 {table t2 trigger t2}] 434do_test trigger1-6.6 { 435 execsql { 436 DROP TRIGGER t2; 437 SELECT type, name FROM sqlite_master; 438 } 439} [concat $view_v1 {table t2}] 440do_test trigger1-6.7 { 441 execsql {SELECT * FROM t2} 442} {3 4 7 8} 443do_test trigger1-6.8 { 444 db close 445 sqlite3 db test.db 446 execsql {SELECT * FROM t2} 447} {3 4 7 8} 448 449integrity_check trigger-7.1 450 451# Check to make sure the name of a trigger can be quoted so that keywords 452# can be used as trigger names. Ticket #468 453# 454do_test trigger1-8.1 { 455 execsql { 456 CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END; 457 SELECT name FROM sqlite_master WHERE type='trigger'; 458 } 459} {trigger} 460do_test trigger1-8.2 { 461 execsql { 462 DROP TRIGGER 'trigger'; 463 SELECT name FROM sqlite_master WHERE type='trigger'; 464 } 465} {} 466do_test trigger1-8.3 { 467 execsql { 468 CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END; 469 SELECT name FROM sqlite_master WHERE type='trigger'; 470 } 471} {trigger} 472do_test trigger1-8.4 { 473 execsql { 474 DROP TRIGGER "trigger"; 475 SELECT name FROM sqlite_master WHERE type='trigger'; 476 } 477} {} 478do_test trigger1-8.5 { 479 execsql { 480 CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END; 481 SELECT name FROM sqlite_master WHERE type='trigger'; 482 } 483} {trigger} 484do_test trigger1-8.6 { 485 execsql { 486 DROP TRIGGER [trigger]; 487 SELECT name FROM sqlite_master WHERE type='trigger'; 488 } 489} {} 490 491ifcapable conflict { 492 # Make sure REPLACE works inside of triggers. 493 # 494 # There are two versions of trigger-9.1 and trigger-9.2. One that uses 495 # compound SELECT statements, and another that does not. 496 ifcapable compound { 497 do_test trigger1-9.1 { 498 execsql { 499 CREATE TABLE t3(a,b); 500 CREATE TABLE t4(x UNIQUE, b); 501 CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN 502 REPLACE INTO t4 VALUES(new.a,new.b); 503 END; 504 INSERT INTO t3 VALUES(1,2); 505 SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; 506 } 507 } {1 2 99 99 1 2} 508 do_test trigger1-9.2 { 509 execsql { 510 INSERT INTO t3 VALUES(1,3); 511 SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; 512 } 513 } {1 2 1 3 99 99 1 3} 514 } else { 515 do_test trigger1-9.1 { 516 execsql { 517 CREATE TABLE t3(a,b); 518 CREATE TABLE t4(x UNIQUE, b); 519 CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN 520 REPLACE INTO t4 VALUES(new.a,new.b); 521 END; 522 INSERT INTO t3 VALUES(1,2); 523 SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; 524 } 525 } {1 2 99 99 1 2} 526 do_test trigger1-9.2 { 527 execsql { 528 INSERT INTO t3 VALUES(1,3); 529 SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; 530 } 531 } {1 2 1 3 99 99 1 3} 532 } 533 execsql { 534 DROP TABLE t3; 535 DROP TABLE t4; 536 } 537} 538 539 540# Ticket #764. At one stage TEMP triggers would fail to re-install when the 541# schema was reloaded. The following tests ensure that TEMP triggers are 542# correctly re-installed. 543# 544# Also verify that references within trigger programs are resolved at 545# statement compile time, not trigger installation time. This means, for 546# example, that you can drop and re-create tables referenced by triggers. 547ifcapable tempdb&&attach { 548 do_test trigger1-10.0 { 549 forcedelete test2.db 550 forcedelete test2.db-journal 551 execsql { 552 ATTACH 'test2.db' AS aux; 553 } 554 } {} 555 do_test trigger1-10.1 { 556 execsql { 557 CREATE TABLE main.t4(a, b, c); 558 CREATE TABLE temp.t4(a, b, c); 559 CREATE TABLE aux.t4(a, b, c); 560 CREATE TABLE insert_log(db, a, b, c); 561 } 562 } {} 563 do_test trigger1-10.2 { 564 execsql { 565 CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN 566 INSERT INTO insert_log VALUES('main', new.a, new.b, new.c); 567 END; 568 CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN 569 INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c); 570 END; 571 CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN 572 INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c); 573 END; 574 } 575 } {} 576 do_test trigger1-10.3 { 577 execsql { 578 INSERT INTO main.t4 VALUES(1, 2, 3); 579 INSERT INTO temp.t4 VALUES(4, 5, 6); 580 INSERT INTO aux.t4 VALUES(7, 8, 9); 581 } 582 } {} 583 do_test trigger1-10.4 { 584 execsql { 585 SELECT * FROM insert_log; 586 } 587 } {main 1 2 3 temp 4 5 6 aux 7 8 9} 588 do_test trigger1-10.5 { 589 execsql { 590 BEGIN; 591 INSERT INTO main.t4 VALUES(1, 2, 3); 592 INSERT INTO temp.t4 VALUES(4, 5, 6); 593 INSERT INTO aux.t4 VALUES(7, 8, 9); 594 ROLLBACK; 595 } 596 } {} 597 do_test trigger1-10.6 { 598 execsql { 599 SELECT * FROM insert_log; 600 } 601 } {main 1 2 3 temp 4 5 6 aux 7 8 9} 602 do_test trigger1-10.7 { 603 execsql { 604 DELETE FROM insert_log; 605 INSERT INTO main.t4 VALUES(11, 12, 13); 606 INSERT INTO temp.t4 VALUES(14, 15, 16); 607 INSERT INTO aux.t4 VALUES(17, 18, 19); 608 } 609 } {} 610 do_test trigger1-10.8 { 611 execsql { 612 SELECT * FROM insert_log; 613 } 614 } {main 11 12 13 temp 14 15 16 aux 17 18 19} 615 do_test trigger1-10.8 { 616 # Drop and re-create the insert_log table in a different database. Note 617 # that we can change the column names because the trigger programs don't 618 # use them explicitly. 619 execsql { 620 DROP TABLE insert_log; 621 CREATE TABLE aux.insert_log(db, d, e, f); 622 } 623 } {} 624 do_test trigger1-10.10 { 625 execsql { 626 INSERT INTO main.t4 VALUES(21, 22, 23); 627 INSERT INTO temp.t4 VALUES(24, 25, 26); 628 INSERT INTO aux.t4 VALUES(27, 28, 29); 629 } 630 } {} 631 do_test trigger1-10.11 { 632 execsql { 633 SELECT * FROM insert_log; 634 } 635 } {main 21 22 23 temp 24 25 26 aux 27 28 29} 636} 637 638do_test trigger1-11.1 { 639 catchsql {SELECT raise(abort,'message');} 640} {1 {RAISE() may only be used within a trigger-program}} 641 642do_test trigger1-15.1 { 643 execsql { 644 CREATE TABLE tA(a INTEGER PRIMARY KEY, b, c); 645 CREATE TRIGGER tA_trigger BEFORE UPDATE ON "tA" BEGIN SELECT 1; END; 646 INSERT INTO tA VALUES(1, 2, 3); 647 } 648 catchsql { UPDATE tA SET a = 'abc' } 649} {1 {datatype mismatch}} 650do_test trigger1-15.2 { 651 catchsql { INSERT INTO tA VALUES('abc', 2, 3) } 652} {1 {datatype mismatch}} 653 654# Ticket #3947: Do not allow qualified table names on INSERT, UPDATE, and 655# DELETE statements within triggers. Actually, this has never been allowed 656# by the grammar. But the error message is confusing: one simply gets a 657# "syntax error". That has now been changed to give a full error message. 658# 659do_test trigger1-16.1 { 660 db eval { 661 CREATE TABLE t16(a,b,c); 662 CREATE INDEX t16a ON t16(a); 663 CREATE INDEX t16b ON t16(b); 664 } 665 catchsql { 666 CREATE TRIGGER main.t16err1 AFTER INSERT ON tA BEGIN 667 INSERT INTO main.t16 VALUES(1,2,3); 668 END; 669 } 670} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}} 671do_test trigger1-16.2 { 672 catchsql { 673 CREATE TRIGGER main.t16err2 AFTER INSERT ON tA BEGIN 674 UPDATE main.t16 SET rowid=rowid+1; 675 END; 676 } 677} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}} 678do_test trigger1-16.3 { 679 catchsql { 680 CREATE TRIGGER main.t16err3 AFTER INSERT ON tA BEGIN 681 DELETE FROM main.t16; 682 END; 683 } 684} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}} 685do_test trigger1-16.4 { 686 catchsql { 687 CREATE TRIGGER main.t16err4 AFTER INSERT ON tA BEGIN 688 UPDATE t16 NOT INDEXED SET rowid=rowid+1; 689 END; 690 } 691} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}} 692do_test trigger1-16.5 { 693 catchsql { 694 CREATE TRIGGER main.t16err5 AFTER INSERT ON tA BEGIN 695 UPDATE t16 INDEXED BY t16a SET rowid=rowid+1 WHERE a=1; 696 END; 697 } 698} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}} 699do_test trigger1-16.6 { 700 catchsql { 701 CREATE TRIGGER main.t16err6 AFTER INSERT ON tA BEGIN 702 DELETE FROM t16 NOT INDEXED WHERE a=123; 703 END; 704 } 705} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}} 706do_test trigger1-16.7 { 707 catchsql { 708 CREATE TRIGGER main.t16err7 AFTER INSERT ON tA BEGIN 709 DELETE FROM t16 INDEXED BY t16a WHERE a=123; 710 END; 711 } 712} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}} 713 714finish_test 715