1
0

lastinsert.test 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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. # Tests to make sure that value returned by last_insert_rowid() (LIRID)
  11. # is updated properly, especially inside triggers
  12. #
  13. # Note 1: insert into table is now the only statement which changes LIRID
  14. # Note 2: upon entry into before or instead of triggers,
  15. # LIRID is unchanged (rather than -1)
  16. # Note 3: LIRID is changed within the context of a trigger,
  17. # but is restored once the trigger exits
  18. # Note 4: LIRID is not changed by an insert into a view (since everything
  19. # is done within instead of trigger context)
  20. #
  21. set testdir [file dirname $argv0]
  22. source $testdir/tester.tcl
  23. # ----------------------------------------------------------------------------
  24. # 1.x - basic tests (no triggers)
  25. # LIRID changed properly after an insert into a table
  26. do_test lastinsert-1.1 {
  27. catchsql {
  28. create table t1 (k integer primary key);
  29. insert into t1 values (1);
  30. insert into t1 values (NULL);
  31. insert into t1 values (NULL);
  32. select last_insert_rowid();
  33. }
  34. } {0 3}
  35. # LIRID unchanged after an update on a table
  36. do_test lastinsert-1.2 {
  37. catchsql {
  38. update t1 set k=4 where k=2;
  39. select last_insert_rowid();
  40. }
  41. } {0 3}
  42. # LIRID unchanged after a delete from a table
  43. do_test lastinsert-1.3 {
  44. catchsql {
  45. delete from t1 where k=4;
  46. select last_insert_rowid();
  47. }
  48. } {0 3}
  49. # LIRID unchanged after create table/view statements
  50. do_test lastinsert-1.4.1 {
  51. catchsql {
  52. create table t2 (k integer primary key, val1, val2, val3);
  53. select last_insert_rowid();
  54. }
  55. } {0 3}
  56. ifcapable view {
  57. do_test lastinsert-1.4.2 {
  58. catchsql {
  59. create view v as select * from t1;
  60. select last_insert_rowid();
  61. }
  62. } {0 3}
  63. } ;# ifcapable view
  64. # All remaining tests involve triggers. Skip them if triggers are not
  65. # supported in this build.
  66. #
  67. ifcapable {!trigger} {
  68. finish_test
  69. return
  70. }
  71. # ----------------------------------------------------------------------------
  72. # 2.x - tests with after insert trigger
  73. # LIRID changed properly after an insert into table containing an after trigger
  74. do_test lastinsert-2.1 {
  75. catchsql {
  76. delete from t2;
  77. create trigger r1 after insert on t1 for each row begin
  78. insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL);
  79. update t2 set k=k+10, val2=100+last_insert_rowid();
  80. update t2 set val3=1000+last_insert_rowid();
  81. end;
  82. insert into t1 values (13);
  83. select last_insert_rowid();
  84. }
  85. } {0 13}
  86. # LIRID equals NEW.k upon entry into after insert trigger
  87. do_test lastinsert-2.2 {
  88. catchsql {
  89. select val1 from t2;
  90. }
  91. } {0 13}
  92. # LIRID changed properly by insert within context of after insert trigger
  93. do_test lastinsert-2.3 {
  94. catchsql {
  95. select val2 from t2;
  96. }
  97. } {0 126}
  98. # LIRID unchanged by update within context of after insert trigger
  99. do_test lastinsert-2.4 {
  100. catchsql {
  101. select val3 from t2;
  102. }
  103. } {0 1026}
  104. # ----------------------------------------------------------------------------
  105. # 3.x - tests with after update trigger
  106. # LIRID not changed after an update onto a table containing an after trigger
  107. do_test lastinsert-3.1 {
  108. catchsql {
  109. delete from t2;
  110. drop trigger r1;
  111. create trigger r1 after update on t1 for each row begin
  112. insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL);
  113. update t2 set k=k+10, val2=100+last_insert_rowid();
  114. update t2 set val3=1000+last_insert_rowid();
  115. end;
  116. update t1 set k=14 where k=3;
  117. select last_insert_rowid();
  118. }
  119. } {0 13}
  120. # LIRID unchanged upon entry into after update trigger
  121. do_test lastinsert-3.2 {
  122. catchsql {
  123. select val1 from t2;
  124. }
  125. } {0 13}
  126. # LIRID changed properly by insert within context of after update trigger
  127. do_test lastinsert-3.3 {
  128. catchsql {
  129. select val2 from t2;
  130. }
  131. } {0 128}
  132. # LIRID unchanged by update within context of after update trigger
  133. do_test lastinsert-3.4 {
  134. catchsql {
  135. select val3 from t2;
  136. }
  137. } {0 1028}
  138. # ----------------------------------------------------------------------------
  139. # 4.x - tests with instead of insert trigger
  140. # These may not be run if either views or triggers were disabled at
  141. # compile-time
  142. ifcapable {view && trigger} {
  143. # LIRID not changed after an insert into view containing an instead of trigger
  144. do_test lastinsert-4.1 {
  145. catchsql {
  146. delete from t2;
  147. drop trigger r1;
  148. create trigger r1 instead of insert on v for each row begin
  149. insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL);
  150. update t2 set k=k+10, val2=100+last_insert_rowid();
  151. update t2 set val3=1000+last_insert_rowid();
  152. end;
  153. insert into v values (15);
  154. select last_insert_rowid();
  155. }
  156. } {0 13}
  157. # LIRID unchanged upon entry into instead of trigger
  158. do_test lastinsert-4.2 {
  159. catchsql {
  160. select val1 from t2;
  161. }
  162. } {0 13}
  163. # LIRID changed properly by insert within context of instead of trigger
  164. do_test lastinsert-4.3 {
  165. catchsql {
  166. select val2 from t2;
  167. }
  168. } {0 130}
  169. # LIRID unchanged by update within context of instead of trigger
  170. do_test lastinsert-4.4 {
  171. catchsql {
  172. select val3 from t2;
  173. }
  174. } {0 1030}
  175. } ;# ifcapable (view && trigger)
  176. # ----------------------------------------------------------------------------
  177. # 5.x - tests with before delete trigger
  178. # LIRID not changed after a delete on a table containing a before trigger
  179. do_test lastinsert-5.1 {
  180. catchsql {
  181. drop trigger r1; -- This was not created if views are disabled.
  182. }
  183. catchsql {
  184. delete from t2;
  185. create trigger r1 before delete on t1 for each row begin
  186. insert into t2 values (77, last_insert_rowid(), NULL, NULL);
  187. update t2 set k=k+10, val2=100+last_insert_rowid();
  188. update t2 set val3=1000+last_insert_rowid();
  189. end;
  190. delete from t1 where k=1;
  191. select last_insert_rowid();
  192. }
  193. } {0 13}
  194. # LIRID unchanged upon entry into delete trigger
  195. do_test lastinsert-5.2 {
  196. catchsql {
  197. select val1 from t2;
  198. }
  199. } {0 13}
  200. # LIRID changed properly by insert within context of delete trigger
  201. do_test lastinsert-5.3 {
  202. catchsql {
  203. select val2 from t2;
  204. }
  205. } {0 177}
  206. # LIRID unchanged by update within context of delete trigger
  207. do_test lastinsert-5.4 {
  208. catchsql {
  209. select val3 from t2;
  210. }
  211. } {0 1077}
  212. # ----------------------------------------------------------------------------
  213. # 6.x - tests with instead of update trigger
  214. # These tests may not run if either views or triggers are disabled.
  215. ifcapable {view && trigger} {
  216. # LIRID not changed after an update on a view containing an instead of trigger
  217. do_test lastinsert-6.1 {
  218. catchsql {
  219. delete from t2;
  220. drop trigger r1;
  221. create trigger r1 instead of update on v for each row begin
  222. insert into t2 values (NEW.k*2, last_insert_rowid(), NULL, NULL);
  223. update t2 set k=k+10, val2=100+last_insert_rowid();
  224. update t2 set val3=1000+last_insert_rowid();
  225. end;
  226. update v set k=16 where k=14;
  227. select last_insert_rowid();
  228. }
  229. } {0 13}
  230. # LIRID unchanged upon entry into instead of trigger
  231. do_test lastinsert-6.2 {
  232. catchsql {
  233. select val1 from t2;
  234. }
  235. } {0 13}
  236. # LIRID changed properly by insert within context of instead of trigger
  237. do_test lastinsert-6.3 {
  238. catchsql {
  239. select val2 from t2;
  240. }
  241. } {0 132}
  242. # LIRID unchanged by update within context of instead of trigger
  243. do_test lastinsert-6.4 {
  244. catchsql {
  245. select val3 from t2;
  246. }
  247. } {0 1032}
  248. } ;# ifcapable (view && trigger)
  249. # ----------------------------------------------------------------------------
  250. # 7.x - complex tests with temporary tables and nested instead of triggers
  251. # These do not run if views or triggers are disabled.
  252. ifcapable {trigger && view && tempdb} {
  253. do_test lastinsert-7.1 {
  254. catchsql {
  255. drop table t1; drop table t2; drop trigger r1;
  256. create temp table t1 (k integer primary key);
  257. create temp table t2 (k integer primary key);
  258. create temp view v1 as select * from t1;
  259. create temp view v2 as select * from t2;
  260. create temp table rid (k integer primary key, rin, rout);
  261. insert into rid values (1, NULL, NULL);
  262. insert into rid values (2, NULL, NULL);
  263. create temp trigger r1 instead of insert on v1 for each row begin
  264. update rid set rin=last_insert_rowid() where k=1;
  265. insert into t1 values (100+NEW.k);
  266. insert into v2 values (100+last_insert_rowid());
  267. update rid set rout=last_insert_rowid() where k=1;
  268. end;
  269. create temp trigger r2 instead of insert on v2 for each row begin
  270. update rid set rin=last_insert_rowid() where k=2;
  271. insert into t2 values (1000+NEW.k);
  272. update rid set rout=last_insert_rowid() where k=2;
  273. end;
  274. insert into t1 values (77);
  275. select last_insert_rowid();
  276. }
  277. } {0 77}
  278. do_test lastinsert-7.2 {
  279. catchsql {
  280. insert into v1 values (5);
  281. select last_insert_rowid();
  282. }
  283. } {0 77}
  284. do_test lastinsert-7.3 {
  285. catchsql {
  286. select rin from rid where k=1;
  287. }
  288. } {0 77}
  289. do_test lastinsert-7.4 {
  290. catchsql {
  291. select rout from rid where k=1;
  292. }
  293. } {0 105}
  294. do_test lastinsert-7.5 {
  295. catchsql {
  296. select rin from rid where k=2;
  297. }
  298. } {0 105}
  299. do_test lastinsert-7.6 {
  300. catchsql {
  301. select rout from rid where k=2;
  302. }
  303. } {0 1205}
  304. do_test lastinsert-8.1 {
  305. db close
  306. sqlite3 db test.db
  307. execsql {
  308. CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
  309. CREATE TABLE t3(a, b);
  310. CREATE TRIGGER after_t2 AFTER INSERT ON t2 BEGIN
  311. INSERT INTO t3 VALUES(new.x, new.y);
  312. END;
  313. INSERT INTO t2 VALUES(5000000000, 1);
  314. SELECT last_insert_rowid();
  315. }
  316. } 5000000000
  317. do_test lastinsert-9.1 {
  318. db eval {INSERT INTO t2 VALUES(123456789012345,0)}
  319. db last_insert_rowid
  320. } {123456789012345}
  321. } ;# ifcapable (view && trigger)
  322. finish_test