summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <malff/marcsql@weblab.(none)>2007-04-24 09:24:21 -0600
committerunknown <malff/marcsql@weblab.(none)>2007-04-24 09:24:21 -0600
commit3eff7d4dd5bba598fe055808697d630622fa249b (patch)
tree03a6a80eee7a518f0f3fab0735e9514d4af88fe1 /sql/sp_head.cc
parent52b86a6e0a9be6f3c41f24b9c30d2b6f885ad94f (diff)
downloadmariadb-git-3eff7d4dd5bba598fe055808697d630622fa249b.tar.gz
Bug#25411 (trigger code truncated), PART I
The issue found with bug 25411 is due to the function skip_rear_comments() which damages the source code while implementing a work around. The root cause of the problem is in the lexical analyser, which does not process special comments properly. For special comments like : [1] aaa /*!50000 bbb */ ccc since 5.0 is a version older that the current code, the parser is in lining the content of the special comment, so that the query to process is [2] aaa bbb ccc However, the text of the query captured when processing a stored procedure, stored function or trigger (or event in 5.1), can be after rebuilding it: [3] aaa bbb */ ccc which is wrong. To fix bug 25411 properly, the lexical analyser needs to return [2] when in lining special comments. In order to implement this, some preliminary cleanup is required in the code, which is implemented by this patch. Before this change, the structure named LEX (or st_lex) contains attributes that belong to lexical analysis, as well as attributes that represents the abstract syntax tree (AST) of a statement. Creating a new LEX structure for each statements (which makes sense for the AST part) also re-initialized the lexical analysis phase each time, which is conceptually wrong. With this patch, the previous st_lex structure has been split in two: - st_lex represents the Abstract Syntax Tree for a statement. The name "lex" has not been changed to avoid a bigger impact in the code base. - class lex_input_stream represents the internal state of the lexical analyser, which by definition should *not* be reinitialized when parsing multiple statements from the same input stream. This change is a pre-requisite for bug 25411, since the implementation of lex_input_stream will later improve to deal properly with special comments, and this processing can not be done with the current implementation of sp_head::reset_lex and sp_head::restore_lex, which interfere with the lexer. This change set alone does not fix bug 25411. sql/item_func.cc: Refactoring, separate lex_input_stream from st_lex. sql/log_event.cc: Refactoring, separate lex_input_stream from st_lex. sql/mysql_priv.h: Refactoring, separate lex_input_stream from st_lex. sql/slave.cc: Refactoring, separate lex_input_stream from st_lex. sql/sp.cc: Refactoring, separate lex_input_stream from st_lex. sql/sp_head.cc: Refactoring, separate lex_input_stream from st_lex. sql/sp_head.h: Refactoring, separate lex_input_stream from st_lex. sql/sql_class.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_class.h: Refactoring, separate lex_input_stream from st_lex. sql/sql_lex.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_lex.h: Refactoring, separate lex_input_stream from st_lex. sql/sql_parse.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_prepare.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_trigger.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_view.cc: Refactoring, separate lex_input_stream from st_lex. sql/sql_yacc.yy: Refactoring, separate lex_input_stream from st_lex.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc31
1 files changed, 9 insertions, 22 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 21225d82188..548a6c903dc 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -519,9 +519,10 @@ void
sp_head::init_strings(THD *thd, LEX *lex)
{
DBUG_ENTER("sp_head::init_strings");
- uchar *endp; /* Used to trim the end */
+ const char *endp; /* Used to trim the end */
/* During parsing, we must use thd->mem_root */
MEM_ROOT *root= thd->mem_root;
+ Lex_input_stream *lip=thd->m_lip;
if (m_param_begin && m_param_end)
{
@@ -531,17 +532,17 @@ sp_head::init_strings(THD *thd, LEX *lex)
}
/* If ptr has overrun end_of_query then end_of_query is the end */
- endp= (lex->ptr > lex->end_of_query ? lex->end_of_query : lex->ptr);
+ endp= (lip->ptr > lip->end_of_query ? lip->end_of_query : lip->ptr);
/*
Trim "garbage" at the end. This is sometimes needed with the
"/ * ! VERSION... * /" wrapper in dump files.
*/
- endp= skip_rear_comments(m_body_begin, endp);
+ endp= skip_rear_comments((char*) m_body_begin, (char*) endp);
m_body.length= endp - m_body_begin;
- m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length);
- m_defstr.length= endp - lex->buf;
- m_defstr.str= strmake_root(root, (char *)lex->buf, m_defstr.length);
+ m_body.str= strmake_root(root, m_body_begin, m_body.length);
+ m_defstr.length= endp - lip->buf;
+ m_defstr.str= strmake_root(root, lip->buf, m_defstr.length);
DBUG_VOID_RETURN;
}
@@ -1756,24 +1757,13 @@ sp_head::reset_lex(THD *thd)
DBUG_ENTER("sp_head::reset_lex");
LEX *sublex;
LEX *oldlex= thd->lex;
- my_lex_states org_next_state= oldlex->next_state;
(void)m_lex.push_front(oldlex);
thd->lex= sublex= new st_lex;
- /* Reset most stuff. The length arguments doesn't matter here. */
- lex_start(thd, oldlex->buf, (ulong) (oldlex->end_of_query - oldlex->ptr));
+ /* Reset most stuff. */
+ lex_start(thd);
- /*
- next_state is normally the same (0), but it happens that we swap lex in
- "mid-sentence", so we must restore it.
- */
- sublex->next_state= org_next_state;
- /* We must reset ptr and end_of_query again */
- sublex->ptr= oldlex->ptr;
- sublex->end_of_query= oldlex->end_of_query;
- sublex->tok_start= oldlex->tok_start;
- sublex->yylineno= oldlex->yylineno;
/* And keep the SP stuff too */
sublex->sphead= oldlex->sphead;
sublex->spcont= oldlex->spcont;
@@ -1806,9 +1796,6 @@ sp_head::restore_lex(THD *thd)
if (! oldlex)
return; // Nothing to restore
- // Update some state in the old one first
- oldlex->ptr= sublex->ptr;
- oldlex->next_state= sublex->next_state;
oldlex->trg_table_fields.push_back(&sublex->trg_table_fields);
/*