os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/trigger1.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
# This file tests creating and dropping triggers, and interaction thereof
sl@0
    11
# with the database COMMIT/ROLLBACK logic.
sl@0
    12
#
sl@0
    13
# 1. CREATE and DROP TRIGGER tests
sl@0
    14
# trig-1.1: Error if table does not exist
sl@0
    15
# trig-1.2: Error if trigger already exists
sl@0
    16
# trig-1.3: Created triggers are deleted if the transaction is rolled back
sl@0
    17
# trig-1.4: DROP TRIGGER removes trigger
sl@0
    18
# trig-1.5: Dropped triggers are restored if the transaction is rolled back
sl@0
    19
# trig-1.6: Error if dropped trigger doesn't exist
sl@0
    20
# trig-1.7: Dropping the table automatically drops all triggers
sl@0
    21
# trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
sl@0
    22
# trig-1.9: Ensure that we cannot create a trigger on sqlite_master
sl@0
    23
# trig-1.10:
sl@0
    24
# trig-1.11:
sl@0
    25
# trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
sl@0
    26
# trig-1.13: Ensure that AFTER triggers cannot be created on views
sl@0
    27
# trig-1.14: Ensure that BEFORE triggers cannot be created on views
sl@0
    28
#
sl@0
    29
sl@0
    30
set testdir [file dirname $argv0]
sl@0
    31
source $testdir/tester.tcl
sl@0
    32
ifcapable {!trigger} {
sl@0
    33
  finish_test
sl@0
    34
  return
sl@0
    35
}
sl@0
    36
sl@0
    37
do_test trigger1-1.1.1 {
sl@0
    38
   catchsql {
sl@0
    39
     CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
sl@0
    40
       SELECT * from sqlite_master;
sl@0
    41
     END;
sl@0
    42
   } 
sl@0
    43
} {1 {no such table: main.no_such_table}}
sl@0
    44
sl@0
    45
ifcapable tempdb {
sl@0
    46
  do_test trigger1-1.1.2 {
sl@0
    47
     catchsql {
sl@0
    48
       CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN
sl@0
    49
         SELECT * from sqlite_master;
sl@0
    50
       END;
sl@0
    51
     } 
sl@0
    52
  } {1 {no such table: no_such_table}}
sl@0
    53
}
sl@0
    54
sl@0
    55
execsql {
sl@0
    56
    CREATE TABLE t1(a);
sl@0
    57
}
sl@0
    58
do_test trigger1-1.1.3 {
sl@0
    59
  catchsql {
sl@0
    60
     CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN
sl@0
    61
        SELECT * FROM sqlite_master;
sl@0
    62
     END;
sl@0
    63
  }
sl@0
    64
} {1 {near "STATEMENT": syntax error}}
sl@0
    65
execsql {
sl@0
    66
	CREATE TRIGGER tr1 INSERT ON t1 BEGIN
sl@0
    67
	  INSERT INTO t1 values(1);
sl@0
    68
 	END;
sl@0
    69
}
sl@0
    70
do_test trigger1-1.2.0 {
sl@0
    71
    catchsql {
sl@0
    72
	CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN
sl@0
    73
	    SELECT * FROM sqlite_master;
sl@0
    74
 	END
sl@0
    75
     }
sl@0
    76
} {0 {}}
sl@0
    77
do_test trigger1-1.2.1 {
sl@0
    78
    catchsql {
sl@0
    79
	CREATE TRIGGER tr1 DELETE ON t1 BEGIN
sl@0
    80
	    SELECT * FROM sqlite_master;
sl@0
    81
 	END
sl@0
    82
     }
sl@0
    83
} {1 {trigger tr1 already exists}}
sl@0
    84
do_test trigger1-1.2.2 {
sl@0
    85
    catchsql {
sl@0
    86
	CREATE TRIGGER "tr1" DELETE ON t1 BEGIN
sl@0
    87
	    SELECT * FROM sqlite_master;
sl@0
    88
 	END
sl@0
    89
     }
sl@0
    90
} {1 {trigger "tr1" already exists}}
sl@0
    91
do_test trigger1-1.2.3 {
sl@0
    92
    catchsql {
sl@0
    93
	CREATE TRIGGER [tr1] DELETE ON t1 BEGIN
sl@0
    94
	    SELECT * FROM sqlite_master;
sl@0
    95
 	END
sl@0
    96
     }
sl@0
    97
} {1 {trigger [tr1] already exists}}
sl@0
    98
