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