summaryrefslogtreecommitdiff
path: root/sql/sql_lex.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_lex.h')
-rw-r--r--sql/sql_lex.h727
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 */