MDEV-17694 Add method LEX::sp_proc_stmt_statement_finalize()
This commit is contained in:
parent
fde5386d16
commit
62bcd74712
@ -9470,3 +9470,59 @@ bool SELECT_LEX::make_unique_derived_name(THD *thd, LEX_CSTRING *alias)
|
|||||||
alias->str= thd->strmake(buff, alias->length);
|
alias->str= thd->strmake(buff, alias->length);
|
||||||
return !alias->str;
|
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);
|
||||||
|
}
|
||||||
|
@ -3558,6 +3558,11 @@ public:
|
|||||||
bool last_field_generated_always_as_row_end();
|
bool last_field_generated_always_as_row_end();
|
||||||
bool set_bincmp(CHARSET_INFO *cs, bool bin);
|
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 get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer);
|
||||||
bool prepared_stmt_params_fix_fields(THD *thd)
|
bool prepared_stmt_params_fix_fields(THD *thd)
|
||||||
{
|
{
|
||||||
|
@ -553,8 +553,6 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
|
|||||||
|
|
||||||
if (lex->sphead)
|
if (lex->sphead)
|
||||||
{
|
{
|
||||||
sp_head *sp= lex->sphead;
|
|
||||||
|
|
||||||
if (!lex->var_list.is_empty())
|
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
|
option setting, so we should construct sp_instr_stmt
|
||||||
for it.
|
for it.
|
||||||
*/
|
*/
|
||||||
LEX_STRING qbuff;
|
|
||||||
sp_instr_stmt *i;
|
|
||||||
Lex_input_stream *lip= &thd->m_parser_state->m_lip;
|
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
|
Extract the query statement from the tokenizer. The
|
||||||
end is either lip->ptr, if there was no lookahead,
|
end is either lip->ptr, if there was no lookahead,
|
||||||
lip->tok_end otherwise.
|
lip->tok_end otherwise.
|
||||||
*/
|
*/
|
||||||
if (no_lookahead)
|
static const LEX_CSTRING setsp= { STRING_WITH_LEN("SET ") };
|
||||||
qbuff.length= lip->get_ptr() - sp->m_tmp_query;
|
const char *qend= no_lookahead ? lip->get_ptr() : lip->get_tok_end();
|
||||||
else
|
Lex_cstring qbuf(lex->sphead->m_tmp_query, qend);
|
||||||
qbuff.length= lip->get_tok_end() - sp->m_tmp_query;
|
if (lex->new_sp_instr_stmt(thd, setsp, qbuf))
|
||||||
|
|
||||||
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))
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
lex->pop_select();
|
lex->pop_select();
|
||||||
@ -4157,44 +4139,8 @@ sp_proc_stmt_statement:
|
|||||||
}
|
}
|
||||||
statement
|
statement
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) ||
|
||||||
Lex_input_stream *lip= YYLIP;
|
Lex->sphead->restore_lex(thd))
|
||||||
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)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -4023,44 +4023,8 @@ sp_proc_stmt_statement:
|
|||||||
}
|
}
|
||||||
sp_statement
|
sp_statement
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) ||
|
||||||
Lex_input_stream *lip= YYLIP;
|
Lex->sphead->restore_lex(thd))
|
||||||
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)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -58,6 +58,12 @@ class Lex_cstring : public LEX_CSTRING
|
|||||||
str= _str;
|
str= _str;
|
||||||
length= _len;
|
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)
|
void set(const char *_str, size_t _len)
|
||||||
{
|
{
|
||||||
str= _str;
|
str= _str;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user