sl@0
    99
do_test trigger1-1.3 {
sl@0
   100
    catchsql {
sl@0
   101
	BEGIN;
sl@0
   102
	CREATE TRIGGER tr2 INSERT ON t1 BEGIN
sl@0
   103
	    SELECT * from sqlite_master; END;
sl@0
   104
        ROLLBACK;
sl@0
   105
	CREATE TRIGGER tr2 INSERT ON t1 BEGIN
sl@0
   106
	    SELECT * from sqlite_master; END;
sl@0
   107
    }
sl@0
   108
} {0 {}}
sl@0
   109
sl@0
   110
do_test trigger1-1.4 {
sl@0
   111
    catchsql {
sl@0
   112
	DROP TRIGGER IF EXISTS tr1;
sl@0
   113
	CREATE TRIGGER tr1 DELETE ON t1 BEGIN
sl@0
   114
	    SELECT * FROM sqlite_master;
sl@0
   115
	END
sl@0
   116
    }
sl@0
   117
} {0 {}}
sl@0
   118
sl@0
   119
do_test trigger1-1.5 {
sl@0
   120
    execsql {
sl@0
   121
	BEGIN;
sl@0
   122
	DROP TRIGGER tr2;
sl@0
   123
	ROLLBACK;
sl@0
   124
	DROP TRIGGER tr2;
sl@0
   125
    }
sl@0
   126
} {}
sl@0
   127
sl@0
   128
do_test trigger1-1.6.1 {
sl@0
   129
    catchsql {
sl@0
   130
	DROP TRIGGER IF EXISTS biggles;
sl@0
   131
    }
sl@0
   132
} {0 {}}
sl@0
   133
sl@0
   134
do_test trigger1-1.6.2 {
sl@0
   135
    catchsql {
sl@0
   136
	DROP TRIGGER biggles;
sl@0
   137
    }
sl@0
   138
} {1 {no such trigger: biggles}}
sl@0
   139
sl@0
   140
do_test trigger1-1.7 {
sl@0
   141
    catchsql {
sl@0
   142
	DROP TABLE t1;
sl@0
   143
	DROP TRIGGER tr1;
sl@0
   144
    }
sl@0
   145
} {1 {no such trigger: tr1}}
sl@0
   146
sl@0
   147
ifcapable tempdb {
sl@0
   148
  execsql {
sl@0
   149
    CREATE TEMP TABLE temp_table(a);
sl@0
   150
  }
sl@0
   151
  do_test trigger1-1.8 {
sl@0
   152
    execsql {
sl@0
   153
  	CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
sl@0
   154
  	    SELECT * from sqlite_master;
sl@0
   155
  	END;
sl@0
   156
  	SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
sl@0
   157
    } 
sl@0
   158
  } {0}
sl@0
   159
}
sl@0
   160
sl@0
   161
do_test trigger1-1.9 {
sl@0
   162
  catchsql {
sl@0
   163
    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
sl@0
   164
       SELECT * FROM sqlite_master;
sl@0
   165
    END;
sl@0
   166
  }
sl@0
   167
} {1 {cannot create trigger on system table}}
sl@0
   168
sl@0
   169
# Check to make sure that a DELETE statement within the body of
sl@0
   170
# a trigger does not mess up the DELETE that caused the trigger to
sl@0
   171
# run in the first place.
sl@0
   172
#
sl@0
   173
do_test trigger1-1.10 {
sl@0
   174
  execsql {
sl@0
   175
    create table t1(a,b);
sl@0
   176
    insert into t1 values(1,'a');
sl@0
   177
    insert into t1 values(2,'b');
sl@0
   178
    insert into t1 values(3,'c');
sl@0
   179
    insert into t1 values(4,'d');
sl@0
   180
    create trigger r1 after delete on t1 for each row begin
sl@0
   181
      delete from t1 WHERE a=old.a+2;
sl@0
   182
    end;
sl@0
   183
    delete from t1 where a=1 OR a=3;
sl@0
   184
    select * from t1;
sl@0
   185
    drop table t1;
sl@0
   186
  }
sl@0
   187
} {2 b 4 d}
sl@0
   188
sl@0
   189
