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.h341
1 files changed, 270 insertions, 71 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index c8fca748b77..3e59ad3afc9 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2010, 2019, MariaDB Corporation.
+ Copyright (c) 2010, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,13 +25,15 @@
#include "sql_trigger.h"
#include "thr_lock.h" /* thr_lock_type, TL_UNLOCK */
#include "mem_root_array.h"
+#include "grant.h"
#include "sql_cmd.h"
#include "sql_alter.h" // Alter_info
#include "sql_window.h"
#include "sql_trigger.h"
-#include "sp.h" // enum stored_procedure_type
+#include "sp.h" // enum enum_sp_type
#include "sql_tvc.h"
#include "item.h"
+#include "sql_limit.h" // Select_limit_counters
#include "sql_schema.h"
/* Used for flags of nesting constructs */
@@ -84,13 +86,13 @@ public:
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
+ my_repertoire_t repertoire(CHARSET_INFO *cs) const
{
return !m_is_8bit && my_charset_is_ascii_based(cs) ?
MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
}
// Get string repertoire by the 8-bit flag, for ASCII-based character sets
- uint repertoire() const
+ my_repertoire_t repertoire() const
{
return !m_is_8bit ? MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
}
@@ -183,6 +185,24 @@ public:
};
+struct Lex_column_list_privilege_st
+{
+ List<Lex_ident_sys> *m_columns;
+ privilege_t m_privilege;
+};
+
+
+class Lex_column_list_privilege: public Lex_column_list_privilege_st
+{
+public:
+ Lex_column_list_privilege(List<Lex_ident_sys> *columns, privilege_t privilege)
+ {
+ m_columns= columns;
+ m_privilege= privilege;
+ }
+};
+
+
/**
ORDER BY ... LIMIT parameters;
*/
@@ -208,6 +228,14 @@ enum sub_select_type
GLOBAL_OPTIONS_TYPE, DERIVED_TABLE_TYPE, OLAP_TYPE
};
+enum set_op_type
+{
+ UNSPECIFIED,
+ UNION_DISTINCT, UNION_ALL,
+ EXCEPT_DISTINCT, EXCEPT_ALL,
+ INTERSECT_DISTINCT, INTERSECT_ALL
+};
+
inline int cmp_unit_op(enum sub_select_type op1, enum sub_select_type op2)
{
DBUG_ASSERT(op1 >= UNION_TYPE && op1 <= EXCEPT_TYPE);
@@ -259,6 +287,7 @@ class sp_name;
class sp_instr;
class sp_pcontext;
class sp_variable;
+class sp_expr_lex;
class sp_assignment_lex;
class st_alter_tablespace;
class partition_info;
@@ -482,11 +511,11 @@ struct LEX_MASTER_INFO
void init()
{
bzero(this, sizeof(*this));
- my_init_dynamic_array(&repl_ignore_server_ids,
+ my_init_dynamic_array(PSI_INSTRUMENT_ME, &repl_ignore_server_ids,
sizeof(::server_id), 0, 16, MYF(0));
- my_init_dynamic_array(&repl_do_domain_ids,
+ my_init_dynamic_array(PSI_INSTRUMENT_ME, &repl_do_domain_ids,
sizeof(ulong), 0, 16, MYF(0));
- my_init_dynamic_array(&repl_ignore_domain_ids,
+ my_init_dynamic_array(PSI_INSTRUMENT_ME, &repl_ignore_domain_ids,
sizeof(ulong), 0, 16, MYF(0));
sql_delay= -1;
}
@@ -822,6 +851,7 @@ void create_explain_query(LEX *lex, MEM_ROOT *mem_root);
void create_explain_query_if_not_exists(LEX *lex, MEM_ROOT *mem_root);
bool print_explain_for_slow_log(LEX *lex, THD *thd, String *str);
+
class st_select_lex_unit: public st_select_lex_node {
protected:
TABLE_LIST result_table_list;
@@ -830,7 +860,7 @@ protected:
bool saved_error;
bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
- ulong additional_options,
+ ulonglong additional_options,
bool is_union_select);
bool join_union_type_handlers(THD *thd,
class Type_holder *holders, uint count);
@@ -842,8 +872,8 @@ public:
// Ensures that at least all members used during cleanup() are initialized.
st_select_lex_unit()
: union_result(NULL), table(NULL), result(NULL),
- cleaned(false),
- fake_select_lex(NULL)
+ cleaned(false), bag_set_op_optimized(false),
+ have_except_all_or_intersect_all(false), fake_select_lex(NULL)
{
}
@@ -854,9 +884,11 @@ public:
optimized, // optimize phase already performed for UNION (unit)
optimized_2,
executed, // already executed
- cleaned;
+ cleaned,
+ bag_set_op_optimized;
bool optimize_started;
+ bool have_except_all_or_intersect_all;
// list of fields which points to temporary table for union
List<Item> item_list;
@@ -869,11 +901,6 @@ public:
*/
List<Item> types;
/**
- There is INTERSECT and it is item used in creating temporary
- table for it
- */
- Item_int *intersect_mark;
- /**
TRUE if the unit contained TVC at the top level that has been wrapped
into SELECT:
VALUES (v1) ... (vn) => SELECT * FROM (VALUES (v1) ... (vn)) as tvc
@@ -904,7 +931,7 @@ public:
//node on which we should return current_select pointer after parsing subquery
st_select_lex *return_to;
/* LIMIT clause runtime counters */
- ha_rows select_limit_cnt, offset_limit_cnt;
+ Select_limit_counters lim;
/* not NULL if unit used in subselect, point to subselect item */
Item_subselect *item;
/*
@@ -929,8 +956,9 @@ public:
fake_select_lex is used.
*/
st_select_lex *saved_fake_select_lex;
-
- st_select_lex *union_distinct; /* pointer to the last UNION DISTINCT */
+
+ /* pointer to the last node before last subsequence of UNION ALL */
+ st_select_lex *union_distinct;
bool describe; /* union exec() called for EXPLAIN */
Procedure *last_procedure; /* Pointer to procedure, if such exists */
@@ -954,8 +982,9 @@ public:
/* UNION methods */
bool prepare(TABLE_LIST *derived_arg, select_result *sel_result,
- ulong additional_options);
+ ulonglong additional_options);
bool optimize();
+ void optimize_bag_operation(bool is_outer_distinct);
bool exec();
bool exec_recursive();
bool cleanup();
@@ -987,6 +1016,21 @@ public:
int save_union_explain_part2(Explain_query *output);
unit_common_op common_op();
+ bool explainable() const
+ {
+ /*
+ EXPLAIN/ANALYZE unit, when:
+ (1) if it's a subquery - it's not part of eliminated WHERE/ON clause.
+ (2) if it's a CTE - it's not hanging (needed for execution)
+ (3) if it's a derived - it's not merged
+ if it's not 1/2/3 - it's some weird internal thing, ignore it
+ */
+ return item ? !item->eliminated : // (1)
+ with_element ? derived && derived->derived_result : // (2)
+ derived ? derived->is_materialized_derived() : // (3)
+ false;
+ }
+
void reset_distinct();
void fix_distinct();
@@ -1026,7 +1070,7 @@ Field_pair *find_matching_field_pair(Item *item, List<Field_pair> pair_list);
#define TOUCHED_SEL_COND 1/* WHERE/HAVING/ON should be reinited before use */
#define TOUCHED_SEL_DERIVED (1<<1)/* derived should be reinited before use */
-
+#define UNIT_NEST_FL 1
/*
SELECT_LEX - store information of parsed SELECT statment
*/
@@ -1049,7 +1093,7 @@ public:
select1->first_nested points to select1.
*/
st_select_lex *first_nested;
-
+ uint8 nest_flags;
Name_resolution_context context;
LEX_CSTRING db;
Item *where, *having; /* WHERE & HAVING clauses */
@@ -1290,10 +1334,8 @@ public:
table_value_constr *tvc;
bool in_tvc;
- /* The interface employed to execute the select query by a foreign engine */
- select_handler *select_h;
/* The object used to organize execution of the query by a foreign engine */
- Pushdown_select *pushdown_select;
+ select_handler *pushdown_select;
/** System Versioning */
public:
@@ -1532,6 +1574,13 @@ public:
select_handler *find_select_handler(THD *thd);
+ bool is_set_op()
+ {
+ return linkage == UNION_TYPE ||
+ linkage == EXCEPT_TYPE ||
+ linkage == INTERSECT_TYPE;
+ }
+
private:
bool m_non_agg_field_used;
bool m_agg_func_used;
@@ -1578,6 +1627,8 @@ public:
void add_statistics(SELECT_LEX_UNIT *unit);
bool make_unique_derived_name(THD *thd, LEX_CSTRING *alias);
void lex_start(LEX *plex);
+ bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); }
+ void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; }
};
typedef class st_select_lex SELECT_LEX;
@@ -2919,15 +2970,6 @@ protected:
bool impossible_where;
bool no_partitions;
public:
- /*
- When single-table UPDATE updates a VIEW, that VIEW's select is still
- listed as the first child. When we print EXPLAIN, it looks like a
- subquery.
- In order to get rid of it, updating_a_view=TRUE means that first child
- select should not be shown when printing EXPLAIN.
- */
- bool updating_a_view;
-
/* Allocate things there */
MEM_ROOT *mem_root;
@@ -3075,6 +3117,28 @@ public:
};
+class Lex_grant_object_name: public Grant_object_name, public Sql_alloc
+{
+public:
+ Lex_grant_object_name(Table_ident *table_ident)
+ :Grant_object_name(table_ident)
+ { }
+ Lex_grant_object_name(const LEX_CSTRING &db, Type type)
+ :Grant_object_name(db, type)
+ { }
+};
+
+
+class Lex_grant_privilege: public Grant_privilege, public Sql_alloc
+{
+public:
+ Lex_grant_privilege() {}
+ Lex_grant_privilege(privilege_t grant, bool all_privileges= false)
+ :Grant_privilege(grant, all_privileges)
+ { }
+};
+
+
struct LEX: public Query_tables_list
{
SELECT_LEX_UNIT unit; /* most upper unit */
@@ -3082,14 +3146,14 @@ struct LEX: public Query_tables_list
private:
SELECT_LEX builtin_select;
- /* current SELECT_LEX in parsing */
public:
+ /* current SELECT_LEX in parsing */
SELECT_LEX *current_select;
/* list of all SELECT_LEX */
SELECT_LEX *all_selects_list;
/* current with clause in parsing if any, otherwise 0*/
- With_clause *curr_with_clause;
+ With_clause *curr_with_clause;
/* pointer to the first with clause in the current statement */
With_clause *with_clauses_list;
/*
@@ -3171,7 +3235,6 @@ public:
Table_type table_type; /* Used for SHOW CREATE */
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<List_item> many_values;
List<set_var_base> var_list;
@@ -3187,7 +3250,6 @@ private:
bool sp_exit_block(THD *thd, sp_label *lab, Item *when);
bool sp_continue_loop(THD *thd, sp_label *lab);
- bool sp_continue_loop(THD *thd, sp_label *lab, Item *when);
bool sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop);
bool sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop);
@@ -3198,6 +3260,10 @@ private:
@retval true ERROR (fields are not allowed). Error is raised.
*/
bool check_expr_allows_fields_or_error(THD *thd, const char *name) const;
+
+protected:
+ bool sp_continue_loop(THD *thd, sp_label *lab, Item *when);
+
public:
void parse_error(uint err_number= ER_SYNTAX_ERROR);
inline bool is_arena_for_set_stmt() {return arena_for_set_stmt != 0;}
@@ -3205,10 +3271,10 @@ public:
void reset_arena_for_set_stmt(Query_arena *backup);
void free_arena_for_set_stmt();
+ void print(String *str, enum_query_type qtype);
List<Item_func_set_user_var> set_var_list; // in-query assignment list
List<Item_param> param_list;
List<LEX_CSTRING> view_list; // view list (list of field names in view)
- List<LEX_CSTRING> with_column_list; // list of column names in with_list_element
List<LEX_STRING> *column_list; // list of column names (in ANALYZE)
List<LEX_STRING> *index_list; // list of index names (in ANALYZE)
/*
@@ -3291,7 +3357,6 @@ public:
uint profile_query_id;
uint profile_options;
- uint grant, grant_tot_col, which_columns;
enum backup_stages backup_stage;
enum Foreign_key::fk_match_opt fk_match_option;
enum_fk_option fk_update_opt;
@@ -3344,7 +3409,6 @@ public:
sp_head *sphead;
sp_name *spname;
bool sp_lex_in_use; // Keep track on lex usage in SPs for error handling
- bool all_privileges;
sp_pcontext *spcont;
@@ -3637,8 +3701,9 @@ public:
if (unlikely(!select_stack_top))
{
current_select= &builtin_select;
- DBUG_PRINT("info", ("Top Select is empty -> sel builtin: %p",
- current_select));
+ DBUG_PRINT("info", ("Top Select is empty -> sel builtin: %p service: %u",
+ current_select, builtin_select.is_service_select));
+ builtin_select.is_service_select= false;
}
else
current_select= select_stack[select_stack_top - 1];
@@ -3714,25 +3779,25 @@ public:
bool sp_proc_stmt_statement_finalize(THD *, bool no_lookahead);
sp_variable *sp_param_init(LEX_CSTRING *name);
- bool sp_param_fill_definition(sp_variable *spvar);
+ bool sp_param_fill_definition(sp_variable *spvar,
+ const Lex_field_type_st &def);
+ bool sf_return_fill_definition(const Lex_field_type_st &def);
- int case_stmt_action_expr(Item* expr);
- int case_stmt_action_when(Item *when, bool simple);
int case_stmt_action_then();
bool setup_select_in_parentheses();
bool set_trigger_new_row(const LEX_CSTRING *name, Item *val);
bool set_trigger_field(const LEX_CSTRING *name1, const LEX_CSTRING *name2,
Item *val);
bool set_system_variable(enum_var_type var_type, sys_var *var,
- const LEX_CSTRING *base_name, Item *val);
- bool set_system_variable(enum_var_type var_type, const LEX_CSTRING *name,
- Item *val);
+ const Lex_ident_sys_st *base_name, Item *val);
+ bool set_system_variable(enum_var_type var_type,
+ const Lex_ident_sys_st *name, Item *val);
bool set_system_variable(THD *thd, enum_var_type var_type,
- const LEX_CSTRING *name1,
- const LEX_CSTRING *name2,
+ const Lex_ident_sys_st *name1,
+ const Lex_ident_sys_st *name2,
Item *val);
bool set_default_system_variable(enum_var_type var_type,
- const LEX_CSTRING *name,
+ const Lex_ident_sys_st *name,
Item *val);
bool set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val);
void set_stmt_init();
@@ -3762,9 +3827,9 @@ public:
const char *body_start,
const char *body_end);
bool call_statement_start(THD *thd, sp_name *name);
- bool call_statement_start(THD *thd, const LEX_CSTRING *name);
- bool call_statement_start(THD *thd, const LEX_CSTRING *name1,
- const LEX_CSTRING *name2);
+ bool call_statement_start(THD *thd, const Lex_ident_sys_st *name);
+ bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
+ const Lex_ident_sys_st *name2);
sp_variable *find_variable(const LEX_CSTRING *name,
sp_pcontext **ctx,
const Sp_rcontext_handler **rh) const;
@@ -3774,9 +3839,9 @@ public:
sp_pcontext *not_used_ctx;
return find_variable(name, &not_used_ctx, rh);
}
- bool set_variable(const LEX_CSTRING *name, Item *item);
- bool set_variable(const LEX_CSTRING *name1, const LEX_CSTRING *name2,
- Item *item);
+ bool set_variable(const Lex_ident_sys_st *name, Item *item);
+ bool set_variable(const Lex_ident_sys_st *name1,
+ const Lex_ident_sys_st *name2, Item *item);
void sp_variable_declarations_init(THD *thd, int nvars);
bool sp_variable_declarations_finalize(THD *thd, int nvars,
const Column_definition *cdef,
@@ -3808,6 +3873,21 @@ public:
const Column_definition &ref,
Row_definition_list *fields,
Item *def);
+
+ LEX_USER *current_user_for_set_password(THD *thd);
+ bool sp_create_set_password_instr(THD *thd,
+ LEX_USER *user,
+ USER_AUTH *auth,
+ bool no_lookahead);
+ bool sp_create_set_password_instr(THD *thd,
+ USER_AUTH *auth,
+ bool no_lookahead)
+ {
+ LEX_USER *user;
+ return !(user= current_user_for_set_password(thd)) ||
+ sp_create_set_password_instr(thd, user, auth, no_lookahead);
+ }
+
bool sp_handler_declaration_init(THD *thd, int type);
bool sp_handler_declaration_finalize(THD *thd, int type);
@@ -3841,11 +3921,13 @@ public:
return create_item_qualified_asterisk(thd, &a, &b);
}
- Item *create_item_ident_field(THD *thd, const char *db, const char *table,
- const Lex_ident_sys_st *name);
+ Item *create_item_ident_field(THD *thd,
+ const Lex_ident_sys_st &db,
+ const Lex_ident_sys_st &table,
+ const Lex_ident_sys_st &name);
Item *create_item_ident_nosp(THD *thd, Lex_ident_sys_st *name)
{
- return create_item_ident_field(thd, NullS, NullS, name);
+ return create_item_ident_field(thd, Lex_ident_sys(), Lex_ident_sys(), *name);
}
Item *create_item_ident_sp(THD *thd, Lex_ident_sys_st *name,
const char *start, const char *end);
@@ -3991,6 +4073,9 @@ public:
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);
+ Item *make_item_func_call_native_or_parse_error(THD *thd,
+ Lex_ident_cli_st &name,
+ List<Item> *args);
my_var *create_outvar(THD *thd, const LEX_CSTRING *name);
/*
@@ -4077,8 +4162,8 @@ public:
bool sp_leave_statement(THD *thd, const LEX_CSTRING *label_name);
bool sp_goto_statement(THD *thd, const LEX_CSTRING *label_name);
- bool sp_continue_statement(THD *thd, Item *when);
- bool sp_continue_statement(THD *thd, const LEX_CSTRING *label_name, Item *when);
+ bool sp_continue_statement(THD *thd);
+ bool sp_continue_statement(THD *thd, const LEX_CSTRING *label_name);
bool sp_iterate_statement(THD *thd, const LEX_CSTRING *label_name);
bool maybe_start_compound_statement(THD *thd);
@@ -4088,6 +4173,7 @@ public:
void sp_pop_loop_empty_label(THD *thd);
bool sp_while_loop_expression(THD *thd, Item *expr);
bool sp_while_loop_finalize(THD *thd);
+ bool sp_if_after_statements(THD *thd);
bool sp_push_goto_label(THD *thd, const LEX_CSTRING *label_name);
Item_param *add_placeholder(THD *thd, const LEX_CSTRING *name,
@@ -4254,13 +4340,13 @@ public:
bool if_not_exists)
{
constr->name= name;
- constr->flags= if_not_exists ?
- Alter_info::CHECK_CONSTRAINT_IF_NOT_EXISTS : 0;
+ constr->flags= if_not_exists ? VCOL_CHECK_CONSTRAINT_IF_NOT_EXISTS : 0;
alter_info.check_constraint_list.push_back(constr);
return false;
}
- bool add_alter_list(const char *par_name, Virtual_column_info *expr,
+ bool add_alter_list(LEX_CSTRING par_name, Virtual_column_info *expr,
bool par_exists);
+ bool add_alter_list(LEX_CSTRING name, LEX_CSTRING new_name, bool exists);
void set_command(enum_sql_command command,
DDL_options_st options)
{
@@ -4351,8 +4437,30 @@ public:
bool add_create_view(THD *thd, DDL_options_st ddl,
uint16 algorithm, enum_view_suid suid,
Table_ident *table_ident);
- bool add_grant_command(THD *thd, enum_sql_command sql_command_arg,
- stored_procedure_type type_arg);
+ bool add_grant_command(THD *thd, const List<LEX_COLUMN> &columns);
+
+ bool stmt_grant_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ privilege_t grant_option);
+
+ bool stmt_revoke_table(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident);
+
+ bool stmt_grant_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph,
+ privilege_t grant_option);
+
+ bool stmt_revoke_sp(THD *thd,
+ Grant_privilege *grant,
+ const Lex_grant_object_name &ident,
+ const Sp_handler &sph);
+
+ bool stmt_grant_proxy(THD *thd, LEX_USER *user, privilege_t grant_option);
+ bool stmt_revoke_proxy(THD *thd, LEX_USER *user);
Vers_parse_info &vers_get_info()
{
@@ -4415,6 +4523,12 @@ public:
SELECT_LEX_UNIT *create_unit(SELECT_LEX*);
SELECT_LEX *wrap_unit_into_derived(SELECT_LEX_UNIT *unit);
SELECT_LEX *wrap_select_chain_into_derived(SELECT_LEX *sel);
+ void init_select()
+ {
+ current_select->init_select();
+ wild= 0;
+ exchange= 0;
+ }
bool main_select_push(bool service= false);
bool insert_select_hack(SELECT_LEX *sel);
SELECT_LEX *create_priority_nest(SELECT_LEX *first_in_nest);
@@ -4457,6 +4571,11 @@ public:
bool distinct,
bool oracle);
SELECT_LEX_UNIT *
+ add_primary_to_query_expression_body(SELECT_LEX_UNIT *unit,
+ SELECT_LEX *sel,
+ enum sub_select_type unit_type,
+ bool distinct);
+ SELECT_LEX_UNIT *
add_primary_to_query_expression_body_ext_parens(
SELECT_LEX_UNIT *unit,
SELECT_LEX *sel,
@@ -4494,6 +4613,11 @@ public:
void stmt_purge_to(const LEX_CSTRING &to);
bool stmt_purge_before(Item *item);
+ SELECT_LEX *returning()
+ { return &builtin_select; }
+ bool has_returning()
+ { return !builtin_select.item_list.is_empty(); }
+
private:
bool stmt_create_routine_start(const DDL_options_st &options)
{
@@ -4526,8 +4650,30 @@ public:
const Lex_ident_sys_st &name,
Item_result return_type,
const LEX_CSTRING &soname);
+
+ bool stmt_drop_function(const DDL_options_st &options,
+ const Lex_ident_sys_st &db,
+ const Lex_ident_sys_st &name);
+
+ bool stmt_drop_function(const DDL_options_st &options,
+ const Lex_ident_sys_st &name);
+
+ bool stmt_drop_procedure(const DDL_options_st &options,
+ sp_name *name);
+
+ bool stmt_alter_function_start(sp_name *name);
+ bool stmt_alter_procedure_start(sp_name *name);
+
+ sp_condition_value *stmt_signal_value(const Lex_ident_sys_st &ident);
+
Spvar_definition *row_field_name(THD *thd, const Lex_ident_sys_st &name);
+ bool set_field_type_udt(Lex_field_type_st *type,
+ const LEX_CSTRING &name,
+ const Lex_length_and_dec_st &attr);
+ bool set_cast_type_udt(Lex_cast_type_st *type,
+ const LEX_CSTRING &name);
+
bool map_data_type(const Lex_ident_sys_st &schema,
Lex_field_type_st *type) const;
@@ -4541,7 +4687,14 @@ public:
select_stack[0]->is_service_select);
}
-
+ bool add_table_foreign_key(const LEX_CSTRING *name,
+ const LEX_CSTRING *constraint_name,
+ Table_ident *table_name,
+ DDL_options ddl_options);
+ bool add_column_foreign_key(const LEX_CSTRING *name,
+ const LEX_CSTRING *constraint_name,
+ Table_ident *ref_table_name,
+ DDL_options ddl_options);
};
@@ -4750,6 +4903,51 @@ public:
};
+class sp_lex_set_var: public sp_lex_local
+{
+public:
+ sp_lex_set_var(THD *thd, const LEX *oldlex)
+ :sp_lex_local(thd, oldlex)
+ {
+ // Set new LEX as if we at start of set rule
+ init_select();
+ sql_command= SQLCOM_SET_OPTION;
+ var_list.empty();
+ autocommit= 0;
+ option_type= oldlex->option_type; // Inherit from the outer lex
+ }
+};
+
+
+class sp_expr_lex: public sp_lex_local
+{
+ Item *m_item; // The expression
+public:
+ sp_expr_lex(THD *thd, LEX *oldlex)
+ :sp_lex_local(thd, oldlex),
+ m_item(NULL)
+ { }
+ void set_item(Item *item)
+ {
+ m_item= item;
+ }
+ Item *get_item() const
+ {
+ return m_item;
+ }
+ bool sp_continue_when_statement(THD *thd);
+ bool sp_continue_when_statement(THD *thd, const LEX_CSTRING *label_name);
+ int case_stmt_action_expr();
+ int case_stmt_action_when(bool simple);
+ bool sp_while_loop_expression(THD *thd)
+ {
+ return LEX::sp_while_loop_expression(thd, get_item());
+ }
+ bool sp_repeat_loop_finalize(THD *thd);
+ bool sp_if_expr(THD *thd);
+};
+
+
/**
An assignment specific LEX, which additionally has an Item (an expression)
and an associated with the Item free_list, which is usually freed
@@ -4829,8 +5027,9 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr);
Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
Item *expr);
-bool sp_create_assignment_lex(THD *thd, bool no_lookahead);
-bool sp_create_assignment_instr(THD *thd, bool no_lookahead);
+bool sp_create_assignment_lex(THD *thd, const char *pos);
+bool sp_create_assignment_instr(THD *thd, bool no_lookahead,
+ bool need_set_keyword= true);
void mark_or_conds_to_avoid_pushdown(Item *cond);