Skip to content

Commit 044ef37

Browse files
MDEV-34723: NEW and OLD in a trigger as row variables
Implementation: NEW and OLD represent the entire table row. So it can be thought of as list of Item_trigger_field. When the old mode is appropriately set, we are in a trigger and NEW or OLD is encountered, create Item_trigger_row object with same constructor as Item_trigger_field, it will also be used later while creating Item_trigger_field objects. Populate the m_fields list while fixing fields. Create a corresponding instruction sp_instr_set_trigger_row which will be used to set the values
1 parent 5ed3668 commit 044ef37

File tree

69 files changed

+1467
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1467
-130
lines changed

mysql-test/main/mdev_34723.result

Lines changed: 355 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,355 @@
1+
#
2+
# NEW and OLD does not work outside trigger and gives error
3+
# regardless of mode
4+
#
5+
SET NEW=OLD;
6+
ERROR HY000: Unknown system variable 'NEW'
7+
SELECT @@old_mode;
8+
@@old_mode
9+
UTF8_IS_UTF8MB3,TRIGGERS_NEW_AND_OLD_ARE_VARS
10+
SET @saved_old_mode= @@old_mode;
11+
SET @@old_mode =
12+
TRIM(BOTH ',' FROM
13+
REPLACE(
14+
CONCAT(',', @@old_mode, ','),
15+
',TRIGGERS_NEW_AND_OLD_ARE_VARS,',
16+
','
17+
)
18+
);
19+
SELECT @@old_mode;
20+
@@old_mode
21+
UTF8_IS_UTF8MB3
22+
SET NEW=OLD;
23+
ERROR HY000: Unknown system variable 'NEW'
24+
#
25+
# Checking for INSERT
26+
#
27+
CREATE TABLE t1 (id1 INT, val1 VARCHAR(10));
28+
CREATE TABLE t2 (id2 INT, val2 VARCHAR(10));
29+
INSERT INTO t1 VALUES (1, "A"), (2, "B"), (3, "C") RETURNING *;
30+
id1 val1
31+
1 A
32+
2 B
33+
3 C
34+
CREATE TRIGGER t1_before_insert_new_eq_old
35+
BEFORE INSERT ON t1
36+
FOR EACH ROW
37+
BEGIN
38+
SET NEW=OLD;
39+
END|
40+
ERROR HY000: There is no OLD row in on INSERT trigger
41+
CREATE TRIGGER t1_after_insert_new_eq_old
42+
AFTER INSERT ON t1
43+
FOR EACH ROW
44+
BEGIN
45+
SET NEW=OLD;
46+
END|
47+
ERROR HY000: There is no OLD row in on INSERT trigger
48+
CREATE TRIGGER t1_after_insert_new_eq_var
49+
AFTER INSERT ON t1
50+
FOR EACH ROW
51+
BEGIN
52+
DECLARE a ROW (x INT,y VARCHAR(10));
53+
SET NEW=a;
54+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
55+
END|
56+
ERROR HY000: Updating of NEW row is not allowed in after trigger
57+
CREATE TRIGGER t1_before_insert_set_new_eq_var
58+
BEFORE INSERT ON t1
59+
FOR EACH ROW
60+
BEGIN
61+
DECLARE new ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
62+
END|
63+
ERROR HY000: Cannot have new as a variable name in the trigger while TRIGGERS_NEW_AND_OLD_ARE_VARS is disabled.
64+
CREATE TRIGGER t1_before_insert_set_new_eq_var
65+
BEFORE INSERT ON t1
66+
FOR EACH ROW
67+
BEGIN
68+
DECLARE old INT DEFAULT(5);
69+
END|
70+
ERROR HY000: Cannot have old as a variable name in the trigger while TRIGGERS_NEW_AND_OLD_ARE_VARS is disabled.
71+
CREATE TRIGGER t1_before_insert_set_new_eq_var
72+
BEFORE INSERT ON t1
73+
FOR EACH ROW
74+
BEGIN
75+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
76+
SET NEW=a;
77+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
78+
END|
79+
INSERT INTO t1 VALUES (4, "D");
80+
SELECT * FROM t1;
81+
id1 val1
82+
1 A
83+
2 B
84+
3 C
85+
5 E
86+
SELECT * FROM t2;
87+
id2 val2
88+
5 E
89+
DROP TRIGGER t1_before_insert_set_new_eq_var;
90+
CREATE TRIGGER t1_before_insert_unequal_row
91+
BEFORE INSERT ON t1
92+
FOR EACH ROW
93+
BEGIN
94+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
95+
SET NEW=a.x;
96+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
97+
END|
98+
INSERT INTO t1 VALUES (6, "F");
99+
ERROR 21000: Operand should contain 2 column(s)
100+
DROP TRIGGER t1_before_insert_unequal_row;
101+
CREATE TRIGGER t1_after_insert_unequal_row
102+
AFTER INSERT ON t1
103+
FOR EACH ROW
104+
BEGIN
105+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
106+
SET NEW=a.x;
107+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
108+
END|
109+
ERROR HY000: Updating of NEW row is not allowed in after trigger
110+
DROP TABLE t1;
111+
DROP TABLE t2;
112+
#
113+
# Checking for UPDATE
114+
#
115+
CREATE TABLE t1 (id1 INT, val1 VARCHAR(10));
116+
CREATE TABLE t2 (id2 INT, val2 VARCHAR(10));
117+
INSERT INTO t1 VALUES (1, "A"), (2, "B"), (3, "C");
118+
SELECT * FROM t1;
119+
id1 val1
120+
1 A
121+
2 B
122+
3 C
123+
CREATE TRIGGER t1_after_update_new_eq_old
124+
AFTER UPDATE ON t1
125+
FOR EACH ROW
126+
BEGIN
127+
SET NEW=OLD;
128+
END|
129+
ERROR HY000: Updating of NEW row is not allowed in after trigger
130+
CREATE TRIGGER t1_after_update_old_eq_new
131+
AFTER UPDATE ON t1
132+
FOR EACH ROW
133+
BEGIN
134+
SET OLD = NEW;
135+
END|
136+
ERROR HY000: Updating of OLD row is not allowed in trigger
137+
CREATE TRIGGER t1_after_update_new_eq_var
138+
AFTER UPDATE ON t1
139+
FOR EACH ROW
140+
BEGIN
141+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
142+
SET NEW=a;
143+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
144+
END|
145+
ERROR HY000: Updating of NEW row is not allowed in after trigger
146+
CREATE TRIGGER t1_after_update_set_old_eq_var
147+
AFTER UPDATE ON t1
148+
FOR EACH ROW
149+
BEGIN
150+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
151+
SET OLD=a;
152+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
153+
END|
154+
ERROR HY000: Updating of OLD row is not allowed in trigger
155+
CREATE TRIGGER t1_before_update_new_eq_old
156+
BEFORE UPDATE ON t1
157+
FOR EACH ROW
158+
BEGIN
159+
SET NEW = OLD;
160+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
161+
END|
162+
CREATE TRIGGER t1_before_update_old_eq_new
163+
BEFORE UPDATE ON t1
164+
FOR EACH ROW
165+
BEGIN
166+
SET OLD=NEW;
167+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
168+
END|
169+
ERROR HY000: Updating of OLD row is not allowed in trigger
170+
SELECT * FROM t1;
171+
id1 val1
172+
1 A
173+
2 B
174+
3 C
175+
SELECT * FROM t2;
176+
id2 val2
177+
UPDATE t1 SET val1="D" WHERE id1= 1;
178+
SELECT * FROM t1;
179+
id1 val1
180+
1 A
181+
2 B
182+
3 C
183+
SELECT * FROM t2;
184+
id2 val2
185+
1 A
186+
DROP TRIGGER t1_before_update_new_eq_old;
187+
CREATE TRIGGER t1_before_update_old_eq_var
188+
BEFORE UPDATE ON t1
189+
FOR EACH ROW
190+
BEGIN
191+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
192+
SET OLD=a;
193+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
194+
END|
195+
ERROR HY000: Updating of OLD row is not allowed in trigger
196+
TRUNCATE TABLE t2;
197+
CREATE TRIGGER t1_before_update_new_eq_var
198+
BEFORE UPDATE ON t1
199+
FOR EACH ROW
200+
BEGIN
201+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
202+
SET NEW=a;
203+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
204+
END|
205+
UPDATE t1 SET val1="D" WHERE id1= 1;
206+
SELECT * FROM t1;
207+
id1 val1
208+
5 E
209+
2 B
210+
3 C
211+
SELECT * FROM t2;
212+
id2 val2
213+
5 E
214+
DROP TRIGGER t1_before_update_new_eq_var;
215+
CREATE TRIGGER t1_before_update_new_eq_var
216+
BEFORE UPDATE ON t1
217+
FOR EACH ROW
218+
BEGIN
219+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT(5, "E");
220+
SET NEW=a.x;
221+
INSERT INTO t2 VALUES (NEW.id1, NEW.val1);
222+
END|
223+
UPDATE t1 SET val1="D" WHERE id1= 5;
224+
ERROR 21000: Operand should contain 2 column(s)
225+
DROP TABLE t1;
226+
DROP TABLE t2;
227+
#
228+
# Checking for DELETE
229+
#
230+
CREATE TABLE t1 (id1 INT, val1 VARCHAR(10));
231+
CREATE TABLE t2 (id2 INT, val2 VARCHAR(10));
232+
INSERT INTO t1 VALUES (1, "A"), (2, "B"), (3, "C");
233+
SELECT * FROM t1;
234+
id1 val1
235+
1 A
236+
2 B
237+
3 C
238+
SELECT * FROM t2;
239+
id2 val2
240+
CREATE TRIGGER t1_before_delete_new_eq_old
241+
BEFORE DELETE ON t1
242+
FOR EACH ROW
243+
BEGIN
244+
SET NEW = OLD;
245+
END|
246+
ERROR HY000: There is no NEW row in on DELETE trigger
247+
CREATE TRIGGER t1_before_delete_old_eq_new
248+
BEFORE DELETE ON t1
249+
FOR EACH ROW
250+
BEGIN
251+
SET OLD = NEW;
252+
END|
253+
ERROR HY000: There is no NEW row in on DELETE trigger
254+
CREATE TRIGGER t1_before_delete_old_eq_var
255+
BEFORE DELETE ON t1
256+
FOR EACH ROW
257+
BEGIN
258+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT (3, "C");
259+
SET OLD=a;
260+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
261+
END|
262+
ERROR HY000: Updating of OLD row is not allowed in trigger
263+
CREATE TRIGGER t1_before_delete_old_eq_var
264+
BEFORE DELETE ON t1
265+
FOR EACH ROW
266+
BEGIN
267+
DECLARE a ROW (x INT,y VARCHAR(10));
268+
SET a=OLD;
269+
INSERT INTO t2 VALUES(OLD.id1, OLD.val1);
270+
END|
271+
CREATE TRIGGER t1_after_delete_new_eq_old
272+
AFTER DELETE ON t1
273+
FOR EACH ROW
274+
BEGIN
275+
SET NEW = OLD;
276+
END|
277+
ERROR HY000: There is no NEW row in on DELETE trigger
278+
CREATE TRIGGER t1_after_delete_old_eq_new
279+
AFTER DELETE ON t1
280+
FOR EACH ROW
281+
BEGIN
282+
SET OLD=NEW;
283+
END|
284+
ERROR HY000: There is no NEW row in on DELETE trigger
285+
CREATE TRIGGER t1_after_delete_old_eq_var
286+
AFTER DELETE ON t1
287+
FOR EACH ROW
288+
BEGIN
289+
DECLARE a ROW (x INT,y VARCHAR(10)) DEFAULT (3, "C");
290+
SET OLD=a;
291+
INSERT INTO t2 VALUES(NEW.id1, NEW.val1);
292+
END|
293+
ERROR HY000: Updating of OLD row is not allowed in trigger
294+
DELETE FROM t1 WHERE id1=1;
295+
SELECT * FROM t1;
296+
id1 val1
297+
2 B
298+
3 C
299+
SELECT * FROM t2;
300+
id2 val2
301+
1 A
302+
TRUNCATE TABLE t2;
303+
DROP TRIGGER t1_before_delete_old_eq_var;
304+
CREATE TRIGGER t1_before_delete_old_eq_var
305+
BEFORE DELETE ON t1
306+
FOR EACH ROW
307+
BEGIN
308+
DECLARE a ROW (x INT,y VARCHAR(10));
309+
SET a=OLD;
310+
INSERT INTO t2 VALUES(OLD.id1, OLD.val1);
311+
END|
312+
SELECT * FROM t2;
313+
id2 val2
314+
DELETE FROM t1 WHERE id1=2;
315+
DROP TRIGGER t1_before_delete_old_eq_var;
316+
CREATE TRIGGER t1_before_delete_unequal_row
317+
BEFORE DELETE ON t1
318+
FOR EACH ROW
319+
BEGIN
320+
DECLARE a ROW (x INT, y VARCHAR(10)) DEFAULT(5, "E");
321+
SET a.x = OLD;
322+
END|
323+
DELETE FROM t1 WHERE id1=3;
324+
ERROR HY000: Cannot cast 'row' as 'int' in assignment of `x`
325+
SELECT * FROM t1;
326+
id1 val1
327+
3 C
328+
SELECT * FROM t2;
329+
id2 val2
330+
2 B
331+
DROP TABLE t1;
332+
DROP TABLE t2;
333+
SET @@old_mode= @saved_old_mode;
334+
SELECT @@old_mode;
335+
@@old_mode
336+
UTF8_IS_UTF8MB3,TRIGGERS_NEW_AND_OLD_ARE_VARS
337+
SET @@old_mode =
338+
TRIM(BOTH ',' FROM
339+
REPLACE(
340+
CONCAT(',', @@old_mode, ','),
341+
',TRIGGERS_NEW_AND_OLD_ARE_VARS,',
342+
','
343+
)
344+
);
345+
SELECT @@old_mode;
346+
@@old_mode
347+
UTF8_IS_UTF8MB3
348+
CREATE TABLE t1 (a INT);
349+
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1
350+
FOR EACH ROW
351+
BEGIN
352+
SET NEW = OLD;
353+
END$
354+
DROP TRIGGER t1_bu;
355+
DROP TABLE t1;

0 commit comments

Comments
 (0)