Commit 8acc9a96 authored by unknown's avatar unknown

Merge moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.0-bug20953

into  moonlight.intranet:/home/tomash/src/mysql_ab/mysql-5.1-bug20953


mysql-test/r/view.result:
  Auto merged
mysql-test/t/sp-error.test:
  Auto merged
mysql-test/t/view.test:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_view.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
mysql-test/r/sp-error.result:
  Manual merge.
parents aef96fd0 6d1fdc73
...@@ -1226,6 +1226,30 @@ END; ...@@ -1226,6 +1226,30 @@ END;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS bug14702() ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS bug14702()
BEGIN BEGIN
END' at line 1 END' at line 1
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT);
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
ERROR HY000: View's SELECT contains a 'INTO' clause
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
ERROR HY000: View's SELECT contains a 'INTO' clause
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
ERROR HY000: View's SELECT contains a 'INTO' clause
CREATE PROCEDURE bug20953()
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
ERROR HY000: View's SELECT contains a subquery in the FROM clause
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
ERROR HY000: View's SELECT contains a variable or parameter
CREATE PROCEDURE bug20953()
BEGIN
DECLARE i INT;
CREATE VIEW v AS SELECT i;
END |
ERROR HY000: View's SELECT contains a variable or parameter
PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
ERROR HY000: View's SELECT contains a variable or parameter
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
drop function if exists bug16164; drop function if exists bug16164;
create function bug16164() returns int create function bug16164() returns int
......
...@@ -12,6 +12,9 @@ create table t1 (a int, b int); ...@@ -12,6 +12,9 @@ create table t1 (a int, b int);
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1; create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
ERROR HY000: View's SELECT contains a variable or parameter ERROR HY000: View's SELECT contains a variable or parameter
create view v1 (c,d) as select a,b from t1
where a = @@global.max_user_connections;
ERROR HY000: View's SELECT contains a variable or parameter
create view v1 (c) as select b+1 from t1; create view v1 (c) as select b+1 from t1;
select c from v1; select c from v1;
c c
...@@ -596,11 +599,6 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function ...@@ -596,11 +599,6 @@ ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function
drop view v1; drop view v1;
create view v1 (a,a) as select 'a','a'; create view v1 (a,a) as select 'a','a';
ERROR 42S21: Duplicate column name 'a' ERROR 42S21: Duplicate column name 'a'
drop procedure if exists p1;
create procedure p1 () begin declare v int; create view v1 as select v; end;//
call p1();
ERROR HY000: View's SELECT contains a variable or parameter
drop procedure p1;
create table t1 (col1 int,col2 char(22)); create table t1 (col1 int,col2 char(22));
insert into t1 values(5,'Hello, world of views'); insert into t1 values(5,'Hello, world of views');
create view v1 as select * from t1; create view v1 as select * from t1;
...@@ -886,6 +884,8 @@ ERROR HY000: View's SELECT contains a 'INTO' clause ...@@ -886,6 +884,8 @@ ERROR HY000: View's SELECT contains a 'INTO' clause
create table t1 (a int); create table t1 (a int);
create view v1 as select a from t1 procedure analyse(); create view v1 as select a from t1 procedure analyse();
ERROR HY000: View's SELECT contains a 'PROCEDURE' clause ERROR HY000: View's SELECT contains a 'PROCEDURE' clause
create view v1 as select 1 from (select 1) as d1;
ERROR HY000: View's SELECT contains a subquery in the FROM clause
drop table t1; drop table t1;
create table t1 (s1 int, primary key (s1)); create table t1 (s1 int, primary key (s1));
create view v1 as select * from t1; create view v1 as select * from t1;
......
...@@ -1789,6 +1789,48 @@ begin ...@@ -1789,6 +1789,48 @@ begin
return 42; return 42;
end| end|
#
# BUG#20953: create proc with a create view that uses local
# vars/params should fail to create
#
# See test case for what syntax is forbidden in a view.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (i INT);
# We do not have to drop this procedure and view because they won't be
# created.
--error ER_VIEW_SELECT_CLAUSE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO @a;
--error ER_VIEW_SELECT_CLAUSE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO DUMPFILE "file";
--error ER_VIEW_SELECT_CLAUSE
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 INTO OUTFILE "file";
--error ER_VIEW_SELECT_CLAUSE
CREATE PROCEDURE bug20953()
CREATE VIEW v AS SELECT i FROM t1 PROCEDURE ANALYSE();
--error ER_VIEW_SELECT_DERIVED
CREATE PROCEDURE bug20953() CREATE VIEW v AS SELECT 1 FROM (SELECT 1) AS d1;
--error ER_VIEW_SELECT_VARIABLE
CREATE PROCEDURE bug20953(i INT) CREATE VIEW v AS SELECT i;
delimiter |;
--error ER_VIEW_SELECT_VARIABLE
CREATE PROCEDURE bug20953()
BEGIN
DECLARE i INT;
CREATE VIEW v AS SELECT i;
END |
delimiter ;|
--error ER_VIEW_SELECT_VARIABLE
PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
DROP TABLE t1;
# #
# BUG#20701: BINARY keyword should be forbidden in stored routines # BUG#20701: BINARY keyword should be forbidden in stored routines
# #
......
...@@ -23,8 +23,11 @@ create table t1 (a int, b int); ...@@ -23,8 +23,11 @@ create table t1 (a int, b int);
insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
# view with variable # view with variable
-- error 1351 -- error ER_VIEW_SELECT_VARIABLE
create view v1 (c,d) as select a,b+@@global.max_user_connections from t1; create view v1 (c,d) as select a,b+@@global.max_user_connections from t1;
-- error ER_VIEW_SELECT_VARIABLE
create view v1 (c,d) as select a,b from t1
where a = @@global.max_user_connections;
# simple view # simple view
create view v1 (c) as select b+1 from t1; create view v1 (c) as select b+1 from t1;
...@@ -486,19 +489,6 @@ drop view v1; ...@@ -486,19 +489,6 @@ drop view v1;
-- error 1060 -- error 1060
create view v1 (a,a) as select 'a','a'; create view v1 (a,a) as select 'a','a';
#
# SP variables inside view test
#
--disable_warnings
drop procedure if exists p1;
--enable_warnings
delimiter //;
create procedure p1 () begin declare v int; create view v1 as select v; end;//
delimiter ;//
-- error 1351
call p1();
drop procedure p1;
# #
# updatablity should be transitive # updatablity should be transitive
# #
...@@ -820,6 +810,8 @@ create view v1 as select 5 into outfile 'ttt'; ...@@ -820,6 +810,8 @@ create view v1 as select 5 into outfile 'ttt';
create table t1 (a int); create table t1 (a int);
-- error 1350 -- error 1350
create view v1 as select a from t1 procedure analyse(); create view v1 as select a from t1 procedure analyse();
-- error ER_VIEW_SELECT_DERIVED
create view v1 as select 1 from (select 1) as d1;
drop table t1; drop table t1;
# #
......
...@@ -151,7 +151,6 @@ void lex_start(THD *thd, const uchar *buf, uint length) ...@@ -151,7 +151,6 @@ void lex_start(THD *thd, const uchar *buf, uint length)
lex->safe_to_cache_query= 1; lex->safe_to_cache_query= 1;
lex->time_zone_tables_used= 0; lex->time_zone_tables_used= 0;
lex->leaf_tables_insert= 0; lex->leaf_tables_insert= 0;
lex->variables_used= 0;
lex->empty_field_list_on_rset= 0; lex->empty_field_list_on_rset= 0;
lex->select_lex.select_number= 1; lex->select_lex.select_number= 1;
lex->next_state=MY_LEX_START; lex->next_state=MY_LEX_START;
......
...@@ -866,6 +866,25 @@ public: ...@@ -866,6 +866,25 @@ public:
}; };
/*
st_parsing_options contains the flags for constructions that are
allowed in the current statement.
*/
struct st_parsing_options
{
bool allows_variable;
bool allows_select_into;
bool allows_select_procedure;
bool allows_derived;
st_parsing_options()
: allows_variable(TRUE), allows_select_into(TRUE),
allows_select_procedure(TRUE), allows_derived(TRUE)
{}
};
/* The state of the lex parsing. This is saved in the THD struct */ /* The state of the lex parsing. This is saved in the THD struct */
typedef struct st_lex : public Query_tables_list typedef struct st_lex : public Query_tables_list
...@@ -1022,7 +1041,7 @@ typedef struct st_lex : public Query_tables_list ...@@ -1022,7 +1041,7 @@ typedef struct st_lex : public Query_tables_list
bool stmt_prepare_mode; bool stmt_prepare_mode;
bool safe_to_cache_query; bool safe_to_cache_query;
bool subqueries, ignore; bool subqueries, ignore;
bool variables_used; st_parsing_options parsing_options;
ALTER_INFO alter_info; ALTER_INFO alter_info;
/* Prepared statements SQL syntax:*/ /* Prepared statements SQL syntax:*/
LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */ LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
......
...@@ -236,25 +236,9 @@ bool mysql_create_view(THD *thd, ...@@ -236,25 +236,9 @@ bool mysql_create_view(THD *thd,
bool res= FALSE; bool res= FALSE;
DBUG_ENTER("mysql_create_view"); DBUG_ENTER("mysql_create_view");
if (lex->proc_list.first || /* This is ensured in the parser. */
lex->result) DBUG_ASSERT(!lex->proc_list.first && !lex->result &&
{ !lex->param_list.elements && !lex->derived_tables);
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), (lex->result ?
"INTO" :
"PROCEDURE"));
res= TRUE;
goto err;
}
if (lex->derived_tables ||
lex->variables_used || lex->param_list.elements)
{
int err= (lex->derived_tables ?
ER_VIEW_SELECT_DERIVED :
ER_VIEW_SELECT_VARIABLE);
my_message(err, ER(err), MYF(0));
res= TRUE;
goto err;
}
if (mode != VIEW_CREATE_NEW) if (mode != VIEW_CREATE_NEW)
{ {
......
...@@ -793,7 +793,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ...@@ -793,7 +793,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item> %type <item>
literal text_literal insert_ident order_ident literal text_literal insert_ident order_ident
simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
bool_term bool_factor bool_test bool_pri variable variable_aux bool_term bool_factor bool_test bool_pri
predicate bit_expr bit_term bit_factor value_expr term factor predicate bit_expr bit_term bit_factor value_expr term factor
table_wild simple_expr udf_expr table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr expr_or_default set_expr_or_default interval_expr
...@@ -5947,32 +5947,7 @@ simple_expr: ...@@ -5947,32 +5947,7 @@ simple_expr:
} }
| literal | literal
| param_marker | param_marker
| '@' ident_or_text SET_VAR expr | variable
{
$$= new Item_func_set_user_var($2,$4);
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_RAND);
lex->variables_used= 1;
}
| '@' ident_or_text
{
$$= new Item_func_get_user_var($2);
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_RAND);
lex->variables_used= 1;
}
| '@' '@' opt_var_ident_type ident_or_text opt_component
{
if ($4.str && $5.str && check_reserved_words(&$4))
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (!($$= get_system_var(YYTHD, $3, $4, $5)))
YYABORT;
Lex->variables_used= 1;
}
| sum_expr | sum_expr
| simple_expr OR_OR_SYM simple_expr | simple_expr OR_OR_SYM simple_expr
{ $$= new Item_func_concat($1, $3); } { $$= new Item_func_concat($1, $3); }
...@@ -6695,6 +6670,46 @@ sum_expr: ...@@ -6695,6 +6670,46 @@ sum_expr:
$5->empty(); $5->empty();
}; };
variable:
'@'
{
if (! Lex->parsing_options.allows_variable)
{
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
YYABORT;
}
}
variable_aux
{
$$= $3;
}
;
variable_aux:
ident_or_text SET_VAR expr
{
$$= new Item_func_set_user_var($1, $3);
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_RAND);
}
| ident_or_text
{
$$= new Item_func_get_user_var($1);
LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_RAND);
}
| '@' opt_var_ident_type ident_or_text opt_component
{
if ($3.str && $4.str && check_reserved_words(&$3))
{
yyerror(ER(ER_SYNTAX_ERROR));
YYABORT;
}
if (!($$= get_system_var(YYTHD, $2, $3, $4)))
YYABORT;
}
;
opt_distinct: opt_distinct:
/* empty */ { $$ = 0; } /* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; }; |DISTINCT { $$ = 1; };
...@@ -7124,6 +7139,13 @@ select_derived_init: ...@@ -7124,6 +7139,13 @@ select_derived_init:
SELECT_SYM SELECT_SYM
{ {
LEX *lex= Lex; LEX *lex= Lex;
if (! lex->parsing_options.allows_derived)
{
my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
YYABORT;
}
SELECT_LEX *sel= lex->current_select; SELECT_LEX *sel= lex->current_select;
TABLE_LIST *embedding; TABLE_LIST *embedding;
if (!sel->embedding || sel->end_nested_join(lex->thd)) if (!sel->embedding || sel->end_nested_join(lex->thd))
...@@ -7508,6 +7530,13 @@ procedure_clause: ...@@ -7508,6 +7530,13 @@ procedure_clause:
| PROCEDURE ident /* Procedure name */ | PROCEDURE ident /* Procedure name */
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (! lex->parsing_options.allows_select_procedure)
{
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
YYABORT;
}
if (&lex->select_lex != lex->current_select) if (&lex->select_lex != lex->current_select)
{ {
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"); my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
...@@ -7607,28 +7636,40 @@ select_var_ident: ...@@ -7607,28 +7636,40 @@ select_var_ident:
; ;
into: into:
INTO OUTFILE TEXT_STRING_filesystem INTO
{
if (! Lex->parsing_options.allows_select_into)
{
my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
YYABORT;
}
}
into_destination
;
into_destination:
OUTFILE TEXT_STRING_filesystem
{ {
LEX *lex= Lex; LEX *lex= Lex;
lex->uncacheable(UNCACHEABLE_SIDEEFFECT); lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($3.str, 0)) || if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
!(lex->result= new select_export(lex->exchange))) !(lex->result= new select_export(lex->exchange)))
YYABORT; YYABORT;
} }
opt_field_term opt_line_term opt_field_term opt_line_term
| INTO DUMPFILE TEXT_STRING_filesystem | DUMPFILE TEXT_STRING_filesystem
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (!lex->describe) if (!lex->describe)
{ {
lex->uncacheable(UNCACHEABLE_SIDEEFFECT); lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
if (!(lex->exchange= new sql_exchange($3.str,1))) if (!(lex->exchange= new sql_exchange($2.str,1)))
YYABORT; YYABORT;
if (!(lex->result= new select_dump(lex->exchange))) if (!(lex->result= new select_dump(lex->exchange)))
YYABORT; YYABORT;
} }
} }
| INTO select_var_list_init | select_var_list_init
{ {
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
} }
...@@ -8837,8 +8878,13 @@ param_marker: ...@@ -8837,8 +8878,13 @@ param_marker:
{ {
THD *thd=YYTHD; THD *thd=YYTHD;
LEX *lex= thd->lex; LEX *lex= thd->lex;
Item_param *item= new Item_param((uint) (lex->tok_start - Item_param *item;
(uchar *) thd->query)); if (! lex->parsing_options.allows_variable)
{
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
YYABORT;
}
item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query));
if (!($$= item) || lex->param_list.push_back(item)) if (!($$= item) || lex->param_list.push_back(item))
{ {
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
...@@ -8958,6 +9004,12 @@ simple_ident: ...@@ -8958,6 +9004,12 @@ simple_ident:
if (spc && (spv = spc->find_variable(&$1))) if (spc && (spv = spc->find_variable(&$1)))
{ {
/* We're compiling a stored procedure and found a variable */ /* We're compiling a stored procedure and found a variable */
if (! lex->parsing_options.allows_variable)
{
my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
YYABORT;
}
Item_splocal *splocal; Item_splocal *splocal;
splocal= new Item_splocal($1, spv->offset, spv->type, splocal= new Item_splocal($1, spv->offset, spv->type,
lex->tok_start_prev - lex->tok_start_prev -
...@@ -8967,7 +9019,6 @@ simple_ident: ...@@ -8967,7 +9019,6 @@ simple_ident:
splocal->m_sp= lex->sphead; splocal->m_sp= lex->sphead;
#endif #endif
$$ = (Item*) splocal; $$ = (Item*) splocal;
lex->variables_used= 1;
lex->safe_to_cache_query=0; lex->safe_to_cache_query=0;
} }
else else
...@@ -10866,6 +10917,24 @@ view_list: ...@@ -10866,6 +10917,24 @@ view_list:
; ;
view_select: view_select:
{
LEX *lex= Lex;
lex->parsing_options.allows_variable= FALSE;
lex->parsing_options.allows_select_into= FALSE;
lex->parsing_options.allows_select_procedure= FALSE;
lex->parsing_options.allows_derived= FALSE;
}
view_select_aux
{
LEX *lex= Lex;
lex->parsing_options.allows_variable= TRUE;
lex->parsing_options.allows_select_into= TRUE;
lex->parsing_options.allows_select_procedure= TRUE;
lex->parsing_options.allows_derived= TRUE;
}
;
view_select_aux:
SELECT_SYM remember_name select_init2 SELECT_SYM remember_name select_init2
{ {
THD *thd=YYTHD; THD *thd=YYTHD;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment