diff options
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r-- | sql/sql_lex.h | 727 |
1 files changed, 639 insertions, 88 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h index bfa6c05974f..b769930958e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -24,7 +24,11 @@ class sp_head; class sp_name; class sp_instr; class sp_pcontext; +class st_alter_tablespace; +class partition_info; +class Event_parse_data; +#ifdef MYSQL_SERVER /* The following hack is needed because mysql_yacc.cc does not define YYSTYPE before including this file @@ -43,10 +47,16 @@ class sp_pcontext; #define LEX_YYSTYPE void * #endif #endif +#endif /* When a command is added here, be sure it's also added in mysqld.cc in "struct show_var_st status_vars[]= {" ... + + If the command returns a result set or is not allowed in stored + functions or triggers, please also make sure that + sp_get_flags_for_command (sp_head.cc) returns proper flags for the + added SQLCOM_. */ enum enum_sql_command { @@ -55,8 +65,8 @@ enum enum_sql_command { SQLCOM_DELETE, SQLCOM_TRUNCATE, SQLCOM_DROP_TABLE, SQLCOM_DROP_INDEX, SQLCOM_SHOW_DATABASES, SQLCOM_SHOW_TABLES, SQLCOM_SHOW_FIELDS, - SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_LOGS, SQLCOM_SHOW_STATUS, - SQLCOM_SHOW_INNODB_STATUS, SQLCOM_SHOW_NDBCLUSTER_STATUS, SQLCOM_SHOW_MUTEX_STATUS, + SQLCOM_SHOW_KEYS, SQLCOM_SHOW_VARIABLES, SQLCOM_SHOW_STATUS, + SQLCOM_SHOW_ENGINE_LOGS, SQLCOM_SHOW_ENGINE_STATUS, SQLCOM_SHOW_ENGINE_MUTEX, SQLCOM_SHOW_PROCESSLIST, SQLCOM_SHOW_MASTER_STAT, SQLCOM_SHOW_SLAVE_STAT, SQLCOM_SHOW_GRANTS, SQLCOM_SHOW_CREATE, SQLCOM_SHOW_CHARSETS, SQLCOM_SHOW_COLLATIONS, SQLCOM_SHOW_CREATE_DB, SQLCOM_SHOW_TABLE_STATUS, @@ -65,6 +75,7 @@ enum enum_sql_command { SQLCOM_LOAD,SQLCOM_SET_OPTION,SQLCOM_LOCK_TABLES,SQLCOM_UNLOCK_TABLES, SQLCOM_GRANT, SQLCOM_CHANGE_DB, SQLCOM_CREATE_DB, SQLCOM_DROP_DB, SQLCOM_ALTER_DB, + SQLCOM_RENAME_DB, SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, @@ -94,6 +105,16 @@ enum enum_sql_command { SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE, SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER, SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE, + SQLCOM_ALTER_TABLESPACE, + SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN, + SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT, + SQLCOM_SHOW_PLUGINS, + SQLCOM_SHOW_CONTRIBUTORS, + SQLCOM_CREATE_SERVER, SQLCOM_DROP_SERVER, SQLCOM_ALTER_SERVER, + SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT, + SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS, + SQLCOM_SHOW_CREATE_TRIGGER, + /* This should be the last !!! */ SQLCOM_END @@ -102,6 +123,13 @@ enum enum_sql_command { // describe/explain types #define DESCRIBE_NORMAL 1 #define DESCRIBE_EXTENDED 2 +/* + This is not within #ifdef because we want "EXPLAIN PARTITIONS ..." to produce + additional "partitions" column even if partitioning is not compiled in. +*/ +#define DESCRIBE_PARTITIONS 4 + +#ifdef MYSQL_SERVER enum enum_sp_suid_behaviour { @@ -121,11 +149,11 @@ enum enum_sp_data_access const LEX_STRING sp_data_access_name[]= { - { (char*) STRING_WITH_LEN("") }, - { (char*) STRING_WITH_LEN("CONTAINS SQL") }, - { (char*) STRING_WITH_LEN("NO SQL") }, - { (char*) STRING_WITH_LEN("READS SQL DATA") }, - { (char*) STRING_WITH_LEN("MODIFIES SQL DATA") } + { C_STRING_WITH_LEN("") }, + { C_STRING_WITH_LEN("CONTAINS SQL") }, + { C_STRING_WITH_LEN("NO SQL") }, + { C_STRING_WITH_LEN("READS SQL DATA") }, + { C_STRING_WITH_LEN("MODIFIES SQL DATA") } }; #define DERIVED_SUBQUERY 1 @@ -147,18 +175,26 @@ enum enum_drop_mode typedef List<Item> List_item; +/* SERVERS CACHE CHANGES */ +typedef struct st_lex_server_options +{ + long port; + uint server_name_length; + char *server_name, *host, *db, *username, *password, *scheme, *socket, *owner; +} LEX_SERVER_OPTIONS; + typedef struct st_lex_master_info { char *host, *user, *password, *log_file_name; uint port, connect_retry; ulonglong pos; ulong server_id; - /* - Variable for MASTER_SSL option. - MASTER_SSL=0 in CHANGE MASTER TO corresponds to SSL_DISABLE - MASTER_SSL=1 corresponds to SSL_ENABLE - */ - enum {SSL_UNCHANGED=0, SSL_DISABLE, SSL_ENABLE} ssl; + /* + Enum is used for making it possible to detect if the user + changed variable or if it should be left at old value + */ + enum {SSL_UNCHANGED, SSL_DISABLE, SSL_ENABLE} + ssl, ssl_verify_server_cert; char *ssl_key, *ssl_cert, *ssl_ca, *ssl_capath, *ssl_cipher; char *relay_log_name; ulong relay_log_pos; @@ -182,6 +218,47 @@ enum tablespace_op_type }; /* + String names used to print a statement with index hints. + Keep in sync with index_hint_type. +*/ +extern const char * index_hint_type_name[]; +typedef uchar index_clause_map; + +/* + Bits in index_clause_map : one for each possible FOR clause in + USE/FORCE/IGNORE INDEX index hint specification +*/ +#define INDEX_HINT_MASK_JOIN (1) +#define INDEX_HINT_MASK_GROUP (1 << 1) +#define INDEX_HINT_MASK_ORDER (1 << 2) + +#define INDEX_HINT_MASK_ALL (INDEX_HINT_MASK_JOIN | INDEX_HINT_MASK_GROUP | \ + INDEX_HINT_MASK_ORDER) + +/* Single element of an USE/FORCE/IGNORE INDEX list specified as a SQL hint */ +class Index_hint : public Sql_alloc +{ +public: + /* The type of the hint : USE/FORCE/IGNORE */ + enum index_hint_type type; + /* Where the hit applies to. A bitmask of INDEX_HINT_MASK_<place> values */ + index_clause_map clause; + /* + The index name. Empty (str=NULL) name represents an empty list + USE INDEX () clause + */ + LEX_STRING key_name; + + Index_hint (enum index_hint_type type_arg, index_clause_map clause_arg, + char *str, uint length) : + type(type_arg), clause(clause_arg) + { + key_name.str= str; + key_name.length= length; + } +}; + +/* The state of the lex parsing for selects master and slaves are pointers to select_lex. @@ -333,7 +410,7 @@ public: static void *operator new(size_t size) { - return (void*) sql_alloc((uint) size); + return sql_alloc(size); } static void *operator new(size_t size, MEM_ROOT *mem_root) { return (void*) alloc_root(mem_root, (uint) size); } @@ -359,15 +436,12 @@ public: virtual uint get_in_sum_expr(); virtual TABLE_LIST* get_table_list(); virtual List<Item>* get_item_list(); - virtual List<String>* get_use_index(); - virtual List<String>* get_ignore_index(); virtual ulong get_table_join_options(); virtual TABLE_LIST *add_table_to_list(THD *thd, Table_ident *table, LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, - List<String> *use_index= 0, - List<String> *ignore_index= 0, + List<Index_hint> *hints= 0, LEX_STRING *option= 0); virtual void set_lock_for_tables(thr_lock_type lock_type) {} @@ -498,8 +572,7 @@ public: SQL_LIST table_list; SQL_LIST group_list; /* GROUP BY clause. */ List<Item> item_list; /* list of fields & expressions */ - List<String> interval_list, use_index, *use_index_ptr, - ignore_index, *ignore_index_ptr; + List<String> interval_list; bool is_item_list_lookup; /* Usualy it is pointer to ftfunc_list_alloc, but in union used to create fake @@ -610,7 +683,6 @@ public: joins on the right. */ List<String> *prev_join_using; - void init_query(); void init_select(); st_select_lex_unit* master_unit(); @@ -647,8 +719,7 @@ public: LEX_STRING *alias, ulong table_options, thr_lock_type flags= TL_UNLOCK, - List<String> *use_index= 0, - List<String> *ignore_index= 0, + List<Index_hint> *hints= 0, LEX_STRING *option= 0); TABLE_LIST* get_table_list(); bool init_nested_join(THD *thd); @@ -657,15 +728,13 @@ public: void add_joined_table(TABLE_LIST *table); TABLE_LIST *convert_right_join(); List<Item>* get_item_list(); - List<String>* get_use_index(); - List<String>* get_ignore_index(); ulong get_table_join_options(); void set_lock_for_tables(thr_lock_type lock_type); inline void init_order() { order_list.elements= 0; order_list.first= 0; - order_list.next= (byte**) &order_list.first; + order_list.next= (uchar**) &order_list.first; } /* This method created for reiniting LEX in mysql_admin_table() and can be @@ -698,28 +767,76 @@ public: select lexes. */ void cleanup_all_joins(bool full); + + void set_index_hint_type(enum index_hint_type type, index_clause_map clause); + + /* + Add a index hint to the tagged list of hints. The type and clause of the + hint will be the current ones (set by set_index_hint()) + */ + bool add_index_hint (THD *thd, char *str, uint length); + + /* make a list to hold index hints */ + void alloc_index_hints (THD *thd); + /* read and clear the index hints */ + List<Index_hint>* pop_index_hints(void) + { + List<Index_hint> *hints= index_hints; + index_hints= NULL; + return hints; + } + + void clear_index_hints(void) { index_hints= NULL; } + +private: + /* current index hint kind. used in filling up index_hints */ + enum index_hint_type current_index_hint_type; + index_clause_map current_index_hint_clause; + /* a list of USE/FORCE/IGNORE INDEX */ + List<Index_hint> *index_hints; }; typedef class st_select_lex SELECT_LEX; - inline bool st_select_lex_unit::is_union () { return first_select()->next_select() && first_select()->next_select()->linkage == UNION_TYPE; } -#define ALTER_ADD_COLUMN 1 -#define ALTER_DROP_COLUMN 2 -#define ALTER_CHANGE_COLUMN 4 -#define ALTER_ADD_INDEX 8 -#define ALTER_DROP_INDEX 16 -#define ALTER_RENAME 32 -#define ALTER_ORDER 64 -#define ALTER_OPTIONS 128 -#define ALTER_CHANGE_COLUMN_DEFAULT 256 -#define ALTER_KEYS_ONOFF 512 -#define ALTER_CONVERT 1024 -#define ALTER_FORCE 2048 +#define ALTER_ADD_COLUMN (1L << 0) +#define ALTER_DROP_COLUMN (1L << 1) +#define ALTER_CHANGE_COLUMN (1L << 2) +#define ALTER_ADD_INDEX (1L << 3) +#define ALTER_DROP_INDEX (1L << 4) +#define ALTER_RENAME (1L << 5) +#define ALTER_ORDER (1L << 6) +#define ALTER_OPTIONS (1L << 7) +#define ALTER_CHANGE_COLUMN_DEFAULT (1L << 8) +#define ALTER_KEYS_ONOFF (1L << 9) +#define ALTER_CONVERT (1L << 10) +#define ALTER_FORCE (1L << 11) +#define ALTER_RECREATE (1L << 12) +#define ALTER_ADD_PARTITION (1L << 13) +#define ALTER_DROP_PARTITION (1L << 14) +#define ALTER_COALESCE_PARTITION (1L << 15) +#define ALTER_REORGANIZE_PARTITION (1L << 16) +#define ALTER_PARTITION (1L << 17) +#define ALTER_OPTIMIZE_PARTITION (1L << 18) +#define ALTER_TABLE_REORG (1L << 19) +#define ALTER_REBUILD_PARTITION (1L << 20) +#define ALTER_ALL_PARTITION (1L << 21) +#define ALTER_ANALYZE_PARTITION (1L << 22) +#define ALTER_CHECK_PARTITION (1L << 23) +#define ALTER_REPAIR_PARTITION (1L << 24) +#define ALTER_REMOVE_PARTITIONING (1L << 25) +#define ALTER_FOREIGN_KEY (1L << 26) + +enum enum_alter_table_change_level +{ + ALTER_TABLE_METADATA_ONLY= 0, + ALTER_TABLE_DATA_CHANGED= 1, + ALTER_TABLE_INDEX_CHANGED= 2 +}; /** @brief Parsing data for CREATE or ALTER TABLE. @@ -731,18 +848,28 @@ inline bool st_select_lex_unit::is_union () class Alter_info { public: - List<Alter_drop> drop_list; - List<Alter_column> alter_list; - List<Key> key_list; - List<create_field> create_list; - uint flags; - enum enum_enable_or_disable keys_onoff; - enum tablespace_op_type tablespace_op; + List<Alter_drop> drop_list; + List<Alter_column> alter_list; + List<Key> key_list; + List<Create_field> create_list; + uint flags; + enum enum_enable_or_disable keys_onoff; + enum tablespace_op_type tablespace_op; + List<char> partition_names; + uint no_parts; + enum_alter_table_change_level change_level; + Create_field *datetime_field; + bool error_if_not_empty; + Alter_info() : flags(0), keys_onoff(LEAVE_AS_IS), - tablespace_op(NO_TABLESPACE_OP) + tablespace_op(NO_TABLESPACE_OP), + no_parts(0), + change_level(ALTER_TABLE_METADATA_ONLY), + datetime_field(NULL), + error_if_not_empty(FALSE) {} void reset() @@ -754,6 +881,11 @@ public: flags= 0; keys_onoff= LEAVE_AS_IS; tablespace_op= NO_TABLESPACE_OP; + no_parts= 0; + partition_names.empty(); + change_level= ALTER_TABLE_METADATA_ONLY; + datetime_field= 0; + error_if_not_empty= FALSE; } /** Construct a copy of this object to be used for mysql_alter_table @@ -761,11 +893,8 @@ public: their Alter_info arguments. This behaviour breaks re-execution of prepared statements and stored procedures and is compensated by always supplying a copy of Alter_info to these functions. - The constructed copy still shares key Key, Alter_drop, create_field - and Alter_column elements of the lists - these structures are not - modified and thus are not copied. - @note You need to use check thd->is_fatal_error for out + @return You need to use check the error in THD for out of memory condition after calling this function. */ Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root); @@ -789,7 +918,7 @@ struct st_trg_chistics enum trg_event_type event; }; -extern sys_var_long_ptr trg_new_row_fake_var; +extern sys_var *trg_new_row_fake_var; enum xa_option_words {XA_NONE, XA_JOIN, XA_RESUME, XA_ONE_PHASE, XA_SUSPEND, XA_FOR_MIGRATE}; @@ -836,7 +965,7 @@ public: in which it was right after query parsing. */ SQL_LIST sroutines_list; - byte **sroutines_list_own_last; + uchar **sroutines_list_own_last; uint sroutines_list_own_elements; /* @@ -886,12 +1015,48 @@ public: query_tables_own_last= 0; } } + + /** + Has the parser/scanner detected that this statement is unsafe? + */ + inline bool is_stmt_unsafe() const { + return binlog_stmt_flags & (1U << BINLOG_STMT_FLAG_UNSAFE); + } + + /** + Flag the current (top-level) statement as unsafe. + + The flag will be reset after the statement has finished. + + */ + inline void set_stmt_unsafe() { + binlog_stmt_flags|= (1U << BINLOG_STMT_FLAG_UNSAFE); + } + + inline void clear_stmt_unsafe() { + binlog_stmt_flags&= ~(1U << BINLOG_STMT_FLAG_UNSAFE); + } + /** true if the parsed tree contains references to stored procedures or functions, false otherwise */ bool uses_stored_routines() const { return sroutines_list.elements != 0; } + +private: + enum enum_binlog_stmt_flag { + BINLOG_STMT_FLAG_UNSAFE, + BINLOG_STMT_FLAG_COUNT + }; + + /* + Tells if the parsing stage detected properties of the statement, + for example: that some items require row-based binlogging to give + a reliable binlog/replication, or if we will use stored functions + or triggers which themselves need require row-based binlogging. + */ + uint32 binlog_stmt_flags; }; @@ -913,8 +1078,40 @@ struct st_parsing_options /** + The state of the lexical parser, when parsing comments. +*/ +enum enum_comment_state +{ + /** + Not parsing comments. + */ + NO_COMMENT, + /** + Parsing comments that need to be preserved. + Typically, these are user comments '/' '*' ... '*' '/'. + */ + PRESERVE_COMMENT, + /** + Parsing comments that need to be discarded. + Typically, these are special comments '/' '*' '!' ... '*' '/', + or '/' '*' '!' 'M' 'M' 'm' 'm' 'm' ... '*' '/', where the comment + markers should not be expanded. + */ + DISCARD_COMMENT +}; + + +/** This class represents the character input stream consumed during lexical analysis. + In addition to consuming the input stream, this class performs some + comment pre processing, by filtering out out of bound special text + from the query input stream. + Two buffers, with pointers inside each buffers, are maintained in + parallel. The 'raw' buffer is the original query text, which may + contain out-of-bound comments. The 'cpp' (for comments pre processor) + is the pre-processed buffer that contains only the query text that + should be seen once out-of-bound data is removed. */ class Lex_input_stream { @@ -922,6 +1119,238 @@ public: Lex_input_stream(THD *thd, const char* buff, unsigned int length); ~Lex_input_stream(); + /** + Set the echo mode. + When echo is true, characters parsed from the raw input stream are + preserved. When false, characters parsed are silently ignored. + @param echo the echo mode. + */ + void set_echo(bool echo) + { + m_echo= echo; + } + + /** + Skip binary from the input stream. + @param n number of bytes to accept. + */ + void skip_binary(int n) + { + if (m_echo) + { + memcpy(m_cpp_ptr, m_ptr, n); + m_cpp_ptr += n; + } + m_ptr += n; + } + + /** + Get a character, and advance in the stream. + @return the next character to parse. + */ + char yyGet() + { + char c= *m_ptr++; + if (m_echo) + *m_cpp_ptr++ = c; + return c; + } + + /** + Get the last character accepted. + @return the last character accepted. + */ + char yyGetLast() + { + return m_ptr[-1]; + } + + /** + Look at the next character to parse, but do not accept it. + */ + char yyPeek() + { + return m_ptr[0]; + } + + /** + Look ahead at some character to parse. + @param n offset of the character to look up + */ + char yyPeekn(int n) + { + return m_ptr[n]; + } + + /** + Cancel the effect of the last yyGet() or yySkip(). + Note that the echo mode should not change between calls to yyGet / yySkip + and yyUnget. The caller is responsible for ensuring that. + */ + void yyUnget() + { + m_ptr--; + if (m_echo) + m_cpp_ptr--; + } + + /** + Accept a character, by advancing the input stream. + */ + void yySkip() + { + if (m_echo) + *m_cpp_ptr++ = *m_ptr++; + else + m_ptr++; + } + + /** + Accept multiple characters at once. + @param n the number of characters to accept. + */ + void yySkipn(int n) + { + if (m_echo) + { + memcpy(m_cpp_ptr, m_ptr, n); + m_cpp_ptr += n; + } + m_ptr += n; + } + + /** + End of file indicator for the query text to parse. + @return true if there are no more characters to parse + */ + bool eof() + { + return (m_ptr >= m_end_of_query); + } + + /** + End of file indicator for the query text to parse. + @param n number of characters expected + @return true if there are less than n characters to parse + */ + bool eof(int n) + { + return ((m_ptr + n) >= m_end_of_query); + } + + /** Get the raw query buffer. */ + const char *get_buf() + { + return m_buf; + } + + /** Get the pre-processed query buffer. */ + const char *get_cpp_buf() + { + return m_cpp_buf; + } + + /** Get the end of the raw query buffer. */ + const char *get_end_of_query() + { + return m_end_of_query; + } + + /** Mark the stream position as the start of a new token. */ + void start_token() + { + m_tok_start_prev= m_tok_start; + m_tok_start= m_ptr; + m_tok_end= m_ptr; + + m_cpp_tok_start_prev= m_cpp_tok_start; + m_cpp_tok_start= m_cpp_ptr; + m_cpp_tok_end= m_cpp_ptr; + } + + /** + Adjust the starting position of the current token. + This is used to compensate for starting whitespace. + */ + void restart_token() + { + m_tok_start= m_ptr; + m_cpp_tok_start= m_cpp_ptr; + } + + /** Get the token start position, in the raw buffer. */ + const char *get_tok_start() + { + return m_tok_start; + } + + /** Get the token start position, in the pre-processed buffer. */ + const char *get_cpp_tok_start() + { + return m_cpp_tok_start; + } + + /** Get the token end position, in the raw buffer. */ + const char *get_tok_end() + { + return m_tok_end; + } + + /** Get the token end position, in the pre-processed buffer. */ + const char *get_cpp_tok_end() + { + return m_cpp_tok_end; + } + + /** Get the previous token start position, in the raw buffer. */ + const char *get_tok_start_prev() + { + return m_tok_start_prev; + } + + /** Get the current stream pointer, in the raw buffer. */ + const char *get_ptr() + { + return m_ptr; + } + + /** Get the current stream pointer, in the pre-processed buffer. */ + const char *get_cpp_ptr() + { + return m_cpp_ptr; + } + + /** Get the length of the current token, in the raw buffer. */ + uint yyLength() + { + /* + The assumption is that the lexical analyser is always 1 character ahead, + which the -1 account for. + */ + DBUG_ASSERT(m_ptr > m_tok_start); + return (uint) ((m_ptr - m_tok_start) - 1); + } + + /** Get the utf8-body string. */ + const char *get_body_utf8_str() + { + return m_body_utf8; + } + + /** Get the utf8-body length. */ + uint get_body_utf8_length() + { + return m_body_utf8_ptr - m_body_utf8; + } + + void body_utf8_start(THD *thd, const char *begin_ptr); + void body_utf8_append(const char *ptr); + void body_utf8_append(const char *ptr, const char *end_ptr); + void body_utf8_append_literal(THD *thd, + const LEX_STRING *txt, + CHARSET_INFO *txt_cs, + const char *end_ptr); + /** Current thread. */ THD *m_thd; @@ -934,37 +1363,112 @@ public: /** Interface with bison, value of the last token parsed. */ LEX_YYSTYPE yylval; - /** Pointer to the current position in the input stream. */ - const char* ptr; +private: + /** Pointer to the current position in the raw input stream. */ + const char *m_ptr; + + /** Starting position of the last token parsed, in the raw buffer. */ + const char *m_tok_start; + + /** Ending position of the previous token parsed, in the raw buffer. */ + const char *m_tok_end; + + /** End of the query text in the input stream, in the raw buffer. */ + const char *m_end_of_query; + + /** Starting position of the previous token parsed, in the raw buffer. */ + const char *m_tok_start_prev; + + /** Begining of the query text in the input stream, in the raw buffer. */ + const char *m_buf; + + /** Length of the raw buffer. */ + uint m_buf_length; + + /** Echo the parsed stream to the pre-processed buffer. */ + bool m_echo; + + /** Pre-processed buffer. */ + char *m_cpp_buf; + + /** Pointer to the current position in the pre-processed input stream. */ + char *m_cpp_ptr; + + /** + Starting position of the last token parsed, + in the pre-processed buffer. + */ + const char *m_cpp_tok_start; + + /** + Starting position of the previous token parsed, + in the pre-procedded buffer. + */ + const char *m_cpp_tok_start_prev; - /** Starting position of the last token parsed. */ - const char* tok_start; + /** + Ending position of the previous token parsed, + in the pre-processed buffer. + */ + const char *m_cpp_tok_end; - /** Ending position of the last token parsed. */ - const char* tok_end; + /** UTF8-body buffer created during parsing. */ + char *m_body_utf8; - /** End of the query text in the input stream. */ - const char* end_of_query; + /** Pointer to the current position in the UTF8-body buffer. */ + char *m_body_utf8_ptr; - /** Starting position of the previous token parsed. */ - const char* tok_start_prev; + /** + Position in the pre-processed buffer. The query from m_cpp_buf to + m_cpp_utf_processed_ptr is converted to UTF8-body. + */ + const char *m_cpp_utf8_processed_ptr; - /** Begining of the query text in the input stream. */ - const char* buf; +public: /** 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; + /** + Position of ';' in the stream, to delimit multiple queries. + This delimiter is in the raw buffer. + */ + const char *found_semicolon; /** SQL_MODE = IGNORE_SPACE. */ bool ignore_space; - /* + + /** TRUE if we're parsing a prepared statement: in this mode we should allow placeholders and disallow multi-statements. */ bool stmt_prepare_mode; + + /** State of the lexical analyser for comments. */ + enum_comment_state in_comment; + + /** + Starting position of the TEXT_STRING or IDENT in the pre-processed + buffer. + + NOTE: this member must be used within MYSQLlex() function only. + */ + const char *m_cpp_text_start; + + /** + Ending position of the TEXT_STRING or IDENT in the pre-processed + buffer. + + NOTE: this member must be used within MYSQLlex() function only. + */ + const char *m_cpp_text_end; + + /** + Character set specified by the character-set-introducer. + + NOTE: this member must be used within MYSQLlex() function only. + */ + CHARSET_INFO *m_underscore_cs; }; @@ -979,7 +1483,8 @@ typedef struct st_lex : public Query_tables_list /* list of all SELECT_LEX */ SELECT_LEX *all_selects_list; - char *length,*dec,*change,*name; + char *length,*dec,*change; + LEX_STRING name; char *help_arg; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ @@ -991,13 +1496,29 @@ typedef struct st_lex : public Query_tables_list LEX_STRING comment, ident; LEX_USER *grant_user; XID *xid; - gptr yacc_yyss,yacc_yyvs; + uchar* yacc_yyss, *yacc_yyvs; THD *thd; - CHARSET_INFO *charset, *underscore_charset; + + /* maintain a list of used plugins for this LEX */ + DYNAMIC_ARRAY plugins; + plugin_ref plugins_static_buffer[INITIAL_LEX_PLUGIN_LIST_SIZE]; + + CHARSET_INFO *charset; /* store original leaf_tables for INSERT SELECT and PS/SP */ TABLE_LIST *leaf_tables_insert; - /* Position (first character index) of SELECT of CREATE VIEW statement */ - uint create_view_select_start; + + /** Start of SELECT of CREATE VIEW statement */ + const char* create_view_select_start; + /** End of SELECT of CREATE VIEW statement */ + const char* create_view_select_end; + + /** Start of 'ON <table>', in trigger statements. */ + const char* raw_trg_on_table_name_begin; + /** End of 'ON <table>', in trigger statements. */ + const char* raw_trg_on_table_name_end; + + /* Partition info structure filled in by PARTITION BY parse part */ + partition_info *part_info; /* The definer of the object being created (view, trigger, stored routine). @@ -1005,8 +1526,8 @@ typedef struct st_lex : public Query_tables_list */ LEX_USER *definer; - List<key_part_spec> col_list; - List<key_part_spec> ref_list; + List<Key_part_spec> col_list; + List<Key_part_spec> ref_list; List<String> interval_list; List<LEX_USER> users_list; List<LEX_COLUMN> columns; @@ -1029,14 +1550,17 @@ typedef struct st_lex : public Query_tables_list required a local context, the parser pops the top-most context. */ List<Name_resolution_context> context_stack; + List<LEX_STRING> db_list; SQL_LIST proc_list, auxiliary_table_list, save_list; - create_field *last_field; + Create_field *last_field; Item_sum *in_sum_func; udf_func udf; HA_CHECK_OPT check_opt; // check/repair options HA_CREATE_INFO create_info; + KEY_CREATE_INFO key_create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER + LEX_SERVER_OPTIONS server_options; USER_RESOURCES mqh; ulong type; /* @@ -1049,7 +1573,15 @@ typedef struct st_lex : public Query_tables_list the variable can contain 0 or 1 for each nest level. */ nesting_map allow_sum_func; - enum_sql_command sql_command, orig_sql_command; + enum_sql_command sql_command; + /* + Usually `expr` rule of yacc is quite reused but some commands better + not support subqueries which comes standard with this rule, like + KILL, HA_READ, CREATE/ALTER EVENT etc. Set this to `false` to get + syntax error back. + */ + bool expr_allows_subselect; + thr_lock_type lock_option; enum SSL_type ssl_type; /* defined in violite.h */ enum enum_duplicates duplicates; @@ -1083,7 +1615,9 @@ typedef struct st_lex : public Query_tables_list uint8 create_view_algorithm; uint8 create_view_check; bool drop_if_exists, drop_temporary, local_file, one_shot_set; - bool in_comment, verbose, no_write_to_binlog; + + bool verbose, no_write_to_binlog; + bool tx_chain, tx_release; /* Special JOIN::prepare mode: changing of query is prohibited. @@ -1108,11 +1642,6 @@ typedef struct st_lex : public Query_tables_list bool prepared_stmt_code_is_varref; /* Names of user variables holding parameters (in EXECUTE) */ List<LEX_STRING> prepared_stmt_params; - /* - Points to part of global table list which contains time zone tables - implicitly used by the statement. - */ - TABLE_LIST *time_zone_tables_used; sp_head *sphead; sp_name *spname; bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */ @@ -1120,6 +1649,9 @@ typedef struct st_lex : public Query_tables_list sp_pcontext *spcont; st_sp_chistics sp_chistics; + + Event_parse_data *event_parse_data; + bool only_view; /* used for SHOW CREATE TABLE/VIEW */ /* field_list was created for view and should be removed before PS/SP @@ -1149,10 +1681,12 @@ typedef struct st_lex : public Query_tables_list - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE"); This pointer is required to add possibly omitted DEFINER-clause to the - DDL-statement before dumping it to the binlog. + DDL-statement before dumping it to the binlog. */ const char *stmt_definition_begin; + const char *stmt_definition_end; + /* Pointers to part of LOAD DATA statement that should be rewritten during replication ("LOCAL 'filename' REPLACE INTO" part). @@ -1160,6 +1694,14 @@ typedef struct st_lex : public Query_tables_list const char *fname_start; const char *fname_end; + LEX_STRING view_body_utf8; + + /* + Reference to a struct that contains information in various commands + to add/create/drop/change table spaces. + */ + st_alter_tablespace *alter_tablespace_info; + bool escape_used; st_lex(); @@ -1167,6 +1709,8 @@ typedef struct st_lex : public Query_tables_list virtual ~st_lex() { destroy_query_tables_list(); + plugin_unlock_list(NULL, (plugin_ref *)plugins.buffer, plugins.elements); + delete_dynamic(&plugins); } inline void uncacheable(uint8 cause) @@ -1193,7 +1737,6 @@ typedef struct st_lex : public Query_tables_list TABLE_LIST *unlink_first_table(bool *link_to_local); void link_first_table_back(TABLE_LIST *first, bool link_to_local); void first_lists_tables_same(); - bool add_time_zone_tables_to_query_tables(THD *thd); bool can_be_merged(); bool can_use_merged(); @@ -1239,7 +1782,7 @@ typedef struct st_lex : public Query_tables_list context_stack.pop(); } - bool copy_db_to(char **p_db, uint *p_db_length) const; + bool copy_db_to(char **p_db, size_t *p_db_length) const; Name_resolution_context *current_context() { @@ -1252,13 +1795,16 @@ typedef struct st_lex : public Query_tables_list void reset_n_backup_query_tables_list(Query_tables_list *backup); void restore_backup_query_tables_list(Query_tables_list *backup); + + bool table_or_sp_used(); + bool is_partition_management() const; } LEX; struct st_lex_local: public st_lex { static void *operator new(size_t size) { - return (void*) sql_alloc((uint) size); + return sql_alloc(size); } static void *operator new(size_t size, MEM_ROOT *mem_root) { @@ -1275,4 +1821,9 @@ extern void lex_free(void); extern void lex_start(THD *thd); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); -extern char *skip_rear_comments(CHARSET_INFO *cs, char *begin, char *end); + +extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str); + +extern bool is_lex_native_function(const LEX_STRING *name); + +#endif /* MYSQL_SERVER */ |