do_test trigger1-1.11 {
sl@0
   190
  execsql {
sl@0
   191
    create table t1(a,b);
sl@0
   192
    insert into t1 values(1,'a');
sl@0
   193
    insert into t1 values(2,'b');
sl@0
   194
    insert into t1 values(3,'c');
sl@0
   195
    insert into t1 values(4,'d');
sl@0
   196
    create trigger r1 after update on t1 for each row begin
sl@0
   197
      delete from t1 WHERE a=old.a+2;
sl@0
   198
    end;
sl@0
   199
    update t1 set b='x-' || b where a=1 OR a=3;
sl@0
   200
    select * from t1;
sl@0
   201
    drop table t1;
sl@0
   202
  }
sl@0
   203
} {1 x-a 2 b 4 d}
sl@0
   204
sl@0
   205
# Ensure that we cannot create INSTEAD OF triggers on tables
sl@0
   206
do_test trigger1-1.12 {
sl@0
   207
  catchsql {
sl@0
   208
    create table t1(a,b);
sl@0
   209
    create trigger t1t instead of update on t1 for each row begin
sl@0
   210
      delete from t1 WHERE a=old.a+2;
sl@0
   211
    end;
sl@0
   212
  }
sl@0
   213
} {1 {cannot create INSTEAD OF trigger on table: main.t1}}
sl@0
   214
sl@0
   215
ifcapable view {
sl@0
   216
# Ensure that we cannot create BEFORE triggers on views
sl@0
   217
do_test trigger1-1.13 {
sl@0
   218
  catchsql {
sl@0
   219
    create view v1 as select * from t1;
sl@0
   220
    create trigger v1t before update on v1 for each row begin
sl@0
   221
      delete from t1 WHERE a=old.a+2;
sl@0
   222
    end;
sl@0
   223
  }
sl@0
   224
} {1 {cannot create BEFORE trigger on view: main.v1}}
sl@0
   225
# Ensure that we cannot create AFTER triggers on views
sl@0
   226
do_test trigger1-1.14 {
sl@0
   227
  catchsql {
sl@0
   228
    drop view v1;
sl@0
   229
    create view v1 as select * from t1;
sl@0
   230
    create trigger v1t AFTER update on v1 for each row begin
sl@0
   231
      delete from t1 WHERE a=old.a+2;
sl@0
   232
    end;
sl@0
   233
  }
sl@0
   234
} {1 {cannot create AFTER trigger on view: main.v1}}
sl@0
   235
} ;# ifcapable view
sl@0
   236
sl@0
   237
# Check for memory leaks in the trigger parser
sl@0
   238
#
sl@0
   239
do_test trigger1-2.1 {
sl@0
   240
  catchsql {
sl@0
   241
    CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
sl@0
   242
      SELECT * FROM;  -- Syntax error
sl@0
   243
    END;
sl@0
   244
  }
sl@0
   245
} {1 {near ";": syntax error}}
sl@0
   246
do_test trigger1-2.2 {
sl@0
   247
  catchsql {
sl@0
   248
    CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
sl@0
   249
      SELECT * FROM t1;
sl@0
   250
      SELECT * FROM;  -- Syntax error
sl@0
   251
    END;
sl@0
   252
  }
sl@0
   253
} {1 {near ";": syntax error}}
sl@0
   254
sl@0
   255
# Create a trigger that refers to a table that might not exist.
sl@0
   256
#
sl@0
   257
