os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/lastinsert.test
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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