diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-11-14 07:38:28 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-11-14 07:38:28 +0400 |
commit | 62bcd74712680fa07c9ed8c42c384c8825c4f9af (patch) | |
tree | 6b120949dbc18036b2e09caf296bb75972230dd0 | |
parent | fde5386d16df100b5ecc8a47f0616de25fd9116e (diff) | |
download | mariadb-git-62bcd74712680fa07c9ed8c42c384c8825c4f9af.tar.gz |
MDEV-17694 Add method LEX::sp_proc_stmt_statement_finalize()
-rw-r--r-- | sql/sql_lex.cc | 56 | ||||
-rw-r--r-- | sql/sql_lex.h | 5 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 66 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 40 | ||||
-rw-r--r-- | sql/vers_string.h | 6 |
5 files changed, 75 insertions, 98 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2f5a845d18c..a7b36c901d6 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -9470,3 +9470,59 @@ bool SELECT_LEX::make_unique_derived_name(THD *thd, LEX_CSTRING *alias) alias->str= thd->strmake(buff, alias->length); return !alias->str; } + + +/* + Make a new sp_instr_stmt and set its m_query to a concatenation + of two strings. +*/ +bool LEX::new_sp_instr_stmt(THD *thd, + const LEX_CSTRING &prefix, + const LEX_CSTRING &suffix) +{ + LEX_STRING qbuff; + sp_instr_stmt *i; + + if (!(i= new (thd->mem_root) sp_instr_stmt(sphead->instructions(), + spcont, this))) + return true; + + qbuff.length= prefix.length + suffix.length; + if (!(qbuff.str= (char*) alloc_root(thd->mem_root, qbuff.length + 1))) + return true; + memcpy(qbuff.str, prefix.str, prefix.length); + strmake(qbuff.str + prefix.length, suffix.str, suffix.length); + i->m_query= qbuff; + return sphead->add_instr(i); +} + + +bool LEX::sp_proc_stmt_statement_finalize_buf(THD *thd, const LEX_CSTRING &qbuf) +{ + sphead->m_flags|= sp_get_flags_for_command(this); + /* "USE db" doesn't work in a procedure */ + if (unlikely(sql_command == SQLCOM_CHANGE_DB)) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "USE"); + return true; + } + /* + Don't add an instruction for SET statements, since all + instructions for them were already added during processing + of "set" rule. + */ + DBUG_ASSERT(sql_command != SQLCOM_SET_OPTION || var_list.is_empty()); + if (sql_command != SQLCOM_SET_OPTION) + return new_sp_instr_stmt(thd, empty_clex_str, qbuf); + return false; +} + + +bool LEX::sp_proc_stmt_statement_finalize(THD *thd, bool no_lookahead) +{ + // Extract the query statement from the tokenizer + Lex_input_stream *lip= &thd->m_parser_state->m_lip; + Lex_cstring qbuf(sphead->m_tmp_query, no_lookahead ? lip->get_ptr() : + lip->get_tok_start()); + return LEX::sp_proc_stmt_statement_finalize_buf(thd, qbuf); +} diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8dab2a06973..b10119b55de 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3558,6 +3558,11 @@ public: bool last_field_generated_always_as_row_end(); bool set_bincmp(CHARSET_INFO *cs, bool bin); + bool new_sp_instr_stmt(THD *, const LEX_CSTRING &prefix, + const LEX_CSTRING &suffix); + bool sp_proc_stmt_statement_finalize_buf(THD *, const LEX_CSTRING &qbuf); + bool sp_proc_stmt_statement_finalize(THD *, bool no_lookahead); + bool get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer); bool prepared_stmt_params_fix_fields(THD *thd) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9a19a5b9c8c..44c22eab665 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -553,8 +553,6 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) if (lex->sphead) { - sp_head *sp= lex->sphead; - if (!lex->var_list.is_empty()) { /* @@ -562,33 +560,17 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead) option setting, so we should construct sp_instr_stmt for it. */ - LEX_STRING qbuff; - sp_instr_stmt *i; Lex_input_stream *lip= &thd->m_parser_state->m_lip; - if (!(i= new (thd->mem_root) - sp_instr_stmt(sp->instructions(), lex->spcont, lex))) - return true; - /* Extract the query statement from the tokenizer. The end is either lip->ptr, if there was no lookahead, lip->tok_end otherwise. */ - if (no_lookahead) - qbuff.length= lip->get_ptr() - sp->m_tmp_query; - else - qbuff.length= lip->get_tok_end() - sp->m_tmp_query; - - if (!(qbuff.str= (char*) alloc_root(thd->mem_root, - qbuff.length + 5))) - return true; - - strmake(strmake(qbuff.str, "SET ", 4), sp->m_tmp_query, - qbuff.length); - qbuff.length+= 4; - i->m_query= qbuff; - if (sp->add_instr(i)) + static const LEX_CSTRING setsp= { STRING_WITH_LEN("SET ") }; + const char *qend= no_lookahead ? lip->get_ptr() : lip->get_tok_end(); + Lex_cstring qbuf(lex->sphead->m_tmp_query, qend); + if (lex->new_sp_instr_stmt(thd, setsp, qbuf)) return true; } lex->pop_select(); @@ -4157,44 +4139,8 @@ sp_proc_stmt_statement: } statement { - LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - sp_head *sp= lex->sphead; - - sp->m_flags|= sp_get_flags_for_command(lex); - /* "USE db" doesn't work in a procedure */ - if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB)) - my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE")); - /* - Don't add an instruction for SET statements, since all - instructions for them were already added during processing - of "set" rule. - */ - DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION || - lex->var_list.is_empty()); - if (lex->sql_command != SQLCOM_SET_OPTION) - { - sp_instr_stmt *i=new (thd->mem_root) - sp_instr_stmt(sp->instructions(), lex->spcont, lex); - if (unlikely(i == NULL)) - MYSQL_YYABORT; - - /* - Extract the query statement from the tokenizer. The - end is either lex->ptr, if there was no lookahead, - lex->tok_end otherwise. - */ - if (yychar == YYEMPTY) - i->m_query.length= lip->get_ptr() - sp->m_tmp_query; - else - i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;; - if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root, - sp->m_tmp_query, - i->m_query.length))) || - unlikely(sp->add_instr(i))) - MYSQL_YYABORT; - } - if (unlikely(sp->restore_lex(thd))) + if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) || + Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } ; diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 5a6914c89c7..67f0f08f824 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -4023,44 +4023,8 @@ sp_proc_stmt_statement: } sp_statement { - LEX *lex= thd->lex; - Lex_input_stream *lip= YYLIP; - sp_head *sp= lex->sphead; - - sp->m_flags|= sp_get_flags_for_command(lex); - /* "USE db" doesn't work in a procedure */ - if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB)) - my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE")); - /* - Don't add an instruction for SET statements, since all - instructions for them were already added during processing - of "set" rule. - */ - DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION || - lex->var_list.is_empty()); - if (lex->sql_command != SQLCOM_SET_OPTION) - { - sp_instr_stmt *i=new (thd->mem_root) - sp_instr_stmt(sp->instructions(), lex->spcont, lex); - if (unlikely(i == NULL)) - MYSQL_YYABORT; - - /* - Extract the query statement from the tokenizer. The - end is either lex->ptr, if there was no lookahead, - lex->tok_end otherwise. - */ - if (yychar == YYEMPTY) - i->m_query.length= lip->get_ptr() - sp->m_tmp_query; - else - i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;; - if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root, - sp->m_tmp_query, - i->m_query.length))) || - unlikely(sp->add_instr(i))) - MYSQL_YYABORT; - } - if (unlikely(sp->restore_lex(thd))) + if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) || + Lex->sphead->restore_lex(thd)) MYSQL_YYABORT; } ; diff --git a/sql/vers_string.h b/sql/vers_string.h index 75abd40d5fa..9d8ca358565 100644 --- a/sql/vers_string.h +++ b/sql/vers_string.h @@ -58,6 +58,12 @@ class Lex_cstring : public LEX_CSTRING str= _str; length= _len; } + Lex_cstring(const char *start, const char *end) + { + DBUG_ASSERT(start <= end); + str= start; + length= end - start; + } void set(const char *_str, size_t _len) { str= _str; |