diff options
author | Marc Alff <marc.alff@sun.com> | 2008-07-14 15:41:30 -0600 |
---|---|---|
committer | Marc Alff <marc.alff@sun.com> | 2008-07-14 15:41:30 -0600 |
commit | e73e7bb9aec760edf7b142ac57696d44da149d86 (patch) | |
tree | 86658bba7f6c4fe4f438a97390da42762a277d3d /sql/sql_view.cc | |
parent | 0617cf0f78fd79e6cf109720f708b98b35e34ce3 (diff) | |
download | mariadb-git-e73e7bb9aec760edf7b142ac57696d44da149d86.tar.gz |
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
The crash was caused by freeing the internal parser stack during the parser
execution.
This occured only for complex stored procedures, after reallocating the parser
stack using my_yyoverflow(), with the following C call stack:
- MYSQLparse()
- any rule calling sp_head::restore_lex()
- lex_end()
- x_free(lex->yacc_yyss), xfree(lex->yacc_yyvs)
The root cause is the implementation of stored procedures, which breaks the
assumption from 4.1 that there is only one LEX structure per parser call.
The solution is to separate the LEX structure into:
- attributes that represent a statement (the current LEX structure),
- attributes that relate to the syntax parser itself (Yacc_state),
so that parsing multiple statements in stored programs can create multiple
LEX structures while not changing the unique Yacc_state.
Now, Yacc_state and the existing Lex_input_stream are aggregated into
Parser_state, a structure that represent the complete state of the (Lexical +
Syntax) parser.
mysql-test/r/parser_stack.result:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
mysql-test/t/parser_stack.test:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sp.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sp_head.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_class.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_class.h:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_lex.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_lex.h:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_parse.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_prepare.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_trigger.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_view.cc:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
sql/sql_yacc.yy:
Bug#35577 (CREATE PROCEDURE causes either crash or syntax error depending on
build)
Diffstat (limited to 'sql/sql_view.cc')
-rw-r--r-- | sql/sql_view.cc | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/sql/sql_view.cc b/sql/sql_view.cc index de92d6dc3b9..3b5fd6a085b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1081,8 +1081,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, char old_db_buf[NAME_LEN+1]; LEX_STRING old_db= { old_db_buf, sizeof(old_db_buf) }; bool dbchanged; - Lex_input_stream lip(thd, table->query.str, table->query.length); - thd->m_lip= &lip; + Parser_state parser_state(thd, table->query.str, table->query.length); /* Use view db name as thread default database, in order to ensure @@ -1091,6 +1090,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, if ((result= sp_use_new_db(thd, table->view_db, &old_db, 1, &dbchanged))) goto end; + thd->m_parser_state= &parser_state; lex_start(thd); view_select= &lex->select_lex; view_select->select_number= ++thd->select_number; @@ -1125,6 +1125,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, CHARSET_INFO *save_cs= thd->variables.character_set_client; thd->variables.character_set_client= system_charset_info; res= MYSQLparse((void *)thd); + thd->m_parser_state= NULL; if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) || (old_lex->sql_command == SQLCOM_SHOW_CREATE)) |