summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbell@sanja.is.com.ua <>2006-04-13 23:12:26 +0300
committerbell@sanja.is.com.ua <>2006-04-13 23:12:26 +0300
commitefb8b990e4dc3c0ebfa8000df7557a7aca841edd (patch)
tree7c82180f348f690107af3589ae36aba1cdb889d6
parentdf69944e7316c1ab7fe0460420240f48ba117c13 (diff)
downloadmariadb-git-efb8b990e4dc3c0ebfa8000df7557a7aca841edd.tar.gz
The check for recursive view definitions added. (BUG#14308)
-rw-r--r--mysql-test/r/view.result23
-rw-r--r--mysql-test/t/view.test31
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sql_view.cc20
4 files changed, 75 insertions, 1 deletions
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 7519b8022f0..b52e6b58c0e 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2600,3 +2600,26 @@ id td
5 2005-01-04
DROP VIEW v1;
DROP TABLE t1;
+create table t1 (a int);
+create view v1 as select * from t1;
+create view v2 as select * from v1;
+drop table t1;
+rename table v2 to t1;
+select * from v1;
+ERROR HY000: `test`.`v1` contain view recursion
+drop view t1, v1;
+create table t1 (a int);
+create function f1() returns int
+begin
+declare mx int;
+select max(a) from t1 into mx;
+return mx;
+end//
+create view v1 as select f1() as a;
+create view v2 as select * from v1;
+drop table t1;
+rename table v2 to t1;
+select * from v1;
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+drop function f1;
+drop view t1, v1;
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 7ef1f82dbd3..81fb161b69a 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2454,3 +2454,34 @@ SELECT * FROM v1 WHERE td BETWEEN '2005.01.02' AND '2005.01.04';
DROP VIEW v1;
DROP TABLE t1;
+
+#
+# BUG#14308: Recursive view definitions
+#
+# using view only
+create table t1 (a int);
+create view v1 as select * from t1;
+create view v2 as select * from v1;
+drop table t1;
+rename table v2 to t1;
+-- error ER_VIEW_RECURSIVE
+select * from v1;
+drop view t1, v1;
+# using SP function
+create table t1 (a int);
+delimiter //;
+create function f1() returns int
+begin
+ declare mx int;
+ select max(a) from t1 into mx;
+ return mx;
+end//
+delimiter ;//
+create view v1 as select f1() as a;
+create view v2 as select * from v1;
+drop table t1;
+rename table v2 to t1;
+-- error ER_SP_NO_RECURSION
+select * from v1;
+drop function f1;
+drop view t1, v1;
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index a1f70fca8df..9519e77903d 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5613,3 +5613,5 @@ ER_SP_NO_AGGREGATE 42000
eng "AGGREGATE is not supported for stored functions"
ER_MAX_PREPARED_STMT_COUNT_REACHED 42000
eng "Can't create more than max_prepared_stmt_count statements (current value: %lu)"
+ER_VIEW_RECURSIVE
+ eng "`%-.64s`.`%-.64s` contain view recursion"
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 39d1ae5c9fb..cdb6c581565 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -771,6 +771,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
SELECT_LEX *end, *view_select;
LEX *old_lex, *lex;
Query_arena *arena, backup;
+ TABLE_LIST *top_view= table->top_table();
int res;
bool result;
DBUG_ENTER("mysql_make_view");
@@ -798,6 +799,24 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
DBUG_RETURN(0);
}
+ /* check loop via view definition */
+ for (TABLE_LIST *precedent= table->referencing_view;
+ precedent;
+ precedent= precedent->referencing_view)
+ {
+ if (precedent->view_name.length == table->table_name_length &&
+ precedent->view_db.length == table->db_length &&
+ my_strcasecmp(system_charset_info,
+ precedent->view_name.str, table->table_name) == 0 &&
+ my_strcasecmp(system_charset_info,
+ precedent->view_db.str, table->db) == 0)
+ {
+ my_error(ER_VIEW_RECURSIVE, MYF(0),
+ top_view->view_db.str, top_view->view_name.str);
+ DBUG_RETURN(TRUE);
+ }
+ }
+
/*
For now we assume that tables will not be changed during PS life (it
will be TRUE as far as we make new table cache).
@@ -896,7 +915,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table)
}
if (!res && !thd->is_fatal_error)
{
- TABLE_LIST *top_view= table->top_table();
TABLE_LIST *view_tables= lex->query_tables;
TABLE_LIST *view_tables_tail= 0;
TABLE_LIST *tbl;