Hi, Sanja! On Jan 27, OleksandrByelkin wrote:
revision-id: 57bf58668877552ee43f4ed86689b8bbb3821c9c (mariadb-10.1.10-23-g57bf586) parent(s): 825f51d1aab51d363dc07ec9fe0829af33063883 committer: Oleksandr Byelkin timestamp: 2016-01-27 00:38:36 +0100 message:
MDEV-8615: Assertion `m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length' failed in Lex_input_stream::body_utf8_start
Nothing should be done before any keyword recognized.
Good! Just two comments: 1. May be it's better to rename s/pop_cs_label/pop_sp_label/ and s/pop_cs_empty_label/pop_sp_empty_label/ ? first, pop_sp_empty_label applies to all SPs, not only to compound statements, and second, pop_cs_label does not apply to compound statements at all :) 2. Your process_control_statement_label() makes no sense here. There is no need to do an if() - because in both branches you always know whether you have a label or not. Please split process_control_statement_label() in two different functions (or two yacc rules, whatever).
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 302c2fd..3c2d386 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -248,6 +248,36 @@ static bool maybe_start_compound_statement(THD *thd) return 0; }
+static bool process_control_statement_label(THD *thd, LEX_STRING label) +{ + if (label.str != NULL) + { + 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; + } + } + else + { + 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'). This helper is used for 'searched' cases only. @@ -4389,6 +4374,84 @@ sp_control_content: } ;
+pop_cs_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_error(ER_SP_LABEL_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + } + } + ; + +pop_cs_empty_label: + { + sp_label *lab; + Lex->sphead->backpatch(lab= Lex->spcont->pop_label()); + DBUG_ASSERT(lab->name.length == 0); + } + ; + +sp_labeled_control: + label_ident ':' LOOP_SYM + { + if (process_control_statement_label(thd, $1)) + MYSQL_YYABORT; + } + loop_body pop_cs_label + { } + | label_ident ':' WHILE_SYM + { + if (process_control_statement_label(thd, $1)) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd); + } + while_body pop_cs_label + { } + | label_ident ':' REPEAT_SYM + { + if (process_control_statement_label(thd, $1)) + MYSQL_YYABORT; + } + repeat_body pop_cs_label + { } + ; + +sp_unlabeled_control: + LOOP_SYM + { + if (process_control_statement_label(thd, null_lex_str)) + MYSQL_YYABORT; + } + loop_body + pop_cs_empty_label + { } + | WHILE_SYM + { + if (process_control_statement_label(thd, null_lex_str)) + MYSQL_YYABORT; + Lex->sphead->reset_lex(thd); + } + while_body + pop_cs_empty_label + { } + | REPEAT_SYM + { + if (process_control_statement_label(thd, null_lex_str)) + MYSQL_YYABORT; + } + repeat_body + pop_cs_empty_label + { } + ; + trg_action_time: BEFORE_SYM { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; }
Regards, Sergei Chief Architect MariaDB and security@mariadb.org