ifcapable tempdb {
sl@0
   258
  do_test trigger1-3.1 {
sl@0
   259
    execsql {
sl@0
   260
      CREATE TEMP TABLE t2(x,y);
sl@0
   261
    }
sl@0
   262
    catchsql {
sl@0
   263
      CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
sl@0
   264
        INSERT INTO t2 VALUES(NEW.a,NEW.b);
sl@0
   265
      END;
sl@0
   266
    }
sl@0
   267
  } {0 {}}
sl@0
   268
  do_test trigger-3.2 {
sl@0
   269
    catchsql {
sl@0
   270
      INSERT INTO t1 VALUES(1,2);
sl@0
   271
      SELECT * FROM t2;
sl@0
   272
    }
sl@0
   273
  } {1 {no such table: main.t2}}
sl@0
   274
  do_test trigger-3.3 {
sl@0
   275
    db close
sl@0
   276
    set rc [catch {sqlite3 db test.db} err]
sl@0
   277
    if {$rc} {lappend rc $err}
sl@0
   278
    set rc
sl@0
   279
  } {0}
sl@0
   280
  do_test trigger-3.4 {
sl@0
   281
    catchsql {
sl@0
   282
      INSERT INTO t1 VALUES(1,2);
sl@0
   283
      SELECT * FROM t2;
sl@0
   284
    }
sl@0
   285
  } {1 {no such table: main.t2}}
sl@0
   286
  do_test trigger-3.5 {
sl@0
   287
    catchsql {
sl@0
   288
      CREATE TEMP TABLE t2(x,y);
sl@0
   289
      INSERT INTO t1 VALUES(1,2);
sl@0
   290
      SELECT * FROM t2;
sl@0
   291
    }
sl@0
   292
  } {1 {no such table: main.t2}}
sl@0
   293
  do_test trigger-3.6 {
sl@0
   294
    catchsql {
sl@0
   295
      DROP TRIGGER r1;
sl@0
   296
      CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
sl@0
   297
        INSERT INTO t2 VALUES(NEW.a,NEW.b);
sl@0
   298
      END;
sl@0
   299
      INSERT INTO t1 VALUES(1,2);
sl@0
   300
      SELECT * FROM t2;
sl@0
   301
    }
sl@0
   302
  } {0 {1 2}}
sl@0
   303
  do_test trigger-3.7 {
sl@0
   304
    execsql {
sl@0
   305
      DROP TABLE t2;
sl@0
   306
      CREATE TABLE t2(x,y);
sl@0
   307
      SELECT * FROM t2;
sl@0
   308
    }
sl@0
   309
  } {}
sl@0
   310
sl@0
   311
  # There are two versions of trigger-3.8 and trigger-3.9. One that uses
sl@0
   312
  # compound SELECT statements, and another that does not.
sl@0
   313
  ifcapable compound {
sl@0
   314
  do_test trigger1-3.8 {
sl@0
   315
    execsql {
sl@0
   316
      INSERT INTO t1 VALUES(3,4);
sl@0
   317
      SELECT * FROM t1 UNION ALL SELECT * FROM t2;
sl@0
   318
    }
sl@0
   319
  } {1 2 3 4 3 4}
sl@0
   320
  do_test trigger1-3.9 {
sl@0
   321
    db close
sl@0
   322
    sqlite3 db test.db
sl@0
   323
    execsql {
sl@0
   324
      INSERT INTO t1 VALUES(5,6);
sl@0
   325
      SELECT * FROM t1 UNION ALL SELECT * FROM t2;
sl@0
   326
    }
sl@0
   327
  } {1 2 3 4 5 6 3 4}
sl@0
   328
  } ;# ifcapable compound
sl@0
   329
  ifcapable !compound {
sl@0
   330
  do_test trigger1-3.8 {
sl@0
   331
    execsql {
sl@0
   332
      INSERT INTO t1 VALUES(3,4);
sl@0
   333
      SELECT * FROM t1; 
sl@0
   334
      SELECT * FROM t2;
sl@0
   335
    }
sl@0
   336
  } {1 2 3 4 3 4}
sl@0
   337
  do_test trigger1-3.9 {
sl@0
   338
    db close
sl@0
   339
    sqlite3 db test.db
sl@0
   340
    execsql {
sl@0
   341
      INSERT INTO t1 VALUES(5,6);
sl@0
   342
      SELECT * FROM t1;
sl@0
   343
      SELECT * FROM t2;
sl@0
   344
    }
sl@0
   345
  } {1 2 3 4 5 6 3 4}
sl@0
   346
  } ;# ifcapable !compound
sl@0
   347
sl@0
   348
  do_test trigger1-4.1 {
sl@0
   349
    execsql {
sl@0
   350
      CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN
sl@0
   351
        INSERT INTO t2 VALUES(NEW.a,NEW.b);
sl@0
   352
      END;
sl@0
   353
      INSERT INTO t1 VALUES(7,8);
sl@0
   354
      SELECT * FROM t2;
sl@0
   355
    }
sl@0
   356
  } {3 4 7 8}
sl@0
   357
  do_test trigger1-4.2 {
sl@0
   358
    sqlite3 db2 test.db
sl@0
   359
    execsql {
sl@0
   360
      INSERT INTO t1 VALUES(9,10);
sl@0
   361
    } db2;
sl@0
   362
    db2 close
sl@0
   363
    execsql {
sl@0
   364
      SELECT * FROM t2;
sl@0
   365
    }
sl@0
   366
  } {3 4 7 8}
sl@0
   367
  do_test trigger1-4.3 {
sl@0
   368
    execsql {
sl@0
   369
      DROP TABLE t1;
sl@0
   370
      SELECT * FROM t2;
sl@0
   371
    };
sl@0
   372
  } {3 4 7 8}
sl@0
   373
  do_test trigger1-4.4 {
sl@0
   374
    db close
sl@0
   375
    sqlite3 db test.db
sl@0
   376
    execsql {
sl@0
   377
      SELECT * FROM t2;
sl@0
   378
    };
sl@0
   379
  } {3 4 7 8}
sl@0
   380
} else {
sl@0
   381
  execsql {
sl@0
   382
    CREATE TABLE t2(x,y);
sl@0
   383
    DROP TABLE t1;
sl@0
   384
    INSERT INTO t2 VALUES(3, 4);
sl@0
   385
    INSERT INTO t2 VALUES(7, 8);
sl@0
   386
  }
sl@0
   387
}
sl@0
   388
