diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 3193 |
1 files changed, 1529 insertions, 1664 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2d692e9e53b..c9c922f6a55 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -65,6 +65,8 @@ #include "set_var.h" #include "rpl_mi.h" #include "lex_token.h" +#include "sql_lex.h" +#include "sql_sequence.h" /* this is to get the bison compilation windows warnings out */ #ifdef _MSC_VER @@ -98,7 +100,7 @@ int yylex(void *yylval, void *yythd); #define MYSQL_YYABORT_UNLESS(A) \ if (!(A)) \ { \ - my_parse_error(thd, ER_SYNTAX_ERROR); \ + thd->parse_error(); \ MYSQL_YYABORT; \ } @@ -111,43 +113,6 @@ int yylex(void *yylval, void *yythd); #define YYDEBUG 0 #endif -/** - @brief Push an error message into MySQL error stack with line - and position information. - - This function provides semantic action implementers with a way - to push the famous "You have a syntax error near..." error - message into the error stack, which is normally produced only if - a parse error is discovered internally by the Bison generated - parser. -*/ - -static void my_parse_error_intern(THD *thd, const char *err_text, - const char *yytext) -{ - Lex_input_stream *lip= &thd->m_parser_state->m_lip; - if (!yytext) - { - if (!(yytext= lip->get_tok_start())) - yytext= ""; - } - /* Push an error into the error stack */ - ErrConvString err(yytext, strlen(yytext), - thd->variables.character_set_client); - my_error(ER_PARSE_ERROR, MYF(0), err_text, err.ptr(), lip->yylineno); -} - - -static void my_parse_error(THD *thd, uint err_number, const char *yytext=0) -{ - return my_parse_error_intern(thd, ER_THD(thd, err_number), yytext); -} - -void LEX::parse_error() -{ - my_parse_error(thd, ER_SYNTAX_ERROR); -} - /** @brief Bison callback to report a syntax/OOM error @@ -164,7 +129,7 @@ void LEX::parse_error() This function is not for use in semantic actions and is internal to the parser, as it performs some pre-return cleanup. - In semantic actions, please use my_parse_error or my_error to + In semantic actions, please use thd->parse_error() or my_error to push an error into the error stack and MYSQL_YYABORT to abort from the parser. */ @@ -181,7 +146,7 @@ void MYSQLerror(THD *thd, const char *s) /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s= ER_THD(thd, ER_SYNTAX_ERROR); - my_parse_error_intern(thd, s, 0); + thd->parse_error(s, 0); } @@ -207,80 +172,6 @@ void turn_parser_debug_on() } #endif -static bool is_native_function(THD *thd, const LEX_STRING *name) -{ - if (find_native_function_builder(thd, *name)) - return true; - - if (is_lex_native_function(name)) - return true; - - return false; -} - - -static sp_head *make_sp_head(THD *thd, sp_name *name, - enum stored_procedure_type type) -{ - LEX *lex= thd->lex; - sp_head *sp; - - /* Order is important here: new - reset - init */ - if ((sp= new sp_head())) - { - sp->reset_thd_mem_root(thd); - sp->init(lex); - sp->m_type= type; - if (name) - sp->init_sp_name(thd, name); - sp->m_chistics= &lex->sp_chistics; - lex->sphead= sp; - } - bzero(&lex->sp_chistics, sizeof(lex->sp_chistics)); - return sp; -} - -static bool maybe_start_compound_statement(THD *thd) -{ - if (!thd->lex->sphead) - { - if (!make_sp_head(thd, NULL, TYPE_ENUM_PROCEDURE)) - return 1; - - Lex->sp_chistics.suid= SP_IS_NOT_SUID; - Lex->sphead->set_body_start(thd, YYLIP->get_cpp_ptr()); - } - return 0; -} - -static bool push_sp_label(THD *thd, LEX_STRING label) -{ - sp_pcontext *ctx= thd->lex->spcont; - sp_label *lab= ctx->find_label(label); - - if (lab) - { - my_error(ER_SP_LABEL_REDEFINE, MYF(0), label.str); - return 1; - } - else - { - lab= thd->lex->spcont->push_label(thd, label, - thd->lex->sphead->instructions()); - lab->type= sp_label::ITERATION; - } - return 0; -} - -static bool push_sp_empty_label(THD *thd) -{ - if (maybe_start_compound_statement(thd)) - return 1; - /* Unlabeled controls get an empty label. */ - thd->lex->spcont->push_label(thd, empty_lex_str, - thd->lex->sphead->instructions()); - return 0; -} /** Helper action for a case expression statement (the expr in 'CASE expr'). @@ -290,22 +181,20 @@ static bool push_sp_empty_label(THD *thd) @return 0 on success */ -int case_stmt_action_expr(LEX *lex, Item* expr) +int LEX::case_stmt_action_expr(Item* expr) { - sp_head *sp= lex->sphead; - sp_pcontext *parsing_ctx= lex->spcont; - int case_expr_id= parsing_ctx->register_case_expr(); + int case_expr_id= spcont->register_case_expr(); sp_instr_set_case_expr *i; - if (parsing_ctx->push_case_expr_id(case_expr_id)) + if (spcont->push_case_expr_id(case_expr_id)) return 1; - i= new (lex->thd->mem_root) - sp_instr_set_case_expr(sp->instructions(), parsing_ctx, case_expr_id, expr, - lex); + i= new (thd->mem_root) + sp_instr_set_case_expr(sphead->instructions(), spcont, case_expr_id, expr, + this); - sp->add_cont_backpatch(i); - return sp->add_instr(i); + sphead->add_cont_backpatch(i); + return sphead->add_instr(i); } /** @@ -316,33 +205,30 @@ int case_stmt_action_expr(LEX *lex, Item* expr) @param simple true for simple cases, false for searched cases */ -int case_stmt_action_when(LEX *lex, Item *when, bool simple) +int LEX::case_stmt_action_when(Item *when, bool simple) { - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - uint ip= sp->instructions(); + uint ip= sphead->instructions(); sp_instr_jump_if_not *i; Item_case_expr *var; Item *expr; - THD *thd= lex->thd; if (simple) { var= new (thd->mem_root) - Item_case_expr(thd, ctx->get_current_case_expr_id()); + Item_case_expr(thd, spcont->get_current_case_expr_id()); #ifndef DBUG_OFF if (var) { - var->m_sp= sp; + var->m_sp= sphead; } #endif expr= new (thd->mem_root) Item_func_eq(thd, var, when); - i= new (thd->mem_root) sp_instr_jump_if_not(ip, ctx, expr, lex); + i= new (thd->mem_root) sp_instr_jump_if_not(ip, spcont, expr, this); } else - i= new (thd->mem_root) sp_instr_jump_if_not(ip, ctx, when, lex); + i= new (thd->mem_root) sp_instr_jump_if_not(ip, spcont, when, this); /* BACKPATCH: Registering forward jump from @@ -350,10 +236,11 @@ 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 !MY_TEST(i) || - sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || - sp->add_cont_backpatch(i) || - sp->add_instr(i); + return + !MY_TEST(i) || + sphead->push_backpatch(thd, i, spcont->push_label(thd, &empty_clex_str, 0)) || + sphead->add_cont_backpatch(i) || + sphead->add_instr(i); } /** @@ -362,13 +249,11 @@ int case_stmt_action_when(LEX *lex, Item *when, bool simple) @param lex the parser lex context */ -int case_stmt_action_then(LEX *lex) +int LEX::case_stmt_action_then() { - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - uint ip= sp->instructions(); - sp_instr_jump *i= new (lex->thd->mem_root) sp_instr_jump(ip, ctx); - if (!MY_TEST(i) || sp->add_instr(i)) + uint ip= sphead->instructions(); + sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, spcont); + if (!MY_TEST(i) || sphead->add_instr(i)) return 1; /* @@ -377,7 +262,7 @@ int case_stmt_action_then(LEX *lex) (jump_if_not from instruction 2 to 5, 5 to 8 ... in the example) */ - sp->backpatch(ctx->pop_label()); + sphead->backpatch(spcont->pop_label()); /* BACKPATCH: Registering forward jump from @@ -385,18 +270,7 @@ int case_stmt_action_then(LEX *lex) (jump from instruction 4 to 12, 7 to 12 ... in the example) */ - return sp->push_backpatch(lex->thd, i, ctx->last_label()); -} - -static bool -find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp) -{ - tmp->var= find_sys_var(thd, tmp->base_name.str, tmp->base_name.length); - - if (tmp->var != NULL) - tmp->base_name= null_lex_str; - - return thd->is_error(); + return sphead->push_backpatch(thd, i, spcont->last_label()); } @@ -404,7 +278,6 @@ find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp) Helper action for a SET statement. Used to push a system variable into the assignment list. - @param thd the current thread @param tmp the system variable with base name @param var_type the scope of the variable @param val the value being assigned to the variable @@ -412,16 +285,15 @@ find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp) @return TRUE if error, FALSE otherwise. */ -static bool -set_system_variable(THD *thd, struct sys_var_with_base *tmp, - enum enum_var_type var_type, Item *val) +bool +LEX::set_system_variable(struct sys_var_with_base *tmp, + enum enum_var_type var_type, Item *val) { set_var *var; - LEX *lex= thd->lex; /* No AUTOCOMMIT from a stored function or trigger. */ - if (lex->spcont && tmp->var == Sys_autocommit_ptr) - lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + if (spcont && tmp->var == Sys_autocommit_ptr) + sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; if (val && val->type() == Item::FIELD_ITEM && ((Item_field*)val)->table_name) @@ -434,45 +306,7 @@ set_system_variable(THD *thd, struct sys_var_with_base *tmp, set_var(thd, var_type, tmp->var, &tmp->base_name, val))) return TRUE; - return lex->var_list.push_back(var, thd->mem_root); -} - - -/** - Helper action for a SET statement. - Used to push a SP local variable into the assignment list. - - @param thd the current thread - @param var_type the SP local variable - @param val the value being assigned to the variable - - @return TRUE if error, FALSE otherwise. -*/ - -static bool -set_local_variable(THD *thd, sp_variable *spv, Item *val) -{ - Item *it; - LEX *lex= thd->lex; - sp_instr_set *sp_set; - - if (val) - it= val; - else if (spv->default_value) - it= spv->default_value; - else - { - it= new (thd->mem_root) Item_null(thd); - if (it == NULL) - return TRUE; - } - - sp_set= new (thd->mem_root) - sp_instr_set(lex->sphead->instructions(), lex->spcont, - spv->offset, it, spv->sql_type(), - lex, TRUE); - - return (sp_set == NULL || lex->sphead->add_instr(sp_set)); + return var_list.push_back(var, thd->mem_root); } @@ -480,17 +314,14 @@ set_local_variable(THD *thd, sp_variable *spv, Item *val) Helper action for a SET statement. Used to SET a field of NEW row. - @param thd the current thread @param name the field name @param val the value being assigned to the row @return TRUE if error, FALSE otherwise. */ -static bool -set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val) +bool LEX::set_trigger_new_row(LEX_CSTRING *name, Item *val) { - LEX *lex= thd->lex; Item_trigger_field *trg_fld; sp_instr_set_trigger_field *sp_fld; @@ -498,22 +329,21 @@ set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val) if (! val) val= new (thd->mem_root) Item_null(thd); - DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE && - (lex->trg_chistics.event == TRG_EVENT_INSERT || - lex->trg_chistics.event == TRG_EVENT_UPDATE)); + DBUG_ASSERT(trg_chistics.action_time == TRG_ACTION_BEFORE && + (trg_chistics.event == TRG_EVENT_INSERT || + trg_chistics.event == TRG_EVENT_UPDATE)); trg_fld= new (thd->mem_root) - Item_trigger_field(thd, lex->current_context(), + Item_trigger_field(thd, current_context(), Item_trigger_field::NEW_ROW, - name->str, UPDATE_ACL, FALSE); + name, UPDATE_ACL, FALSE); if (trg_fld == NULL) return TRUE; sp_fld= new (thd->mem_root) - sp_instr_set_trigger_field(lex->sphead->instructions(), - lex->spcont, trg_fld, val, - lex); + sp_instr_set_trigger_field(sphead->instructions(), + spcont, trg_fld, val, this); if (sp_fld == NULL) return TRUE; @@ -522,16 +352,15 @@ set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val) Let us add this item to list of all Item_trigger_field objects in trigger. */ - lex->trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field); + trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field); - return lex->sphead->add_instr(sp_fld); + return sphead->add_instr(sp_fld); } /** Create an object to represent a SP variable in the Item-hierarchy. - @param thd The current thread. @param name The SP variable name. @param spvar The SP variable (optional). @param start_in_q Start position of the SP variable name in the query. @@ -543,29 +372,27 @@ set_trigger_new_row(THD *thd, LEX_STRING *name, Item *val) @return An Item_splocal object representing the SP variable, or NULL on error. */ -static Item_splocal* -create_item_for_sp_var(THD *thd, LEX_STRING name, sp_variable *spvar, - const char *start_in_q, const char *end_in_q) +Item_splocal* +LEX::create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar, + const char *start_in_q, const char *end_in_q) { Item_splocal *item; - LEX *lex= thd->lex; uint pos_in_q, len_in_q; - sp_pcontext *spc = lex->spcont; /* If necessary, look for the variable. */ - if (spc && !spvar) - spvar= spc->find_variable(name, false); + if (spcont && !spvar) + spvar= spcont->find_variable(name, false); if (!spvar) { - my_error(ER_SP_UNDECLARED_VAR, MYF(0), name.str); + my_error(ER_SP_UNDECLARED_VAR, MYF(0), name->str); return NULL; } - DBUG_ASSERT(spc && spvar); + DBUG_ASSERT(spcont && spvar); /* Position and length of the SP variable name in the query. */ - pos_in_q= start_in_q - lex->sphead->m_tmp_query; + pos_in_q= start_in_q - sphead->m_tmp_query; len_in_q= end_in_q - start_in_q; item= new (thd->mem_root) @@ -574,7 +401,7 @@ create_item_for_sp_var(THD *thd, LEX_STRING name, sp_variable *spvar, #ifndef DBUG_OFF if (item) - item->m_sp= lex->sphead; + item->m_sp= sphead; #endif return item; @@ -673,58 +500,75 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, @return <code>false</code> if successful, <code>true</code> if an error was reported. In the latter case parsing should stop. */ -bool add_select_to_union_list(LEX *lex, bool is_union_distinct, - bool is_top_level) +bool LEX::add_select_to_union_list(bool is_union_distinct, + enum sub_select_type type, + bool is_top_level) { - /* + const char *type_name= (type == INTERSECT_TYPE ? "INTERSECT" : + (type == EXCEPT_TYPE ? "EXCEPT" : "UNION")); + /* Only the last SELECT can have INTO. Since the grammar won't allow INTO in a nested SELECT, we make this check only when creating a top-level SELECT. */ - if (is_top_level && lex->result) + if (is_top_level && result) { - my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); + my_error(ER_WRONG_USAGE, MYF(0), type_name, "INTO"); return TRUE; } - if (lex->current_select->order_list.first && !lex->current_select->braces) + if (current_select->order_list.first && !current_select->braces) { - my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY"); + my_error(ER_WRONG_USAGE, MYF(0), type_name, "ORDER BY"); return TRUE; } - if (lex->current_select->explicit_limit && !lex->current_select->braces) + if (current_select->explicit_limit && !current_select->braces) { - my_error(ER_WRONG_USAGE, MYF(0), "UNION", "LIMIT"); + my_error(ER_WRONG_USAGE, MYF(0), type_name, "LIMIT"); return TRUE; } - if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + if (current_select->linkage == GLOBAL_OPTIONS_TYPE) { - my_parse_error(lex->thd, ER_SYNTAX_ERROR); + thd->parse_error(); return TRUE; } + if (!is_union_distinct && (type == INTERSECT_TYPE || type == EXCEPT_TYPE)) + { + my_error(ER_WRONG_USAGE, MYF(0), type_name, "ALL"); + return TRUE; + } + /* + Priority implementation, but also trying to keep things as flat + as possible */ + if (type == INTERSECT_TYPE && + (current_select->linkage != INTERSECT_TYPE && + current_select != current_select->master_unit()->first_select())) + { + /* + This and previous SELECTs should go one level down because of + priority + */ + SELECT_LEX *prev= exclude_last_select(); + if (add_unit_in_brackets(prev)) + return TRUE; + return add_select_to_union_list(is_union_distinct, type, 0); + } + else + { + check_automatic_up(type); + } /* This counter shouldn't be incremented for UNION parts */ - lex->nest_level--; - if (mysql_new_select(lex, 0)) + nest_level--; + if (mysql_new_select(this, 0, NULL)) return TRUE; - mysql_init_select(lex); - lex->current_select->linkage=UNION_TYPE; + mysql_init_select(this); + current_select->linkage= type; if (is_union_distinct) /* UNION DISTINCT - remember position */ - lex->current_select->master_unit()->union_distinct= - lex->current_select; - return FALSE; -} - - -static bool add_create_index_prepare(LEX *lex, Table_ident *table) -{ - lex->sql_command= SQLCOM_CREATE_INDEX; - if (!lex->current_select->add_table_to_list(lex->thd, table, NULL, - TL_OPTION_UPDATING, - TL_READ_NO_INSERT, - MDL_SHARED_UPGRADABLE)) - return TRUE; - lex->alter_info.reset(); - lex->alter_info.flags= Alter_info::ALTER_ADD_INDEX; - lex->option_list= NULL; + { + current_select->master_unit()->union_distinct= + current_select; + } + else + DBUG_ASSERT(type == UNION_TYPE); return FALSE; } @@ -747,7 +591,7 @@ static bool add_create_index_prepare(LEX *lex, Table_ident *table) @param no_lookahead True if the parser has no lookahead */ -static void sp_create_assignment_lex(THD *thd, bool no_lookahead) +void sp_create_assignment_lex(THD *thd, bool no_lookahead) { LEX *lex= thd->lex; @@ -785,7 +629,7 @@ static void sp_create_assignment_lex(THD *thd, bool no_lookahead) @return false if success, true otherwise. */ -static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) +bool sp_create_assignment_instr(THD *thd, bool no_lookahead) { LEX *lex= thd->lex; @@ -838,50 +682,33 @@ static bool sp_create_assignment_instr(THD *thd, bool no_lookahead) return false; } - -static void add_key_to_list(LEX *lex, LEX_STRING *field_name, - enum Key::Keytype type, bool check_exists) +void LEX::add_key_to_list(LEX_CSTRING *field_name, + enum Key::Keytype type, bool check_exists) { Key *key; - MEM_ROOT *mem_root= lex->thd->mem_root; + MEM_ROOT *mem_root= thd->mem_root; key= new (mem_root) - Key(type, null_lex_str, HA_KEY_ALG_UNDEF, false, + Key(type, &null_clex_str, HA_KEY_ALG_UNDEF, false, DDL_options(check_exists ? DDL_options::OPT_IF_NOT_EXISTS : DDL_options::OPT_NONE)); - key->columns.push_back(new (mem_root) Key_part_spec(*field_name, 0), + key->columns.push_back(new (mem_root) Key_part_spec(field_name, 0), mem_root); - lex->alter_info.key_list.push_back(key, mem_root); + alter_info.key_list.push_back(key, mem_root); } -void LEX::init_last_field(Column_definition *field, const char *field_name, - CHARSET_INFO *cs) +void LEX::init_last_field(Column_definition *field, + const LEX_CSTRING *field_name, + const CHARSET_INFO *cs) { last_field= field; - field->field_name= field_name; + field->field_name= *field_name; /* reset LEX fields that are used in Create_field::set_and_check() */ charset= cs; } -void LEX::set_last_field_type(const Lex_field_type_st &type) -{ - last_field->sql_type= type.field_type(); - last_field->charset= charset; - - if (type.length()) - { - int err; - last_field->length= my_strtoll10(type.length(), NULL, &err); - if (err) - last_field->length= ~0ULL; // safety - } - else - last_field->length= 0; - - last_field->decimals= type.dec() ? (uint)atoi(type.dec()) : 0; -} bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) { @@ -929,19 +756,33 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) ulong ulong_num; ulonglong ulonglong_number; longlong longlong_number; + uint sp_instr_addr; /* structs */ - LEX_STRING lex_str; + LEX_CSTRING lex_str; LEX_SYMBOL symbol; + Lex_string_with_metadata_st lex_string_with_metadata; struct sys_var_with_base variable; - struct { int vars, conds, hndlrs, curs; } spblock; + Lex_string_with_pos_st lex_string_with_pos; + Lex_spblock_st spblock; + Lex_spblock_handlers_st spblock_handlers; Lex_length_and_dec_st Lex_length_and_dec; Lex_cast_type_st Lex_cast_type; Lex_field_type_st Lex_field_type; Lex_dyncol_type_st Lex_dyncol_type; + Lex_for_loop_st for_loop; + Lex_for_loop_bounds_st for_loop_bounds; + struct + { + LEX_CSTRING name; + uint offset; + } sp_cursor_name_and_offset; /* pointers */ Create_field *create_field; + Spvar_definition *spvar_definition; + Row_definition_list *spvar_definition_list; + const Type_handler *type_handler; CHARSET_INFO *charset; Condition_information_item *cond_info_item; DYNCALL_CREATE_DEF *dyncol_def; @@ -951,25 +792,28 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) Item_param *item_param; Key_part_spec *key_part; LEX *lex; - LEX_STRING *lex_str_ptr; + sp_assignment_lex *assignment_lex; + class sp_lex_cursor *sp_cursor_stmt; + LEX_CSTRING *lex_str_ptr; LEX_USER *lex_user; List<Condition_information_item> *cond_info_list; List<DYNCALL_CREATE_DEF> *dyncol_def_list; List<Item> *item_list; + List<sp_assignment_lex> *sp_assignment_lex_list; List<Statement_information_item> *stmt_info_list; List<String> *string_list; - List<LEX_STRING> *lex_str_list; + List<LEX_CSTRING> *lex_str_list; Statement_information_item *stmt_info_item; String *string; TABLE_LIST *table_list; Table_ident *table; + Qualified_column_ident *qualified_column_ident; char *simple_string; const char *const_simple_string; chooser_compare_func_creator boolfunc2creator; class my_var *myvar; class sp_condition_value *spcondvalue; class sp_head *sphead; - class sp_label *splabel; class sp_name *spname; class sp_variable *spvar; class With_clause *with_clause; @@ -984,6 +828,8 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) st_trg_execution_order trg_execution_order; /* enums */ + enum enum_view_suid view_suid; + enum sub_select_type unit_type; enum Condition_information_item::Name cond_info_item_name; enum enum_diag_condition_item_name diag_condition_item_name; enum Diagnostics_information::Which_area diag_area; @@ -992,7 +838,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr) enum Item_udftype udf_type; enum Key::Keytype key_type; enum Statement_information_item::Name stmt_info_item_name; - enum enum_field_types field_type; enum enum_filetype filetype; enum enum_tx_isolation tx_isolation; enum enum_var_type var_type; @@ -1112,6 +957,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CLASS_ORIGIN_SYM /* SQL-2003-N */ %token CLIENT_SYM %token CLOSE_SYM /* SQL-2003-R */ +%token CLOB /* SQL-2003-R */ %token COALESCE /* SQL-2003-N */ %token CODE_SYM %token COLLATE_SYM /* SQL-2003-R */ @@ -1157,6 +1003,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CURSOR_SYM /* SQL-2003-R */ %token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ +%token CYCLE_SYM %token DATABASE %token DATABASES %token DATAFILE_SYM @@ -1174,6 +1021,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DECIMAL_NUM %token DECIMAL_SYM /* SQL-2003-R */ %token DECLARE_SYM /* SQL-2003-R */ +%token DECODE_SYM /* Oracle function, non-reserved */ %token DEFAULT /* SQL-2003-R */ %token DEFINER_SYM %token DELAYED_SYM @@ -1194,6 +1042,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DOUBLE_SYM /* SQL-2003-R */ %token DO_DOMAIN_IDS_SYM %token DO_SYM +%token DOT_DOT_SYM %token DROP /* SQL-2003-R */ %token DUAL_SYM %token DUMPFILE @@ -1202,6 +1051,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token EACH_SYM /* SQL-2003-R */ %token ELSE /* SQL-2003-R */ %token ELSEIF_SYM +%token ELSIF_SYM /* Oracle, reserved in PL/SQL*/ %token ENABLE_SYM %token ENCLOSED %token END /* SQL-2003-R */ @@ -1220,8 +1070,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token EVERY_SYM /* SQL-2003-N */ %token EXCHANGE_SYM %token EXAMINED_SYM +%token EXCEPT_SYM /* SQL-2003-R */ %token EXCLUDE_SYM /* SQL-2011-N */ %token EXECUTE_SYM /* SQL-2003-R */ +%token EXCEPTION_SYM /* SQL-2003-N */ %token EXISTS /* SQL-2003-R */ %token EXIT_SYM %token EXPANSION_SYM @@ -1259,6 +1111,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token GET_FORMAT /* MYSQL-FUNC */ %token GET_SYM /* SQL-2003-R */ %token GLOBAL_SYM /* SQL-2003-R */ +%token GOTO_SYM /* Oracle, reserved in PL/SQL*/ %token GRANT /* SQL-2003-R */ %token GRANTS %token GROUP_SYM /* SQL-2003-R */ @@ -1289,6 +1142,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token IGNORE_SERVER_IDS_SYM %token IMMEDIATE_SYM /* SQL-2003-R */ %token IMPORT +%token INCREMENT_SYM %token INDEXES %token INDEX_SYM %token INFILE @@ -1299,6 +1153,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token INSERT /* SQL-2003-R */ %token INSERT_METHOD %token INSTALL_SYM +%token INTERSECT_SYM /* SQL-2003-R */ %token INTERVAL_SYM /* SQL-2003-R */ %token INTO /* SQL-2003-R */ %token INT_SYM /* SQL-2003-R */ @@ -1308,6 +1163,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token IPC_SYM %token IS /* SQL-2003-R */ %token ISOLATION /* SQL-2003-R */ +%token ISOPEN_SYM /* Oracle-N */ %token ISSUER_SYM %token ITERATE_SYM %token JOIN_SYM /* SQL-2003-R */ @@ -1319,6 +1175,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token LANGUAGE_SYM /* SQL-2003-R */ %token LAST_SYM /* SQL-2003-N */ %token LAST_VALUE +%token LASTVAL_SYM /* PostgreSQL sequence function */ %token LE /* OPERATOR */ %token LEADING /* SQL-2003-R */ %token LEAVES @@ -1377,7 +1234,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MAX_UPDATES_PER_HOUR %token MAX_STATEMENT_TIME_SYM %token MAX_USER_CONNECTIONS_SYM -%token MAX_VALUE_SYM /* SQL-2003-N */ +%token MAXVALUE_SYM /* SQL-2003-N */ %token MEDIUMBLOB %token MEDIUMINT %token MEDIUMTEXT @@ -1390,6 +1247,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MINUTE_MICROSECOND_SYM %token MINUTE_SECOND_SYM %token MINUTE_SYM /* SQL-2003-R */ +%token MINVALUE_SYM %token MIN_ROWS %token MIN_SYM /* SQL-2003-N */ %token MODE_SYM @@ -1413,12 +1271,18 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token NEG %token NEW_SYM /* SQL-2003-R */ %token NEXT_SYM /* SQL-2003-N */ +%token NEXTVAL_SYM /* PostgreSQL sequence function */ +%token NOCACHE_SYM +%token NOCYCLE_SYM %token NODEGROUP_SYM %token NONE_SYM /* SQL-2003-R */ %token NOT2_SYM %token NOT_SYM /* SQL-2003-R */ +%token NOTFOUND_SYM /* Oracle-R */ %token NOW_SYM %token NO_SYM /* SQL-2003-R */ +%token NOMAXVALUE_SYM +%token NOMINVALUE_SYM %token NO_WAIT_SYM %token NO_WRITE_TO_BINLOG %token NTILE_SYM @@ -1428,6 +1292,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token NUMERIC_SYM /* SQL-2003-R */ %token NTH_VALUE_SYM /* SQL-2011 */ %token NVARCHAR_SYM +%token OF_SYM /* SQL-1992-R, Oracle-R */ %token OFFSET_SYM %token OLD_PASSWORD_SYM %token ON /* SQL-2003-R */ @@ -1475,6 +1340,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token PREPARE_SYM /* SQL-2003-R */ %token PRESERVE_SYM %token PREV_SYM +%token PREVIOUS_SYM %token PRIMARY_SYM /* SQL-2003-R */ %token PRIVILEGES /* SQL-2003-N */ %token PROCEDURE_SYM /* SQL-2003-R */ @@ -1487,8 +1353,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token QUARTER_SYM %token QUERY_SYM %token QUICK +%token RAISE_SYM /* Oracle-PLSQL-R */ %token RANGE_SYM /* SQL-2003-R */ %token RANK_SYM +%token RAW /* Oracle */ %token READS_SYM /* SQL-2003-R */ %token READ_ONLY_SYM %token READ_SYM /* SQL-2003-N */ @@ -1519,6 +1387,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token REPLICATION %token REQUIRE_SYM %token RESET_SYM +%token RESTART_SYM %token RESIGNAL_SYM /* SQL-2003-R */ %token RESOURCES %token RESTORE_SYM @@ -1528,6 +1397,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token RETURNING_SYM %token RETURNS_SYM /* SQL-2003-R */ %token RETURN_SYM /* SQL-2003-R */ +%token REUSE_SYM /* Oracle-R */ %token REVERSE_SYM %token REVOKE /* SQL-2003-R */ %token RIGHT /* SQL-2003-R */ @@ -1535,8 +1405,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ROLLBACK_SYM /* SQL-2003-R */ %token ROLLUP_SYM /* SQL-2003-R */ %token ROUTINE_SYM /* SQL-2003-N */ +%token ROWCOUNT_SYM /* Oracle-N */ %token ROW_SYM /* SQL-2003-R */ %token ROWS_SYM /* SQL-2003-R */ +%token ROWTYPE_SYM /* Oracle-PLSQL-R */ %token ROW_COUNT_SYM /* SQL-2003-N */ %token ROW_FORMAT_SYM %token ROW_NUMBER_SYM @@ -1550,12 +1422,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SELECT_SYM /* SQL-2003-R */ %token SENSITIVE_SYM /* FUTURE-USE */ %token SEPARATOR_SYM +%token SEQUENCE_SYM %token SERIALIZABLE_SYM /* SQL-2003-N */ %token SERIAL_SYM %token SESSION_SYM /* SQL-2003-N */ %token SERVER_SYM %token SERVER_OPTIONS %token SET /* SQL-2003-R */ +%token SETVAL_SYM /* PostgreSQL sequence function */ %token SET_VAR %token SHARE_SYM %token SHIFT_LEFT /* OPERATOR */ @@ -1681,6 +1555,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token VALUE_SYM /* SQL-2003-R */ %token VARBINARY %token VARCHAR /* SQL-2003-R */ +%token VARCHAR2 /* Oracle */ %token VARIABLES %token VARIANCE_SYM %token VARYING /* SQL-2003-R */ @@ -1733,35 +1608,52 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %left INTERVAL_SYM %type <lex_str> - IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM + IDENT IDENT_QUOTED DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM HEX_STRING - LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text + LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text IDENT_sys TEXT_STRING_sys TEXT_STRING_literal - NCHAR_STRING opt_component key_cache_name + opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty opt_constraint constraint opt_ident + sp_decl_ident + sp_block_label opt_place opt_db + +%type <lex_string_with_metadata> + TEXT_STRING + NCHAR_STRING %type <lex_str_ptr> opt_table_alias +%type <lex_string_with_pos> + ident ident_with_tok_start + %type <table> table_ident table_ident_nodb references xid table_ident_opt_wild create_like +%type <qualified_column_ident> + qualified_column_ident + optionally_qualified_column_ident + %type <simple_string> - remember_name remember_end opt_db remember_tok_start + remember_name remember_end remember_tok_start wild_and_where - field_length opt_field_length opt_field_length_default_1 %type <const_simple_string> - opt_place + field_length opt_field_length opt_field_length_default_1 %type <string> text_string hex_or_bin_String opt_gconcat_separator -%type <field_type> int_type real_type +%type <type_handler> int_type real_type %type <Lex_field_type> type_with_opt_collate field_type + field_type_numeric + field_type_string + field_type_lob + field_type_temporal + field_type_misc %type <Lex_dyncol_type> opt_dyncol_type dyncol_type numeric_dyncol_type temporal_dyncol_type string_dyncol_type @@ -1788,7 +1680,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_recursive %type <object_ddl_options> - create_or_replace + create_or_replace opt_if_not_exists opt_if_exists @@ -1810,11 +1702,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); ws_nweights ws_level_flag_desc ws_level_flag_reverse ws_level_flags opt_ws_levels ws_level_list ws_level_list_item ws_level_number - ws_level_range ws_level_list_or_range + ws_level_range ws_level_list_or_range bool %type <ulonglong_number> ulonglong_num real_ulonglong_num size_number +%type <longlong_number> + longlong_num + %type <choice> choice %type <lock_type> @@ -1830,7 +1725,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); geometry_function signed_literal expr_or_literal opt_escape sp_opt_default - simple_ident_nospvar simple_ident_q + simple_ident_nospvar simple_ident_q simple_ident_q2 field_or_var limit_option part_func_expr window_func_expr @@ -1853,6 +1748,18 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); expr_list opt_udf_expr_list udf_expr_list when_list ident_list ident_list_arg opt_expr_list +%type <sp_cursor_stmt> + sp_cursor_stmt_lex + sp_cursor_stmt + +%type <assignment_lex> + assignment_source_lex + assignment_source_expr + +%type <sp_assignment_lex_list> + cursor_actual_parameters + opt_parenthesized_cursor_actual_parameters + %type <var_type> option_type opt_var_type opt_var_ident_type @@ -1893,6 +1800,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <Lex_length_and_dec> precision opt_precision float_options %type <symbol> keyword keyword_sp + keyword_sp_data_type + keyword_sp_not_data_type %type <lex_user> user grant_user grant_role user_or_role current_role admin_option_for_role user_maybe_role @@ -1929,6 +1838,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <virtual_column> opt_check_constraint check_constraint virtual_column_func column_default_expr +%type <unit_type> unit_type_decl %type <NONE> analyze_stmt_command @@ -1977,11 +1887,9 @@ 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_algorithm view_or_trigger_or_sp_or_event - definer_tail no_definer_tail - view_suid view_tail view_list_opt view_list view_select - view_check_option trigger_tail sp_tail sf_tail event_tail - udf_tail udf_tail2 + view_list_opt view_list view_select + trigger_tail sp_tail sf_tail event_tail + udf_tail create_function_tail install uninstall partition_entry binlog_base64_event normal_key_options normal_key_opts all_key_opt spatial_key_options fulltext_key_options normal_key_opt @@ -2010,13 +1918,15 @@ END_OF_INPUT %type <NONE> case_stmt_specification %type <NONE> loop_body while_body repeat_body -%type <num> sp_decl_idents sp_handler_type sp_hcond_list +%type <num> view_algorithm view_check_option +%type <view_suid> view_suid opt_view_suid + +%type <num> sp_decl_idents sp_decl_idents_init_vars +%type <num> sp_handler_type sp_hcond_list %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value -%type <spblock> sp_decls sp_decl -%type <lex> sp_cursor_stmt +%type <spblock> sp_decls sp_decl sp_decl_body sp_decl_variable_list %type <spname> sp_name -%type <splabel> sp_block_content -%type <spvar> sp_param_name_and_type +%type <spvar> sp_param_name sp_param_name_and_type %type <spvar_mode> sp_opt_inout %type <index_hint> index_hint_type %type <num> index_hint_clause normal_join inner_join @@ -2037,6 +1947,9 @@ END_OF_INPUT %type <cond_info_item_name> condition_information_item_name; %type <cond_info_list> condition_information; +%type <spvar_definition> row_field_name row_field_definition +%type <spvar_definition_list> row_field_definition_list row_type_body + %type <NONE> opt_window_clause window_def_list window_def window_spec %type <lex_str_ptr> window_name %type <NONE> opt_window_ref opt_window_frame_clause @@ -2333,7 +2246,7 @@ master_def: if ($3 > MASTER_DELAY_MAX) { my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0), - $3, MASTER_DELAY_MAX); + (ulong) $3, (ulong) MASTER_DELAY_MAX); } else Lex->mi.sql_delay = $3; @@ -2513,7 +2426,7 @@ optional_connection_name: /* empty */ { LEX *lex= thd->lex; - lex->mi.connection_name= null_lex_str; + lex->mi.connection_name= null_clex_str; } | connection_name ; @@ -2549,7 +2462,7 @@ create: */ lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; lex->create_info.default_table_charset= NULL; - lex->name= null_lex_str; + lex->name= null_clex_str; lex->create_last_non_select_table= lex->last_table(); } create_body @@ -2568,13 +2481,71 @@ create: } create_table_set_open_action_and_adjust_tables(lex); } + | create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident + { + LEX *lex= thd->lex; + lex->create_info.init(); + if (lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2, $1 | $4)) + 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->alter_info.reset(); + lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; + lex->name= null_clex_str; + lex->create_last_non_select_table= lex->last_table(); + if (!(lex->create_info.seq_create_info= new (thd->mem_root) + sequence_definition())) + MYSQL_YYABORT; + } + opt_sequence opt_create_table_options + { + LEX *lex= thd->lex; + + if (lex->create_info.seq_create_info->check_and_adjust(1)) + { + my_error(ER_SEQUENCE_INVALID_DATA, MYF(0), + lex->select_lex.table_list.first->db, + lex->select_lex.table_list.first->table_name); + MYSQL_YYABORT; + } + + /* No fields specified, generate them */ + if (prepare_sequence_fields(thd, &lex->alter_info.create_list)) + MYSQL_YYABORT; + + /* CREATE SEQUENCE always creates a sequence */ + Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE; + Lex->create_info.sequence= 1; + + lex->current_select= &lex->select_lex; + if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) && + !lex->create_info.db_type) + { + lex->create_info.use_default_db_type(thd); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WARN_USING_OTHER_HANDLER, + ER_THD(thd, ER_WARN_USING_OTHER_HANDLER), + hton_name(lex->create_info.db_type)->str, + $5->table.str); + } + create_table_set_open_action_and_adjust_tables(lex); + } | create_or_replace opt_unique INDEX_SYM opt_if_not_exists ident opt_key_algorithm_clause ON table_ident { - if (add_create_index_prepare(Lex, $8)) + if (Lex->add_create_index_prepare($8)) MYSQL_YYABORT; - if (Lex->add_create_index($2, $5, $6, $1 | $4)) + if (Lex->add_create_index($2, &$5, $6, $1 | $4)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options @@ -2582,9 +2553,9 @@ create: | create_or_replace fulltext INDEX_SYM opt_if_not_exists ident ON table_ident { - if (add_create_index_prepare(Lex, $7)) + if (Lex->add_create_index_prepare($7)) MYSQL_YYABORT; - if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) MYSQL_YYABORT; } '(' key_list ')' fulltext_key_options @@ -2592,9 +2563,9 @@ create: | create_or_replace spatial INDEX_SYM opt_if_not_exists ident ON table_ident { - if (add_create_index_prepare(Lex, $7)) + if (Lex->add_create_index_prepare($7)) MYSQL_YYABORT; - if (Lex->add_create_index($2, $5, HA_KEY_ALG_UNDEF, $1 | $4)) + if (Lex->add_create_index($2, &$5, HA_KEY_ALG_UNDEF, $1 | $4)) MYSQL_YYABORT; } '(' key_list ')' spatial_key_options @@ -2611,15 +2582,50 @@ create: MYSQL_YYABORT; lex->name= $4; } - | create_or_replace + | create_or_replace definer_opt opt_view_suid VIEW_SYM + opt_if_not_exists table_ident + { + if (Lex->add_create_view(thd, $1 | $5, + DTYPE_ALGORITHM_UNDEFINED, $3, $6)) + MYSQL_YYABORT; + } + view_list_opt AS view_select + { } + | create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM + opt_if_not_exists table_ident + { + if (Lex->add_create_view(thd, $1 | $6, $2, $4, $7)) + MYSQL_YYABORT; + } + view_list_opt AS view_select + { } + | create_or_replace definer_opt TRIGGER_SYM + { Lex->create_info.set($1); } + trigger_tail + { } + | create_or_replace definer_opt PROCEDURE_SYM + { Lex->create_info.set($1); } + sp_tail + { } + | create_or_replace definer_opt EVENT_SYM + { Lex->create_info.set($1); } + event_tail + { } + | create_or_replace definer FUNCTION_SYM + { Lex->create_info.set($1); } + sf_tail + { } + | create_or_replace no_definer FUNCTION_SYM + { Lex->create_info.set($1); } + create_function_tail + { } + | create_or_replace no_definer AGGREGATE_SYM FUNCTION_SYM { Lex->create_info.set($1); - Lex->create_view_mode= ($1.or_replace() ? VIEW_CREATE_OR_REPLACE : - VIEW_CREATE_NEW); - Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; - Lex->create_view_suid= TRUE; + Lex->udf.type= UDFTYPE_AGGREGATE; } - view_or_trigger_or_sp_or_event { } + udf_tail + { } | create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list opt_require_clause opt_resource_options { @@ -2645,6 +2651,107 @@ create: { } ; +create_function_tail: + sf_tail { } + | udf_tail { Lex->udf.type= UDFTYPE_FUNCTION; } + ; + +opt_sequence: + /* empty */ { } + | sequence_defs + ; + +sequence_defs: + sequence_def + | sequence_defs sequence_def + ; + +sequence_def: + MINVALUE_SYM opt_equal longlong_num + { + Lex->create_info.seq_create_info->min_value= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; + } + | NO_SYM MINVALUE_SYM + { + if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + MYSQL_YYABORT; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; + } + | NOMINVALUE_SYM + { + if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value) + MYSQL_YYABORT; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value; + } + | MAXVALUE_SYM opt_equal longlong_num + { + Lex->create_info.seq_create_info->max_value= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; + } + | NO_SYM MAXVALUE_SYM + { + if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + MYSQL_YYABORT; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; + } + | NOMAXVALUE_SYM + { + if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value) + MYSQL_YYABORT; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value; + } + | START_SYM opt_with longlong_num + { + Lex->create_info.seq_create_info->start= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_start; + } + | INCREMENT_SYM opt_by longlong_num + { + Lex->create_info.seq_create_info->increment= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment; + } + | CACHE_SYM opt_equal longlong_num + { + Lex->create_info.seq_create_info->cache= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; + } + | NOCACHE_SYM + { + Lex->create_info.seq_create_info->cache= 0; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache; + } + | CYCLE_SYM + { + Lex->create_info.seq_create_info->cycle= 1; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; + } + | NOCYCLE_SYM + { + Lex->create_info.seq_create_info->cycle= 0; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle; + } + | RESTART_SYM + { + if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + { + thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); + YYABORT; + } + Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart; + } + | RESTART_SYM opt_with longlong_num + { + if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE) + { + thd->parse_error(ER_SYNTAX_ERROR, "RESTART"); + YYABORT; + } + Lex->create_info.seq_create_info->restart= $3; + Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value; + } + ; + server_def: SERVER_SYM opt_if_not_exists ident_or_text { @@ -2672,7 +2779,8 @@ server_option: { MYSQL_YYABORT_UNLESS(Lex->server_options.host.str == 0); Lex->server_options.host= $2; - my_casedn_str(system_charset_info, Lex->server_options.host.str); + my_casedn_str(system_charset_info, + (char*) Lex->server_options.host.str); } | DATABASE TEXT_STRING_sys { @@ -2701,16 +2809,16 @@ server_option: ; event_tail: - remember_name EVENT_SYM opt_if_not_exists sp_name + remember_name opt_if_not_exists sp_name { LEX *lex=Lex; lex->stmt_definition_begin= $1; - if (lex->add_create_options_with_check($3)) + if (lex->add_create_options_with_check($2)) MYSQL_YYABORT; if (!(lex->event_parse_data= Event_parse_data::new_instance(thd))) MYSQL_YYABORT; - lex->event_parse_data->identifier= $4; + lex->event_parse_data->identifier= $3; lex->event_parse_data->on_completion= Event_parse_data::ON_COMPLETION_DROP; @@ -2838,10 +2946,10 @@ ev_sql_stmt: if (lex->sphead) my_yyabort_error((ER_EVENT_RECURSION_FORBIDDEN, MYF(0))); - if (!make_sp_head(thd, lex->event_parse_data->identifier, TYPE_ENUM_PROCEDURE)) + if (!lex->make_sp_head(thd, lex->event_parse_data->identifier, + TYPE_ENUM_PROCEDURE)) MYSQL_YYABORT; - lex->sp_chistics.suid= SP_IS_SUID; //always the definer! lex->sphead->set_body_start(thd, lip->get_cpp_ptr()); } sp_proc_stmt @@ -2874,29 +2982,13 @@ clear_privileges: sp_name: ident '.' ident { - if (!$1.str || check_db_name(&$1)) - my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); - if (check_routine_name(&$3)) - MYSQL_YYABORT; - $$= new (thd->mem_root) sp_name($1, $3, true); - if ($$ == NULL) + if (!($$= Lex->make_sp_name(thd, &$1, &$3))) MYSQL_YYABORT; - $$->init_qname(thd); } | ident { - LEX *lex= thd->lex; - LEX_STRING db; - if (check_routine_name(&$1)) - { + if (!($$= Lex->make_sp_name(thd, &$1))) MYSQL_YYABORT; - } - if (lex->copy_db_to(&db.str, &db.length)) - MYSQL_YYABORT; - $$= new (thd->mem_root) sp_name(db, $1, false); - if ($$ == NULL) - MYSQL_YYABORT; - $$->init_qname(thd); } ; @@ -2991,34 +3083,31 @@ sp_fdparams: | sp_param_name_and_type ; -sp_param_name_and_type: +sp_param_name: ident { - LEX *lex= Lex; - sp_pcontext *spc= lex->spcont; - - if (spc->find_variable($1, TRUE)) - my_yyabort_error((ER_SP_DUP_PARAM, MYF(0), $1.str)); - - sp_variable *spvar= spc->add_variable(thd, $1); - - lex->init_last_field(&spvar->field_def, $1.str, - thd->variables.collation_database); - $<spvar>$= spvar; + if (!($$= Lex->sp_param_init(&$1))) + MYSQL_YYABORT; } - type_with_opt_collate - { - LEX *lex= Lex; - sp_variable *spvar= $<spvar>2; + ; - if (lex->sphead->fill_field_definition(thd, lex, lex->last_field)) - { +sp_param_name_and_type: + sp_param_name type_with_opt_collate + { + if (Lex->sp_param_fill_definition($$= $1)) MYSQL_YYABORT; - } - spvar->field_def.field_name= spvar->name.str; - spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL; - - $$= spvar; + } + | sp_param_name TYPE_SYM OF_SYM qualified_column_ident + { + Lex->sphead->fill_spvar_using_type_reference($$= $1, $4); + } + | sp_param_name ROW_SYM row_type_body + { + $$= $1; + $$->field_def.field_name= $$->name; + Lex->sphead->fill_spvar_definition(thd, &$$->field_def); + Lex->sphead->row_fill_field_definitions(thd, $3); + $$->field_def.set_row_field_definitions($3); } ; @@ -3044,6 +3133,30 @@ sp_opt_inout: | INOUT_SYM { $$= sp_variable::MODE_INOUT; } ; +sp_parenthesized_fdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_fdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + +sp_parenthesized_pdparam_list: + '(' + { + Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1; + } + sp_pdparam_list + ')' + { + Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); + } + ; + sp_proc_stmts: /* Empty */ {} | sp_proc_stmts sp_proc_stmt ';' @@ -3057,7 +3170,7 @@ sp_proc_stmts1: sp_decls: /* Empty */ { - $$.vars= $$.conds= $$.hndlrs= $$.curs= 0; + $$.init(); } | sp_decls sp_decl ';' { @@ -3065,196 +3178,194 @@ sp_decls: because letting the grammar rules reflect it caused tricky shift/reduce conflicts with the wrong result. (And we get better error handling this way.) */ - if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) - my_yyabort_error((ER_SP_VARCOND_AFTER_CURSHNDLR, MYF(0))); - if ($2.curs && $1.hndlrs) - my_yyabort_error((ER_SP_CURSOR_AFTER_HANDLER, MYF(0))); - $$.vars= $1.vars + $2.vars; - $$.conds= $1.conds + $2.conds; - $$.hndlrs= $1.hndlrs + $2.hndlrs; - $$.curs= $1.curs + $2.curs; + if (Lex->sp_declarations_join(&$$, $1, $2)) + MYSQL_YYABORT; } ; sp_decl: - DECLARE_SYM sp_decl_idents - { - LEX *lex= Lex; - sp_pcontext *pctx= lex->spcont; + DECLARE_SYM sp_decl_body { $$= $2; } + ; - // get the last variable: - uint num_vars= pctx->context_var_count(); - uint var_idx= pctx->var_context2runtime(num_vars - 1); - sp_variable *spvar= pctx->find_variable(var_idx); - lex->sphead->reset_lex(thd); - pctx->declare_var_boundary($2); - thd->lex->init_last_field(&spvar->field_def, spvar->name.str, - thd->variables.collation_database); +qualified_column_ident: + sp_decl_ident '.' ident + { + if (!($$= new (thd->mem_root) Qualified_column_ident(&$1, &$3))) + MYSQL_YYABORT; } - type_with_opt_collate - sp_opt_default + | sp_decl_ident '.' ident '.' ident { - LEX *lex= Lex; - sp_pcontext *pctx= lex->spcont; - uint num_vars= pctx->context_var_count(); - Item *dflt_value_item= $5; - - if (!dflt_value_item) - { - dflt_value_item= new (thd->mem_root) Item_null(thd); - if (dflt_value_item == NULL) - MYSQL_YYABORT; - /* QQ Set to the var_type with null_value? */ - } - - for (uint i = num_vars-$2 ; i < num_vars ; i++) - { - uint var_idx= pctx->var_context2runtime(i); - sp_variable *spvar= pctx->find_variable(var_idx); - bool last= i == num_vars - 1; - - if (!spvar) - MYSQL_YYABORT; - - if (!last) - spvar->field_def= *lex->last_field; - - spvar->default_value= dflt_value_item; - spvar->field_def.field_name= spvar->name.str; - - if (lex->sphead->fill_field_definition(thd, lex, - &spvar->field_def)) - { - MYSQL_YYABORT; - } - - spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL; - - /* The last instruction is responsible for freeing LEX. */ - - sp_instr_set *is= new (lex->thd->mem_root) - sp_instr_set(lex->sphead->instructions(), - pctx, var_idx, dflt_value_item, - $4.field_type(), lex, last); - if (is == NULL || lex->sphead->add_instr(is)) - MYSQL_YYABORT; - } + if (!($$= new (thd->mem_root) Qualified_column_ident(thd, + &$1, &$3, &$5))) + MYSQL_YYABORT; + } + ; - pctx->declare_var_boundary(0); - if (lex->sphead->restore_lex(thd)) +optionally_qualified_column_ident: + sp_decl_ident + { + if (!($$= new (thd->mem_root) Qualified_column_ident(&$1))) MYSQL_YYABORT; - $$.vars= $2; - $$.conds= $$.hndlrs= $$.curs= 0; } - | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + | sp_decl_ident '.' ident { - LEX *lex= Lex; - sp_pcontext *spc= lex->spcont; - - if (spc->find_condition($2, TRUE)) - my_yyabort_error((ER_SP_DUP_COND, MYF(0), $2.str)); - if(spc->add_condition(thd, $2, $5)) + if (!($$= new (thd->mem_root) Qualified_column_ident(&$1, &$3))) MYSQL_YYABORT; - $$.vars= $$.hndlrs= $$.curs= 0; - $$.conds= 1; } - | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + | sp_decl_ident '.' ident '.' ident { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - - sp_handler *h= lex->spcont->add_handler(thd, - (sp_handler::enum_type) $2); + if (!($$= new (thd->mem_root) Qualified_column_ident(thd, + &$1, &$3, &$5))) + MYSQL_YYABORT; + } + ; - lex->spcont= lex->spcont->push_context(thd, - sp_pcontext::HANDLER_SCOPE); +row_field_name: + ident + { + if (check_string_char_length(&$1, 0, NAME_CHAR_LEN, + system_charset_info, 1)) + my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str)); + if (!($$= new (thd->mem_root) Spvar_definition())) + MYSQL_YYABORT; + Lex->init_last_field($$, &$1, thd->variables.collation_database); + } + ; - sp_pcontext *ctx= lex->spcont; - sp_instr_hpush_jump *i= - new (thd->mem_root) sp_instr_hpush_jump(sp->instructions(), - ctx, h); +row_field_definition: + row_field_name type_with_opt_collate + ; - if (i == NULL || sp->add_instr(i)) +row_field_definition_list: + row_field_definition + { + if (!($$= new (thd->mem_root) Row_definition_list())) MYSQL_YYABORT; + $$->push_back($1, thd->mem_root); + } + | row_field_definition_list ',' row_field_definition + { + uint unused; + if ($1->find_row_field_by_name(&$3->field_name, &unused)) + my_yyabort_error((ER_DUP_FIELDNAME, MYF(0), $3->field_name.str)); + $$= $1; + $$->push_back($3, thd->mem_root); + } + ; + +row_type_body: + '(' row_field_definition_list ')' { $$= $2; } + ; + +sp_decl_idents_init_vars: + sp_decl_idents + { + Lex->sp_variable_declarations_init(thd, $1); + } + ; - /* For continue handlers, mark end of handler scope. */ - if ($2 == sp_handler::CONTINUE && - sp->push_backpatch(thd, i, ctx->last_label())) +sp_decl_variable_list: + sp_decl_idents_init_vars + type_with_opt_collate + sp_opt_default + { + if (Lex->sp_variable_declarations_finalize(thd, $1, + &Lex->last_field[0], $3)) + MYSQL_YYABORT; + $$.init_using_vars($1); + } + | sp_decl_idents_init_vars + TYPE_SYM OF_SYM optionally_qualified_column_ident + sp_opt_default + { + if (Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $4, $5)) MYSQL_YYABORT; + $$.init_using_vars($1); + } + | sp_decl_idents_init_vars + ROW_SYM TYPE_SYM OF_SYM optionally_qualified_column_ident + sp_opt_default + { + if (Lex->sp_variable_declarations_rowtype_finalize(thd, $1, $5, $6)) + MYSQL_YYABORT; + $$.init_using_vars($1); + } + | sp_decl_idents_init_vars + ROW_SYM row_type_body + sp_opt_default + { + if (Lex->sp_variable_declarations_row_finalize(thd, $1, $3, $4)) + MYSQL_YYABORT; + $$.init_using_vars($1); + } + ; - if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0))) +sp_decl_body: + sp_decl_variable_list + | sp_decl_ident CONDITION_SYM FOR_SYM sp_cond + { + if (Lex->spcont->declare_condition(thd, &$1, $4)) + MYSQL_YYABORT; + $$.vars= $$.hndlrs= $$.curs= 0; + $$.conds= 1; + } + | sp_handler_type HANDLER_SYM FOR_SYM + { + if (Lex->sp_handler_declaration_init(thd, $1)) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - sp_label *hlab= lex->spcont->pop_label(); /* After this hdlr */ - sp_instr_hreturn *i; - - if ($2 == sp_handler::CONTINUE) - { - i= new (thd->mem_root) - sp_instr_hreturn(sp->instructions(), ctx); - if (i == NULL || - sp->add_instr(i)) - MYSQL_YYABORT; - } - else - { /* EXIT or UNDO handler, just jump to the end of the block */ - i= new (thd->mem_root) - sp_instr_hreturn(sp->instructions(), ctx); - if (i == NULL || - sp->add_instr(i) || - sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */ - MYSQL_YYABORT; - } - lex->sphead->backpatch(hlab); - - lex->spcont= ctx->pop_context(); - + if (Lex->sp_handler_declaration_finalize(thd, $1)) + MYSQL_YYABORT; $$.vars= $$.conds= $$.curs= 0; $$.hndlrs= 1; } - | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + | sp_decl_ident CURSOR_SYM { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - uint offp; - sp_instr_cpush *i; - - if (ctx->find_cursor($2, &offp, TRUE)) - my_yyabort_error((ER_SP_DUP_CURS, MYF(0), $2.str)); - - i= new (thd->mem_root) - sp_instr_cpush(sp->instructions(), ctx, $5, - ctx->current_cursor_count()); - if (i == NULL || sp->add_instr(i) || ctx->add_cursor($2)) + Lex->sp_block_init(thd); + } + opt_parenthesized_cursor_formal_parameters + FOR_SYM sp_cursor_stmt + { + sp_pcontext *param_ctx= Lex->spcont; + if (Lex->sp_block_finalize(thd)) + MYSQL_YYABORT; + if (Lex->sp_declare_cursor(thd, &$1, $6, param_ctx, true)) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; } ; +opt_parenthesized_cursor_formal_parameters: + /* Empty */ + | '(' sp_fdparams ')' + ; + + +sp_cursor_stmt_lex: + { + DBUG_ASSERT(thd->lex->sphead); + if (!($$= new (thd->mem_root) sp_lex_cursor(thd, thd->lex))) + MYSQL_YYABORT; + } + ; + sp_cursor_stmt: + sp_cursor_stmt_lex { - Lex->sphead->reset_lex(thd); + DBUG_ASSERT(thd->free_list == NULL); + Lex->sphead->reset_lex(thd, $1); } select { - LEX *lex= Lex; - - DBUG_ASSERT(lex->sql_command == SQLCOM_SELECT); - - if (lex->result) - my_yyabort_error((ER_SP_BAD_CURSOR_SELECT, MYF(0))); - lex->sp_lex_in_use= TRUE; - $$= lex; - if (lex->sphead->restore_lex(thd)) + DBUG_ASSERT(Lex == $1); + if ($1->stmt_finalize(thd) || + $1->sphead->restore_lex(thd)) MYSQL_YYABORT; + $$= $1; } ; @@ -3329,7 +3440,7 @@ sp_hcond: } | ident /* CONDITION name */ { - $$= Lex->spcont->find_condition($1, false); + $$= Lex->spcont->find_condition(&$1, false); if ($$ == NULL) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); } @@ -3356,13 +3467,7 @@ sp_hcond: signal_stmt: SIGNAL_SYM signal_value opt_set_signal_information { - LEX *lex= thd->lex; - Yacc_state *state= & thd->m_parser_state->m_yacc; - - lex->sql_command= SQLCOM_SIGNAL; - lex->m_sql_cmd= - new (thd->mem_root) Sql_cmd_signal($2, state->m_set_signal_info); - if (lex->m_sql_cmd == NULL) + if (Lex->add_signal_statement(thd, $2)) MYSQL_YYABORT; } ; @@ -3376,7 +3481,7 @@ signal_value: /* SIGNAL foo cannot be used outside of stored programs */ if (lex->spcont == NULL) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); - cond= lex->spcont->find_condition($1, false); + cond= lex->spcont->find_condition(&$1, false); if (cond == NULL) my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str)); if (cond->type != sp_condition_value::SQLSTATE) @@ -3442,7 +3547,7 @@ signal_allowed_expr: SIGNAL/RESIGNAL ... SET <signal condition item name> = @foo := expr */ - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -3483,14 +3588,7 @@ signal_condition_information_item_name: resignal_stmt: RESIGNAL_SYM opt_signal_value opt_set_signal_information { - LEX *lex= thd->lex; - Yacc_state *state= & thd->m_parser_state->m_yacc; - - lex->sql_command= SQLCOM_RESIGNAL; - lex->m_sql_cmd= - new (thd->mem_root) Sql_cmd_resignal($2, - state->m_set_signal_info); - if (lex->m_sql_cmd == NULL) + if (Lex->add_resignal_statement(thd, $2)) MYSQL_YYABORT; } ; @@ -3559,15 +3657,15 @@ simple_target_specification: ident { Lex_input_stream *lip= &thd->m_parser_state->m_lip; - $$= create_item_for_sp_var(thd, $1, NULL, - lip->get_tok_start(), lip->get_ptr()); - + $$= thd->lex->create_item_for_sp_var(&$1, NULL, + lip->get_tok_start(), + lip->get_ptr()); if ($$ == NULL) MYSQL_YYABORT; } | '@' ident_or_text { - $$= new (thd->mem_root) Item_func_get_user_var(thd, $2); + $$= new (thd->mem_root) Item_func_get_user_var(thd, &$2); if ($$ == NULL) MYSQL_YYABORT; } @@ -3641,17 +3739,21 @@ condition_information_item_name: { $$= Condition_information_item::RETURNED_SQLSTATE; } ; +sp_decl_ident: + ident { $$= $1; } + ; + sp_decl_idents: - ident + sp_decl_ident { /* NOTE: field definition is filled in sp_decl section. */ LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable($1, TRUE)) + if (spc->find_variable(&$1, TRUE)) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $1.str)); - spc->add_variable(thd, $1); + spc->add_variable(thd, &$1); $$= 1; } | sp_decl_idents ',' ident @@ -3661,9 +3763,9 @@ sp_decl_idents: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_variable($3, TRUE)) + if (spc->find_variable(&$3, TRUE)) my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $3.str)); - spc->add_variable(thd, $3); + spc->add_variable(thd, &$3); $$= $1 + 1; } ; @@ -3710,7 +3812,7 @@ sp_proc_stmt_compound_ok: sp_proc_stmt_if: IF_SYM { - if (maybe_start_compound_statement(thd)) + if (Lex->maybe_start_compound_statement(thd)) MYSQL_YYABORT; Lex->sphead->new_cont_backpatch(NULL); } @@ -3785,7 +3887,7 @@ sp_proc_stmt_return: i= new (thd->mem_root) sp_instr_freturn(sp->instructions(), lex->spcont, $3, - sp->m_return_field_def.sql_type, lex); + sp->m_return_field_def.type_handler(), lex); if (i == NULL || sp->add_instr(i)) MYSQL_YYABORT; sp->m_flags|= sp_head::HAS_RETURN; @@ -3798,130 +3900,92 @@ sp_proc_stmt_return: sp_proc_stmt_leave: LEAVE_SYM label_ident { - LEX *lex= Lex; - sp_head *sp = lex->sphead; - sp_pcontext *ctx= lex->spcont; - sp_label *lab= ctx->find_label($2); - - if (! lab) - my_yyabort_error((ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str)); - - sp_instr_jump *i; - uint ip= sp->instructions(); - uint n; - /* - When jumping to a BEGIN-END block end, the target jump - points to the block hpop/cpop cleanup instructions, - so we should exclude the block context here. - When jumping to something else (i.e., SP_LAB_ITER), - there are no hpop/cpop at the jump destination, - so we should include the block context here for cleanup. - */ - bool exclusive= (lab->type == sp_label::BEGIN); - - n= ctx->diff_handlers(lab->ctx, exclusive); - if (n) - { - sp_instr_hpop *hpop= new (thd->mem_root) - sp_instr_hpop(ip++, ctx, n); - if (hpop == NULL) - MYSQL_YYABORT; - sp->add_instr(hpop); - } - n= ctx->diff_cursors(lab->ctx, exclusive); - if (n) - { - sp_instr_cpop *cpop= new (thd->mem_root) - sp_instr_cpop(ip++, ctx, n); - if (cpop == NULL) - MYSQL_YYABORT; - sp->add_instr(cpop); - } - i= new (thd->mem_root) sp_instr_jump(ip, ctx); - if (i == NULL) + if (Lex->sp_leave_statement(thd, &$2)) MYSQL_YYABORT; - sp->push_backpatch(thd, i, lab); /* Jumping forward */ - sp->add_instr(i); } ; sp_proc_stmt_iterate: ITERATE_SYM label_ident { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - sp_label *lab= ctx->find_label($2); + if (Lex->sp_iterate_statement(thd, &$2)) + MYSQL_YYABORT; + } + ; - if (! lab || lab->type != sp_label::ITERATION) - my_yyabort_error((ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str)); +assignment_source_lex: + { + DBUG_ASSERT(Lex->sphead); + if (!($$= new (thd->mem_root) sp_assignment_lex(thd, thd->lex))) + MYSQL_YYABORT; + } + ; - sp_instr_jump *i; - uint ip= sp->instructions(); - uint n; +assignment_source_expr: + assignment_source_lex + { + DBUG_ASSERT(thd->free_list == NULL); + Lex->sphead->reset_lex(thd, $1); + } + expr + { + DBUG_ASSERT($1 == thd->lex); + $$= $1; + $$->sp_lex_in_use= true; + $$->set_item_and_free_list($3, thd->free_list); + thd->free_list= NULL; + if ($$->sphead->restore_lex(thd)) + MYSQL_YYABORT; + } + ; - n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ - if (n) - { - sp_instr_hpop *hpop= new (thd->mem_root) - sp_instr_hpop(ip++, ctx, n); - if (hpop == NULL || - sp->add_instr(hpop)) - MYSQL_YYABORT; - } - n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ - if (n) - { - sp_instr_cpop *cpop= new (thd->mem_root) - sp_instr_cpop(ip++, ctx, n); - if (cpop == NULL || - sp->add_instr(cpop)) - MYSQL_YYABORT; - } - i= new (thd->mem_root) - sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ - if (i == NULL || - sp->add_instr(i)) +cursor_actual_parameters: + assignment_source_expr + { + if (!($$= new (thd->mem_root) List<sp_assignment_lex>)) MYSQL_YYABORT; + $$->push_back($1, thd->mem_root); } + | cursor_actual_parameters ',' assignment_source_expr + { + $$= $1; + $$->push_back($3, thd->mem_root); + } + ; + +opt_parenthesized_cursor_actual_parameters: + /* Empty */ { $$= NULL; } + | '(' cursor_actual_parameters ')' { $$= $2; } ; sp_proc_stmt_open: - OPEN_SYM ident + OPEN_SYM ident opt_parenthesized_cursor_actual_parameters { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - uint offset; - sp_instr_copen *i; - - if (! lex->spcont->find_cursor($2, &offset, false)) - my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $2.str)); - i= new (thd->mem_root) - sp_instr_copen(sp->instructions(), lex->spcont, offset); - if (i == NULL || - sp->add_instr(i)) + if (Lex->sp_open_cursor(thd, &$2, $3)) MYSQL_YYABORT; } ; -sp_proc_stmt_fetch: - FETCH_SYM sp_opt_fetch_noise ident INTO +sp_proc_stmt_fetch_head: + FETCH_SYM ident INTO { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - uint offset; - sp_instr_cfetch *i; - - if (! lex->spcont->find_cursor($3, &offset, false)) - my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $3.str)); - i= new (thd->mem_root) - sp_instr_cfetch(sp->instructions(), lex->spcont, offset); - if (i == NULL || - sp->add_instr(i)) + if (Lex->sp_add_cfetch(thd, &$2)) MYSQL_YYABORT; } - sp_fetch_list - {} + | FETCH_SYM FROM ident INTO + { + if (Lex->sp_add_cfetch(thd, &$3)) + MYSQL_YYABORT; + } + | FETCH_SYM NEXT_SYM FROM ident INTO + { + if (Lex->sp_add_cfetch(thd, &$4)) + MYSQL_YYABORT; + } + ; + +sp_proc_stmt_fetch: + sp_proc_stmt_fetch_head sp_fetch_list { } ; sp_proc_stmt_close: @@ -3932,7 +3996,7 @@ sp_proc_stmt_close: uint offset; sp_instr_cclose *i; - if (! lex->spcont->find_cursor($2, &offset, false)) + if (! lex->spcont->find_cursor(&$2, &offset, false)) my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $2.str)); i= new (thd->mem_root) sp_instr_cclose(sp->instructions(), lex->spcont, offset); @@ -3942,12 +4006,6 @@ sp_proc_stmt_close: } ; -sp_opt_fetch_noise: - /* Empty */ - | NEXT_SYM FROM - | FROM - ; - sp_fetch_list: ident { @@ -3956,7 +4014,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable($1, false))) + if (!spc || !(spv = spc->find_variable(&$1, false))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); /* An SP local variable */ @@ -3970,7 +4028,7 @@ sp_fetch_list: sp_pcontext *spc= lex->spcont; sp_variable *spv; - if (!spc || !(spv = spc->find_variable($3, false))) + if (!spc || !(spv = spc->find_variable(&$3, false))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $3.str)); /* An SP local variable */ @@ -3990,7 +4048,7 @@ sp_if: sp_instr_jump_if_not *i= new (thd->mem_root) sp_instr_jump_if_not(ip, ctx, $2, lex); if (i == NULL || - sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || + sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -4007,7 +4065,7 @@ sp_if: sp->add_instr(i)) MYSQL_YYABORT; sp->backpatch(ctx->pop_label()); - sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)); + sp->push_backpatch(thd, i, ctx->push_label(thd, &empty_clex_str, 0)); } sp_elseifs { @@ -4026,7 +4084,7 @@ sp_elseifs: case_stmt_specification: CASE_SYM { - if (maybe_start_compound_statement(thd)) + if (Lex->maybe_start_compound_statement(thd)) MYSQL_YYABORT; /** @@ -4072,7 +4130,7 @@ case_stmt_specification: BACKPATCH: Creating target label for the jump to after END CASE (instruction 12 in the example) */ - Lex->spcont->push_label(thd, empty_lex_str, Lex->sphead->instructions()); + Lex->spcont->push_label(thd, &empty_clex_str, Lex->sphead->instructions()); } case_stmt_body else_clause_opt @@ -4097,7 +4155,7 @@ case_stmt_body: { Lex->sphead->reset_lex(thd); /* For expr $2 */ } expr { - if (case_stmt_action_expr(Lex, $2)) + if (Lex->case_stmt_action_expr($2)) MYSQL_YYABORT; if (Lex->sphead->restore_lex(thd)) @@ -4129,7 +4187,7 @@ simple_when_clause: /* Simple case: <caseval> = <whenval> */ LEX *lex= Lex; - if (case_stmt_action_when(lex, $3, true)) + if (lex->case_stmt_action_when($3, true)) MYSQL_YYABORT; /* For expr $3 */ if (lex->sphead->restore_lex(thd)) @@ -4138,8 +4196,7 @@ simple_when_clause: THEN_SYM sp_proc_stmts1 { - LEX *lex= Lex; - if (case_stmt_action_then(lex)) + if (Lex->case_stmt_action_then()) MYSQL_YYABORT; } ; @@ -4152,7 +4209,7 @@ searched_when_clause: expr { LEX *lex= Lex; - if (case_stmt_action_when(lex, $3, false)) + if (lex->case_stmt_action_when($3, false)) MYSQL_YYABORT; /* For expr $3 */ if (lex->sphead->restore_lex(thd)) @@ -4161,8 +4218,7 @@ searched_when_clause: THEN_SYM sp_proc_stmts1 { - LEX *lex= Lex; - if (case_stmt_action_then(lex)) + if (Lex->case_stmt_action_then()) MYSQL_YYABORT; } ; @@ -4183,88 +4239,62 @@ else_clause_opt: ; sp_opt_label: - /* Empty */ { $$= null_lex_str; } + /* Empty */ { $$= null_clex_str; } | label_ident { $$= $1; } ; -sp_labeled_block: - label_ident ':' BEGIN_SYM +sp_block_label: + label_ident ':' { - LEX *lex= Lex; - sp_pcontext *ctx= lex->spcont; - sp_label *lab= ctx->find_label($1); + if (Lex->spcont->block_label_declare(&$1)) + MYSQL_YYABORT; + $$= $1; + } + ; - if (lab) - my_yyabort_error((ER_SP_LABEL_REDEFINE, MYF(0), $1.str)); - lex->name= $1; +sp_labeled_block: + sp_block_label + BEGIN_SYM + { + Lex->sp_block_init(thd, &$1); } - sp_block_content sp_opt_label + sp_decls + sp_proc_stmts + END + sp_opt_label { - if ($6.str) - { - if (my_strcasecmp(system_charset_info, $6.str, $5->name.str) != 0) - my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $6.str)); - } + if (Lex->sp_block_finalize(thd, $4, &$7)) + MYSQL_YYABORT; } ; sp_unlabeled_block: BEGIN_SYM { - Lex->name= empty_lex_str; // Unlabeled blocks get an empty label + Lex->sp_block_init(thd); } - sp_block_content - { } - ; - -sp_unlabeled_block_not_atomic: - BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ + sp_decls + sp_proc_stmts + END { - if (maybe_start_compound_statement(thd)) + if (Lex->sp_block_finalize(thd, $3)) MYSQL_YYABORT; - Lex->name= empty_lex_str; // Unlabeled blocks get an empty label } - sp_block_content - { } ; -sp_block_content: +sp_unlabeled_block_not_atomic: + BEGIN_SYM not ATOMIC_SYM /* TODO: BEGIN ATOMIC (not -> opt_not) */ { - LEX *lex= Lex; - sp_label *lab= lex->spcont->push_label(thd, lex->name, - lex->sphead->instructions()); - lab->type= sp_label::BEGIN; - lex->spcont= lex->spcont->push_context(thd, - sp_pcontext::REGULAR_SCOPE); + if (Lex->maybe_start_compound_statement(thd)) + MYSQL_YYABORT; + Lex->sp_block_init(thd); } sp_decls sp_proc_stmts END { - LEX *lex= Lex; - sp_head *sp= lex->sphead; - sp_pcontext *ctx= lex->spcont; - sp_instr *i; - - sp->backpatch(ctx->last_label()); /* We always have a label */ - if ($2.hndlrs) - { - i= new (thd->mem_root) - sp_instr_hpop(sp->instructions(), ctx, $2.hndlrs); - if (i == NULL || - sp->add_instr(i)) - MYSQL_YYABORT; - } - if ($2.curs) - { - i= new (thd->mem_root) - sp_instr_cpop(sp->instructions(), ctx, $2.curs); - if (i == NULL || - sp->add_instr(i)) - MYSQL_YYABORT; - } - lex->spcont= ctx->pop_context(); - $$ = lex->spcont->pop_label(); + if (Lex->sp_block_finalize(thd, $5)) + MYSQL_YYABORT; } ; @@ -4286,30 +4316,15 @@ while_body: expr DO_SYM { LEX *lex= Lex; - sp_head *sp= lex->sphead; - uint ip= sp->instructions(); - sp_instr_jump_if_not *i= new (thd->mem_root) - sp_instr_jump_if_not(ip, lex->spcont, $1, lex); - if (i == NULL || - /* Jumping forward */ - sp->push_backpatch(thd, i, lex->spcont->last_label()) || - sp->new_cont_backpatch(i) || - sp->add_instr(i)) + if (lex->sp_while_loop_expression(thd, $1)) MYSQL_YYABORT; - if (sp->restore_lex(thd)) + if (lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } sp_proc_stmts1 END WHILE_SYM { - LEX *lex= Lex; - uint ip= lex->sphead->instructions(); - sp_label *lab= lex->spcont->last_label(); /* Jumping back */ - sp_instr_jump *i= new (thd->mem_root) - sp_instr_jump(ip, lex->spcont, lab->ip); - if (i == NULL || - lex->sphead->add_instr(i)) + if (Lex->sp_while_loop_finalize(thd)) MYSQL_YYABORT; - lex->sphead->do_cont_backpatch(); } ; @@ -4333,79 +4348,68 @@ repeat_body: } ; -pop_sp_label: +pop_sp_loop_label: sp_opt_label { - sp_label *lab; - Lex->sphead->backpatch(lab= Lex->spcont->pop_label()); - if ($1.str) - { - if (my_strcasecmp(system_charset_info, $1.str, - lab->name.str) != 0) - my_yyabort_error((ER_SP_LABEL_MISMATCH, MYF(0), $1.str)); - } - } - ; - -pop_sp_empty_label: - { - sp_label *lab; - Lex->sphead->backpatch(lab= Lex->spcont->pop_label()); - DBUG_ASSERT(lab->name.length == 0); + if (Lex->sp_pop_loop_label(thd, &$1)) + MYSQL_YYABORT; } ; sp_labeled_control: label_ident ':' LOOP_SYM { - if (push_sp_label(thd, $1)) + if (Lex->sp_push_loop_label(thd, &$1)) MYSQL_YYABORT; } - loop_body pop_sp_label + loop_body pop_sp_loop_label { } | label_ident ':' WHILE_SYM { - if (push_sp_label(thd, $1)) + if (Lex->sp_push_loop_label(thd, &$1)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } - while_body pop_sp_label + while_body pop_sp_loop_label { } | label_ident ':' REPEAT_SYM { - if (push_sp_label(thd, $1)) + if (Lex->sp_push_loop_label(thd, &$1)) MYSQL_YYABORT; } - repeat_body pop_sp_label + repeat_body pop_sp_loop_label { } ; sp_unlabeled_control: LOOP_SYM { - if (push_sp_empty_label(thd)) + if (Lex->sp_push_loop_empty_label(thd)) MYSQL_YYABORT; } loop_body - pop_sp_empty_label - { } + { + Lex->sp_pop_loop_empty_label(thd); + } | WHILE_SYM { - if (push_sp_empty_label(thd)) + if (Lex->sp_push_loop_empty_label(thd)) MYSQL_YYABORT; Lex->sphead->reset_lex(thd); } while_body - pop_sp_empty_label - { } + { + Lex->sp_pop_loop_empty_label(thd); + } | REPEAT_SYM { - if (push_sp_empty_label(thd)) + if (Lex->sp_push_loop_empty_label(thd)) MYSQL_YYABORT; } repeat_body - pop_sp_empty_label - { } + { + Lex->sp_pop_loop_empty_label(thd); + } ; trg_action_time: @@ -4762,11 +4766,11 @@ size_number: ulonglong number; uint text_shift_number= 0; longlong prefix_number; - char *start_ptr= $1.str; + const char *start_ptr= $1.str; uint str_len= $1.length; - char *end_ptr= start_ptr + str_len; + const char *end_ptr= start_ptr + str_len; int error; - prefix_number= my_strtoll10(start_ptr, &end_ptr, &error); + prefix_number= my_strtoll10(start_ptr, (char**) &end_ptr, &error); if ((start_ptr + str_len - 1) == end_ptr) { switch (end_ptr[0]) @@ -4824,7 +4828,7 @@ create_body: if (! src_table) MYSQL_YYABORT; /* CREATE TABLE ... LIKE is not allowed for views. */ - src_table->required_type= FRMTYPE_TABLE; + src_table->required_type= TABLE_TYPE_NORMAL; } ; @@ -4922,7 +4926,7 @@ have_partitioning: /* empty */ { #ifdef WITH_PARTITION_STORAGE_ENGINE - LEX_STRING partition_name={C_STRING_WITH_LEN("partition")}; + LEX_CSTRING partition_name={STRING_WITH_LEN("partition")}; if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN)) my_yyabort_error((ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--skip-partition")); @@ -4939,7 +4943,7 @@ partition_entry: LEX *lex= Lex; if (!lex->part_info) { - my_parse_error(thd, ER_PARTITION_ENTRY_ERROR); + thd->parse_error(ER_PARTITION_ENTRY_ERROR); MYSQL_YYABORT; } /* @@ -4996,7 +5000,7 @@ opt_key_algo: Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_55; break; default: - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -5112,7 +5116,7 @@ part_func_expr: { if (!Lex->safe_to_cache_query) { - my_parse_error(thd, ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); + thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; } $$=$1; @@ -5152,7 +5156,7 @@ part_defs: if (part_info->num_parts != count_curr_parts) { - my_parse_error(thd, ER_PARTITION_WRONG_NO_PART_ERROR); + thd->parse_error(ER_PARTITION_WRONG_NO_PART_ERROR); MYSQL_YYABORT; } } @@ -5274,7 +5278,7 @@ opt_part_values: ; part_func_max: - MAX_VALUE_SYM + MAXVALUE_SYM { partition_info *part_info= Lex->part_info; @@ -5282,7 +5286,7 @@ part_func_max: part_info->num_columns != 1U) { part_info->print_debug("Kilroy II", NULL); - my_parse_error(thd, ER_PARTITION_COLUMN_LIST_ERROR); + thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); MYSQL_YYABORT; } else @@ -5313,7 +5317,7 @@ part_values_in: part_info->num_columns > MAX_REF_PARTS) { part_info->print_debug("Kilroy III", NULL); - my_parse_error(thd, ER_PARTITION_COLUMN_LIST_ERROR); + thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); MYSQL_YYABORT; } /* @@ -5334,7 +5338,7 @@ part_values_in: partition_info *part_info= Lex->part_info; if (part_info->num_columns < 2U) { - my_parse_error(thd, ER_ROW_SINGLE_PARTITION_FIELD_ERROR); + thd->parse_error(ER_ROW_SINGLE_PARTITION_FIELD_ERROR); MYSQL_YYABORT; } } @@ -5375,7 +5379,7 @@ part_value_item: error. */ part_info->print_debug("Kilroy I", NULL); - my_parse_error(thd, ER_PARTITION_COLUMN_LIST_ERROR); + thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR); MYSQL_YYABORT; } part_info->curr_list_object= 0; @@ -5388,12 +5392,12 @@ part_value_item_list: ; part_value_expr_item: - MAX_VALUE_SYM + MAXVALUE_SYM { partition_info *part_info= Lex->part_info; if (part_info->part_type == LIST_PARTITION) { - my_parse_error(thd, ER_MAXVALUE_IN_VALUES_IN); + thd->parse_error(ER_MAXVALUE_IN_VALUES_IN); MYSQL_YYABORT; } if (part_info->add_max_value(thd)) @@ -5409,7 +5413,7 @@ part_value_expr_item: if (!lex->safe_to_cache_query) { - my_parse_error(thd, ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); + thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR); MYSQL_YYABORT; } if (part_info->add_column_list_value(thd, part_expr)) @@ -5431,7 +5435,7 @@ opt_sub_partition: We come here when we have defined subpartitions on the first partition but not on all the subsequent partitions. */ - my_parse_error(thd, ER_PARTITION_WRONG_NO_SUBPART_ERROR); + thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } } @@ -5443,7 +5447,7 @@ opt_sub_partition: if (part_info->num_subparts != part_info->count_curr_subparts) { - my_parse_error(thd, ER_PARTITION_WRONG_NO_SUBPART_ERROR); + thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } } @@ -5451,7 +5455,7 @@ opt_sub_partition: { if (part_info->partitions.elements > 1) { - my_parse_error(thd, ER_PARTITION_WRONG_NO_SUBPART_ERROR); + thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } part_info->num_subparts= part_info->count_curr_subparts; @@ -5486,7 +5490,7 @@ sub_part_definition: the second partition (the current partition processed have already been put into the partitions list. */ - my_parse_error(thd, ER_PARTITION_WRONG_NO_SUBPART_ERROR); + thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR); MYSQL_YYABORT; } if (!sub_p_elem || @@ -5720,7 +5724,7 @@ create_table_option: Lex->create_info.table_options|= HA_OPTION_PACK_KEYS; break; default: - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS; @@ -5741,7 +5745,7 @@ create_table_option: Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_ON; break; default: - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC; @@ -5761,7 +5765,7 @@ create_table_option: Lex->create_info.table_options|= HA_OPTION_STATS_PERSISTENT; break; default: - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT; @@ -5784,7 +5788,7 @@ create_table_option: we can store the higher bits from stats_sample_pages in .frm too. */ if ($3 == 0 || $3 > 0xffff) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } Lex->create_info.stats_sample_pages=$3; @@ -5913,6 +5917,11 @@ create_table_option: engine_option_value($1, &Lex->create_info.option_list, &Lex->option_list_last); } + | SEQUENCE_SYM opt_equal choice + { + Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE; + Lex->create_info.sequence= $3; + } ; default_charset: @@ -6025,28 +6034,28 @@ key_def: key_or_index opt_if_not_exists opt_ident opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, $3, $4, $2)) + if (Lex->add_key(Key::MULTIPLE, &$3, $4, $2)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | key_or_index opt_if_not_exists ident TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key(Key::MULTIPLE, $3, $5, $2)) + if (Lex->add_key(Key::MULTIPLE, &$3, $5, $2)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } | fulltext opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, $4, HA_KEY_ALG_UNDEF, $3)) + if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) MYSQL_YYABORT; } '(' key_list ')' fulltext_key_options { } | spatial opt_key_or_index opt_if_not_exists opt_ident { Lex->option_list= NULL; - if (Lex->add_key($1, $4, HA_KEY_ALG_UNDEF, $3)) + if (Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)) MYSQL_YYABORT; } '(' key_list ')' spatial_key_options { } @@ -6055,7 +6064,7 @@ key_def: opt_USING_key_algorithm { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? $4 : $1, $5, $3)) + if (Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } @@ -6063,7 +6072,7 @@ key_def: TYPE_SYM btree_or_rtree { Lex->option_list= NULL; - if (Lex->add_key($2, $4.str ? $4 : $1, $6, $3)) + if (Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { } @@ -6071,7 +6080,7 @@ key_def: { if (Lex->check_add_key($4) || !(Lex->last_key= (new (thd->mem_root) - Key(Key::MULTIPLE, $1.str ? $1 : $5, + Key(Key::MULTIPLE, $1.str ? &$1 : &$5, HA_KEY_ALG_UNDEF, true, $4)))) MYSQL_YYABORT; Lex->option_list= NULL; @@ -6080,11 +6089,11 @@ key_def: { LEX *lex=Lex; Key *key= (new (thd->mem_root) - Foreign_key($5.str ? $5 : $1, - lex->last_key->columns, - $10->db, - $10->table, - lex->ref_list, + Foreign_key($5.str ? &$5 : &$1, + &lex->last_key->columns, + &$10->db, + &$10->table, + &lex->ref_list, lex->fk_delete_opt, lex->fk_update_opt, lex->fk_match_option, @@ -6130,7 +6139,7 @@ check_constraint: ; opt_constraint: - /* empty */ { $$= null_lex_str; } + /* empty */ { $$= null_clex_str; } | constraint { $$= $1; } ; @@ -6151,7 +6160,7 @@ field_spec: if (!f) MYSQL_YYABORT; - lex->init_last_field(f, $1.str, NULL); + lex->init_last_field(f, &$1, NULL); $<create_field>$= f; } field_type_or_serial opt_check_constraint @@ -6168,19 +6177,18 @@ field_spec: $$->create_if_not_exists= Lex->check_exists; if ($$->flags & PRI_KEY_FLAG) - add_key_to_list(lex, &$1, Key::PRIMARY, Lex->check_exists); + lex->add_key_to_list(&$1, Key::PRIMARY, lex->check_exists); else if ($$->flags & UNIQUE_KEY_FLAG) - add_key_to_list(lex, &$1, Key::UNIQUE, Lex->check_exists); + lex->add_key_to_list(&$1, Key::UNIQUE, lex->check_exists); } ; field_type_or_serial: - field_type { Lex->set_last_field_type($1); } field_def + field_type { Lex->last_field->set_attributes($1, Lex->charset); } + field_def | SERIAL_SYM { - Lex_field_type_st type; - type.set(MYSQL_TYPE_LONGLONG); - Lex->set_last_field_type(type); + Lex->last_field->set_handler(&type_handler_longlong); Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_KEY_FLAG; } @@ -6319,65 +6327,86 @@ column_default_expr: ; field_type: + field_type_numeric + | field_type_temporal + | field_type_string + | field_type_lob + | field_type_misc + ; + +field_type_numeric: int_type opt_field_length field_options { $$.set($1, $2); } | real_type opt_precision field_options { $$.set($1, $2); } | FLOAT_SYM float_options field_options { - $$.set(MYSQL_TYPE_FLOAT, $2); + $$.set(&type_handler_float, $2); if ($2.length() && !$2.dec()) { int err; ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); if (err || tmp_length > PRECISION_FOR_DOUBLE) my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0), - Lex->last_field->field_name)); + Lex->last_field->field_name.str)); if (tmp_length > PRECISION_FOR_FLOAT) - $$.set(MYSQL_TYPE_DOUBLE); + $$.set(&type_handler_double); else - $$.set(MYSQL_TYPE_FLOAT); + $$.set(&type_handler_float); } } | BIT_SYM opt_field_length_default_1 { - $$.set(MYSQL_TYPE_BIT, $2); + $$.set(&type_handler_bit, $2); } | BOOL_SYM { - $$.set(MYSQL_TYPE_TINY, "1"); + $$.set(&type_handler_tiny, "1"); } | BOOLEAN_SYM { - $$.set(MYSQL_TYPE_TINY, "1"); + $$.set(&type_handler_tiny, "1"); } - | char opt_field_length_default_1 opt_binary + | DECIMAL_SYM float_options field_options + { $$.set(&type_handler_newdecimal, $2);} + | NUMERIC_SYM float_options field_options + { $$.set(&type_handler_newdecimal, $2);} + | FIXED_SYM float_options field_options + { $$.set(&type_handler_newdecimal, $2);} + ; + + +field_type_string: + char opt_field_length_default_1 opt_binary { - $$.set(MYSQL_TYPE_STRING, $2); + $$.set(&type_handler_string, $2); } | nchar opt_field_length_default_1 opt_bin_mod { - $$.set(MYSQL_TYPE_STRING, $2); + $$.set(&type_handler_string, $2); bincmp_collation(national_charset_info, $3); } | BINARY opt_field_length_default_1 { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_STRING, $2); + $$.set(&type_handler_string, $2); } | varchar field_length opt_binary { - $$.set(MYSQL_TYPE_VARCHAR, $2); + $$.set(&type_handler_varchar, $2); } | nvarchar field_length opt_bin_mod { - $$.set(MYSQL_TYPE_VARCHAR, $2); + $$.set(&type_handler_varchar, $2); bincmp_collation(national_charset_info, $3); } | VARBINARY field_length { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_VARCHAR, $2); + $$.set(&type_handler_varchar, $2); } - | YEAR_SYM opt_field_length field_options + ; + +field_type_temporal: + YEAR_SYM opt_field_length field_options { if ($2) { @@ -6393,18 +6422,23 @@ field_type: buff, "YEAR(4)"); } } - $$.set(MYSQL_TYPE_YEAR, $2); + $$.set(&type_handler_year, $2); } - | DATE_SYM - { $$.set(MYSQL_TYPE_DATE); } + | DATE_SYM { $$.set(thd->type_handler_for_date()); } | TIME_SYM opt_field_length - { $$.set(opt_mysql56_temporal_format ? - MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); } + { + $$.set(opt_mysql56_temporal_format ? + static_cast<const Type_handler*>(&type_handler_time2) : + static_cast<const Type_handler*>(&type_handler_time), + $2); + } | TIMESTAMP opt_field_length { if (thd->variables.sql_mode & MODE_MAXDB) $$.set(opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); + static_cast<const Type_handler*>(&type_handler_datetime2) : + static_cast<const Type_handler*>(&type_handler_datetime), + $2); else { /* @@ -6413,29 +6447,39 @@ field_type: */ if (!opt_explicit_defaults_for_timestamp) Lex->last_field->flags|= NOT_NULL_FLAG; - $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 - : MYSQL_TYPE_TIMESTAMP, $2); + $$.set(opt_mysql56_temporal_format ? + static_cast<const Type_handler*>(&type_handler_timestamp2): + static_cast<const Type_handler*>(&type_handler_timestamp), + $2); } } | DATETIME opt_field_length - { $$.set(opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); } - | TINYBLOB + { + $$.set(opt_mysql56_temporal_format ? + static_cast<const Type_handler*>(&type_handler_datetime2) : + static_cast<const Type_handler*>(&type_handler_datetime), + $2); + } + ; + + +field_type_lob: + TINYBLOB { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_TINY_BLOB); + $$.set(&type_handler_tiny_blob); } | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_BLOB, $2); + $$.set(&type_handler_blob, $2); } | spatial_type float_options srid_option { #ifdef HAVE_SPATIAL Lex->charset=&my_charset_bin; Lex->last_field->geom_type= $1; - $$.set(MYSQL_TYPE_GEOMETRY, $2); + $$.set(&type_handler_geometry, $2); #else my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define)); @@ -6444,42 +6488,39 @@ field_type: | MEDIUMBLOB { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_MEDIUM_BLOB); + $$.set(&type_handler_medium_blob); } | LONGBLOB { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_LONG_BLOB); + $$.set(&type_handler_long_blob); } | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; - $$.set(MYSQL_TYPE_MEDIUM_BLOB); + $$.set(&type_handler_medium_blob); } | LONG_SYM varchar opt_binary - { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } + { $$.set(&type_handler_medium_blob); } | TINYTEXT opt_binary - { $$.set(MYSQL_TYPE_TINY_BLOB); } + { $$.set(&type_handler_tiny_blob); } | TEXT_SYM opt_field_length opt_binary - { $$.set(MYSQL_TYPE_BLOB, $2); } + { $$.set(&type_handler_blob, $2); } | MEDIUMTEXT opt_binary - { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } + { $$.set(&type_handler_medium_blob); } | LONGTEXT opt_binary - { $$.set(MYSQL_TYPE_LONG_BLOB); } - | DECIMAL_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | NUMERIC_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | FIXED_SYM float_options field_options - { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} - | ENUM '(' string_list ')' opt_binary - { $$.set(MYSQL_TYPE_ENUM); } - | SET '(' string_list ')' opt_binary - { $$.set(MYSQL_TYPE_SET); } + { $$.set(&type_handler_long_blob); } | LONG_SYM opt_binary - { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } + { $$.set(&type_handler_medium_blob); } | JSON_SYM opt_binary - { $$.set(MYSQL_TYPE_BLOB); } + { $$.set(&type_handler_blob); } + ; + +field_type_misc: + ENUM '(' string_list ')' opt_binary + { $$.set(&type_handler_enum); } + | SET '(' string_list ')' opt_binary + { $$.set(&type_handler_set); } ; spatial_type: @@ -6516,23 +6557,22 @@ nvarchar: ; int_type: - INT_SYM { $$=MYSQL_TYPE_LONG; } - | TINYINT { $$=MYSQL_TYPE_TINY; } - | SMALLINT { $$=MYSQL_TYPE_SHORT; } - | MEDIUMINT { $$=MYSQL_TYPE_INT24; } - | BIGINT { $$=MYSQL_TYPE_LONGLONG; } + INT_SYM { $$= &type_handler_long; } + | TINYINT { $$= &type_handler_tiny; } + | SMALLINT { $$= &type_handler_short; } + | MEDIUMINT { $$= &type_handler_int24; } + | BIGINT { $$= &type_handler_longlong; } ; real_type: REAL { $$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ? - MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE; + static_cast<const Type_handler *>(&type_handler_float) : + static_cast<const Type_handler *>(&type_handler_double); } - | DOUBLE_SYM - { $$=MYSQL_TYPE_DOUBLE; } - | DOUBLE_SYM PRECISION - { $$=MYSQL_TYPE_DOUBLE; } + | DOUBLE_SYM { $$= &type_handler_double; } + | DOUBLE_SYM PRECISION { $$= &type_handler_double; } ; srid_option: @@ -6676,7 +6716,7 @@ type_with_opt_collate: if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2))) MYSQL_YYABORT; } - Lex->set_last_field_type($1); + Lex->last_field->set_attributes($1, Lex->charset); } ; @@ -6770,7 +6810,7 @@ ws_nweights: { if ($2 == 0) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -6858,14 +6898,14 @@ opt_ref_list: ref_list: ref_list ',' ident { - Key_part_spec *key= new (thd->mem_root) Key_part_spec($3, 0); + Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$3, 0); if (key == NULL) MYSQL_YYABORT; Lex->ref_list.push_back(key, thd->mem_root); } | ident { - Key_part_spec *key= new (thd->mem_root) Key_part_spec($1, 0); + Key_part_spec *key= new (thd->mem_root) Key_part_spec(&$1, 0); if (key == NULL) MYSQL_YYABORT; LEX *lex= Lex; @@ -7091,7 +7131,7 @@ key_list: key_part: ident { - $$= new (thd->mem_root) Key_part_spec($1, 0); + $$= new (thd->mem_root) Key_part_spec(&$1, 0); if ($$ == NULL) MYSQL_YYABORT; } @@ -7100,19 +7140,19 @@ key_part: int key_part_len= atoi($3.str); if (!key_part_len) my_yyabort_error((ER_KEY_PART_0, MYF(0), $1.str)); - $$= new (thd->mem_root) Key_part_spec($1, (uint) key_part_len); + $$= new (thd->mem_root) Key_part_spec(&$1, (uint) key_part_len); if ($$ == NULL) MYSQL_YYABORT; } ; opt_ident: - /* empty */ { $$= null_lex_str; } + /* empty */ { $$= null_clex_str; } | field_ident { $$= $1; } ; opt_component: - /* empty */ { $$= null_lex_str; } + /* empty */ { $$= null_clex_str; } | '.' ident { $$= $2; } ; @@ -7129,8 +7169,8 @@ string_list: alter: ALTER { - Lex->name= null_lex_str; - Lex->only_view= FALSE; + Lex->name= null_clex_str; + Lex->table_type= TABLE_TYPE_UNKNOWN; Lex->sql_command= SQLCOM_ALTER_TABLE; Lex->duplicates= DUP_ERROR; Lex->select_lex.init_order(); @@ -7189,7 +7229,7 @@ alter: if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE")); - bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + lex->sp_chistics.init(); } sp_a_chistics { @@ -7204,7 +7244,7 @@ alter: if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); - bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + lex->sp_chistics.init(); } sp_a_chistics { @@ -7213,31 +7253,24 @@ alter: lex->sql_command= SQLCOM_ALTER_FUNCTION; lex->spname= $3; } - | ALTER view_algorithm definer_opt + | ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident { - LEX *lex= Lex; - - if (lex->sphead) - my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW")); - lex->create_view_mode= VIEW_ALTER; + if (Lex->add_alter_view(thd, $2, $4, $6)) + MYSQL_YYABORT; } - view_tail + view_list_opt AS view_select {} - | ALTER definer_opt + | ALTER definer_opt opt_view_suid VIEW_SYM table_ident /* We have two separate rules for ALTER VIEW rather that optional view_algorithm above, to resolve the ambiguity with the ALTER EVENT below. */ { - LEX *lex= Lex; - - if (lex->sphead) - my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW")); - lex->create_view_algorithm= VIEW_ALGORITHM_INHERIT; - lex->create_view_mode= VIEW_ALTER; + if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5)) + MYSQL_YYABORT; } - view_tail + view_list_opt AS view_select {} | ALTER definer_opt remember_name EVENT_SYM sp_name { @@ -7264,7 +7297,7 @@ alter: { if (!($7 || $8 || $9 || $10 || $11)) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } /* @@ -7307,6 +7340,33 @@ alter: Lex->create_info.set($2); Lex->sql_command= SQLCOM_ALTER_USER; } + | ALTER SEQUENCE_SYM opt_if_exists_table_element + { + LEX *lex= Lex; + lex->name= null_clex_str; + lex->table_type= TABLE_TYPE_UNKNOWN; + lex->sql_command= SQLCOM_ALTER_SEQUENCE; + lex->create_info.init(); + lex->no_write_to_binlog= 0; + DBUG_ASSERT(!lex->m_sql_cmd); + } + table_ident + { + LEX *lex= Lex; + if (!(lex->create_info.seq_create_info= new (thd->mem_root) + sequence_definition()) || + !lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_SEQUENCE, + TL_WRITE, MDL_EXCLUSIVE)) + MYSQL_YYABORT; + } + sequence_defs + { + /* Create a generic ALTER SEQUENCE statment. */ + Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence(); + if (Lex->m_sql_cmd == NULL) + MYSQL_YYABORT; + } ; ev_alter_on_schedule_completion: @@ -7335,7 +7395,7 @@ opt_ev_sql_stmt: ; ident_or_empty: - /* empty */ { $$= null_lex_str; } + /* empty */ { $$= null_clex_str; } | ident { $$= $1; } ; @@ -7620,7 +7680,7 @@ alter_list_item: { Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - $5->change= $4.str; + $5->change= $4; $5->after= $6; } | MODIFY_SYM opt_column opt_if_exists_table_element @@ -7725,7 +7785,7 @@ alter_list_item: MYSQL_YYABORT; } if (check_table_name($3->table.str,$3->table.length, FALSE) || - ($3->db.str && check_db_name(&$3->db))) + ($3->db.str && check_db_name((LEX_STRING*) &$3->db))) my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3->table.str)); lex->name= $3->table; lex->alter_info.flags|= Alter_info::ALTER_RENAME; @@ -7840,15 +7900,16 @@ opt_restrict: ; opt_place: - /* empty */ { $$= NULL; } + /* empty */ { $$= null_clex_str; } | AFTER_SYM ident { - $$= $2.str; + $$= $2; Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } | FIRST_SYM { - $$= first_keyword; + $$.str= first_keyword; + $$.length= 5; /* Length of "first" */ Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } ; @@ -7903,7 +7964,7 @@ start: if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) && ($3 & MYSQL_START_TRANS_OPT_READ_ONLY)) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } lex->start_transaction_opt= $3; @@ -8006,7 +8067,9 @@ opt_checksum_type: repair_table_or_view: table_or_tables table_list opt_mi_repair_type - | VIEW_SYM { Lex->only_view= TRUE; } table_list opt_view_repair_type + | VIEW_SYM + { Lex->table_type= TABLE_TYPE_VIEW; } + table_list opt_view_repair_type ; repair: @@ -8171,7 +8234,9 @@ binlog_base64_event: check_view_or_table: table_or_tables table_list opt_mi_check_type - | VIEW_SYM { Lex->only_view= TRUE; } table_list opt_view_check_type + | VIEW_SYM + { Lex->table_type= TABLE_TYPE_VIEW; } + table_list opt_view_check_type ; check: CHECK_SYM @@ -8718,7 +8783,7 @@ select_item_list: { Item *item= new (thd->mem_root) Item_field(thd, &thd->lex->current_select->context, - NULL, NULL, "*"); + NULL, NULL, &star_clex_str); if (item == NULL) MYSQL_YYABORT; if (add_item_to_list(thd, item)) @@ -8747,7 +8812,7 @@ select_item: $2->is_autogenerated_name= FALSE; $2->set_name(thd, $4.str, $4.length, system_charset_info); } - else if (!$2->name) + else if (!$2->name.str || $2->name.str == item_empty_name) { $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } @@ -8768,12 +8833,12 @@ remember_name: remember_end: { - $$= (char*) YYLIP->get_cpp_tok_end(); + $$= (char*) YYLIP->get_cpp_tok_end_rtrim(); } ; select_alias: - /* empty */ { $$=null_lex_str;} + /* empty */ { $$=null_clex_str;} | AS ident { $$=$2; } | AS TEXT_STRING_sys { $$=$2; } | ident { $$=$1; } @@ -9372,10 +9437,7 @@ column_default_non_parenthesized_expr: } | CAST_SYM '(' expr AS cast_type ')' { - LEX *lex= Lex; - $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), - lex->charset); - if ($$ == NULL) + if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) MYSQL_YYABORT; } | CASE_SYM opt_expr when_list opt_else END @@ -9386,9 +9448,7 @@ column_default_non_parenthesized_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), - Lex->charset); - if ($$ == NULL) + if (!($$= $5.create_typecast_item(thd, $3, Lex->charset))) MYSQL_YYABORT; } | CONVERT_SYM '(' expr USING charset_name ')' @@ -9414,6 +9474,41 @@ column_default_non_parenthesized_expr: if ($$ == NULL) MYSQL_YYABORT; } + | NEXT_SYM VALUE_SYM FOR_SYM table_ident + { + if (!($$= Lex->create_item_func_nextval(thd, $4))) + MYSQL_YYABORT; + } + | NEXTVAL_SYM '(' table_ident ')' + { + if (!($$= Lex->create_item_func_nextval(thd, $3))) + MYSQL_YYABORT; + } + | PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident + { + if (!($$= Lex->create_item_func_lastval(thd, $4))) + MYSQL_YYABORT; + } + | LASTVAL_SYM '(' table_ident ')' + { + if (!($$= Lex->create_item_func_lastval(thd, $3))) + MYSQL_YYABORT; + } + | SETVAL_SYM '(' table_ident ',' longlong_num ')' + { + if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1))) + MYSQL_YYABORT; + } + | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ')' + { + if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7))) + MYSQL_YYABORT; + } + | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ',' ulonglong_num ')' + { + if (!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7))) + MYSQL_YYABORT; + } ; simple_expr: @@ -9432,9 +9527,8 @@ simple_expr: | '(' parenthesized_expr ')' { $$= $2; } | BINARY simple_expr %prec NEG { - $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL, - &my_charset_bin); - if ($$ == NULL) + Type_cast_attributes at(&my_charset_bin); + if (!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))) MYSQL_YYABORT; } | simple_expr OR_OR_SYM simple_expr @@ -9728,6 +9822,12 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } + | DECODE_SYM '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } | EXTRACT_SYM '(' interval FROM expr ')' { $$=new (thd->mem_root) Item_extract(thd, $3, $5); @@ -9873,7 +9973,7 @@ function_call_nonkeyword: COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_dyncol_get(thd, $3, $5, $7.type(), + $$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(), $7.length(), $7.dec(), lex->charset); if ($$ == NULL) @@ -10157,7 +10257,7 @@ function_call_generic: { if (lex->current_select->inc_in_sum_expr()) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -10184,10 +10284,10 @@ function_call_generic: This will be revised with WL#2128 (SQL PATH) */ - builder= find_native_function_builder(thd, $1); + builder= find_native_function_builder(thd, &$1); if (builder) { - item= builder->create_func(thd, $1, $4); + item= builder->create_func(thd, &$1, $4); } else { @@ -10209,7 +10309,7 @@ function_call_generic: { builder= find_qualified_function_builder(thd); DBUG_ASSERT(builder); - item= builder->create_func(thd, $1, $4); + item= builder->create_func(thd, &$1, $4); } } @@ -10237,7 +10337,7 @@ function_call_generic: version() (a vendor can specify any schema). */ - if (!$1.str || check_db_name(&$1)) + if (!$1.str || check_db_name((LEX_STRING*) &$1)) my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str)); if (check_routine_name(&$3)) { @@ -10246,7 +10346,7 @@ function_call_generic: builder= find_qualified_function_builder(thd); DBUG_ASSERT(builder); - item= builder->create_with_db(thd, $1, $3, true, $5); + item= builder->create_with_db(thd, &$1, &$3, true, $5); if (! ($$= item)) { @@ -10598,7 +10698,7 @@ simple_window_func: window_name: ident { - $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING)); + $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); if ($$ == NULL) MYSQL_YYABORT; } @@ -10620,7 +10720,7 @@ variable_aux: ident_or_text SET_VAR expr { Item_func_set_user_var *item; - $$= item= new (thd->mem_root) Item_func_set_user_var(thd, $1, $3); + $$= item= new (thd->mem_root) Item_func_set_user_var(thd, &$1, $3); if ($$ == NULL) MYSQL_YYABORT; LEX *lex= Lex; @@ -10629,7 +10729,7 @@ variable_aux: } | ident_or_text { - $$= new (thd->mem_root) Item_func_get_user_var(thd, $1); + $$= new (thd->mem_root) Item_func_get_user_var(thd, &$1); if ($$ == NULL) MYSQL_YYABORT; LEX *lex= Lex; @@ -10640,7 +10740,7 @@ variable_aux: /* disallow "SELECT @@global.global.variable" */ if ($3.str && $4.str && check_reserved_words(&$3)) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } if (!($$= get_system_var(thd, $2, $3, $4))) @@ -10683,7 +10783,7 @@ in_sum_expr: LEX *lex= Lex; if (lex->current_select->inc_in_sum_expr()) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -10696,34 +10796,34 @@ in_sum_expr: cast_type: BINARY opt_field_length - { $$.set(ITEM_CAST_CHAR, $2); Lex->charset= &my_charset_bin; } + { $$.set(&type_handler_long_blob, $2); Lex->charset= &my_charset_bin; } | CHAR_SYM opt_field_length { Lex->charset= thd->variables.collation_connection; } opt_binary - { $$.set(ITEM_CAST_CHAR, $2); } + { $$.set(&type_handler_long_blob, $2); } | NCHAR_SYM opt_field_length { Lex->charset= national_charset_info; - $$.set(ITEM_CAST_CHAR, $2, 0); + $$.set(&type_handler_long_blob, $2, 0); } | cast_type_numeric { $$= $1; Lex->charset= NULL; } | cast_type_temporal { $$= $1; Lex->charset= NULL; } ; cast_type_numeric: - INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } - | SIGNED_SYM { $$.set(ITEM_CAST_SIGNED_INT); } - | SIGNED_SYM INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); } - | UNSIGNED { $$.set(ITEM_CAST_UNSIGNED_INT); } - | UNSIGNED INT_SYM { $$.set(ITEM_CAST_UNSIGNED_INT); } - | DECIMAL_SYM float_options { $$.set(ITEM_CAST_DECIMAL, $2); } - | DOUBLE_SYM opt_precision { $$.set(ITEM_CAST_DOUBLE, $2); } + INT_SYM { $$.set(&type_handler_longlong); } + | SIGNED_SYM { $$.set(&type_handler_longlong); } + | SIGNED_SYM INT_SYM { $$.set(&type_handler_longlong); } + | UNSIGNED { $$.set(&type_handler_ulonglong); } + | UNSIGNED INT_SYM { $$.set(&type_handler_ulonglong); } + | DECIMAL_SYM float_options { $$.set(&type_handler_newdecimal, $2); } + | DOUBLE_SYM opt_precision { $$.set(&type_handler_double, $2); } ; cast_type_temporal: - DATE_SYM { $$.set(ITEM_CAST_DATE); } - | TIME_SYM opt_field_length { $$.set(ITEM_CAST_TIME, 0, $2); } - | DATETIME opt_field_length { $$.set(ITEM_CAST_DATETIME, 0, $2); } + DATE_SYM { $$.set(&type_handler_newdate); } + | TIME_SYM opt_field_length { $$.set(&type_handler_time2, 0, $2); } + | DATETIME opt_field_length { $$.set(&type_handler_datetime2, 0, $2); } ; opt_expr_list: @@ -10802,7 +10902,7 @@ table_ref: LEX *lex= Lex; if (!($$= lex->current_select->nest_last_join(thd))) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -11057,6 +11157,7 @@ table_primary_derived: are no outer parentheses, add_table_to_list() will throw error in this case */ LEX *lex=Lex; + lex->check_automatic_up(UNSPECIFIED_TYPE); SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel->master_unit(); lex->current_select= sel= unit->outer_select(); @@ -11072,17 +11173,13 @@ table_primary_derived: lex->pop_context(); lex->nest_level--; } - /*else if (($3->select_lex && - $3->select_lex->master_unit()->is_union() && - ($3->select_lex->master_unit()->first_select() == - $3->select_lex || !$3->lifted)) || $5)*/ else if ($5 != NULL) { /* Tables with or without joins within parentheses cannot have aliases, and we ruled out derived tables above. */ - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } else @@ -11147,7 +11244,7 @@ select_derived_union: { if ($1) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -11155,7 +11252,7 @@ select_derived_union: { if ($1) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -11211,7 +11308,7 @@ select_derived: MYSQL_YYABORT; if (!$2 && $$) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -11238,11 +11335,11 @@ select_derived2: if (!lex->expr_allows_subselect || lex->sql_command == (int)SQLCOM_PURGE) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || - mysql_new_select(lex, 1)) + mysql_new_select(lex, 1, NULL)) MYSQL_YYABORT; mysql_init_select(lex); lex->current_select->linkage= DERIVED_TABLE_TYPE; @@ -11336,7 +11433,7 @@ key_usage_element: ident { Select->add_index_hint(thd, $1.str, $1.length); } | PRIMARY_SYM - { Select->add_index_hint(thd, (char *)"PRIMARY", 7); } + { Select->add_index_hint(thd, "PRIMARY", 7); } ; key_usage_list: @@ -11412,7 +11509,7 @@ opt_table_alias: /* empty */ { $$=0; } | table_alias ident { - $$= (LEX_STRING*) thd->memdup(&$2,sizeof(LEX_STRING)); + $$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING)); if ($$ == NULL) MYSQL_YYABORT; } @@ -11548,7 +11645,7 @@ window_def: if (Select->add_window_def(thd, $1, lex->win_ref, Select->group_list, Select->order_list, - lex->win_frame )) + lex->win_frame)) MYSQL_YYABORT; } ; @@ -11565,7 +11662,7 @@ opt_window_ref: /* empty */ {} | ident { - thd->lex->win_ref= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING)); + thd->lex->win_ref= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); if (thd->lex->win_ref == NULL) MYSQL_YYABORT; } @@ -11730,13 +11827,13 @@ order_clause: yet. */ SELECT_LEX *first_sl= unit->first_select(); - if (!unit->is_union() && + if (!unit->is_unit_op() && (first_sl->order_list.elements || first_sl->select_limit) && unit->add_fake_select_lex(thd)) MYSQL_YYABORT; } - if (sel->master_unit()->is_union() && !sel->braces) + if (sel->master_unit()->is_unit_op() && !sel->braces) { /* At this point we don't know yet whether this is the last @@ -11776,7 +11873,7 @@ limit_clause_init: LIMIT { SELECT_LEX *sel= Select; - if (sel->master_unit()->is_union() && !sel->braces) + if (sel->master_unit()->is_unit_op() && !sel->braces) { /* Move LIMIT that belongs to UNION to fake_select_lex */ Lex->current_select= sel->master_unit()->fake_select_lex; @@ -11829,32 +11926,25 @@ limit_options: ; limit_option: - ident + ident_with_tok_start { - Item_splocal *splocal; LEX *lex= thd->lex; Lex_input_stream *lip= & thd->m_parser_state->m_lip; - sp_variable *spv; - sp_pcontext *spc = lex->spcont; - if (spc && (spv = spc->find_variable($1, false))) - { - splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->sql_type(), - lip->get_tok_start() - lex->sphead->m_tmp_query, - lip->get_ptr() - lip->get_tok_start()); - if (splocal == NULL) - MYSQL_YYABORT; -#ifndef DBUG_OFF - splocal->m_sp= lex->sphead; -#endif - lex->safe_to_cache_query=0; - } - else - my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); - if (splocal->type() != Item::INT_ITEM) - my_yyabort_error((ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0))); - splocal->limit_clause_param= TRUE; - $$= splocal; + if (!($$= lex->create_item_limit(thd, &$1, + $1.m_pos - + lex->substatement_query(thd), + lip->get_tok_end() - $1.m_pos))) + MYSQL_YYABORT; + } + | ident_with_tok_start '.' ident + { + LEX *lex= thd->lex; + Lex_input_stream *lip= & thd->m_parser_state->m_lip; + if (!($$= lex->create_item_limit(thd, &$1, &$3, + $1.m_pos - + lex->substatement_query(thd), + lip->get_ptr() - $1.m_pos))) + MYSQL_YYABORT; } | param_marker { @@ -11900,23 +11990,26 @@ delete_limit_clause: Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT); sel->explicit_limit= 1; } - | LIMIT ROWS_SYM EXAMINED_SYM { my_parse_error(thd, ER_SYNTAX_ERROR); MYSQL_YYABORT; } - | LIMIT limit_option ROWS_SYM EXAMINED_SYM { my_parse_error(thd, ER_SYNTAX_ERROR); MYSQL_YYABORT; } + | LIMIT ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; } + | LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; } + ; + +opt_plus: + /* empty */ + | '+' ; int_num: - NUM { int error; $$= (int) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (int) my_strtoll10($2.str, (char**) 0, &error); } | '-' NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); } - | '-' LONG_NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); } - ; ulong_num: - NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } | HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); } - | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulong_num: @@ -11927,12 +12020,19 @@ real_ulong_num: | dec_num_error { MYSQL_YYABORT; } ; +longlong_num: + opt_plus NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); } + | LONG_NUM { int error; $$= (longlong) my_strtoll10($1.str, (char**) 0, &error); } + | '-' NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } + | '-' LONG_NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); } + + ulonglong_num: - NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } - | FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + opt_plus NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus LONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } + | opt_plus FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); } ; real_ulonglong_num: @@ -11945,7 +12045,7 @@ real_ulonglong_num: dec_num_error: dec_num - { my_parse_error(thd, ER_ONLY_INTEGERS_ALLOWED); } + { thd->parse_error(ER_ONLY_INTEGERS_ALLOWED); } ; dec_num: @@ -11958,6 +12058,12 @@ choice: | DEFAULT { $$= HA_CHOICE_UNDEF; } ; +bool: + ulong_num { $$= $1 != 0; } + | TRUE_SYM { $$= 1; } + | FALSE_SYM { $$= 0; } + + procedure_clause: PROCEDURE_SYM ident /* Procedure name */ { @@ -11970,7 +12076,7 @@ procedure_clause: lex->proc_list.next= &lex->proc_list.first; Item_field *item= new (thd->mem_root) Item_field(thd, &lex->current_select->context, - NULL, NULL, $2.str); + NULL, NULL, &$2); if (item == NULL) MYSQL_YYABORT; if (add_proc_to_list(thd, item)) @@ -12007,7 +12113,7 @@ procedure_item: { if (add_proc_to_list(thd, $2)) MYSQL_YYABORT; - if (!$2->name) + if (!$2->name.str || $2->name.str == item_empty_name) $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } ; @@ -12050,19 +12156,24 @@ select_var_ident: select_outvar select_outvar: '@' ident_or_text { - $$ = Lex->result ? new (thd->mem_root) my_var_user($2) : NULL; + $$ = Lex->result ? new (thd->mem_root) my_var_user(&$2) : NULL; } | ident_or_text { sp_variable *t; - if (!Lex->spcont || !(t= Lex->spcont->find_variable($1, false))) + if (!Lex->spcont || !(t= Lex->spcont->find_variable(&$1, false))) my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str)); $$ = Lex->result ? (new (thd->mem_root) - my_var_sp($1, t->offset, t->sql_type(), + my_var_sp(&$1, t->offset, t->type_handler(), Lex->sphead)) : NULL; } + | ident '.' ident + { + if (!($$= Lex->create_outvar(thd, &$1, &$3))) + MYSQL_YYABORT; + } ; into: @@ -12160,31 +12271,29 @@ drop: { LEX *lex= thd->lex; sp_name *spname; - if ($4.str && check_db_name(&$4)) + if ($4.str && check_db_name((LEX_STRING*) &$4)) my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $4.str)); if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); lex->set_command(SQLCOM_DROP_FUNCTION, $3); - spname= new (thd->mem_root) sp_name($4, $6, true); + spname= new (thd->mem_root) sp_name(&$4, &$6, true); if (spname == NULL) MYSQL_YYABORT; - spname->init_qname(thd); lex->spname= spname; } | DROP FUNCTION_SYM opt_if_exists ident { LEX *lex= thd->lex; - LEX_STRING db= {0, 0}; + LEX_CSTRING db= {0, 0}; sp_name *spname; if (lex->sphead) my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "FUNCTION")); if (thd->db && lex->copy_db_to(&db.str, &db.length)) MYSQL_YYABORT; lex->set_command(SQLCOM_DROP_FUNCTION, $3); - spname= new (thd->mem_root) sp_name(db, $4, false); + spname= new (thd->mem_root) sp_name(&db, &$4, false); if (spname == NULL) MYSQL_YYABORT; - spname->init_qname(thd); lex->spname= spname; } | DROP PROCEDURE_SYM opt_if_exists sp_name @@ -12238,6 +12347,17 @@ drop: Lex->set_command(SQLCOM_DROP_SERVER, $3); Lex->server_options.reset($4); } + | DROP opt_temporary SEQUENCE_SYM opt_if_exists + + { + LEX *lex= Lex; + lex->set_command(SQLCOM_DROP_SEQUENCE, $2, $4); + lex->table_type= TABLE_TYPE_SEQUENCE; + YYPS->m_lock_type= TL_UNLOCK; + YYPS->m_mdl_type= MDL_EXCLUSIVE; + } + table_list + {} ; table_list: @@ -12456,6 +12576,16 @@ opt_equal: | equal {} ; +opt_with: + opt_equal {} + | WITH {} + ; + +opt_by: + opt_equal {} + | BY {} + ; + no_braces: '(' { @@ -12645,7 +12775,7 @@ table_wild_list: table_wild_one: ident opt_wild { - Table_ident *ti= new (thd->mem_root) Table_ident($1); + Table_ident *ti= new (thd->mem_root) Table_ident(&$1); if (ti == NULL) MYSQL_YYABORT; if (!Select->add_table_to_list(thd, @@ -12658,7 +12788,7 @@ table_wild_one: } | ident '.' ident opt_wild { - Table_ident *ti= new (thd->mem_root) Table_ident(thd, $1, $3, 0); + Table_ident *ti= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); if (ti == NULL) MYSQL_YYABORT; if (!Select->add_table_to_list(thd, @@ -12779,7 +12909,7 @@ show: { LEX *lex=Lex; lex->wild=0; - lex->ident=null_lex_str; + lex->ident= null_clex_str; mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; lex->create_info.init(); @@ -12802,7 +12932,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select_lex.db= $3; + lex->select_lex.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES)) MYSQL_YYABORT; } @@ -12810,7 +12940,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TRIGGERS; - lex->select_lex.db= $3; + lex->select_lex.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS)) MYSQL_YYABORT; } @@ -12818,7 +12948,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_EVENTS; - lex->select_lex.db= $2; + lex->select_lex.db= $2.str; if (prepare_schema_table(thd, lex, 0, SCH_EVENTS)) MYSQL_YYABORT; } @@ -12826,7 +12956,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; - lex->select_lex.db= $3; + lex->select_lex.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_TABLES)) MYSQL_YYABORT; } @@ -12834,7 +12964,7 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; - lex->select_lex.db= $3; + lex->select_lex.db= $3.str; if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES)) MYSQL_YYABORT; } @@ -12866,8 +12996,8 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_FIELDS; - if ($5) - $4->change_db($5); + if ($5.str) + $4->change_db(&$5); if (prepare_schema_table(thd, lex, $4, SCH_COLUMNS)) MYSQL_YYABORT; } @@ -12894,8 +13024,8 @@ show_param: { LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_KEYS; - if ($4) - $3->change_db($4); + if ($4.str) + $3->change_db(&$4); if (prepare_schema_table(thd, lex, $3, SCH_STATISTICS)) MYSQL_YYABORT; } @@ -13002,7 +13132,15 @@ show_param: lex->sql_command = SQLCOM_SHOW_CREATE; if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) MYSQL_YYABORT; - lex->only_view= 1; + lex->table_type= TABLE_TYPE_VIEW; + } + | CREATE SEQUENCE_SYM table_ident + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_CREATE; + if (!lex->select_lex.add_table_to_list(thd, $3, NULL, 0)) + MYSQL_YYABORT; + lex->table_type= TABLE_TYPE_SEQUENCE; } | MASTER_SYM STATUS_SYM { @@ -13016,7 +13154,7 @@ show_param: | SLAVE STATUS_SYM { LEX *lex= thd->lex; - lex->mi.connection_name= null_lex_str; + lex->mi.connection_name= null_clex_str; lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; lex->verbose= 0; } @@ -13101,12 +13239,12 @@ show_param: ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str, &in_plugin); if (!table || !table->old_format || !in_plugin) { - my_parse_error(thd, ER_SYNTAX_ERROR, $2); + thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } if (lex->wild && table->idx_field1 < 0) { - my_parse_error(thd, ER_SYNTAX_ERROR, $3); + thd->parse_error(ER_SYNTAX_ERROR, $3); MYSQL_YYABORT; } if (make_schema_select(thd, Lex->current_select, table)) @@ -13134,8 +13272,8 @@ opt_storage: ; opt_db: - /* empty */ { $$= 0; } - | from_or_in ident { $$= $2.str; } + /* empty */ { $$= null_clex_str; } + | from_or_in ident { $$= $2; } ; opt_full: @@ -13294,8 +13432,10 @@ opt_flush_lock: 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. */ + /* Don't try to flush views. */ + tables->required_type= TABLE_TYPE_NORMAL; + /* Ignore temporary tables. */ + tables->open_type= OT_BASE_ONLY; } } ; @@ -13307,7 +13447,7 @@ flush_lock: { if (Lex->query_tables == NULL) // Table list can't be empty { - my_parse_error(thd, ER_NO_TABLES_USED); + thd->parse_error(ER_NO_TABLES_USED); MYSQL_YYABORT; } Lex->type|= REFRESH_FOR_EXPORT; @@ -13348,7 +13488,7 @@ flush_option: | LOGS_SYM { Lex->type|= REFRESH_LOG; - Lex->relay_log_connection_name= empty_lex_str; + Lex->relay_log_connection_name= empty_clex_str; } | STATUS_SYM { Lex->type|= REFRESH_STATUS; } @@ -13372,7 +13512,7 @@ flush_option: ST_SCHEMA_TABLE *table= find_schema_table(thd, $1.str); if (!table || !table->reset_table) { - my_parse_error(thd, ER_SYNTAX_ERROR, $2); + thd->parse_error(ER_SYNTAX_ERROR, $2); MYSQL_YYABORT; } Lex->view_list.push_back((LEX_STRING*) @@ -13686,7 +13826,7 @@ field_or_var: simple_ident_nospvar {$$= $1;} | '@' ident_or_text { - $$= new (thd->mem_root) Item_user_var_as_out_param(thd, $2); + $$= new (thd->mem_root) Item_user_var_as_out_param(thd, &$2); if ($$ == NULL) MYSQL_YYABORT; } @@ -13718,37 +13858,16 @@ load_data_set_elem: text_literal: TEXT_STRING { - LEX_STRING tmp; - CHARSET_INFO *cs_con= thd->variables.collation_connection; - CHARSET_INFO *cs_cli= thd->variables.character_set_client; - uint repertoire= thd->lex->text_string_is_7bit && - my_charset_is_ascii_based(cs_cli) ? - MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; - if (thd->charset_is_collation_connection || - (repertoire == MY_REPERTOIRE_ASCII && - my_charset_is_ascii_based(cs_con))) - tmp= $1; - else - { - if (thd->convert_string(&tmp, cs_con, $1.str, $1.length, cs_cli)) - MYSQL_YYABORT; - } - $$= new (thd->mem_root) Item_string(thd, tmp.str, tmp.length, - cs_con, - DERIVATION_COERCIBLE, - repertoire); - if ($$ == NULL) + if (!($$= thd->make_string_literal($1))) MYSQL_YYABORT; } | NCHAR_STRING { - uint repertoire= Lex->text_string_is_7bit ? - MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30; DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info)); $$= new (thd->mem_root) Item_string(thd, $1.str, $1.length, national_charset_info, DERIVATION_COERCIBLE, - repertoire); + $1.repertoire()); if ($$ == NULL) MYSQL_YYABORT; } @@ -13831,17 +13950,10 @@ hex_or_bin_String: param_marker: PARAM_MARKER { - LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - Item_param *item; - if (! lex->parsing_options.allows_variable) - my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0))); - const char *query_start= lex->sphead ? lex->sphead->m_tmp_query - : thd->query(); - item= new (thd->mem_root) Item_param(thd, lip->get_tok_start() - - query_start); - if (!($$= item) || lex->param_list.push_back(item, thd->mem_root)) - my_yyabort_error((ER_OUT_OF_RESOURCES, MYF(0))); + if (!($$= Lex->add_placeholder(thd, ¶m_clex_str, + YYLIP->get_tok_start(), + YYLIP->get_tok_start() + 1))) + MYSQL_YYABORT; } ; @@ -14032,7 +14144,7 @@ with_list_element: query_name opt_with_column_list { - $2= new List<LEX_STRING> (Lex->with_column_list); + $2= new List<LEX_CSTRING> (Lex->with_column_list); if ($2 == NULL) MYSQL_YYABORT; Lex->with_column_list.empty(); @@ -14059,13 +14171,13 @@ opt_with_column_list: with_column_list: ident { - Lex->with_column_list.push_back((LEX_STRING*) - thd->memdup(&$1, sizeof(LEX_STRING))); + Lex->with_column_list.push_back((LEX_CSTRING*) + thd->memdup(&$1, sizeof(LEX_CSTRING))); } | with_column_list ',' ident { - Lex->with_column_list.push_back((LEX_STRING*) - thd->memdup(&$3, sizeof(LEX_STRING))); + Lex->with_column_list.push_back((LEX_CSTRING*) + thd->memdup(&$3, sizeof(LEX_CSTRING))); } ; @@ -14073,7 +14185,7 @@ with_column_list: query_name: ident { - $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING)); + $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING)); if ($$ == NULL) MYSQL_YYABORT; } @@ -14095,7 +14207,7 @@ table_wild: { SELECT_LEX *sel= Select; $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, $1.str, "*"); + NullS, $1.str, &star_clex_str); if ($$ == NULL) MYSQL_YYABORT; sel->with_wild++; @@ -14107,7 +14219,7 @@ table_wild: NullS : $1.str; $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), schema, - $3.str,"*"); + $3.str, &star_clex_str); if ($$ == NULL) MYSQL_YYABORT; sel->with_wild++; @@ -14121,66 +14233,28 @@ order_ident: simple_ident: ident { - LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; - sp_variable *spv; - sp_pcontext *spc = lex->spcont; - if (spc && (spv = spc->find_variable($1, false))) - { - /* We're compiling a stored procedure and found a variable */ - if (! lex->parsing_options.allows_variable) - my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0))); - - Item_splocal *splocal; - splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->sql_type(), - lip->get_tok_start_prev() - lex->sphead->m_tmp_query, - lip->get_tok_end() - lip->get_tok_start_prev()); - if (splocal == NULL) - MYSQL_YYABORT; -#ifndef DBUG_OFF - splocal->m_sp= lex->sphead; -#endif - $$= splocal; - lex->safe_to_cache_query=0; - } - else - { - SELECT_LEX *sel=Select; - if ((sel->parsing_place != IN_HAVING) || - (sel->get_in_sum_expr() > 0)) - { - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, NullS, $1.str); - } - else - { - $$= new (thd->mem_root) Item_ref(thd, Lex->current_context(), - NullS, NullS, $1.str); - } - if ($$ == NULL) - MYSQL_YYABORT; - } + if (!($$= Lex->create_item_ident(thd, &$1, + lip->get_tok_start_prev(), + lip->get_tok_end()))) + MYSQL_YYABORT; + } + | simple_ident_q2 + | ident '.' ident + { + LEX *lex= thd->lex; + if (!($$= lex->create_item_ident(thd, &$1, &$3, + $1.m_pos - + lex->substatement_query(thd), + YYLIP->get_tok_end() - $1.m_pos))) + MYSQL_YYABORT; } - | simple_ident_q { $$= $1; } ; simple_ident_nospvar: ident { - SELECT_LEX *sel=Select; - if ((sel->parsing_place != IN_HAVING) || - (sel->get_in_sum_expr() > 0)) - { - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, NullS, $1.str); - } - else - { - $$= new (thd->mem_root) Item_ref(thd, Lex->current_context(), - NullS, NullS, $1.str); - } - if ($$ == NULL) + if (!($$= Lex->create_item_ident_nosp(thd, &$1))) MYSQL_YYABORT; } | simple_ident_q { $$= $1; } @@ -14189,125 +14263,21 @@ simple_ident_nospvar: simple_ident_q: ident '.' ident { - LEX *lex= thd->lex; - - /* - FIXME This will work ok in simple_ident_nospvar case because - we can't meet simple_ident_nospvar in trigger now. But it - should be changed in future. - */ - if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && - (!my_strcasecmp(system_charset_info, $1.str, "NEW") || - !my_strcasecmp(system_charset_info, $1.str, "OLD"))) - { - Item_trigger_field *trg_fld; - bool new_row= ($1.str[0]=='N' || $1.str[0]=='n'); - - if (lex->trg_chistics.event == TRG_EVENT_INSERT && - !new_row) - my_yyabort_error((ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT")); - - if (lex->trg_chistics.event == TRG_EVENT_DELETE && - new_row) - my_yyabort_error((ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE")); - - DBUG_ASSERT(!new_row || - (lex->trg_chistics.event == TRG_EVENT_INSERT || - lex->trg_chistics.event == TRG_EVENT_UPDATE)); - const bool tmp_read_only= - !(new_row && lex->trg_chistics.action_time == TRG_ACTION_BEFORE); - trg_fld= new (thd->mem_root) - Item_trigger_field(thd, Lex->current_context(), - new_row ? - Item_trigger_field::NEW_ROW: - Item_trigger_field::OLD_ROW, - $3.str, - SELECT_ACL, - tmp_read_only); - if (trg_fld == NULL) - MYSQL_YYABORT; - - /* - Let us add this item to list of all Item_trigger_field objects - in trigger. - */ - lex->trg_table_fields.link_in_list(trg_fld, - &trg_fld->next_trg_field); - - $$= trg_fld; - } - else - { - SELECT_LEX *sel= lex->current_select; - if (sel->no_table_names_allowed) - { - my_error(ER_TABLENAME_NOT_ALLOWED_HERE, - MYF(0), $1.str, thd->where); - } - if ((sel->parsing_place != IN_HAVING) || - (sel->get_in_sum_expr() > 0)) - { - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, $1.str, $3.str); - } - else - { - $$= new (thd->mem_root) Item_ref(thd, Lex->current_context(), - NullS, $1.str, $3.str); - } - if ($$ == NULL) - MYSQL_YYABORT; - } + if (!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))) + MYSQL_YYABORT; } - | '.' ident '.' ident - { - LEX *lex= thd->lex; - SELECT_LEX *sel= lex->current_select; - if (sel->no_table_names_allowed) - { - my_error(ER_TABLENAME_NOT_ALLOWED_HERE, - MYF(0), $2.str, thd->where); - } - if ((sel->parsing_place != IN_HAVING) || - (sel->get_in_sum_expr() > 0)) - { - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - NullS, $2.str, $4.str); + | simple_ident_q2 + ; - } - else - { - $$= new (thd->mem_root) Item_ref(thd, Lex->current_context(), - NullS, $2.str, $4.str); - } - if ($$ == NULL) +simple_ident_q2: + '.' ident '.' ident + { + if (!($$= Lex->create_item_ident(thd, &null_clex_str, &$2, &$4))) MYSQL_YYABORT; } | ident '.' ident '.' ident { - LEX *lex= thd->lex; - SELECT_LEX *sel= lex->current_select; - const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ? - NullS : $1.str); - if (sel->no_table_names_allowed) - { - my_error(ER_TABLENAME_NOT_ALLOWED_HERE, - MYF(0), $3.str, thd->where); - } - if ((sel->parsing_place != IN_HAVING) || - (sel->get_in_sum_expr() > 0)) - { - $$= new (thd->mem_root) Item_field(thd, Lex->current_context(), - schema, - $3.str, $5.str); - } - else - { - $$= new (thd->mem_root) Item_ref(thd, Lex->current_context(), - schema, - $3.str, $5.str); - } - if ($$ == NULL) + if (!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))) MYSQL_YYABORT; } ; @@ -14337,20 +14307,20 @@ field_ident: table_ident: ident { - $$= new (thd->mem_root) Table_ident($1); + $$= new (thd->mem_root) Table_ident(&$1); if ($$ == NULL) MYSQL_YYABORT; } | ident '.' ident { - $$= new (thd->mem_root) Table_ident(thd, $1, $3, 0); + $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); if ($$ == NULL) MYSQL_YYABORT; } | '.' ident { /* For Delphi */ - $$= new (thd->mem_root) Table_ident($2); + $$= new (thd->mem_root) Table_ident(&$2); if ($$ == NULL) MYSQL_YYABORT; } @@ -14359,13 +14329,13 @@ table_ident: table_ident_opt_wild: ident opt_wild { - $$= new (thd->mem_root) Table_ident($1); + $$= new (thd->mem_root) Table_ident(&$1); if ($$ == NULL) MYSQL_YYABORT; } | ident '.' ident opt_wild { - $$= new (thd->mem_root) Table_ident(thd, $1, $3, 0); + $$= new (thd->mem_root) Table_ident(thd, &$1, &$3, 0); if ($$ == NULL) MYSQL_YYABORT; } @@ -14374,8 +14344,8 @@ table_ident_opt_wild: table_ident_nodb: ident { - LEX_STRING db={(char*) any_db,3}; - $$= new (thd->mem_root) Table_ident(thd, db, $1, 0); + LEX_CSTRING db={(char*) any_db,3}; + $$= new (thd->mem_root) Table_ident(thd, &db, &$1, 0); if ($$ == NULL) MYSQL_YYABORT; } @@ -14400,9 +14370,12 @@ IDENT_sys: } else { - if (thd->convert_with_error(system_charset_info, &$$, + LEX_STRING to; + if (thd->convert_with_error(system_charset_info, &to, thd->charset(), $1.str, $1.length)) MYSQL_YYABORT; + $$.str= to.str; + $$.length= to.length; } } ; @@ -14414,9 +14387,12 @@ TEXT_STRING_sys: $$= $1; else { - if (thd->convert_string(&$$, system_charset_info, + LEX_STRING to; + if (thd->convert_string(&to, system_charset_info, $1.str, $1.length, thd->charset())) MYSQL_YYABORT; + $$.str= to.str; + $$.length= to.length; } } ; @@ -14428,10 +14404,13 @@ TEXT_STRING_literal: $$= $1; else { - if (thd->convert_string(&$$, thd->variables.collation_connection, + LEX_STRING to; + if (thd->convert_string(&to, thd->variables.collation_connection, $1.str, $1.length, thd->charset())) MYSQL_YYABORT; - } + $$.str= to.str; + $$.length= to.length; + } } ; @@ -14442,22 +14421,45 @@ TEXT_STRING_filesystem: $$= $1; else { - if (thd->convert_string(&$$, + LEX_STRING to; + if (thd->convert_string(&to, thd->variables.character_set_filesystem, $1.str, $1.length, thd->charset())) MYSQL_YYABORT; + $$.str= to.str; + $$.length= to.length; } } ; ident: - IDENT_sys { $$=$1; } + IDENT_sys + { + (LEX_CSTRING &)$$= $1; + $$.m_pos= (char *) YYLIP->get_tok_start_prev(); + } | keyword { $$.str= thd->strmake($1.str, $1.length); if ($$.str == NULL) MYSQL_YYABORT; $$.length= $1.length; + $$.m_pos= (char *) YYLIP->get_tok_start_prev(); + } + ; + +ident_with_tok_start: + IDENT_sys + { + (LEX_CSTRING &)$$= $1; + $$.m_pos= (char *) YYLIP->get_tok_start(); + } + | keyword + { + if (!($$.str= thd->strmake($1.str, $1.length))) + MYSQL_YYABORT; + $$.length= $1.length; + $$.m_pos= (char *) YYLIP->get_tok_start(); } ; @@ -14481,10 +14483,10 @@ ident_or_text: user_maybe_role: ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) + if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) MYSQL_YYABORT; $$->user = $1; - $$->host= null_lex_str; // User or Role, see get_current_user() + $$->host= null_clex_str; // User or Role, see get_current_user() $$->reset_auth(); if (check_string_char_length(&$$->user, ER_USERNAME, @@ -14494,7 +14496,7 @@ user_maybe_role: } | ident_or_text '@' ident_or_text { - if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) + if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; $$->reset_auth(); @@ -14511,7 +14513,7 @@ user_maybe_role: It's OK to use in-place lowercase as long as the character set is utf8. */ - my_casedn_str(system_charset_info, $$->host.str); + my_casedn_str(system_charset_info, (char*) $$->host.str); } else { @@ -14527,8 +14529,8 @@ user_maybe_role: if (!($$=(LEX_USER*)thd->calloc(sizeof(LEX_USER)))) MYSQL_YYABORT; $$->user= current_user; - $$->plugin= empty_lex_str; - $$->auth= empty_lex_str; + $$->plugin= empty_clex_str; + $$->auth= empty_clex_str; } ; @@ -14545,27 +14547,23 @@ user: user_maybe_role /* Keyword that we allow for identifiers (except SP labels) */ keyword: keyword_sp {} + | keyword_sp_verb_clause{} | ASCII_SYM {} | BACKUP_SYM {} - | BEGIN_SYM {} | BINLOG_SYM {} | BYTE_SYM {} | CACHE_SYM {} | CHARSET {} | CHECKSUM_SYM {} | CHECKPOINT_SYM {} - | CLOSE_SYM {} | COLUMN_ADD_SYM {} | COLUMN_CHECK_SYM {} | COLUMN_CREATE_SYM {} | COLUMN_DELETE_SYM {} | COLUMN_GET_SYM {} | COMMENT_SYM {} - | COMMIT_SYM {} | CONTAINS_SYM {} | DEALLOCATE_SYM {} - | DO_SYM {} - | END {} | EXAMINED_SYM {} | EXCLUDE_SYM {} | EXECUTE_SYM {} @@ -14574,13 +14572,11 @@ keyword: | FOLLOWING_SYM {} | FORMAT_SYM {} | GET_SYM {} - | HANDLER_SYM {} | HELP_SYM {} | HOST_SYM {} | INSTALL_SYM {} | LANGUAGE_SYM {} | NO_SYM {} - | OPEN_SYM {} | OPTION {} | OPTIONS_SYM {} | OTHERS_SYM {} @@ -14591,14 +14587,10 @@ keyword: | PRECEDING_SYM {} | PREPARE_SYM {} | REMOVE_SYM {} - | REPAIR {} | RESET_SYM {} | RESTORE_SYM {} - | ROLLBACK_SYM {} - | SAVEPOINT_SYM {} | SECURITY_SYM {} | SERVER_SYM {} - | SHUTDOWN {} | SIGNED_SYM {} | SOCKET_SYM {} | SLAVE {} @@ -14608,7 +14600,6 @@ keyword: | STOP_SYM {} | STORED_SYM {} | TIES_SYM {} - | TRUNCATE_SYM {} | UNICODE_SYM {} | UNINSTALL_SYM {} | UNBOUNDED_SYM {} @@ -14624,6 +14615,73 @@ keyword: * conflicts. */ keyword_sp: + keyword_sp_data_type + | keyword_sp_not_data_type + ; + + +/* + Keywords that start a statement. + Generally allowed as identifiers (e.g. table, column names) + - not allowed as SP label names + - not allowed as variable names in Oracle-style assignments: + xxx:=10 +*/ +keyword_sp_verb_clause: + BEGIN_SYM { /* Compound. Reserved in Oracle */ } + | CLOSE_SYM { /* Verb clause. Reserved in Oracle */ } + | COMMIT_SYM { /* Verb clause. Reserved in Oracle */ } + | DO_SYM { /* Verb clause */ } + | END { /* Compound. Reserved in Oracle */ } + | HANDLER_SYM { /* Verb clause */ } + | OPEN_SYM { /* Verb clause. Reserved in Oracle */ } + | REPAIR { /* Verb clause */ } + | ROLLBACK_SYM { /* Verb clause. Reserved in Oracle */ } + | SAVEPOINT_SYM { /* Verb clause. Reserved in Oracle */ } + | SHUTDOWN { /* Verb clause */ } + | TRUNCATE_SYM { /* Verb clause. Reserved in Oracle */ } + ; + + +/* + These keywords are generally allowed as identifiers, + but not allowed as non-delimited SP variable names in sql_mode=ORACLE. +*/ +keyword_sp_data_type: + BIT_SYM {} + | BOOLEAN_SYM {} /* PLSQL-R */ + | BOOL_SYM {} + | CLOB {} + | DATE_SYM {} /* Oracle-R, PLSQL-R */ + | DATETIME {} + | ENUM {} + | FIXED_SYM {} + | GEOMETRYCOLLECTION {} + | GEOMETRY_SYM {} + | JSON_SYM {} + | LINESTRING {} + | MEDIUM_SYM {} + | MULTILINESTRING {} + | MULTIPOINT {} + | MULTIPOLYGON {} + | NATIONAL_SYM {} + | NCHAR_SYM {} + | NUMBER_SYM {} /* Oracle-R, PLSQL-R */ + | NVARCHAR_SYM {} + | POINT_SYM {} + | POLYGON {} + | RAW {} /* Oracle-R */ + | ROW_SYM {} + | SERIAL_SYM {} + | TEXT_SYM {} + | TIMESTAMP {} + | TIME_SYM {} /* Oracle-R */ + | VARCHAR2 {} /* Oracle-R, PLSQL-R */ + | YEAR_SYM {} + ; + + +keyword_sp_not_data_type: ACTION {} | ADDDATE_SYM {} | ADMIN_SYM {} @@ -14641,10 +14699,7 @@ keyword_sp: | AUTO_SYM {} | AVG_ROW_LENGTH {} | AVG_SYM {} - | BIT_SYM {} | BLOCK_SYM {} - | BOOL_SYM {} - | BOOLEAN_SYM {} | BTREE_SYM {} | CASCADED {} | CATALOG_NAME_SYM {} @@ -14679,11 +14734,11 @@ keyword_sp: */ | CURRENT_SYM {} | CURSOR_NAME_SYM {} + | CYCLE_SYM {} | DATA_SYM {} | DATAFILE_SYM {} - | DATETIME {} - | DATE_SYM {} | DAY_SYM {} + | DECODE_SYM {} | DEFINER_SYM {} | DELAY_KEY_WRITE_SYM {} | DES_KEY_FILE {} @@ -14695,8 +14750,8 @@ keyword_sp: | DUMPFILE {} | DUPLICATE_SYM {} | DYNAMIC_SYM {} + | ELSIF_SYM {} | ENDS_SYM {} - | ENUM {} | ENGINE_SYM {} | ENGINES_SYM {} | ERROR_SYM {} @@ -14705,6 +14760,7 @@ keyword_sp: | EVENT_SYM {} | EVENTS_SYM {} | EVERY_SYM {} + | EXCEPTION_SYM {} | EXCHANGE_SYM {} | EXPANSION_SYM {} | EXPORT_SYM {} @@ -14717,14 +14773,12 @@ keyword_sp: | FULL {} | FILE_SYM {} | FIRST_SYM {} - | FIXED_SYM {} | GENERAL {} | GENERATED_SYM {} - | GEOMETRY_SYM {} - | GEOMETRYCOLLECTION {} | GET_FORMAT {} | GRANTS {} | GLOBAL_SYM {} + | GOTO_SYM {} | HASH_SYM {} | HARD_SYM {} | HOSTS_SYM {} @@ -14732,6 +14786,7 @@ keyword_sp: | ID_SYM {} | IDENTIFIED_SYM {} | IGNORE_SERVER_IDS_SYM {} + | INCREMENT_SYM {} | IMMEDIATE_SYM {} /* SQL-2003-R */ | INVOKER_SYM {} | IMPORT {} @@ -14740,16 +14795,16 @@ keyword_sp: | IO_SYM {} | IPC_SYM {} | ISOLATION {} + | ISOPEN_SYM {} | ISSUER_SYM {} - | JSON_SYM {} | INSERT_METHOD {} | KEY_BLOCK_SIZE {} | LAST_VALUE {} | LAST_SYM {} + | LASTVAL_SYM {} | LEAVES {} | LESS_SYM {} | LEVEL_SYM {} - | LINESTRING {} | LIST_SYM {} | LOCAL_SYM {} | LOCKS_SYM {} @@ -14783,34 +14838,34 @@ keyword_sp: | MAX_STATEMENT_TIME_SYM {} | MAX_UPDATES_PER_HOUR {} | MAX_USER_CONNECTIONS_SYM {} - | MEDIUM_SYM {} | MEMORY_SYM {} | MERGE_SYM {} | MESSAGE_TEXT_SYM {} | MICROSECOND_SYM {} | MIGRATE_SYM {} | MINUTE_SYM {} + | MINVALUE_SYM {} | MIN_ROWS {} | MODIFY_SYM {} | MODE_SYM {} | MONTH_SYM {} - | MULTILINESTRING {} - | MULTIPOINT {} - | MULTIPOLYGON {} | MUTEX_SYM {} | MYSQL_SYM {} | MYSQL_ERRNO_SYM {} | NAME_SYM {} | NAMES_SYM {} - | NATIONAL_SYM {} - | NCHAR_SYM {} | NEXT_SYM {} + | NEXTVAL_SYM {} | NEW_SYM {} + | NOCACHE_SYM {} + | NOCYCLE_SYM {} + | NOMINVALUE_SYM {} + | NOMAXVALUE_SYM {} | NO_WAIT_SYM {} | NODEGROUP_SYM {} | NONE_SYM {} - | NUMBER_SYM {} - | NVARCHAR_SYM {} + | NOTFOUND_SYM {} + | OF_SYM {} /* SQL-1999-R, Oracle-R */ | OFFSET_SYM {} | OLD_PASSWORD_SYM {} | ONE_SYM {} @@ -14826,10 +14881,9 @@ keyword_sp: | PHASE_SYM {} | PLUGIN_SYM {} | PLUGINS_SYM {} - | POINT_SYM {} - | POLYGON {} | PRESERVE_SYM {} | PREV_SYM {} + | PREVIOUS_SYM {} | PRIVILEGES {} | PROCESS {} | PROCESSLIST_SYM {} @@ -14839,6 +14893,7 @@ keyword_sp: | QUARTER_SYM {} | QUERY_SYM {} | QUICK {} + | RAISE_SYM {} | READ_ONLY_SYM {} | REBUILD_SYM {} | RECOVER_SYM {} @@ -14855,23 +14910,27 @@ keyword_sp: | REPEATABLE_SYM {} | REPLICATION {} | RESOURCES {} + | RESTART_SYM {} | RESUME_SYM {} | RETURNED_SQLSTATE_SYM {} | RETURNS_SYM {} + | REUSE_SYM {} /* Oracle-R */ | REVERSE_SYM {} | ROLE_SYM {} | ROLLUP_SYM {} | ROUTINE_SYM {} + | ROWCOUNT_SYM {} + | ROWTYPE_SYM {} | ROW_COUNT_SYM {} | ROW_FORMAT_SYM {} - | ROW_SYM {} | RTREE_SYM {} | SCHEDULE_SYM {} | SCHEMA_NAME_SYM {} | SECOND_SYM {} - | SERIAL_SYM {} + | SEQUENCE_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} + | SETVAL_SYM {} | SIMPLE_SYM {} | SHARE_SYM {} | SLAVE_POS_SYM {} @@ -14904,15 +14963,12 @@ keyword_sp: | TABLESPACE {} | TEMPORARY {} | TEMPTABLE_SYM {} - | TEXT_SYM {} | THAN_SYM {} | TRANSACTION_SYM {} | TRANSACTIONAL_SYM {} | TRIGGERS_SYM {} - | TIMESTAMP {} | TIMESTAMP_ADD {} | TIMESTAMP_DIFF {} - | TIME_SYM {} | TYPES_SYM {} | TYPE_SYM {} | UDF_RETURNS_SYM {} @@ -14936,8 +14992,7 @@ keyword_sp: | WORK_SYM {} | X509_SYM {} | XML_SYM {} - | YEAR_SYM {} - | VIA_SYM {} + | VIA_SYM {} ; /* @@ -14951,22 +15006,15 @@ set: SET { LEX *lex=Lex; - lex->sql_command= SQLCOM_SET_OPTION; - mysql_init_select(lex); - lex->option_type=OPT_SESSION; + lex->set_stmt_init(); lex->var_list.empty(); - lex->autocommit= 0; sp_create_assignment_lex(thd, yychar == YYEMPTY); } start_option_value_list {} | SET STATEMENT_SYM { - LEX *lex= Lex; - mysql_init_select(lex); - lex->option_type= OPT_SESSION; - lex->sql_command= SQLCOM_SET_OPTION; - lex->autocommit= 0; + Lex->set_stmt_init(); } set_stmt_option_value_following_option_type_list { @@ -15096,7 +15144,7 @@ option_value_following_option_type: if ($1.var && $1.var != trg_new_row_fake_var) { /* It is a system variable. */ - if (set_system_variable(thd, &$1, lex->option_type, $3)) + if (lex->set_system_variable(&$1, lex->option_type, $3)) MYSQL_YYABORT; } else @@ -15105,7 +15153,7 @@ option_value_following_option_type: Not in trigger assigning value to new row, and option_type preceding local variable is illegal. */ - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } } @@ -15113,36 +15161,30 @@ option_value_following_option_type: /* Option values without preceding option_type. */ option_value_no_option_type: - internal_variable_name equal set_expr_or_default + ident equal set_expr_or_default { - LEX *lex= Lex; - - if ($1.var == trg_new_row_fake_var) - { - /* We are in trigger and assigning value to field of new row */ - if (set_trigger_new_row(thd, &$1.base_name, $3)) - MYSQL_YYABORT; - } - else if ($1.var) - { - /* It is a system variable. */ - if (set_system_variable(thd, &$1, lex->option_type, $3)) - MYSQL_YYABORT; - } - else - { - sp_pcontext *spc= lex->spcont; - sp_variable *spv= spc->find_variable($1.base_name, false); - - /* It is a local variable. */ - if (set_local_variable(thd, spv, $3)) - MYSQL_YYABORT; - } + struct sys_var_with_base var; + if (Lex->init_internal_variable(&var, &$1) || + Lex->set_variable(&var, $3)) + MYSQL_YYABORT; + } + | ident '.' ident equal set_expr_or_default + { + DBUG_ASSERT(Lex->var_list.is_empty()); + if (Lex->set_variable(&$1, &$3, $5)) + MYSQL_YYABORT; + } + | DEFAULT '.' ident equal set_expr_or_default + { + struct sys_var_with_base var; + if (Lex->init_default_internal_variable(&var, $3) || + Lex->set_variable(&var, $5)) + MYSQL_YYABORT; } | '@' ident_or_text equal expr { Item_func_set_user_var *item; - item= new (thd->mem_root) Item_func_set_user_var(thd, $2, $4); + item= new (thd->mem_root) Item_func_set_user_var(thd, &$2, $4); if (item == NULL) MYSQL_YYABORT; set_var_user *var= new (thd->mem_root) set_var_user(item); @@ -15159,7 +15201,7 @@ option_value_no_option_type: if (find_sys_var_null_base(thd, &tmp)) MYSQL_YYABORT; } - if (set_system_variable(thd, &tmp, $3, $6)) + if (Lex->set_system_variable(&tmp, $3, $6)) MYSQL_YYABORT; } | charset old_or_new_charset_name_or_default @@ -15180,15 +15222,11 @@ option_value_no_option_type: { LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - LEX_STRING names; - - names.str= (char *)"names"; - names.length= 5; - if (spc && spc->find_variable(names, false)) + LEX_CSTRING names= { STRING_WITH_LEN("names") }; + if (spc && spc->find_variable(&names, false)) my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); else - my_parse_error(thd, ER_SYNTAX_ERROR); - + thd->parse_error(); MYSQL_YYABORT; } | NAMES_SYM charset_name_or_default opt_collate @@ -15265,77 +15303,18 @@ option_value_no_option_type: internal_variable_name: ident { - sp_pcontext *spc= thd->lex->spcont; - sp_variable *spv; - - /* Best effort lookup for system variable. */ - if (!spc || !(spv = spc->find_variable($1, false))) - { - struct sys_var_with_base tmp= {NULL, $1}; - - /* Not an SP local variable */ - if (find_sys_var_null_base(thd, &tmp)) - MYSQL_YYABORT; - - $$= tmp; - } - else - { - /* - Possibly an SP local variable (or a shadowed sysvar). - Will depend on the context of the SET statement. - */ - $$.var= NULL; - $$.base_name= $1; - } + if (Lex->init_internal_variable(&$$, &$1)) + MYSQL_YYABORT; } | ident '.' ident { - LEX *lex= Lex; - if (check_reserved_words(&$1)) - { - my_parse_error(thd, ER_SYNTAX_ERROR); + if (Lex->init_internal_variable(&$$, &$1, &$3)) MYSQL_YYABORT; - } - if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && - (!my_strcasecmp(system_charset_info, $1.str, "NEW") || - !my_strcasecmp(system_charset_info, $1.str, "OLD"))) - { - if ($1.str[0]=='O' || $1.str[0]=='o') - my_yyabort_error((ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", "")); - if (lex->trg_chistics.event == TRG_EVENT_DELETE) - { - my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), - "NEW", "on DELETE"); - MYSQL_YYABORT; - } - if (lex->trg_chistics.action_time == TRG_ACTION_AFTER) - my_yyabort_error((ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after ")); - /* This special combination will denote field of NEW row */ - $$.var= trg_new_row_fake_var; - $$.base_name= $3; - } - else - { - sys_var *tmp=find_sys_var(thd, $3.str, $3.length); - if (!tmp) - MYSQL_YYABORT; - if (!tmp->is_struct()) - my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); - $$.var= tmp; - $$.base_name= $1; - } } | DEFAULT '.' ident { - sys_var *tmp=find_sys_var(thd, $3.str, $3.length); - if (!tmp) + if (Lex->init_default_internal_variable(&$$, $3)) MYSQL_YYABORT; - if (!tmp->is_struct()) - my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); - $$.var= tmp; - $$.base_name.str= (char*) "default"; - $$.base_name.length= 7; } ; @@ -15356,7 +15335,7 @@ transaction_access_mode: set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_read_only"), - &null_lex_str, + &null_clex_str, item)); if (var == NULL) MYSQL_YYABORT; @@ -15374,7 +15353,7 @@ isolation_level: set_var *var= (new (thd->mem_root) set_var(thd, lex->option_type, find_sys_var(thd, "tx_isolation"), - &null_lex_str, + &null_clex_str, item)); if (var == NULL) MYSQL_YYABORT; @@ -15399,15 +15378,15 @@ opt_for_user: { LEX *lex= thd->lex; sp_pcontext *spc= lex->spcont; - LEX_STRING pw= { C_STRING_WITH_LEN("password") }; + LEX_CSTRING pw= { STRING_WITH_LEN("password") }; - if (spc && spc->find_variable(pw, false)) + if (spc && spc->find_variable(&pw, false)) my_yyabort_error((ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str)); if (!(lex->definer= (LEX_USER*) thd->calloc(sizeof(LEX_USER)))) MYSQL_YYABORT; lex->definer->user= current_user; - lex->definer->plugin= empty_lex_str; - lex->definer->auth= empty_lex_str; + lex->definer->plugin= empty_clex_str; + lex->definer->auth= empty_clex_str; } | FOR_SYM user equal { Lex->definer= $2; } ; @@ -15566,7 +15545,7 @@ handler: ; handler_read_or_scan: - handler_scan_function { Lex->ident= null_lex_str; } + handler_scan_function { Lex->ident= null_clex_str; } | ident handler_rkey_function { Lex->ident= $1; } ; @@ -15619,7 +15598,7 @@ revoke_command: LEX *lex= Lex; if (lex->columns.elements) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } lex->sql_command= SQLCOM_REVOKE; @@ -15630,7 +15609,7 @@ revoke_command: LEX *lex= Lex; if (lex->columns.elements) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } lex->sql_command= SQLCOM_REVOKE; @@ -15681,7 +15660,7 @@ grant_command: LEX *lex= Lex; if (lex->columns.elements) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } lex->sql_command= SQLCOM_GRANT; @@ -15693,7 +15672,7 @@ grant_command: LEX *lex= Lex; if (lex->columns.elements) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } lex->sql_command= SQLCOM_GRANT; @@ -15754,13 +15733,13 @@ grant_role: CHARSET_INFO *cs= system_charset_info; /* trim end spaces (as they'll be lost in mysql.user anyway) */ $1.length= cs->cset->lengthsp(cs, $1.str, $1.length); - $1.str[$1.length] = '\0'; + ((char*) $1.str)[$1.length] = '\0'; if ($1.length == 0) my_yyabort_error((ER_INVALID_ROLE, MYF(0), "")); - if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) + if (!($$=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) MYSQL_YYABORT; - $$->user = $1; - $$->host= empty_lex_str; + $$->user= $1; + $$->host= empty_clex_str; $$->reset_auth(); if (check_string_char_length(&$$->user, ER_USERNAME, @@ -15970,7 +15949,7 @@ grant_user: { $$= $1; $1->plugin= $4; - $1->auth= empty_lex_str; + $1->auth= empty_clex_str; } | user IDENTIFIED_SYM via_or_with ident_or_text using_or_as TEXT_STRING_sys { @@ -16152,11 +16131,6 @@ opt_release: | NO_SYM RELEASE_SYM { $$= TVL_NO; } ; -opt_savepoint: - /* empty */ {} - | SAVEPOINT_SYM {} - ; - commit: COMMIT_SYM opt_work opt_chain opt_release { @@ -16179,13 +16153,18 @@ rollback: lex->tx_chain= $3; lex->tx_release= $4; } - | ROLLBACK_SYM opt_work - TO_SYM opt_savepoint ident + | ROLLBACK_SYM opt_work TO_SYM SAVEPOINT_SYM ident { LEX *lex=Lex; lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT; lex->ident= $5; } + | ROLLBACK_SYM opt_work TO_SYM ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT; + lex->ident= $4; + } ; savepoint: @@ -16210,6 +16189,14 @@ release: UNIONS : glue selects together */ +unit_type_decl: + UNION_SYM + { $$= UNION_TYPE; } + | INTERSECT_SYM + { $$= INTERSECT_TYPE; } + | EXCEPT_SYM + { $$= EXCEPT_TYPE; } + union_clause: /* empty */ {} @@ -16217,9 +16204,9 @@ union_clause: ; union_list: - UNION_SYM union_option + unit_type_decl union_option { - if (add_select_to_union_list(Lex, (bool)$2, TRUE)) + if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) MYSQL_YYABORT; } union_list_part2 @@ -16233,9 +16220,9 @@ union_list: ; union_list_view: - UNION_SYM union_option + unit_type_decl union_option { - if (add_select_to_union_list(Lex, (bool)$2, TRUE)) + if (Lex->add_select_to_union_list((bool)$2, $1, TRUE)) MYSQL_YYABORT; } query_expression_body_view @@ -16274,9 +16261,9 @@ order_or_limit: Start a UNION, for non-top level query expressions. */ union_head_non_top: - UNION_SYM union_option + unit_type_decl union_option { - if (add_select_to_union_list(Lex, (bool)$2, FALSE)) + if (Lex->add_select_to_union_list((bool)$2, $1, FALSE)) MYSQL_YYABORT; } ; @@ -16334,7 +16321,7 @@ subselect_start: if (!lex->expr_allows_subselect || lex->sql_command == (int)SQLCOM_PURGE) { - my_parse_error(thd, ER_SYNTAX_ERROR); + thd->parse_error(); MYSQL_YYABORT; } /* @@ -16344,7 +16331,7 @@ subselect_start: (SELECT .. ) UNION ... becomes SELECT * FROM ((SELECT ...) UNION ...) */ - if (mysql_new_select(Lex, 1)) + if (mysql_new_select(Lex, 1, NULL)) MYSQL_YYABORT; } ; @@ -16353,6 +16340,7 @@ subselect_end: { LEX *lex=Lex; + lex->check_automatic_up(UNSPECIFIED_TYPE); lex->pop_context(); SELECT_LEX *child= lex->current_select; lex->current_select = lex->current_select->return_after_parsing(); @@ -16414,38 +16402,6 @@ query_expression_option: /************************************************************************** - CREATE VIEW | TRIGGER | PROCEDURE statements. - -**************************************************************************/ - -view_or_trigger_or_sp_or_event: - definer definer_tail - {} - | no_definer no_definer_tail - {} - | view_algorithm definer_opt view_tail - {} - ; - -definer_tail: - view_tail - | trigger_tail - | sp_tail - | sf_tail - | event_tail - ; - -no_definer_tail: - view_tail - | trigger_tail - | sp_tail - | sf_tail - | udf_tail - | event_tail - ; - -/************************************************************************** - DEFINER clause support. **************************************************************************/ @@ -16486,39 +16442,19 @@ definer: **************************************************************************/ view_algorithm: - ALGORITHM_SYM '=' UNDEFINED_SYM - { Lex->create_view_algorithm= DTYPE_ALGORITHM_UNDEFINED; } - | ALGORITHM_SYM '=' MERGE_SYM - { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; } - | ALGORITHM_SYM '=' TEMPTABLE_SYM - { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } + ALGORITHM_SYM '=' UNDEFINED_SYM { $$= DTYPE_ALGORITHM_UNDEFINED; } + | ALGORITHM_SYM '=' MERGE_SYM { $$= VIEW_ALGORITHM_MERGE; } + | ALGORITHM_SYM '=' TEMPTABLE_SYM { $$= VIEW_ALGORITHM_TMPTABLE; } ; -view_suid: - /* empty */ - { Lex->create_view_suid= VIEW_SUID_DEFAULT; } - | SQL_SYM SECURITY_SYM DEFINER_SYM - { Lex->create_view_suid= VIEW_SUID_DEFINER; } - | SQL_SYM SECURITY_SYM INVOKER_SYM - { Lex->create_view_suid= VIEW_SUID_INVOKER; } +opt_view_suid: + /* empty */ { $$= VIEW_SUID_DEFAULT; } + | view_suid { $$= $1; } ; -view_tail: - view_suid VIEW_SYM opt_if_not_exists table_ident - { - LEX *lex= thd->lex; - if (lex->add_create_options_with_check($3)) - MYSQL_YYABORT; - lex->sql_command= SQLCOM_CREATE_VIEW; - /* first table in list is target VIEW name */ - if (!lex->select_lex.add_table_to_list(thd, $4, NULL, - TL_OPTION_UPDATING, - TL_IGNORE, - MDL_EXCLUSIVE)) - MYSQL_YYABORT; - lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB; - } - view_list_opt AS view_select +view_suid: + SQL_SYM SECURITY_SYM DEFINER_SYM { $$= VIEW_SUID_DEFINER; } + | SQL_SYM SECURITY_SYM INVOKER_SYM { $$= VIEW_SUID_INVOKER; } ; view_list_opt: @@ -16546,18 +16482,20 @@ view_select: { LEX *lex= Lex; lex->parsing_options.allows_variable= FALSE; - lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr(); + lex->create_view->select.str= (char *) YYLIP->get_cpp_ptr(); } opt_with_clause query_expression_body_view view_check_option { LEX *lex= Lex; - uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str; + uint len= YYLIP->get_cpp_ptr() - lex->create_view->select.str; uint not_used; - void *create_view_select= thd->memdup(lex->create_view_select.str, len); - lex->create_view_select.length= len; - lex->create_view_select.str= (char *) create_view_select; - trim_whitespace(thd->charset(), &lex->create_view_select, + void *create_view_select= thd->memdup(lex->create_view->select.str, len); + lex->create_view->select.length= len; + lex->create_view->select.str= (char *) create_view_select; + trim_whitespace(thd->charset(), + &lex->create_view->select, ¬_used); + lex->create_view->check= $4; lex->parsing_options.allows_variable= TRUE; lex->current_select->set_with_clause($2); } @@ -16575,14 +16513,10 @@ query_expression_body_view: ; view_check_option: - /* empty */ - { Lex->create_view_check= VIEW_CHECK_NONE; } - | WITH CHECK_SYM OPTION - { Lex->create_view_check= VIEW_CHECK_CASCADED; } - | WITH CASCADED CHECK_SYM OPTION - { Lex->create_view_check= VIEW_CHECK_CASCADED; } - | WITH LOCAL_SYM CHECK_SYM OPTION - { Lex->create_view_check= VIEW_CHECK_LOCAL; } + /* empty */ { $$= VIEW_CHECK_NONE; } + | WITH CHECK_SYM OPTION { $$= VIEW_CHECK_CASCADED; } + | WITH CASCADED CHECK_SYM OPTION { $$= VIEW_CHECK_CASCADED; } + | WITH LOCAL_SYM CHECK_SYM OPTION { $$= VIEW_CHECK_LOCAL; } ; /************************************************************************** @@ -16614,25 +16548,24 @@ trigger_follows_precedes_clause: ; trigger_tail: - TRIGGER_SYM remember_name opt_if_not_exists { - if (Lex->add_create_options_with_check($3)) + if (Lex->add_create_options_with_check($2)) MYSQL_YYABORT; } sp_name trg_action_time trg_event ON - remember_name /* $9 */ - { /* $10 */ + remember_name /* $8 */ + { /* $9 */ Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start(); } - table_ident /* $11 */ + table_ident /* $10 */ FOR_SYM - remember_name /* $13 */ - { /* $14 */ + remember_name /* $12 */ + { /* $13 */ Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start(); } EACH_SYM @@ -16640,28 +16573,28 @@ trigger_tail: { Lex->trg_chistics.ordering_clause_begin= YYLIP->get_cpp_ptr(); } - trigger_follows_precedes_clause /* $18 */ - { /* $19 */ + trigger_follows_precedes_clause /* $17 */ + { /* $18 */ LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; if (lex->sphead) my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER")); - lex->stmt_definition_begin= $2; - lex->ident.str= $9; - lex->ident.length= $13 - $9; - lex->spname= $5; - (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($18); + lex->stmt_definition_begin= $1; + lex->ident.str= $8; + lex->ident.length= $12 - $8; + lex->spname= $4; + (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($17); lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr(); - if (!make_sp_head(thd, $5, TYPE_ENUM_TRIGGER)) + if (!lex->make_sp_head(thd, $4, TYPE_ENUM_TRIGGER)) MYSQL_YYABORT; lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt /* $20 */ - { /* $21 */ + sp_proc_stmt /* $19 */ + { /* $20 */ LEX *lex= Lex; sp_head *sp= lex->sphead; @@ -16677,8 +16610,8 @@ trigger_tail: sp_proc_stmt alternatives are not saving/restoring LEX, so lex->query_tables can be wiped out. */ - if (!lex->select_lex.add_table_to_list(thd, $11, - (LEX_STRING*) 0, + if (!lex->select_lex.add_table_to_list(thd, $10, + (LEX_CSTRING*) 0, TL_OPTION_UPDATING, TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) @@ -16693,74 +16626,56 @@ trigger_tail: **************************************************************************/ udf_tail: - AGGREGATE_SYM udf_tail2 { thd->lex->udf.type= UDFTYPE_AGGREGATE; } - | udf_tail2 { thd->lex->udf.type= UDFTYPE_FUNCTION; } - ; - -udf_tail2: - FUNCTION_SYM opt_if_not_exists ident + opt_if_not_exists ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys { LEX *lex= thd->lex; - if (lex->add_create_options_with_check($2)) + if (lex->add_create_options_with_check($1)) MYSQL_YYABORT; - if (is_native_function(thd, & $3)) - my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $3.str)); + if (is_native_function(thd, & $2)) + my_yyabort_error((ER_NATIVE_FCT_NAME_COLLISION, MYF(0), $2.str)); lex->sql_command= SQLCOM_CREATE_FUNCTION; - lex->udf.name= $3; - lex->udf.returns= (Item_result) $5; - lex->udf.dl= $7.str; + lex->udf.name= $2; + lex->udf.returns= (Item_result) $4; + lex->udf.dl= $6.str; } ; -sf_tail: - FUNCTION_SYM /* $1 */ - opt_if_not_exists /* $2 */ - sp_name /* $3 */ - '(' /* $4 */ - { /* $5 */ - LEX *lex= Lex; - Lex_input_stream *lip= YYLIP; - const char* tmp_param_begin; - - if (lex->add_create_options_with_check($2)) - MYSQL_YYABORT; - lex->spname= $3; - - if (lex->sphead) - my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION")); - if (!make_sp_head(thd, $3, TYPE_ENUM_FUNCTION)) - MYSQL_YYABORT; - - tmp_param_begin= lip->get_cpp_tok_start(); - tmp_param_begin++; - lex->sphead->m_param_begin= tmp_param_begin; - } - sp_fdparam_list /* $6 */ - ')' /* $7 */ - { /* $8 */ - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); - } - RETURNS_SYM /* $9 */ - { /* $10 */ +sf_return_type: + RETURNS_SYM + { LEX *lex= Lex; - lex->init_last_field(&lex->sphead->m_return_field_def, NULL, + lex->init_last_field(&lex->sphead->m_return_field_def, + &empty_clex_str, thd->variables.collation_database); } - type_with_opt_collate /* $11 */ - { /* $12 */ - if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field)) + type_with_opt_collate + { + if (Lex->sphead->fill_field_definition(thd, Lex->last_field)) + MYSQL_YYABORT; + } + ; + +sf_tail: + opt_if_not_exists + sp_name + { + if (!Lex->make_sp_head_no_recursive(thd, $1, $2, + TYPE_ENUM_FUNCTION)) MYSQL_YYABORT; } - sp_c_chistics /* $13 */ - { /* $14 */ + sp_parenthesized_fdparam_list + sf_return_type + sp_c_chistics + { LEX *lex= thd->lex; Lex_input_stream *lip= YYLIP; + lex->sphead->set_chistics(lex->sp_chistics); lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt_in_returns_clause /* $15 */ + sp_proc_stmt_in_returns_clause { LEX *lex= thd->lex; sp_head *sp= lex->sphead; @@ -16771,74 +16686,24 @@ sf_tail: lex->sql_command= SQLCOM_CREATE_SPFUNCTION; sp->set_stmt_end(thd); if (!(sp->m_flags & sp_head::HAS_RETURN)) - my_yyabort_error((ER_SP_NORETURN, MYF(0), sp->m_qname.str)); - if (is_native_function(thd, & sp->m_name)) - { - /* - This warning will be printed when - [1] A client query is parsed, - [2] A stored function is loaded by db_load_routine. - Printing the warning for [2] is intentional, to cover the - following scenario: - - A user define a SF 'foo' using MySQL 5.N - - An application uses select foo(), and works. - - MySQL 5.{N+1} defines a new native function 'foo', as - part of a new feature. - - MySQL 5.{N+1} documentation is updated, and should mention - that there is a potential incompatible change in case of - existing stored function named 'foo'. - - The user deploys 5.{N+1}. At this point, 'select foo()' - means something different, and the user code is most likely - broken (it's only safe if the code is 'select db.foo()'). - With a warning printed when the SF is loaded (which has to - occur before the call), the warning will provide a hint - explaining the root cause of a later failure of 'select foo()'. - With no warning printed, the user code will fail with no - apparent reason. - Printing a warning each time db_load_routine is executed for - an ambiguous function is annoying, since that can happen a lot, - but in practice should not happen unless there *are* name - collisions. - If a collision exists, it should not be silenced but fixed. - */ - push_warning_printf(thd, - Sql_condition::WARN_LEVEL_NOTE, - ER_NATIVE_FCT_NAME_COLLISION, - ER_THD(thd, ER_NATIVE_FCT_NAME_COLLISION), - sp->m_name.str); - } + my_yyabort_error((ER_SP_NORETURN, MYF(0), + ErrConvDQName(sp).ptr())); + (void) is_native_function_with_warn(thd, &sp->m_name); sp->restore_thd_mem_root(thd); } ; sp_tail: - PROCEDURE_SYM opt_if_not_exists sp_name + opt_if_not_exists sp_name { - if (Lex->add_create_options_with_check($2)) - MYSQL_YYABORT; - - if (Lex->sphead) - my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE")); - - if (!make_sp_head(thd, $3, TYPE_ENUM_PROCEDURE)) + if (!Lex->make_sp_head_no_recursive(thd, $1, $2, + TYPE_ENUM_PROCEDURE)) MYSQL_YYABORT; - Lex->spname= $3; - } - '(' - { - const char* tmp_param_begin; - - tmp_param_begin= YYLIP->get_cpp_tok_start(); - tmp_param_begin++; - Lex->sphead->m_param_begin= tmp_param_begin; - } - sp_pdparam_list - ')' - { - Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start(); } + sp_parenthesized_pdparam_list sp_c_chistics { + Lex->sphead->set_chistics(Lex->sp_chistics); Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start()); } sp_proc_stmt @@ -16946,7 +16811,7 @@ install: { LEX *lex= Lex; lex->sql_command= SQLCOM_INSTALL_PLUGIN; - lex->comment= null_lex_str; + lex->comment= null_clex_str; lex->ident= $3; } ; @@ -16962,7 +16827,7 @@ uninstall: { LEX *lex= Lex; lex->sql_command= SQLCOM_UNINSTALL_PLUGIN; - lex->comment= null_lex_str; + lex->comment= null_clex_str; lex->ident= $3; } ; |