summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-11-14 07:38:28 +0400
committerAlexander Barkov <bar@mariadb.com>2018-11-14 07:38:28 +0400
commit62bcd74712680fa07c9ed8c42c384c8825c4f9af (patch)
tree6b120949dbc18036b2e09caf296bb75972230dd0
parentfde5386d16df100b5ecc8a47f0616de25fd9116e (diff)
downloadmariadb-git-62bcd74712680fa07c9ed8c42c384c8825c4f9af.tar.gz
MDEV-17694 Add method LEX::sp_proc_stmt_statement_finalize()
-rw-r--r--sql/sql_lex.cc56
-rw-r--r--sql/sql_lex.h5
-rw-r--r--sql/sql_yacc.yy66
-rw-r--r--sql/sql_yacc_ora.yy40
-rw-r--r--sql/vers_string.h6
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;