Skip to content

Commit 90b9c95

Browse files
BUG#21142859: FUNCTION UPDATING A VIEW FAILS TO FIND TABLE
THAT ACTUALLY EXISTS ANALYSIS: ========= Stored functions updating a view where the view table has a trigger defined that updates another table, fails reporting an error that the table doesn't exist. If there is a trigger defined on a table, a variable 'trg_event_map' will be set to a non-zero value after the parsed tree creation. This indicates what triggers we need to pre-load for the TABLE_LIST when opening an associated table. During the prelocking phase, the variable 'trg_event_map' will not be set for the view table. This value will be set after the processing of triggers defined on the table. During the processing of sub-statements, 'locked_tables_mode' will be set to 'LTM_PRELOCKED' which denotes that further locking of tables/functions cannot be done. This results in the other table not being locked and thus further processing results in an error getting reported. FIX: ==== During the prelocking of view, the value of 'trg_event_map' of the view is copied to 'trg_event_map' of the next table in the TABLE_LIST. This results in the locking of tables associated with the trigger as well.
1 parent cb29741 commit 90b9c95

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

mysql-test/r/sp-prelocking.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,3 +320,23 @@ c2
320320
DROP TRIGGER t1_ai;
321321
DROP TABLE t1, t2;
322322
End of 5.0 tests
323+
#
324+
# Bug#21142859: FUNCTION UPDATING A VIEW FAILS TO FIND TABLE THAT ACTUALLY EXISTS
325+
#
326+
CREATE TABLE t1 SELECT 1 AS fld1, 'A' AS fld2;
327+
CREATE TABLE t2 (fld3 INT, fld4 CHAR(1));
328+
CREATE VIEW v1 AS SELECT * FROM t1;
329+
CREATE TRIGGER t1_au AFTER UPDATE ON t1
330+
FOR EACH ROW INSERT INTO t2 VALUES (new.fld1, new.fld2);
331+
CREATE FUNCTION f1() RETURNS INT
332+
BEGIN
333+
UPDATE v1 SET fld2='B' WHERE fld1=1;
334+
RETURN row_count();
335+
END !
336+
# Without the patch, an error was getting reported.
337+
SELECT f1();
338+
f1()
339+
1
340+
DROP FUNCTION f1;
341+
DROP VIEW v1;
342+
DROP TABLE t1,t2;

mysql-test/t/sp-prelocking.test

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,29 @@ DROP TABLE t1, t2;
388388

389389
--echo End of 5.0 tests
390390

391+
--echo #
392+
--echo # Bug#21142859: FUNCTION UPDATING A VIEW FAILS TO FIND TABLE THAT ACTUALLY EXISTS
393+
--echo #
394+
395+
CREATE TABLE t1 SELECT 1 AS fld1, 'A' AS fld2;
396+
CREATE TABLE t2 (fld3 INT, fld4 CHAR(1));
397+
398+
CREATE VIEW v1 AS SELECT * FROM t1;
399+
400+
CREATE TRIGGER t1_au AFTER UPDATE ON t1
401+
FOR EACH ROW INSERT INTO t2 VALUES (new.fld1, new.fld2);
402+
403+
DELIMITER !;
404+
CREATE FUNCTION f1() RETURNS INT
405+
BEGIN
406+
UPDATE v1 SET fld2='B' WHERE fld1=1;
407+
RETURN row_count();
408+
END !
409+
DELIMITER ;!
410+
411+
--echo # Without the patch, an error was getting reported.
412+
SELECT f1();
413+
414+
DROP FUNCTION f1;
415+
DROP VIEW v1;
416+
DROP TABLE t1,t2;

sql/sql_base.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License as published by
@@ -5211,6 +5211,15 @@ handle_view(THD *thd, Query_tables_list *prelocking_ctx,
52115211
&table_list->view->sroutines_list,
52125212
table_list->top_table());
52135213
}
5214+
5215+
/*
5216+
If a trigger was defined on one of the associated tables then assign the
5217+
'trg_event_map' value of the view to the next table in table_list. When a
5218+
Stored function is invoked, all the associated tables including the tables
5219+
associated with the trigger are prelocked.
5220+
*/
5221+
if (table_list->trg_event_map && table_list->next_global)
5222+
table_list->next_global->trg_event_map= table_list->trg_event_map;
52145223
return FALSE;
52155224
}
52165225

0 commit comments

Comments
 (0)