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