diff options
author | malff/marcsql@weblab.(none) <> | 2007-04-24 09:24:21 -0600 |
---|---|---|
committer | malff/marcsql@weblab.(none) <> | 2007-04-24 09:24:21 -0600 |
commit | fc809c70cc108b2f0cf0f0b32d9fdbb92d0b2f88 (patch) | |
tree | 03a6a80eee7a518f0f3fab0735e9514d4af88fe1 /sql/sql_lex.h | |
parent | 09cfc052f74b18ca31037a77f495eb5edeadabd4 (diff) | |
download | mariadb-git-fc809c70cc108b2f0cf0f0b32d9fdbb92d0b2f88.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.
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r-- | sql/sql_lex.h | 70 |
1 files changed, 55 insertions, 15 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h index de7de0d46e9..8a9bc62a83e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -469,7 +469,7 @@ public: void set_limit(st_select_lex *values); void set_thd(THD *thd_arg) { thd= thd_arg; } - friend void lex_start(THD *thd, uchar *buf, uint length); + friend void lex_start(THD *thd); friend int subselect_union_engine::exec(); List<Item> *get_unit_column_types(); @@ -675,7 +675,7 @@ public: void cut_subtree() { slave= 0; } bool test_limit(); - friend void lex_start(THD *thd, uchar *buf, uint length); + friend void lex_start(THD *thd); st_select_lex() : n_sum_items(0), n_child_sum_items(0) {} void make_empty_select() { @@ -898,30 +898,70 @@ struct st_parsing_options }; +/** + This class represents the character input stream consumed during + lexical analysis. +*/ +class Lex_input_stream +{ +public: + Lex_input_stream(THD *thd, const char* buff, unsigned int length); + ~Lex_input_stream(); + + /** Current thread. */ + THD *m_thd; + + /** Current line number. */ + uint yylineno; + + /** Length of the last token parsed. */ + uint yytoklen; + + /** Interface with bison, value of the last token parsed. */ + LEX_YYSTYPE yylval; + + /** Pointer to the current position in the input stream. */ + const char* ptr; + + /** Starting position of the last token parsed. */ + const char* tok_start; + + /** Ending position of the last token parsed. */ + const char* tok_end; + + /** End of the query text in the input stream. */ + const char* end_of_query; + + /** Starting position of the previous token parsed. */ + const char* tok_start_prev; + + /** Begining of the query text in the input stream. */ + const char* buf; + + /** Current state of the lexical analyser. */ + enum my_lex_states next_state; + + /** Position of ';' in the stream, to delimit multiple queries. */ + const char* found_semicolon; +}; + + /* The state of the lex parsing. This is saved in the THD struct */ typedef struct st_lex : public Query_tables_list { - uint yylineno,yytoklen; /* Simulate lex */ - LEX_YYSTYPE yylval; SELECT_LEX_UNIT unit; /* most upper unit */ SELECT_LEX select_lex; /* first SELECT_LEX */ /* current SELECT_LEX in parsing */ SELECT_LEX *current_select; /* list of all SELECT_LEX */ SELECT_LEX *all_selects_list; - uchar *buf; /* The beginning of string, used by SPs */ - uchar *ptr,*tok_start,*tok_end,*end_of_query; - - /* The values of tok_start/tok_end as they were one call of MYSQLlex before */ - uchar *tok_start_prev, *tok_end_prev; char *length,*dec,*change,*name; char *help_arg; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ char* x509_subject,*x509_issuer,*ssl_cipher; - char* found_semicolon; /* For multi queries - next query */ String *wild; sql_exchange *exchange; select_result *result; @@ -990,7 +1030,6 @@ typedef struct st_lex : public Query_tables_list enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option; enum SSL_type ssl_type; /* defined in violite.h */ - enum my_lex_states next_state; enum enum_duplicates duplicates; enum enum_tx_isolation tx_isolation; enum enum_ha_read_modes ha_read_mode; @@ -1101,8 +1140,9 @@ typedef struct st_lex : public Query_tables_list Pointers to part of LOAD DATA statement that should be rewritten during replication ("LOCAL 'filename' REPLACE INTO" part). */ - uchar *fname_start, *fname_end; - + const char *fname_start; + const char *fname_end; + bool escape_used; st_lex(); @@ -1211,7 +1251,7 @@ struct st_lex_local: public st_lex extern void lex_init(void); extern void lex_free(void); -extern void lex_start(THD *thd, uchar *buf,uint length); +extern void lex_start(THD *thd); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern uchar *skip_rear_comments(uchar *begin, uchar *end); +extern char *skip_rear_comments(char *begin, char *end); |