sl@0
   389
sl@0
   390
integrity_check trigger1-5.1
sl@0
   391
sl@0
   392
# Create a trigger with the same name as a table.  Make sure the
sl@0
   393
# trigger works.  Then drop the trigger.  Make sure the table is
sl@0
   394
# still there.
sl@0
   395
#
sl@0
   396
set view_v1 {}
sl@0
   397
ifcapable view {
sl@0
   398
  set view_v1 {view v1}
sl@0
   399
}
sl@0
   400
do_test trigger1-6.1 {
sl@0
   401
  execsql {SELECT type, name FROM sqlite_master}
sl@0
   402
} [concat $view_v1 {table t2}]
sl@0
   403
do_test trigger1-6.2 {
sl@0
   404
  execsql {
sl@0
   405
    CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN
sl@0
   406
      SELECT RAISE(ABORT,'deletes are not allows');
sl@0
   407
    END;
sl@0
   408
    SELECT type, name FROM sqlite_master;
sl@0
   409
  }
sl@0
   410
} [concat $view_v1 {table t2 trigger t2}]
sl@0
   411
do_test trigger1-6.3 {
sl@0
   412
  catchsql {DELETE FROM t2}
sl@0
   413
} {1 {deletes are not allows}}
sl@0
   414
do_test trigger1-6.4 {
sl@0
   415
  execsql {SELECT * FROM t2}
sl@0
   416
} {3 4 7 8}
sl@0
   417
do_test trigger1-6.5 {
sl@0
   418
  db close
sl@0
   419
  sqlite3 db test.db
sl@0
   420
  execsql {SELECT type, name FROM sqlite_master}
sl@0
   421
} [concat $view_v1 {table t2 trigger t2}]
sl@0
   422
do_test trigger1-6.6 {
sl@0
   423
  execsql {
sl@0
   424
    DROP TRIGGER t2;
sl@0
   425
    SELECT type, name FROM sqlite_master;
sl@0
   426
  }
sl@0
   427
} [concat $view_v1 {table t2}]
sl@0
   428
do_test trigger1-6.7 {
sl@0
   429
  execsql {SELECT * FROM t2}
sl@0
   430
} {3 4 7 8}
sl@0
   431
do_test trigger1-6.8 {
sl@0
   432
  db close
sl@0
   433
  sqlite3 db test.db
sl@0
   434
  execsql {SELECT * FROM t2}
sl@0
   435
} {3 4 7 8}
sl@0
   436
sl@0
   437
integrity_check trigger-7.1
sl@0
   438
sl@0
   439
# Check to make sure the name of a trigger can be quoted so that keywords
sl@0
   440
# can be used as trigger names.  Ticket #468
sl@0
   441
#
sl@0
   442
do_test trigger1-8.1 {
sl@0
   443
  execsql {
sl@0
   444
    CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END;
sl@0
   445
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   446
  }
sl@0
   447
} {trigger}
sl@0
   448
do_test trigger1-8.2 {
sl@0
   449
  execsql {
sl@0
   450
    DROP TRIGGER 'trigger';
sl@0
   451
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   452
  }
sl@0
   453
} {}
sl@0
   454
do_test trigger1-8.3 {
sl@0
   455
  execsql {
sl@0
   456
    CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END;
sl@0
   457
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   458
  }
sl@0
   459
} {trigger}
sl@0
   460
