~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/test/regress/expected/triggers.out

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
--
 
2
-- TRIGGERS
 
3
--
 
4
create table pkeys (pkey1 int4 not null, pkey2 text not null);
 
5
create table fkeys (fkey1 int4, fkey2 text, fkey3 int);
 
6
create table fkeys2 (fkey21 int4, fkey22 text, pkey23 int not null);
 
7
create index fkeys_i on fkeys (fkey1, fkey2);
 
8
create index fkeys2_i on fkeys2 (fkey21, fkey22);
 
9
create index fkeys2p_i on fkeys2 (pkey23);
 
10
insert into pkeys values (10, '1');
 
11
insert into pkeys values (20, '2');
 
12
insert into pkeys values (30, '3');
 
13
insert into pkeys values (40, '4');
 
14
insert into pkeys values (50, '5');
 
15
insert into pkeys values (60, '6');
 
16
create unique index pkeys_i on pkeys (pkey1, pkey2);
 
17
--
 
18
-- For fkeys:
 
19
--      (fkey1, fkey2)  --> pkeys (pkey1, pkey2)
 
20
--      (fkey3)         --> fkeys2 (pkey23)
 
21
--
 
22
create trigger check_fkeys_pkey_exist 
 
23
        before insert or update on fkeys 
 
24
        for each row 
 
25
        execute procedure 
 
26
        check_primary_key ('fkey1', 'fkey2', 'pkeys', 'pkey1', 'pkey2');
 
27
create trigger check_fkeys_pkey2_exist 
 
28
        before insert or update on fkeys 
 
29
        for each row 
 
30
        execute procedure check_primary_key ('fkey3', 'fkeys2', 'pkey23');
 
31
--
 
32
-- For fkeys2:
 
33
--      (fkey21, fkey22)        --> pkeys (pkey1, pkey2)
 
34
--
 
35
create trigger check_fkeys2_pkey_exist 
 
36
        before insert or update on fkeys2 
 
37
        for each row 
 
38
        execute procedure 
 
39
        check_primary_key ('fkey21', 'fkey22', 'pkeys', 'pkey1', 'pkey2');
 
40
-- Test comments
 
41
COMMENT ON TRIGGER check_fkeys2_pkey_bad ON fkeys2 IS 'wrong';
 
42
ERROR:  trigger "check_fkeys2_pkey_bad" for table "fkeys2" does not exist
 
43
COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS 'right';
 
44
COMMENT ON TRIGGER check_fkeys2_pkey_exist ON fkeys2 IS NULL;
 
45
--
 
46
-- For pkeys:
 
47
--      ON DELETE/UPDATE (pkey1, pkey2) CASCADE:
 
48
--              fkeys (fkey1, fkey2) and fkeys2 (fkey21, fkey22)
 
49
--
 
50
create trigger check_pkeys_fkey_cascade
 
51
        before delete or update on pkeys 
 
52
        for each row 
 
53
        execute procedure 
 
54
        check_foreign_key (2, 'cascade', 'pkey1', 'pkey2', 
 
55
        'fkeys', 'fkey1', 'fkey2', 'fkeys2', 'fkey21', 'fkey22');
 
56
--
 
57
-- For fkeys2:
 
58
--      ON DELETE/UPDATE (pkey23) RESTRICT:
 
59
--              fkeys (fkey3)
 
60
--
 
61
create trigger check_fkeys2_fkey_restrict 
 
62
        before delete or update on fkeys2
 
63
        for each row 
 
64
        execute procedure check_foreign_key (1, 'restrict', 'pkey23', 'fkeys', 'fkey3');
 
65
insert into fkeys2 values (10, '1', 1);
 
66
insert into fkeys2 values (30, '3', 2);
 
67
insert into fkeys2 values (40, '4', 5);
 
68
insert into fkeys2 values (50, '5', 3);
 
69
-- no key in pkeys
 
