diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 737 |
1 files changed, 405 insertions, 332 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 24dc3c44b0f..1870b3f719f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -54,6 +54,7 @@ #include "sql_handler.h" // Sql_cmd_handler_* #include "sql_signal.h" #include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics +#include "sql_cte.h" #include "event_parse_data.h" #include "create_options.h" #include <myisam.h> @@ -346,7 +347,7 @@ int case_stmt_action_when(LEX *lex, Item *when, bool simple) */ return !MY_TEST(i) || - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) || + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i); } @@ -380,7 +381,7 @@ int case_stmt_action_then(LEX *lex) (jump from instruction 4 to 12, 7 to 12 ... in the example) */ - return sp->push_backpatch(i, ctx->last_label()); + return sp->push_backpatch(lex->thd, i, ctx->last_label()); } static bool @@ -464,7 +465,8 @@ set_local_variable(THD *thd, sp_variable *spv, Item *val) sp_set= new (thd->mem_root) sp_instr_set(lex->sphead->instructions(), lex->spcont, - spv->offset, it, spv->type, lex, TRUE); + spv->offset, it, spv->sql_type(), + lex, TRUE); return (sp_set == NULL || lex->sphead->add_instr(sp_set)); } @@ -563,7 +565,8 @@ create_item_for_sp_var(THD *thd, LEX_STRING name, sp_variable *spvar, len_in_q= end_in_q - start_in_q; item= new (thd->mem_root) - Item_splocal(thd, name, spvar->offset, spvar->type, pos_in_q, len_in_q); + Item_splocal(thd, name, spvar->offset, spvar->sql_type(), + pos_in_q, len_in_q); #ifndef DBUG_OFF if (item) @@ -882,7 +885,7 @@ static void add_key_to_list(LEX *lex, LEX_STRING *field_name, lex->alter_info.key_list.push_back(key, mem_root); } -void LEX::init_last_field(Create_field *field, const char *field_name, +void LEX::init_last_field(Column_definition *field, const char *field_name, CHARSET_INFO *cs) { last_field= field; @@ -890,28 +893,25 @@ void LEX::init_last_field(Create_field *field, const char *field_name, field->field_name= field_name; /* reset LEX fields that are used in Create_field::set_and_check() */ - length= 0; - dec= 0; charset= cs; } -void LEX::set_last_field_type(enum enum_field_types field_type) +void LEX::set_last_field_type(const Lex_field_type_st &type) { - last_field->sql_type= field_type; - last_field->create_if_not_exists= check_exists; + last_field->sql_type= type.field_type(); last_field->charset= charset; - if (length) + if (type.length()) { int err; - last_field->length= my_strtoll10(length, NULL, &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= dec ? (uint)atoi(dec) : 0; + last_field->decimals= type.dec() ? (uint)atoi(type.dec()) : 0; } bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) @@ -953,8 +953,13 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) LEX_SYMBOL symbol; struct sys_var_with_base variable; struct { int vars, conds, hndlrs, curs; } spblock; + 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; /* pointers */ + Create_field *create_field; CHARSET_INFO *charset; Condition_information_item *cond_info_item; DYNCALL_CREATE_DEF *dyncol_def; @@ -976,6 +981,7 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) TABLE_LIST *table_list; Table_ident *table; char *simple_string; + const char *const_simple_string; chooser_compare_func_creator boolfunc2creator; class my_var *myvar; class sp_condition_value *spcondvalue; @@ -983,13 +989,14 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin) class sp_label *splabel; class sp_name *spname; class sp_variable *spvar; + class With_clause *with_clause; + handlerton *db_type; st_select_lex *select_lex; struct p_elem_val *p_elem_value; udf_func *udf; /* enums */ - enum Cast_target cast_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; @@ -1023,10 +1030,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %parse-param { THD *thd } %lex-param { THD *thd } /* - Currently there are 160 shift/reduce conflicts. + Currently there are 121 shift/reduce conflicts. We should not introduce new conflicts any more. */ -%expect 162 +%expect 121 /* Comments for TOKENS. @@ -1481,6 +1488,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token REAL /* SQL-2003-R */ %token REBUILD_SYM %token RECOVER_SYM +%token RECURSIVE_SYM %token REDOFILE_SYM %token REDO_BUFFER_SIZE_SYM %token REDUNDANT_SYM @@ -1730,11 +1738,22 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <simple_string> remember_name remember_end opt_db remember_tok_start wild_and_where + field_length opt_field_length opt_field_length_default_1 + +%type <const_simple_string> + opt_place %type <string> text_string hex_or_bin_String opt_gconcat_separator -%type <field_type> type_with_opt_collate int_type real_type field_type +%type <field_type> int_type real_type + +%type <Lex_field_type> type_with_opt_collate field_type + +%type <Lex_dyncol_type> opt_dyncol_type dyncol_type + numeric_dyncol_type temporal_dyncol_type string_dyncol_type + +%type <create_field> field_spec column_def %type <geom_type> spatial_type @@ -1748,12 +1767,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_natural_language_mode opt_query_expansion opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt - optional_flush_tables_arguments opt_dyncol_type dyncol_type + optional_flush_tables_arguments opt_time_precision kill_type kill_option int_num opt_default_time_precision case_stmt_body opt_bin_mod opt_if_exists_table_element opt_if_not_exists_table_element opt_into opt_procedure_clause + opt_recursive %type <object_ddl_options> create_or_replace @@ -1852,7 +1872,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type <ha_rkey_mode> handler_rkey_mode -%type <cast_type> cast_type +%type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal + +%type <Lex_length_and_dec> precision opt_precision float_options %type <symbol> keyword keyword_sp @@ -1898,7 +1920,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); persistent_column_stat_spec persistent_index_stat_spec table_column_list table_index_list table_index_name check start checksum - field_list field_list_item field_spec kill column_def key_def + field_list field_list_item kill key_def keycache_list keycache_list_or_parts assign_to_keycache assign_to_keycache_parts preload_list preload_list_or_parts preload_keys preload_keys_parts @@ -1906,13 +1928,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_limit_clause delete_limit_clause fields opt_values values procedure_list procedure_list2 procedure_item field_def handler opt_generated_always - opt_precision opt_ignore opt_column opt_restrict + opt_ignore opt_column opt_restrict grant revoke set lock unlock string_list field_options field_option field_opt_list opt_binary table_lock_list table_lock ref_list opt_match_clause opt_on_update_delete use opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name table_alias_ref_list table_alias_ref - opt_place opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges grant_ident grant_list grant_option object_privilege object_privilege_list user_list user_and_role_list @@ -1925,9 +1946,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild union_clause union_list - precision subselect_start opt_and charset + subselect_start opt_and charset subselect_end select_var_list select_var_list_init help - field_length opt_field_length opt_extended_describe shutdown opt_format_json prepare prepare_src execute deallocate @@ -1955,6 +1975,7 @@ END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return + sp_proc_stmt_in_returns_clause %type <NONE> sp_proc_stmt_compound_ok %type <NONE> sp_proc_stmt_if %type <NONE> sp_labeled_control sp_unlabeled_control @@ -1995,6 +2016,10 @@ END_OF_INPUT THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM ROLE_SYM +%type <with_clause> opt_with_clause with_clause + +%type <lex_str_ptr> query_name + %% @@ -2559,6 +2584,7 @@ create: } view_or_trigger_or_sp_or_event { } | create_or_replace USER opt_if_not_exists clear_privileges grant_list + opt_require_clause opt_resource_options { if (Lex->set_command_with_check(SQLCOM_CREATE_USER, $1 | $3)) MYSQL_YYABORT; @@ -2958,9 +2984,7 @@ sp_param_name_and_type: LEX *lex= Lex; sp_variable *spvar= $<spvar>2; - spvar->type= $3; - if (lex->sphead->fill_field_definition(thd, lex, $3, - lex->last_field)) + if (lex->sphead->fill_field_definition(thd, lex, lex->last_field)) { MYSQL_YYABORT; } @@ -3055,7 +3079,6 @@ sp_decl: LEX *lex= Lex; sp_pcontext *pctx= lex->spcont; uint num_vars= pctx->context_var_count(); - enum enum_field_types var_type= $4; Item *dflt_value_item= $5; if (!dflt_value_item) @@ -3078,11 +3101,10 @@ sp_decl: if (!last) spvar->field_def= *lex->last_field; - spvar->type= var_type; spvar->default_value= dflt_value_item; spvar->field_def.field_name= spvar->name.str; - if (lex->sphead->fill_field_definition(thd, lex, var_type, + if (lex->sphead->fill_field_definition(thd, lex, &spvar->field_def)) { MYSQL_YYABORT; @@ -3097,7 +3119,7 @@ sp_decl: pctx, var_idx, dflt_value_item, - var_type, + $4.field_type(), lex, last)); if (is == NULL || @@ -3147,10 +3169,10 @@ sp_decl: /* For continue handlers, mark end of handler scope. */ if ($2 == sp_handler::CONTINUE && - sp->push_backpatch(i, ctx->last_label())) + sp->push_backpatch(thd, i, ctx->last_label())) MYSQL_YYABORT; - if (sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0))) + if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0))) MYSQL_YYABORT; } sp_hcond_list sp_proc_stmt @@ -3175,7 +3197,7 @@ sp_decl: sp_instr_hreturn(sp->instructions(), ctx); if (i == NULL || sp->add_instr(i) || - sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ + sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */ MYSQL_YYABORT; } lex->sphead->backpatch(hlab); @@ -3682,18 +3704,31 @@ sp_opt_default: | DEFAULT expr { $$ = $2; } ; -sp_proc_stmt: - sp_proc_stmt_statement - | sp_proc_stmt_return +/* + ps_proc_stmt_in_returns_clause is a statement that is allowed + in the RETURNS clause of a stored function definition directly, + without the BEGIN..END block. + It should not include any syntax structures starting with '(', to avoid + shift/reduce conflicts with the rule "field_type" and its sub-rules + that scan an optional length, like CHAR(1) or YEAR(4). + See MDEV-9166. +*/ +sp_proc_stmt_in_returns_clause: + sp_proc_stmt_return | sp_labeled_block | sp_unlabeled_block | sp_labeled_control + | sp_proc_stmt_compound_ok + ; + +sp_proc_stmt: + sp_proc_stmt_in_returns_clause + | sp_proc_stmt_statement | sp_proc_stmt_leave | sp_proc_stmt_iterate | sp_proc_stmt_open | sp_proc_stmt_fetch | sp_proc_stmt_close - | sp_proc_stmt_compound_ok ; sp_proc_stmt_compound_ok: @@ -3847,7 +3882,7 @@ sp_proc_stmt_leave: i= new (lex->thd->mem_root) sp_instr_jump(ip, ctx); if (i == NULL) MYSQL_YYABORT; - sp->push_backpatch(i, lab); /* Jumping forward */ + sp->push_backpatch(thd, i, lab); /* Jumping forward */ sp->add_instr(i); } } @@ -4024,7 +4059,7 @@ sp_if: sp_instr_jump_if_not *i= new (lex->thd->mem_root) sp_instr_jump_if_not(ip, ctx, $2, lex); if (i == NULL || - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) || + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -4041,7 +4076,7 @@ sp_if: sp->add_instr(i)) MYSQL_YYABORT; sp->backpatch(ctx->pop_label()); - sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)); + sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)); } sp_elseifs { @@ -4332,7 +4367,7 @@ while_body: sp_instr_jump_if_not(ip, lex->spcont, $1, lex); if (i == NULL || /* Jumping forward */ - sp->push_backpatch(i, lex->spcont->last_label()) || + sp->push_backpatch(thd, i, lex->spcont->last_label()) || sp->new_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -5090,7 +5125,7 @@ part_func: '(' remember_name part_func_expr remember_end ')' { partition_info *part_info= Lex->part_info; - if (part_info->set_part_expr($2+1, $3, $4, FALSE)) + if (part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE)) { MYSQL_YYABORT; } part_info->num_columns= 1; part_info->column_list= FALSE; @@ -5100,7 +5135,7 @@ part_func: sub_part_func: '(' remember_name part_func_expr remember_end ')' { - if (Lex->part_info->set_part_expr($2+1, $3, $4, TRUE)) + if (Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE)) { MYSQL_YYABORT; } } ; @@ -6043,13 +6078,13 @@ field_list: ; field_list_item: - column_def + column_def { } | key_def ; column_def: - field_spec opt_check_constraint - | field_spec references + field_spec opt_check_constraint { $$= $1; } + | field_spec references { $$= $1; } ; key_def: @@ -6171,21 +6206,23 @@ field_spec: MYSQL_YYABORT; lex->init_last_field(f, $1.str, NULL); + $<create_field>$= f; } field_type { Lex->set_last_field_type($3); } field_def { LEX *lex=Lex; - Create_field *f= lex->last_field; + $$= $<create_field>2; - if (f->check(thd)) + if ($$->check(thd)) MYSQL_YYABORT; - lex->alter_info.create_list.push_back(f, thd->mem_root); + lex->alter_info.create_list.push_back($$, thd->mem_root); - if (f->flags & PRI_KEY_FLAG) + $$->create_if_not_exists= Lex->check_exists; + if ($$->flags & PRI_KEY_FLAG) add_key_to_list(lex, &$1, Key::PRIMARY, Lex->check_exists); - else if (f->flags & (UNIQUE_FLAG | UNIQUE_KEY_FLAG)) + else if ($$->flags & UNIQUE_KEY_FLAG) add_key_to_list(lex, &$1, Key::UNIQUE, Lex->check_exists); } ; @@ -6231,13 +6268,13 @@ vcol_attribute: UNIQUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | UNIQUE_SYM KEY_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; } @@ -6277,15 +6314,15 @@ virtual_column_func: ; field_type: - int_type opt_field_length field_options { $$=$1; } - | real_type opt_precision field_options { $$=$1; } + 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 { - $$=MYSQL_TYPE_FLOAT; - if (Lex->length && !Lex->dec) + $$.set(MYSQL_TYPE_FLOAT, $2); + if ($2.length() && !$2.dec()) { int err; - ulonglong tmp_length= my_strtoll10(Lex->length, NULL, &err); + ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err); if (err || tmp_length > PRECISION_FOR_DOUBLE) { my_error(ER_WRONG_FIELD_SPEC, MYF(0), @@ -6293,80 +6330,57 @@ field_type: MYSQL_YYABORT; } else if (tmp_length > PRECISION_FOR_FLOAT) - $$= MYSQL_TYPE_DOUBLE; - Lex->length= 0; + $$.set(MYSQL_TYPE_DOUBLE); + else + $$.set(MYSQL_TYPE_FLOAT); } } - | BIT_SYM - { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_BIT; - } - | BIT_SYM field_length + | BIT_SYM opt_field_length_default_1 { - $$=MYSQL_TYPE_BIT; + $$.set(MYSQL_TYPE_BIT, $2); } | BOOL_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; + $$.set(MYSQL_TYPE_TINY, "1"); } | BOOLEAN_SYM { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_TINY; - } - | char field_length opt_binary - { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_TINY, "1"); } - | char opt_binary + | char opt_field_length_default_1 opt_binary { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } - | nchar field_length opt_bin_mod + | nchar opt_field_length_default_1 opt_bin_mod { - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); bincmp_collation(national_charset_info, $3); } - | nchar opt_bin_mod + | BINARY opt_field_length_default_1 { - Lex->length= (char*) "1"; - $$=MYSQL_TYPE_STRING; - bincmp_collation(national_charset_info, $2); - } - | BINARY field_length - { - Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; - } - | BINARY - { - Lex->length= (char*) "1"; Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_STRING; + $$.set(MYSQL_TYPE_STRING, $2); } | varchar field_length opt_binary { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | nvarchar field_length opt_bin_mod { - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); bincmp_collation(national_charset_info, $3); } | VARBINARY field_length { Lex->charset=&my_charset_bin; - $$= MYSQL_TYPE_VARCHAR; + $$.set(MYSQL_TYPE_VARCHAR, $2); } | YEAR_SYM opt_field_length field_options { - if (Lex->length) + if ($2) { errno= 0; - ulong length= strtoul(Lex->length, NULL, 10); + ulong length= strtoul($2, NULL, 10); if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4) { char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; @@ -6377,18 +6391,18 @@ field_type: buff, "YEAR(4)"); } } - $$=MYSQL_TYPE_YEAR; + $$.set(MYSQL_TYPE_YEAR, $2); } | DATE_SYM - { $$=MYSQL_TYPE_DATE; } + { $$.set(MYSQL_TYPE_DATE); } | TIME_SYM opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); } | TIMESTAMP opt_field_length { if (thd->variables.sql_mode & MODE_MAXDB) - $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; + $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); else { /* @@ -6397,29 +6411,29 @@ field_type: */ if (!opt_explicit_defaults_for_timestamp) Lex->last_field->flags|= NOT_NULL_FLAG; - $$= opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 - : MYSQL_TYPE_TIMESTAMP; + $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2 + : MYSQL_TYPE_TIMESTAMP, $2); } } | DATETIME opt_field_length - { $$= opt_mysql56_temporal_format ? - MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; } + { $$.set(opt_mysql56_temporal_format ? + MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); } | TINYBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_TINY_BLOB; + $$.set(MYSQL_TYPE_TINY_BLOB); } | BLOB_SYM opt_field_length { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_BLOB; + $$.set(MYSQL_TYPE_BLOB, $2); } | spatial_type float_options srid_option { #ifdef HAVE_SPATIAL Lex->charset=&my_charset_bin; Lex->last_field->geom_type= $1; - $$=MYSQL_TYPE_GEOMETRY; + $$.set(MYSQL_TYPE_GEOMETRY, $2); #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); @@ -6429,57 +6443,52 @@ field_type: | MEDIUMBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGBLOB { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_LONG_BLOB; + $$.set(MYSQL_TYPE_LONG_BLOB); } | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; - $$=MYSQL_TYPE_MEDIUM_BLOB; + $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONG_SYM varchar opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | TINYTEXT opt_binary - { $$=MYSQL_TYPE_TINY_BLOB; } + { $$.set(MYSQL_TYPE_TINY_BLOB); } | TEXT_SYM opt_field_length opt_binary - { $$=MYSQL_TYPE_BLOB; } + { $$.set(MYSQL_TYPE_BLOB, $2); } | MEDIUMTEXT opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | LONGTEXT opt_binary - { $$=MYSQL_TYPE_LONG_BLOB; } + { $$.set(MYSQL_TYPE_LONG_BLOB); } | DECIMAL_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | NUMERIC_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | FIXED_SYM float_options field_options - { $$=MYSQL_TYPE_NEWDECIMAL;} + { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);} | ENUM '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_ENUM; } + { $$.set(MYSQL_TYPE_ENUM); } | SET '(' string_list ')' opt_binary - { $$=MYSQL_TYPE_SET; } + { $$.set(MYSQL_TYPE_SET); } | LONG_SYM opt_binary - { $$=MYSQL_TYPE_MEDIUM_BLOB; } + { $$.set(MYSQL_TYPE_MEDIUM_BLOB); } | SERIAL_SYM { - $$=MYSQL_TYPE_LONGLONG; + $$.set(MYSQL_TYPE_LONGLONG); Lex->last_field->flags|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | - UNIQUE_FLAG); + UNIQUE_KEY_FLAG); } ; spatial_type: GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } - | POINT_SYM - { - Lex->length= const_cast<char*>(STRINGIFY_ARG - (MAX_LEN_GEOM_POINT_FIELD)); - $$= Field::GEOM_POINT; - } + | POINT_SYM { $$= Field::GEOM_POINT; } | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } | LINESTRING { $$= Field::GEOM_LINESTRING; } | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } @@ -6540,21 +6549,13 @@ srid_option: ; float_options: - /* empty */ - { Lex->dec=Lex->length= (char*)0; } - | field_length - { Lex->dec= (char*)0; } - | precision - {} + /* empty */ { $$.set(0, 0); } + | field_length { $$.set($1, 0); } + | precision { $$= $1; } ; precision: - '(' NUM ',' NUM ')' - { - LEX *lex=Lex; - lex->length=$2.str; - lex->dec=$4.str; - } + '(' NUM ',' NUM ')' { $$.set($2.str, $4.str); } ; field_options: @@ -6574,19 +6575,22 @@ field_option: ; field_length: - '(' LONG_NUM ')' { Lex->length= $2.str; } - | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; } - | '(' DECIMAL_NUM ')' { Lex->length= $2.str; } - | '(' NUM ')' { Lex->length= $2.str; }; + '(' LONG_NUM ')' { $$= $2.str; } + | '(' ULONGLONG_NUM ')' { $$= $2.str; } + | '(' DECIMAL_NUM ')' { $$= $2.str; } + | '(' NUM ')' { $$= $2.str; }; opt_field_length: - /* empty */ { Lex->length=(char*) 0; /* use default length */ } - | field_length { } - ; + /* empty */ { $$= (char*) 0; /* use default length */ } + | field_length { $$= $1; } + +opt_field_length_default_1: + /* empty */ { $$= (char*) "1"; } + | field_length { $$= $1; } opt_precision: - /* empty */ {} - | precision {} + /* empty */ { $$.set(0, 0); } + | precision { $$= $1; } ; opt_attribute: @@ -6614,7 +6618,7 @@ attribute: | SERIAL_SYM DEFAULT VALUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; + lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | opt_primary KEY_SYM @@ -6626,7 +6630,7 @@ attribute: | UNIQUE_SYM { LEX *lex=Lex; - lex->last_field->flags|= UNIQUE_FLAG; + lex->last_field->flags|= UNIQUE_KEY_FLAG; lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX; } | UNIQUE_SYM KEY_SYM @@ -7347,6 +7351,13 @@ alter: lex->sql_command= SQLCOM_ALTER_SERVER; lex->server_options.reset($3); } OPTIONS_SYM '(' server_options_list ')' { } + /* ALTER USER foo is allowed for MySQL compatibility. */ + | ALTER opt_if_exists USER clear_privileges grant_list + opt_require_clause opt_resource_options + { + Lex->create_info.set($2); + Lex->sql_command= SQLCOM_ALTER_USER; + } ; ev_alter_on_schedule_completion: @@ -7634,6 +7645,7 @@ alter_list_item: add_column column_def opt_place { Lex->create_last_non_select_table= Lex->last_table(); + $2->after= $3; } | ADD key_def { @@ -7650,14 +7662,16 @@ alter_list_item: { Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - Lex->last_field->change= $4.str; + $5->change= $4.str; + $5->after= $6; } | MODIFY_SYM opt_column opt_if_exists_table_element field_spec opt_place { Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN; Lex->create_last_non_select_table= Lex->last_table(); - Lex->last_field->change= Lex->last_field->field_name; + $4->change= $4->field_name; + $4->after= $5; } | DROP opt_column opt_if_exists_table_element field_ident opt_restrict { @@ -7870,15 +7884,15 @@ opt_restrict: ; opt_place: - /* empty */ {} + /* empty */ { $$= NULL; } | AFTER_SYM ident { - store_position_for_column($2.str); + $$= $2.str; Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } | FIRST_SYM { - store_position_for_column(first_keyword); + $$= first_keyword; Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER; } ; @@ -8452,10 +8466,11 @@ opt_ignore_leaves: select: - select_init + opt_with_clause select_init { LEX *lex= Lex; lex->sql_command= SQLCOM_SELECT; + lex->current_select->set_with_clause($1); } ; @@ -8722,11 +8737,11 @@ select_item: MYSQL_YYABORT; } $2->is_autogenerated_name= FALSE; - $2->set_name($4.str, $4.length, system_charset_info); + $2->set_name(thd, $4.str, $4.length, system_charset_info); } else if (!$2->name) { - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } } ; @@ -9187,92 +9202,44 @@ all_or_any: opt_dyncol_type: /* empty */ { - LEX *lex= Lex; - $$= DYN_COL_NULL; /* automatic type */ - lex->charset= NULL; - lex->length= lex->dec= 0; + $$.set(DYN_COL_NULL); /* automatic type */ + Lex->charset= NULL; } | AS dyncol_type { $$= $2; } ; dyncol_type: - INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_INT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | UNSIGNED INT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_UINT; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DOUBLE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | REAL - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | FLOAT_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DOUBLE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | DECIMAL_SYM float_options - { - $$= DYN_COL_DECIMAL; - Lex->charset= NULL; - } - | char + numeric_dyncol_type { $$= $1; Lex->charset= NULL; } + | temporal_dyncol_type { $$= $1; Lex->charset= NULL; } + | string_dyncol_type { $$= $1; } + ; + +numeric_dyncol_type: + INT_SYM { $$.set(DYN_COL_INT); } + | UNSIGNED INT_SYM { $$.set(DYN_COL_UINT); } + | DOUBLE_SYM { $$.set(DYN_COL_DOUBLE); } + | REAL { $$.set(DYN_COL_DOUBLE); } + | FLOAT_SYM { $$.set(DYN_COL_DOUBLE); } + | DECIMAL_SYM float_options { $$.set(DYN_COL_DECIMAL, $2); } + ; + +temporal_dyncol_type: + DATE_SYM { $$.set(DYN_COL_DATE); } + | TIME_SYM opt_field_length { $$.set(DYN_COL_TIME, 0, $2); } + | DATETIME opt_field_length { $$.set(DYN_COL_DATETIME, 0, $2); } + ; + +string_dyncol_type: + char { Lex->charset= thd->variables.collation_connection; } opt_binary { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->length= lex->dec= 0; + $$.set(DYN_COL_STRING); } | nchar { - LEX *lex= Lex; - $$= DYN_COL_STRING; - lex->charset= national_charset_info; - lex->length= lex->dec= 0; - } - | DATE_SYM - { - LEX *lex= Lex; - $$= DYN_COL_DATE; - lex->charset= NULL; - lex->length= lex->dec= 0; - } - | TIME_SYM opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_TIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; - } - | DATETIME opt_field_length - { - LEX *lex= Lex; - $$= DYN_COL_DATETIME; - lex->charset= NULL; - lex->dec= lex->length; - lex->length= 0; + $$.set(DYN_COL_STRING); + Lex->charset= national_charset_info; } ; @@ -9286,14 +9253,14 @@ dyncall_create_element: MYSQL_YYABORT; $$->key= $1; $$->value= $3; - $$->type= (DYNAMIC_COLUMN_TYPE)$4; + $$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type(); $$->cs= lex->charset; - if (lex->length) - $$->len= strtoul(lex->length, NULL, 10); + if ($4.length()) + $$->len= strtoul($4.length(), NULL, 10); else $$->len= 0; - if (lex->dec) - $$->frac= strtoul(lex->dec, NULL, 10); + if ($4.dec()) + $$->frac= strtoul($4.dec(), NULL, 10); else $$->len= 0; } @@ -9434,7 +9401,7 @@ simple_expr: | CAST_SYM '(' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_cast(thd, $3, $5, lex->length, lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9447,7 +9414,7 @@ simple_expr: } | CONVERT_SYM '(' expr ',' cast_type ')' { - $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec, + $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(), Lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -9887,8 +9854,8 @@ function_call_nonkeyword: COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')' { LEX *lex= Lex; - $$= create_func_dyncol_get(thd, $3, $5, $7, - lex->length, lex->dec, + $$= create_func_dyncol_get(thd, $3, $5, $7.type(), + $7.length(), $7.dec(), lex->charset); if ($$ == NULL) MYSQL_YYABORT; @@ -10028,7 +9995,7 @@ function_call_conflict: if (!(i1= get_system_var(thd, OPT_SESSION, name, null_lex_str))) MYSQL_YYABORT; - i1->set_name((const char *) + i1->set_name(thd, (const char *) STRING_WITH_LEN("@@default_week_format"), system_charset_info); $$= new (thd->mem_root) Item_func_week(thd, $3, i1); @@ -10315,7 +10282,7 @@ udf_expr: if ($4.str) { $2->is_autogenerated_name= FALSE; - $2->set_name($4.str, $4.length, system_charset_info); + $2->set_name(thd, $4.str, $4.length, system_charset_info); } /* A field has to have its proper name in order for name @@ -10325,7 +10292,7 @@ udf_expr: */ else if ($2->type() != Item::FIELD_ITEM && $2->type() != Item::REF_ITEM /* For HAVING */ ) - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); $$= $2; } ; @@ -10577,43 +10544,35 @@ in_sum_expr: cast_type: BINARY opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); Lex->charset= &my_charset_bin; } | CHAR_SYM opt_field_length { Lex->charset= thd->variables.collation_connection; } opt_binary - { $$=ITEM_CAST_CHAR; Lex->dec= 0; } + { $$.set(ITEM_CAST_CHAR, $2); } | NCHAR_SYM opt_field_length - { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } - | INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | SIGNED_SYM INT_SYM - { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | UNSIGNED INT_SYM - { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | DATE_SYM - { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } - | TIME_SYM opt_field_length - { - $$=ITEM_CAST_TIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DATETIME opt_field_length { - $$=ITEM_CAST_DATETIME; - LEX *lex= Lex; - lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0; - } - | DECIMAL_SYM float_options - { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; } - | DOUBLE_SYM - { Lex->charset= NULL; Lex->length= Lex->dec= 0;} - opt_precision - { $$=ITEM_CAST_DOUBLE; } + Lex->charset= national_charset_info; + $$.set(ITEM_CAST_CHAR, $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); } + ; + +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); } + ; opt_expr_list: /* empty */ { $$= NULL; } @@ -10937,20 +10896,20 @@ table_factor: and our parser. Possibly this rule could be replaced by our query_expression_body. */ - | '(' get_select_lex select_derived_union ')' opt_table_alias + | '('opt_with_clause get_select_lex select_derived_union ')' opt_table_alias { - /* Use $2 instead of Lex->current_select as derived table will + /* Use $3 instead of Lex->current_select as derived table will alter value of Lex->current_select. */ - if (!($3 || $5) && $2->embedding && - !$2->embedding->nested_join->join_list.elements) + if (!($4 || $6) && $3->embedding && + !$3->embedding->nested_join->join_list.elements) { - /* we have a derived table ($3 == NULL) but no alias, + /* we have a derived table ($4 == NULL) but no alias, Since we are nested in further parentheses so we can pass NULL to the outer level parentheses Permits parsing of "((((select ...))) as xyz)" */ $$= 0; } - else if (!$3) + else if (!$4) { /* Handle case of derived table, alias may be NULL if there are no outer parentheses, add_table_to_list() will throw @@ -10958,12 +10917,13 @@ table_factor: LEX *lex=Lex; SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel->master_unit(); + unit->set_with_clause($2); lex->current_select= sel= unit->outer_select(); Table_ident *ti= new (thd->mem_root) Table_ident(unit); if (ti == NULL) MYSQL_YYABORT; if (!($$= sel->add_table_to_list(lex->thd, - ti, $5, 0, + ti, $6, 0, TL_READ, MDL_SHARED_READ))) MYSQL_YYABORT; @@ -10971,11 +10931,11 @@ table_factor: 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) + /*else if (($4->select_lex && + $4->select_lex->master_unit()->is_union() && + ($4->select_lex->master_unit()->first_select() == + $4->select_lex || !$4->lifted)) || $6)*/ + else if ($6 != NULL) { /* Tables with or without joins within parentheses cannot @@ -10988,7 +10948,7 @@ table_factor: { /* nested join: FROM (t1 JOIN t2 ...), nest_level is the same as in the outer query */ - $$= $3; + $$= $4; } /* Fields in derived table can be used in upper select in @@ -11576,7 +11536,7 @@ limit_option: if (spc && (spv = spc->find_variable($1, false))) { splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->type, + 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) @@ -11762,7 +11722,7 @@ procedure_item: if (add_proc_to_list(thd, $2)) MYSQL_YYABORT; if (!$2->name) - $2->set_name($1, (uint) ($3 - $1), thd->charset()); + $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset()); } ; @@ -11816,7 +11776,7 @@ select_outvar: MYSQL_YYABORT; } $$ = Lex->result ? (new (thd->mem_root) - my_var_sp($1, t->offset, t->type, + my_var_sp($1, t->offset, t->sql_type(), Lex->sphead)) : NULL; } @@ -12826,6 +12786,18 @@ show_param: lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER; lex->spname= $3; } + | CREATE USER + { + Lex->sql_command= SQLCOM_SHOW_CREATE_USER; + if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER)))) + MYSQL_YYABORT; + Lex->grant_user->user= current_user; + } + | CREATE USER user + { + Lex->sql_command= SQLCOM_SHOW_CREATE_USER; + Lex->grant_user= $3; + } | PROCEDURE_SYM STATUS_SYM wild_and_where { LEX *lex= Lex; @@ -13489,7 +13461,7 @@ load_data_set_elem: if (lex->update_list.push_back($1, thd->mem_root) || lex->value_list.push_back($4, thd->mem_root)) MYSQL_YYABORT; - $4->set_name_no_truncate($3, (uint) ($5 - $3), thd->charset()); + $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset()); } ; @@ -13775,8 +13747,93 @@ temporal_literal: ; +opt_with_clause: + /*empty */ { $$= 0; } + | with_clause + { + $$= $1; + Lex->derived_tables|= DERIVED_WITH; + } + ; + + +with_clause: + WITH opt_recursive + { + With_clause *with_clause= + new With_clause($2, Lex->curr_with_clause); + if (with_clause == NULL) + MYSQL_YYABORT; + Lex->curr_with_clause= with_clause; + with_clause->add_to_list(Lex->with_clauses_list_last_next); + } + with_list + { + $$= Lex->curr_with_clause; + Lex->curr_with_clause= Lex->curr_with_clause->pop(); + } + ; + + +opt_recursive: + /*empty*/ { $$= 0; } + | RECURSIVE_SYM { $$= 1; } + ; + + +with_list: + with_list_element + | with_list ',' with_list_element + ; + + +with_list_element: + query_name + opt_with_column_list + AS '(' remember_name subselect remember_end ')' + { + With_element *elem= new With_element($1, Lex->with_column_list, $6->master_unit()); + if (elem == NULL || Lex->curr_with_clause->add_with_element(elem)) + MYSQL_YYABORT; + Lex->with_column_list.empty(); + if (elem->set_unparsed_spec(thd, $5+1, $7)) + MYSQL_YYABORT; + } + ; + + +opt_with_column_list: + /* empty */ + {} + | '(' with_column_list ')' + ; + + +with_column_list: + ident + { + Lex->with_column_list.push_back((LEX_STRING*) + thd->memdup(&$1, sizeof(LEX_STRING))); + } + | with_column_list ',' ident + { + Lex->with_column_list.push_back((LEX_STRING*) + thd->memdup(&$3, sizeof(LEX_STRING))); + } + ; + + +query_name: + ident + { + $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING)); + if ($$ == NULL) + MYSQL_YYABORT; + } + ; + /********************************************************************** ** Creating different items. **********************************************************************/ @@ -13832,7 +13889,7 @@ simple_ident: Item_splocal *splocal; splocal= new (thd->mem_root) - Item_splocal(thd, $1, spv->offset, spv->type, + 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) @@ -14265,6 +14322,7 @@ keyword: | ASCII_SYM {} | BACKUP_SYM {} | BEGIN_SYM {} + | BINLOG_SYM {} | BYTE_SYM {} | CACHE_SYM {} | CHARSET {} @@ -14348,7 +14406,6 @@ keyword_sp: | AUTO_SYM {} | AVG_ROW_LENGTH {} | AVG_SYM {} - | BINLOG_SYM {} | BIT_SYM {} | BLOCK_SYM {} | BOOL_SYM {} @@ -15401,14 +15458,14 @@ grant: grant_command: grant_privileges ON opt_table grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; lex->sql_command= SQLCOM_GRANT; lex->type= 0; } | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; if (lex->columns.elements) @@ -15420,7 +15477,7 @@ grant_command: lex->type= TYPE_ENUM_FUNCTION; } | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list - require_clause grant_options + opt_require_clause opt_grant_options { LEX *lex= Lex; if (lex->columns.elements) @@ -15780,7 +15837,7 @@ column_list_id: } ; -require_clause: +opt_require_clause: /* empty */ | REQUIRE_SYM require_list { @@ -15800,24 +15857,8 @@ require_clause: } ; -grant_options: - /* empty */ {} - | WITH grant_option_list - ; - -opt_grant_option: - /* empty */ {} - | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} - ; - -grant_option_list: - grant_option_list grant_option {} - | grant_option {} - ; - -grant_option: - GRANT OPTION { Lex->grant |= GRANT_ACL;} - | MAX_QUERIES_PER_HOUR ulong_num +resource_option: + MAX_QUERIES_PER_HOUR ulong_num { LEX *lex=Lex; lex->mqh.questions=$2; @@ -15849,6 +15890,37 @@ grant_option: } ; +resource_option_list: + resource_option_list resource_option {} + | resource_option {} + ; + +opt_resource_options: + /* empty */ {} + | WITH resource_option_list + ; + + +opt_grant_options: + /* empty */ {} + | WITH grant_option_list {} + ; + +opt_grant_option: + /* empty */ {} + | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} + ; + +grant_option_list: + grant_option_list grant_option {} + | grant_option {} + ; + +grant_option: + GRANT OPTION { Lex->grant |= GRANT_ACL;} + | resource_option {} + ; + begin: BEGIN_SYM { @@ -16044,9 +16116,10 @@ query_expression_body: /* Corresponds to <query expression> in the SQL:2003 standard. */ subselect: - subselect_start query_expression_body subselect_end + subselect_start opt_with_clause query_expression_body subselect_end { - $$= $2; + $3->set_with_clause($2); + $$= $3; } ; @@ -16273,7 +16346,7 @@ view_select: lex->parsing_options.allows_derived= FALSE; lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr(); } - view_select_aux view_check_option + opt_with_clause view_select_aux view_check_option { LEX *lex= Lex; uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str; @@ -16285,6 +16358,7 @@ view_select: lex->parsing_options.allows_select_into= TRUE; lex->parsing_options.allows_select_procedure= TRUE; lex->parsing_options.allows_derived= TRUE; + lex->current_select->set_with_clause($2); } ; @@ -16450,8 +16524,7 @@ sf_tail: } type_with_opt_collate /* $11 */ { /* $12 */ - if (Lex->sphead->fill_field_definition(thd, Lex, $11, - Lex->last_field)) + if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field)) MYSQL_YYABORT; } sp_c_chistics /* $13 */ @@ -16461,7 +16534,7 @@ sf_tail: lex->sphead->set_body_start(thd, lip->get_cpp_tok_start()); } - sp_proc_stmt /* $15 */ + sp_proc_stmt_in_returns_clause /* $15 */ { LEX *lex= thd->lex; sp_head *sp= lex->sphead; |