trigger2.test 19 KB

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