The second cleanup patch in scope of BUG#11986.
1. Introduce parse_sql() as a high-level replacement for MYSQLparse(). parse_sql() is responsible to switch and restore "parser context" (THD::m_lip for now). 2. Fix typo in sp.cc: THD::spcont should be reset *before* calling the parser. sql/event_data_objects.cc: Use parse_sql() instead of MYSQLparse(). sql/mysql_priv.h: Introduce parse_sql() instead of auto-generated MYSQLparse. sql/sp.cc: 1. Use parse_sql() instead of MYSQLparse(). 2. THD::spcont should be reset before calling the parser. sql/sql_class.cc: Reset THD::m_lip. sql/sql_parse.cc: 1. Introduce parse_sql() instead of auto-generated MYSQLparse(). 2. Backup, switch and restore THD::m_lip inside parse_sql(). 3. Use parse_sql() instead of MYSQLparse(). sql/sql_partition.cc: Use parse_sql() instead of MYSQLparse(). sql/sql_prepare.cc: Use parse_sql() instead of MYSQLparse(). sql/sql_trigger.cc: Use parse_sql() instead of MYSQLparse(). sql/sql_view.cc: Use parse_sql() instead of MYSQLparse().
This commit is contained in:
parent
e615aaff68
commit
efaaeecaa8
@ -1875,11 +1875,9 @@ Event_job_data::execute(THD *thd, bool drop)
|
|||||||
|
|
||||||
{
|
{
|
||||||
Lex_input_stream lip(thd, thd->query, thd->query_length);
|
Lex_input_stream lip(thd, thd->query, thd->query_length);
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
int err= MYSQLparse(thd);
|
|
||||||
|
|
||||||
if (err || thd->is_fatal_error)
|
if (parse_sql(thd, &lip))
|
||||||
{
|
{
|
||||||
sql_print_error("Event Scheduler: "
|
sql_print_error("Event Scheduler: "
|
||||||
"%serror during compilation of %s.%s",
|
"%serror during compilation of %s.%s",
|
||||||
|
@ -618,6 +618,8 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
|
|||||||
uint max_char_length, CHARSET_INFO *cs,
|
uint max_char_length, CHARSET_INFO *cs,
|
||||||
bool no_error);
|
bool no_error);
|
||||||
|
|
||||||
|
bool parse_sql(THD *thd, class Lex_input_stream *lip);
|
||||||
|
|
||||||
enum enum_mysql_completiontype {
|
enum enum_mysql_completiontype {
|
||||||
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
|
ROLLBACK_RELEASE=-2, ROLLBACK=1, ROLLBACK_AND_CHAIN=7,
|
||||||
COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6
|
COMMIT_RELEASE=-1, COMMIT=0, COMMIT_AND_CHAIN=6
|
||||||
@ -1953,7 +1955,6 @@ void free_list(I_List <i_string_pair> *list);
|
|||||||
void free_list(I_List <i_string> *list);
|
void free_list(I_List <i_string> *list);
|
||||||
|
|
||||||
/* sql_yacc.cc */
|
/* sql_yacc.cc */
|
||||||
extern int MYSQLparse(void *thd);
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
extern void turn_parser_debug_on();
|
extern void turn_parser_debug_on();
|
||||||
#endif
|
#endif
|
||||||
|
42
sql/sp.cc
42
sql/sp.cc
@ -384,32 +384,32 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
|
|||||||
if ((ret= sp_use_new_db(thd, name->m_db, &old_db, 1, &dbchanged)))
|
if ((ret= sp_use_new_db(thd, name->m_db, &old_db, 1, &dbchanged)))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
thd->spcont= NULL;
|
||||||
|
|
||||||
{
|
{
|
||||||
Lex_input_stream lip(thd, defstr.c_ptr(), defstr.length());
|
Lex_input_stream lip(thd, defstr.c_ptr(), defstr.length());
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
ret= MYSQLparse(thd);
|
|
||||||
|
if (parse_sql(thd, &lip) || newlex.sphead == NULL)
|
||||||
|
{
|
||||||
|
sp_head *sp= newlex.sphead;
|
||||||
|
|
||||||
|
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
|
||||||
|
goto end;
|
||||||
|
delete sp;
|
||||||
|
ret= SP_PARSE_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
|
||||||
|
goto end;
|
||||||
|
*sphp= newlex.sphead;
|
||||||
|
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
|
||||||
|
(*sphp)->set_info(created, modified, &chistics, sql_mode);
|
||||||
|
(*sphp)->optimize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->spcont= 0;
|
|
||||||
if (ret || thd->is_fatal_error || newlex.sphead == NULL)
|
|
||||||
{
|
|
||||||
sp_head *sp= newlex.sphead;
|
|
||||||
|
|
||||||
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
|
|
||||||
goto end;
|
|
||||||
delete sp;
|
|
||||||
ret= SP_PARSE_ERROR;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
|
|
||||||
goto end;
|
|
||||||
*sphp= newlex.sphead;
|
|
||||||
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
|
|
||||||
(*sphp)->set_info(created, modified, &chistics, sql_mode);
|
|
||||||
(*sphp)->optimize();
|
|
||||||
}
|
|
||||||
end:
|
end:
|
||||||
lex_end(thd->lex);
|
lex_end(thd->lex);
|
||||||
thd->spcont= old_spcont;
|
thd->spcont= old_spcont;
|
||||||
|
@ -342,7 +342,8 @@ THD::THD()
|
|||||||
in_lock_tables(0),
|
in_lock_tables(0),
|
||||||
bootstrap(0),
|
bootstrap(0),
|
||||||
derived_tables_processing(FALSE),
|
derived_tables_processing(FALSE),
|
||||||
spcont(NULL)
|
spcont(NULL),
|
||||||
|
m_lip(NULL)
|
||||||
{
|
{
|
||||||
ulong tmp;
|
ulong tmp;
|
||||||
|
|
||||||
|
@ -5343,12 +5343,11 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||||||
sp_cache_flush_obsolete(&thd->sp_func_cache);
|
sp_cache_flush_obsolete(&thd->sp_func_cache);
|
||||||
|
|
||||||
Lex_input_stream lip(thd, inBuf, length);
|
Lex_input_stream lip(thd, inBuf, length);
|
||||||
thd->m_lip= &lip;
|
|
||||||
|
|
||||||
int err= MYSQLparse(thd);
|
bool err= parse_sql(thd, &lip);
|
||||||
*found_semicolon= lip.found_semicolon;
|
*found_semicolon= lip.found_semicolon;
|
||||||
|
|
||||||
if (!err && ! thd->is_fatal_error)
|
if (!err)
|
||||||
{
|
{
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
if (mqh_used && thd->user_connect &&
|
if (mqh_used && thd->user_connect &&
|
||||||
@ -5371,8 +5370,8 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
|||||||
PROCESSLIST.
|
PROCESSLIST.
|
||||||
Note that we don't need LOCK_thread_count to modify query_length.
|
Note that we don't need LOCK_thread_count to modify query_length.
|
||||||
*/
|
*/
|
||||||
if (lip.found_semicolon &&
|
if (*found_semicolon &&
|
||||||
(thd->query_length= (ulong)(lip.found_semicolon - thd->query)))
|
(thd->query_length= (ulong)(*found_semicolon - thd->query)))
|
||||||
thd->query_length--;
|
thd->query_length--;
|
||||||
/* Actually execute the query */
|
/* Actually execute the query */
|
||||||
mysql_execute_command(thd);
|
mysql_execute_command(thd);
|
||||||
@ -5426,12 +5425,10 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length)
|
|||||||
DBUG_ENTER("mysql_test_parse_for_slave");
|
DBUG_ENTER("mysql_test_parse_for_slave");
|
||||||
|
|
||||||
Lex_input_stream lip(thd, inBuf, length);
|
Lex_input_stream lip(thd, inBuf, length);
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
mysql_reset_thd_for_next_command(thd);
|
mysql_reset_thd_for_next_command(thd);
|
||||||
int err= MYSQLparse((void*) thd);
|
|
||||||
|
|
||||||
if (!err && ! thd->is_fatal_error &&
|
if (!parse_sql(thd, &lip) &&
|
||||||
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
|
all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first))
|
||||||
error= 1; /* Ignore question */
|
error= 1; /* Ignore question */
|
||||||
thd->end_statement();
|
thd->end_statement();
|
||||||
@ -7123,3 +7120,34 @@ bool check_string_char_length(LEX_STRING *str, const char *err_msg,
|
|||||||
my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
|
my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int MYSQLparse(void *thd); // from sql_yacc.cc
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
This is a wrapper of MYSQLparse(). All the code should call parse_sql()
|
||||||
|
instead of MYSQLparse().
|
||||||
|
|
||||||
|
@param thd Thread context.
|
||||||
|
@param lip Lexer context.
|
||||||
|
|
||||||
|
@return Error status.
|
||||||
|
@retval FALSE on success.
|
||||||
|
@retval TRUE on parsing error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool parse_sql(THD *thd, Lex_input_stream *lip)
|
||||||
|
{
|
||||||
|
bool err_status;
|
||||||
|
|
||||||
|
DBUG_ASSERT(thd->m_lip == NULL);
|
||||||
|
|
||||||
|
thd->m_lip= lip;
|
||||||
|
|
||||||
|
err_status= MYSQLparse(thd) != 0 || thd->is_fatal_error;
|
||||||
|
|
||||||
|
thd->m_lip= NULL;
|
||||||
|
|
||||||
|
return err_status;
|
||||||
|
}
|
||||||
|
@ -3696,7 +3696,6 @@ bool mysql_unpack_partition(THD *thd,
|
|||||||
thd->variables.character_set_client= system_charset_info;
|
thd->variables.character_set_client= system_charset_info;
|
||||||
|
|
||||||
Lex_input_stream lip(thd, part_buf, part_info_len);
|
Lex_input_stream lip(thd, part_buf, part_info_len);
|
||||||
thd->m_lip= &lip;
|
|
||||||
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
/*
|
/*
|
||||||
@ -3725,7 +3724,7 @@ bool mysql_unpack_partition(THD *thd,
|
|||||||
lex.part_info->part_state= part_state;
|
lex.part_info->part_state= part_state;
|
||||||
lex.part_info->part_state_len= part_state_len;
|
lex.part_info->part_state_len= part_state_len;
|
||||||
DBUG_PRINT("info", ("Parse: %s", part_buf));
|
DBUG_PRINT("info", ("Parse: %s", part_buf));
|
||||||
if (MYSQLparse((void*)thd) || thd->is_fatal_error)
|
if (parse_sql(thd, &lip))
|
||||||
{
|
{
|
||||||
thd->free_items();
|
thd->free_items();
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -2858,12 +2858,11 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
|
|
||||||
Lex_input_stream lip(thd, thd->query, thd->query_length);
|
Lex_input_stream lip(thd, thd->query, thd->query_length);
|
||||||
lip.stmt_prepare_mode= TRUE;
|
lip.stmt_prepare_mode= TRUE;
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
int err= MYSQLparse((void *)thd);
|
|
||||||
|
|
||||||
error= err || thd->is_fatal_error ||
|
error= parse_sql(thd, &lip) ||
|
||||||
thd->net.report_error || init_param_array(this);
|
thd->net.report_error ||
|
||||||
|
init_param_array(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
While doing context analysis of the query (in check_prepared_statement)
|
While doing context analysis of the query (in check_prepared_statement)
|
||||||
|
@ -981,12 +981,10 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
|
|||||||
thd->variables.sql_mode= (ulong)*trg_sql_mode;
|
thd->variables.sql_mode= (ulong)*trg_sql_mode;
|
||||||
|
|
||||||
Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
|
Lex_input_stream lip(thd, trg_create_str->str, trg_create_str->length);
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
thd->spcont= 0;
|
thd->spcont= 0;
|
||||||
int err= MYSQLparse((void *)thd);
|
|
||||||
|
|
||||||
if (err || thd->is_fatal_error)
|
if (parse_sql(thd, &lip))
|
||||||
{
|
{
|
||||||
/* Currently sphead is always deleted in case of a parse error */
|
/* Currently sphead is always deleted in case of a parse error */
|
||||||
DBUG_ASSERT(lex.sphead == 0);
|
DBUG_ASSERT(lex.sphead == 0);
|
||||||
|
@ -893,7 +893,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
LEX *old_lex, *lex;
|
LEX *old_lex, *lex;
|
||||||
Query_arena *arena, backup;
|
Query_arena *arena, backup;
|
||||||
TABLE_LIST *top_view= table->top_table();
|
TABLE_LIST *top_view= table->top_table();
|
||||||
int res;
|
bool res;
|
||||||
bool result, view_is_mergeable;
|
bool result, view_is_mergeable;
|
||||||
TABLE_LIST *view_main_select_tables;
|
TABLE_LIST *view_main_select_tables;
|
||||||
DBUG_ENTER("mysql_make_view");
|
DBUG_ENTER("mysql_make_view");
|
||||||
@ -1005,7 +1005,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
|
|
||||||
{
|
{
|
||||||
Lex_input_stream lip(thd, table->query.str, table->query.length);
|
Lex_input_stream lip(thd, table->query.str, table->query.length);
|
||||||
thd->m_lip= &lip;
|
|
||||||
lex_start(thd);
|
lex_start(thd);
|
||||||
view_select= &lex->select_lex;
|
view_select= &lex->select_lex;
|
||||||
view_select->select_number= ++thd->select_number;
|
view_select->select_number= ++thd->select_number;
|
||||||
@ -1039,7 +1038,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
|
MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
|
||||||
CHARSET_INFO *save_cs= thd->variables.character_set_client;
|
CHARSET_INFO *save_cs= thd->variables.character_set_client;
|
||||||
thd->variables.character_set_client= system_charset_info;
|
thd->variables.character_set_client= system_charset_info;
|
||||||
res= MYSQLparse((void *)thd);
|
res= parse_sql(thd, &lip);
|
||||||
|
|
||||||
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
|
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
|
||||||
(old_lex->sql_command == SQLCOM_SHOW_CREATE))
|
(old_lex->sql_command == SQLCOM_SHOW_CREATE))
|
||||||
@ -1048,7 +1047,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
|||||||
thd->variables.character_set_client= save_cs;
|
thd->variables.character_set_client= save_cs;
|
||||||
thd->variables.sql_mode= save_mode;
|
thd->variables.sql_mode= save_mode;
|
||||||
}
|
}
|
||||||
if (!res && !thd->is_fatal_error)
|
if (!res)
|
||||||
{
|
{
|
||||||
TABLE_LIST *view_tables= lex->query_tables;
|
TABLE_LIST *view_tables= lex->query_tables;
|
||||||
TABLE_LIST *view_tables_tail= 0;
|
TABLE_LIST *view_tables_tail= 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user