xref: /sqlite-3.40.0/test/triggerB.test (revision f436620e)
1f93d9999Sdrh# 2008 April 15
2f93d9999Sdrh#
3f93d9999Sdrh# The author disclaims copyright to this source code.  In place of
4*f436620eSdrh# a legal notice', here is a blessing:
5f93d9999Sdrh#
6f93d9999Sdrh#    May you do good and not evil.
7f93d9999Sdrh#    May you find forgiveness for yourself and forgive others.
8f93d9999Sdrh#    May you share freely, never taking more than you give.
9f93d9999Sdrh#
10f93d9999Sdrh#***********************************************************************
11f93d9999Sdrh# This file implements regression tests for SQLite library. Specifically,
12f93d9999Sdrh# it tests updating tables with constraints within a trigger.  Ticket #3055.
13f93d9999Sdrh#
14f93d9999Sdrh
15f93d9999Sdrhset testdir [file dirname $argv0]
16f93d9999Sdrhsource $testdir/tester.tcl
17f93d9999Sdrhifcapable {!trigger} {
18f93d9999Sdrh  finish_test
19f93d9999Sdrh  return
20f93d9999Sdrh}
21f93d9999Sdrh
22f93d9999Sdrh# Create test tables with constraints.
23f93d9999Sdrh#
24f93d9999Sdrhdo_test triggerB-1.1 {
25f93d9999Sdrh  execsql {
26f93d9999Sdrh    CREATE TABLE x(x INTEGER PRIMARY KEY, y INT NOT NULL);
27f93d9999Sdrh    INSERT INTO x(y) VALUES(1);
28f93d9999Sdrh    INSERT INTO x(y) VALUES(1);
29f93d9999Sdrh    CREATE TEMP VIEW vx AS SELECT x, y, 0 AS yy FROM x;
30f93d9999Sdrh    CREATE TEMP TRIGGER tx INSTEAD OF UPDATE OF y ON vx
31f93d9999Sdrh    BEGIN
32f93d9999Sdrh      UPDATE x SET y = new.y WHERE x = new.x;
33f93d9999Sdrh    END;
34f93d9999Sdrh    SELECT * FROM vx;
35f93d9999Sdrh  }
36f93d9999Sdrh} {1 1 0 2 1 0}
37f93d9999Sdrhdo_test triggerB-1.2 {
38f93d9999Sdrh  execsql {
39f93d9999Sdrh    UPDATE vx SET y = yy;
40f93d9999Sdrh    SELECT * FROM vx;
41f93d9999Sdrh  }
42f93d9999Sdrh} {1 0 0 2 0 0}
43f93d9999Sdrh
44*f436620eSdrh# Added 2008-08-22:
45*f436620eSdrh#
46*f436620eSdrh# Name resolution within triggers.
47*f436620eSdrh#
48*f436620eSdrhdo_test triggerB-2.1 {
49*f436620eSdrh  catchsql {
50*f436620eSdrh    CREATE TRIGGER ty AFTER INSERT ON x BEGIN
51*f436620eSdrh       SELECT wen.x; -- Unrecognized name
52*f436620eSdrh    END;
53*f436620eSdrh    INSERT INTO x VALUES(1,2);
54*f436620eSdrh  }
55*f436620eSdrh} {1 {no such column: wen.x}}
56*f436620eSdrhdo_test triggerB-2.2 {
57*f436620eSdrh  catchsql {
58*f436620eSdrh    CREATE TRIGGER tz AFTER UPDATE ON x BEGIN
59*f436620eSdrh       SELECT dlo.x; -- Unrecognized name
60*f436620eSdrh    END;
61*f436620eSdrh    UPDATE x SET y=y+1;
62*f436620eSdrh  }
63*f436620eSdrh} {1 {no such column: dlo.x}}
64*f436620eSdrh
65*f436620eSdrhdo_test triggerB-2.3 {
66*f436620eSdrh  execsql {
67*f436620eSdrh    CREATE TABLE t2(a INTEGER PRIMARY KEY, b);
68*f436620eSdrh    INSERT INTO t2 VALUES(1,2);
69*f436620eSdrh    CREATE TABLE changes(x,y);
70*f436620eSdrh    CREATE TRIGGER r1t2 AFTER UPDATE ON t2 BEGIN
71*f436620eSdrh      INSERT INTO changes VALUES(new.a, new.b);
72*f436620eSdrh    END;
73*f436620eSdrh  }
74*f436620eSdrh  execsql {
75*f436620eSdrh    UPDATE t2 SET a=a+10;
76*f436620eSdrh    SELECT * FROM changes;
77*f436620eSdrh  }
78*f436620eSdrh} {11 2}
79*f436620eSdrhdo_test triggerB-2.4 {
80*f436620eSdrh  execsql {
81*f436620eSdrh    CREATE TRIGGER r2t2 AFTER DELETE ON t2 BEGIN
82*f436620eSdrh      INSERT INTO changes VALUES(old.a, old.c);
83*f436620eSdrh    END;
84*f436620eSdrh  }
85*f436620eSdrh  catchsql {
86*f436620eSdrh    DELETE FROM t2;
87*f436620eSdrh  }
88*f436620eSdrh} {1 {no such column: old.c}}
89*f436620eSdrh
90*f436620eSdrh# Triggers maintain a mask of columns from the invoking table that are
91*f436620eSdrh# used in the trigger body as NEW.column or OLD.column.  That mask is then
92*f436620eSdrh# used to reduce the amount of information that needs to be loaded into
93*f436620eSdrh# the NEW and OLD pseudo-tables at run-time.
94*f436620eSdrh#
95*f436620eSdrh# These tests cases check the logic for when there are many columns - more
96*f436620eSdrh# than will fit in a bitmask.
97*f436620eSdrh#
98*f436620eSdrhdo_test triggerB-3.1 {
99*f436620eSdrh  execsql {
100*f436620eSdrh    CREATE TABLE t3(
101*f436620eSdrh       c0,  c1,  c2,  c3,  c4,  c5,  c6,  c7,  c8,  c9,
102*f436620eSdrh       c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
103*f436620eSdrh       c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
104*f436620eSdrh       c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
105*f436620eSdrh       c40, c41, c42, c43, c44, c45, c46, c47, c48, c49,
106*f436620eSdrh       c50, c51, c52, c53, c54, c55, c56, c57, c58, c59,
107*f436620eSdrh       c60, c61, c62, c63, c64, c65
108*f436620eSdrh    );
109*f436620eSdrh    CREATE TABLE t3_changes(colnum, oldval, newval);
110*f436620eSdrh    INSERT INTO t3 VALUES(
111*f436620eSdrh       'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9',
112*f436620eSdrh       'a10','a11','a12','a13','a14','a15','a16','a17','a18','a19',
113*f436620eSdrh       'a20','a21','a22','a23','a24','a25','a26','a27','a28','a29',
114*f436620eSdrh       'a30','a31','a32','a33','a34','a35','a36','a37','a38','a39',
115*f436620eSdrh       'a40','a41','a42','a43','a44','a45','a46','a47','a48','a49',
116*f436620eSdrh       'a50','a51','a52','a53','a54','a55','a56','a57','a58','a59',
117*f436620eSdrh       'a60','a61','a62','a63','a64','a65'
118*f436620eSdrh    );
119*f436620eSdrh  }
120*f436620eSdrh  for {set i 0} {$i<=65} {incr i} {
121*f436620eSdrh    set sql [subst {
122*f436620eSdrh      CREATE TRIGGER t3c$i AFTER UPDATE ON t3
123*f436620eSdrh         WHEN old.c$i!=new.c$i BEGIN
124*f436620eSdrh          INSERT INTO t3_changes VALUES($i, old.c$i, new.c$i);
125*f436620eSdrh      END
126*f436620eSdrh    }]
127*f436620eSdrh    db eval $sql
128*f436620eSdrh  }
129*f436620eSdrh  execsql {
130*f436620eSdrh    SELECT * FROM t3_changes
131*f436620eSdrh  }
132*f436620eSdrh} {}
133*f436620eSdrhfor {set i 0} {$i<=64} {incr i} {
134*f436620eSdrh  do_test triggerB-3.2.$i.1 [subst {
135*f436620eSdrh    execsql {
136*f436620eSdrh      UPDATE t3 SET c$i='b$i';
137*f436620eSdrh      SELECT * FROM t3_changes ORDER BY rowid DESC LIMIT 1;
138*f436620eSdrh    }
139*f436620eSdrh  }] [subst {$i a$i b$i}]
140*f436620eSdrh  do_test triggerB-3.2.$i.2 [subst {
141*f436620eSdrh    execsql {
142*f436620eSdrh      SELECT count(*) FROM t3_changes
143*f436620eSdrh    }
144*f436620eSdrh  }] [expr {$i+1}]
145*f436620eSdrh  do_test triggerB-3.2.$i.2 [subst {
146*f436620eSdrh    execsql {
147*f436620eSdrh      SELECT * FROM t3_changes WHERE colnum=$i
148*f436620eSdrh    }
149*f436620eSdrh  }] [subst {$i a$i b$i}]
150*f436620eSdrh}
151*f436620eSdrh
152*f436620eSdrh
153f93d9999Sdrhfinish_test
154