summaryrefslogtreecommitdiff
path: root/sql/sql_yacc.yy
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_yacc.yy')
-rw-r--r--sql/sql_yacc.yy2434
1 files changed, 1616 insertions, 818 deletions
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 2a46bb2a027..fe7f3021be6 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -54,6 +54,9 @@
#include "sql_handler.h" // Sql_cmd_handler_*
#include "sql_signal.h"
#include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics
+#include "sql_cte.h"
+#include "sql_window.h"
+#include "item_windowfunc.h"
#include "event_parse_data.h"
#include "create_options.h"
#include <myisam.h>
@@ -131,8 +134,7 @@ static void my_parse_error_intern(THD *thd, const char *err_text,
/* Push an error into the error stack */
ErrConvString err(yytext, strlen(yytext),
thd->variables.character_set_client);
- my_printf_error(ER_PARSE_ERROR, ER_THD(thd, ER_PARSE_ERROR), MYF(0),
- err_text, err.ptr(), lip->yylineno);
+ my_error(ER_PARSE_ERROR, MYF(0), err_text, err.ptr(), lip->yylineno);
}
@@ -349,7 +351,7 @@ int case_stmt_action_when(LEX *lex, Item *when, bool simple)
*/
return !MY_TEST(i) ||
- sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) ||
+ sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) ||
sp->add_cont_backpatch(i) ||
sp->add_instr(i);
}
@@ -383,7 +385,7 @@ int case_stmt_action_then(LEX *lex)
(jump from instruction 4 to 12, 7 to 12 ... in the example)
*/
- return sp->push_backpatch(i, ctx->last_label());
+ return sp->push_backpatch(lex->thd, i, ctx->last_label());
}
static bool
@@ -467,7 +469,8 @@ set_local_variable(THD *thd, sp_variable *spv, Item *val)
sp_set= new (thd->mem_root)
sp_instr_set(lex->sphead->instructions(), lex->spcont,
- spv->offset, it, spv->type, lex, TRUE);
+ spv->offset, it, spv->sql_type(),
+ lex, TRUE);
return (sp_set == NULL || lex->sphead->add_instr(sp_set));
}
@@ -562,11 +565,12 @@ create_item_for_sp_var(THD *thd, LEX_STRING name, sp_variable *spvar,
DBUG_ASSERT(spc && spvar);
/* Position and length of the SP variable name in the query. */
- pos_in_q= start_in_q - lex->sphead->m_tmp_query;
- len_in_q= end_in_q - start_in_q;
+ pos_in_q= (uint)(start_in_q - lex->sphead->m_tmp_query);
+ len_in_q= (uint)(end_in_q - start_in_q);
item= new (thd->mem_root)
- Item_splocal(thd, name, spvar->offset, spvar->type, pos_in_q, len_in_q);
+ Item_splocal(thd, name, spvar->offset, spvar->sql_type(),
+ pos_in_q, len_in_q);
#ifndef DBUG_OFF
if (item)
@@ -703,47 +707,13 @@ bool add_select_to_union_list(LEX *lex, bool is_union_distinct,
return TRUE;
mysql_init_select(lex);
lex->current_select->linkage=UNION_TYPE;
+ lex->current_select->with_all_modifier= !is_union_distinct;
if (is_union_distinct) /* UNION DISTINCT - remember position */
lex->current_select->master_unit()->union_distinct=
lex->current_select;
return FALSE;
}
-/**
- @brief Initializes a SELECT_LEX for a query within parentheses (aka
- braces).
-
- @return false if successful, true if an error was reported. In the latter
- case parsing should stop.
- */
-bool setup_select_in_parentheses(LEX *lex)
-{
- SELECT_LEX * sel= lex->current_select;
- /*
- if (sel->set_braces(1))
- {
- my_parse_error(lex->thd, ER_SYNTAX_ERROR);
- return TRUE;
- }
- */
- DBUG_ASSERT(sel->braces);
- if (sel->linkage == UNION_TYPE &&
- !sel->master_unit()->first_select()->braces &&
- sel->master_unit()->first_select()->linkage ==
- UNION_TYPE)
- {
- my_parse_error(lex->thd, ER_SYNTAX_ERROR);
- return TRUE;
- }
- if (sel->linkage == UNION_TYPE &&
- sel->olap != UNSPECIFIED_OLAP_TYPE &&
- sel->master_unit()->fake_select_lex)
- {
- my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
- return TRUE;
- }
- return FALSE;
-}
static bool add_create_index_prepare(LEX *lex, Table_ident *table)
{
@@ -885,7 +855,7 @@ static void add_key_to_list(LEX *lex, LEX_STRING *field_name,
lex->alter_info.key_list.push_back(key, mem_root);
}
-void LEX::init_last_field(Create_field *field, const char *field_name,
+void LEX::init_last_field(Column_definition *field, const char *field_name,
CHARSET_INFO *cs)
{
last_field= field;
@@ -893,28 +863,25 @@ void LEX::init_last_field(Create_field *field, const char *field_name,
field->field_name= field_name;
/* reset LEX fields that are used in Create_field::set_and_check() */
- length= 0;
- dec= 0;
charset= cs;
}
-void LEX::set_last_field_type(enum enum_field_types field_type)
+void LEX::set_last_field_type(const Lex_field_type_st &type)
{
- last_field->sql_type= field_type;
- last_field->create_if_not_exists= check_exists;
+ last_field->sql_type= type.field_type();
last_field->charset= charset;
- if (length)
+ if (type.length())
{
int err;
- last_field->length= my_strtoll10(length, NULL, &err);
+ last_field->length= my_strtoll10(type.length(), NULL, &err);
if (err)
last_field->length= ~0ULL; // safety
}
else
last_field->length= 0;
- last_field->decimals= dec ? (uint)atoi(dec) : 0;
+ last_field->decimals= type.dec() ? (uint)atoi(type.dec()) : 0;
}
bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
@@ -944,6 +911,19 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
MYSQL_YYABORT; \
} while(0)
+Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
+{
+ Virtual_column_info *v= new (thd->mem_root) Virtual_column_info();
+ if (!v)
+ {
+ mem_alloc_error(sizeof(Virtual_column_info));
+ return 0;
+ }
+ v->expr= expr;
+ v->utf8= 0; /* connection charset */
+ return v;
+}
+
%}
%union {
int num;
@@ -956,8 +936,13 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
LEX_SYMBOL symbol;
struct sys_var_with_base variable;
struct { int vars, conds, hndlrs, curs; } spblock;
+ Lex_length_and_dec_st Lex_length_and_dec;
+ Lex_cast_type_st Lex_cast_type;
+ Lex_field_type_st Lex_field_type;
+ Lex_dyncol_type_st Lex_dyncol_type;
/* pointers */
+ Create_field *create_field;
CHARSET_INFO *charset;
Condition_information_item *cond_info_item;
DYNCALL_CREATE_DEF *dyncol_def;
@@ -974,11 +959,13 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
List<Item> *item_list;
List<Statement_information_item> *stmt_info_list;
List<String> *string_list;
+ List<LEX_STRING> *lex_str_list;
Statement_information_item *stmt_info_item;
String *string;
TABLE_LIST *table_list;
Table_ident *table;
char *simple_string;
+ const char *const_simple_string;
chooser_compare_func_creator boolfunc2creator;
class my_var *myvar;
class sp_condition_value *spcondvalue;
@@ -986,13 +973,18 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
class sp_label *splabel;
class sp_name *spname;
class sp_variable *spvar;
+ class With_clause *with_clause;
+ class Virtual_column_info *virtual_column;
+
handlerton *db_type;
st_select_lex *select_lex;
struct p_elem_val *p_elem_value;
+ class Window_frame *window_frame;
+ class Window_frame_bound *window_frame_bound;
udf_func *udf;
+ st_trg_execution_order trg_execution_order;
/* enums */
- enum Cast_target cast_type;
enum Condition_information_item::Name cond_info_item_name;
enum enum_diag_condition_item_name diag_condition_item_name;
enum Diagnostics_information::Which_area diag_area;
@@ -1015,6 +1007,10 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
enum sp_variable::enum_mode spvar_mode;
enum thr_lock_type lock_type;
enum enum_mysql_timestamp_type date_time_type;
+ enum Window_frame_bound::Bound_precedence_type bound_precedence_type;
+ enum Window_frame::Frame_units frame_units;
+ enum Window_frame::Frame_exclusion frame_exclusion;
+ enum trigger_order_type trigger_action_order_type;
DDL_options_st object_ddl_options;
}
@@ -1026,15 +1022,16 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 160 shift/reduce conflicts.
+ Currently there are 102 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 161
+%expect 101
/*
Comments for TOKENS.
For each token, please include in the same line a comment that contains
the following tags:
+ SQL-2011-N : Non Reserved keywird as per SQL-2011
SQL-2003-R : Reserved keyword as per SQL-2003
SQL-2003-N : Non Reserved keyword as per SQL-2003
SQL-1999-R : Reserved keyword as per SQL-1999
@@ -1152,6 +1149,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CREATE /* SQL-2003-R */
%token CROSS /* SQL-2003-R */
%token CUBE_SYM /* SQL-2003-R */
+%token CUME_DIST_SYM
%token CURDATE /* MYSQL-FUNC */
%token CURRENT_SYM /* SQL-2003-R */
%token CURRENT_USER /* SQL-2003-R */
@@ -1181,8 +1179,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DEFINER_SYM
%token DELAYED_SYM
%token DELAY_KEY_WRITE_SYM
-%token DELETE_SYM /* SQL-2003-R */
%token DELETE_DOMAIN_ID_SYM
+%token DELETE_SYM /* SQL-2003-R */
+%token DENSE_RANK_SYM
%token DESC /* SQL-2003-N */
%token DESCRIBE /* SQL-2003-R */
%token DES_KEY_FILE
@@ -1223,6 +1222,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token EVERY_SYM /* SQL-2003-N */
%token EXCHANGE_SYM
%token EXAMINED_SYM
+%token EXCLUDE_SYM /* SQL-2011-N */
%token EXECUTE_SYM /* SQL-2003-R */
%token EXISTS /* SQL-2003-R */
%token EXIT_SYM
@@ -1236,11 +1236,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token FAULTS_SYM
%token FETCH_SYM /* SQL-2003-R */
%token FILE_SYM
+%token FIRST_VALUE_SYM /* SQL-2011 */
%token FIRST_SYM /* SQL-2003-N */
%token FIXED_SYM
%token FLOAT_NUM
%token FLOAT_SYM /* SQL-2003-R */
%token FLUSH_SYM
+%token FOLLOWS_SYM /* MYSQL trigger*/
+%token FOLLOWING_SYM /* SQL-2011-N */
%token FORCE_SYM
%token FOREIGN /* SQL-2003-R */
%token FOR_SYM /* SQL-2003-R */
@@ -1262,6 +1265,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GRANTS
%token GROUP_SYM /* SQL-2003-R */
%token GROUP_CONCAT_SYM
+%token LAG_SYM /* SQL-2011 */
+%token LEAD_SYM /* SQL-2011 */
%token HANDLER_SYM
%token HARD_SYM
%token HASH_SYM
@@ -1284,6 +1289,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token IGNORE_DOMAIN_IDS_SYM
%token IGNORE_SYM
%token IGNORE_SERVER_IDS_SYM
+%token IMMEDIATE_SYM /* SQL-2003-R */
%token IMPORT
%token INDEXES
%token INDEX_SYM
@@ -1307,6 +1313,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ISSUER_SYM
%token ITERATE_SYM
%token JOIN_SYM /* SQL-2003-R */
+%token JSON_SYM
%token KEYS
%token KEY_BLOCK_SIZE
%token KEY_SYM /* SQL-2003-N */
@@ -1342,6 +1349,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token LOOP_SYM
%token LOW_PRIORITY
%token MASTER_CONNECT_RETRY_SYM
+%token MASTER_DELAY_SYM
%token MASTER_GTID_POS_SYM
%token MASTER_HOST_SYM
%token MASTER_LOG_FILE_SYM
@@ -1415,10 +1423,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NO_SYM /* SQL-2003-R */
%token NO_WAIT_SYM
%token NO_WRITE_TO_BINLOG
+%token NTILE_SYM
%token NULL_SYM /* SQL-2003-R */
%token NUM
%token NUMBER_SYM /* SQL-2003-N */
%token NUMERIC_SYM /* SQL-2003-R */
+%token NTH_VALUE_SYM /* SQL-2011 */
%token NVARCHAR_SYM
%token OFFSET_SYM
%token OLD_PASSWORD_SYM
@@ -1435,9 +1445,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ORDER_SYM /* SQL-2003-R */
%token OR_OR_SYM /* OPERATOR */
%token OR_SYM /* SQL-2003-R */
+%token OTHERS_SYM /* SQL-2011-N */
%token OUTER
%token OUTFILE
%token OUT_SYM /* SQL-2003-R */
+%token OVER_SYM
%token OWNER_SYM
%token PACK_KEYS_SYM
%token PAGE_SYM
@@ -1450,6 +1462,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PARTITIONS_SYM
%token PARTITIONING_SYM
%token PASSWORD_SYM
+%token PERCENT_RANK_SYM
%token PERSISTENT_SYM
%token PHASE_SYM
%token PLUGINS_SYM
@@ -1458,6 +1471,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token POLYGON
%token PORT_SYM
%token POSITION_SYM /* SQL-2003-N */
+%token PRECEDES_SYM /* MYSQL */
+%token PRECEDING_SYM /* SQL-2011-N */
%token PRECISION /* SQL-2003-R */
%token PREPARE_SYM /* SQL-2003-R */
%token PRESERVE_SYM
@@ -1475,6 +1490,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token QUERY_SYM
%token QUICK
%token RANGE_SYM /* SQL-2003-R */
+%token RANK_SYM
%token READS_SYM /* SQL-2003-R */
%token READ_ONLY_SYM
%token READ_SYM /* SQL-2003-N */
@@ -1482,6 +1498,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token REAL /* SQL-2003-R */
%token REBUILD_SYM
%token RECOVER_SYM
+%token RECURSIVE_SYM
%token REDOFILE_SYM
%token REDO_BUFFER_SIZE_SYM
%token REDUNDANT_SYM
@@ -1520,10 +1537,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ROLLBACK_SYM /* SQL-2003-R */
%token ROLLUP_SYM /* SQL-2003-R */
%token ROUTINE_SYM /* SQL-2003-N */
-%token ROWS_SYM /* SQL-2003-R */
-%token ROW_FORMAT_SYM
%token ROW_SYM /* SQL-2003-R */
+%token ROWS_SYM /* SQL-2003-R */
%token ROW_COUNT_SYM /* SQL-2003-N */
+%token ROW_FORMAT_SYM
+%token ROW_NUMBER_SYM
%token RTREE_SYM
%token SAVEPOINT_SYM /* SQL-2003-R */
%token SCHEDULE_SYM
@@ -1587,6 +1605,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token STD_SYM
%token STOP_SYM
%token STORAGE_SYM
+%token STORED_SYM
%token STRAIGHT_JOIN
%token STRING_SYM
%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */
@@ -1614,6 +1633,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token TEXT_SYM
%token THAN_SYM
%token THEN_SYM /* SQL-2003-R */
+%token TIES_SYM /* SQL-2011-N */
%token TIMESTAMP /* SQL-2003-R */
%token TIMESTAMP_ADD
%token TIMESTAMP_DIFF
@@ -1634,6 +1654,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token TYPE_SYM /* SQL-2003-N */
%token UDF_RETURNS_SYM
%token ULONGLONG_NUM
+%token UNBOUNDED_SYM /* SQL-2011-N */
%token UNCOMMITTED_SYM /* SQL-2003-N */
%token UNDEFINED_SYM
%token UNDERSCORE_CHARSET
@@ -1675,6 +1696,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token WEIGHT_STRING_SYM
%token WHEN_SYM /* SQL-2003-R */
%token WHERE /* SQL-2003-R */
+%token WINDOW_SYM
%token WHILE_SYM
%token WITH /* SQL-2003-R */
%token WITH_CUBE_SYM /* INTERNAL */
@@ -1719,7 +1741,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
NCHAR_STRING opt_component key_cache_name
sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
- opt_constraint constraint opt_ident
+ opt_constraint constraint opt_ident ident_table_alias
%type <lex_str_ptr>
opt_table_alias
@@ -1729,13 +1751,25 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
table_ident_opt_wild create_like
%type <simple_string>
- remember_name remember_end opt_db remember_tok_start
+ remember_name remember_end opt_db
+ remember_tok_start remember_tok_end
wild_and_where
+ field_length opt_field_length opt_field_length_default_1
+
+%type <const_simple_string>
+ opt_place
%type <string>
text_string hex_or_bin_String opt_gconcat_separator
-%type <field_type> type_with_opt_collate int_type real_type field_type
+%type <field_type> int_type real_type
+
+%type <Lex_field_type> type_with_opt_collate field_type
+
+%type <Lex_dyncol_type> opt_dyncol_type dyncol_type
+ numeric_dyncol_type temporal_dyncol_type string_dyncol_type
+
+%type <create_field> field_spec column_def
%type <geom_type> spatial_type
@@ -1744,17 +1778,17 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
udf_type opt_local opt_no_write_to_binlog
opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options union_option
- opt_not opt_union_order_or_limit
- union_opt select_derived_init transaction_access_mode_types
+ opt_not
+ select_derived_init transaction_access_mode_types
opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
- optional_flush_tables_arguments opt_dyncol_type dyncol_type
+ optional_flush_tables_arguments
opt_time_precision kill_type kill_option int_num
opt_default_time_precision
case_stmt_body opt_bin_mod
opt_if_exists_table_element opt_if_not_exists_table_element
- opt_into opt_procedure_clause
+ opt_recursive
%type <object_ddl_options>
create_or_replace
@@ -1793,15 +1827,18 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
literal text_literal insert_ident order_ident temporal_literal
simple_ident expr opt_expr opt_else sum_expr in_sum_expr
variable variable_aux bool_pri
- predicate bit_expr
- table_wild simple_expr udf_expr
+ predicate bit_expr parenthesized_expr
+ table_wild simple_expr column_default_non_parenthesized_expr udf_expr
expr_or_default set_expr_or_default
- geometry_function
- signed_literal now_or_signed_literal opt_escape
+ geometry_function signed_literal expr_or_literal
+ opt_escape
sp_opt_default
simple_ident_nospvar simple_ident_q
field_or_var limit_option
part_func_expr
+ window_func_expr
+ window_func
+ simple_window_func
function_call_keyword
function_call_nonkeyword
function_call_generic
@@ -1837,9 +1874,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <table_list>
join_table_list join_table
table_factor table_ref esc_table_ref
+ table_primary_ident table_primary_derived
select_derived derived_table_list
select_derived_union
-
+ derived_query_specification
%type <date_time_type> date_time_type;
%type <interval> interval
@@ -1853,9 +1891,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <ha_rkey_mode> handler_rkey_mode
-%type <cast_type> cast_type
+%type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal
-%type <symbol> keyword keyword_sp
+%type <Lex_length_and_dec> precision opt_precision float_options
+
+%type <symbol> keyword keyword_sp keyword_alias
%type <lex_user> user grant_user grant_role user_or_role current_role
admin_option_for_role user_maybe_role
@@ -1875,8 +1915,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <variable> internal_variable_name
%type <select_lex> subselect
- get_select_lex query_specification
+ get_select_lex get_select_lex_derived
+ query_specification
+ query_term_union_not_ready
+ query_term_union_ready
query_expression_body
+ select_paren_derived
%type <boolfunc2creator> comp_op
@@ -1886,6 +1930,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <myvar> select_outvar
+%type <virtual_column> opt_check_constraint check_constraint virtual_column_func
+ column_default_expr
+
%type <NONE>
analyze_stmt_command
query verb_clause create change select do drop insert replace insert2
@@ -1899,7 +1946,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
persistent_column_stat_spec persistent_index_stat_spec
table_column_list table_index_list table_index_name
check start checksum
- field_list field_list_item field_spec kill column_def key_def
+ field_list field_list_item kill key_def constraint_def
keycache_list keycache_list_or_parts assign_to_keycache
assign_to_keycache_parts
preload_list preload_list_or_parts preload_keys preload_keys_parts
@@ -1907,13 +1954,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_limit_clause delete_limit_clause fields opt_values values
procedure_list procedure_list2 procedure_item
field_def handler opt_generated_always
- opt_precision opt_ignore opt_column opt_restrict
- grant revoke set lock unlock string_list field_options field_option
- field_opt_list opt_binary table_lock_list table_lock
+ opt_ignore opt_column opt_restrict
+ grant revoke set lock unlock string_list field_options
+ opt_binary table_lock_list table_lock
ref_list opt_match_clause opt_on_update_delete use
opt_delete_options opt_delete_option varchar nchar nvarchar
opt_outer table_list table_name table_alias_ref_list table_alias_ref
- opt_place
opt_attribute opt_attribute_list attribute column_list column_list_id
opt_column_list grant_privileges grant_ident grant_list grant_option
object_privilege object_privilege_list user_list user_and_role_list
@@ -1926,9 +1972,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
handler_rkey_function handler_read_or_scan
single_multi table_wild_list table_wild_one opt_wild
union_clause union_list
- precision subselect_start opt_and charset
+ subselect_start opt_and charset
subselect_end select_var_list select_var_list_init help
- field_length opt_field_length
opt_extended_describe shutdown
opt_format_json
prepare prepare_src execute deallocate
@@ -1951,12 +1996,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
definer_opt no_definer definer get_diagnostics
parse_vcol_expr vcol_opt_specifier vcol_opt_attribute
vcol_opt_attribute_list vcol_attribute
+ opt_serial_attribute opt_serial_attribute_list serial_attribute
explainable_command
opt_delete_gtid_domain
END_OF_INPUT
%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
+ sp_proc_stmt_in_returns_clause
%type <NONE> sp_proc_stmt_compound_ok
%type <NONE> sp_proc_stmt_if
%type <NONE> sp_labeled_control sp_unlabeled_control
@@ -1982,6 +2029,9 @@ END_OF_INPUT
%type <NONE> signal_stmt resignal_stmt
%type <diag_condition_item_name> signal_condition_information_item_name
+%type <trg_execution_order> trigger_follows_precedes_clause;
+%type <trigger_action_order_type> trigger_action_order;
+
%type <diag_area> which_area;
%type <diag_info> diagnostics_information;
%type <stmt_info_item> statement_information_item;
@@ -1991,12 +2041,27 @@ END_OF_INPUT
%type <cond_info_item_name> condition_information_item_name;
%type <cond_info_list> condition_information;
+%type <NONE> opt_window_clause window_def_list window_def window_spec
+%type <lex_str_ptr> window_name
+%type <NONE> opt_window_ref opt_window_frame_clause
+%type <frame_units> window_frame_units;
+%type <NONE> window_frame_extent;
+%type <frame_exclusion> opt_window_frame_exclusion;
+%type <window_frame_bound> window_frame_start window_frame_bound;
+
+
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
ROLE_SYM
+%type <with_clause> opt_with_clause with_clause
+
+%type <lex_str_ptr> query_name
+
+%type <lex_str_list> opt_with_column_list
+
%%
@@ -2152,23 +2217,20 @@ prepare:
PREPARE_SYM ident FROM prepare_src
{
LEX *lex= thd->lex;
+ if (lex->table_or_sp_used())
+ my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
+ "PREPARE..FROM"));
lex->sql_command= SQLCOM_PREPARE;
lex->prepared_stmt_name= $2;
}
;
prepare_src:
- TEXT_STRING_sys
- {
- LEX *lex= thd->lex;
- lex->prepared_stmt_code= $1;
- lex->prepared_stmt_code_is_varref= FALSE;
- }
- | '@' ident_or_text
+ { Lex->expr_allows_subselect= false; }
+ expr
{
- LEX *lex= thd->lex;
- lex->prepared_stmt_code= $2;
- lex->prepared_stmt_code_is_varref= TRUE;
+ Lex->prepared_stmt_code= $2;
+ Lex->expr_allows_subselect= true;
}
;
@@ -2181,11 +2243,27 @@ execute:
}
execute_using
{}
+ | EXECUTE_SYM IMMEDIATE_SYM prepare_src
+ {
+ if (Lex->table_or_sp_used())
+ my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
+ "EXECUTE IMMEDIATE"));
+ Lex->sql_command= SQLCOM_EXECUTE_IMMEDIATE;
+ }
+ execute_using
+ {}
;
execute_using:
/* nothing */
- | USING execute_var_list
+ | USING { Lex->expr_allows_subselect= false; }
+ execute_var_list
+ {
+ if (Lex->table_or_sp_used())
+ my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0),
+ "EXECUTE..USING"));
+ Lex->expr_allows_subselect= true;
+ }
;
execute_var_list:
@@ -2194,12 +2272,9 @@ execute_var_list:
;
execute_var_ident:
- '@' ident_or_text
+ expr_or_default
{
- LEX *lex=Lex;
- LEX_STRING *lexstr= (LEX_STRING*)thd->memdup(&$2, sizeof(LEX_STRING));
- if (!lexstr || lex->prepared_stmt_params.push_back(lexstr,
- thd->mem_root))
+ if (Lex->prepared_stmt_params.push_back($1, thd->mem_root))
MYSQL_YYABORT;
}
;
@@ -2257,6 +2332,16 @@ master_def:
{
Lex->mi.connect_retry = $3;
}
+ | MASTER_DELAY_SYM '=' ulong_num
+ {
+ if ($3 > MASTER_DELAY_MAX)
+ {
+ my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0),
+ (uint) $3, (uint) MASTER_DELAY_MAX);
+ }
+ else
+ Lex->mi.sql_delay = $3;
+ }
| MASTER_SSL_SYM '=' ulong_num
{
Lex->mi.ssl= $3 ?
@@ -2389,9 +2474,9 @@ master_file_def:
If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
instead of causing subsequent errors.
We need to do it in this file, because only there we know that
- MASTER_LOG_POS has been explicitely specified. On the contrary
+ MASTER_LOG_POS has been explicitly specified. On the contrary
in change_master() (sql_repl.cc) we cannot distinguish between 0
- (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
+ (MASTER_LOG_POS explicitly specified as 0) and 0 (unspecified),
whereas we want to distinguish (specified 0 means "read the binlog
from 0" (4 in fact), unspecified means "don't change the position
(keep the preceding value)").
@@ -2532,6 +2617,7 @@ create:
}
view_or_trigger_or_sp_or_event { }
| create_or_replace USER_SYM opt_if_not_exists clear_privileges grant_list
+ opt_require_clause opt_resource_options
{
if (Lex->set_command_with_check(SQLCOM_CREATE_USER, $1 | $3))
MYSQL_YYABORT;
@@ -2920,9 +3006,7 @@ sp_param_name_and_type:
LEX *lex= Lex;
sp_variable *spvar= $<spvar>2;
- spvar->type= $3;
- if (lex->sphead->fill_field_definition(thd, lex, $3,
- lex->last_field))
+ if (lex->sphead->fill_field_definition(thd, lex, lex->last_field))
{
MYSQL_YYABORT;
}
@@ -3009,7 +3093,6 @@ sp_decl:
LEX *lex= Lex;
sp_pcontext *pctx= lex->spcont;
uint num_vars= pctx->context_var_count();
- enum enum_field_types var_type= $4;
Item *dflt_value_item= $5;
if (!dflt_value_item)
@@ -3032,11 +3115,10 @@ sp_decl:
if (!last)
spvar->field_def= *lex->last_field;
- spvar->type= var_type;
spvar->default_value= dflt_value_item;
spvar->field_def.field_name= spvar->name.str;
- if (lex->sphead->fill_field_definition(thd, lex, var_type,
+ if (lex->sphead->fill_field_definition(thd, lex,
&spvar->field_def))
{
MYSQL_YYABORT;
@@ -3046,10 +3128,10 @@ sp_decl:
/* The last instruction is responsible for freeing LEX. */
- sp_instr_set *is= new (thd->mem_root)
- sp_instr_set(lex->sphead->instructions(),
+ sp_instr_set *is= new (lex->thd->mem_root)
+ sp_instr_set(lex->sphead->instructions(),
pctx, var_idx, dflt_value_item,
- var_type, lex, last);
+ $4.field_type(), lex, last);
if (is == NULL || lex->sphead->add_instr(is))
MYSQL_YYABORT;
}
@@ -3093,10 +3175,10 @@ sp_decl:
/* For continue handlers, mark end of handler scope. */
if ($2 == sp_handler::CONTINUE &&
- sp->push_backpatch(i, ctx->last_label()))
+ sp->push_backpatch(thd, i, ctx->last_label()))
MYSQL_YYABORT;
- if (sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)))
+ if (sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)))
MYSQL_YYABORT;
}
sp_hcond_list sp_proc_stmt
@@ -3121,7 +3203,7 @@ sp_decl:
sp_instr_hreturn(sp->instructions(), ctx);
if (i == NULL ||
sp->add_instr(i) ||
- sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */
+ sp->push_backpatch(thd, i, lex->spcont->last_label())) /* Block end */
MYSQL_YYABORT;
}
lex->sphead->backpatch(hlab);
@@ -3467,6 +3549,7 @@ statement_information_item:
if ($$ == NULL)
MYSQL_YYABORT;
}
+ ;
simple_target_specification:
ident
@@ -3524,6 +3607,7 @@ condition_information_item:
if ($$ == NULL)
MYSQL_YYABORT;
}
+ ;
condition_information_item_name:
CLASS_ORIGIN_SYM
@@ -3586,18 +3670,31 @@ sp_opt_default:
| DEFAULT expr { $$ = $2; }
;
-sp_proc_stmt:
- sp_proc_stmt_statement
- | sp_proc_stmt_return
+/*
+ ps_proc_stmt_in_returns_clause is a statement that is allowed
+ in the RETURNS clause of a stored function definition directly,
+ without the BEGIN..END block.
+ It should not include any syntax structures starting with '(', to avoid
+ shift/reduce conflicts with the rule "field_type" and its sub-rules
+ that scan an optional length, like CHAR(1) or YEAR(4).
+ See MDEV-9166.
+*/
+sp_proc_stmt_in_returns_clause:
+ sp_proc_stmt_return
| sp_labeled_block
| sp_unlabeled_block
| sp_labeled_control
+ | sp_proc_stmt_compound_ok
+ ;
+
+sp_proc_stmt:
+ sp_proc_stmt_in_returns_clause
+ | sp_proc_stmt_statement
| sp_proc_stmt_leave
| sp_proc_stmt_iterate
| sp_proc_stmt_open
| sp_proc_stmt_fetch
| sp_proc_stmt_close
- | sp_proc_stmt_compound_ok
;
sp_proc_stmt_compound_ok:
@@ -3740,7 +3837,7 @@ sp_proc_stmt_leave:
i= new (thd->mem_root) sp_instr_jump(ip, ctx);
if (i == NULL)
MYSQL_YYABORT;
- sp->push_backpatch(i, lab); /* Jumping forward */
+ sp->push_backpatch(thd, i, lab); /* Jumping forward */
sp->add_instr(i);
}
;
@@ -3890,7 +3987,7 @@ sp_if:
sp_instr_jump_if_not *i= new (thd->mem_root)
sp_instr_jump_if_not(ip, ctx, $2, lex);
if (i == NULL ||
- sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0)) ||
+ sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0)) ||
sp->add_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
@@ -3907,7 +4004,7 @@ sp_if:
sp->add_instr(i))
MYSQL_YYABORT;
sp->backpatch(ctx->pop_label());
- sp->push_backpatch(i, ctx->push_label(thd, empty_lex_str, 0));
+ sp->push_backpatch(thd, i, ctx->push_label(thd, empty_lex_str, 0));
}
sp_elseifs
{
@@ -4192,7 +4289,7 @@ while_body:
sp_instr_jump_if_not(ip, lex->spcont, $1, lex);
if (i == NULL ||
/* Jumping forward */
- sp->push_backpatch(i, lex->spcont->last_label()) ||
+ sp->push_backpatch(thd, i, lex->spcont->last_label()) ||
sp->new_cont_backpatch(i) ||
sp->add_instr(i))
MYSQL_YYABORT;
@@ -4704,7 +4801,11 @@ create_body:
conflict that prevents the rule above from parsing a syntax like
CREATE TABLE t1 (SELECT 1);
*/
- | '(' create_select ')' { Select->set_braces(1);} union_opt {}
+ | '(' create_select_query_specification ')'
+ | '(' create_select_query_specification ')'
+ { Select->set_braces(1);} union_list {}
+ | '(' create_select_query_specification ')'
+ { Select->set_braces(1);} union_order_or_limit {}
| create_like
{
@@ -4725,12 +4826,27 @@ create_like:
opt_create_select:
/* empty */ {}
- | opt_duplicate opt_as create_select
- { Select->set_braces(0);}
- union_clause {}
- | opt_duplicate opt_as '(' create_select ')'
- { Select->set_braces(1);}
- union_opt {}
+ | opt_duplicate opt_as create_select_query_expression
+ ;
+
+create_select_query_expression:
+ opt_with_clause SELECT_SYM create_select_part2 opt_table_expression
+ create_select_part4
+ {
+ Select->set_braces(0);
+ Select->set_with_clause($1);
+ }
+ union_clause
+ | opt_with_clause SELECT_SYM create_select_part2
+ create_select_part3_union_not_ready create_select_part4
+ {
+ Select->set_with_clause($1);
+ }
+ | '(' create_select_query_specification ')'
+ | '(' create_select_query_specification ')'
+ { Select->set_braces(1);} union_list {}
+ | '(' create_select_query_specification ')'
+ { Select->set_braces(1);} union_order_or_limit {}
;
opt_create_partitioning:
@@ -4749,7 +4865,7 @@ opt_create_partitioning:
/*
This part of the parser is about handling of the partition information.
- It's first version was written by Mikael Ronström with lots of answers to
+ It's first version was written by Mikael Ronstrm with lots of answers to
questions provided by Antony Curtis.
The partition grammar can be called from three places.
@@ -4826,7 +4942,9 @@ partition_entry:
;
partition:
- BY part_type_def opt_num_parts opt_sub_part part_defs
+ BY
+ { Lex->safe_to_cache_query= 1; }
+ part_type_def opt_num_parts opt_sub_part part_defs
;
part_type_def:
@@ -4915,7 +5033,7 @@ part_func:
'(' remember_name part_func_expr remember_end ')'
{
partition_info *part_info= Lex->part_info;
- if (part_info->set_part_expr($2+1, $3, $4, FALSE))
+ if (part_info->set_part_expr(thd, $2 + 1, $3, $4, FALSE))
{ MYSQL_YYABORT; }
part_info->num_columns= 1;
part_info->column_list= FALSE;
@@ -4925,7 +5043,7 @@ part_func:
sub_part_func:
'(' remember_name part_func_expr remember_end ')'
{
- if (Lex->part_info->set_part_expr($2+1, $3, $4, TRUE))
+ if (Lex->part_info->set_part_expr(thd, $2 + 1, $3, $4, TRUE))
{ MYSQL_YYABORT; }
}
;
@@ -4983,11 +5101,7 @@ sub_part_field_item:
part_func_expr:
bit_expr
{
- LEX *lex= Lex;
- bool not_corr_func;
- not_corr_func= !lex->safe_to_cache_query;
- lex->safe_to_cache_query= 1;
- if (not_corr_func)
+ if (!Lex->safe_to_cache_query)
{
my_parse_error(thd, ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR);
MYSQL_YYABORT;
@@ -5123,6 +5237,27 @@ opt_part_values:
part_info->part_type= LIST_PARTITION;
}
part_values_in {}
+ | DEFAULT
+ {
+ LEX *lex= Lex;
+ partition_info *part_info= lex->part_info;
+ if (! lex->is_partition_management())
+ {
+ if (part_info->part_type != LIST_PARTITION)
+ my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
+ "LIST", "DEFAULT"));
+ }
+ else
+ part_info->part_type= LIST_PARTITION;
+ if (part_info->init_column_part(thd))
+ {
+ MYSQL_YYABORT;
+ }
+ if (part_info->add_max_value(thd))
+ {
+ MYSQL_YYABORT;
+ }
+ }
;
part_func_max:
@@ -5407,8 +5542,15 @@ opt_part_option:
End of partition parser part
*/
-create_select:
- SELECT_SYM
+create_select_query_specification:
+ opt_with_clause SELECT_SYM create_select_part2 create_select_part3
+ create_select_part4
+ {
+ Select->set_with_clause($1);
+ }
+ ;
+
+create_select_part2:
{
LEX *lex=Lex;
if (lex->sql_command == SQLCOM_INSERT)
@@ -5427,7 +5569,20 @@ create_select:
{
Select->parsing_place= NO_MATTER;
}
- table_expression
+ ;
+
+create_select_part3:
+ opt_table_expression
+ | create_select_part3_union_not_ready
+ ;
+
+create_select_part3_union_not_ready:
+ table_expression order_or_limit
+ | order_or_limit
+ ;
+
+create_select_part4:
+ opt_select_lock_type
{
/*
The following work only with the local list, the global list
@@ -5840,13 +5995,16 @@ field_list:
;
field_list_item:
- column_def
+ column_def { }
| key_def
+ | constraint_def
;
column_def:
- field_spec opt_check_constraint
+ field_spec
+ { $$= $1; }
| field_spec references
+ { $$= $1; }
;
key_def:
@@ -5930,16 +6088,36 @@ key_def:
/* Only used for ALTER TABLE. Ignored otherwise. */
lex->alter_info.flags|= Alter_info::ADD_FOREIGN_KEY;
}
- | opt_constraint check_constraint { }
- ;
+ ;
+
+constraint_def:
+ opt_constraint check_constraint
+ {
+ Lex->add_constraint(&$1, $2, FALSE);
+ }
+ ;
opt_check_constraint:
- /* empty */
- | check_constraint
+ /* empty */ { $$= (Virtual_column_info*) 0; }
+ | check_constraint { $$= $1;}
;
check_constraint:
CHECK_SYM '(' expr ')'
+ {
+ Virtual_column_info *v=
+ add_virtual_expression(thd, $3);
+ if (!v)
+ {
+ MYSQL_YYABORT;
+ }
+ $$= v;
+ }
+ ;
+
+opt_constraint_no_id:
+ /* Empty */ {}
+ | CONSTRAINT {}
;
opt_constraint:
@@ -5965,29 +6143,59 @@ field_spec:
MYSQL_YYABORT;
lex->init_last_field(f, $1.str, NULL);
+ $<create_field>$= f;
}
- field_type { Lex->set_last_field_type($3); }
- field_def
+ field_type_or_serial opt_check_constraint
{
LEX *lex=Lex;
- Create_field *f= lex->last_field;
+ $$= $<create_field>2;
+
+ $$->check_constraint= $4;
- if (f->check(thd))
+ if ($$->check(thd))
MYSQL_YYABORT;
- lex->alter_info.create_list.push_back(f, thd->mem_root);
+ lex->alter_info.create_list.push_back($$, thd->mem_root);
- if (f->flags & PRI_KEY_FLAG)
+ $$->create_if_not_exists= Lex->check_exists;
+ if ($$->flags & PRI_KEY_FLAG)
add_key_to_list(lex, &$1, Key::PRIMARY, Lex->check_exists);
- else if (f->flags & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
+ else if ($$->flags & UNIQUE_KEY_FLAG)
add_key_to_list(lex, &$1, Key::UNIQUE, Lex->check_exists);
}
;
+field_type_or_serial:
+ field_type { Lex->set_last_field_type($1); } field_def
+ | SERIAL_SYM
+ {
+ Lex_field_type_st type;
+ type.set(MYSQL_TYPE_LONGLONG);
+ Lex->set_last_field_type(type);
+ Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG
+ | UNSIGNED_FLAG | UNIQUE_KEY_FLAG;
+ }
+ opt_serial_attribute
+ ;
+
+opt_serial_attribute:
+ /* empty */ {}
+ | opt_serial_attribute_list {}
+ ;
+
+opt_serial_attribute_list:
+ opt_serial_attribute_list serial_attribute {}
+ | serial_attribute
+ ;
+
+
field_def:
opt_attribute
- | opt_generated_always AS
- '(' virtual_column_func ')'
+ | opt_generated_always AS virtual_column_func
+ {
+ Lex->last_field->vcol_info= $3;
+ Lex->last_field->flags&= ~NOT_NULL_FLAG; // undo automatic NOT NULL for timestamps
+ }
vcol_opt_specifier vcol_opt_attribute
;
@@ -6009,6 +6217,10 @@ vcol_opt_specifier:
{
Lex->last_field->vcol_info->set_stored_in_db_flag(TRUE);
}
+ | STORED_SYM
+ {
+ Lex->last_field->vcol_info->set_stored_in_db_flag(TRUE);
+ }
;
vcol_opt_attribute:
@@ -6025,136 +6237,143 @@ vcol_attribute:
UNIQUE_SYM
{
LEX *lex=Lex;
- lex->last_field->flags|= UNIQUE_FLAG;
+ lex->last_field->flags|= UNIQUE_KEY_FLAG;
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
| UNIQUE_SYM KEY_SYM
{
LEX *lex=Lex;
- lex->last_field->flags|= UNIQUE_FLAG;
+ lex->last_field->flags|= UNIQUE_KEY_FLAG;
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
| COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
;
parse_vcol_expr:
- PARSE_VCOL_EXPR_SYM '(' virtual_column_func ')'
+ PARSE_VCOL_EXPR_SYM
{
/*
"PARSE_VCOL_EXPR" can only be used by the SQL server
when reading a '*.frm' file.
Prevent the end user from invoking this command.
*/
- if (!Lex->parse_vcol_expr)
- my_yyabort_error((ER_SYNTAX_ERROR, MYF(0)));
+ MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr);
+ }
+ expr
+ {
+ Virtual_column_info *v= add_virtual_expression(thd, $3);
+ if (!v)
+ MYSQL_YYABORT;
+ Lex->last_field->vcol_info= v;
}
;
+parenthesized_expr:
+ subselect
+ {
+ $$= new (thd->mem_root) Item_singlerow_subselect(thd, $1);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | expr
+ | expr ',' expr_list
+ {
+ $3->push_front($1, thd->mem_root);
+ $$= new (thd->mem_root) Item_row(thd, *$3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
virtual_column_func:
- remember_name expr remember_end
+ '(' parenthesized_expr ')'
{
- Virtual_column_info *v= new (thd->mem_root) Virtual_column_info();
+ Virtual_column_info *v=
+ add_virtual_expression(thd, $2);
if (!v)
{
- mem_alloc_error(sizeof(Virtual_column_info));
MYSQL_YYABORT;
}
- uint expr_len= (uint)($3 - $1) - 1;
- v->expr_str.str= (char* ) thd->memdup($1 + 1, expr_len);
- v->expr_str.length= expr_len;
- v->expr_item= $2;
- Lex->last_field->vcol_info= v;
+ $$= v;
+ }
+ ;
+
+expr_or_literal: column_default_non_parenthesized_expr | signed_literal ;
+
+column_default_expr:
+ virtual_column_func
+ | expr_or_literal
+ {
+ if (!($$= add_virtual_expression(thd, $1)))
+ MYSQL_YYABORT;
}
;
field_type:
- int_type opt_field_length field_options { $$=$1; }
- | real_type opt_precision field_options { $$=$1; }
+ int_type opt_field_length field_options { $$.set($1, $2); }
+ | real_type opt_precision field_options { $$.set($1, $2); }
| FLOAT_SYM float_options field_options
{
- $$=MYSQL_TYPE_FLOAT;
- if (Lex->length && !Lex->dec)
+ $$.set(MYSQL_TYPE_FLOAT, $2);
+ if ($2.length() && !$2.dec())
{
int err;
- ulonglong tmp_length= my_strtoll10(Lex->length, NULL, &err);
+ ulonglong tmp_length= my_strtoll10($2.length(), NULL, &err);
if (err || tmp_length > PRECISION_FOR_DOUBLE)
my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0),
Lex->last_field->field_name));
if (tmp_length > PRECISION_FOR_FLOAT)
- $$= MYSQL_TYPE_DOUBLE;
- Lex->length= 0;
+ $$.set(MYSQL_TYPE_DOUBLE);
+ else
+ $$.set(MYSQL_TYPE_FLOAT);
}
}
- | BIT_SYM
+ | BIT_SYM opt_field_length_default_1
{
- Lex->length= (char*) "1";
- $$=MYSQL_TYPE_BIT;
- }
- | BIT_SYM field_length
- {
- $$=MYSQL_TYPE_BIT;
+ $$.set(MYSQL_TYPE_BIT, $2);
}
| BOOL_SYM
{
- Lex->length= (char*) "1";
- $$=MYSQL_TYPE_TINY;
+ $$.set(MYSQL_TYPE_TINY, "1");
}
| BOOLEAN_SYM
{
- Lex->length= (char*) "1";
- $$=MYSQL_TYPE_TINY;
- }
- | char field_length opt_binary
- {
- $$=MYSQL_TYPE_STRING;
+ $$.set(MYSQL_TYPE_TINY, "1");
}
- | char opt_binary
+ | char opt_field_length_default_1 opt_binary
{
- Lex->length= (char*) "1";
- $$=MYSQL_TYPE_STRING;
+ $$.set(MYSQL_TYPE_STRING, $2);
}
- | nchar field_length opt_bin_mod
+ | nchar opt_field_length_default_1 opt_bin_mod
{
- $$=MYSQL_TYPE_STRING;
+ $$.set(MYSQL_TYPE_STRING, $2);
bincmp_collation(national_charset_info, $3);
}
- | nchar opt_bin_mod
- {
- Lex->length= (char*) "1";
- $$=MYSQL_TYPE_STRING;
- bincmp_collation(national_charset_info, $2);
- }
- | BINARY field_length
- {
- Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_STRING;
- }
- | BINARY
+ | BINARY opt_field_length_default_1
{
- Lex->length= (char*) "1";
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_STRING;
+ $$.set(MYSQL_TYPE_STRING, $2);
}
| varchar field_length opt_binary
{
- $$= MYSQL_TYPE_VARCHAR;
+ $$.set(MYSQL_TYPE_VARCHAR, $2);
}
| nvarchar field_length opt_bin_mod
{
- $$= MYSQL_TYPE_VARCHAR;
+ $$.set(MYSQL_TYPE_VARCHAR, $2);
bincmp_collation(national_charset_info, $3);
}
| VARBINARY field_length
{
Lex->charset=&my_charset_bin;
- $$= MYSQL_TYPE_VARCHAR;
+ $$.set(MYSQL_TYPE_VARCHAR, $2);
}
| YEAR_SYM opt_field_length field_options
{
- if (Lex->length)
+ if ($2)
{
errno= 0;
- ulong length= strtoul(Lex->length, NULL, 10);
+ ulong length= strtoul($2, NULL, 10);
if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4)
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
@@ -6165,18 +6384,18 @@ field_type:
buff, "YEAR(4)");
}
}
- $$=MYSQL_TYPE_YEAR;
+ $$.set(MYSQL_TYPE_YEAR, $2);
}
| DATE_SYM
- { $$=MYSQL_TYPE_DATE; }
+ { $$.set(MYSQL_TYPE_DATE); }
| TIME_SYM opt_field_length
- { $$= opt_mysql56_temporal_format ?
- MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME; }
+ { $$.set(opt_mysql56_temporal_format ?
+ MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); }
| TIMESTAMP opt_field_length
{
if (thd->variables.sql_mode & MODE_MAXDB)
- $$= opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME;
+ $$.set(opt_mysql56_temporal_format ?
+ MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2);
else
{
/*
@@ -6185,29 +6404,29 @@ field_type:
*/
if (!opt_explicit_defaults_for_timestamp)
Lex->last_field->flags|= NOT_NULL_FLAG;
- $$= opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2
- : MYSQL_TYPE_TIMESTAMP;
+ $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2
+ : MYSQL_TYPE_TIMESTAMP, $2);
}
}
| DATETIME opt_field_length
- { $$= opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME; }
+ { $$.set(opt_mysql56_temporal_format ?
+ MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); }
| TINYBLOB
{
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_TINY_BLOB;
+ $$.set(MYSQL_TYPE_TINY_BLOB);
}
| BLOB_SYM opt_field_length
{
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_BLOB;
+ $$.set(MYSQL_TYPE_BLOB, $2);
}
| spatial_type float_options srid_option
{
#ifdef HAVE_SPATIAL
Lex->charset=&my_charset_bin;
Lex->last_field->geom_type= $1;
- $$=MYSQL_TYPE_GEOMETRY;
+ $$.set(MYSQL_TYPE_GEOMETRY, $2);
#else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define));
@@ -6216,57 +6435,51 @@ field_type:
| MEDIUMBLOB
{
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_MEDIUM_BLOB;
+ $$.set(MYSQL_TYPE_MEDIUM_BLOB);
}
| LONGBLOB
{
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_LONG_BLOB;
+ $$.set(MYSQL_TYPE_LONG_BLOB);
}
| LONG_SYM VARBINARY
{
Lex->charset=&my_charset_bin;
- $$=MYSQL_TYPE_MEDIUM_BLOB;
+ $$.set(MYSQL_TYPE_MEDIUM_BLOB);
}
| LONG_SYM varchar opt_binary
- { $$=MYSQL_TYPE_MEDIUM_BLOB; }
+ { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
| TINYTEXT opt_binary
- { $$=MYSQL_TYPE_TINY_BLOB; }
+ { $$.set(MYSQL_TYPE_TINY_BLOB); }
| TEXT_SYM opt_field_length opt_binary
- { $$=MYSQL_TYPE_BLOB; }
+ { $$.set(MYSQL_TYPE_BLOB, $2); }
| MEDIUMTEXT opt_binary
- { $$=MYSQL_TYPE_MEDIUM_BLOB; }
+ { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
| LONGTEXT opt_binary
- { $$=MYSQL_TYPE_LONG_BLOB; }
+ { $$.set(MYSQL_TYPE_LONG_BLOB); }
| DECIMAL_SYM float_options field_options
- { $$=MYSQL_TYPE_NEWDECIMAL;}
+ { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
| NUMERIC_SYM float_options field_options
- { $$=MYSQL_TYPE_NEWDECIMAL;}
+ { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
| FIXED_SYM float_options field_options
- { $$=MYSQL_TYPE_NEWDECIMAL;}
+ { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
| ENUM '(' string_list ')' opt_binary
- { $$=MYSQL_TYPE_ENUM; }
+ { $$.set(MYSQL_TYPE_ENUM); }
| SET '(' string_list ')' opt_binary
- { $$=MYSQL_TYPE_SET; }
+ { $$.set(MYSQL_TYPE_SET); }
| LONG_SYM opt_binary
- { $$=MYSQL_TYPE_MEDIUM_BLOB; }
- | SERIAL_SYM
+ { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ | JSON_SYM
{
- $$=MYSQL_TYPE_LONGLONG;
- Lex->last_field->flags|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
- UNIQUE_FLAG);
+ Lex->charset= &my_charset_utf8mb4_bin;
+ $$.set(MYSQL_TYPE_LONG_BLOB);
}
;
spatial_type:
GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; }
| GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; }
- | POINT_SYM
- {
- Lex->length= const_cast<char*>(STRINGIFY_ARG
- (MAX_LEN_GEOM_POINT_FIELD));
- $$= Field::GEOM_POINT;
- }
+ | POINT_SYM { $$= Field::GEOM_POINT; }
| MULTIPOINT { $$= Field::GEOM_MULTIPOINT; }
| LINESTRING { $$= Field::GEOM_LINESTRING; }
| MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; }
@@ -6327,53 +6540,44 @@ srid_option:
;
float_options:
- /* empty */
- { Lex->dec=Lex->length= (char*)0; }
- | field_length
- { Lex->dec= (char*)0; }
- | precision
- {}
+ /* empty */ { $$.set(0, 0); }
+ | field_length { $$.set($1, 0); }
+ | precision { $$= $1; }
;
precision:
- '(' NUM ',' NUM ')'
- {
- LEX *lex=Lex;
- lex->length=$2.str;
- lex->dec=$4.str;
- }
+ '(' NUM ',' NUM ')' { $$.set($2.str, $4.str); }
;
field_options:
/* empty */ {}
- | field_opt_list {}
- ;
-
-field_opt_list:
- field_opt_list field_option {}
- | field_option {}
- ;
-
-field_option:
- SIGNED_SYM {}
+ | SIGNED_SYM {}
| UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG;}
| ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
+ | UNSIGNED ZEROFILL { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
+ | ZEROFILL UNSIGNED { Lex->last_field->flags|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
;
field_length:
- '(' LONG_NUM ')' { Lex->length= $2.str; }
- | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; }
- | '(' DECIMAL_NUM ')' { Lex->length= $2.str; }
- | '(' NUM ')' { Lex->length= $2.str; };
+ '(' LONG_NUM ')' { $$= $2.str; }
+ | '(' ULONGLONG_NUM ')' { $$= $2.str; }
+ | '(' DECIMAL_NUM ')' { $$= $2.str; }
+ | '(' NUM ')' { $$= $2.str; }
+ ;
opt_field_length:
- /* empty */ { Lex->length=(char*) 0; /* use default length */ }
- | field_length { }
+ /* empty */ { $$= (char*) 0; /* use default length */ }
+ | field_length { $$= $1; }
+ ;
+
+opt_field_length_default_1:
+ /* empty */ { $$= (char*) "1"; }
+ | field_length { $$= $1; }
;
opt_precision:
- /* empty */ {}
- | precision {}
+ /* empty */ { $$.set(0, 0); }
+ | precision { $$= $1; }
;
opt_attribute:
@@ -6388,8 +6592,7 @@ opt_attribute_list:
attribute:
NULL_SYM { Lex->last_field->flags&= ~ NOT_NULL_FLAG; }
- | not NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; }
- | DEFAULT now_or_signed_literal { Lex->last_field->def= $2; }
+ | DEFAULT column_default_expr { Lex->last_field->default_value= $2; }
| ON UPDATE_SYM NOW_SYM opt_default_time_precision
{
Item *item= new (thd->mem_root) Item_func_now_local(thd, $4);
@@ -6401,28 +6604,9 @@ attribute:
| SERIAL_SYM DEFAULT VALUE_SYM
{
LEX *lex=Lex;
- lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
+ lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG;
lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
}
- | opt_primary KEY_SYM
- {
- LEX *lex=Lex;
- lex->last_field->flags|= PRI_KEY_FLAG | NOT_NULL_FLAG;
- lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
- }
- | UNIQUE_SYM
- {
- LEX *lex=Lex;
- lex->last_field->flags|= UNIQUE_FLAG;
- lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
- }
- | UNIQUE_SYM KEY_SYM
- {
- LEX *lex=Lex;
- lex->last_field->flags|= UNIQUE_KEY_FLAG;
- lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
- }
- | COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
| COLLATE_SYM collation_name
{
if (Lex->charset && !my_charset_same(Lex->charset,$2))
@@ -6430,6 +6614,18 @@ attribute:
$2->name,Lex->charset->csname));
Lex->last_field->charset= $2;
}
+ | serial_attribute
+ ;
+
+serial_attribute:
+ not NULL_SYM { Lex->last_field->flags|= NOT_NULL_FLAG; }
+ | opt_primary KEY_SYM
+ {
+ LEX *lex=Lex;
+ lex->last_field->flags|= PRI_KEY_FLAG | NOT_NULL_FLAG;
+ lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
+ }
+ | vcol_attribute
| IDENT_sys equal TEXT_STRING_sys
{
if ($3.length > ENGINE_OPTION_MAX_LENGTH)
@@ -6474,18 +6670,6 @@ type_with_opt_collate:
}
;
-
-now_or_signed_literal:
- NOW_SYM opt_default_time_precision
- {
- $$= new (thd->mem_root) Item_func_now_local(thd, $2);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | signed_literal
- { $$=$1; }
- ;
-
charset:
CHAR_SYM SET {}
| CHARSET {}
@@ -6809,12 +6993,14 @@ fulltext_key_opts:
opt_USING_key_algorithm:
/* Empty*/ { $$= HA_KEY_ALG_UNDEF; }
| USING btree_or_rtree { $$= $2; }
+ ;
/* TYPE is a valid identifier, so it's handled differently than USING */
opt_key_algorithm_clause:
/* Empty*/ { $$= HA_KEY_ALG_UNDEF; }
| USING btree_or_rtree { $$= $2; }
| TYPE_SYM btree_or_rtree { $$= $2; }
+ ;
key_using_alg:
USING btree_or_rtree
@@ -6926,7 +7112,8 @@ string_list:
text_string
{ Lex->last_field->interval_list.push_back($1, thd->mem_root); }
| string_list ',' text_string
- { Lex->last_field->interval_list.push_back($3, thd->mem_root); };
+ { Lex->last_field->interval_list.push_back($3, thd->mem_root); }
+ ;
/*
** Alter table
@@ -7106,6 +7293,13 @@ alter:
lex->sql_command= SQLCOM_ALTER_SERVER;
lex->server_options.reset($3);
} OPTIONS_SYM '(' server_options_list ')' { }
+ /* ALTER USER foo is allowed for MySQL compatibility. */
+ | ALTER opt_if_exists USER_SYM clear_privileges grant_list
+ opt_require_clause opt_resource_options
+ {
+ Lex->create_info.set($2);
+ Lex->sql_command= SQLCOM_ALTER_USER;
+ }
;
ev_alter_on_schedule_completion:
@@ -7163,7 +7357,7 @@ alter_commands:
| remove_partitioning
| partitioning
/*
- This part was added for release 5.1 by Mikael Ronström.
+ This part was added for release 5.1 by Mikael Ronstrm.
From here we insert a number of commands to manage the partitions of a
partitioned table such as adding partitions, dropping partitions,
reorganising partitions in various manners. In future releases the list
@@ -7393,6 +7587,7 @@ alter_list_item:
add_column column_def opt_place
{
Lex->create_last_non_select_table= Lex->last_table();
+ $2->after= $3;
}
| ADD key_def
{
@@ -7404,19 +7599,31 @@ alter_list_item:
Lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN |
Alter_info::ALTER_ADD_INDEX;
}
+ | ADD constraint_def
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_CHECK_CONSTRAINT;
+ }
+ | ADD CONSTRAINT IF_SYM not EXISTS field_ident check_constraint
+ {
+ Lex->alter_info.flags|= Alter_info::ALTER_ADD_CHECK_CONSTRAINT;
+ Lex->add_constraint(&$6, $7, TRUE);
+ }
| CHANGE opt_column opt_if_exists_table_element field_ident
field_spec opt_place
{
- Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
+ Lex->alter_info.flags|= (Alter_info::ALTER_CHANGE_COLUMN |
+ Alter_info::ALTER_RENAME_COLUMN);
Lex->create_last_non_select_table= Lex->last_table();
- Lex->last_field->change= $4.str;
+ $5->change= $4.str;
+ $5->after= $6;
}
| MODIFY_SYM opt_column opt_if_exists_table_element
field_spec opt_place
{
Lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
Lex->create_last_non_select_table= Lex->last_table();
- Lex->last_field->change= Lex->last_field->field_name;
+ $4->change= $4->field_name;
+ $4->after= $5;
}
| DROP opt_column opt_if_exists_table_element field_ident opt_restrict
{
@@ -7428,6 +7635,17 @@ alter_list_item:
lex->alter_info.drop_list.push_back(ad, thd->mem_root);
lex->alter_info.flags|= Alter_info::ALTER_DROP_COLUMN;
}
+ | DROP CONSTRAINT opt_if_exists_table_element field_ident
+ {
+ LEX *lex=Lex;
+ Alter_drop *ad= (new (thd->mem_root)
+ Alter_drop(Alter_drop::CHECK_CONSTRAINT,
+ $4.str, $3));
+ if (ad == NULL)
+ MYSQL_YYABORT;
+ lex->alter_info.drop_list.push_back(ad, thd->mem_root);
+ lex->alter_info.flags|= Alter_info::ALTER_DROP_CHECK_CONSTRAINT;
+ }
| DROP FOREIGN KEY_SYM opt_if_exists_table_element field_ident
{
LEX *lex=Lex;
@@ -7438,7 +7656,7 @@ alter_list_item:
lex->alter_info.drop_list.push_back(ad, thd->mem_root);
lex->alter_info.flags|= Alter_info::DROP_FOREIGN_KEY;
}
- | DROP PRIMARY_SYM KEY_SYM
+ | DROP opt_constraint_no_id PRIMARY_SYM KEY_SYM
{
LEX *lex=Lex;
Alter_drop *ad= (new (thd->mem_root)
@@ -7471,7 +7689,7 @@ alter_list_item:
lex->alter_info.keys_onoff= Alter_info::ENABLE;
lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
}
- | ALTER opt_column field_ident SET DEFAULT signed_literal
+ | ALTER opt_column field_ident SET DEFAULT column_default_expr
{
LEX *lex=Lex;
Alter_column *ac= new (thd->mem_root) Alter_column($3.str,$6);
@@ -7484,7 +7702,7 @@ alter_list_item:
{
LEX *lex=Lex;
Alter_column *ac= (new (thd->mem_root)
- Alter_column($3.str, (Item*) 0));
+ Alter_column($3.str, (Virtual_column_info*) 0));
if (ac == NULL)
MYSQL_YYABORT;
lex->alter_info.alter_list.push_back(ac, thd->mem_root);
@@ -7544,6 +7762,7 @@ opt_index_lock_algorithm:
| alter_algorithm_option
| alter_lock_option alter_algorithm_option
| alter_algorithm_option alter_lock_option
+ ;
alter_algorithm_option:
ALGORITHM_SYM opt_equal DEFAULT
@@ -7602,6 +7821,7 @@ alter_option:
Lex->alter_info.requested_lock=
Alter_info::ALTER_TABLE_LOCK_NONE;
}
+ ;
opt_restrict:
@@ -7611,15 +7831,15 @@ opt_restrict:
;
opt_place:
- /* empty */ {}
+ /* empty */ { $$= NULL; }
| AFTER_SYM ident
{
- store_position_for_column($2.str);
+ $$= $2.str;
Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
}
| FIRST_SYM
{
- store_position_for_column(first_keyword);
+ $$= first_keyword;
Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
}
;
@@ -7646,6 +7866,7 @@ slave:
LEX *lex=Lex;
lex->sql_command = SQLCOM_SLAVE_ALL_START;
lex->type = 0;
+ /* If you change this code don't forget to update STOP SLAVE too */
}
{}
| STOP_SYM SLAVE optional_connection_name slave_thread_opts
@@ -7761,7 +7982,7 @@ checksum:
{
LEX *lex=Lex;
lex->sql_command = SQLCOM_CHECKSUM;
- /* Will be overriden during execution. */
+ /* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
table_list opt_checksum_type
@@ -7787,7 +8008,7 @@ repair:
lex->no_write_to_binlog= $2;
lex->check_opt.init();
lex->alter_info.reset();
- /* Will be overriden during execution. */
+ /* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
repair_table_or_view
@@ -7829,7 +8050,7 @@ analyze:
lex->no_write_to_binlog= $2;
lex->check_opt.init();
lex->alter_info.reset();
- /* Will be overriden during execution. */
+ /* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
analyze_table_list
@@ -7865,6 +8086,7 @@ persistent_stat_spec:
{}
| COLUMNS persistent_column_stat_spec INDEXES persistent_index_stat_spec
{}
+ ;
persistent_column_stat_spec:
ALL {}
@@ -7960,7 +8182,7 @@ check: CHECK_SYM
lex->sql_command = SQLCOM_CHECK;
lex->check_opt.init();
lex->alter_info.reset();
- /* Will be overriden during execution. */
+ /* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
check_view_or_table
@@ -8007,7 +8229,7 @@ optimize:
lex->no_write_to_binlog= $2;
lex->check_opt.init();
lex->alter_info.reset();
- /* Will be overriden during execution. */
+ /* Will be overridden during execution. */
YYPS->m_lock_type= TL_UNLOCK;
}
table_list
@@ -8195,17 +8417,26 @@ opt_ignore_leaves:
select:
- select_init
+ opt_with_clause select_init
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_SELECT;
+ lex->current_select->set_with_clause($1);
}
;
-/* Need select_init2 for subselects. */
select_init:
- SELECT_SYM select_init2
- | '(' select_paren ')' union_opt
+ SELECT_SYM select_options_and_item_list select_init3
+ | '(' select_paren ')'
+ | '(' select_paren ')' union_list
+ | '(' select_paren ')' union_order_or_limit
+ ;
+
+union_list_part2:
+ SELECT_SYM select_options_and_item_list select_init3_union_query_term
+ | '(' select_paren_union_query_term ')'
+ | '(' select_paren_union_query_term ')' union_list
+ | '(' select_paren_union_query_term ')' union_order_or_limit
;
select_paren:
@@ -8216,67 +8447,149 @@ select_paren:
*/
Lex->current_select->set_braces(true);
}
- SELECT_SYM select_part2
+ SELECT_SYM select_options_and_item_list select_part3
+ opt_select_lock_type
{
- if (setup_select_in_parentheses(Lex))
- MYSQL_YYABORT;
+ DBUG_ASSERT(Lex->current_select->braces);
}
| '(' select_paren ')'
;
+select_paren_union_query_term:
+ {
+ /*
+ In order to correctly parse UNION's global ORDER BY we need to
+ set braces before parsing the clause.
+ */
+ Lex->current_select->set_braces(true);
+ }
+ SELECT_SYM select_options_and_item_list select_part3_union_query_term
+ opt_select_lock_type
+ {
+ DBUG_ASSERT(Lex->current_select->braces);
+ }
+ | '(' select_paren_union_query_term ')'
+ ;
+
+select_paren_view:
+ {
+ /*
+ In order to correctly parse UNION's global ORDER BY we need to
+ set braces before parsing the clause.
+ */
+ Lex->current_select->set_braces(true);
+ }
+ SELECT_SYM select_options_and_item_list select_part3_view
+ opt_select_lock_type
+ {
+ DBUG_ASSERT(Lex->current_select->braces);
+ }
+ | '(' select_paren_view ')'
+ ;
+
/* The equivalent of select_paren for nested queries. */
select_paren_derived:
{
Lex->current_select->set_braces(true);
}
SELECT_SYM select_part2_derived
- table_expression
+ opt_table_expression
+ opt_order_clause
+ opt_limit_clause
+ opt_select_lock_type
{
- if (setup_select_in_parentheses(Lex))
- MYSQL_YYABORT;
+ DBUG_ASSERT(Lex->current_select->braces);
+ $$= Lex->current_select->master_unit()->first_select();
}
- | '(' select_paren_derived ')'
+ | '(' select_paren_derived ')' { $$= $2; }
;
-select_init2:
- select_part2
+select_init3:
+ opt_table_expression
+ opt_select_lock_type
{
- LEX *lex= Lex;
/* Parentheses carry no meaning here */
- lex->current_select->set_braces(false);
+ Lex->current_select->set_braces(false);
}
union_clause
+ | select_part3_union_not_ready
+ opt_select_lock_type
+ {
+ /* Parentheses carry no meaning here */
+ Lex->current_select->set_braces(false);
+ }
;
-/*
- Theoretically we can merge all 3 right hand sides of the select_part2
- rule into one, however such a transformation adds one shift/reduce
- conflict more.
-*/
-select_part2:
- select_options_and_item_list
- opt_order_clause
- opt_limit_clause
+
+select_init3_union_query_term:
+ opt_table_expression
opt_select_lock_type
- | select_options_and_item_list into opt_select_lock_type
- | select_options_and_item_list
- opt_into
- from_clause
- opt_where_clause
- opt_group_clause
- opt_having_clause
- opt_order_clause
- opt_limit_clause
- opt_procedure_clause
- opt_into
+ {
+ /* Parentheses carry no meaning here */
+ Lex->current_select->set_braces(false);
+ }
+ union_clause
+ | select_part3_union_not_ready_noproc
opt_select_lock_type
{
- if ($2 && $10) /* double "INTO" clause */
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "INTO", "INTO"));
+ /* Parentheses carry no meaning here */
+ Lex->current_select->set_braces(false);
+ }
+ ;
- if ($9 && ($2 || $10)) /* "INTO" with "PROCEDURE ANALYSE" */
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "PROCEDURE", "INTO"));
+
+select_init3_view:
+ opt_table_expression opt_select_lock_type
+ {
+ Lex->current_select->set_braces(false);
}
+ | opt_table_expression opt_select_lock_type
+ {
+ Lex->current_select->set_braces(false);
+ }
+ union_list_view
+ | order_or_limit opt_select_lock_type
+ {
+ Lex->current_select->set_braces(false);
+ }
+ | table_expression order_or_limit opt_select_lock_type
+ {
+ Lex->current_select->set_braces(false);
+ }
+ ;
+
+/*
+ The SELECT parts after select_item_list that cannot be followed by UNION.
+*/
+
+select_part3:
+ opt_table_expression
+ | select_part3_union_not_ready
+ ;
+
+select_part3_union_query_term:
+ opt_table_expression
+ | select_part3_union_not_ready_noproc
+ ;
+
+select_part3_view:
+ opt_table_expression
+ | order_or_limit
+ | table_expression order_or_limit
+ ;
+
+select_part3_union_not_ready:
+ select_part3_union_not_ready_noproc
+ | table_expression procedure_clause
+ | table_expression order_or_limit procedure_clause
+ ;
+
+select_part3_union_not_ready_noproc:
+ order_or_limit
+ | into opt_table_expression opt_order_clause opt_limit_clause
+ | table_expression into
+ | table_expression order_or_limit
+ | table_expression order_or_limit into
;
select_options_and_item_list:
@@ -8293,24 +8606,25 @@ select_options_and_item_list:
}
;
+
+/**
+ <table expression>, as in the SQL standard.
+*/
table_expression:
- opt_from_clause
+ from_clause
opt_where_clause
opt_group_clause
opt_having_clause
- opt_order_clause
- opt_limit_clause
- opt_procedure_clause
- opt_select_lock_type
+ opt_window_clause
;
-from_clause:
- FROM table_reference_list
+opt_table_expression:
+ /* Empty */
+ | table_expression
;
-opt_from_clause:
- /* empty */
- | from_clause
+from_clause:
+ FROM table_reference_list
;
table_reference_list:
@@ -8432,11 +8746,11 @@ select_item:
check_column_name($4.str))
my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), $4.str));
$2->is_autogenerated_name= FALSE;
- $2->set_name($4.str, $4.length, system_charset_info);
+ $2->set_name(thd, $4.str, $4.length, system_charset_info);
}
else if (!$2->name)
{
- $2->set_name($1, (uint) ($3 - $1), thd->charset());
+ $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
}
}
;
@@ -8447,6 +8761,12 @@ remember_tok_start:
}
;
+remember_tok_end:
+ {
+ $$= (char*) YYLIP->get_tok_end();
+ }
+ ;
+
remember_name:
{
$$= (char*) YYLIP->get_cpp_tok_start();
@@ -8470,13 +8790,13 @@ select_alias:
opt_default_time_precision:
/* empty */ { $$= NOT_FIXED_DEC; }
| '(' ')' { $$= NOT_FIXED_DEC; }
- | '(' real_ulong_num ')' { $$= $2; };
+ | '(' real_ulong_num ')' { $$= $2; }
;
opt_time_precision:
/* empty */ { $$= 0; }
| '(' ')' { $$= 0; }
- | '(' real_ulong_num ')' { $$= $2; };
+ | '(' real_ulong_num ')' { $$= $2; }
;
optional_braces:
@@ -8709,8 +9029,7 @@ predicate:
Item_func_in *item= new (thd->mem_root) Item_func_in(thd, *$7);
if (item == NULL)
MYSQL_YYABORT;
- item->negate();
- $$= item;
+ $$= item->neg_transformer(thd);
}
| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
{
@@ -8724,8 +9043,7 @@ predicate:
item= new (thd->mem_root) Item_func_between(thd, $1, $4, $6);
if (item == NULL)
MYSQL_YYABORT;
- item->negate();
- $$= item;
+ $$= item->neg_transformer(thd);
}
| bit_expr SOUNDS_SYM LIKE bit_expr
{
@@ -8750,9 +9068,7 @@ predicate:
Lex->escape_used);
if (item == NULL)
MYSQL_YYABORT;
- $$= new (thd->mem_root) Item_func_not(thd, item);
- if ($$ == NULL)
- MYSQL_YYABORT;
+ $$= item->neg_transformer(thd);
}
| bit_expr REGEXP bit_expr
{
@@ -8897,92 +9213,44 @@ all_or_any:
opt_dyncol_type:
/* empty */
{
- LEX *lex= Lex;
- $$= DYN_COL_NULL; /* automatic type */
- lex->charset= NULL;
- lex->length= lex->dec= 0;
+ $$.set(DYN_COL_NULL); /* automatic type */
+ Lex->charset= NULL;
}
| AS dyncol_type { $$= $2; }
;
dyncol_type:
- INT_SYM
- {
- LEX *lex= Lex;
- $$= DYN_COL_INT;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | UNSIGNED INT_SYM
- {
- LEX *lex= Lex;
- $$= DYN_COL_UINT;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | DOUBLE_SYM
- {
- LEX *lex= Lex;
- $$= DYN_COL_DOUBLE;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | REAL
- {
- LEX *lex= Lex;
- $$= DYN_COL_DOUBLE;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | FLOAT_SYM
- {
- LEX *lex= Lex;
- $$= DYN_COL_DOUBLE;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | DECIMAL_SYM float_options
- {
- $$= DYN_COL_DECIMAL;
- Lex->charset= NULL;
- }
- | char
+ numeric_dyncol_type { $$= $1; Lex->charset= NULL; }
+ | temporal_dyncol_type { $$= $1; Lex->charset= NULL; }
+ | string_dyncol_type { $$= $1; }
+ ;
+
+numeric_dyncol_type:
+ INT_SYM { $$.set(DYN_COL_INT); }
+ | UNSIGNED INT_SYM { $$.set(DYN_COL_UINT); }
+ | DOUBLE_SYM { $$.set(DYN_COL_DOUBLE); }
+ | REAL { $$.set(DYN_COL_DOUBLE); }
+ | FLOAT_SYM { $$.set(DYN_COL_DOUBLE); }
+ | DECIMAL_SYM float_options { $$.set(DYN_COL_DECIMAL, $2); }
+ ;
+
+temporal_dyncol_type:
+ DATE_SYM { $$.set(DYN_COL_DATE); }
+ | TIME_SYM opt_field_length { $$.set(DYN_COL_TIME, 0, $2); }
+ | DATETIME opt_field_length { $$.set(DYN_COL_DATETIME, 0, $2); }
+ ;
+
+string_dyncol_type:
+ char
{ Lex->charset= thd->variables.collation_connection; }
opt_binary
{
- LEX *lex= Lex;
- $$= DYN_COL_STRING;
- lex->length= lex->dec= 0;
+ $$.set(DYN_COL_STRING);
}
| nchar
{
- LEX *lex= Lex;
- $$= DYN_COL_STRING;
- lex->charset= national_charset_info;
- lex->length= lex->dec= 0;
- }
- | DATE_SYM
- {
- LEX *lex= Lex;
- $$= DYN_COL_DATE;
- lex->charset= NULL;
- lex->length= lex->dec= 0;
- }
- | TIME_SYM opt_field_length
- {
- LEX *lex= Lex;
- $$= DYN_COL_TIME;
- lex->charset= NULL;
- lex->dec= lex->length;
- lex->length= 0;
- }
- | DATETIME opt_field_length
- {
- LEX *lex= Lex;
- $$= DYN_COL_DATETIME;
- lex->charset= NULL;
- lex->dec= lex->length;
- lex->length= 0;
+ $$.set(DYN_COL_STRING);
+ Lex->charset= national_charset_info;
}
;
@@ -8996,17 +9264,18 @@ dyncall_create_element:
MYSQL_YYABORT;
$$->key= $1;
$$->value= $3;
- $$->type= (DYNAMIC_COLUMN_TYPE)$4;
+ $$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type();
$$->cs= lex->charset;
- if (lex->length)
- $$->len= strtoul(lex->length, NULL, 10);
+ if ($4.length())
+ $$->len= strtoul($4.length(), NULL, 10);
else
$$->len= 0;
- if (lex->dec)
- $$->frac= strtoul(lex->dec, NULL, 10);
+ if ($4.dec())
+ $$->frac= strtoul($4.dec(), NULL, 10);
else
$$->len= 0;
}
+ ;
dyncall_create_list:
dyncall_create_element
@@ -9023,70 +9292,45 @@ dyncall_create_list:
}
;
-simple_expr:
+/*
+ Expressions that the parser allows in a column DEFAULT clause
+ without parentheses. These expressions cannot end with a COLLATE clause.
+
+ If we allowed any "expr" in DEFAULT clause, there would be a confusion
+ in queries like this:
+ CREATE TABLE t1 (a TEXT DEFAULT 'a' COLLATE latin1_bin);
+ It would be not clear what COLLATE stands for:
+ - the collation of the column `a`, or
+ - the collation of the string literal 'a'
+
+ This restriction allows to parse the above query unambiguiusly:
+ COLLATE belongs to the column rather than the literal.
+ If one needs COLLATE to belong to the literal, parentheses must be used:
+ CREATE TABLE t1 (a TEXT DEFAULT ('a' COLLATE latin1_bin));
+ Note: the COLLATE clause is rather meaningless here, but the query
+ is syntactically correct.
+
+ Note, some of the expressions are not actually allowed in DEFAULT,
+ e.g. sum_expr, window_func_expr, ROW(...), VALUES().
+ We could move them to simple_expr, but that would make
+ these two queries return a different error messages:
+ CREATE TABLE t1 (a INT DEFAULT AVG(1));
+ CREATE TABLE t1 (a INT DEFAULT (AVG(1)));
+ The first query would return "syntax error".
+ Currenly both return:
+ Function or expression 'avg(' is not allowed for 'DEFAULT' ...
+*/
+column_default_non_parenthesized_expr:
simple_ident
| function_call_keyword
| function_call_nonkeyword
| function_call_generic
| function_call_conflict
- | simple_expr COLLATE_SYM ident_or_text %prec NEG
- {
- Item *i1= new (thd->mem_root) Item_string(thd, $3.str,
- $3.length,
- thd->charset());
- if (i1 == NULL)
- MYSQL_YYABORT;
- $$= new (thd->mem_root) Item_func_set_collation(thd, $1, i1);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
| literal
| param_marker { $$= $1; }
| variable
| sum_expr
- | simple_expr OR_OR_SYM simple_expr
- {
- $$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | '+' simple_expr %prec NEG
- {
- $$= $2;
- }
- | '-' simple_expr %prec NEG
- {
- $$= new (thd->mem_root) Item_func_neg(thd, $2);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | '~' simple_expr %prec NEG
- {
- $$= new (thd->mem_root) Item_func_bit_neg(thd, $2);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | not2 simple_expr %prec NEG
- {
- $$= negate_expression(thd, $2);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | '(' subselect ')'
- {
- $$= new (thd->mem_root) Item_singlerow_subselect(thd, $2);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
- | '(' expr ')'
- { $$= $2; }
- | '(' expr ',' expr_list ')'
- {
- $4->push_front($2, thd->mem_root);
- $$= new (thd->mem_root) Item_row(thd, *$4);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
+ | window_func_expr
| ROW_SYM '(' expr ',' expr_list ')'
{
$5->push_front($3, thd->mem_root);
@@ -9134,17 +9378,10 @@ simple_expr:
Select->add_ftfunc_to_list(thd, i1);
$$= i1;
}
- | BINARY simple_expr %prec NEG
- {
- $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL,
- &my_charset_bin);
- if ($$ == NULL)
- MYSQL_YYABORT;
- }
| CAST_SYM '(' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_cast(thd, $3, $5, lex->length, lex->dec,
+ $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(),
lex->charset);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -9157,7 +9394,7 @@ simple_expr:
}
| CONVERT_SYM '(' expr ',' cast_type ')'
{
- $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec,
+ $$= create_func_cast(thd, $3, $5.type(), $5.length(), $5.dec(),
Lex->charset);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -9185,6 +9422,57 @@ simple_expr:
if ($$ == NULL)
MYSQL_YYABORT;
}
+ ;
+
+simple_expr:
+ column_default_non_parenthesized_expr
+ | simple_expr COLLATE_SYM ident_or_text %prec NEG
+ {
+ Item *i1= new (thd->mem_root) Item_string(thd, $3.str,
+ $3.length,
+ thd->charset());
+ if (i1 == NULL)
+ MYSQL_YYABORT;
+ $$= new (thd->mem_root) Item_func_set_collation(thd, $1, i1);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | '(' parenthesized_expr ')' { $$= $2; }
+ | BINARY simple_expr %prec NEG
+ {
+ $$= create_func_cast(thd, $2, ITEM_CAST_CHAR, NULL, NULL,
+ &my_charset_bin);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | simple_expr OR_OR_SYM simple_expr
+ {
+ $$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | '+' simple_expr %prec NEG
+ {
+ $$= $2;
+ }
+ | '-' simple_expr %prec NEG
+ {
+ $$= $2->neg(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | '~' simple_expr %prec NEG
+ {
+ $$= new (thd->mem_root) Item_func_bit_neg(thd, $2);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | not2 simple_expr %prec NEG
+ {
+ $$= negate_expression(thd, $2);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
| INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM
/* we cannot put interval before - */
{
@@ -9593,8 +9881,8 @@ function_call_nonkeyword:
COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
{
LEX *lex= Lex;
- $$= create_func_dyncol_get(thd, $3, $5, $7,
- lex->length, lex->dec,
+ $$= create_func_dyncol_get(thd, $3, $5, $7.type(),
+ $7.length(), $7.dec(),
lex->charset);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -9656,8 +9944,23 @@ function_call_conflict:
if ($$ == NULL)
MYSQL_YYABORT;
}
- | LAST_VALUE '(' expr_list ')'
+ /* LAST_VALUE here conflicts with the definition for window functions.
+ We have these 2 separate rules to remove the shift/reduce conflict.
+ */
+ | LAST_VALUE '(' expr ')'
{
+ List<Item> *list= new (thd->mem_root) List<Item>;
+ if (list == NULL)
+ MYSQL_YYABORT;
+ list->push_back($3, thd->mem_root);
+
+ $$= new (thd->mem_root) Item_func_last_value(thd, *list);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | LAST_VALUE '(' expr_list ',' expr ')'
+ {
+ $3->push_back($5, thd->mem_root);
$$= new (thd->mem_root) Item_func_last_value(thd, *$3);
if ($$ == NULL)
MYSQL_YYABORT;
@@ -9729,15 +10032,7 @@ function_call_conflict:
}
| WEEK_SYM '(' expr ')'
{
- Item *i1;
- LEX_STRING name= {C_STRING_WITH_LEN("default_week_format")};
- if (!(i1= get_system_var(thd, OPT_SESSION,
- name, null_lex_str)))
- MYSQL_YYABORT;
- i1->set_name((const char *)
- STRING_WITH_LEN("@@default_week_format"),
- system_charset_info);
- $$= new (thd->mem_root) Item_func_week(thd, $3, i1);
+ $$= new (thd->mem_root) Item_func_week(thd, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -10017,7 +10312,7 @@ udf_expr:
if ($4.str)
{
$2->is_autogenerated_name= FALSE;
- $2->set_name($4.str, $4.length, system_charset_info);
+ $2->set_name(thd, $4.str, $4.length, system_charset_info);
}
/*
A field has to have its proper name in order for name
@@ -10027,7 +10322,7 @@ udf_expr:
*/
else if ($2->type() != Item::FIELD_ITEM &&
$2->type() != Item::REF_ITEM /* For HAVING */ )
- $2->set_name($1, (uint) ($3 - $1), thd->charset());
+ $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
$$= $2;
}
;
@@ -10171,6 +10466,152 @@ sum_expr:
}
;
+window_func_expr:
+ window_func OVER_SYM window_name
+ {
+ $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, $3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ if (Select->add_window_func((Item_window_func *) $$))
+ MYSQL_YYABORT;
+ }
+ |
+ window_func OVER_SYM window_spec
+ {
+ LEX *lex= Lex;
+ if (Select->add_window_spec(thd, lex->win_ref,
+ Select->group_list,
+ Select->order_list,
+ lex->win_frame))
+ MYSQL_YYABORT;
+ $$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1,
+ thd->lex->win_spec);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ if (Select->add_window_func((Item_window_func *) $$))
+ MYSQL_YYABORT;
+ }
+ ;
+
+window_func:
+ simple_window_func
+ |
+ sum_expr
+ {
+ ((Item_sum *) $1)->mark_as_window_func_sum_expr();
+ }
+ ;
+
+simple_window_func:
+ ROW_NUMBER_SYM '(' ')'
+ {
+ $$= new (thd->mem_root) Item_sum_row_number(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ RANK_SYM '(' ')'
+ {
+ $$= new (thd->mem_root) Item_sum_rank(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ DENSE_RANK_SYM '(' ')'
+ {
+ $$= new (thd->mem_root) Item_sum_dense_rank(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ PERCENT_RANK_SYM '(' ')'
+ {
+ $$= new (thd->mem_root) Item_sum_percent_rank(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ CUME_DIST_SYM '(' ')'
+ {
+ $$= new (thd->mem_root) Item_sum_cume_dist(thd);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ NTILE_SYM '(' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_ntile(thd, $3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ FIRST_VALUE_SYM '(' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_first_value(thd, $3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ LAST_VALUE '(' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_last_value(thd, $3);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ NTH_VALUE_SYM '(' expr ',' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_nth_value(thd, $3, $5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ LEAD_SYM '(' expr ')'
+ {
+ /* No second argument defaults to 1. */
+ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1);
+ if (item_offset == NULL)
+ MYSQL_YYABORT;
+ $$= new (thd->mem_root) Item_sum_lead(thd, $3, item_offset);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ LEAD_SYM '(' expr ',' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_lead(thd, $3, $5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ LAG_SYM '(' expr ')'
+ {
+ /* No second argument defaults to 1. */
+ Item* item_offset= new (thd->mem_root) Item_uint(thd, 1);
+ if (item_offset == NULL)
+ MYSQL_YYABORT;
+ $$= new (thd->mem_root) Item_sum_lag(thd, $3, item_offset);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ |
+ LAG_SYM '(' expr ',' expr ')'
+ {
+ $$= new (thd->mem_root) Item_sum_lag(thd, $3, $5);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
+window_name:
+ ident
+ {
+ $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING));
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
variable:
'@'
{
@@ -10234,19 +10675,7 @@ opt_gconcat_separator:
opt_gorder_clause:
/* empty */
- | ORDER_SYM BY
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
- sel->olap != UNSPECIFIED_OLAP_TYPE &&
- (sel->linkage != UNION_TYPE || sel->braces))
- {
- my_yyabort_error((ER_WRONG_USAGE, MYF(0),
- "CUBE/ROLLUP", "ORDER BY"));
- }
- }
- gorder_list;
+ | ORDER_SYM BY gorder_list
;
gorder_list:
@@ -10275,43 +10704,35 @@ in_sum_expr:
cast_type:
BINARY opt_field_length
- { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
+ { $$.set(ITEM_CAST_CHAR, $2); Lex->charset= &my_charset_bin; }
| CHAR_SYM opt_field_length
{ Lex->charset= thd->variables.collation_connection; }
opt_binary
- { $$=ITEM_CAST_CHAR; Lex->dec= 0; }
+ { $$.set(ITEM_CAST_CHAR, $2); }
| NCHAR_SYM opt_field_length
- { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
- | INT_SYM
- { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | SIGNED_SYM
- { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | SIGNED_SYM INT_SYM
- { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | UNSIGNED
- { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | UNSIGNED INT_SYM
- { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | DATE_SYM
- { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
- | TIME_SYM opt_field_length
- {
- $$=ITEM_CAST_TIME;
- LEX *lex= Lex;
- lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0;
- }
- | DATETIME opt_field_length
{
- $$=ITEM_CAST_DATETIME;
- LEX *lex= Lex;
- lex->charset= NULL; lex->dec= lex->length; lex->length= (char*)0;
- }
- | DECIMAL_SYM float_options
- { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
- | DOUBLE_SYM
- { Lex->charset= NULL; Lex->length= Lex->dec= 0;}
- opt_precision
- { $$=ITEM_CAST_DOUBLE; }
+ Lex->charset= national_charset_info;
+ $$.set(ITEM_CAST_CHAR, $2, 0);
+ }
+ | cast_type_numeric { $$= $1; Lex->charset= NULL; }
+ | cast_type_temporal { $$= $1; Lex->charset= NULL; }
+ ;
+
+cast_type_numeric:
+ INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); }
+ | SIGNED_SYM { $$.set(ITEM_CAST_SIGNED_INT); }
+ | SIGNED_SYM INT_SYM { $$.set(ITEM_CAST_SIGNED_INT); }
+ | UNSIGNED { $$.set(ITEM_CAST_UNSIGNED_INT); }
+ | UNSIGNED INT_SYM { $$.set(ITEM_CAST_UNSIGNED_INT); }
+ | DECIMAL_SYM float_options { $$.set(ITEM_CAST_DECIMAL, $2); }
+ | DOUBLE_SYM opt_precision { $$.set(ITEM_CAST_DOUBLE, $2); }
+ ;
+
+cast_type_temporal:
+ DATE_SYM { $$.set(ITEM_CAST_DATE); }
+ | TIME_SYM opt_field_length { $$.set(ITEM_CAST_TIME, 0, $2); }
+ | DATETIME opt_field_length { $$.set(ITEM_CAST_DATETIME, 0, $2); }
+ ;
opt_expr_list:
/* empty */ { $$= NULL; }
@@ -10383,7 +10804,7 @@ when_list:
/* Equivalent to <table reference> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
- table_factor { $$=$1; }
+ table_factor { $$= $1; }
| join_table
{
LEX *lex= Lex;
@@ -10587,6 +11008,11 @@ use_partition:
*/
/* Warning - may return NULL in case of incomplete SELECT */
table_factor:
+ table_primary_ident
+ | table_primary_derived
+ ;
+
+table_primary_ident:
{
SELECT_LEX *sel= Select;
sel->table_join_options= 0;
@@ -10602,43 +11028,28 @@ table_factor:
MYSQL_YYABORT;
Select->add_joined_table($$);
}
- | select_derived_init get_select_lex select_derived2
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if ($1)
- {
- if (sel->set_braces(1))
- {
- my_parse_error(thd, ER_SYNTAX_ERROR);
- MYSQL_YYABORT;
- }
- }
- if ($2->init_nested_join(thd))
- MYSQL_YYABORT;
- $$= 0;
- /* incomplete derived tables return NULL, we must be
- nested in select_derived rule to be here. */
- }
- /*
- Represents a flattening of the following rules from the SQL:2003
- standard. This sub-rule corresponds to the sub-rule
- <table primary> ::= ... | <derived table> [ AS ] <correlation name>
-
- The following rules have been flattened into query_expression_body
- (since we have no <with clause>).
-
- <derived table> ::= <table subquery>
- <table subquery> ::= <subquery>
- <subquery> ::= <left paren> <query expression> <right paren>
- <query expression> ::= [ <with clause> ] <query expression body>
-
- For the time being we use the non-standard rule
- select_derived_union which is a compromise between the standard
- and our parser. Possibly this rule could be replaced by our
- query_expression_body.
- */
- | '(' get_select_lex select_derived_union ')' opt_table_alias
+ ;
+
+
+
+/*
+ Represents a flattening of the following rules from the SQL:2003
+ standard. This sub-rule corresponds to the sub-rule
+ <table primary> ::= ... | <derived table> [ AS ] <correlation name>
+
+ <derived table> ::= <table subquery>
+ <table subquery> ::= <subquery>
+ <subquery> ::= <left paren> <query expression> <right paren>
+ <query expression> ::= [ <with clause> ] <query expression body>
+
+ For the time being we use the non-standard rule
+ select_derived_union which is a compromise between the standard
+ and our parser. Possibly this rule could be replaced by our
+ query_expression_body.
+*/
+
+table_primary_derived:
+ '(' get_select_lex select_derived_union ')' opt_table_alias
{
/* Use $2 instead of Lex->current_select as derived table will
alter value of Lex->current_select. */
@@ -10701,6 +11112,25 @@ table_factor:
!$$->derived->first_select()->next_select())
$$->select_lex->add_where_field($$->derived->first_select());
}
+ /* Represents derived table with WITH clause */
+ | '(' get_select_lex subselect_start
+ with_clause query_expression_body
+ subselect_end ')' opt_table_alias
+ {
+ LEX *lex=Lex;
+ SELECT_LEX *sel= $2;
+ SELECT_LEX_UNIT *unit= $5->master_unit();
+ Table_ident *ti= new (thd->mem_root) Table_ident(unit);
+ if (ti == NULL)
+ MYSQL_YYABORT;
+ $5->set_with_clause($4);
+ lex->current_select= sel;
+ if (!($$= sel->add_table_to_list(lex->thd,
+ ti, $8, 0,
+ TL_READ, MDL_SHARED_READ)))
+ MYSQL_YYABORT;
+ sel->add_joined_table($$);
+ }
;
/*
@@ -10723,47 +11153,45 @@ table_factor:
subqueries have their own union rules.
*/
select_derived_union:
- select_derived opt_union_order_or_limit
+ select_derived
+ | select_derived union_order_or_limit
{
- if ($1 && $2)
+ if ($1)
{
my_parse_error(thd, ER_SYNTAX_ERROR);
MYSQL_YYABORT;
}
}
- | select_derived_union
- UNION_SYM
- union_option
- {
- if (add_select_to_union_list(Lex, (bool)$3, FALSE))
- MYSQL_YYABORT;
- }
- query_specification
+ | select_derived union_head_non_top
{
- /*
- Remove from the name resolution context stack the context of the
- last select in the union.
- */
- Lex->pop_context();
-
- if ($1 != NULL)
+ if ($1)
{
my_parse_error(thd, ER_SYNTAX_ERROR);
MYSQL_YYABORT;
}
}
- ;
+ union_list_derived_part2
+ | derived_query_specification opt_select_lock_type
+ | derived_query_specification order_or_limit opt_select_lock_type
+ | derived_query_specification opt_select_lock_type union_list_derived
+ ;
+
+union_list_derived_part2:
+ query_term_union_not_ready { Lex->pop_context(); }
+ | query_term_union_ready { Lex->pop_context(); }
+ | query_term_union_ready { Lex->pop_context(); } union_list_derived
+ ;
+
+union_list_derived:
+ union_head_non_top union_list_derived_part2
+ ;
+
/* The equivalent of select_init2 for nested queries. */
select_init2_derived:
select_part2_derived
{
- LEX *lex= Lex;
- if (lex->current_select->set_braces(0))
- {
- my_parse_error(thd, ER_SYNTAX_ERROR);
- MYSQL_YYABORT;
- }
+ Select->set_braces(0);
}
;
@@ -10784,19 +11212,15 @@ select_part2_derived:
/* handle contents of parentheses in join expression */
select_derived:
- get_select_lex
- {
- if ($1->init_nested_join(thd))
- MYSQL_YYABORT;
- }
- derived_table_list
+ get_select_lex_derived derived_table_list
{
- /* for normal joins, $3 != NULL and end_nested_join() != NULL,
+ LEX *lex= Lex;
+ /* for normal joins, $2 != NULL and end_nested_join() != NULL,
for derived tables, both must equal NULL */
- if (!($$= $1->end_nested_join(thd)) && $3)
+ if (!($$= $1->end_nested_join(lex->thd)) && $2)
MYSQL_YYABORT;
- if (!$3 && $$)
+ if (!$2 && $$)
{
my_parse_error(thd, ER_SYNTAX_ERROR);
MYSQL_YYABORT;
@@ -10804,6 +11228,20 @@ select_derived:
}
;
+/*
+ Similar to query_specification, but for derived tables.
+ Example: the inner parenthesized SELECT in this query:
+ SELECT * FROM (SELECT * FROM t1);
+*/
+derived_query_specification:
+ SELECT_SYM select_derived_init select_derived2
+ {
+ if ($2)
+ Select->set_braces(1);
+ $$= NULL;
+ }
+ ;
+
select_derived2:
{
LEX *lex= Lex;
@@ -10825,30 +11263,27 @@ select_derived2:
{
Select->parsing_place= NO_MATTER;
}
- table_expression
+ opt_table_expression
;
get_select_lex:
/* Empty */ { $$= Select; }
;
-select_derived_init:
- SELECT_SYM
+get_select_lex_derived:
+ get_select_lex
{
LEX *lex= Lex;
+ if ($1->init_nested_join(lex->thd))
+ MYSQL_YYABORT;
+ }
+ ;
- if (! lex->parsing_options.allows_derived)
- my_yyabort_error((ER_VIEW_SELECT_DERIVED, MYF(0)));
+select_derived_init:
+ {
+ LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- TABLE_LIST *embedding;
- if (!sel->embedding || sel->end_nested_join(thd))
- {
- /* we are not in parentheses */
- my_parse_error(thd, ER_SYNTAX_ERROR);
- MYSQL_YYABORT;
- }
- embedding= Select->embedding;
+ TABLE_LIST *embedding= lex->current_select->embedding;
$$= embedding &&
!embedding->nested_join->join_list.elements;
/* return true if we are deeply nested */
@@ -10986,7 +11421,7 @@ table_alias:
opt_table_alias:
/* empty */ { $$=0; }
- | table_alias ident
+ | table_alias ident_table_alias
{
$$= (LEX_STRING*) thd->memdup(&$2,sizeof(LEX_STRING));
if ($$ == NULL)
@@ -11101,6 +11536,156 @@ olap_opt:
;
/*
+ optional window clause in select
+*/
+
+opt_window_clause:
+ /* empty */
+ {}
+ | WINDOW_SYM
+ window_def_list
+ {}
+ ;
+
+window_def_list:
+ window_def_list ',' window_def
+ | window_def
+ ;
+
+window_def:
+ window_name AS window_spec
+ {
+ LEX *lex= Lex;
+ if (Select->add_window_def(thd, $1, lex->win_ref,
+ Select->group_list,
+ Select->order_list,
+ lex->win_frame ))
+ MYSQL_YYABORT;
+ }
+ ;
+
+window_spec:
+ '('
+ { Select->prepare_add_window_spec(thd); }
+ opt_window_ref opt_window_partition_clause
+ opt_window_order_clause opt_window_frame_clause
+ ')'
+ ;
+
+opt_window_ref:
+ /* empty */ {}
+ | ident
+ {
+ thd->lex->win_ref= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING));
+ if (thd->lex->win_ref == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
+opt_window_partition_clause:
+ /* empty */ { }
+ | PARTITION_SYM BY group_list
+ ;
+
+opt_window_order_clause:
+ /* empty */ { }
+ | ORDER_SYM BY order_list
+ ;
+
+opt_window_frame_clause:
+ /* empty */ {}
+ | window_frame_units window_frame_extent opt_window_frame_exclusion
+ {
+ LEX *lex= Lex;
+ lex->win_frame=
+ new (thd->mem_root) Window_frame($1,
+ lex->frame_top_bound,
+ lex->frame_bottom_bound,
+ $3);
+ if (lex->win_frame == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
+window_frame_units:
+ ROWS_SYM { $$= Window_frame::UNITS_ROWS; }
+ | RANGE_SYM { $$= Window_frame::UNITS_RANGE; }
+ ;
+
+window_frame_extent:
+ window_frame_start
+ {
+ LEX *lex= Lex;
+ lex->frame_top_bound= $1;
+ lex->frame_bottom_bound=
+ new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::CURRENT, NULL);
+ if (lex->frame_bottom_bound == NULL)
+ MYSQL_YYABORT;
+ }
+ | BETWEEN_SYM window_frame_bound AND_SYM window_frame_bound
+ {
+ LEX *lex= Lex;
+ lex->frame_top_bound= $2;
+ lex->frame_bottom_bound= $4;
+ }
+ ;
+
+window_frame_start:
+ UNBOUNDED_SYM PRECEDING_SYM
+ {
+ $$= new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::PRECEDING, NULL);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | CURRENT_SYM ROW_SYM
+ {
+ $$= new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::CURRENT, NULL);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | literal PRECEDING_SYM
+ {
+ $$= new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::PRECEDING, $1);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
+window_frame_bound:
+ window_frame_start { $$= $1; }
+ | UNBOUNDED_SYM FOLLOWING_SYM
+ {
+ $$= new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::FOLLOWING, NULL);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ | literal FOLLOWING_SYM
+ {
+ $$= new (thd->mem_root)
+ Window_frame_bound(Window_frame_bound::FOLLOWING, $1);
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
+opt_window_frame_exclusion:
+ /* empty */ { $$= Window_frame::EXCL_NONE; }
+ | EXCLUDE_SYM CURRENT_SYM ROW_SYM
+ { $$= Window_frame::EXCL_CURRENT_ROW; }
+ | EXCLUDE_SYM GROUP_SYM
+ { $$= Window_frame::EXCL_GROUP; }
+ | EXCLUDE_SYM TIES_SYM
+ { $$= Window_frame::EXCL_TIES; }
+ | EXCLUDE_SYM NO_SYM OTHERS_SYM
+ { $$= Window_frame::EXCL_NONE; }
+ ;
+
+/*
Order by statement in ALTER TABLE
*/
@@ -11265,10 +11850,18 @@ limit_option:
sp_pcontext *spc = lex->spcont;
if (spc && (spv = spc->find_variable($1, false)))
{
+ uint pos_in_query= 0;
+ uint len_in_query= 0;
+ if (!lex->clone_spec_offset)
+ {
+ pos_in_query= (uint)(lip->get_tok_start() -
+ lex->sphead->m_tmp_query);
+ len_in_query= (uint)(lip->get_ptr() -
+ lip->get_tok_start());
+ }
splocal= new (thd->mem_root)
- Item_splocal(thd, $1, spv->offset, spv->type,
- lip->get_tok_start() - lex->sphead->m_tmp_query,
- lip->get_ptr() - lip->get_tok_start());
+ Item_splocal(thd, $1, spv->offset, spv->sql_type(),
+ pos_in_query, len_in_query);
if (splocal == NULL)
MYSQL_YYABORT;
#ifndef DBUG_OFF
@@ -11313,6 +11906,7 @@ limit_rows_option:
LEX *lex=Lex;
lex->limit_rows_examined= $1;
}
+ ;
delete_limit_clause:
/* empty */
@@ -11385,17 +11979,13 @@ choice:
| DEFAULT { $$= HA_CHOICE_UNDEF; }
;
-opt_procedure_clause:
- /* empty */ { $$= false; }
- | PROCEDURE_SYM ident /* Procedure name */
+procedure_clause:
+ PROCEDURE_SYM ident /* Procedure name */
{
LEX *lex=Lex;
- if (! lex->parsing_options.allows_select_procedure)
- my_yyabort_error((ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE"));
+ DBUG_ASSERT(&lex->select_lex == lex->current_select);
- if (&lex->select_lex != lex->current_select)
- my_yyabort_error((ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery"));
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= &lex->proc_list.first;
@@ -11420,7 +12010,6 @@ opt_procedure_clause:
{
/* Subqueries are allowed from now.*/
Lex->expr_allows_subselect= true;
- $$= true;
}
;
@@ -11440,7 +12029,7 @@ procedure_item:
if (add_proc_to_list(thd, $2))
MYSQL_YYABORT;
if (!$2->name)
- $2->set_name($1, (uint) ($3 - $1), thd->charset());
+ $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
}
;
@@ -11491,24 +12080,14 @@ select_outvar:
if (!Lex->spcont || !(t= Lex->spcont->find_variable($1, false)))
my_yyabort_error((ER_SP_UNDECLARED_VAR, MYF(0), $1.str));
$$ = Lex->result ? (new (thd->mem_root)
- my_var_sp($1, t->offset, t->type,
+ my_var_sp($1, t->offset, t->sql_type(),
Lex->sphead)) :
NULL;
}
;
-opt_into:
- /* empty */ { $$= false; }
- | into { $$= true; }
- ;
-
into:
- INTO
- {
- if (! Lex->parsing_options.allows_select_into)
- my_yyabort_error((ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO"));
- }
- into_destination
+ INTO into_destination
;
into_destination:
@@ -11840,7 +12419,8 @@ insert_table:
lex->field_list.empty();
lex->many_values.empty();
lex->insert_list=0;
- };
+ }
+ ;
insert_field_spec:
insert_values {}
@@ -11865,12 +12445,7 @@ fields:
insert_values:
VALUES values_list {}
| VALUE_SYM values_list {}
- | create_select
- { Select->set_braces(0);}
- union_clause {}
- | '(' create_select ')'
- { Select->set_braces(1);}
- union_opt {}
+ | create_select_query_expression {}
;
values_list:
@@ -11943,6 +12518,12 @@ expr_or_default:
if ($$ == NULL)
MYSQL_YYABORT;
}
+ | IGNORE_SYM
+ {
+ $$= new (thd->mem_root) Item_ignore_value(thd, Lex->current_context());
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
;
opt_insert_update:
@@ -12486,6 +13067,18 @@ show_param:
lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER;
lex->spname= $3;
}
+ | CREATE USER_SYM
+ {
+ Lex->sql_command= SQLCOM_SHOW_CREATE_USER;
+ if (!(Lex->grant_user= (LEX_USER*)thd->alloc(sizeof(LEX_USER))))
+ MYSQL_YYABORT;
+ Lex->grant_user->user= current_user;
+ }
+ | CREATE USER_SYM user
+ {
+ Lex->sql_command= SQLCOM_SHOW_CREATE_USER;
+ Lex->grant_user= $3;
+ }
| PROCEDURE_SYM STATUS_SYM wild_and_where
{
LEX *lex= Lex;
@@ -12845,6 +13438,7 @@ delete_domain_id:
optional_flush_tables_arguments:
/* empty */ {$$= 0;}
| AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; }
+ ;
reset:
RESET_SYM
@@ -12937,6 +13531,7 @@ kill_type:
/* Empty */ { $$= (int) KILL_HARD_BIT; }
| HARD_SYM { $$= (int) KILL_HARD_BIT; }
| SOFT_SYM { $$= 0; }
+ ;
kill_option:
/* empty */ { $$= (int) KILL_CONNECTION; }
@@ -13111,7 +13706,8 @@ line_term:
opt_xml_rows_identified_by:
/* empty */ { }
| ROWS_SYM IDENTIFIED_SYM BY text_string
- { Lex->exchange->line_term = $4; };
+ { Lex->exchange->line_term = $4; }
+ ;
opt_ignore_lines:
/* empty */
@@ -13167,7 +13763,7 @@ load_data_set_elem:
if (lex->update_list.push_back($1, thd->mem_root) ||
lex->value_list.push_back($4, thd->mem_root))
MYSQL_YYABORT;
- $4->set_name_no_truncate($3, (uint) ($5 - $3), thd->charset());
+ $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset());
}
;
@@ -13292,20 +13888,28 @@ param_marker:
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
Item_param *item;
+ bool rc;
if (! lex->parsing_options.allows_variable)
my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0)));
- const char *query_start= lex->sphead ? lex->sphead->m_tmp_query
- : thd->query();
- item= new (thd->mem_root) Item_param(thd, lip->get_tok_start() -
- query_start);
- if (!($$= item) || lex->param_list.push_back(item, thd->mem_root))
+ const char *query_start= lex->sphead && !lex->clone_spec_offset ?
+ lex->sphead->m_tmp_query : lip->get_buf();
+ item= new (thd->mem_root) Item_param(thd,
+ (uint)(lip->get_tok_start() -
+ query_start));
+ if (!($$= item))
+ MYSQL_YYABORT;
+ if (!lex->clone_spec_offset)
+ rc= lex->param_list.push_back(item, thd->mem_root);
+ else
+ rc= item->add_as_clone(thd);
+ if (rc)
my_yyabort_error((ER_OUT_OF_RESOURCES, MYF(0)));
+
}
;
signed_literal:
- literal { $$ = $1; }
- | '+' NUM_literal { $$ = $2; }
+ '+' NUM_literal { $$ = $2; }
| '-' NUM_literal
{
$2->max_length++;
@@ -13333,13 +13937,13 @@ literal:
}
| FALSE_SYM
{
- $$= new (thd->mem_root) Item_int(thd, (char*) "FALSE",0,1);
+ $$= new (thd->mem_root) Item_bool(thd, (char*) "FALSE",0);
if ($$ == NULL)
MYSQL_YYABORT;
}
| TRUE_SYM
{
- $$= new (thd->mem_root) Item_int(thd, (char*) "TRUE",1,1);
+ $$= new (thd->mem_root) Item_bool(thd, (char*) "TRUE",1);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -13447,8 +14051,104 @@ temporal_literal:
;
+opt_with_clause:
+ /*empty */ { $$= 0; }
+ | with_clause
+ {
+ $$= $1;
+ }
+ ;
+
+
+with_clause:
+ WITH opt_recursive
+ {
+ With_clause *with_clause=
+ new With_clause($2, Lex->curr_with_clause);
+ if (with_clause == NULL)
+ MYSQL_YYABORT;
+ Lex->derived_tables|= DERIVED_WITH;
+ Lex->curr_with_clause= with_clause;
+ with_clause->add_to_list(Lex->with_clauses_list_last_next);
+ }
+ with_list
+ {
+ $$= Lex->curr_with_clause;
+ Lex->curr_with_clause= Lex->curr_with_clause->pop();
+ }
+ ;
+
+
+opt_recursive:
+ /*empty*/ { $$= 0; }
+ | RECURSIVE_SYM { $$= 1; }
+ ;
+
+
+with_list:
+ with_list_element
+ | with_list ',' with_list_element
+ ;
+
+
+with_list_element:
+ query_name
+ opt_with_column_list
+ {
+ $2= new List<LEX_STRING> (Lex->with_column_list);
+ if ($2 == NULL)
+ MYSQL_YYABORT;
+ Lex->with_column_list.empty();
+ }
+ AS '(' remember_tok_start subselect remember_tok_end ')'
+ {
+ LEX *lex= thd->lex;
+ const char *query_start= lex->sphead ? lex->sphead->m_tmp_query
+ : thd->query();
+ char *spec_start= $6 + 1;
+ With_element *elem= new With_element($1, *$2, $7->master_unit());
+ if (elem == NULL || Lex->curr_with_clause->add_with_element(elem))
+ MYSQL_YYABORT;
+ if (elem->set_unparsed_spec(thd, spec_start, $8,
+ (uint) (spec_start - query_start)))
+ MYSQL_YYABORT;
+ }
+ ;
+
+
+opt_with_column_list:
+ /* empty */
+ { $$= NULL; }
+ | '(' with_column_list ')'
+ { $$= NULL; }
+ ;
+
+
+with_column_list:
+ ident
+ {
+ Lex->with_column_list.push_back((LEX_STRING*)
+ thd->memdup(&$1, sizeof(LEX_STRING)));
+ }
+ | with_column_list ',' ident
+ {
+ Lex->with_column_list.push_back((LEX_STRING*)
+ thd->memdup(&$3, sizeof(LEX_STRING)));
+ }
+ ;
+
+
+query_name:
+ ident
+ {
+ $$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING));
+ if ($$ == NULL)
+ MYSQL_YYABORT;
+ }
+ ;
+
/**********************************************************************
** Creating different items.
**********************************************************************/
@@ -13500,10 +14200,18 @@ simple_ident:
my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0)));
Item_splocal *splocal;
+ uint pos_in_query= 0;
+ uint len_in_query= 0;
+ if (!lex->clone_spec_offset)
+ {
+ pos_in_query= (uint)(lip->get_tok_start_prev() -
+ lex->sphead->m_tmp_query);
+ len_in_query= (uint)(lip->get_tok_end() -
+ lip->get_tok_start_prev());
+ }
splocal= new (thd->mem_root)
- Item_splocal(thd, $1, spv->offset, spv->type,
- lip->get_tok_start_prev() - lex->sphead->m_tmp_query,
- lip->get_tok_end() - lip->get_tok_start_prev());
+ Item_splocal(thd, $1, spv->offset, spv->sql_type(),
+ pos_in_query, len_in_query);
if (splocal == NULL)
MYSQL_YYABORT;
#ifndef DBUG_OFF
@@ -13756,10 +14464,7 @@ IDENT_sys:
if (thd->charset_is_system_charset)
{
CHARSET_INFO *cs= system_charset_info;
- int dummy_error;
- uint wlen= cs->cset->well_formed_len(cs, $1.str,
- $1.str+$1.length,
- $1.length, &dummy_error);
+ uint wlen= Well_formed_prefix(cs, $1.str, $1.length).length();
if (wlen < $1.length)
{
ErrConvString err($1.str, $1.length, &my_charset_bin);
@@ -13821,6 +14526,17 @@ TEXT_STRING_filesystem:
}
;
+ident_table_alias:
+ IDENT_sys { $$= $1; }
+ | keyword_alias
+ {
+ $$.str= thd->strmake($1.str, $1.length);
+ if ($$.str == NULL)
+ MYSQL_YYABORT;
+ $$.length= $1.length;
+ }
+ ;
+
ident:
IDENT_sys { $$=$1; }
| keyword
@@ -13913,12 +14629,13 @@ user: user_maybe_role
}
;
-/* Keyword that we allow for identifiers (except SP labels) */
-keyword:
+/* Keywords which we allow as table aliases. */
+keyword_alias:
keyword_sp {}
| ASCII_SYM {}
| BACKUP_SYM {}
| BEGIN_SYM {}
+ | BINLOG_SYM {}
| BYTE_SYM {}
| CACHE_SYM {}
| CHARSET {}
@@ -13937,8 +14654,11 @@ keyword:
| DO_SYM {}
| END {}
| EXAMINED_SYM {}
+ | EXCLUDE_SYM {}
| EXECUTE_SYM {}
| FLUSH_SYM {}
+ | FOLLOWS_SYM {}
+ | FOLLOWING_SYM {}
| FORMAT_SYM {}
| GET_SYM {}
| HANDLER_SYM {}
@@ -13950,9 +14670,12 @@ keyword:
| OPEN_SYM {}
| OPTION {}
| OPTIONS_SYM {}
+ | OTHERS_SYM {}
| OWNER_SYM {}
| PARSER_SYM {}
| PORT_SYM {}
+ | PRECEDES_SYM {}
+ | PRECEDING_SYM {}
| PREPARE_SYM {}
| REMOVE_SYM {}
| REPAIR {}
@@ -13970,14 +14693,21 @@ keyword:
| SONAME_SYM {}
| START_SYM {}
| STOP_SYM {}
+ | STORED_SYM {}
+ | TIES_SYM {}
| TRUNCATE_SYM {}
| UNICODE_SYM {}
| UNINSTALL_SYM {}
+ | UNBOUNDED_SYM {}
| WRAPPER_SYM {}
| XA_SYM {}
| UPGRADE_SYM {}
;
+
+/* Keyword that we allow for identifiers (except SP labels) */
+keyword: keyword_alias | WINDOW_SYM {};
+
/*
* Keywords that we allow for labels in SPs.
* Anything that's the beginning of a statement or characteristics
@@ -14002,7 +14732,6 @@ keyword_sp:
| AUTO_SYM {}
| AVG_ROW_LENGTH {}
| AVG_SYM {}
- | BINLOG_SYM {}
| BIT_SYM {}
| BLOCK_SYM {}
| BOOL_SYM {}
@@ -14094,6 +14823,7 @@ keyword_sp:
| ID_SYM {}
| IDENTIFIED_SYM {}
| IGNORE_SERVER_IDS_SYM {}
+ | IMMEDIATE_SYM {} /* SQL-2003-R */
| INVOKER_SYM {}
| IMPORT {}
| INDEXES {}
@@ -14102,6 +14832,7 @@ keyword_sp:
| IPC_SYM {}
| ISOLATION {}
| ISSUER_SYM {}
+ | JSON_SYM {}
| INSERT_METHOD {}
| KEY_BLOCK_SIZE {}
| LAST_VALUE {}
@@ -14128,6 +14859,7 @@ keyword_sp:
| MASTER_PASSWORD_SYM {}
| MASTER_SERVER_ID_SYM {}
| MASTER_CONNECT_RETRY_SYM {}
+ | MASTER_DELAY_SYM {}
| MASTER_SSL_SYM {}
| MASTER_SSL_CA_SYM {}
| MASTER_SSL_CAPATH_SYM {}
@@ -14221,7 +14953,6 @@ keyword_sp:
| ROLE_SYM {}
| ROLLUP_SYM {}
| ROUTINE_SYM {}
- | ROWS_SYM {}
| ROW_COUNT_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}
@@ -14348,8 +15079,9 @@ set_stmt_option_value_following_option_type_list:
*/
option_value_following_option_type
| set_stmt_option_value_following_option_type_list ',' option_value_following_option_type
+ ;
-// Start of option value list
+/* Start of option value list */
start_option_value_list:
option_value_no_option_type
{
@@ -14374,7 +15106,7 @@ start_option_value_list:
;
-// Start of option value list, option_type was given
+/* Start of option value list, option_type was given */
start_option_value_list_following_option_type:
option_value_following_option_type
{
@@ -14389,13 +15121,13 @@ start_option_value_list_following_option_type:
}
;
-// Remainder of the option value list after first option value.
+/* Remainder of the option value list after first option value. */
option_value_list_continued:
/* empty */
| ',' option_value_list
;
-// Repeating list of option values after first option value.
+/* Repeating list of option values after first option value. */
option_value_list:
{
sp_create_assignment_lex(thd, yychar == YYEMPTY);
@@ -14416,7 +15148,7 @@ option_value_list:
}
;
-// Wrapper around option values following the first option value in the stmt.
+/* Wrapper around option values following the first option value in the stmt. */
option_value:
option_type
{
@@ -14446,7 +15178,7 @@ opt_var_ident_type:
| SESSION_SYM '.' { $$=OPT_SESSION; }
;
-// Option values with preceding option_type.
+/* Option values with preceding option_type. */
option_value_following_option_type:
internal_variable_name equal set_expr_or_default
{
@@ -14470,7 +15202,7 @@ option_value_following_option_type:
}
;
-// Option values without preceding option_type.
+/* Option values without preceding option_type. */
option_value_no_option_type:
internal_variable_name equal set_expr_or_default
{
@@ -14514,7 +15246,7 @@ option_value_no_option_type:
struct sys_var_with_base tmp= $4;
if (tmp.var == trg_new_row_fake_var)
{
- my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), "NEW");
+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), 3, "NEW");
MYSQL_YYABORT;
}
/* Lookup if necessary: must be a system variable. */
@@ -15036,14 +15768,14 @@ grant:
grant_command:
grant_privileges ON opt_table grant_ident TO_SYM grant_list
- require_clause grant_options
+ opt_require_clause opt_grant_options
{
LEX *lex= Lex;
lex->sql_command= SQLCOM_GRANT;
lex->type= 0;
}
| grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
- require_clause grant_options
+ opt_require_clause opt_grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
@@ -15055,7 +15787,7 @@ grant_command:
lex->type= TYPE_ENUM_FUNCTION;
}
| grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list
- require_clause grant_options
+ opt_require_clause opt_grant_options
{
LEX *lex= Lex;
if (lex->columns.elements)
@@ -15085,12 +15817,14 @@ grant_command:
;
opt_with_admin:
- /* nothing */ { Lex->definer = 0; }
- | WITH ADMIN_SYM user_or_role { Lex->definer = $3; }
+ /* nothing */ { Lex->definer = 0; }
+ | WITH ADMIN_SYM user_or_role { Lex->definer = $3; }
+ ;
opt_with_admin_option:
- /* nothing */ { Lex->with_admin_option= false; }
- | WITH ADMIN_SYM OPTION { Lex->with_admin_option= true; }
+ /* nothing */ { Lex->with_admin_option= false; }
+ | WITH ADMIN_SYM OPTION { Lex->with_admin_option= true; }
+ ;
role_list:
grant_role
@@ -15392,7 +16126,7 @@ column_list_id:
}
;
-require_clause:
+opt_require_clause:
/* empty */
| REQUIRE_SYM require_list
{
@@ -15412,24 +16146,8 @@ require_clause:
}
;
-grant_options:
- /* empty */ {}
- | WITH grant_option_list
- ;
-
-opt_grant_option:
- /* empty */ {}
- | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
- ;
-
-grant_option_list:
- grant_option_list grant_option {}
- | grant_option {}
- ;
-
-grant_option:
- GRANT OPTION { Lex->grant |= GRANT_ACL;}
- | MAX_QUERIES_PER_HOUR ulong_num
+resource_option:
+ MAX_QUERIES_PER_HOUR ulong_num
{
LEX *lex=Lex;
lex->mqh.questions=$2;
@@ -15461,6 +16179,37 @@ grant_option:
}
;
+resource_option_list:
+ resource_option_list resource_option {}
+ | resource_option {}
+ ;
+
+opt_resource_options:
+ /* empty */ {}
+ | WITH resource_option_list
+ ;
+
+
+opt_grant_options:
+ /* empty */ {}
+ | WITH grant_option_list {}
+ ;
+
+opt_grant_option:
+ /* empty */ {}
+ | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ ;
+
+grant_option_list:
+ grant_option_list grant_option {}
+ | grant_option {}
+ ;
+
+grant_option:
+ GRANT OPTION { Lex->grant |= GRANT_ACL;}
+ | resource_option {}
+ ;
+
begin:
BEGIN_SYM
{
@@ -15502,7 +16251,7 @@ opt_release:
{ $$= TVL_UNKNOWN; }
| RELEASE_SYM { $$= TVL_YES; }
| NO_SYM RELEASE_SYM { $$= TVL_NO; }
-;
+ ;
opt_savepoint:
/* empty */ {}
@@ -15574,7 +16323,7 @@ union_list:
if (add_select_to_union_list(Lex, (bool)$2, TRUE))
MYSQL_YYABORT;
}
- select_init
+ union_list_part2
{
/*
Remove from the name resolution context stack the context of the
@@ -15584,16 +16333,18 @@ union_list:
}
;
-union_opt:
- opt_union_order_or_limit
- | union_list { $$= 1; }
+union_list_view:
+ UNION_SYM union_option
+ {
+ if (add_select_to_union_list(Lex, (bool)$2, TRUE))
+ MYSQL_YYABORT;
+ }
+ query_expression_body_view
+ {
+ Lex->pop_context();
+ }
;
-opt_union_order_or_limit:
- /* Empty */ { $$= 0; }
- | union_order_or_limit { $$= 1; }
- ;
-
union_order_or_limit:
{
LEX *lex= thd->lex;
@@ -15620,45 +16371,61 @@ order_or_limit:
| limit_clause
;
+/*
+ Start a UNION, for non-top level query expressions.
+*/
+union_head_non_top:
+ UNION_SYM union_option
+ {
+ if (add_select_to_union_list(Lex, (bool)$2, FALSE))
+ MYSQL_YYABORT;
+ }
+ ;
+
union_option:
/* empty */ { $$=1; }
| DISTINCT { $$=1; }
| ALL { $$=0; }
;
+/*
+ Corresponds to the SQL Standard
+ <query specification> ::=
+ SELECT [ <set quantifier> ] <select list> <table expression>
+
+ Notes:
+ - We allow more options in addition to <set quantifier>
+ - <table expression> is optional in MariaDB
+*/
query_specification:
- SELECT_SYM select_init2_derived
- table_expression
- {
- $$= Lex->current_select->master_unit()->first_select();
- }
- | '(' select_paren_derived ')'
- opt_union_order_or_limit
+ SELECT_SYM select_init2_derived opt_table_expression
{
$$= Lex->current_select->master_unit()->first_select();
}
;
+query_term_union_not_ready:
+ query_specification order_or_limit opt_select_lock_type { $$= $1; }
+ | '(' select_paren_derived ')' union_order_or_limit { $$= $2; }
+ ;
+
+query_term_union_ready:
+ query_specification opt_select_lock_type { $$= $1; }
+ | '(' select_paren_derived ')' { $$= $2; }
+ ;
+
query_expression_body:
- query_specification
- | query_expression_body
- UNION_SYM union_option
- {
- if (add_select_to_union_list(Lex, (bool)$3, FALSE))
- MYSQL_YYABORT;
- }
- query_specification
- {
- Lex->pop_context();
- $$= $1;
- }
+ query_term_union_not_ready { $$= $1; }
+ | query_term_union_ready { $$= $1; }
+ | query_term_union_ready union_list_derived { $$= $1; }
;
/* Corresponds to <query expression> in the SQL:2003 standard. */
subselect:
- subselect_start query_expression_body subselect_end
+ subselect_start opt_with_clause query_expression_body subselect_end
{
- $$= $2;
+ $3->set_with_clause($2);
+ $$= $3;
}
;
@@ -15882,29 +16649,32 @@ view_select:
{
LEX *lex= Lex;
lex->parsing_options.allows_variable= FALSE;
- lex->parsing_options.allows_select_into= FALSE;
- lex->parsing_options.allows_select_procedure= FALSE;
- lex->parsing_options.allows_derived= FALSE;
lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr();
}
- view_select_aux view_check_option
+ opt_with_clause query_expression_body_view view_check_option
{
LEX *lex= Lex;
- uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
+ size_t len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
+ uint not_used;
void *create_view_select= thd->memdup(lex->create_view_select.str, len);
lex->create_view_select.length= len;
lex->create_view_select.str= (char *) create_view_select;
- trim_whitespace(thd->charset(), &lex->create_view_select);
+ trim_whitespace(thd->charset(), &lex->create_view_select,
+ &not_used);
lex->parsing_options.allows_variable= TRUE;
- lex->parsing_options.allows_select_into= TRUE;
- lex->parsing_options.allows_select_procedure= TRUE;
- lex->parsing_options.allows_derived= TRUE;
+ lex->current_select->set_with_clause($2);
}
;
-view_select_aux:
- SELECT_SYM select_init2
- | '(' select_paren ')' union_opt
+/*
+ SQL Standard <query expression body> for VIEWs.
+ Does not include INTO and PROCEDURE clauses.
+*/
+query_expression_body_view:
+ SELECT_SYM select_options_and_item_list select_init3_view
+ | '(' select_paren_view ')'
+ | '(' select_paren_view ')' union_order_or_limit
+ | '(' select_paren_view ')' union_list_view
;
view_check_option:
@@ -15924,6 +16694,28 @@ view_check_option:
**************************************************************************/
+trigger_action_order:
+ FOLLOWS_SYM
+ { $$= TRG_ORDER_FOLLOWS; }
+ | PRECEDES_SYM
+ { $$= TRG_ORDER_PRECEDES; }
+ ;
+
+trigger_follows_precedes_clause:
+ /* empty */
+ {
+ $$.ordering_clause= TRG_ORDER_NONE;
+ $$.anchor_trigger_name.str= NULL;
+ $$.anchor_trigger_name.length= 0;
+ }
+ |
+ trigger_action_order ident_or_text
+ {
+ $$.ordering_clause= $1;
+ $$.anchor_trigger_name= $2;
+ }
+ ;
+
trigger_tail:
TRIGGER_SYM
remember_name
@@ -15948,7 +16740,11 @@ trigger_tail:
}
EACH_SYM
ROW_SYM
- { /* $17 */
+ {
+ Lex->trg_chistics.ordering_clause_begin= YYLIP->get_cpp_ptr();
+ }
+ trigger_follows_precedes_clause /* $18 */
+ { /* $19 */
LEX *lex= thd->lex;
Lex_input_stream *lip= YYLIP;
@@ -15959,14 +16755,16 @@ trigger_tail:
lex->ident.str= $9;
lex->ident.length= $13 - $9;
lex->spname= $5;
+ (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($18);
+ lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
if (!make_sp_head(thd, $5, TYPE_ENUM_TRIGGER))
MYSQL_YYABORT;
- lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
+ lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
- sp_proc_stmt /* $18 */
- { /* $19 */
+ sp_proc_stmt /* $20 */
+ { /* $21 */
LEX *lex= Lex;
sp_head *sp= lex->sphead;
@@ -16055,8 +16853,7 @@ sf_tail:
}
type_with_opt_collate /* $11 */
{ /* $12 */
- if (Lex->sphead->fill_field_definition(thd, Lex, $11,
- Lex->last_field))
+ if (Lex->sphead->fill_field_definition(thd, Lex, Lex->last_field))
MYSQL_YYABORT;
}
sp_c_chistics /* $13 */
@@ -16066,7 +16863,7 @@ sf_tail:
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
- sp_proc_stmt /* $15 */
+ sp_proc_stmt_in_returns_clause /* $15 */
{
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
@@ -16275,10 +17072,11 @@ uninstall:
/* Avoid compiler warning from sql_yacc.cc where yyerrlab1 is not used */
keep_gcc_happy:
- IMPOSSIBLE_ACTION
- {
- YYERROR;
- }
+ IMPOSSIBLE_ACTION
+ {
+ YYERROR;
+ }
+ ;
/**
@} (end of group Parser)