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.h489
1 files changed, 347 insertions, 142 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 89e3abe284f..c1be116272f 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -37,12 +37,16 @@
/**
- A string with metadata.
+ A string with metadata. Usually points to a string in the client
+ character set, but unlike Lex_ident_cli_st (see below) it does not
+ necessarily point to a query fragment. It can also point to memory
+ of other kinds (e.g. an additional THD allocated memory buffer
+ not overlapping with the current query text).
+
We'll add more flags here eventually, to know if the string has, e.g.:
- multi-byte characters
- bad byte sequences
- backslash escapes: 'a\nb'
- - separator escapes: 'a''b'
and reuse the original query fragments instead of making the string
copy too early, in Lex_input_stream::get_text().
This will allow to avoid unnecessary copying, as well as
@@ -50,9 +54,30 @@
*/
struct Lex_string_with_metadata_st: public LEX_CSTRING
{
+private:
bool m_is_8bit; // True if the string has 8bit characters
+ char m_quote; // Quote character, or 0 if not quoted
public:
void set_8bit(bool is_8bit) { m_is_8bit= is_8bit; }
+ void set_metadata(bool is_8bit, char quote)
+ {
+ m_is_8bit= is_8bit;
+ m_quote= quote;
+ }
+ void set(const char *s, size_t len, bool is_8bit, char quote)
+ {
+ str= s;
+ length= len;
+ set_metadata(is_8bit, quote);
+ }
+ void set(const LEX_CSTRING *s, bool is_8bit, char quote)
+ {
+ ((LEX_CSTRING &)*this)= *s;
+ set_metadata(is_8bit, quote);
+ }
+ bool is_8bit() const { return m_is_8bit; }
+ bool is_quoted() const { return m_quote != '\0'; }
+ char quote() const { return m_quote; }
// Get string repertoire by the 8-bit flag and the character set
uint repertoire(CHARSET_INFO *cs) const
{
@@ -67,6 +92,76 @@ public:
};
+/*
+ Used to store identifiers in the client character set.
+ Points to a query fragment.
+*/
+struct Lex_ident_cli_st: public Lex_string_with_metadata_st
+{
+public:
+ void set_keyword(const char *s, size_t len)
+ {
+ set(s, len, false, '\0');
+ }
+ void set_ident(const char *s, size_t len, bool is_8bit)
+ {
+ set(s, len, is_8bit, '\0');
+ }
+ void set_ident_quoted(const char *s, size_t len, bool is_8bit, char quote)
+ {
+ set(s, len, is_8bit, quote);
+ }
+ void set_unquoted(const LEX_CSTRING *s, bool is_8bit)
+ {
+ set(s, is_8bit, '\0');
+ }
+ const char *pos() const { return str - is_quoted(); }
+ const char *end() const { return str + length + is_quoted(); }
+};
+
+
+class Lex_ident_cli: public Lex_ident_cli_st
+{
+public:
+ Lex_ident_cli(const LEX_CSTRING *s, bool is_8bit)
+ {
+ set_unquoted(s, is_8bit);
+ }
+ Lex_ident_cli(const char *s, size_t len)
+ {
+ set_ident(s, len, false);
+ }
+};
+
+
+struct Lex_ident_sys_st: public LEX_CSTRING
+{
+public:
+ bool copy_ident_cli(THD *thd, const Lex_ident_cli_st *str);
+ bool copy_keyword(THD *thd, const Lex_ident_cli_st *str);
+ bool copy_sys(THD *thd, const LEX_CSTRING *str);
+ bool convert(THD *thd, const LEX_CSTRING *str, CHARSET_INFO *cs);
+ bool copy_or_convert(THD *thd, const Lex_ident_cli_st *str, CHARSET_INFO *cs);
+ bool is_null() const { return str == NULL; }
+ bool to_size_number(ulonglong *to) const;
+};
+
+
+class Lex_ident_sys: public Lex_ident_sys_st
+{
+public:
+ Lex_ident_sys(THD *thd, const Lex_ident_cli_st *str)
+ {
+ if (copy_ident_cli(thd, str))
+ ((LEX_CSTRING &) *this)= null_clex_str;
+ }
+ Lex_ident_sys()
+ {
+ ((LEX_CSTRING &) *this)= null_clex_str;
+ }
+};
+
+
enum sub_select_type
{
UNSPECIFIED_TYPE,
@@ -173,7 +268,7 @@ struct LEX_TYPE
#define LEX_YYSTYPE void *
#else
#include "lex_symbol.h"
-#if MYSQL_LEX
+#ifdef MYSQL_LEX
#include "item_func.h" /* Cast_target used in sql_yacc.h */
#include "sql_get_diagnostics.h" /* Types used in sql_yacc.h */
#include "sp_pcontext.h"
@@ -186,13 +281,13 @@ struct LEX_TYPE
#endif
// describe/explain types
-#define DESCRIBE_NORMAL 1
-#define DESCRIBE_EXTENDED 2
+#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
+#define DESCRIBE_PARTITIONS 4
#ifdef MYSQL_SERVER
@@ -224,24 +319,24 @@ enum enum_sp_aggregate_type
GROUP_AGGREGATE
};
-const LEX_STRING sp_data_access_name[]=
+const LEX_CSTRING sp_data_access_name[]=
{
- { 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") }
+ { STRING_WITH_LEN("") },
+ { STRING_WITH_LEN("CONTAINS SQL") },
+ { STRING_WITH_LEN("NO SQL") },
+ { STRING_WITH_LEN("READS SQL DATA") },
+ { STRING_WITH_LEN("MODIFIES SQL DATA") }
};
-#define DERIVED_SUBQUERY 1
-#define DERIVED_VIEW 2
+#define DERIVED_SUBQUERY 1
+#define DERIVED_VIEW 2
#define DERIVED_WITH 4
enum enum_view_create_mode
{
- VIEW_CREATE_NEW, // check that there are not such VIEW/table
- VIEW_ALTER, // check that VIEW .frm with such name exists
- VIEW_CREATE_OR_REPLACE // check only that there are not such table
+ VIEW_CREATE_NEW, // check that there are not such VIEW/table
+ VIEW_ALTER, // check that VIEW .frm with such name exists
+ VIEW_CREATE_OR_REPLACE // check only that there are not such table
};
@@ -273,8 +368,8 @@ enum enum_drop_mode
};
/* Options to add_table_to_list() */
-#define TL_OPTION_UPDATING 1
-#define TL_OPTION_FORCE_INDEX 2
+#define TL_OPTION_UPDATING 1
+#define TL_OPTION_FORCE_INDEX 2
#define TL_OPTION_IGNORE_LEAVES 4
#define TL_OPTION_ALIAS 8
#define TL_OPTION_SEQUENCE 16
@@ -749,7 +844,7 @@ public:
st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
bool describe; /* union exec() called for EXPLAIN */
- Procedure *last_procedure; /* Pointer to procedure, if such exists */
+ Procedure *last_procedure; /* Pointer to procedure, if such exists */
bool columns_are_renamed;
@@ -770,7 +865,8 @@ public:
bool is_excluded() { return prev == NULL; }
/* UNION methods */
- bool prepare(THD *thd, select_result *result, ulong additional_options);
+ bool prepare(TABLE_LIST *derived_arg, select_result *sel_result,
+ ulong additional_options);
bool optimize();
bool exec();
bool exec_recursive();
@@ -839,7 +935,7 @@ public:
/*
Point to the LEX in which it was created, used in view subquery detection.
- TODO: make also st_select_lex::parent_stmt_lex (see THD::stmt_lex)
+ TODO: make also st_select_lex::parent_stmt_lex (see LEX::stmt_lex)
and use st_select_lex::parent_lex & st_select_lex::parent_stmt_lex
instead of global (from THD) references where it is possible.
*/
@@ -859,7 +955,7 @@ public:
List<Item> item_list; /* list of fields & expressions */
List<Item> pre_fix; /* above list before fix_fields */
- bool is_item_list_lookup;
+ bool is_item_list_lookup;
/*
Usualy it is pointer to ftfunc_list_alloc, but in union used to create fake
select_lex for calling mysql_select under results of union
@@ -942,6 +1038,11 @@ public:
uint select_n_where_fields;
/* reserved for exists 2 in */
uint select_n_reserved;
+ /*
+ it counts the number of bit fields in the SELECT list. These are used when DISTINCT is
+ converted to a GROUP BY involving BIT fields.
+ */
+ uint hidden_bit_fields;
enum_parsing_place parsing_place; /* where we are parsing expression */
enum_parsing_place context_analysis_place; /* where we are in prepare */
bool with_sum_func; /* sum function indicator */
@@ -983,6 +1084,7 @@ public:
*/
bool subquery_in_having;
/* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
+ bool with_all_modifier; /* used for selects in union */
bool is_correlated;
/*
This variable is required to ensure proper work of subqueries and
@@ -1087,11 +1189,11 @@ public:
bool add_order_to_list(THD *thd, Item *item, bool asc);
bool add_gorder_to_list(THD *thd, Item *item, bool asc);
TABLE_LIST* add_table_to_list(THD *thd, Table_ident *table,
- LEX_CSTRING *alias,
- ulong table_options,
- thr_lock_type flags= TL_UNLOCK,
+ LEX_CSTRING *alias,
+ ulong table_options,
+ thr_lock_type flags= TL_UNLOCK,
enum_mdl_type mdl_type= MDL_SHARED_READ,
- List<Index_hint> *hints= 0,
+ List<Index_hint> *hints= 0,
List<String> *partition_names= 0,
LEX_STRING *option= 0);
TABLE_LIST* get_table_list();
@@ -1242,7 +1344,7 @@ public:
void collect_grouping_fields(THD *thd, ORDER *grouping_list);
void check_cond_extraction_for_grouping_fields(Item *cond);
Item *build_cond_for_grouping_fields(THD *thd, Item *cond,
- bool no_to_clones);
+ bool no_to_clones);
List<Window_spec> window_specs;
void prepare_add_window_spec(THD *thd);
@@ -2065,6 +2167,16 @@ public:
void reset(char *buff, size_t length);
/**
+ The main method to scan the next token, with token contraction processing
+ for LALR(2) resolution, e.g. translate "WITH" followed by "ROLLUP"
+ to a single token WITH_ROLLUP_SYM.
+ */
+ int lex_token(union YYSTYPE *yylval, THD *thd);
+
+ void reduce_digest_token(uint token_left, uint token_right);
+
+private:
+ /**
Set the echo mode.
When echo is true, characters parsed from the raw input stream are
@@ -2193,15 +2305,6 @@ public:
/**
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
*/
@@ -2210,24 +2313,6 @@ public:
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()
{
@@ -2250,10 +2335,65 @@ public:
m_cpp_tok_start= m_cpp_ptr;
}
+ /**
+ Get the maximum length of the utf8-body buffer.
+ The utf8 body can grow because of the character set conversion and escaping.
+ */
+ size_t get_body_utf8_maximum_length(THD *thd);
+
+ /** 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);
+ }
+
+ /**
+ Test if a lookahead token was already scanned by lex_token(),
+ for LALR(2) resolution.
+ */
+ bool has_lookahead() const
+ {
+ return lookahead_token >= 0;
+ }
+
+public:
+
+ /**
+ 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);
+ }
+
+ /** 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;
+ }
+
/** Get the token start position, in the raw buffer. */
const char *get_tok_start()
{
- return m_tok_start;
+ return has_lookahead() ? m_tok_start_prev : m_tok_start;
}
void set_cpp_tok_start(const char *pos)
@@ -2267,39 +2407,16 @@ public:
return m_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 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 previus token start position, in the pre-processed buffer. */
- const char *get_cpp_start_prev()
- {
- return m_cpp_tok_start_prev;
- }
-
/** Get the token start position, in the pre-processed buffer. */
const char *get_cpp_tok_start()
{
- return m_cpp_tok_start;
+ return has_lookahead() ? m_cpp_tok_start_prev : m_cpp_tok_start;
}
/** Get the token end position, in the pre-processed buffer. */
@@ -2353,32 +2470,19 @@ public:
return (size_t) (m_body_utf8_ptr - m_body_utf8);
}
- /**
- Get the maximum length of the utf8-body buffer.
- The utf8 body can grow because of the character set conversion and escaping.
- */
- size_t get_body_utf8_maximum_length(THD *thd);
-
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_ident(THD *thd,
- const LEX_CSTRING *txt,
+ const Lex_string_with_metadata_st *txt,
const char *end_ptr);
void body_utf8_append_escape(THD *thd,
const LEX_CSTRING *txt,
CHARSET_INFO *txt_cs,
const char *end_ptr,
my_wc_t sep);
- /** Current thread. */
- THD *m_thd;
-
- /** Current line number. */
- uint yylineno;
-
- /** Interface with bison, value of the last token parsed. */
- LEX_YYSTYPE yylval;
+private:
/**
LALR(2) resolution, look ahead token.
Value of the next token to return, if any,
@@ -2395,9 +2499,20 @@ public:
void add_digest_token(uint token, LEX_YYSTYPE yylval);
- void reduce_digest_token(uint token_left, uint token_right);
+ bool consume_comment(int remaining_recursions_permitted);
+ int lex_one_token(union YYSTYPE *yylval, THD *thd);
+ int find_keyword(Lex_ident_cli_st *str, uint len, bool function);
+ LEX_CSTRING get_token(uint skip, uint length);
+ int scan_ident_sysvar(THD *thd, Lex_ident_cli_st *str);
+ int scan_ident_start(THD *thd, Lex_ident_cli_st *str);
+ int scan_ident_middle(THD *thd, Lex_ident_cli_st *str,
+ CHARSET_INFO **cs, my_lex_states *);
+ int scan_ident_delimited(THD *thd, Lex_ident_cli_st *str);
+ bool get_7bit_or_8bit_ident(THD *thd, uchar *last_char);
+
+ /** Current thread. */
+ THD *m_thd;
-private:
/** Pointer to the current position in the raw input stream. */
char *m_ptr;
@@ -2483,6 +2598,15 @@ public:
*/
bool multi_statements;
+ /** Current line number. */
+ uint yylineno;
+
+ /**
+ Current statement digest instrumentation.
+ */
+ sql_digest_state* m_digest;
+
+private:
/** State of the lexical analyser for comments. */
enum_comment_state in_comment;
enum_comment_state in_comment_saved;
@@ -2509,13 +2633,9 @@ public:
NOTE: this member must be used within MYSQLlex() function only.
*/
CHARSET_INFO *m_underscore_cs;
-
- /**
- Current statement digest instrumentation.
- */
- sql_digest_state* m_digest;
};
+
/**
Abstract representation of a statement.
This class is an interface between the parser and the runtime.
@@ -2691,10 +2811,25 @@ struct LEX: public Query_tables_list
// type information
CHARSET_INFO *charset;
+ /*
+ LEX which represents current statement (conventional, SP or PS)
+
+ For example during view parsing THD::lex will point to the views LEX and
+ lex::stmt_lex will point to LEX of the statement where the view will be
+ included
+
+ Currently it is used to have always correct select numbering inside
+ statement (LEX::current_select_number) without storing and restoring a
+ global counter which was THD::select_number.
+
+ TODO: make some unified statement representation (now SP has different)
+ to store such data like LEX::current_select_number.
+ */
+ LEX *stmt_lex;
LEX_CSTRING name;
const char *help_arg;
- const char *backup_dir; /* For RESTORE/BACKUP */
+ const char *backup_dir; /* For RESTORE/BACKUP */
const char* to_log; /* For PURGE MASTER LOGS TO */
const char* x509_subject,*x509_issuer,*ssl_cipher;
String *wild; /* Wildcard in SHOW {something} LIKE 'wild'*/
@@ -2732,7 +2867,7 @@ struct LEX: public Query_tables_list
List<Key_part_spec> ref_list;
List<LEX_USER> users_list;
List<LEX_COLUMN> columns;
- List<Item> *insert_list,field_list,value_list,update_list;
+ List<Item> *insert_list,field_list,value_list,update_list;
List<List_item> many_values;
List<set_var_base> var_list;
List<set_var_base> stmt_var_list; //SET_STATEMENT values
@@ -2785,10 +2920,10 @@ public:
Column_definition *last_field;
Item_sum *in_sum_func;
udf_func udf;
- HA_CHECK_OPT check_opt; // check/repair options
+ HA_CHECK_OPT check_opt; // check/repair options
Table_specification_st create_info;
Key *last_key;
- LEX_MASTER_INFO mi; // used by CHANGE MASTER
+ LEX_MASTER_INFO mi; // used by CHANGE MASTER
LEX_SERVER_OPTIONS server_options;
LEX_CSTRING relay_log_connection_name;
USER_RESOURCES mqh;
@@ -2827,7 +2962,7 @@ public:
*/
bool parse_vcol_expr;
- enum SSL_type ssl_type; /* defined in violite.h */
+ enum SSL_type ssl_type; // defined in violite.h
enum enum_duplicates duplicates;
enum enum_tx_isolation tx_isolation;
enum enum_ha_read_modes ha_read_mode;
@@ -2888,7 +3023,7 @@ public:
List<Item> prepared_stmt_params;
sp_head *sphead;
sp_name *spname;
- bool sp_lex_in_use; /* Keep track on lex usage in SPs for error handling */
+ bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
bool all_privileges;
bool proxy_priv;
@@ -3149,7 +3284,10 @@ public:
void restore_backup_query_tables_list(Query_tables_list *backup);
bool table_or_sp_used();
+
bool is_partition_management() const;
+ bool part_values_current(THD *thd);
+ bool part_values_history(THD *thd);
/**
@brief check if the statement is a single-level join
@@ -3181,6 +3319,11 @@ public:
void init_last_field(Column_definition *field, const LEX_CSTRING *name,
const CHARSET_INFO *cs);
+ bool last_field_generated_always_as_row_start_or_end(Lex_ident *p,
+ const char *type,
+ uint flags);
+ bool last_field_generated_always_as_row_start();
+ bool last_field_generated_always_as_row_end();
bool set_bincmp(CHARSET_INFO *cs, bool bin);
bool get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer);
@@ -3304,20 +3447,42 @@ public:
bool sp_open_cursor(THD *thd, const LEX_CSTRING *name,
List<sp_assignment_lex> *parameters);
- Item_splocal *create_item_for_sp_var(LEX_CSTRING *name, sp_variable *spvar,
- const char *start, const char *end);
+ Item_splocal *create_item_for_sp_var(const Lex_ident_cli_st *name,
+ sp_variable *spvar);
+
+ Item *create_item_qualified_asterisk(THD *thd, const Lex_ident_sys_st *name);
+ Item *create_item_qualified_asterisk(THD *thd,
+ const Lex_ident_sys_st *a,
+ const Lex_ident_sys_st *b);
+ Item *create_item_qualified_asterisk(THD *thd, const Lex_ident_cli_st *cname)
+ {
+ Lex_ident_sys name(thd, cname);
+ if (name.is_null())
+ return NULL; // EOM
+ return create_item_qualified_asterisk(thd, &name);
+ }
+ Item *create_item_qualified_asterisk(THD *thd,
+ const Lex_ident_cli_st *ca,
+ const Lex_ident_cli_st *cb)
+ {
+ Lex_ident_sys a(thd, ca), b(thd, cb);
+ if (a.is_null() || b.is_null())
+ return NULL; // EOM
+ return create_item_qualified_asterisk(thd, &a, &b);
+ }
- Item *create_item_ident_nosp(THD *thd, LEX_CSTRING *name);
- Item *create_item_ident_sp(THD *thd, LEX_CSTRING *name,
+ Item *create_item_ident_nosp(THD *thd, Lex_ident_sys_st *name);
+ Item *create_item_ident_sp(THD *thd, Lex_ident_sys_st *name,
const char *start, const char *end);
- Item *create_item_ident(THD *thd, LEX_CSTRING *name,
- const char *start, const char *end)
+ Item *create_item_ident(THD *thd, Lex_ident_cli_st *cname)
{
+ Lex_ident_sys name(thd, cname);
+ if (name.is_null())
+ return NULL; // EOM
return sphead ?
- create_item_ident_sp(thd, name, start, end) :
- create_item_ident_nosp(thd, name);
+ create_item_ident_sp(thd, &name, cname->pos(), cname->end()) :
+ create_item_ident_nosp(thd, &name);
}
-
/*
Create an Item corresponding to a qualified name: a.b
when the parser is out of an SP context.
@@ -3332,8 +3497,8 @@ public:
- Item_ref
*/
Item *create_item_ident_nospvar(THD *thd,
- const LEX_CSTRING *a,
- const LEX_CSTRING *b);
+ const Lex_ident_sys_st *a,
+ const Lex_ident_sys_st *b);
/*
Create an Item corresponding to a ROW field valiable: var.field
@param THD - THD, for mem_root
@@ -3347,8 +3512,8 @@ public:
*/
Item_splocal *create_item_spvar_row_field(THD *thd,
const Sp_rcontext_handler *rh,
- const LEX_CSTRING *var,
- const LEX_CSTRING *field,
+ const Lex_ident_sys *var,
+ const Lex_ident_sys *field,
sp_variable *spvar,
const char *start,
const char *end);
@@ -3361,15 +3526,11 @@ public:
@param thd - THD, for mem_root
@param a - the first name
@param b - the second name
- @param start - position in the query (for binary log)
- @param end - end in the query (for binary log)
@retval - NULL on error, or a pointer to a new Item.
*/
Item *create_item_ident(THD *thd,
- const LEX_CSTRING *a,
- const LEX_CSTRING *b,
- const char *start,
- const char *end);
+ const Lex_ident_cli_st *a,
+ const Lex_ident_cli_st *b);
/*
Create an item from its qualified name.
Depending on context, it can be a table field, a table field reference,
@@ -3381,9 +3542,27 @@ public:
@retval - NULL on error, or a pointer to a new Item.
*/
Item *create_item_ident(THD *thd,
- const LEX_CSTRING *a,
- const LEX_CSTRING *b,
- const LEX_CSTRING *c);
+ const Lex_ident_sys_st *a,
+ const Lex_ident_sys_st *b,
+ const Lex_ident_sys_st *c);
+
+ Item *create_item_ident(THD *thd,
+ const Lex_ident_cli_st *ca,
+ const Lex_ident_cli_st *cb,
+ const Lex_ident_cli_st *cc)
+ {
+ Lex_ident_sys b(thd, cb), c(thd, cc);
+ if (b.is_null() || c.is_null())
+ return NULL;
+ if (ca->pos() == cb->pos()) // SELECT .t1.col1
+ {
+ DBUG_ASSERT(ca->length == 0);
+ Lex_ident_sys none;
+ return create_item_ident(thd, &none, &b, &c);
+ }
+ Lex_ident_sys a(thd, ca);
+ return a.is_null() ? NULL : create_item_ident(thd, &a, &b, &c);
+ }
/*
Create an item for "NEXT VALUE FOR sequence_name"
@@ -3408,16 +3587,11 @@ public:
Create an item for a name in LIMIT clause: LIMIT var
@param THD - THD, for mem_root
@param var_name - the variable name
- @param start - position in the query (for binary log)
- @param end - end in the query (for binary log)
@retval - a new Item corresponding to the SP variable,
or NULL on error
(non in SP, unknown variable, wrong data type).
*/
- Item *create_item_limit(THD *thd,
- const LEX_CSTRING *var_name,
- const char *start,
- const char *end);
+ Item *create_item_limit(THD *thd, const Lex_ident_cli_st *var_name);
/*
Create an item for a qualified name in LIMIT clause: LIMIT var.field
@@ -3432,14 +3606,14 @@ public:
wrong data type).
*/
Item *create_item_limit(THD *thd,
- const LEX_CSTRING *var_name,
- const LEX_CSTRING *field_name,
- const char *start,
- const char *end);
+ const Lex_ident_cli_st *var_name,
+ const Lex_ident_cli_st *field_name);
Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c);
Item *make_item_func_substr(THD *thd, Item *a, Item *b);
+ Item *make_item_func_call_generic(THD *thd, Lex_ident_cli_st *db,
+ Lex_ident_cli_st *name, List<Item> *args);
my_var *create_outvar(THD *thd, const LEX_CSTRING *name);
/*
@@ -3457,7 +3631,10 @@ public:
Item *create_and_link_Item_trigger_field(THD *thd, const LEX_CSTRING *name,
bool new_row);
-
+ // For syntax with colon, e.g. :NEW.a or :OLD.a
+ Item *make_item_colon_ident_ident(THD *thd,
+ const Lex_ident_cli_st *a,
+ const Lex_ident_cli_st *b);
void sp_block_init(THD *thd, const LEX_CSTRING *label);
void sp_block_init(THD *thd)
{
@@ -3529,7 +3706,7 @@ public:
Item *value);
sp_variable *sp_add_for_loop_upper_bound(THD *thd, Item *value)
{
- LEX_CSTRING name= { C_STRING_WITH_LEN("[upper_bound]") };
+ LEX_CSTRING name= { STRING_WITH_LEN("[upper_bound]") };
return sp_add_for_loop_variable(thd, &name, value);
}
bool sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop,
@@ -3753,6 +3930,34 @@ public:
return create_info.vers_info;
}
sp_package *get_sp_package() const;
+
+ /**
+ Check if the select is a simple select (not an union).
+ @retval
+ 0 ok
+ @retval
+ 1 error ; In this case the error messege is sent to the client
+ */
+ bool check_simple_select(const LEX_CSTRING *option)
+ {
+ if (current_select != &select_lex)
+ {
+ char command[80];
+ strmake(command, option->str, MY_MIN(option->length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return true;
+ }
+ return false;
+ }
+
+ void tvc_start()
+ {
+ field_list.empty();
+ many_values.empty();
+ insert_list= 0;
+ }
+ bool tvc_finalize();
+ bool tvc_finalize_derived();
};