summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy131
1 files changed, 83 insertions, 48 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 7514b7bec63..ceb4e247848 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -344,7 +344,7 @@ int case_stmt_action_when(LEX *lex, Item *when, bool simple)
(jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
*/
- return !test(i) ||
+ return !MY_TEST(i) ||
sp->push_backpatch(i, ctx->push_label(current_thd, empty_lex_str, 0)) ||
sp->add_cont_backpatch(i) ||
sp->add_instr(i);
@@ -362,7 +362,7 @@ int case_stmt_action_then(LEX *lex)
sp_pcontext *ctx= lex->spcont;
uint ip= sp->instructions();
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
- if (!test(i) || sp->add_instr(i))
+ if (!MY_TEST(i) || sp->add_instr(i))
return 1;
/*
@@ -1155,6 +1155,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token EXISTS /* SQL-2003-R */
%token EXIT_SYM
%token EXPANSION_SYM
+%token EXPORT_SYM
%token EXTENDED_SYM
%token EXTENT_SIZE_SYM
%token EXTRACT_SYM /* SQL-2003-N */
@@ -1664,7 +1665,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <num>
type type_with_opt_collate int_type real_type order_dir lock_option
udf_type opt_if_exists opt_local opt_table_options table_options
- table_option opt_if_not_exists opt_no_write_to_binlog
+ table_option opt_if_not_exists create_or_replace opt_no_write_to_binlog
opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option
field_def
@@ -1771,7 +1772,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <symbol> keyword keyword_sp
%type <lex_user> user grant_user grant_role user_or_role current_role
- admin_option_for_role
+ admin_option_for_role user_maybe_role
%type <charset>
opt_collate
@@ -1828,7 +1829,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
object_privilege object_privilege_list user_list user_and_role_list
rename_list
clear_privileges flush_options flush_option
- opt_with_read_lock flush_options_list
+ opt_flush_lock flush_lock flush_options_list
equal optional_braces
opt_mi_check_type opt_to mi_check_types
table_to_table_list table_to_table opt_table_list opt_as
@@ -1843,7 +1844,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
statement sp_suid
sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
- view_replace_or_algorithm view_replace
view_algorithm view_or_trigger_or_sp_or_event
definer_tail no_definer_tail
view_suid view_tail view_list_opt view_list view_select
@@ -2341,25 +2341,29 @@ connection_name:
/* create a table */
create:
- CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
+ create_or_replace opt_table_options TABLE_SYM opt_if_not_exists table_ident
{
LEX *lex= thd->lex;
lex->sql_command= SQLCOM_CREATE_TABLE;
+ if ($1 && $4)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE", "IF NOT EXISTS");
+ MYSQL_YYABORT;
+ }
if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
TL_OPTION_UPDATING,
TL_WRITE, MDL_EXCLUSIVE))
MYSQL_YYABORT;
- /*
- For CREATE TABLE, an non-existing table is not an error.
- Instruct open_tables() to just take an MDL lock if the
- table does not exist.
- */
- lex->query_tables->open_strategy= TABLE_LIST::OPEN_IF_EXISTS;
lex->alter_info.reset();
lex->col_list.empty();
lex->change=NullS;
bzero((char*) &lex->create_info,sizeof(lex->create_info));
- lex->create_info.options=$2 | $4;
+ /*
+ For CREATE TABLE we should not open the table even if it exists.
+ If the table exists, we should either not create it or replace it
+ */
+ lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
+ lex->create_info.options= ($1 | $2 | $4);
lex->create_info.default_table_charset= NULL;
lex->name.str= 0;
lex->name.length= 0;
@@ -2428,14 +2432,22 @@ create:
lex->name= $4;
lex->create_info.options=$3;
}
- | CREATE
+ | create_or_replace
{
- Lex->create_view_mode= VIEW_CREATE_NEW;
+ Lex->create_view_mode= ($1 == 0 ? VIEW_CREATE_NEW :
+ VIEW_CREATE_OR_REPLACE);
Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED;
Lex->create_view_suid= TRUE;
}
view_or_trigger_or_sp_or_event
- {}
+ {
+ if ($1 && Lex->sql_command != SQLCOM_CREATE_VIEW)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "OR REPLACE",
+ "TRIGGERS / SP / EVENT");
+ MYSQL_YYABORT;
+ }
+ }
| CREATE USER clear_privileges grant_list
{
Lex->sql_command = SQLCOM_CREATE_USER;
@@ -5515,6 +5527,17 @@ opt_if_not_exists:
}
;
+create_or_replace:
+ CREATE /* empty */
+ {
+ $$= 0;
+ }
+ | CREATE OR_SYM REPLACE
+ {
+ $$= HA_LEX_CREATE_REPLACE;
+ }
+ ;
+
opt_create_table_options:
/* empty */
| create_table_options
@@ -10262,7 +10285,7 @@ variable_aux:
if ($$ == NULL)
MYSQL_YYABORT;
LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
+ lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
lex->set_var_list.push_back(item);
}
| ident_or_text
@@ -10271,7 +10294,7 @@ variable_aux:
if ($$ == NULL)
MYSQL_YYABORT;
LEX *lex= Lex;
- lex->uncacheable(UNCACHEABLE_RAND);
+ lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
}
| '@' opt_var_ident_type ident_or_text opt_component
{
@@ -12778,24 +12801,36 @@ flush_options:
YYPS->m_lock_type= TL_READ_NO_INSERT;
YYPS->m_mdl_type= MDL_SHARED_HIGH_PRIO;
}
- opt_table_list {}
- opt_with_read_lock {}
+ opt_table_list opt_flush_lock
| flush_options_list
;
-opt_with_read_lock:
+opt_flush_lock:
/* empty */ {}
- | WITH READ_SYM LOCK_SYM optional_flush_tables_arguments
+ | flush_lock
+ {
+ TABLE_LIST *tables= Lex->query_tables;
+ for (; tables; tables= tables->next_global)
{
- TABLE_LIST *tables= Lex->query_tables;
- Lex->type|= REFRESH_READ_LOCK | $4;
- for (; tables; tables= tables->next_global)
- {
- tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
- tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
- tables->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
- }
+ tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
+ tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
+ tables->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
}
+ }
+ ;
+
+flush_lock:
+ WITH READ_SYM LOCK_SYM optional_flush_tables_arguments
+ { Lex->type|= REFRESH_READ_LOCK | $4; }
+ | FOR_SYM
+ {
+ if (Lex->query_tables == NULL) // Table list can't be empty
+ {
+ my_parse_error(ER(ER_NO_TABLES_USED));
+ MYSQL_YYABORT;
+ }
+ Lex->type|= REFRESH_FOR_EXPORT;
+ } EXPORT_SYM
;
flush_options_list:
@@ -13916,7 +13951,7 @@ ident_or_text:
| LEX_HOSTNAME { $$=$1;}
;
-user:
+user_maybe_role:
ident_or_text
{
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
@@ -13974,7 +14009,15 @@ user:
}
;
-user_or_role: user | current_role;
+user_or_role: user_maybe_role | current_role;
+
+user: user_maybe_role
+ {
+ if ($1->user.str != current_user.str && $1->host.str == 0)
+ $1->host= host_not_specified;
+ $$= $1;
+ }
+ ;
/* Keyword that we allow for identifiers (except SP labels) */
keyword:
@@ -14131,6 +14174,7 @@ keyword_sp:
| EVERY_SYM {}
| EXCHANGE_SYM {}
| EXPANSION_SYM {}
+ | EXPORT_SYM {}
| EXTENDED_SYM {}
| EXTENT_SIZE_SYM {}
| FAULTS_SYM {}
@@ -15148,6 +15192,11 @@ current_role:
grant_role:
ident_or_text
{
+ if ($1.length == 0)
+ {
+ my_error(ER_INVALID_ROLE, MYF(0), "");
+ MYSQL_YYABORT;
+ }
if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
MYSQL_YYABORT;
$$->user = $1;
@@ -15799,7 +15848,7 @@ view_or_trigger_or_sp_or_event:
{}
| no_definer no_definer_tail
{}
- | view_replace_or_algorithm definer_opt view_tail
+ | view_algorithm definer_opt view_tail
{}
;
@@ -15858,20 +15907,6 @@ definer:
**************************************************************************/
-view_replace_or_algorithm:
- view_replace
- {}
- | view_replace view_algorithm
- {}
- | view_algorithm
- {}
- ;
-
-view_replace:
- OR_SYM REPLACE
- { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
- ;
-
view_algorithm:
ALGORITHM_SYM EQ UNDEFINED_SYM
{ Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; }