diff options
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r-- | sql/sql_yacc.yy | 281 |
1 files changed, 240 insertions, 41 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4ed9946a334..2d884cb739c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -43,6 +43,7 @@ #include "sp_pcontext.h" #include "sp_rcontext.h" #include "sp.h" +#include "sql_signal.h" #include "event_parse_data.h" #include <myisam.h> #include <myisammrg.h> @@ -507,6 +508,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, sp_head *sphead; struct p_elem_val *p_elem_value; enum index_hint_type index_hint; + Diag_condition_item_name diag_condition_item_name; } %{ @@ -588,6 +590,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CASCADED /* SQL-2003-R */ %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ +%token CATALOG_NAME_SYM /* SQL-2003-N */ %token CHAIN_SYM /* SQL-2003-N */ %token CHANGE %token CHANGED @@ -596,6 +599,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ %token CIPHER_SYM +%token CLASS_ORIGIN_SYM /* SQL-2003-N */ %token CLIENT_SYM %token CLOSE_SYM /* SQL-2003-R */ %token COALESCE /* SQL-2003-N */ @@ -604,6 +608,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COLLATION_SYM /* SQL-2003-N */ %token COLUMNS %token COLUMN_SYM /* SQL-2003-R */ +%token COLUMN_NAME_SYM /* SQL-2003-N */ %token COMMENT_SYM %token COMMITTED_SYM /* SQL-2003-N */ %token COMMIT_SYM /* SQL-2003-R */ @@ -611,10 +616,13 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token COMPLETION_SYM %token COMPRESSED_SYM %token CONCURRENT -%token CONDITION_SYM /* SQL-2003-N */ +%token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ %token CONNECTION_SYM %token CONSISTENT_SYM %token CONSTRAINT /* SQL-2003-R */ +%token CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ +%token CONSTRAINT_NAME_SYM /* SQL-2003-N */ +%token CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ %token CONTAINS_SYM /* SQL-2003-N */ %token CONTEXT_SYM %token CONTINUE_SYM /* SQL-2003-R */ @@ -628,6 +636,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CURDATE /* MYSQL-FUNC */ %token CURRENT_USER /* SQL-2003-R */ %token CURSOR_SYM /* SQL-2003-R */ +%token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ %token DATABASE %token DATABASES @@ -829,6 +838,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MEDIUM_SYM %token MEMORY_SYM %token MERGE_SYM /* SQL-2003-R */ +%token MESSAGE_TEXT_SYM /* SQL-2003-N */ %token MICROSECOND_SYM /* MYSQL-FUNC */ %token MIGRATE_SYM %token MINUTE_MICROSECOND_SYM @@ -845,6 +855,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token MULTIPOINT %token MULTIPOLYGON %token MUTEX_SYM +%token MYSQL_ERRNO_SYM %token NAMES_SYM /* SQL-2003-N */ %token NAME_SYM /* SQL-2003-N */ %token NATIONAL_SYM /* SQL-2003-R */ @@ -945,6 +956,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token REPLICATION %token REQUIRE_SYM %token RESET_SYM +%token RESIGNAL_SYM /* SQL-2003-R */ %token RESOURCES %token RESTORE_SYM %token RESTRICT @@ -962,6 +974,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token RTREE_SYM %token SAVEPOINT_SYM /* SQL-2003-R */ %token SCHEDULE_SYM +%token SCHEMA_NAME_SYM /* SQL-2003-N */ %token SECOND_MICROSECOND_SYM %token SECOND_SYM /* SQL-2003-R */ %token SECURITY_SYM /* SQL-2003-N */ @@ -980,6 +993,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SHIFT_RIGHT /* OPERATOR */ %token SHOW %token SHUTDOWN +%token SIGNAL_SYM /* SQL-2003-R */ %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE @@ -1013,6 +1027,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token STORAGE_SYM %token STRAIGHT_JOIN %token STRING_SYM +%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ %token SUBDATE_SYM %token SUBJECT_SYM %token SUBPARTITIONS_SYM @@ -1029,6 +1044,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ %token TABLE_CHECKSUM_SYM +%token TABLE_NAME_SYM /* SQL-2003-N */ %token TEMPORARY /* SQL-2003-N */ %token TEMPTABLE_SYM %token TERMINATED @@ -1186,6 +1202,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); function_call_nonkeyword function_call_generic function_call_conflict + signal_allowed_expr %type <item_num> NUM_literal @@ -1313,13 +1330,16 @@ END_OF_INPUT %type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt %type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list -%type <spcondtype> sp_cond sp_hcond +%type <spcondtype> sp_cond sp_hcond sqlstate signal_value opt_signal_value %type <spblock> sp_decls sp_decl %type <lex> sp_cursor_stmt %type <spname> sp_name %type <index_hint> index_hint_type %type <num> index_hint_clause +%type <NONE> signal_stmt resignal_stmt +%type <diag_condition_item_name> signal_condition_information_item_name + %type <NONE> '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM @@ -1440,12 +1460,14 @@ statement: | repair | replace | reset + | resignal_stmt | restore | revoke | rollback | savepoint | select | set + | signal_stmt | show | slave | start @@ -2339,12 +2361,12 @@ sp_decl: LEX *lex= Lex; sp_pcontext *spc= lex->spcont; - if (spc->find_cond(&$2, TRUE)) - { - my_error(ER_SP_DUP_COND, MYF(0), $2.str); - MYSQL_YYABORT; - } - if(YYTHD->lex->spcont->push_cond(&$2, $5)) + if (spc->find_cond(&$2, TRUE)) + { + my_error(ER_SP_DUP_COND, MYF(0), $2.str); + MYSQL_YYABORT; + } + if(YYTHD->lex->spcont->push_cond(&$2, $5)) MYSQL_YYABORT; $$.vars= $$.hndlrs= $$.curs= 0; $$.conds= 1; @@ -2359,9 +2381,9 @@ sp_decl: sp_pcontext *ctx= lex->spcont; sp_instr_hpush_jump *i= new sp_instr_hpush_jump(sp->instructions(), ctx, $2, - ctx->current_var_count()); + ctx->current_var_count()); if (i == NULL || - sp->add_instr(i) || + sp->add_instr(i) || sp->push_backpatch(i, ctx->push_label((char *)"", 0))) MYSQL_YYABORT; } @@ -2378,15 +2400,15 @@ sp_decl: i= new sp_instr_hreturn(sp->instructions(), ctx, ctx->current_var_count()); if (i == NULL || - sp->add_instr(i)) + sp->add_instr(i)) MYSQL_YYABORT; } else { /* EXIT or UNDO handler, just jump to the end of the block */ i= new sp_instr_hreturn(sp->instructions(), ctx, 0); if (i == NULL || - sp->add_instr(i) || - sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ + sp->add_instr(i) || + sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */ MYSQL_YYABORT; } lex->sphead->backpatch(hlab); @@ -2413,9 +2435,9 @@ sp_decl: } i= new sp_instr_cpush(sp->instructions(), ctx, $5, ctx->current_cursor_count()); - if (i == NULL || + if (i == NULL || sp->add_instr(i) || - ctx->push_cursor(&$2)) + ctx->push_cursor(&$2)) MYSQL_YYABORT; $$.vars= $$.conds= $$.hndlrs= 0; $$.curs= 1; @@ -2483,13 +2505,22 @@ sp_hcond_element: sp_cond: ulong_num { /* mysql errno */ + if ($1 == 0) + { + my_error(ER_WRONG_VALUE, MYF(0), "CONDITION", "0"); + MYSQL_YYABORT; + } $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); if ($$ == NULL) MYSQL_YYABORT; $$->type= sp_cond_type_t::number; $$->mysqlerr= $1; } - | SQLSTATE_SYM opt_value TEXT_STRING_literal + | sqlstate + ; + +sqlstate: + SQLSTATE_SYM opt_value TEXT_STRING_literal { /* SQLSTATE */ if (!sp_cond_check(&$3)) { @@ -2500,8 +2531,8 @@ sp_cond: if ($$ == NULL) MYSQL_YYABORT; $$->type= sp_cond_type_t::state; - memcpy($$->sqlstate, $3.str, 5); - $$->sqlstate[5]= '\0'; + memcpy($$->sqlstate, $3.str, SQLSTATE_LENGTH); + $$->sqlstate[SQLSTATE_LENGTH]= '\0'; } ; @@ -2547,6 +2578,160 @@ sp_hcond: } ; +signal_stmt: + SIGNAL_SYM signal_value opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Yacc_state *state= & thd->m_parser_state->m_yacc; + + lex->sql_command= SQLCOM_SIGNAL; + lex->m_stmt= new (thd->mem_root) Signal_statement(lex, $2, + state->m_set_signal_info); + if (lex->m_stmt == NULL) + MYSQL_YYABORT; + } + ; + +signal_value: + ident + { + LEX *lex= Lex; + sp_cond_type_t *cond; + if (lex->spcont == NULL) + { + /* SIGNAL foo cannot be used outside of stored programs */ + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + cond= lex->spcont->find_cond(&$1); + if (cond == NULL) + { + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + if (cond->type != sp_cond_type_t::state) + { + my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0)); + MYSQL_YYABORT; + } + $$= cond; + } + | sqlstate + { $$= $1; } + ; + +opt_signal_value: + /* empty */ + { $$= NULL; } + | signal_value + { $$= $1; } + ; + +opt_set_signal_information: + /* empty */ + { + YYTHD->m_parser_state->m_yacc.m_set_signal_info.clear(); + } + | SET signal_information_item_list + ; + +signal_information_item_list: + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info; + info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info; + int index= (int) $1; + info->clear(); + info->m_item[index]= $3; + } + | signal_information_item_list ',' + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info; + info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info; + int index= (int) $3; + if (info->m_item[index] != NULL) + { + my_error(ER_DUP_SIGNAL_SET, MYF(0), + Diag_condition_item_names[index].str); + MYSQL_YYABORT; + } + info->m_item[index]= $5; + } + ; + +/* + Only a limited subset of <expr> are allowed in SIGNAL/RESIGNAL. +*/ +signal_allowed_expr: + literal + { $$= $1; } + | variable + { + if ($1->type() == Item::FUNC_ITEM) + { + Item_func *item= (Item_func*) $1; + if (item->functype() == Item_func::SUSERVAR_FUNC) + { + /* + Don't allow the following syntax: + SIGNAL/RESIGNAL ... + SET <signal condition item name> = @foo := expr + */ + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } + $$= $1; + } + | simple_ident + { $$= $1; } + ; + +/* conditions that can be set in signal / resignal */ +signal_condition_information_item_name: + CLASS_ORIGIN_SYM + { $$= DIAG_CLASS_ORIGIN; } + | SUBCLASS_ORIGIN_SYM + { $$= DIAG_SUBCLASS_ORIGIN; } + | CONSTRAINT_CATALOG_SYM + { $$= DIAG_CONSTRAINT_CATALOG; } + | CONSTRAINT_SCHEMA_SYM + { $$= DIAG_CONSTRAINT_SCHEMA; } + | CONSTRAINT_NAME_SYM + { $$= DIAG_CONSTRAINT_NAME; } + | CATALOG_NAME_SYM + { $$= DIAG_CATALOG_NAME; } + | SCHEMA_NAME_SYM + { $$= DIAG_SCHEMA_NAME; } + | TABLE_NAME_SYM + { $$= DIAG_TABLE_NAME; } + | COLUMN_NAME_SYM + { $$= DIAG_COLUMN_NAME; } + | CURSOR_NAME_SYM + { $$= DIAG_CURSOR_NAME; } + | MESSAGE_TEXT_SYM + { $$= DIAG_MESSAGE_TEXT; } + | MYSQL_ERRNO_SYM + { $$= DIAG_MYSQL_ERRNO; } + ; + +resignal_stmt: + RESIGNAL_SYM opt_signal_value opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Yacc_state *state= & thd->m_parser_state->m_yacc; + + lex->sql_command= SQLCOM_RESIGNAL; + lex->m_stmt= new (thd->mem_root) Resignal_statement(lex, $2, + state->m_set_signal_info); + if (lex->m_stmt == NULL) + MYSQL_YYABORT; + } + ; + sp_decl_idents: ident { @@ -2683,7 +2868,7 @@ sp_proc_stmt_return: i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3, sp->m_return_field_def.sql_type, lex); if (i == NULL || - sp->add_instr(i)) + sp->add_instr(i)) MYSQL_YYABORT; sp->m_flags|= sp_head::HAS_RETURN; } @@ -2923,7 +3108,7 @@ sp_if: sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, $2, lex); if (i == NULL || - sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || + sp->push_backpatch(i, ctx->push_label((char *)"", 0)) || sp->add_cont_backpatch(i) || sp->add_instr(i)) MYSQL_YYABORT; @@ -3205,7 +3390,7 @@ sp_unlabeled_control: if (i == NULL || lex->sphead->add_instr(i)) MYSQL_YYABORT; - } + } | WHILE_SYM { Lex->sphead->reset_lex(YYTHD); } expr DO_SYM @@ -3216,7 +3401,7 @@ sp_unlabeled_control: sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, $3, lex); if (i == NULL || - /* Jumping forward */ + /* Jumping forward */ sp->push_backpatch(i, lex->spcont->last_label()) || sp->new_cont_backpatch(i) || sp->add_instr(i)) @@ -5023,6 +5208,7 @@ field_length: opt_field_length: /* empty */ { Lex->length=(char*) 0; /* use default length */ } | field_length { } + ; opt_precision: /* empty */ {} @@ -6410,7 +6596,7 @@ select_paren: sel->olap != UNSPECIFIED_OLAP_TYPE && sel->master_unit()->fake_select_lex) { - my_error(ER_WRONG_USAGE, MYF(0), + my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY"); MYSQL_YYABORT; } @@ -8705,24 +8891,25 @@ interval: ; interval_time_stamp: - interval_time_st {} - | FRAC_SECOND_SYM { - $$=INTERVAL_MICROSECOND; - /* - FRAC_SECOND was mistakenly implemented with - a wrong resolution. According to the ODBC - standard it should be nanoseconds, not - microseconds. Changing it to nanoseconds - in MySQL would mean making TIMESTAMPDIFF - and TIMESTAMPADD to return DECIMAL, since - the return value would be too big for BIGINT - Hence we just deprecate the incorrect - implementation without changing its - resolution. - */ - WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND"); - } - ; + interval_time_st {} + | FRAC_SECOND_SYM + { + $$=INTERVAL_MICROSECOND; + /* + FRAC_SECOND was mistakenly implemented with + a wrong resolution. According to the ODBC + standard it should be nanoseconds, not + microseconds. Changing it to nanoseconds + in MySQL would mean making TIMESTAMPDIFF + and TIMESTAMPADD to return DECIMAL, since + the return value would be too big for BIGINT + Hence we just deprecate the incorrect + implementation without changing its + resolution. + */ + WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND"); + } + ; interval_time_st: DAY_SYM { $$=INTERVAL_DAY; } @@ -11423,13 +11610,16 @@ keyword_sp: | BOOLEAN_SYM {} | BTREE_SYM {} | CASCADED {} + | CATALOG_NAME_SYM {} | CHAIN_SYM {} | CHANGED {} | CIPHER_SYM {} | CLIENT_SYM {} + | CLASS_ORIGIN_SYM {} | COALESCE {} | CODE_SYM {} | COLLATION_SYM {} + | COLUMN_NAME_SYM {} | COLUMNS {} | COMMITTED_SYM {} | COMPACT_SYM {} @@ -11438,10 +11628,14 @@ keyword_sp: | CONCURRENT {} | CONNECTION_SYM {} | CONSISTENT_SYM {} + | CONSTRAINT_CATALOG_SYM {} + | CONSTRAINT_SCHEMA_SYM {} + | CONSTRAINT_NAME_SYM {} | CONTEXT_SYM {} | CONTRIBUTORS_SYM {} | CPU_SYM {} | CUBE_SYM {} + | CURSOR_NAME_SYM {} | DATA_SYM {} | DATAFILE_SYM {} | DATETIME {} @@ -11533,6 +11727,7 @@ keyword_sp: | MEDIUM_SYM {} | MEMORY_SYM {} | MERGE_SYM {} + | MESSAGE_TEXT_SYM {} | MICROSECOND_SYM {} | MIGRATE_SYM {} | MINUTE_SYM {} @@ -11544,6 +11739,7 @@ keyword_sp: | MULTIPOINT {} | MULTIPOLYGON {} | MUTEX_SYM {} + | MYSQL_ERRNO_SYM {} | NAME_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} @@ -11603,6 +11799,7 @@ keyword_sp: | ROW_SYM {} | RTREE_SYM {} | SCHEDULE_SYM {} + | SCHEMA_NAME_SYM {} | SECOND_SYM {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} @@ -11621,6 +11818,7 @@ keyword_sp: | STATUS_SYM {} | STORAGE_SYM {} | STRING_SYM {} + | SUBCLASS_ORIGIN_SYM {} | SUBDATE_SYM {} | SUBJECT_SYM {} | SUBPARTITION_SYM {} @@ -11629,6 +11827,7 @@ keyword_sp: | SUSPEND_SYM {} | SWAPS_SYM {} | SWITCHES_SYM {} + | TABLE_NAME_SYM {} | TABLES {} | TABLE_CHECKSUM_SYM {} | TABLESPACE {} |