Skip to content

Commit 705abde

Browse files
author
Varun Gupta
committed
MDEV-13170: Database service (MySQL) stops after update with trigger
For prepare statemtent/stored procedures we rollback the items to original ones after prepare execution in the function reinit_stmt_before_use. This rollback is done for group by, order by clauses but is not done for the window specification containing the order by and partition by clause of the window function.
1 parent f74649b commit 705abde

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

mysql-test/r/win.result

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3423,3 +3423,37 @@ GROUP BY LEFT('2018-08-24', 100) having 1=1 limit 0;
34233423
id select_type table type possible_keys key key_len ref rows Extra
34243424
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit
34253425
drop table t1;
3426+
#
3427+
# MDEV-13170: Database service (MySQL) stops after update with trigger
3428+
#
3429+
CREATE TABLE t1 ( t1_id int, point_id int, ml_id int, UNIQUE KEY t1_ml_u (ml_id,point_id)) ;
3430+
INSERT INTO t1 VALUES (1,1,8884),(2,1,8885);
3431+
CREATE TABLE t2 ( db_time datetime, au_nr int, col_id int, new_val int);
3432+
CREATE TABLE t3 (id1 int, id2 int, d1 int);
3433+
CREATE TRIGGER t1_aurtrg AFTER UPDATE ON t1 FOR EACH ROW begin
3434+
CREATE OR REPLACE TEMPORARY TABLE trg_u AS
3435+
WITH l AS
3436+
(SELECT a.*,
3437+
Max(t2.col_id) over (PARTITION BY a.d1),
3438+
Max(t2.new_val) over (PARTITION BY a.d1)
3439+
FROM
3440+
(SELECT d1 , id1, id2 FROM t3) a
3441+
JOIN t2 ON (a.d1=t2.db_time AND a.id1=t2.au_nr))
3442+
SELECT 1;
3443+
END;//
3444+
update t1 set ml_id=8884 where point_id=1;
3445+
ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u'
3446+
update t1 set ml_id=8884 where point_id=1;
3447+
ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u'
3448+
drop table t1, t2,t3;
3449+
CREATE TABLE t1 (i INT, a char);
3450+
INSERT INTO t1 VALUES (1, 'a'),(2, 'b');
3451+
create view v1 as select * from t1;
3452+
PREPARE stmt FROM "SELECT i, row_number() over (partition by i order by i) FROM v1";
3453+
execute stmt;
3454+
i row_number() over (partition by i order by i)
3455+
1 1
3456+
2 1
3457+
deallocate prepare stmt;
3458+
drop table t1;
3459+
drop view v1;

mysql-test/t/win.test

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,3 +2175,44 @@ explain
21752175
SELECT DISTINCT BIT_OR(100) OVER () FROM t1
21762176
GROUP BY LEFT('2018-08-24', 100) having 1=1 limit 0;
21772177
drop table t1;
2178+
2179+
--echo #
2180+
--echo # MDEV-13170: Database service (MySQL) stops after update with trigger
2181+
--echo #
2182+
2183+
CREATE TABLE t1 ( t1_id int, point_id int, ml_id int, UNIQUE KEY t1_ml_u (ml_id,point_id)) ;
2184+
INSERT INTO t1 VALUES (1,1,8884),(2,1,8885);
2185+
2186+
CREATE TABLE t2 ( db_time datetime, au_nr int, col_id int, new_val int);
2187+
CREATE TABLE t3 (id1 int, id2 int, d1 int);
2188+
2189+
delimiter //;
2190+
2191+
CREATE TRIGGER t1_aurtrg AFTER UPDATE ON t1 FOR EACH ROW begin
2192+
CREATE OR REPLACE TEMPORARY TABLE trg_u AS
2193+
WITH l AS
2194+
(SELECT a.*,
2195+
Max(t2.col_id) over (PARTITION BY a.d1),
2196+
Max(t2.new_val) over (PARTITION BY a.d1)
2197+
FROM
2198+
(SELECT d1 , id1, id2 FROM t3) a
2199+
JOIN t2 ON (a.d1=t2.db_time AND a.id1=t2.au_nr))
2200+
SELECT 1;
2201+
2202+
END;//
2203+
2204+
delimiter ;//
2205+
--error 1062
2206+
update t1 set ml_id=8884 where point_id=1;
2207+
--error 1062
2208+
update t1 set ml_id=8884 where point_id=1;
2209+
drop table t1, t2,t3;
2210+
2211+
CREATE TABLE t1 (i INT, a char);
2212+
INSERT INTO t1 VALUES (1, 'a'),(2, 'b');
2213+
create view v1 as select * from t1;
2214+
PREPARE stmt FROM "SELECT i, row_number() over (partition by i order by i) FROM v1";
2215+
execute stmt;
2216+
deallocate prepare stmt;
2217+
drop table t1;
2218+
drop view v1;

sql/sql_prepare.cc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2927,6 +2927,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
29272927
{
29282928
SELECT_LEX *sl= lex->all_selects_list;
29292929
DBUG_ENTER("reinit_stmt_before_use");
2930+
Window_spec *win_spec;
29302931

29312932
/*
29322933
We have to update "thd" pointer in LEX, all its units and in LEX::result,
@@ -2995,6 +2996,17 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
29952996
/* Fix ORDER list */
29962997
for (order= sl->order_list.first; order; order= order->next)
29972998
order->item= &order->item_ptr;
2999+
/* Fix window functions too */
3000+
List_iterator<Window_spec> it(sl->window_specs);
3001+
3002+
while ((win_spec= it++))
3003+
{
3004+
for (order= win_spec->partition_list->first; order; order= order->next)
3005+
order->item= &order->item_ptr;
3006+
for (order= win_spec->order_list->first; order; order= order->next)
3007+
order->item= &order->item_ptr;
3008+
}
3009+
29983010
{
29993011
#ifndef DBUG_OFF
30003012
bool res=

0 commit comments

Comments
 (0)