Skip to content

Commit 62bcd74

Browse files
committed
MDEV-17694 Add method LEX::sp_proc_stmt_statement_finalize()
1 parent fde5386 commit 62bcd74

File tree

5 files changed

+75
-98
lines changed

5 files changed

+75
-98
lines changed

sql/sql_lex.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9470,3 +9470,59 @@ bool SELECT_LEX::make_unique_derived_name(THD *thd, LEX_CSTRING *alias)
94709470
alias->str= thd->strmake(buff, alias->length);
94719471
return !alias->str;
94729472
}
9473+
9474+
9475+
/*
9476+
Make a new sp_instr_stmt and set its m_query to a concatenation
9477+
of two strings.
9478+
*/
9479+
bool LEX::new_sp_instr_stmt(THD *thd,
9480+
const LEX_CSTRING &prefix,
9481+
const LEX_CSTRING &suffix)
9482+
{
9483+
LEX_STRING qbuff;
9484+
sp_instr_stmt *i;
9485+
9486+
if (!(i= new (thd->mem_root) sp_instr_stmt(sphead->instructions(),
9487+
spcont, this)))
9488+
return true;
9489+
9490+
qbuff.length= prefix.length + suffix.length;
9491+
if (!(qbuff.str= (char*) alloc_root(thd->mem_root, qbuff.length + 1)))
9492+
return true;
9493+
memcpy(qbuff.str, prefix.str, prefix.length);
9494+
strmake(qbuff.str + prefix.length, suffix.str, suffix.length);
9495+
i->m_query= qbuff;
9496+
return sphead->add_instr(i);
9497+
}
9498+
9499+
9500+
bool LEX::sp_proc_stmt_statement_finalize_buf(THD *thd, const LEX_CSTRING &qbuf)
9501+
{
9502+
sphead->m_flags|= sp_get_flags_for_command(this);
9503+
/* "USE db" doesn't work in a procedure */
9504+
if (unlikely(sql_command == SQLCOM_CHANGE_DB))
9505+
{
9506+
my_error(ER_SP_BADSTATEMENT, MYF(0), "USE");
9507+
return true;
9508+
}
9509+
/*
9510+
Don't add an instruction for SET statements, since all
9511+
instructions for them were already added during processing
9512+
of "set" rule.
9513+
*/
9514+
DBUG_ASSERT(sql_command != SQLCOM_SET_OPTION || var_list.is_empty());
9515+
if (sql_command != SQLCOM_SET_OPTION)
9516+
return new_sp_instr_stmt(thd, empty_clex_str, qbuf);
9517+
return false;
9518+
}
9519+
9520+
9521+
bool LEX::sp_proc_stmt_statement_finalize(THD *thd, bool no_lookahead)
9522+
{
9523+
// Extract the query statement from the tokenizer
9524+
Lex_input_stream *lip= &thd->m_parser_state->m_lip;
9525+
Lex_cstring qbuf(sphead->m_tmp_query, no_lookahead ? lip->get_ptr() :
9526+
lip->get_tok_start());
9527+
return LEX::sp_proc_stmt_statement_finalize_buf(thd, qbuf);
9528+
}

sql/sql_lex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3558,6 +3558,11 @@ struct LEX: public Query_tables_list
35583558
bool last_field_generated_always_as_row_end();
35593559
bool set_bincmp(CHARSET_INFO *cs, bool bin);
35603560

3561+
bool new_sp_instr_stmt(THD *, const LEX_CSTRING &prefix,
3562+
const LEX_CSTRING &suffix);
3563+
bool sp_proc_stmt_statement_finalize_buf(THD *, const LEX_CSTRING &qbuf);
3564+
bool sp_proc_stmt_statement_finalize(THD *, bool no_lookahead);
3565+
35613566
bool get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer);
35623567
bool prepared_stmt_params_fix_fields(THD *thd)
35633568
{

sql/sql_yacc.yy

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -553,42 +553,24 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead)
553553

