Loading mysql-test/r/view.result +14 −0 Original line number Diff line number Diff line Loading @@ -2736,6 +2736,20 @@ m e 1 b DROP VIEW v1; DROP TABLE t1,t2; DROP FUNCTION IF EXISTS f1; DROP VIEW IF EXISTS v1; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (1); CREATE VIEW v1 AS SELECT MAX(i) FROM t1; CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.i = (SELECT * FROM v1) + 1; INSERT INTO t1 VALUES (1); CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1); UPDATE t1 SET i= f1(); DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL, b INT NULL DEFAULT NULL); CREATE VIEW v1 AS SELECT a, b FROM t1; INSERT INTO v1 (b) VALUES (2); Loading mysql-test/t/view.test +37 −0 Original line number Diff line number Diff line Loading @@ -2597,6 +2597,7 @@ SELECT * FROM t2; DROP VIEW v1; DROP TABLE t1,t2; # # Bug#16110: insert permitted into view col w/o default value # Loading Loading @@ -2879,4 +2880,40 @@ SHOW CREATE VIEW v1; DROP VIEW v1; DROP TABLE t1, t2; # # Bug#19111: TRIGGERs selecting from a VIEW on the firing base table # fail # # Allow to select from a view on a table being modified in a trigger # and stored function, since plain select is allowed there. # --disable_warnings DROP FUNCTION IF EXISTS f1; DROP VIEW IF EXISTS v1; DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (1); CREATE VIEW v1 AS SELECT MAX(i) FROM t1; # Plain 'SET NEW.i = (SELECT MAX(i) FROM t1) + 1' works, so select # from a view should work too. CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.i = (SELECT * FROM v1) + 1; INSERT INTO t1 VALUES (1); # Plain 'RETURN (SELECT MAX(i) FROM t1)' works in INSERT, so select # from a view should work too. CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1); UPDATE t1 SET i= f1(); DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1; --echo End of 5.0 tests. sql/sql_base.cc +8 −3 Original line number Diff line number Diff line Loading @@ -806,6 +806,10 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, Also SELECT::exclude_from_table_unique_test used to exclude from check tables of main SELECT of multi-delete and multi-update We also skip tables with TABLE_LIST::prelocking_placeholder set, because we want to allow SELECTs from them, and their modification will rise the error anyway. TODO: when we will have table/view change detection we can do this check only once for PS/SP Loading Loading @@ -852,12 +856,13 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list) if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) && (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) || ((!res->table || res->table != table->table) && res->select_lex && !res->select_lex->exclude_from_table_unique_test)) res->select_lex && !res->select_lex->exclude_from_table_unique_test && !res->prelocking_placeholder)) break; /* If we found entry of this table or or table of SELECT which already If we found entry of this table or table of SELECT which already processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test). (exclude_from_table_unique_test) or prelocking placeholder. */ table_list= res->next_global; DBUG_PRINT("info", Loading Loading
mysql-test/r/view.result +14 −0 Original line number Diff line number Diff line Loading @@ -2736,6 +2736,20 @@ m e 1 b DROP VIEW v1; DROP TABLE t1,t2; DROP FUNCTION IF EXISTS f1; DROP VIEW IF EXISTS v1; DROP TABLE IF EXISTS t1; CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (1); CREATE VIEW v1 AS SELECT MAX(i) FROM t1; CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.i = (SELECT * FROM v1) + 1; INSERT INTO t1 VALUES (1); CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1); UPDATE t1 SET i= f1(); DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL, b INT NULL DEFAULT NULL); CREATE VIEW v1 AS SELECT a, b FROM t1; INSERT INTO v1 (b) VALUES (2); Loading
mysql-test/t/view.test +37 −0 Original line number Diff line number Diff line Loading @@ -2597,6 +2597,7 @@ SELECT * FROM t2; DROP VIEW v1; DROP TABLE t1,t2; # # Bug#16110: insert permitted into view col w/o default value # Loading Loading @@ -2879,4 +2880,40 @@ SHOW CREATE VIEW v1; DROP VIEW v1; DROP TABLE t1, t2; # # Bug#19111: TRIGGERs selecting from a VIEW on the firing base table # fail # # Allow to select from a view on a table being modified in a trigger # and stored function, since plain select is allowed there. # --disable_warnings DROP FUNCTION IF EXISTS f1; DROP VIEW IF EXISTS v1; DROP TABLE IF EXISTS t1; --enable_warnings CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (1); CREATE VIEW v1 AS SELECT MAX(i) FROM t1; # Plain 'SET NEW.i = (SELECT MAX(i) FROM t1) + 1' works, so select # from a view should work too. CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET NEW.i = (SELECT * FROM v1) + 1; INSERT INTO t1 VALUES (1); # Plain 'RETURN (SELECT MAX(i) FROM t1)' works in INSERT, so select # from a view should work too. CREATE FUNCTION f1() RETURNS INT RETURN (SELECT * FROM v1); UPDATE t1 SET i= f1(); DROP FUNCTION f1; DROP VIEW v1; DROP TABLE t1; --echo End of 5.0 tests.
sql/sql_base.cc +8 −3 Original line number Diff line number Diff line Loading @@ -806,6 +806,10 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, Also SELECT::exclude_from_table_unique_test used to exclude from check tables of main SELECT of multi-delete and multi-update We also skip tables with TABLE_LIST::prelocking_placeholder set, because we want to allow SELECTs from them, and their modification will rise the error anyway. TODO: when we will have table/view change detection we can do this check only once for PS/SP Loading Loading @@ -852,12 +856,13 @@ TABLE_LIST* unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list) if (((! (res= find_table_in_global_list(table_list, d_name, t_name))) && (! (res= mysql_lock_have_duplicate(thd, table, table_list)))) || ((!res->table || res->table != table->table) && res->select_lex && !res->select_lex->exclude_from_table_unique_test)) res->select_lex && !res->select_lex->exclude_from_table_unique_test && !res->prelocking_placeholder)) break; /* If we found entry of this table or or table of SELECT which already If we found entry of this table or table of SELECT which already processed in derived table or top select of multi-update/multi-delete (exclude_from_table_unique_test). (exclude_from_table_unique_test) or prelocking placeholder. */ table_list= res->next_global; DBUG_PRINT("info", Loading