70
insert into fkeys2 values (70, '5', 3);
 
71
ERROR:  tuple references non-existent key
 
72
DETAIL:  Trigger "check_fkeys2_pkey_exist" found tuple referencing non-existent key in "pkeys".
 
73
insert into fkeys values (10, '1', 2);
 
74
insert into fkeys values (30, '3', 3);
 
75
insert into fkeys values (40, '4', 2);
 
76
insert into fkeys values (50, '5', 2);
 
77
-- no key in pkeys
 
78
insert into fkeys values (70, '5', 1);
 
79
ERROR:  tuple references non-existent key
 
80
DETAIL:  Trigger "check_fkeys_pkey_exist" found tuple referencing non-existent key in "pkeys".
 
81
-- no key in fkeys2
 
82
insert into fkeys values (60, '6', 4);
 
83
ERROR:  tuple references non-existent key
 
84
DETAIL:  Trigger "check_fkeys_pkey2_exist" found tuple referencing non-existent key in "fkeys2".
 
85
delete from pkeys where pkey1 = 30 and pkey2 = '3';
 
86
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys are deleted
 
87
ERROR:  "check_fkeys2_fkey_restrict": tuple is referenced in "fkeys"
 
88
CONTEXT:  SQL statement "delete from fkeys2 where fkey21 = $1 and fkey22 = $2 "
 
89
delete from pkeys where pkey1 = 40 and pkey2 = '4';
 
90
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys are deleted
 
91
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys2 are deleted
 
92
update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 50 and pkey2 = '5';
 
93
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys are deleted
 
94
ERROR:  "check_fkeys2_fkey_restrict": tuple is referenced in "fkeys"
 
95
CONTEXT:  SQL statement "delete from fkeys2 where fkey21 = $1 and fkey22 = $2 "
 
96
update pkeys set pkey1 = 7, pkey2 = '70' where pkey1 = 10 and pkey2 = '1';
 
97
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys are deleted
 
98
NOTICE:  check_pkeys_fkey_cascade: 1 tuple(s) of fkeys2 are deleted
 
99
DROP TABLE pkeys;
 
100
DROP TABLE fkeys;
 
101
DROP TABLE fkeys2;
 
102
-- -- I've disabled the funny_dup17 test because the new semantics
 
103
-- -- of AFTER ROW triggers, which get now fired at the end of a
 
104
-- -- query always, cause funny_dup17 to enter an endless loop.
 
105
-- --
 
106
-- --      Jan
 
107
--
 
108
-- create table dup17 (x int4);
 
109
-- 
 
110
-- create trigger dup17_before 
 
111
--      before insert on dup17
 
112
--      for each row 
 
113
--      execute procedure 
 
114
--      funny_dup17 ()
 
115
-- ;
 
116
-- 
 
117
-- insert into dup17 values (17);
 
118
-- select count(*) from dup17;
 
119
-- insert into dup17 values (17);
 
120
-- select count(*) from dup17;
 
121
-- 
 
122
-- drop trigger dup17_before on dup17;
 
123
-- 
 
124
-- create trigger dup17_after
 
125
--      after insert on dup17
 
126
--      for each row 
 
127
--      execute procedure 
 
128
--      funny_dup17 ()
 
129
-- ;
 
130
-- insert into dup17 values (13);
 
131
-- select count(*) from dup17 where x = 13;
 
132
-- insert into dup17 values (13);
 
133
-- select count(*) from dup17 where x = 13;
 
134
-- 
 
135
-- DROP TABLE dup17;
 
136
create sequence ttdummy_seq increment 10 start 0 minvalue 0;
 
137
create table tttest (
 
138
        price_id        int4, 
 
139
        price_val       int4, 
 
140
        price_on        int4,
 
141
        price_off       int4 default 999999
 
142
);
 
143
create trigger ttdummy 
 
144
        before delete or update on tttest
 
145
        for each row 
 