do_test trigger1-8.4 {
sl@0
   461
  execsql {
sl@0
   462
    DROP TRIGGER "trigger";
sl@0
   463
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   464
  }
sl@0
   465
} {}
sl@0
   466
do_test trigger1-8.5 {
sl@0
   467
  execsql {
sl@0
   468
    CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END;
sl@0
   469
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   470
  }
sl@0
   471
} {trigger}
sl@0
   472
do_test trigger1-8.6 {
sl@0
   473
  execsql {
sl@0
   474
    DROP TRIGGER [trigger];
sl@0
   475
    SELECT name FROM sqlite_master WHERE type='trigger';
sl@0
   476
  }
sl@0
   477
} {}
sl@0
   478
sl@0
   479
ifcapable conflict {
sl@0
   480
  # Make sure REPLACE works inside of triggers.
sl@0
   481
  #
sl@0
   482
  # There are two versions of trigger-9.1 and trigger-9.2. One that uses
sl@0
   483
  # compound SELECT statements, and another that does not.
sl@0
   484
  ifcapable compound {
sl@0
   485
    do_test trigger1-9.1 {
sl@0
   486
      execsql {
sl@0
   487
        CREATE TABLE t3(a,b);
sl@0
   488
        CREATE TABLE t4(x UNIQUE, b);
sl@0
   489
        CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN
sl@0
   490
          REPLACE INTO t4 VALUES(new.a,new.b);
sl@0
   491
        END;
sl@0
   492
        INSERT INTO t3 VALUES(1,2);
sl@0
   493
        SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4;
sl@0
   494
      }
sl@0
   495
    } {1 2 99 99 1 2}
sl@0
   496
    do_test trigger1-9.2 {
sl@0
   497
      execsql {
sl@0
   498
        INSERT INTO t3 VALUES(1,3);
sl@0
   499
        SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4;
sl@0
   500
      }
sl@0
   501
    } {1 2 1 3 99 99 1 3}
sl@0
   502
  } else {
sl@0
   503
    do_test trigger1-9.1 {
sl@0
   504
      execsql {
sl@0
   505
        CREATE TABLE t3(a,b);
sl@0
   506
        CREATE TABLE t4(x UNIQUE, b);
sl@0
   507
        CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN
sl@0
   508
          REPLACE INTO t4 VALUES(new.a,new.b);
sl@0
   509
        END;
sl@0
   510
        INSERT INTO t3 VALUES(1,2);
sl@0
   511
        SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4;
sl@0
   512
      }
sl@0
   513
    } {1 2 99 99 1 2}
sl@0
   514
    do_test trigger1-9.2 {
sl@0
   515
      execsql {
sl@0
   516
        INSERT INTO t3 VALUES(1,3);
sl@0
   517
        SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4;
sl@0
   518
      }
sl@0
   519
    } {1 2 1 3 99 99 1 3}
sl@0
   520
  }
sl@0
   521
  execsql {
sl@0
   522
    DROP TABLE t3;
sl@0
   523
    DROP TABLE t4;
sl@0
   524
  }
sl@0
   525
}
sl@0
   526
sl@0
   527
sl@0
   528
# Ticket #764. At one stage TEMP triggers would fail to re-install when the
sl@0
   529
# schema was reloaded. The following tests ensure that TEMP triggers are
sl@0
   530
# correctly re-installed.
sl@0
   531
#
sl@0
   532
# Also verify that references within trigger programs are resolved at
sl@0
   533
# statement compile time, not trigger installation time. This means, for
sl@0
   534
# example, that you can drop and re-create tables referenced by triggers. 
sl@0
   535
ifcapable tempdb&&attach {
sl@0
   536
  do_test trigger1-10.0 {
sl@0
   537
    file delete -force test2.db
sl@0
   538
    file delete -force test2.db-journal
sl@0
   539
    execsql {
sl@0
   540
      ATTACH 'test2.db' AS aux;
sl@0
   541
    }
sl@0
   542
  } {}
sl@0
   543
  do_test trigger1-10.1 {
sl@0
   544
    execsql {
sl@0
   545
      CREATE TABLE main.t4(a, b, c);
sl@0
   546
      CREATE TABLE temp.t4(a, b, c);
sl@0
   547
      CREATE TABLE aux.t4(a, b, c);
sl@0
   548
      CREATE TABLE insert_log(db, a, b, c);
sl@0
   549
    }
sl@0
   550
  } {}
sl@0
   551
  do_test trigger1-10.2 {
sl@0
   552
    execsql {
sl@0
   553
      CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN 
sl@0
   554
        INSERT INTO insert_log VALUES('main', new.a, new.b, new.c);
sl@0
   555
      END;
sl@0
   556
      CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN 
sl@0
   557
        INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c);
sl@0
   558
      END;
sl@0
   559
      CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN 
sl@0
   560
        INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c);
sl@0
   561
      END;
sl@0
   562
    }
