Commit 1ff91214 authored by anozdrin/alik@ibm's avatar anozdrin/alik@ibm

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.
parent 96f57c13
...@@ -1875,11 +1875,9 @@ Event_job_data::execute(THD *thd, bool drop) ...@@ -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, ...@@ -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); ...@@ -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
......
...@@ -384,15 +384,13 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ...@@ -384,15 +384,13 @@ 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);
}
thd->spcont= 0; if (parse_sql(thd, &lip) || newlex.sphead == NULL)
if (ret || thd->is_fatal_error || newlex.sphead == NULL)
{ {
sp_head *sp= newlex.sphead; sp_head *sp= newlex.sphead;
...@@ -410,6 +408,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, ...@@ -410,6 +408,8 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
(*sphp)->set_info(created, modified, &chistics, sql_mode); (*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize(); (*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() ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment