trigger9.test 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. # 2008 January 1
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library. Specifically,
  12. # it tests some compiler optimizations for SQL statements featuring
  13. # triggers:
  14. #
  15. #
  16. #
  17. # trigger9-1.* - Test that if there are no references to OLD.* cols, or a
  18. # reference to only OLD.rowid, the data is not loaded.
  19. #
  20. # trigger9-2.* - Test that for NEW.* records populated by UPDATE
  21. # statements, unused fields are populated with NULL values.
  22. #
  23. # trigger9-3.* - Test that the temporary tables used for OLD.* references
  24. # in "INSTEAD OF" triggers have NULL values in unused
  25. # fields.
  26. #
  27. set testdir [file dirname $argv0]
  28. source $testdir/tester.tcl
  29. ifcapable {!trigger} {
  30. finish_test
  31. return
  32. }
  33. proc has_rowdata {sql} {
  34. expr {[lsearch [execsql "explain $sql"] RowData]>=0}
  35. }
  36. do_test trigger9-1.1 {
  37. execsql {
  38. PRAGMA page_size = 1024;
  39. CREATE TABLE t1(x, y, z);
  40. INSERT INTO t1 VALUES('1', randstr(10000,10000), '2');
  41. INSERT INTO t1 VALUES('2', randstr(10000,10000), '4');
  42. INSERT INTO t1 VALUES('3', randstr(10000,10000), '6');
  43. CREATE TABLE t2(x);
  44. }
  45. } {}
  46. do_test trigger9-1.2.1 {
  47. execsql {
  48. BEGIN;
  49. CREATE TRIGGER trig1 BEFORE DELETE ON t1 BEGIN
  50. INSERT INTO t2 VALUES(old.rowid);
  51. END;
  52. DELETE FROM t1;
  53. SELECT * FROM t2;
  54. }
  55. } {1 2 3}
  56. do_test trigger9-1.2.3 {
  57. has_rowdata {DELETE FROM t1}
  58. } 0
  59. do_test trigger9-1.2.4 { execsql { ROLLBACK } } {}
  60. do_test trigger9-1.3.1 {
  61. execsql {
  62. BEGIN;
  63. CREATE TRIGGER trig1 BEFORE DELETE ON t1 BEGIN
  64. INSERT INTO t2 VALUES(old.x);
  65. END;
  66. DELETE FROM t1;
  67. SELECT * FROM t2;
  68. }
  69. } {1 2 3}
  70. do_test trigger9-1.3.2 {
  71. has_rowdata {DELETE FROM t1}
  72. } 0
  73. do_test trigger9-1.3.3 { execsql { ROLLBACK } } {}
  74. do_test trigger9-1.4.1 {
  75. execsql {
  76. BEGIN;
  77. CREATE TRIGGER trig1 BEFORE DELETE ON t1 WHEN old.x='1' BEGIN
  78. INSERT INTO t2 VALUES(old.rowid);
  79. END;
  80. DELETE FROM t1;
  81. SELECT * FROM t2;
  82. }
  83. } {1}
  84. do_test trigger9-1.4.2 {
  85. has_rowdata {DELETE FROM t1}
  86. } 0
  87. do_test trigger9-1.4.3 { execsql { ROLLBACK } } {}
  88. do_test trigger9-1.5.1 {
  89. execsql {
  90. BEGIN;
  91. CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
  92. INSERT INTO t2 VALUES(old.rowid);
  93. END;
  94. UPDATE t1 SET y = '';
  95. SELECT * FROM t2;
  96. }
  97. } {1 2 3}
  98. do_test trigger9-1.5.2 {
  99. has_rowdata {UPDATE t1 SET y = ''}
  100. } 0
  101. do_test trigger9-1.5.3 { execsql { ROLLBACK } } {}
  102. do_test trigger9-1.6.1 {
  103. execsql {
  104. BEGIN;
  105. CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
  106. INSERT INTO t2 VALUES(old.x);
  107. END;
  108. UPDATE t1 SET y = '';
  109. SELECT * FROM t2;
  110. }
  111. } {1 2 3}
  112. do_test trigger9-1.6.2 {
  113. has_rowdata {UPDATE t1 SET y = ''}
  114. } 0
  115. do_test trigger9-1.6.3 { execsql { ROLLBACK } } {}
  116. do_test trigger9-1.7.1 {
  117. execsql {
  118. BEGIN;
  119. CREATE TRIGGER trig1 BEFORE UPDATE ON t1 WHEN old.x>='2' BEGIN
  120. INSERT INTO t2 VALUES(old.x);
  121. END;
  122. UPDATE t1 SET y = '';
  123. SELECT * FROM t2;
  124. }
  125. } {2 3}
  126. do_test trigger9-1.7.2 {
  127. has_rowdata {UPDATE t1 SET y = ''}
  128. } 0
  129. do_test trigger9-1.7.3 { execsql { ROLLBACK } } {}
  130. do_test trigger9-3.1 {
  131. execsql {
  132. CREATE TABLE t3(a, b);
  133. INSERT INTO t3 VALUES(1, 'one');
  134. INSERT INTO t3 VALUES(2, 'two');
  135. INSERT INTO t3 VALUES(3, 'three');
  136. }
  137. } {}
  138. do_test trigger9-3.2 {
  139. execsql {
  140. BEGIN;
  141. CREATE VIEW v1 AS SELECT * FROM t3;
  142. CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
  143. INSERT INTO t2 VALUES(old.a);
  144. END;
  145. UPDATE v1 SET b = 'hello';
  146. SELECT * FROM t2;
  147. ROLLBACK;
  148. }
  149. } {1 2 3}
  150. do_test trigger9-3.3 {
  151. # In this test the 'c' column of the view is not required by
  152. # the INSTEAD OF trigger, but the expression is reused internally as
  153. # part of the view's WHERE clause. Check that this does not cause
  154. # a problem.
  155. #
  156. execsql {
  157. BEGIN;
  158. CREATE VIEW v1 AS SELECT a, b AS c FROM t3 WHERE c > 'one';
  159. CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
  160. INSERT INTO t2 VALUES(old.a);
  161. END;
  162. UPDATE v1 SET c = 'hello';
  163. SELECT * FROM t2;
  164. ROLLBACK;
  165. }
  166. } {2 3}
  167. do_test trigger9-3.4 {
  168. execsql {
  169. BEGIN;
  170. INSERT INTO t3 VALUES(3, 'three');
  171. INSERT INTO t3 VALUES(3, 'four');
  172. CREATE VIEW v1 AS SELECT DISTINCT a, b FROM t3;
  173. CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
  174. INSERT INTO t2 VALUES(old.a);
  175. END;
  176. UPDATE v1 SET b = 'hello';
  177. SELECT * FROM t2;
  178. ROLLBACK;
  179. }
  180. } {1 2 3 3}
  181. ifcapable compound {
  182. do_test trigger9-3.5 {
  183. execsql {
  184. BEGIN;
  185. INSERT INTO t3 VALUES(1, 'uno');
  186. CREATE VIEW v1 AS SELECT a, b FROM t3 EXCEPT SELECT 1, 'one';
  187. CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
  188. INSERT INTO t2 VALUES(old.a);
  189. END;
  190. UPDATE v1 SET b = 'hello';
  191. SELECT * FROM t2;
  192. ROLLBACK;
  193. }
  194. } {1 2 3}
  195. do_test trigger9-3.6 {
  196. execsql {
  197. BEGIN;
  198. INSERT INTO t3 VALUES(1, 'zero');
  199. CREATE VIEW v1 AS
  200. SELECT sum(a) AS a, max(b) AS b FROM t3 GROUP BY t3.a HAVING b>'two';
  201. CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
  202. INSERT INTO t2 VALUES(old.a);
  203. END;
  204. UPDATE v1 SET b = 'hello';
  205. SELECT * FROM t2;
  206. ROLLBACK;
  207. }
  208. } {2}
  209. }
  210. finish_test