554554
if (lex->sphead)
555555
{
556-
sp_head *sp= lex->sphead;
557-
558556
if (!lex->var_list.is_empty())
559557
{
560558
/*
561559
We have assignment to user or system variable or
562560
option setting, so we should construct sp_instr_stmt
563561
for it.
564562
*/
565-
LEX_STRING qbuff;
566-
sp_instr_stmt *i;
567563
Lex_input_stream *lip= &thd->m_parser_state->m_lip;
568564

569-
if (!(i= new (thd->mem_root)
570-
sp_instr_stmt(sp->instructions(), lex->spcont, lex)))
571-
return true;
572-
573565
/*
574566
Extract the query statement from the tokenizer. The
575567
end is either lip->ptr, if there was no lookahead,
576568
lip->tok_end otherwise.
577569
*/
578-
if (no_lookahead)
579-
qbuff.length= lip->get_ptr() - sp->m_tmp_query;
580-
else
581-
qbuff.length= lip->get_tok_end() - sp->m_tmp_query;
582-
583-
if (!(qbuff.str= (char*) alloc_root(thd->mem_root,
584-
qbuff.length + 5)))
585-
return true;
586-
587-
strmake(strmake(qbuff.str, "SET ", 4), sp->m_tmp_query,
588-
qbuff.length);
589-
qbuff.length+= 4;
590-
i->m_query= qbuff;
591-
if (sp->add_instr(i))
570+
static const LEX_CSTRING setsp= { STRING_WITH_LEN("SET ") };
571+
const char *qend= no_lookahead ? lip->get_ptr() : lip->get_tok_end();
572+
Lex_cstring qbuf(lex->sphead->m_tmp_query, qend);
573+
if (lex->new_sp_instr_stmt(thd, setsp, qbuf))
592574
return true;
593575
}
594576
lex->pop_select();
@@ -4157,44 +4139,8 @@ sp_proc_stmt_statement:
41574139
}
41584140
statement
41594141
{
4160-
LEX *lex= thd->lex;
4161-
Lex_input_stream *lip= YYLIP;
4162-
sp_head *sp= lex->sphead;
4163-
4164-
sp->m_flags|= sp_get_flags_for_command(lex);
4165-
/* "USE db" doesn't work in a procedure */
4166-
if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB))
4167-
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE"));
4168-
/*
4169-
Don't add an instruction for SET statements, since all
4170-
instructions for them were already added during processing
4171-
of "set" rule.
4172-
*/
4173-
DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION ||
4174-
lex->var_list.is_empty());
4175-
if (lex->sql_command != SQLCOM_SET_OPTION)
4176-
{
4177-
sp_instr_stmt *i=new (thd->mem_root)
4178-
sp_instr_stmt(sp->instructions(), lex->spcont, lex);
4179-
if (unlikely(i == NULL))
4180-
MYSQL_YYABORT;
4181-
4182-
/*
4183-
Extract the query statement from the tokenizer. The
4184-
end is either lex->ptr, if there was no lookahead,
4185-
lex->tok_end otherwise.
4186-
*/
4187-
if (yychar == YYEMPTY)
4188-
i->m_query.length= lip->get_ptr() - sp->m_tmp_query;
4189-
else
4190-
i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;;
4191-
if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root,
4192-
sp->m_tmp_query,
4193-
i->m_query.length))) ||
4194-
unlikely(sp->add_instr(i)))
4195-
MYSQL_YYABORT;
4196-
}
4197-
if (unlikely(sp->restore_lex(thd)))
4142+
if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) ||
4143+
Lex->sphead->restore_lex(thd))
41984144
MYSQL_YYABORT;
41994145
}
42004146
;

sql/sql_yacc_ora.yy

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4023,44 +4023,8 @@ sp_proc_stmt_statement:
40234023
}
40244024
sp_statement
40254025
{
4026-
LEX *lex= thd->lex;
4027-
Lex_input_stream *lip= YYLIP;
4028-
sp_head *sp= lex->sphead;
4029-
4030-
sp->m_flags|= sp_get_flags_for_command(lex);
4031-
/* "USE db" doesn't work in a procedure */
4032-
if (unlikely(lex->sql_command == SQLCOM_CHANGE_DB))
4033-
my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "USE"));
4034-
/*
4035-
Don't add an instruction for SET statements, since all
4036-
instructions for them were already added during processing
4037-
of "set" rule.
4038-
*/
4039-
DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION ||
4040-
lex->var_list.is_empty());
4041-
if (lex->sql_command != SQLCOM_SET_OPTION)
4042-
{
4043-
sp_instr_stmt *i=new (thd->mem_root)
4044-
sp_instr_stmt(sp->instructions(), lex->spcont, lex);
4045-
if (unlikely(i == NULL))
4046-
MYSQL_YYABORT;
4047-
4048-
/*
4049-
Extract the query statement from the tokenizer. The
4050-
end is either lex->ptr, if there was no lookahead,
4051-
lex->tok_end otherwise.
4052-
*/
4053-
if (yychar == YYEMPTY)
4054-
i->m_query.length= lip->get_ptr() - sp->m_tmp_query;
4055-
else
4056-
i->m_query.length= lip->get_tok_start() - sp->m_tmp_query;;
4057-
if (unlikely(!(i->m_query.str= strmake_root(thd->mem_root,
4058-
sp->m_tmp_query,
4059-
i->m_query.length))) ||
4060-
unlikely(sp->add_instr(i)))
4061-
MYSQL_YYABORT;
4062-
}
4063-
if (unlikely(sp->restore_lex(thd)))
4026+
if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) ||
4027+
Lex->sphead->restore_lex(thd))
40644028
MYSQL_YYABORT;
40654029
}
40664030
;

sql/vers_string.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ class Lex_cstring : public LEX_CSTRING
5858
str= _str;
5959
length= _len;
6060
}
61+
Lex_cstring(const char *start, const char *end)
62+
{
63+
DBUG_ASSERT(start <= end);
64+
str= start;
65+
length= end - start;
66+
}
6167
void set(const char *_str, size_t _len)
6268
{
6369
str= _str;

0 commit comments

Comments
 (0)