sl@0
   563
  } {}
sl@0
   564
  do_test trigger1-10.3 {
sl@0
   565
    execsql {
sl@0
   566
      INSERT INTO main.t4 VALUES(1, 2, 3);
sl@0
   567
      INSERT INTO temp.t4 VALUES(4, 5, 6);
sl@0
   568
      INSERT INTO aux.t4  VALUES(7, 8, 9);
sl@0
   569
    }
sl@0
   570
  } {}
sl@0
   571
  do_test trigger1-10.4 {
sl@0
   572
    execsql {
sl@0
   573
      SELECT * FROM insert_log;
sl@0
   574
    }
sl@0
   575
  } {main 1 2 3 temp 4 5 6 aux 7 8 9}
sl@0
   576
  do_test trigger1-10.5 {
sl@0
   577
    execsql {
sl@0
   578
      BEGIN;
sl@0
   579
      INSERT INTO main.t4 VALUES(1, 2, 3);
sl@0
   580
      INSERT INTO temp.t4 VALUES(4, 5, 6);
sl@0
   581
      INSERT INTO aux.t4  VALUES(7, 8, 9);
sl@0
   582
      ROLLBACK;
sl@0
   583
    }
sl@0
   584
  } {}
sl@0
   585
  do_test trigger1-10.6 {
sl@0
   586
    execsql {
sl@0
   587
      SELECT * FROM insert_log;
sl@0
   588
    }
sl@0
   589
  } {main 1 2 3 temp 4 5 6 aux 7 8 9}
sl@0
   590
  do_test trigger1-10.7 {
sl@0
   591
    execsql {
sl@0
   592
      DELETE FROM insert_log;
sl@0
   593
      INSERT INTO main.t4 VALUES(11, 12, 13);
sl@0
   594
      INSERT INTO temp.t4 VALUES(14, 15, 16);
sl@0
   595
      INSERT INTO aux.t4  VALUES(17, 18, 19);
sl@0
   596
    }
sl@0
   597
  } {}
sl@0
   598
  do_test trigger1-10.8 {
sl@0
   599
    execsql {
sl@0
   600
      SELECT * FROM insert_log;
sl@0
   601
    }
sl@0
   602
  } {main 11 12 13 temp 14 15 16 aux 17 18 19}
sl@0
   603
  do_test trigger1-10.8 {
sl@0
   604
  # Drop and re-create the insert_log table in a different database. Note
sl@0
   605
  # that we can change the column names because the trigger programs don't
sl@0
   606
  # use them explicitly.
sl@0
   607
    execsql {
sl@0
   608
      DROP TABLE insert_log;
sl@0
   609
      CREATE TABLE aux.insert_log(db, d, e, f);
sl@0
   610
    }
sl@0
   611
  } {}
sl@0
   612
  do_test trigger1-10.10 {
sl@0
   613
    execsql {
sl@0
   614
      INSERT INTO main.t4 VALUES(21, 22, 23);
sl@0
   615
      INSERT INTO temp.t4 VALUES(24, 25, 26);
sl@0
   616
      INSERT INTO aux.t4  VALUES(27, 28, 29);
sl@0
   617
    }
sl@0
   618
  } {}
sl@0
   619
  do_test trigger1-10.11 {
sl@0
   620
    execsql {
sl@0
   621
      SELECT * FROM insert_log;
sl@0
   622
    }
sl@0
   623
  } {main 21 22 23 temp 24 25 26 aux 27 28 29}
sl@0
   624
}
sl@0
   625
sl@0
   626
do_test trigger1-11.1 {
sl@0
   627
  catchsql {SELECT raise(abort,'message');}
sl@0
   628
} {1 {RAISE() may only be used within a trigger-program}}
sl@0
   629
sl@0
   630
sl@0
   631
finish_test