summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
authorkroki/tomash@moonlight.intranet <>2006-10-12 18:02:57 +0400
committerkroki/tomash@moonlight.intranet <>2006-10-12 18:02:57 +0400
commit591c06d4b771124cc2cf453fbf51d5d99a4ad95e (patch)
tree7ae61d5bb5fd24e75732f9e4edce8de6658ad691 /sql/sql_yacc.yy
parented2d8cce575710f8d821fbaed4f35b6263525d87 (diff)
downloadmariadb-git-591c06d4b771124cc2cf453fbf51d5d99a4ad95e.tar.gz
BUG#20953: create proc with a create view that uses local vars/params
should fail to create The problem was that this type of errors was checked during view creation, which doesn't happen when CREATE VIEW is a statement of a created stored routine. The solution is to perform the checks at parse time. The idea of the fix is that the parser checks if a construction just parsed is allowed in current circumstances by testing certain flags, and this flags are reset for VIEWs. The side effect of this change is that if the user already have such bogus routines, it will now get a error when trying to do SHOW CREATE PROCEDURE proc; (and some other) and when trying to execute such routine he will get ERROR 1457 (HY000): Failed to load routine test.p5. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) However there should be very few such users (if any), and they may (and should) drop these bogus routines.
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy139
1 files changed, 104 insertions, 35 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index deac9cb5c40..523a359e3dd 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -721,7 +721,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item>
literal text_literal insert_ident order_ident
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
table_wild simple_expr udf_expr
expr_or_default set_expr_or_default interval_expr
@@ -4281,32 +4281,7 @@ simple_expr:
}
| literal
| param_marker
- | '@' ident_or_text SET_VAR expr
- {
- $$= 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;
- }
+ | variable
| sum_expr
| simple_expr OR_OR_SYM simple_expr
{ $$= new Item_func_concat($1, $3); }
@@ -5006,6 +4981,46 @@ sum_expr:
$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:
/* empty */ { $$ = 0; }
|DISTINCT { $$ = 1; };
@@ -5428,6 +5443,13 @@ select_derived_init:
SELECT_SYM
{
LEX *lex= Lex;
+
+ if (! lex->parsing_options.allows_derived)
+ {
+ my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
+ YYABORT;
+ }
+
SELECT_LEX *sel= lex->current_select;
TABLE_LIST *embedding;
if (!sel->embedding || sel->end_nested_join(lex->thd))
@@ -5787,6 +5809,13 @@ procedure_clause:
| PROCEDURE ident /* Procedure name */
{
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)
{
my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
@@ -5886,28 +5915,40 @@ select_var_ident:
;
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->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)))
YYABORT;
}
opt_field_term opt_line_term
- | INTO DUMPFILE TEXT_STRING_filesystem
+ | DUMPFILE TEXT_STRING_filesystem
{
LEX *lex=Lex;
if (!lex->describe)
{
lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
- if (!(lex->exchange= new sql_exchange($3.str,1)))
+ if (!(lex->exchange= new sql_exchange($2.str,1)))
YYABORT;
if (!(lex->result= new select_dump(lex->exchange)))
YYABORT;
}
}
- | INTO select_var_list_init
+ | select_var_list_init
{
Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
}
@@ -7067,8 +7108,13 @@ param_marker:
{
THD *thd=YYTHD;
LEX *lex= thd->lex;
- Item_param *item= new Item_param((uint) (lex->tok_start -
- (uchar *) thd->query));
+ Item_param *item;
+ 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))
{
my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
@@ -7188,6 +7234,12 @@ simple_ident:
if (spc && (spv = spc->find_variable(&$1)))
{
/* 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;
splocal= new Item_splocal($1, spv->offset, spv->type,
lex->tok_start_prev -
@@ -7197,7 +7249,6 @@ simple_ident:
splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
- lex->variables_used= 1;
lex->safe_to_cache_query=0;
}
else
@@ -9038,6 +9089,24 @@ view_list:
;
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
{
THD *thd=YYTHD;