146
        execute procedure 
 
147
        ttdummy (price_on, price_off);
 
148
create trigger ttserial 
 
149
        before insert or update on tttest
 
150
        for each row 
 
151
        execute procedure 
 
152
        autoinc (price_on, ttdummy_seq);
 
153
insert into tttest values (1, 1, null);
 
154
insert into tttest values (2, 2, null);
 
155
insert into tttest values (3, 3, 0);
 
156
select * from tttest;
 
157
 price_id | price_val | price_on | price_off 
 
158
----------+-----------+----------+-----------
 
159
        1 |         1 |       10 |    999999
 
160
        2 |         2 |       20 |    999999
 
161
        3 |         3 |       30 |    999999
 
162
(3 rows)
 
163
 
 
164
delete from tttest where price_id = 2;
 
165
select * from tttest;
 
166
 price_id | price_val | price_on | price_off 
 
167
----------+-----------+----------+-----------
 
168
        1 |         1 |       10 |    999999
 
169
        3 |         3 |       30 |    999999
 
170
        2 |         2 |       20 |        40
 
171
(3 rows)
 
172
 
 
173
-- what do we see ?
 
174
-- get current prices
 
175
select * from tttest where price_off = 999999;
 
176
 price_id | price_val | price_on | price_off 
 
177
----------+-----------+----------+-----------
 
178
        1 |         1 |       10 |    999999
 
179
        3 |         3 |       30 |    999999
 
180
(2 rows)
 
181
 
 
182
-- change price for price_id == 3
 
183
update tttest set price_val = 30 where price_id = 3;
 
184
select * from tttest;
 
185
 price_id | price_val | price_on | price_off 
 
186
----------+-----------+----------+-----------
 
187
        1 |         1 |       10 |    999999
 
188
        2 |         2 |       20 |        40
 
189
        3 |        30 |       50 |    999999
 
190
        3 |         3 |       30 |        50
 
191
(4 rows)
 
192
 
 
193
-- now we want to change pric_id in ALL tuples
 
194
-- this gets us not what we need
 
195
update tttest set price_id = 5 where price_id = 3;
 
196
select * from tttest;
 
197
 price_id | price_val | price_on | price_off 
 
198
----------+-----------+----------+-----------
 
199
        1 |         1 |       10 |    999999
 
200
        2 |         2 |       20 |        40
 
201
        3 |         3 |       30 |        50
 
202
        5 |        30 |       60 |    999999
 
203
        3 |        30 |       50 |        60
 
204
(5 rows)
 
205
 
 
206
-- restore data as before last update:
 
207
select set_ttdummy(0);
 
208
 set_ttdummy 
 
209
-------------
 
210
           1
 
211
(1 row)
 
212
 
 
213
delete from tttest where price_id = 5;
 
214
update tttest set price_off = 999999 where price_val = 30;
 
215
select * from tttest;
 
216
 price_id | price_val | price_on | price_off 
 
217
----------+-----------+----------+-----------
 
218
        1 |         1 |       10 |    999999
 
219
        2 |         2 |       20 |        40
 
220
        3 |         3 |       30 |        50
 
221
        3 |        30 |       50 |    999999
 
222
(4 rows)
 
223
 
 
224
-- and try change price_id now!
 
225
update tttest set price_id = 5 where price_id = 3;
 
226
select * from tttest;
 
227
 price_id | price_val | price_on | price_off 
 
228
----------+-----------+----------+-----------
 
229
        1 |         1 |       10 |    999999
 
230
        2 |         2 |       20 |        40
 
231
        5 |         3 |       30 |        50
 
232
        5 |        30 |       50 |    999999
 
233
(4 rows)
 
234
 
 
235
-- isn't it what we need ?
 
236
select set_ttdummy(1);
 
237
 set_ttdummy 
 
238
-------------
 
239
           0
 
240
(1 row)
 
