Annotation of embedaddon/sqlite3/test/trigger2.test, revision 1.1.1.1

1.1       misho       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: # Regression testing of FOR EACH ROW table triggers
                     11: #
                     12: # 1. Trigger execution order tests. 
                     13: # These tests ensure that BEFORE and AFTER triggers are fired at the correct
                     14: # times relative to each other and the triggering statement. 
                     15: #
                     16: # trigger2-1.1.*: ON UPDATE trigger execution model.
                     17: # trigger2-1.2.*: DELETE trigger execution model.
                     18: # trigger2-1.3.*: INSERT trigger execution model.
                     19: #
                     20: # 2. Trigger program execution tests.
                     21: # These tests ensure that trigger programs execute correctly (ie. that a
                     22: # trigger program can correctly execute INSERT, UPDATE, DELETE * SELECT
                     23: # statements, and combinations thereof).
                     24: #
                     25: # 3. Selective trigger execution 
                     26: # This tests that conditional triggers (ie. UPDATE OF triggers and triggers
                     27: # with WHEN clauses) are fired only fired when they are supposed to be.
                     28: #
                     29: # trigger2-3.1: UPDATE OF triggers
                     30: # trigger2-3.2: WHEN clause
                     31: #
                     32: # 4. Cascaded trigger execution 
                     33: # Tests that trigger-programs may cause other triggers to fire. Also that a 
                     34: # trigger-program is never executed recursively.
                     35: # 
                     36: # trigger2-4.1: Trivial cascading trigger
                     37: # trigger2-4.2: Trivial recursive trigger handling 
                     38: #
                     39: # 5. Count changes behaviour.
                     40: # Verify that rows altered by triggers are not included in the return value
                     41: # of the "count changes" interface.
                     42: #
                     43: # 6. ON CONFLICT clause handling
                     44: # trigger2-6.1[a-f]: INSERT statements
                     45: # trigger2-6.2[a-f]: UPDATE statements
                     46: #
                     47: # 7. & 8. Triggers on views fire correctly.
                     48: #
                     49: 
                     50: set testdir [file dirname $argv0]
                     51: source $testdir/tester.tcl
                     52: ifcapable {!trigger} {
                     53:   finish_test
                     54:   return
                     55: }
                     56: 
                     57: # The tests in this file were written before SQLite supported recursive
                     58: # trigger invocation, and some tests depend on that to pass. So disable
                     59: # recursive triggers for this file.
                     60: catchsql { pragma recursive_triggers = off } 
                     61: 
                     62: # 1.
                     63: ifcapable subquery {
                     64:   set ii 0
                     65:   set tbl_definitions [list \
                     66:        {CREATE TABLE tbl (a, b);}                                      \
                     67:        {CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);}                  \
                     68:         {CREATE TABLE tbl (a, b PRIMARY KEY);}                          \
                     69:        {CREATE TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);}      \
                     70:   ]
                     71:   ifcapable tempdb {
                     72:     lappend tbl_definitions \
                     73:         {CREATE TEMP TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} 
                     74:     lappend tbl_definitions {CREATE TEMP TABLE tbl (a, b);}
                     75:     lappend tbl_definitions \
                     76:         {CREATE TEMPORARY TABLE tbl (a INTEGER PRIMARY KEY, b);}
                     77:   }
                     78:   foreach tbl_defn $tbl_definitions {
                     79:     incr ii
                     80:     catchsql { DROP INDEX tbl_idx; }
                     81:     catchsql {
                     82:       DROP TABLE rlog;
                     83:       DROP TABLE clog;
                     84:       DROP TABLE tbl;
                     85:       DROP TABLE other_tbl;
                     86:     }
                     87:   
                     88:     execsql $tbl_defn
                     89:   
                     90:     execsql {
                     91:       INSERT INTO tbl VALUES(1, 2);
                     92:       INSERT INTO tbl VALUES(3, 4);
                     93:   
                     94:       CREATE TABLE rlog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
                     95:       CREATE TABLE clog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
                     96:   
                     97:       CREATE TRIGGER before_update_row BEFORE UPDATE ON tbl FOR EACH ROW 
                     98:         BEGIN
                     99:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    100:          old.a, old.b, 
                    101:          (SELECT coalesce(sum(a),0) FROM tbl),
                    102:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    103:          new.a, new.b);
                    104:       END;
                    105:   
                    106:       CREATE TRIGGER after_update_row AFTER UPDATE ON tbl FOR EACH ROW 
                    107:         BEGIN
                    108:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    109:          old.a, old.b, 
                    110:          (SELECT coalesce(sum(a),0) FROM tbl),
                    111:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    112:          new.a, new.b);
                    113:       END;
                    114:   
                    115:       CREATE TRIGGER conditional_update_row AFTER UPDATE ON tbl FOR EACH ROW
                    116:         WHEN old.a = 1
                    117:         BEGIN
                    118:         INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog), 
                    119:          old.a, old.b, 
                    120:          (SELECT coalesce(sum(a),0) FROM tbl),
                    121:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    122:          new.a, new.b);
                    123:       END;
                    124:     }
                    125:   
                    126:     do_test trigger2-1.$ii.1 {
                    127:       set r {}
                    128:       foreach v [execsql { 
                    129:         UPDATE tbl SET a = a * 10, b = b * 10;
                    130:         SELECT * FROM rlog ORDER BY idx;
                    131:         SELECT * FROM clog ORDER BY idx;
                    132:       }] {
                    133:         lappend r [expr {int($v)}]
                    134:       }
                    135:       set r
                    136:     } [list 1 1 2  4  6 10 20 \
                    137:             2 1 2 13 24 10 20 \
                    138:            3 3 4 13 24 30 40 \
                    139:            4 3 4 40 60 30 40 \
                    140:             1 1 2 13 24 10 20 ]
                    141:   
                    142:     execsql {
                    143:       DELETE FROM rlog;
                    144:       DELETE FROM tbl;
                    145:       INSERT INTO tbl VALUES (100, 100);
                    146:       INSERT INTO tbl VALUES (300, 200);
                    147:       CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW
                    148:         BEGIN
                    149:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    150:          old.a, old.b, 
                    151:          (SELECT coalesce(sum(a),0) FROM tbl),
                    152:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    153:          0, 0);
                    154:       END;
                    155:   
                    156:       CREATE TRIGGER delete_after_row AFTER DELETE ON tbl FOR EACH ROW
                    157:         BEGIN
                    158:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    159:          old.a, old.b, 
                    160:          (SELECT coalesce(sum(a),0) FROM tbl),
                    161:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    162:          0, 0);
                    163:       END;
                    164:     }
                    165:     do_test trigger2-1.$ii.2 {
                    166:       set r {}
                    167:       foreach v [execsql {
                    168:         DELETE FROM tbl;
                    169:         SELECT * FROM rlog;
                    170:       }] {
                    171:         lappend r [expr {int($v)}]
                    172:       }
                    173:       set r
                    174:     } [list 1 100 100 400 300 0 0 \
                    175:             2 100 100 300 200 0 0 \
                    176:             3 300 200 300 200 0 0 \
                    177:             4 300 200 0 0 0 0 ]
                    178:   
                    179:     execsql {
                    180:       DELETE FROM rlog;
                    181:       CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW
                    182:         BEGIN
                    183:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    184:          0, 0,
                    185:          (SELECT coalesce(sum(a),0) FROM tbl),
                    186:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    187:          new.a, new.b);
                    188:       END;
                    189:   
                    190:       CREATE TRIGGER insert_after_row AFTER INSERT ON tbl FOR EACH ROW
                    191:         BEGIN
                    192:         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
                    193:          0, 0,
                    194:          (SELECT coalesce(sum(a),0) FROM tbl),
                    195:           (SELECT coalesce(sum(b),0) FROM tbl), 
                    196:          new.a, new.b);
                    197:       END;
                    198:     }
                    199:     do_test trigger2-1.$ii.3 {
                    200:       execsql {
                    201:   
                    202:         CREATE TABLE other_tbl(a, b);
                    203:         INSERT INTO other_tbl VALUES(1, 2);
                    204:         INSERT INTO other_tbl VALUES(3, 4);
                    205:         -- INSERT INTO tbl SELECT * FROM other_tbl;
                    206:         INSERT INTO tbl VALUES(5, 6);
                    207:         DROP TABLE other_tbl;
                    208:   
                    209:         SELECT * FROM rlog;
                    210:       }
                    211:     } [list 1 0 0 0 0 5 6 \
                    212:             2 0 0 5 6 5 6 ]
                    213:   
                    214:     integrity_check trigger2-1.$ii.4
                    215:   }
                    216:   catchsql {
                    217:     DROP TABLE rlog;
                    218:     DROP TABLE clog;
                    219:     DROP TABLE tbl;
                    220:     DROP TABLE other_tbl;
                    221:   }
                    222: }
                    223: 
                    224: # 2.
                    225: set ii 0
                    226: foreach tr_program {
                    227:   {UPDATE tbl SET b = old.b;}
                    228:   {INSERT INTO log VALUES(new.c, 2, 3);}
                    229:   {DELETE FROM log WHERE a = 1;}
                    230:   {INSERT INTO tbl VALUES(500, new.b * 10, 700); 
                    231:     UPDATE tbl SET c = old.c; 
                    232:     DELETE FROM log;}
                    233:   {INSERT INTO log select * from tbl;} 
                    234: } {
                    235:   foreach test_varset [ list \
                    236:     {
                    237:       set statement {UPDATE tbl SET c = 10 WHERE a = 1;} 
                    238:       set prep      {INSERT INTO tbl VALUES(1, 2, 3);}
                    239:       set newC 10
                    240:       set newB 2
                    241:       set newA 1
                    242:       set oldA 1
                    243:       set oldB 2
                    244:       set oldC 3
                    245:     } \
                    246:     {
                    247:       set statement {DELETE FROM tbl WHERE a = 1;}
                    248:       set prep      {INSERT INTO tbl VALUES(1, 2, 3);}
                    249:       set oldA 1
                    250:       set oldB 2
                    251:       set oldC 3
                    252:     } \
                    253:     {
                    254:       set statement {INSERT INTO tbl VALUES(1, 2, 3);}
                    255:       set newA 1
                    256:       set newB 2
                    257:       set newC 3
                    258:     }
                    259:   ] \
                    260:   {
                    261:     set statement {}
                    262:     set prep {}
                    263:     set newA {''}
                    264:     set newB {''}
                    265:     set newC {''}
                    266:     set oldA {''}
                    267:     set oldB {''}
                    268:     set oldC {''}
                    269: 
                    270:     incr ii
                    271: 
                    272:     eval $test_varset
                    273: 
                    274:     set statement_type [string range $statement 0 5]
                    275:     set tr_program_fixed $tr_program
                    276:     if {$statement_type == "DELETE"} {
                    277:       regsub -all new\.a $tr_program_fixed {''} tr_program_fixed 
                    278:       regsub -all new\.b $tr_program_fixed {''} tr_program_fixed 
                    279:       regsub -all new\.c $tr_program_fixed {''} tr_program_fixed 
                    280:     }
                    281:     if {$statement_type == "INSERT"} {
                    282:       regsub -all old\.a $tr_program_fixed {''} tr_program_fixed 
                    283:       regsub -all old\.b $tr_program_fixed {''} tr_program_fixed 
                    284:       regsub -all old\.c $tr_program_fixed {''} tr_program_fixed 
                    285:     }
                    286: 
                    287: 
                    288:     set tr_program_cooked $tr_program
                    289:     regsub -all new\.a $tr_program_cooked $newA tr_program_cooked 
                    290:     regsub -all new\.b $tr_program_cooked $newB tr_program_cooked 
                    291:     regsub -all new\.c $tr_program_cooked $newC tr_program_cooked 
                    292:     regsub -all old\.a $tr_program_cooked $oldA tr_program_cooked 
                    293:     regsub -all old\.b $tr_program_cooked $oldB tr_program_cooked 
                    294:     regsub -all old\.c $tr_program_cooked $oldC tr_program_cooked 
                    295: 
                    296:     catchsql {
                    297:       DROP TABLE tbl;
                    298:       DROP TABLE log;
                    299:     }
                    300: 
                    301:     execsql {
                    302:       CREATE TABLE tbl(a PRIMARY KEY, b, c);
                    303:       CREATE TABLE log(a, b, c);
                    304:     }
                    305: 
                    306:     set query {SELECT * FROM tbl; SELECT * FROM log;}
                    307:     set prep "$prep; INSERT INTO log VALUES(1, 2, 3);\
                    308:              INSERT INTO log VALUES(10, 20, 30);"
                    309: 
                    310: # Check execution of BEFORE programs:
                    311: 
                    312:     set before_data [ execsql "$prep $tr_program_cooked $statement $query" ]
                    313: 
                    314:     execsql "DELETE FROM tbl; DELETE FROM log; $prep";
                    315:     execsql "CREATE TRIGGER the_trigger BEFORE [string range $statement 0 6]\
                    316:              ON tbl BEGIN $tr_program_fixed END;"
                    317: 
                    318:     do_test trigger2-2.$ii-before "execsql {$statement $query}" $before_data
                    319: 
                    320:     execsql "DROP TRIGGER the_trigger;"
                    321:     execsql "DELETE FROM tbl; DELETE FROM log;"
                    322: 
                    323: # Check execution of AFTER programs
                    324:     set after_data [ execsql "$prep $statement $tr_program_cooked $query" ]
                    325: 
                    326:     execsql "DELETE FROM tbl; DELETE FROM log; $prep";
                    327:     execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
                    328:              ON tbl BEGIN $tr_program_fixed END;"
                    329: 
                    330:     do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
                    331:     execsql "DROP TRIGGER the_trigger;"
                    332: 
                    333:     integrity_check trigger2-2.$ii-integrity
                    334:   }
                    335: }
                    336: catchsql {
                    337:   DROP TABLE tbl;
                    338:   DROP TABLE log;
                    339: }
                    340: 
                    341: # 3.
                    342: 
                    343: # trigger2-3.1: UPDATE OF triggers
                    344: execsql {
                    345:   CREATE TABLE tbl (a, b, c, d);
                    346:   CREATE TABLE log (a);
                    347:   INSERT INTO log VALUES (0);
                    348:   INSERT INTO tbl VALUES (0, 0, 0, 0);
                    349:   INSERT INTO tbl VALUES (1, 0, 0, 0);
                    350:   CREATE TRIGGER tbl_after_update_cd BEFORE UPDATE OF c, d ON tbl
                    351:     BEGIN
                    352:       UPDATE log SET a = a + 1;
                    353:     END;
                    354: }
                    355: do_test trigger2-3.1 {
                    356:   execsql {
                    357:     UPDATE tbl SET b = 1, c = 10; -- 2
                    358:     UPDATE tbl SET b = 10; -- 0
                    359:     UPDATE tbl SET d = 4 WHERE a = 0; --1
                    360:     UPDATE tbl SET a = 4, b = 10; --0
                    361:     SELECT * FROM log;
                    362:   }
                    363: } {3}
                    364: execsql {
                    365:   DROP TABLE tbl;
                    366:   DROP TABLE log;
                    367: }
                    368: 
                    369: # trigger2-3.2: WHEN clause
                    370: set when_triggers [list {t1 BEFORE INSERT ON tbl WHEN new.a > 20}]
                    371: ifcapable subquery {
                    372:   lappend when_triggers \
                    373:       {t2 BEFORE INSERT ON tbl WHEN (SELECT count(*) FROM tbl) = 0}
                    374: }
                    375: 
                    376: execsql {
                    377:   CREATE TABLE tbl (a, b, c, d);
                    378:   CREATE TABLE log (a);
                    379:   INSERT INTO log VALUES (0);
                    380: }
                    381: 
                    382: foreach trig $when_triggers {
                    383:   execsql "CREATE TRIGGER $trig BEGIN UPDATE log set a = a + 1; END;"
                    384: }
                    385: 
                    386: ifcapable subquery {
                    387:   set t232 {1 0 1}
                    388: } else {
                    389:   set t232 {0 0 1}
                    390: }
                    391: do_test trigger2-3.2 {
                    392:   execsql { 
                    393: 
                    394:     INSERT INTO tbl VALUES(0, 0, 0, 0);     -- 1 (ifcapable subquery)
                    395:     SELECT * FROM log;
                    396:     UPDATE log SET a = 0;
                    397: 
                    398:     INSERT INTO tbl VALUES(0, 0, 0, 0);     -- 0
                    399:     SELECT * FROM log;
                    400:     UPDATE log SET a = 0;
                    401: 
                    402:     INSERT INTO tbl VALUES(200, 0, 0, 0);     -- 1
                    403:     SELECT * FROM log;
                    404:     UPDATE log SET a = 0;
                    405:   }
                    406: } $t232
                    407: execsql {
                    408:   DROP TABLE tbl;
                    409:   DROP TABLE log;
                    410: }
                    411: integrity_check trigger2-3.3
                    412: 
                    413: # Simple cascaded trigger
                    414: execsql {
                    415:   CREATE TABLE tblA(a, b);
                    416:   CREATE TABLE tblB(a, b);
                    417:   CREATE TABLE tblC(a, b);
                    418: 
                    419:   CREATE TRIGGER tr1 BEFORE INSERT ON tblA BEGIN
                    420:     INSERT INTO tblB values(new.a, new.b);
                    421:   END;
                    422: 
                    423:   CREATE TRIGGER tr2 BEFORE INSERT ON tblB BEGIN
                    424:     INSERT INTO tblC values(new.a, new.b);
                    425:   END;
                    426: }
                    427: do_test trigger2-4.1 {
                    428:   execsql {
                    429:     INSERT INTO tblA values(1, 2);
                    430:     SELECT * FROM tblA;
                    431:     SELECT * FROM tblB;
                    432:     SELECT * FROM tblC;
                    433:   }
                    434: } {1 2 1 2 1 2}
                    435: execsql {
                    436:   DROP TABLE tblA;
                    437:   DROP TABLE tblB;
                    438:   DROP TABLE tblC;
                    439: }
                    440: 
                    441: # Simple recursive trigger
                    442: execsql {
                    443:   CREATE TABLE tbl(a, b, c);
                    444:   CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl 
                    445:     BEGIN
                    446:       INSERT INTO tbl VALUES (new.a, new.b, new.c);
                    447:     END;
                    448: }
                    449: do_test trigger2-4.2 {
                    450:   execsql {
                    451:     INSERT INTO tbl VALUES (1, 2, 3);
                    452:     select * from tbl;
                    453:   }
                    454: } {1 2 3 1 2 3}
                    455: execsql {
                    456:   DROP TABLE tbl;
                    457: }
                    458: 
                    459: # 5.
                    460: execsql {
                    461:   CREATE TABLE tbl(a, b, c);
                    462:   CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl 
                    463:     BEGIN
                    464:       INSERT INTO tbl VALUES (1, 2, 3);
                    465:       INSERT INTO tbl VALUES (2, 2, 3);
                    466:       UPDATE tbl set b = 10 WHERE a = 1;
                    467:       DELETE FROM tbl WHERE a = 1;
                    468:       DELETE FROM tbl;
                    469:     END;
                    470: }
                    471: do_test trigger2-5 {
                    472:   execsql {
                    473:     INSERT INTO tbl VALUES(100, 200, 300);
                    474:   }
                    475:   db changes
                    476: } {1}
                    477: execsql {
                    478:   DROP TABLE tbl;
                    479: }
                    480: 
                    481: ifcapable conflict {
                    482:   # Handling of ON CONFLICT by INSERT statements inside triggers
                    483:   execsql {
                    484:     CREATE TABLE tbl (a primary key, b, c);
                    485:     CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
                    486:       INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
                    487:     END;
                    488:   }
                    489:   do_test trigger2-6.1a {
                    490:     execsql {
                    491:       BEGIN;
                    492:       INSERT INTO tbl values (1, 2, 3);
                    493:       SELECT * from tbl;
                    494:     }
                    495:   } {1 2 3}
                    496:   do_test trigger2-6.1b {
                    497:     catchsql {
                    498:       INSERT OR ABORT INTO tbl values (2, 2, 3);
                    499:     }
                    500:   } {1 {column a is not unique}}
                    501:   do_test trigger2-6.1c {
                    502:     execsql {
                    503:       SELECT * from tbl;
                    504:     }
                    505:   } {1 2 3}
                    506:   do_test trigger2-6.1d {
                    507:     catchsql {
                    508:       INSERT OR FAIL INTO tbl values (2, 2, 3);
                    509:     }
                    510:   } {1 {column a is not unique}}
                    511:   do_test trigger2-6.1e {
                    512:     execsql {
                    513:       SELECT * from tbl;
                    514:     }
                    515:   } {1 2 3 2 2 3}
                    516:   do_test trigger2-6.1f {
                    517:     execsql {
                    518:       INSERT OR REPLACE INTO tbl values (2, 2, 3);
                    519:       SELECT * from tbl;
                    520:     }
                    521:   } {1 2 3 2 0 0}
                    522:   do_test trigger2-6.1g {
                    523:     catchsql {
                    524:       INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
                    525:     }
                    526:   } {1 {column a is not unique}}
                    527:   do_test trigger2-6.1h {
                    528:     execsql {
                    529:       SELECT * from tbl;
                    530:     }
                    531:   } {}
                    532:   execsql {DELETE FROM tbl}
                    533:   
                    534:   
                    535:   # Handling of ON CONFLICT by UPDATE statements inside triggers
                    536:   execsql {
                    537:     INSERT INTO tbl values (4, 2, 3);
                    538:     INSERT INTO tbl values (6, 3, 4);
                    539:     CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
                    540:       UPDATE OR IGNORE tbl SET a = new.a, c = 10;
                    541:     END;
                    542:   }
                    543:   do_test trigger2-6.2a {
                    544:     execsql {
                    545:       BEGIN;
                    546:       UPDATE tbl SET a = 1 WHERE a = 4;
                    547:       SELECT * from tbl;
                    548:     }
                    549:   } {1 2 10 6 3 4}
                    550:   do_test trigger2-6.2b {
                    551:     catchsql {
                    552:       UPDATE OR ABORT tbl SET a = 4 WHERE a = 1;
                    553:     }
                    554:   } {1 {column a is not unique}}
                    555:   do_test trigger2-6.2c {
                    556:     execsql {
                    557:       SELECT * from tbl;
                    558:     }
                    559:   } {1 2 10 6 3 4}
                    560:   do_test trigger2-6.2d {
                    561:     catchsql {
                    562:       UPDATE OR FAIL tbl SET a = 4 WHERE a = 1;
                    563:     }
                    564:   } {1 {column a is not unique}}
                    565:   do_test trigger2-6.2e {
                    566:     execsql {
                    567:       SELECT * from tbl;
                    568:     }
                    569:   } {4 2 10 6 3 4}
                    570:   do_test trigger2-6.2f.1 {
                    571:     execsql {
                    572:       UPDATE OR REPLACE tbl SET a = 1 WHERE a = 4;
                    573:       SELECT * from tbl;
                    574:     }
                    575:   } {1 3 10}
                    576:   do_test trigger2-6.2f.2 {
                    577:     execsql {
                    578:       INSERT INTO tbl VALUES (2, 3, 4);
                    579:       SELECT * FROM tbl;
                    580:     }
                    581:   } {1 3 10 2 3 4}
                    582:   do_test trigger2-6.2g {
                    583:     catchsql {
                    584:       UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
                    585:     }
                    586:   } {1 {column a is not unique}}
                    587:   do_test trigger2-6.2h {
                    588:     execsql {
                    589:       SELECT * from tbl;
                    590:     }
                    591:   } {4 2 3 6 3 4}
                    592:   execsql {
                    593:     DROP TABLE tbl;
                    594:   }
                    595: } ; # ifcapable conflict
                    596: 
                    597: # 7. Triggers on views
                    598: ifcapable view {
                    599: 
                    600: do_test trigger2-7.1 {
                    601:   execsql {
                    602:   CREATE TABLE ab(a, b);
                    603:   CREATE TABLE cd(c, d);
                    604:   INSERT INTO ab VALUES (1, 2);
                    605:   INSERT INTO ab VALUES (0, 0);
                    606:   INSERT INTO cd VALUES (3, 4);
                    607: 
                    608:   CREATE TABLE tlog(ii INTEGER PRIMARY KEY, 
                    609:       olda, oldb, oldc, oldd, newa, newb, newc, newd);
                    610: 
                    611:   CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;
                    612: 
                    613:   CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
                    614:     INSERT INTO tlog VALUES(NULL, 
                    615:        old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
                    616:   END;
                    617:   CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
                    618:     INSERT INTO tlog VALUES(NULL, 
                    619:        old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
                    620:   END;
                    621: 
                    622:   CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
                    623:     INSERT INTO tlog VALUES(NULL, 
                    624:        old.a, old.b, old.c, old.d, 0, 0, 0, 0);
                    625:   END;
                    626:   CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
                    627:     INSERT INTO tlog VALUES(NULL, 
                    628:        old.a, old.b, old.c, old.d, 0, 0, 0, 0);
                    629:   END;
                    630: 
                    631:   CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
                    632:     INSERT INTO tlog VALUES(NULL, 
                    633:        0, 0, 0, 0, new.a, new.b, new.c, new.d);
                    634:   END;
                    635:    CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
                    636:     INSERT INTO tlog VALUES(NULL, 
                    637:        0, 0, 0, 0, new.a, new.b, new.c, new.d);
                    638:    END;
                    639:   }
                    640: } {};
                    641: 
                    642: do_test trigger2-7.2 {
                    643:   execsql {
                    644:     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
                    645:     DELETE FROM abcd WHERE a = 1;
                    646:     INSERT INTO abcd VALUES(10, 20, 30, 40);
                    647:     SELECT * FROM tlog;
                    648:   }
                    649: } [ list 1 1 2 3 4 100 25 3 4 \
                    650:          2 1 2 3 4 100 25 3 4 \
                    651:         3 1 2 3 4 0 0 0 0 \
                    652:         4 1 2 3 4 0 0 0 0 \
                    653:         5 0 0 0 0 10 20 30 40 \
                    654:         6 0 0 0 0 10 20 30 40 ]
                    655: 
                    656: do_test trigger2-7.3 {
                    657:   execsql {
                    658:     DELETE FROM tlog;
                    659:     INSERT INTO abcd VALUES(10, 20, 30, 40);
                    660:     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
                    661:     DELETE FROM abcd WHERE a = 1;
                    662:     SELECT * FROM tlog;
                    663:   }
                    664: } [ list \
                    665:    1 0 0 0 0 10 20 30 40 \
                    666:    2 0 0 0 0 10 20 30 40 \
                    667:    3 1 2 3 4 100 25 3 4 \
                    668:    4 1 2 3 4 100 25 3 4 \
                    669:    5 1 2 3 4 0 0 0 0 \
                    670:    6 1 2 3 4 0 0 0 0 \
                    671: ]
                    672: do_test trigger2-7.4 {
                    673:   execsql {
                    674:     DELETE FROM tlog;
                    675:     DELETE FROM abcd WHERE a = 1;
                    676:     INSERT INTO abcd VALUES(10, 20, 30, 40);
                    677:     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
                    678:     SELECT * FROM tlog;
                    679:   }
                    680: } [ list \
                    681:    1 1 2 3 4 0 0 0 0 \
                    682:    2 1 2 3 4 0 0 0 0 \
                    683:    3 0 0 0 0 10 20 30 40 \
                    684:    4 0 0 0 0 10 20 30 40 \
                    685:    5 1 2 3 4 100 25 3 4 \
                    686:    6 1 2 3 4 100 25 3 4 \
                    687: ]
                    688: 
                    689: do_test trigger2-8.1 {
                    690:   execsql {
                    691:     CREATE TABLE t1(a,b,c);
                    692:     INSERT INTO t1 VALUES(1,2,3);
                    693:     CREATE VIEW v1 AS
                    694:       SELECT a+b AS x, b+c AS y, a+c AS z FROM t1;
                    695:     SELECT * FROM v1;
                    696:   }
                    697: } {3 5 4}
                    698: do_test trigger2-8.2 {
                    699:   execsql {
                    700:     CREATE TABLE v1log(a,b,c,d,e,f);
                    701:     CREATE TRIGGER r1 INSTEAD OF DELETE ON v1 BEGIN
                    702:       INSERT INTO v1log VALUES(OLD.x,NULL,OLD.y,NULL,OLD.z,NULL);
                    703:     END;
                    704:     DELETE FROM v1 WHERE x=1;
                    705:     SELECT * FROM v1log;
                    706:   }
                    707: } {}
                    708: do_test trigger2-8.3 {
                    709:   execsql {
                    710:     DELETE FROM v1 WHERE x=3;
                    711:     SELECT * FROM v1log;
                    712:   }
                    713: } {3 {} 5 {} 4 {}}
                    714: do_test trigger2-8.4 {
                    715:   execsql {
                    716:     INSERT INTO t1 VALUES(4,5,6);
                    717:     DELETE FROM v1log;
                    718:     DELETE FROM v1 WHERE y=11;
                    719:     SELECT * FROM v1log;
                    720:   }
                    721: } {9 {} 11 {} 10 {}}
                    722: do_test trigger2-8.5 {
                    723:   execsql {
                    724:     CREATE TRIGGER r2 INSTEAD OF INSERT ON v1 BEGIN
                    725:       INSERT INTO v1log VALUES(NULL,NEW.x,NULL,NEW.y,NULL,NEW.z);
                    726:     END;
                    727:     DELETE FROM v1log;
                    728:     INSERT INTO v1 VALUES(1,2,3);
                    729:     SELECT * FROM v1log;
                    730:   }
                    731: } {{} 1 {} 2 {} 3}
                    732: do_test trigger2-8.6 {
                    733:   execsql {
                    734:     CREATE TRIGGER r3 INSTEAD OF UPDATE ON v1 BEGIN
                    735:       INSERT INTO v1log VALUES(OLD.x,NEW.x,OLD.y,NEW.y,OLD.z,NEW.z);
                    736:     END;
                    737:     DELETE FROM v1log;
                    738:     UPDATE v1 SET x=x+100, y=y+200, z=z+300;
                    739:     SELECT * FROM v1log;
                    740:   }
                    741: } {3 103 5 205 4 304 9 109 11 211 10 310}
                    742: 
                    743: # At one point the following was causing a segfault.
                    744: do_test trigger2-9.1 {
                    745:   execsql {
                    746:     CREATE TABLE t3(a TEXT, b TEXT);
                    747:     CREATE VIEW v3 AS SELECT t3.a FROM t3;
                    748:     CREATE TRIGGER trig1 INSTEAD OF DELETE ON v3 BEGIN
                    749:       SELECT 1;
                    750:     END;
                    751:     DELETE FROM v3 WHERE a = 1;
                    752:   }
                    753: } {}
                    754: 
                    755: } ;# ifcapable view
                    756: 
                    757: integrity_check trigger2-9.9
                    758: 
                    759: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>