241
 
 
242
-- we want to correct some "date"
 
243
update tttest set price_on = -1 where price_id = 1;
 
244
ERROR:  ttdummy (tttest): you can't change price_on and/or price_off columns (use set_ttdummy)
 
245
-- but this doesn't work
 
246
-- try in this way
 
247
select set_ttdummy(0);
 
248
 set_ttdummy 
 
249
-------------
 
250
           1
 
251
(1 row)
 
252
 
 
253
update tttest set price_on = -1 where price_id = 1;
 
254
select * from tttest;
 
255
 price_id | price_val | price_on | price_off 
 
256
----------+-----------+----------+-----------
 
257
        2 |         2 |       20 |        40
 
258
        5 |         3 |       30 |        50
 
259
        5 |        30 |       50 |    999999
 
260
        1 |         1 |       -1 |    999999
 
261
(4 rows)
 
262
 
 
263
-- isn't it what we need ?
 
264
-- get price for price_id == 5 as it was @ "date" 35
 
265
select * from tttest where price_on <= 35 and price_off > 35 and price_id = 5;
 
266
 price_id | price_val | price_on | price_off 
 
267
----------+-----------+----------+-----------
 
268
        5 |         3 |       30 |        50
 
269
(1 row)
 
270
 
 
271
drop table tttest;
 
272
drop sequence ttdummy_seq;
 
273
--
 
274
-- tests for per-statement triggers
 
275
--
 
276
CREATE TABLE log_table (tstamp timestamp default timeofday()::timestamp);
 
277
CREATE TABLE main_table (a int, b int);
 
278
COPY main_table (a,b) FROM stdin;
 
279
CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE 'plpgsql' AS '
 
280
BEGIN
 
281
        RAISE NOTICE ''trigger_func() called: action = %, when = %, level = %'', TG_OP, TG_WHEN, TG_LEVEL;
 
282
        RETURN NULL;
 
283
END;';
 
284
CREATE TRIGGER before_ins_stmt_trig BEFORE INSERT ON main_table
 
285
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
 
286
CREATE TRIGGER after_ins_stmt_trig AFTER INSERT ON main_table
 
287
FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func();
 
288
--
 
289
-- if neither 'FOR EACH ROW' nor 'FOR EACH STATEMENT' was specified,
 
290
-- CREATE TRIGGER should default to 'FOR EACH STATEMENT'
 
291
--
 
292
CREATE TRIGGER before_upd_stmt_trig AFTER UPDATE ON main_table
 
293
EXECUTE PROCEDURE trigger_func();
 
294
CREATE TRIGGER before_upd_row_trig AFTER UPDATE ON main_table
 
295
FOR EACH ROW EXECUTE PROCEDURE trigger_func();
 
296
INSERT INTO main_table DEFAULT VALUES;
 
297
NOTICE:  trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT
 
298
NOTICE:  trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT
 
299
UPDATE main_table SET a = a + 1 WHERE b < 30;
 
300
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = ROW
 
301
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = ROW
 
302
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = ROW
 
303
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = ROW
 
304
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = STATEMENT
 
305
-- UPDATE that effects zero rows should still call per-statement trigger
 
306
UPDATE main_table SET a = a + 2 WHERE b > 100;
 
307
NOTICE:  trigger_func() called: action = UPDATE, when = AFTER, level = STATEMENT
 
308
-- COPY should fire per-row and per-statement INSERT triggers
 
309
COPY main_table (a, b) FROM stdin;
 
310
NOTICE:  trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT
 
311
NOTICE:  trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT
 
312
SELECT * FROM main_table ORDER BY a, b;
 
313
 a  | b  
 
314
----+----
 
315
  6 | 10
 
316
 21 | 20
 
317
 30 | 40
 
318
 31 | 10
 
319
 50 | 35
 
320
 50 | 60
 
321
 81 | 15
 
322
    |   
 
323
(8 rows)
 
324