mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 19:06:14 +01:00 
			
		
		
		
	 8bb920c226
			
		
	
	
	8bb920c226
	
	
	
		
			
			Sql_alloc: add operator new(size_t, const THD *) noexcept. Also change throw() to noexcept in other Sql_alloc operators. Item: add operator new(size_t, const THD *). The implementations are in the bottom of item.cc and sql_class.cc.
		
			
				
	
	
		
			20311 lines
		
	
	
	
		
			609 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			20311 lines
		
	
	
	
		
			609 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /*
 | |
|    Copyright (c) 2000, 2015, Oracle and/or its affiliates.
 | |
|    Copyright (c) 2010, 2023, MariaDB
 | |
| 
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; version 2 of the License.
 | |
| 
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
| 
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
 | |
| 
 | |
| /* sql_yacc.yy */
 | |
| 
 | |
| /**
 | |
|   @defgroup Parser Parser
 | |
|   @{
 | |
| */
 | |
| 
 | |
| %{
 | |
| #define YYLIP  (& thd->m_parser_state->m_lip)
 | |
| #define YYPS   (& thd->m_parser_state->m_yacc)
 | |
| #define YYCSCL (thd->variables.character_set_client)
 | |
| 
 | |
| #define MYSQL_YACC
 | |
| #define YYINITDEPTH 100
 | |
| #define YYMAXDEPTH 3200                        /* Because of 64K stack */
 | |
| #define Lex (thd->lex)
 | |
| 
 | |
| #define Select Lex->current_select
 | |
| #include "mariadb.h"
 | |
| #include "sql_priv.h"
 | |
| #include "sql_parse.h"                        /* comp_*_creator */
 | |
| #include "sql_table.h"                        /* primary_key_name */
 | |
| #include "sql_partition.h"  /* partition_info, HASH_PARTITION */
 | |
| #include "sql_class.h"      /* Key_part_spec, enum_filetype, Diag_condition_item_name */
 | |
| #include "slave.h"
 | |
| #include "lex_symbol.h"
 | |
| #include "item_create.h"
 | |
| #include "sp_head.h"
 | |
| #include "sp_instr.h"                          // classes sp_instr,...
 | |
| #include "sp_rcontext.h"
 | |
| #include "sp.h"
 | |
| #include "sql_show.h"
 | |
| #include "sql_alter.h"                         // Sql_cmd_alter_table*
 | |
| #include "sql_truncate.h"                      // Sql_cmd_truncate_table
 | |
| #include "sql_admin.h"                         // Sql_cmd_analyze/Check..._table
 | |
| #include "sql_partition_admin.h"               // Sql_cmd_alter_table_*_part.
 | |
| #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>
 | |
| #include <myisammrg.h>
 | |
| #include "keycaches.h"
 | |
| #include "set_var.h"
 | |
| #include "rpl_mi.h"
 | |
| #include "lex_token.h"
 | |
| #include "sql_lex.h"
 | |
| #include "sql_sequence.h"
 | |
| #include "my_base.h"
 | |
| #include "sql_type_json.h"
 | |
| #include "json_table.h"
 | |
| #include "sql_update.h"
 | |
| #include "sql_delete.h"
 | |
| 
 | |
| /* this is to get the bison compilation windows warnings out */
 | |
| #ifdef _MSC_VER
 | |
| /* warning C4065: switch statement contains 'default' but no 'case' labels */
 | |
| /* warning C4102: 'yyexhaustedlab': unreferenced label */
 | |
| #pragma warning (disable : 4065 4102)
 | |
| #endif
 | |
| #if defined (__GNUC__) || defined (__clang__)
 | |
| #pragma GCC diagnostic ignored "-Wunused-label" /* yyexhaustedlab: */
 | |
| #endif
 | |
| 
 | |
| /* Stack size 28200 with clang for MYSQLparse() and ORAparse() */
 | |
| PRAGMA_DISABLE_CHECK_STACK_FRAME
 | |
| 
 | |
| int yylex(void *yylval, void *yythd);
 | |
| 
 | |
| #define yyoverflow(A,B,C,D,E,F)               \
 | |
|   {                                           \
 | |
|     size_t val= *(F);                         \
 | |
|     if (unlikely(my_yyoverflow((B), (D), &val))) \
 | |
|     {                                         \
 | |
|       yyerror(thd, (char*) (A));              \
 | |
|       return 2;                               \
 | |
|     }                                         \
 | |
|     else                                      \
 | |
|     {                                         \
 | |
|       *(F)= (YYSIZE_T)val;                    \
 | |
|     }                                         \
 | |
|   }
 | |
| 
 | |
| #define MYSQL_YYABORT                         \
 | |
|   do                                          \
 | |
|   {                                           \
 | |
|     YYABORT;                                  \
 | |
|   } while (0)
 | |
| 
 | |
| #define MYSQL_YYABORT_UNLESS(A)                  \
 | |
|   if (unlikely(!(A)))                            \
 | |
|   {                                              \
 | |
|     thd->parse_error();                          \
 | |
|     MYSQL_YYABORT;                               \
 | |
|   }
 | |
| 
 | |
| #define my_yyabort_error(A)                      \
 | |
|   do { my_error A; MYSQL_YYABORT; } while(0)
 | |
| 
 | |
| #ifndef DBUG_OFF
 | |
| #define YYDEBUG 1
 | |
| #else
 | |
| #define YYDEBUG 0
 | |
| #endif
 | |
| 
 | |
| 
 | |
| static Item* escape(THD *thd)
 | |
| {
 | |
|   thd->lex->escape_used= false;
 | |
|   const char *esc= thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES ? "" : "\\";
 | |
|   return new (thd) Item_string_ascii(thd, esc, MY_TEST(esc[0]));
 | |
| }
 | |
| 
 | |
| 
 | |
| /**
 | |
|   @brief Bison callback to report a syntax/OOM error
 | |
| 
 | |
|   This function is invoked by the bison-generated parser
 | |
|   when a syntax error, a parse error or an out-of-memory
 | |
|   condition occurs. This function is not invoked when the
 | |
|   parser is requested to abort by semantic action code
 | |
|   by means of YYABORT or YYACCEPT macros. This is why these
 | |
|   macros should not be used (use MYSQL_YYABORT/MYSQL_YYACCEPT
 | |
|   instead).
 | |
| 
 | |
|   The parser will abort immediately after invoking this callback.
 | |
| 
 | |
|   This function is not for use in semantic actions and is internal to
 | |
|   the parser, as it performs some pre-return cleanup. 
 | |
|   In semantic actions, please use thd->parse_error() or my_error to
 | |
|   push an error into the error stack and MYSQL_YYABORT
 | |
|   to abort from the parser.
 | |
| */
 | |
| 
 | |
| static void yyerror(THD *thd, const char *s)
 | |
| {
 | |
|   /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
 | |
|   if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
 | |
|     s= ER_THD(thd, ER_SYNTAX_ERROR);
 | |
|   thd->parse_error(s, 0);
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifndef DBUG_OFF
 | |
| #define __CONCAT_UNDERSCORED(x,y)  x ## _ ## y
 | |
| #define _CONCAT_UNDERSCORED(x,y)   __CONCAT_UNDERSCORED(x,y)
 | |
| void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
 | |
| {
 | |
|   /*
 | |
|      MYSQLdebug is in sql/yy_*.cc, in bison generated code.
 | |
|      Turning this option on is **VERY** verbose, and should be
 | |
|      used when investigating a syntax error problem only.
 | |
| 
 | |
|      The syntax to run with bison traces is as follows :
 | |
|      - Starting a server manually :
 | |
|        mysqld --debug-dbug="d,parser_debug" ...
 | |
|      - Running a test :
 | |
|        mysql-test-run.pl --mysqld="--debug-dbug=d,parser_debug" ...
 | |
| 
 | |
|      The result will be in the process stderr (var/log/master.err)
 | |
|    */
 | |
| 
 | |
| #ifndef _AIX
 | |
|   extern int yydebug;
 | |
| #else
 | |
|   static int yydebug;
 | |
| #endif
 | |
|   yydebug= 1;
 | |
| }
 | |
| #endif
 | |
| 
 | |
| 
 | |
| %}
 | |
| %union {
 | |
|   int  num;
 | |
|   ulong ulong_num;
 | |
|   ulonglong ulonglong_number;
 | |
|   longlong longlong_number;
 | |
|   uint sp_instr_addr;
 | |
|   /*
 | |
|     Longlong_hybrid does not have a default constructor, hence the
 | |
|     default value below.
 | |
|   */
 | |
|   Longlong_hybrid longlong_hybrid_number= Longlong_hybrid(0, false);
 | |
| 
 | |
|   /* structs */
 | |
|   LEX_CSTRING lex_str;
 | |
|   Lex_ident_cli_st kwd;
 | |
|   Lex_ident_cli_st ident_cli;
 | |
|   Lex_ident_sys_st ident_sys;
 | |
|   Lex_column_list_privilege_st column_list_privilege;
 | |
|   Lex_string_with_metadata_st lex_string_with_metadata;
 | |
|   Lex_spblock_st spblock;
 | |
|   Lex_spblock_handlers_st spblock_handlers;
 | |
|   Lex_length_and_dec_st Lex_length_and_dec;
 | |
|   Lex_cast_type_st Lex_cast_type;
 | |
|   Lex_field_type_st Lex_field_type;
 | |
|   Lex_exact_charset_extended_collation_attrs_st
 | |
|                     Lex_exact_charset_extended_collation_attrs;
 | |
|   Lex_extended_collation_st Lex_extended_collation;
 | |
|   Lex_dyncol_type_st Lex_dyncol_type;
 | |
|   Lex_for_loop_st for_loop;
 | |
|   Lex_for_loop_bounds_st for_loop_bounds;
 | |
|   Lex_trim_st trim;
 | |
|   Json_table_column::On_response json_on_response;
 | |
|   Lex_substring_spec_st substring_spec;
 | |
|   vers_history_point_t vers_history_point;
 | |
|   struct
 | |
|   {
 | |
|     enum sub_select_type unit_type;
 | |
|     bool distinct;
 | |
|   } unit_operation;
 | |
|   struct
 | |
|   {
 | |
|     SELECT_LEX *first;
 | |
|     SELECT_LEX *prev_last;
 | |
|   } select_list;
 | |
|   SQL_I_List<ORDER> *select_order;
 | |
|   Lex_select_lock select_lock;
 | |
|   Lex_select_limit select_limit;
 | |
|   Lex_order_limit_lock *order_limit_lock;
 | |
| 
 | |
|   /* pointers */
 | |
|   Lex_ident_sys *ident_sys_ptr;
 | |
|   Create_field *create_field;
 | |
|   Spvar_definition *spvar_definition;
 | |
|   Row_definition_list *spvar_definition_list;
 | |
|   const Type_handler *type_handler;
 | |
|   const class Sp_handler *sp_handler;
 | |
|   CHARSET_INFO *charset;
 | |
|   Condition_information_item *cond_info_item;
 | |
|   DYNCALL_CREATE_DEF *dyncol_def;
 | |
|   Diagnostics_information *diag_info;
 | |
|   Item *item;
 | |
|   Item_num *item_num;
 | |
|   Item_param *item_param;
 | |
|   Item_basic_constant *item_basic_constant;
 | |
|   Key_part_spec *key_part;
 | |
|   LEX *lex;
 | |
|   sp_instr_fetch_cursor *instr_fetch_cursor;
 | |
|   sp_expr_lex *expr_lex;
 | |
|   sp_assignment_lex *assignment_lex;
 | |
|   class sp_lex_cursor *sp_cursor_stmt;
 | |
|   LEX_CSTRING *lex_str_ptr;
 | |
|   LEX_USER *lex_user;
 | |
|   USER_AUTH *user_auth;
 | |
|   List<Condition_information_item> *cond_info_list;
 | |
|   List<DYNCALL_CREATE_DEF> *dyncol_def_list;
 | |
|   List<Item> *item_list;
 | |
|   List<sp_assignment_lex> *sp_assignment_lex_list;
 | |
|   List<Statement_information_item> *stmt_info_list;
 | |
|   List<String> *string_list;
 | |
|   List<Lex_ident_sys> *ident_sys_list;
 | |
|   List<sp_fetch_target> *fetch_target_list;
 | |
|   Statement_information_item *stmt_info_item;
 | |
|   String *string;
 | |
|   TABLE_LIST *table_list;
 | |
|   Table_ident *table;
 | |
|   Qualified_column_ident *qualified_column_ident;
 | |
|   char *simple_string;
 | |
|   const char *const_simple_string;
 | |
|   chooser_compare_func_creator boolfunc2creator;
 | |
|   class Lex_grant_privilege *lex_grant;
 | |
|   class Lex_grant_object_name *lex_grant_ident;
 | |
|   class my_var *myvar;
 | |
|   class sp_condition_value *spcondvalue;
 | |
|   class sp_head *sphead;
 | |
|   class sp_name *spname;
 | |
|   class sp_variable *spvar;
 | |
|   class sp_record *sprec;
 | |
|   class With_element_head *with_element_head;
 | |
|   class With_clause *with_clause;
 | |
|   class Virtual_column_info *virtual_column;
 | |
|   engine_option_value *engine_option_value_ptr;
 | |
| 
 | |
|   handlerton *db_type;
 | |
|   st_select_lex *select_lex;
 | |
|   st_select_lex_unit *select_lex_unit;
 | |
|   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 enum_sp_suid_behaviour sp_suid;
 | |
|   enum enum_sp_aggregate_type sp_aggregate_type;
 | |
|   enum enum_view_suid view_suid;
 | |
|   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;
 | |
|   enum enum_fk_option m_fk_option;
 | |
|   enum Item_udftype udf_type;
 | |
|   enum Key::Keytype key_type;
 | |
|   enum Statement_information_item::Name stmt_info_item_name;
 | |
|   enum enum_filetype filetype;
 | |
|   enum enum_tx_isolation tx_isolation;
 | |
|   enum enum_var_type var_type;
 | |
|   enum enum_yes_no_unknown m_yes_no_unk;
 | |
|   enum ha_choice choice;
 | |
|   enum ha_key_alg key_alg;
 | |
|   enum ha_rkey_function ha_rkey_mode;
 | |
|   enum index_hint_type index_hint;
 | |
|   enum interval_type interval, interval_time_st;
 | |
|   enum row_type row_type;
 | |
|   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;
 | |
|   enum vers_kind_t vers_range_unit;
 | |
|   enum Column_definition::enum_column_versioning vers_column_versioning;
 | |
|   enum plsql_cursor_attr_t plsql_cursor_attr;
 | |
|   enum Alter_info::enum_alter_table_algorithm alter_table_algo_val;
 | |
|   privilege_t privilege;
 | |
|   struct
 | |
|   {
 | |
|     Item *expr;
 | |
|     LEX_CSTRING expr_str;
 | |
|   } expr_and_query_str;
 | |
| }
 | |
| 
 | |
| %{
 | |
| /* avoid unintentional %union size increases, it's what a parser stack made of */
 | |
| static_assert(sizeof(YYSTYPE) == sizeof(void*)*2+8, "%union size check");
 | |
| bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
 | |
| %}
 | |
| 
 | |
| %define api.pure                                    /* We have threads */
 | |
| %parse-param { THD *thd }
 | |
| %lex-param { THD *thd }
 | |
| /*
 | |
|   We should not introduce any further shift/reduce conflicts.
 | |
| */
 | |
| 
 | |
| %ifdef MARIADB
 | |
| %expect 62
 | |
| %else
 | |
| %expect 63
 | |
| %endif
 | |
| 
 | |
| /*
 | |
|    Comments for TOKENS.
 | |
|    For each token, please include in the same line a comment that contains
 | |
|    the following tags:
 | |
|    SQL-2011-R : Reserved keyword as per SQL-2011
 | |
|    SQL-2011-N : Non Reserved keyword 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
 | |
|    SQL-1999-N : Non Reserved keyword as per SQL-1999
 | |
|    MYSQL      : MySQL extention (unspecified)
 | |
|    MYSQL-FUNC : MySQL extention, function
 | |
|    INTERNAL   : Not a real token, lex optimization
 | |
|    OPERATOR   : SQL operator
 | |
|    FUTURE-USE : Reserved for future use
 | |
| 
 | |
|    This makes the code grep-able, and helps maintenance.
 | |
| */
 | |
| 
 | |
| 
 | |
| %token <lex_str> '@'
 | |
| 
 | |
| /*
 | |
|   Special purpose tokens
 | |
| */
 | |
| %token  <NONE> ABORT_SYM              /* INTERNAL (used in lex) */
 | |
| %token  <NONE> IMPOSSIBLE_ACTION      /* To avoid warning for yyerrlab1 */
 | |
| %token  <NONE> FORCE_LOOKAHEAD        /* INTERNAL never returned by the lexer */
 | |
| %token  <NONE> END_OF_INPUT           /* INTERNAL */
 | |
| %token  <kwd>  COLON_ORACLE_SYM       /* INTERNAL */
 | |
| %token  <kwd>  PARAM_MARKER           /* INTERNAL */
 | |
| %token  <NONE> FOR_SYSTEM_TIME_SYM    /* INTERNAL */
 | |
| %token  <NONE> LEFT_PAREN_ALT         /* INTERNAL */
 | |
| %token  <NONE> LEFT_PAREN_WITH        /* INTERNAL */
 | |
| %token  <NONE> LEFT_PAREN_LIKE        /* INTERNAL */
 | |
| %token  <NONE> ORACLE_CONCAT_SYM      /* INTERNAL */
 | |
| %token  <NONE> PERCENT_ORACLE_SYM     /* INTERNAL */
 | |
| %token  <NONE> WITH_CUBE_SYM          /* INTERNAL */
 | |
| %token  <NONE> WITH_ROLLUP_SYM        /* INTERNAL */
 | |
| %token  <NONE> WITH_SYSTEM_SYM        /* INTERNAL */
 | |
| 
 | |
| /*
 | |
|   Identifiers
 | |
| */
 | |
| %token  IDENT
 | |
| %token  IDENT_QUOTED
 | |
| %token  LEX_HOSTNAME
 | |
| %token  UNDERSCORE_CHARSET            /* _latin1 */
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Literals
 | |
| */
 | |
| %token  BIN_NUM                       /* LITERAL */
 | |
| %token  DECIMAL_NUM                   /* LITERAL */
 | |
| %token  FLOAT_NUM                     /* LITERAL */
 | |
| %token  HEX_NUM                       /* LITERAL */
 | |
| %token  HEX_STRING                    /* LITERAL */
 | |
| %token  LONG_NUM                      /* LITERAL */
 | |
| %token  NCHAR_STRING                  /* LITERAL */
 | |
| %token  NUM                           /* LITERAL */
 | |
| %token  TEXT_STRING                   /* LITERAL */
 | |
| %token  ULONGLONG_NUM                 /* LITERAL */
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Operators
 | |
| */
 | |
| %token  <NONE> AND_AND_SYM            /* OPERATOR */
 | |
| %token  <NONE> DOT_DOT_SYM            /* OPERATOR */
 | |
| %token  <NONE> EQUAL_SYM              /* OPERATOR */
 | |
| %token  <NONE> GE                     /* OPERATOR */
 | |
| %token  <NONE> LE                     /* OPERATOR */
 | |
| %token  <NONE> MYSQL_CONCAT_SYM       /* OPERATOR */
 | |
| %token  <NONE> NE                     /* OPERATOR */
 | |
| %token  <NONE> NOT2_SYM               /* OPERATOR */
 | |
| %token  <NONE> OR2_SYM                /* OPERATOR */
 | |
| %token  <NONE> SET_VAR                /* OPERATOR */
 | |
| %token  <NONE> SHIFT_LEFT             /* OPERATOR */
 | |
| %token  <NONE> SHIFT_RIGHT            /* OPERATOR */
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Reserved keywords
 | |
| */
 | |
| %token  <kwd> ACCESSIBLE_SYM
 | |
| %token  <kwd> ADD                           /* SQL-2003-R */
 | |
| %token  <kwd> ALL                           /* SQL-2003-R */
 | |
| %token  <kwd> ALTER                         /* SQL-2003-R */
 | |
| %token  <kwd> ANALYZE_SYM
 | |
| %token  <kwd> AND_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> ASC                           /* SQL-2003-N */
 | |
| %token  <kwd> ASENSITIVE_SYM                /* FUTURE-USE */
 | |
| %token  <kwd> AS                            /* SQL-2003-R */
 | |
| %token  <kwd> BEFORE_SYM                    /* SQL-2003-N */
 | |
| %token  <kwd> BETWEEN_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> BIGINT                        /* SQL-2003-R */
 | |
| %token  <kwd> BINARY                        /* SQL-2003-R */
 | |
| %token  <kwd> BIT_AND                       /* MYSQL-FUNC */
 | |
| %token  <kwd> BIT_OR                        /* MYSQL-FUNC */
 | |
| %token  <kwd> BIT_XOR                       /* MYSQL-FUNC */
 | |
| %token  <kwd> BLOB_MARIADB_SYM              /* SQL-2003-R */
 | |
| %token  <kwd> BLOB_ORACLE_SYM               /* Oracle-R   */
 | |
| %token  <kwd> BODY_ORACLE_SYM               /* Oracle-R   */
 | |
| %token  <kwd> BOTH                          /* SQL-2003-R */
 | |
| %token  <kwd> BY                            /* SQL-2003-R */
 | |
| %token  <kwd> CALL_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> CASCADE                       /* SQL-2003-N */
 | |
| %token  <kwd> CASE_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> CAST_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> CHANGE
 | |
| %token  <kwd> CHAR_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> CHECK_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> COLLATE_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> CONDITION_SYM                 /* SQL-2003-R, SQL-2008-R */
 | |
| %token  <kwd> CONSTRAINT                    /* SQL-2003-R */
 | |
| %token  <kwd> CONTINUE_MARIADB_SYM          /* SQL-2003-R, Oracle-R */
 | |
| %token  <kwd> CONTINUE_ORACLE_SYM           /* SQL-2003-R, Oracle-R */
 | |
| %token  <kwd> CONVERT_SYM                   /* SQL-2003-N */
 | |
| %token  <kwd> COUNT_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd> CREATE                        /* SQL-2003-R */
 | |
| %token  <kwd> CROSS                         /* SQL-2003-R */
 | |
| %token  <kwd> CUME_DIST_SYM
 | |
| %token  <kwd> CURDATE                       /* MYSQL-FUNC */
 | |
| %token  <kwd> CURRENT_ROLE                  /* SQL-2003-R */
 | |
| %token  <kwd> CURRENT_USER                  /* SQL-2003-R */
 | |
| %token  <kwd> CURSOR_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> CURTIME                       /* MYSQL-FUNC */
 | |
| %token  <kwd> DATABASE
 | |
| %token  <kwd> DATABASES
 | |
| %token  <kwd> DATE_ADD_INTERVAL             /* MYSQL-FUNC */
 | |
| %token  <kwd> DATE_SUB_INTERVAL             /* MYSQL-FUNC */
 | |
| %token  <kwd> DAY_HOUR_SYM
 | |
| %token  <kwd> DAY_MICROSECOND_SYM
 | |
| %token  <kwd> DAY_MINUTE_SYM
 | |
| %token  <kwd> DAY_SECOND_SYM
 | |
| %token  <kwd> DECIMAL_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> DECLARE_MARIADB_SYM           /* SQL-2003-R */
 | |
| %token  <kwd> DECLARE_ORACLE_SYM            /* Oracle-R   */
 | |
| %token  <kwd> DEFAULT                       /* SQL-2003-R */
 | |
| %token  <kwd> DELETE_DOMAIN_ID_SYM
 | |
| %token  <kwd> DELETE_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> DENSE_RANK_SYM
 | |
| %token  <kwd> DESCRIBE                      /* SQL-2003-R */
 | |
| %token  <kwd> DESC                          /* SQL-2003-N */
 | |
| %token  <kwd> DETERMINISTIC_SYM             /* SQL-2003-R */
 | |
| %token  <kwd> DISTINCT                      /* SQL-2003-R */
 | |
| %token  <kwd> DIV_SYM
 | |
| %token  <kwd> DO_DOMAIN_IDS_SYM
 | |
| %token  <kwd> DOUBLE_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> DROP                          /* SQL-2003-R */
 | |
| %token  <kwd> DUAL_SYM
 | |
| %token  <kwd> EACH_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> ELSEIF_MARIADB_SYM
 | |
| %token  <kwd> ELSE                          /* SQL-2003-R */
 | |
| %token  <kwd> ELSIF_ORACLE_SYM              /* PLSQL-R    */
 | |
| %token  <kwd> EMPTY_SYM                     /* SQL-2016-R */
 | |
| %token  <kwd> ENCLOSED
 | |
| %token  <kwd> ESCAPED
 | |
| %token  <kwd> EXCEPT_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> EXISTS                        /* SQL-2003-R */
 | |
| %token  <kwd> EXTRACT_SYM                   /* SQL-2003-N */
 | |
| %token  <kwd> FALSE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> FETCH_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> FIRST_VALUE_SYM               /* SQL-2011 */
 | |
| %token  <kwd> FLOAT_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> FOREIGN                       /* SQL-2003-R */
 | |
| %token  <kwd> FOR_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> FROM
 | |
| %token  <kwd> FULLTEXT_SYM
 | |
| %token  <kwd> GOTO_ORACLE_SYM               /* Oracle-R   */
 | |
| %token  <kwd> GRANT                         /* SQL-2003-R */
 | |
| %token  <kwd> GROUP_CONCAT_SYM
 | |
| %token  <rwd> JSON_ARRAYAGG_SYM
 | |
| %token  <rwd> JSON_OBJECTAGG_SYM
 | |
| %token  <kwd> JSON_TABLE_SYM
 | |
| %token  <kwd> GROUP_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> HAVING                        /* SQL-2003-R */
 | |
| %token  <kwd> HOUR_MICROSECOND_SYM
 | |
| %token  <kwd> HOUR_MINUTE_SYM
 | |
| %token  <kwd> HOUR_SECOND_SYM
 | |
| %token  <kwd> IF_SYM
 | |
| %token  <kwd> IGNORE_DOMAIN_IDS_SYM
 | |
| %token  <kwd> IGNORE_SYM
 | |
| %token  <kwd> IGNORED_SYM
 | |
| %token  <kwd> INDEX_SYM
 | |
| %token  <kwd> INFILE
 | |
| %token  <kwd> INNER_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> INOUT_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> INSENSITIVE_SYM               /* SQL-2003-R */
 | |
| %token  <kwd> INSERT                        /* SQL-2003-R */
 | |
| %token  <kwd> IN_SYM                        /* SQL-2003-R */
 | |
| %token  <kwd> INTERSECT_SYM                 /* SQL-2003-R */
 | |
| %token  <kwd> INTERVAL_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd> INTO                          /* SQL-2003-R */
 | |
| %token  <kwd> INT_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> IS                            /* SQL-2003-R */
 | |
| %token  <kwd> ITERATE_SYM
 | |
| %token  <kwd> JOIN_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> KEYS
 | |
| %token  <kwd> KEY_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd> KILL_SYM
 | |
| %token  <kwd> LAG_SYM                       /* SQL-2011 */
 | |
| %token  <kwd> LEADING                       /* SQL-2003-R */
 | |
| %token  <kwd> LEAD_SYM                      /* SQL-2011 */
 | |
| %token  <kwd> LEAVE_SYM
 | |
| %token  <kwd> LEFT                          /* SQL-2003-R */
 | |
| %token  <kwd> LIKE                          /* SQL-2003-R */
 | |
| %token  <kwd> LIMIT
 | |
| %token  <kwd> LINEAR_SYM
 | |
| %token  <kwd> LINES
 | |
| %token  <kwd> LOAD
 | |
| %token  <kwd> LOCALTIMESTAMP                /* SQL-2003-R */
 | |
| %token  <kwd> LOCATOR_SYM                   /* SQL-2003-N */
 | |
| %token  <kwd> LOCK_SYM
 | |
| %token  <kwd> LONGBLOB
 | |
| %token  <kwd> LONG_SYM
 | |
| %token  <kwd> LONGTEXT
 | |
| %token  <kwd> LOOP_SYM
 | |
| %token  <kwd> LOW_PRIORITY
 | |
| %token  <kwd> MASTER_SSL_VERIFY_SERVER_CERT_SYM
 | |
| %token  <kwd> MATCH                         /* SQL-2003-R */
 | |
| %token  <kwd> MAX_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd> MAXVALUE_SYM                  /* SQL-2003-N */
 | |
| %token  <kwd> MEDIAN_SYM
 | |
| %token  <kwd> MEDIUMBLOB
 | |
| %token  <kwd> MEDIUMINT
 | |
| %token  <kwd> MEDIUMTEXT
 | |
| %token  <kwd> MIN_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd> MINUS_ORACLE_SYM              /* Oracle-R   */
 | |
| %token  <kwd> MINUTE_MICROSECOND_SYM
 | |
| %token  <kwd> MINUTE_SECOND_SYM
 | |
| %token  <kwd> MODIFIES_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd> MOD_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd> NATURAL                       /* SQL-2003-R */
 | |
| %token  <kwd> NEG
 | |
| %token  <kwd> NESTED_SYM                    /* SQL-2003-N */
 | |
| %token  <kwd> NOT_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> NO_WRITE_TO_BINLOG
 | |
| %token  <kwd> NOW_SYM
 | |
| %token  <kwd> NTH_VALUE_SYM                 /* SQL-2011 */
 | |
| %token  <kwd> NTILE_SYM
 | |
| %token  <kwd> NULL_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> NUMERIC_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> ON                            /* SQL-2003-R */
 | |
| %token  <kwd> OPTIMIZE
 | |
| %token  <kwd> OPTIONALLY
 | |
| %token  <kwd> ORDER_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> ORDINALITY_SYM                /* SQL-2003-N */
 | |
| %token  <kwd> OR_SYM                        /* SQL-2003-R */
 | |
| %token  <kwd> OTHERS_ORACLE_SYM             /* SQL-2011-N, PLSQL-R */
 | |
| %token  <kwd> OUTER
 | |
| %token  <kwd> OUTFILE
 | |
| %token  <kwd> OUT_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> OVER_SYM
 | |
| %token  <kwd> PACKAGE_ORACLE_SYM            /* Oracle-R   */
 | |
| %token  <kwd> PAGE_CHECKSUM_SYM
 | |
| %token  <kwd> PARSE_VCOL_EXPR_SYM
 | |
| %token  <kwd> PARTITION_SYM                 /* SQL-2003-R */
 | |
| %token  <kwd> PATH_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd> PERCENTILE_CONT_SYM
 | |
| %token  <kwd> PERCENTILE_DISC_SYM
 | |
| %token  <kwd> PERCENT_RANK_SYM
 | |
| %token  <kwd> PORTION_SYM                   /* SQL-2016-R */
 | |
| %token  <kwd> POSITION_SYM                  /* SQL-2003-N */
 | |
| %token  <kwd> PRECISION                     /* SQL-2003-R */
 | |
| %token  <kwd> PRIMARY_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> PROCEDURE_SYM                 /* SQL-2003-R */
 | |
| %token  <kwd> PURGE
 | |
| %token  <kwd> RAISE_ORACLE_SYM              /* PLSQL-R    */
 | |
| %token  <kwd> RANGE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> RANK_SYM
 | |
| %token  <kwd> READS_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> READ_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd> READ_WRITE_SYM
 | |
| %token  <kwd> REAL                          /* SQL-2003-R */
 | |
| %token  <kwd> RECURSIVE_SYM
 | |
| %token  <kwd> REFERENCES                    /* SQL-2003-R */
 | |
| %token  <kwd> REF_SYSTEM_ID_SYM
 | |
| %token  <kwd> REGEXP
 | |
| %token  <kwd> RELEASE_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> RENAME
 | |
| %token  <kwd> REPEAT_SYM                    /* MYSQL-FUNC */
 | |
| %token  <kwd> REQUIRE_SYM
 | |
| %token  <kwd> RESIGNAL_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd> RESTRICT
 | |
| %token  <kwd> RETURNING_SYM
 | |
| %token  <kwd> RETURN_MARIADB_SYM            /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd> RETURN_ORACLE_SYM             /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd> REVOKE                        /* SQL-2003-R */
 | |
| %token  <kwd> RIGHT                         /* SQL-2003-R */
 | |
| %token  <kwd> ROW_NUMBER_SYM
 | |
| %token  <kwd> ROWS_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> ROWTYPE_ORACLE_SYM            /* PLSQL-R    */
 | |
| %token  <kwd> SECOND_MICROSECOND_SYM
 | |
| %token  <kwd> SELECT_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> SENSITIVE_SYM                 /* FUTURE-USE */
 | |
| %token  <kwd> SEPARATOR_SYM
 | |
| %token  <kwd> SERVER_OPTIONS
 | |
| %token  <kwd> SET                           /* SQL-2003-R */
 | |
| %token  <kwd> SHOW
 | |
| %token  <kwd> SIGNAL_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> SMALLINT                      /* SQL-2003-R */
 | |
| %token  <kwd> SPATIAL_SYM
 | |
| %token  <kwd> SPECIFIC_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd> SQL_BIG_RESULT
 | |
| %token  <kwd> SQLEXCEPTION_SYM              /* SQL-2003-R */
 | |
| %token  <kwd> SQL_SMALL_RESULT
 | |
| %token  <kwd> SQLSTATE_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd> SQL_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd> SQLWARNING_SYM                /* SQL-2003-R */
 | |
| %token  <kwd> SSL_SYM
 | |
| %token  <kwd> STARTING
 | |
| %token  <kwd> STATS_AUTO_RECALC_SYM
 | |
| %token  <kwd> STATS_PERSISTENT_SYM
 | |
| %token  <kwd> STATS_SAMPLE_PAGES_SYM
 | |
| %token  <kwd> STDDEV_SAMP_SYM               /* SQL-2003-N */
 | |
| %token  <kwd> STD_SYM
 | |
| %token  <kwd> STRAIGHT_JOIN
 | |
| %token  <kwd> SUM_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd> SYSDATE
 | |
| %token  <kwd> TABLE_REF_PRIORITY
 | |
| %token  <kwd> TABLE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> TERMINATED
 | |
| %token  <kwd> THEN_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> TINYBLOB
 | |
| %token  <kwd> TINYINT
 | |
| %token  <kwd> TINYTEXT
 | |
| %token  <kwd> TO_SYM                        /* SQL-2003-R */
 | |
| %token  <kwd> TRAILING                      /* SQL-2003-R */
 | |
| %token  <kwd> TRIGGER_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd> TRUE_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> UNDO_SYM                      /* FUTURE-USE */
 | |
| %token  <kwd> UNION_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd> UNIQUE_SYM
 | |
| %token  <kwd> UNLOCK_SYM
 | |
| %token  <kwd> UNSIGNED
 | |
| %token  <kwd> UPDATE_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd> USAGE                         /* SQL-2003-N */
 | |
| %token  <kwd> USE_SYM
 | |
| %token  <kwd> USING                         /* SQL-2003-R */
 | |
| %token  <kwd> UTC_DATE_SYM
 | |
| %token  <kwd> UTC_TIMESTAMP_SYM
 | |
| %token  <kwd> UTC_TIME_SYM
 | |
| %token  <kwd> VALUES_IN_SYM
 | |
| %token  <kwd> VALUES_LESS_SYM
 | |
| %token  <kwd> VALUES                        /* SQL-2003-R */
 | |
| %token  <kwd> VARBINARY
 | |
| %token  <kwd> VARCHAR                       /* SQL-2003-R */
 | |
| %token  <kwd> VARIANCE_SYM
 | |
| %token  <kwd> VAR_SAMP_SYM
 | |
| %token  <kwd> VARYING                       /* SQL-2003-R */
 | |
| %token  <kwd> VECTOR_SYM
 | |
| %token  <kwd> WHEN_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd> WHERE                         /* SQL-2003-R */
 | |
| %token  <kwd> WHILE_SYM
 | |
| %token  <kwd> WITH                          /* SQL-2003-R */
 | |
| %token  <kwd> XOR
 | |
| %token  <kwd> YEAR_MONTH_SYM
 | |
| %token  <kwd> ZEROFILL
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Keywords that have different reserved status in std/oracle modes.
 | |
| */
 | |
| %token  <kwd>  BODY_MARIADB_SYM              // Oracle-R
 | |
| %token  <kwd>  ELSEIF_ORACLE_SYM
 | |
| %token  <kwd>  ELSIF_MARIADB_SYM             // PLSQL-R
 | |
| %token  <kwd>  EXCEPTION_ORACLE_SYM          // SQL-2003-N, PLSQL-R
 | |
| %token  <kwd>  GOTO_MARIADB_SYM              // Oracle-R
 | |
| %token  <kwd>  NOCOPY_SYM                    // PLSQL-N
 | |
| %token  <kwd>  OTHERS_MARIADB_SYM            // SQL-2011-N, PLSQL-R
 | |
| %token  <kwd>  PACKAGE_MARIADB_SYM           // Oracle-R
 | |
| %token  <kwd>  RAISE_MARIADB_SYM             // PLSQL-R
 | |
| %token  <kwd>  RECORD_SYM
 | |
| %token  <kwd>  ROWTYPE_MARIADB_SYM           // PLSQL-R
 | |
| %token  <kwd>  ROWNUM_SYM                    /* Oracle-R */
 | |
| 
 | |
| /*
 | |
|   SQL functions with a special syntax
 | |
| */
 | |
| %token  <kwd> REPLACE                        /* MYSQL-FUNC */
 | |
| %token  <kwd> SUBSTRING                      /* SQL-2003-N */
 | |
| %token  <kwd> TRIM                           /* SQL-2003-N */
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Non-reserved keywords
 | |
| */
 | |
| 
 | |
| %token  <kwd>  ACCOUNT_SYM                   /* MYSQL */
 | |
| %token  <kwd>  ACTION                        /* SQL-2003-N */
 | |
| %token  <kwd>  ADMIN_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  ADDDATE_SYM                   /* MYSQL-FUNC */
 | |
| %token  <kwd>  AFTER_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  AGAINST
 | |
| %token  <kwd>  AGGREGATE_SYM
 | |
| %token  <kwd>  ALGORITHM_SYM
 | |
| %token  <kwd>  ALWAYS_SYM
 | |
| %token  <kwd>  ANY_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd>  ASCII_SYM                     /* MYSQL-FUNC */
 | |
| %token  <kwd>  AT_SYM                        /* SQL-2003-R */
 | |
| %token  <kwd>  ATOMIC_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  AUTHORS_SYM
 | |
| %token  <kwd>  AUTOEXTEND_SIZE_SYM
 | |
| %token  <kwd>  AUTO_INC
 | |
| %token  <kwd>  AUTO_SYM
 | |
| %token  <kwd>  AVG_ROW_LENGTH
 | |
| %token  <kwd>  AVG_SYM                       /* SQL-2003-N */
 | |
| %token  <kwd>  BACKUP_SYM
 | |
| %token  <kwd>  BEGIN_MARIADB_SYM             /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd>  BEGIN_ORACLE_SYM              /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd>  BINLOG_SYM
 | |
| %token  <kwd>  BIT_SYM                       /* MYSQL-FUNC */
 | |
| %token  <kwd>  BLOCK_SYM
 | |
| %token  <kwd>  BOOL_SYM
 | |
| %token  <kwd>  BOOLEAN_SYM                   /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd>  BTREE_SYM
 | |
| %token  <kwd>  BYTE_SYM
 | |
| %token  <kwd>  CACHE_SYM
 | |
| %token  <kwd>  CASCADED                      /* SQL-2003-R */
 | |
| %token  <kwd>  CATALOG_NAME_SYM              /* SQL-2003-N */
 | |
| %token  <kwd>  CHAIN_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  CHANGED
 | |
| %token  <kwd>  CHANNEL_SYM
 | |
| %token  <kwd>  CHARSET
 | |
| %token  <kwd>  CHECKPOINT_SYM
 | |
| %token  <kwd>  CHECKSUM_SYM
 | |
| %token  <kwd>  CIPHER_SYM
 | |
| %token  <kwd>  CLASS_ORIGIN_SYM              /* SQL-2003-N */
 | |
| %token  <kwd>  CLIENT_SYM
 | |
| %token  <kwd>  CLOB_MARIADB_SYM              /* SQL-2003-R */
 | |
| %token  <kwd>  CLOB_ORACLE_SYM               /* Oracle-R   */
 | |
| %token  <kwd>  CLOSE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  COALESCE                      /* SQL-2003-N */
 | |
| %token  <kwd>  CODE_SYM
 | |
| %token  <kwd>  COLLATION_SYM                 /* SQL-2003-N */
 | |
| %token  <kwd>  COLUMNS
 | |
| %token  <kwd>  COLUMN_ADD_SYM
 | |
| %token  <kwd>  COLUMN_CHECK_SYM
 | |
| %token  <kwd>  COLUMN_CREATE_SYM
 | |
| %token  <kwd>  COLUMN_DELETE_SYM
 | |
| %token  <kwd>  COLUMN_GET_SYM
 | |
| %token  <kwd>  COLUMN_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  COLUMN_NAME_SYM               /* SQL-2003-N */
 | |
| %token  <kwd>  COMMENT_SYM                   /* Oracle-R   */
 | |
| %token  <kwd>  COMMITTED_SYM                 /* SQL-2003-N */
 | |
| %token  <kwd>  COMMIT_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  COMPACT_SYM
 | |
| %token  <kwd>  COMPLETION_SYM
 | |
| %token  <kwd>  COMPRESSED_SYM
 | |
| %token  <kwd>  CONCURRENT
 | |
| %token  <kwd>  CONNECTION_SYM
 | |
| %token  <kwd>  CONSISTENT_SYM
 | |
| %token  <kwd>  CONSTRAINT_CATALOG_SYM        /* SQL-2003-N */
 | |
| %token  <kwd>  CONSTRAINT_NAME_SYM           /* SQL-2003-N */
 | |
| %token  <kwd>  CONSTRAINT_SCHEMA_SYM         /* SQL-2003-N */
 | |
| %token  <kwd>  CONTAINS_SYM                  /* SQL-2003-N */
 | |
| %token  <kwd>  CONTEXT_SYM
 | |
| %token  <kwd>  CONTRIBUTORS_SYM
 | |
| %token  <kwd>  CPU_SYM
 | |
| %token  <kwd>  CUBE_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  CURRENT_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  CURRENT_POS_SYM
 | |
| %token  <kwd>  CURSOR_NAME_SYM               /* SQL-2003-N */
 | |
| %token  <kwd>  CYCLE_SYM
 | |
| %token  <kwd>  DATAFILE_SYM
 | |
| %token  <kwd>  DATA_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  DATETIME
 | |
| %token  <kwd>  DATE_SYM                      /* SQL-2003-R, Oracle-R, PLSQL-R */
 | |
| %token  <kwd>  DAY_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd>  DEALLOCATE_SYM                /* SQL-2003-R */
 | |
| %token  <kwd>  DEFINER_SYM
 | |
| %token  <kwd>  DELAYED_SYM
 | |
| %token  <kwd>  DELAY_KEY_WRITE_SYM
 | |
| %token  <kwd>  DES_KEY_FILE
 | |
| %token  <kwd>  DIAGNOSTICS_SYM               /* SQL-2003-N */
 | |
| %token  <kwd>  DIRECTORY_SYM
 | |
| %token  <kwd>  DISABLE_SYM
 | |
| %token  <kwd>  DISCARD
 | |
| %token  <kwd>  DISK_SYM
 | |
| %token  <kwd>  DO_SYM
 | |
| %token  <kwd>  DUMPFILE
 | |
| %token  <kwd>  DUPLICATE_SYM
 | |
| %token  <kwd>  DYNAMIC_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  ENABLE_SYM
 | |
| %token  <kwd>  END                           /* SQL-2003-R, PLSQL-R */
 | |
| %token  <kwd>  ENDS_SYM
 | |
| %token  <kwd>  ENGINES_SYM
 | |
| %token  <kwd>  ENGINE_SYM
 | |
| %token  <kwd>  ENUM
 | |
| %token  <kwd>  ERROR_SYM
 | |
| %token  <kwd>  ERRORS
 | |
| %token  <kwd>  ESCAPE_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  EVENTS_SYM
 | |
| %token  <kwd>  EVENT_SYM
 | |
| %token  <kwd>  EVERY_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  EXCHANGE_SYM
 | |
| %token  <kwd>  EXAMINED_SYM
 | |
| %token  <kwd>  EXCLUDE_SYM                   /* SQL-2011-N */
 | |
| %token  <kwd>  EXECUTE_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  EXCEPTION_MARIADB_SYM         /* SQL-2003-N, PLSQL-R */
 | |
| %token  <kwd>  EXIT_MARIADB_SYM              /* PLSQL-R */
 | |
| %token  <kwd>  EXIT_ORACLE_SYM               /* PLSQL-R */
 | |
| %token  <kwd>  EXPANSION_SYM
 | |
| %token  <kwd>  EXPIRE_SYM                    /* MySQL */
 | |
| %token  <kwd>  EXPORT_SYM
 | |
| %token  <kwd>  EXTENDED_SYM
 | |
| %token  <kwd>  EXTENT_SIZE_SYM
 | |
| %token  <kwd>  FAST_SYM
 | |
| %token  <kwd>  FAULTS_SYM
 | |
| %token  <kwd>  FEDERATED_SYM                 /* MariaDB privilege */
 | |
| %token  <kwd>  FILE_SYM
 | |
| %token  <kwd>  FIRST_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  FIXED_SYM
 | |
| %token  <kwd>  FLUSH_SYM
 | |
| %token  <kwd>  FOLLOWS_SYM                   /* MYSQL trigger*/
 | |
| %token  <kwd>  FOLLOWING_SYM                 /* SQL-2011-N */
 | |
| %token  <kwd>  FORCE_SYM
 | |
| %token  <kwd>  FORMAT_SYM
 | |
| %token  <kwd>  FOUND_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  FULL                          /* SQL-2003-R */
 | |
| %token  <kwd>  FUNCTION_SYM                  /* SQL-2003-R, Oracle-R */
 | |
| %token  <kwd>  GENERAL
 | |
| %token  <kwd>  GENERATED_SYM
 | |
| %token  <kwd>  GET_FORMAT                    /* MYSQL-FUNC */
 | |
| %token  <kwd>  GET_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd>  GLOBAL_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  GRANTS
 | |
| %token  <kwd>  HANDLER_SYM
 | |
| %token  <kwd>  HARD_SYM
 | |
| %token  <kwd>  HASH_SYM
 | |
| %token  <kwd>  HELP_SYM
 | |
| %token  <kwd>  HIGH_PRIORITY
 | |
| %token  <kwd>  HISTORY_SYM                   /* MYSQL */
 | |
| %token  <kwd>  HOST_SYM
 | |
| %token  <kwd>  HOSTS_SYM
 | |
| %token  <kwd>  HOUR_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  ID_SYM                        /* MYSQL */
 | |
| %token  <kwd>  IDENTIFIED_SYM
 | |
| %token  <kwd>  IGNORE_SERVER_IDS_SYM
 | |
| %token  <kwd>  IMMEDIATE_SYM                 /* SQL-2003-R */
 | |
| %token  <kwd>  IMPORT
 | |
| %token  <kwd>  INCREMENT_SYM
 | |
| %token  <kwd>  INDEXES
 | |
| %token  <kwd>  INITIAL_SIZE_SYM
 | |
| %token  <kwd>  INSERT_METHOD
 | |
| %token  <kwd>  INSTALL_SYM
 | |
| %token  <kwd>  INVOKER_SYM
 | |
| %token  <kwd>  IO_SYM
 | |
| %token  <kwd>  IPC_SYM
 | |
| %token  <kwd>  ISOLATION                     /* SQL-2003-R */
 | |
| %token  <kwd>  ISOPEN_SYM                    /* Oracle-N   */
 | |
| %token  <kwd>  ISSUER_SYM
 | |
| %token  <kwd>  INVISIBLE_SYM
 | |
| %token  <kwd>  JSON_SYM
 | |
| %token  <kwd>  KEY_BLOCK_SIZE
 | |
| %token  <kwd>  LANGUAGE_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd>  LAST_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  LAST_VALUE
 | |
| %token  <kwd>  LASTVAL_SYM                   /* PostgreSQL sequence function */
 | |
| %token  <kwd>  LEAVES
 | |
| %token  <kwd>  LESS_SYM
 | |
| %token  <kwd>  LEVEL_SYM
 | |
| %token  <kwd>  LIST_SYM
 | |
| %token  <kwd>  LOCAL_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  LOCKED_SYM
 | |
| %token  <kwd>  LOCKS_SYM
 | |
| %token  <kwd>  LOGFILE_SYM
 | |
| %token  <kwd>  LOGS_SYM
 | |
| %token  <kwd>  MASTER_CONNECT_RETRY_SYM
 | |
| %token  <kwd>  MASTER_DELAY_SYM
 | |
| %token  <kwd>  MASTER_GTID_POS_SYM
 | |
| %token  <kwd>  MASTER_HOST_SYM
 | |
| %token  <kwd>  MASTER_LOG_FILE_SYM
 | |
| %token  <kwd>  MASTER_LOG_POS_SYM
 | |
| %token  <kwd>  MASTER_PASSWORD_SYM
 | |
| %token  <kwd>  MASTER_PORT_SYM
 | |
| %token  <kwd>  MASTER_RETRY_COUNT_SYM
 | |
| %token  <kwd>  MASTER_SERVER_ID_SYM
 | |
| %token  <kwd>  MASTER_SSL_CAPATH_SYM
 | |
| %token  <kwd>  MASTER_SSL_CA_SYM
 | |
| %token  <kwd>  MASTER_SSL_CERT_SYM
 | |
| %token  <kwd>  MASTER_SSL_CIPHER_SYM
 | |
| %token  <kwd>  MASTER_SSL_CRL_SYM
 | |
| %token  <kwd>  MASTER_SSL_CRLPATH_SYM
 | |
| %token  <kwd>  MASTER_SSL_KEY_SYM
 | |
| %token  <kwd>  MASTER_SSL_SYM
 | |
| %token  <kwd>  MASTER_SYM
 | |
| %token  <kwd>  MASTER_USER_SYM
 | |
| %token  <kwd>  MASTER_USE_GTID_SYM
 | |
| %token  <kwd>  MASTER_HEARTBEAT_PERIOD_SYM
 | |
| %token  <kwd>  MASTER_DEMOTE_TO_SLAVE_SYM
 | |
| %token  <kwd>  MAX_CONNECTIONS_PER_HOUR
 | |
| %token  <kwd>  MAX_QUERIES_PER_HOUR
 | |
| %token  <kwd>  MAX_ROWS
 | |
| %token  <kwd>  MAX_SIZE_SYM
 | |
| %token  <kwd>  MAX_UPDATES_PER_HOUR
 | |
| %token  <kwd>  MAX_STATEMENT_TIME_SYM
 | |
| %token  <kwd>  MAX_USER_CONNECTIONS_SYM
 | |
| %token  <kwd>  MEDIUM_SYM
 | |
| %token  <kwd>  MEMORY_SYM
 | |
| %token  <kwd>  MERGE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  MESSAGE_TEXT_SYM              /* SQL-2003-N */
 | |
| %token  <kwd>  MICROSECOND_SYM               /* MYSQL-FUNC */
 | |
| %token  <kwd>  MIGRATE_SYM
 | |
| %token  <kwd>  MINUTE_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  MINVALUE_SYM
 | |
| %token  <kwd>  MIN_ROWS
 | |
| %token  <kwd>  MODE_SYM
 | |
| %token  <kwd>  MODIFY_SYM
 | |
| %token  <kwd>  MONITOR_SYM                   /* MariaDB privilege */
 | |
| %token  <kwd>  MONTH_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  MUTEX_SYM
 | |
| %token  <kwd>  MYSQL_SYM
 | |
| %token  <kwd>  MYSQL_ERRNO_SYM
 | |
| %token  <kwd>  NAMES_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  NAME_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  NATIONAL_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd>  NCHAR_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  NEVER_SYM                     /* MySQL */
 | |
| %token  <kwd>  NEXT_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  NEXTVAL_SYM                   /* PostgreSQL sequence function */
 | |
| %token  <kwd>  NOCACHE_SYM
 | |
| %token  <kwd>  NOCYCLE_SYM
 | |
| %token  <kwd>  NODEGROUP_SYM
 | |
| %token  <kwd>  NONE_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  NOTFOUND_SYM                  /* Oracle-R   */
 | |
| %token  <kwd>  NO_SYM                        /* SQL-2003-R */
 | |
| %token  <kwd>  NOMAXVALUE_SYM
 | |
| %token  <kwd>  NOMINVALUE_SYM
 | |
| %token  <kwd>  NO_WAIT_SYM
 | |
| %token  <kwd>  NOWAIT_SYM
 | |
| %token  <kwd>  NUMBER_MARIADB_SYM            /* SQL-2003-N  */
 | |
| %token  <kwd>  NUMBER_ORACLE_SYM             /* Oracle-R, PLSQL-R */
 | |
| %token  <kwd>  NVARCHAR_SYM
 | |
| %token  <kwd>  OF_SYM                        /* SQL-1992-R, Oracle-R */
 | |
| %token  <kwd>  OFFSET_SYM
 | |
| %token  <kwd>  OLD_PASSWORD_SYM
 | |
| %token  <kwd>  ONE_SYM
 | |
| %token  <kwd>  ONLY_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  ONLINE_SYM
 | |
| %token  <kwd>  OPEN_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  OPTIONS_SYM
 | |
| %token  <kwd>  OPTION                        /* SQL-2003-N */
 | |
| %token  <kwd>  OVERLAPS_SYM
 | |
| %token  <kwd>  OWNER_SYM
 | |
| %token  <kwd>  PACK_KEYS_SYM
 | |
| %token  <kwd>  PAGE_SYM
 | |
| %token  <kwd>  PARSER_SYM
 | |
| %token  <kwd>  PARTIAL                       /* SQL-2003-N */
 | |
| %token  <kwd>  PARTITIONS_SYM
 | |
| %token  <kwd>  PARTITIONING_SYM
 | |
| %token  <kwd>  PASSWORD_SYM
 | |
| %token  <kwd>  PERIOD_SYM                    /* SQL-2011-R */
 | |
| %token  <kwd>  PERSISTENT_SYM
 | |
| %token  <kwd>  PHASE_SYM
 | |
| %token  <kwd>  PLUGINS_SYM
 | |
| %token  <kwd>  PLUGIN_SYM
 | |
| %token  <kwd>  PORT_SYM
 | |
| %token  <kwd>  PRECEDES_SYM                  /* MYSQL */
 | |
| %token  <kwd>  PRECEDING_SYM                 /* SQL-2011-N */
 | |
| %token  <kwd>  PREPARE_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  PRESERVE_SYM
 | |
| %token  <kwd>  PREV_SYM
 | |
| %token  <kwd>  PREVIOUS_SYM
 | |
| %token  <kwd>  PRIVILEGES                    /* SQL-2003-N */
 | |
| %token  <kwd>  PROCESS
 | |
| %token  <kwd>  PROCESSLIST_SYM
 | |
| %token  <kwd>  PROFILE_SYM
 | |
| %token  <kwd>  PROFILES_SYM
 | |
| %token  <kwd>  PROXY_SYM
 | |
| %token  <kwd>  QUARTER_SYM
 | |
| %token  <kwd>  QUERY_SYM
 | |
| %token  <kwd>  QUICK
 | |
| %token  <kwd>  RAW_MARIADB_SYM
 | |
| %token  <kwd>  RAW_ORACLE_SYM                /* Oracle-R */
 | |
| %token  <kwd>  READ_ONLY_SYM
 | |
| %token  <kwd>  REBUILD_SYM
 | |
| %token  <kwd>  RECOVER_SYM
 | |
| %token  <kwd>  REDOFILE_SYM
 | |
| %token  <kwd>  REDO_BUFFER_SIZE_SYM
 | |
| %token  <kwd>  REDUNDANT_SYM
 | |
| %token  <kwd>  RELAY
 | |
| %token  <kwd>  RELAYLOG_SYM
 | |
| %token  <kwd>  RELAY_LOG_FILE_SYM
 | |
| %token  <kwd>  RELAY_LOG_POS_SYM
 | |
| %token  <kwd>  RELAY_THREAD
 | |
| %token  <kwd>  RELOAD
 | |
| %token  <kwd>  REMOVE_SYM
 | |
| %token  <kwd>  REORGANIZE_SYM
 | |
| %token  <kwd>  REPAIR
 | |
| %token  <kwd>  REPEATABLE_SYM                /* SQL-2003-N */
 | |
| %token  <kwd>  REPLAY_SYM                    /* MariaDB privilege */
 | |
| %token  <kwd>  REPLICATION
 | |
| %token  <kwd>  RESET_SYM
 | |
| %token  <kwd>  RESTART_SYM
 | |
| %token  <kwd>  RESOURCES
 | |
| %token  <kwd>  RESTORE_SYM
 | |
| %token  <kwd>  RESUME_SYM
 | |
| %token  <kwd>  RETURNED_SQLSTATE_SYM         /* SQL-2003-N */
 | |
| %token  <kwd>  RETURNS_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  REUSE_SYM                     /* Oracle-R   */
 | |
| %token  <kwd>  REVERSE_SYM
 | |
| %token  <kwd>  ROLE_SYM
 | |
| %token  <kwd>  ROLLBACK_SYM                  /* SQL-2003-R */
 | |
| %token  <kwd>  ROLLUP_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  ROUTINE_SYM                   /* SQL-2003-N */
 | |
| %token  <kwd>  ROWCOUNT_SYM                  /* Oracle-N   */
 | |
| %token  <kwd>  ROW_SYM                       /* SQL-2003-R */
 | |
| %token  <kwd>  ROW_COUNT_SYM                 /* SQL-2003-N */
 | |
| %token  <kwd>  ROW_FORMAT_SYM
 | |
| %token  <kwd>  RTREE_SYM
 | |
| %token  <kwd>  SAVEPOINT_SYM                 /* SQL-2003-R */
 | |
| %token  <kwd>  SCHEDULE_SYM
 | |
| %token  <kwd>  SCHEMA_NAME_SYM               /* SQL-2003-N */
 | |
| %token  <kwd>  SECOND_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  SECURITY_SYM                  /* SQL-2003-N */
 | |
| %token  <kwd>  SEQUENCE_SYM
 | |
| %token  <kwd>  SERIALIZABLE_SYM              /* SQL-2003-N */
 | |
| %token  <kwd>  SERIAL_SYM
 | |
| %token  <kwd>  SESSION_SYM                   /* SQL-2003-N */
 | |
| %token  <kwd>  SESSION_USER_SYM              /* SQL-2003-R */
 | |
| %token  <kwd>  SERVER_SYM
 | |
| %token  <kwd>  SETVAL_SYM                    /* PostgreSQL sequence function */
 | |
| %token  <kwd>  SHARE_SYM
 | |
| %token  <kwd>  SHUTDOWN
 | |
| %token  <kwd>  SIGNED_SYM
 | |
| %token  <kwd>  SIMPLE_SYM                    /* SQL-2003-N */
 | |
| %token  <kwd>  SKIP_SYM
 | |
| %token  <kwd>  SLAVE
 | |
| %token  <kwd>  SLAVES
 | |
| %token  <kwd>  SLAVE_POS_SYM
 | |
| %token  <kwd>  SLOW
 | |
| %token  <kwd>  SNAPSHOT_SYM
 | |
| %token  <kwd>  SOCKET_SYM
 | |
| %token  <kwd>  SOFT_SYM
 | |
| %token  <kwd>  SONAME_SYM
 | |
| %token  <kwd>  SOUNDS_SYM
 | |
| %token  <kwd>  SOURCE_SYM
 | |
| %token  <kwd>  SQL_AFTER_GTIDS_SYM
 | |
| %token  <kwd>  SQL_BEFORE_GTIDS_SYM
 | |
| %token  <kwd>  SQL_BUFFER_RESULT
 | |
| %token  <kwd>  SQL_CACHE_SYM
 | |
| %token  <kwd>  SQL_CALC_FOUND_ROWS
 | |
| %token  <kwd>  SQL_NO_CACHE_SYM
 | |
| %token  <kwd>  SQL_THREAD
 | |
| %token  <kwd>  STAGE_SYM
 | |
| %token  <kwd>  STARTS_SYM
 | |
| %token  <kwd>  START_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  STATEMENT_SYM
 | |
| %token  <kwd>  STATUS_SYM
 | |
| %token  <kwd>  STOP_SYM
 | |
| %token  <kwd>  STORAGE_SYM
 | |
| %token  <kwd>  STORED_SYM
 | |
| %token  <kwd>  STRING_SYM
 | |
| %token  <kwd>  SUBCLASS_ORIGIN_SYM           /* SQL-2003-N */
 | |
| %token  <kwd>  SUBDATE_SYM
 | |
| %token  <kwd>  SUBJECT_SYM
 | |
| %token  <kwd>  SUBPARTITIONS_SYM
 | |
| %token  <kwd>  SUBPARTITION_SYM
 | |
| %token  <kwd>  SUPER_SYM
 | |
| %token  <kwd>  SUSPEND_SYM
 | |
| %token  <kwd>  SWAPS_SYM
 | |
| %token  <kwd>  SWITCHES_SYM
 | |
| %token  <kwd>  SYSTEM                        /* SQL-2011-R */
 | |
| %token  <kwd>  SYSTEM_TIME_SYM               /* SQL-2011-R */
 | |
| %token  <kwd>  TABLES
 | |
| %token  <kwd>  TABLESPACE
 | |
| %token  <kwd>  TABLE_CHECKSUM_SYM
 | |
| %token  <kwd>  TABLE_NAME_SYM                /* SQL-2003-N */
 | |
| %token  <kwd>  TEMPORARY                     /* SQL-2003-N */
 | |
| %token  <kwd>  TEMPTABLE_SYM
 | |
| %token  <kwd>  TEXT_SYM
 | |
| %token  <kwd>  THAN_SYM
 | |
| %token  <kwd>  TIES_SYM                      /* SQL-2011-N */
 | |
| %token  <kwd>  TIMESTAMP                     /* SQL-2003-R */
 | |
| %token  <kwd>  TIMESTAMP_ADD
 | |
| %token  <kwd>  TIMESTAMP_DIFF
 | |
| %token  <kwd>  TIME_SYM                      /* SQL-2003-R, Oracle-R */
 | |
| %token  <kwd>  TRANSACTION_SYM
 | |
| %token  <kwd>  TRANSACTIONAL_SYM
 | |
| %token  <kwd>  THREADS_SYM
 | |
| %token  <kwd>  TRIGGERS_SYM
 | |
| %token  <kwd>  TRIM_ORACLE
 | |
| %token  <kwd>  TRUNCATE_SYM
 | |
| %token  <kwd>  TYPE_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  UDF_RETURNS_SYM
 | |
| %token  <kwd>  UNBOUNDED_SYM                 /* SQL-2011-N */
 | |
| %token  <kwd>  UNCOMMITTED_SYM               /* SQL-2003-N */
 | |
| %token  <kwd>  UNDEFINED_SYM
 | |
| %token  <kwd>  UNDOFILE_SYM
 | |
| %token  <kwd>  UNDO_BUFFER_SIZE_SYM
 | |
| %token  <kwd>  UNICODE_SYM
 | |
| %token  <kwd>  UNINSTALL_SYM
 | |
| %token  <kwd>  UNKNOWN_SYM                   /* SQL-2003-R */
 | |
| %token  <kwd>  UNTIL_SYM
 | |
| %token  <kwd>  UPGRADE_SYM
 | |
| %token  <kwd>  USER_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>  USE_FRM
 | |
| %token  <kwd>  VALIDATION_SYM                /* MYSQL */
 | |
| %token  <kwd>  VALUE_SYM                     /* SQL-2003-R */
 | |
| %token  <kwd>  VARCHAR2_MARIADB_SYM
 | |
| %token  <kwd>  VARCHAR2_ORACLE_SYM           /* Oracle-R, PLSQL-R */
 | |
| %token  <kwd>  VARIABLES
 | |
| %token  <kwd>  VERSIONING_SYM                /* SQL-2011-R */
 | |
| %token  <kwd>  VIA_SYM
 | |
| %token  <kwd>  VIEW_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  VISIBLE_SYM                   /* MySQL 8.0 */
 | |
| %token  <kwd>  VIRTUAL_SYM
 | |
| %token  <kwd>  WAIT_SYM
 | |
| %token  <kwd>  WARNINGS
 | |
| %token  <kwd>  WEEK_SYM
 | |
| %token  <kwd>  WEIGHT_STRING_SYM
 | |
| %token  <kwd>  WINDOW_SYM                    /* SQL-2003-R */
 | |
| %token  <kwd>  WITHIN
 | |
| %token  <kwd>  WITHOUT                       /* SQL-2003-R */
 | |
| %token  <kwd>  WORK_SYM                      /* SQL-2003-N */
 | |
| %token  <kwd>  WRAPPER_SYM
 | |
| %token  <kwd>  WRITE_SYM                     /* SQL-2003-N */
 | |
| %token  <kwd>  X509_SYM
 | |
| %token  <kwd>  XA_SYM
 | |
| %token  <kwd>  XML_SYM
 | |
| %token  <kwd>  YEAR_SYM                      /* SQL-2003-R */
 | |
| %token  <kwd>   ST_COLLECT_SYM
 | |
| /* A dummy token to force the priority of table_ref production in a join. */
 | |
| %left   CONDITIONLESS_JOIN
 | |
| %left   JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT ON_SYM USING
 | |
|  
 | |
| %left   SET_VAR
 | |
| %left   OR_SYM OR2_SYM
 | |
| %left   XOR
 | |
| %left   AND_SYM AND_AND_SYM
 | |
| 
 | |
| %left   PREC_BELOW_NOT
 | |
| 
 | |
| /* The precendence of boolean NOT is in fact here. See the comment below. */
 | |
| 
 | |
| %left   '=' EQUAL_SYM GE '>' LE '<' NE
 | |
| %nonassoc IS
 | |
| %right BETWEEN_SYM
 | |
| %left   LIKE SOUNDS_SYM REGEXP IN_SYM
 | |
| %left   '|'
 | |
| %left   '&'
 | |
| %left   SHIFT_LEFT SHIFT_RIGHT
 | |
| %left   '-' '+' ORACLE_CONCAT_SYM
 | |
| %left   '*' '/' '%' DIV_SYM MOD_SYM
 | |
| %left   '^'
 | |
| %left   MYSQL_CONCAT_SYM
 | |
| /*
 | |
|   Boolean negation has a special branch in "expr" starting with NOT_SYM.
 | |
|   The precedence of logical negation is determined by the grammar itself
 | |
|   (without using Bison terminal symbol precedence) in this order
 | |
|   - Boolean factor (i.e. logical AND)
 | |
|   - Boolean NOT
 | |
|   - Boolean test (such as '=', IS NULL, IS TRUE)
 | |
| 
 | |
|   But we also need a precedence for NOT_SYM in other contexts,
 | |
|   to shift (without reduce) in these cases:
 | |
|      predicate <here> NOT IN ...
 | |
|      predicate <here> NOT BETWEEN ...
 | |
|      predicate <here> NOT LIKE ...
 | |
|      predicate <here> NOT REGEXP ...
 | |
|   If the precedence of NOT_SYM was low, it would reduce immediately
 | |
|   after scanning "predicate" and then produce a syntax error on "NOT".
 | |
| */
 | |
| %nonassoc NOT_SYM
 | |
| %nonassoc NEG '~' NOT2_SYM BINARY
 | |
| %nonassoc COLLATE_SYM
 | |
| %nonassoc SUBQUERY_AS_EXPR
 | |
| 
 | |
| /*
 | |
|   Tokens that can change their meaning from identifier to something else
 | |
|   in certain context.
 | |
| 
 | |
|   - TRANSACTION: identifier, history unit:
 | |
|       SELECT transaction FROM t1;
 | |
|       SELECT * FROM t1 FOR SYSTEM_TIME AS OF TRANSACTION @var;
 | |
| 
 | |
|   - TIMESTAMP: identifier, literal, history unit:
 | |
|       SELECT timestamp FROM t1;
 | |
|       SELECT TIMESTAMP '2001-01-01 10:20:30';
 | |
|       SELECT * FROM t1 FOR SYSTEM_TIME AS OF TIMESTAMP CONCAT(@date,' ',@time);
 | |
| 
 | |
|   - PERIOD: identifier, period for system time:
 | |
|       SELECT period FROM t1;
 | |
|       ALTER TABLE DROP PERIOD FOR SYSTEM TIME;
 | |
| 
 | |
|   - SYSTEM: identifier, system versioning:
 | |
|       SELECT system FROM t1;
 | |
|       ALTER TABLE DROP SYSTEM VERSIONIONG;
 | |
| 
 | |
|   - USER: identifier, user:
 | |
|       SELECT user FROM t1;
 | |
|       KILL USER foo;
 | |
| 
 | |
|    Note, we need here only tokens that cause shift/reduce conflicts
 | |
|    with keyword identifiers. For example:
 | |
|       opt_clause1: %empty | KEYWORD ... ;
 | |
|       clause2: opt_clause1 ident;
 | |
|    KEYWORD can appear both in opt_clause1 and in "ident" through the "keyword"
 | |
|    rule. So the parser reports a conflict on how to interpret KEYWORD:
 | |
|      - as a start of non-empty branch in opt_clause1, or
 | |
|      - as an identifier which follows the empty branch in opt_clause1.
 | |
| 
 | |
|    Example#1:
 | |
|      alter_list_item:
 | |
|        DROP opt_column opt_if_exists_table_element field_ident
 | |
|      | DROP SYSTEM VERSIONING_SYM
 | |
|    SYSTEM can be a keyword in field_ident, or can be a start of
 | |
|    SYSTEM VERSIONING.
 | |
| 
 | |
|    Example#2:
 | |
|      system_time_expr: AS OF_SYM history_point
 | |
|      history_point: opt_history_unit bit_expr
 | |
|      opt_history_unit: | TRANSACTION_SYM
 | |
|    TRANSACTION can be a non-empty history unit, or can be an identifier
 | |
|    in bit_expr.
 | |
| 
 | |
|    In the grammar below we use %prec to explicitly tell Bison to go
 | |
|    through the empty branch in the optional rule only when the lookahead
 | |
|    token does not belong to a small set of selected tokens.
 | |
| 
 | |
|    Tokens NEXT_SYM and PREVIOUS_SYM also change their meaning from
 | |
|    identifiers to sequence operations when followed by VALUE_SYM:
 | |
|       SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1;
 | |
|    but we don't need to list them here as they do not seem to cause
 | |
|    conflicts (according to bison -v), as both meanings
 | |
|    (as identifier, and as a sequence operation) are parts of the same target
 | |
|    column_default_non_parenthesized_expr, and there are no any optional
 | |
|    clauses between the start of column_default_non_parenthesized_expr
 | |
|    and until NEXT_SYM / PREVIOUS_SYM.
 | |
| */
 | |
| %left   PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE
 | |
| %left   TRANSACTION_SYM TIMESTAMP PERIOD_SYM SYSTEM USER COMMENT_SYM
 | |
| 
 | |
| %left   PREC_BELOW_SP_OBJECT_TYPE
 | |
| %left   PACKAGE_MARIADB_SYM FUNCTION_SYM
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Tokens that can appear in a token contraction on the second place
 | |
|   and change the meaning of the previous token.
 | |
| 
 | |
|   - TEXT_STRING: changes the meaning of TIMESTAMP/TIME/DATE
 | |
|     from identifier to literal:
 | |
|       SELECT timestamp FROM t1;
 | |
|       SELECT TIMESTAMP'2001-01-01 00:00:00' FROM t1;
 | |
| 
 | |
|   - Parenthesis: changes the meaning of TIMESTAMP/TIME/DATE
 | |
|     from identifiers to CAST-alike functions:
 | |
|       SELECT timestamp FROM t1;
 | |
|       SELECT timestamp(1) FROM t1;
 | |
| 
 | |
|   - VALUE: changes NEXT and PREVIOUS from identifier to sequence operation:
 | |
|       SELECT next, previous FROM t1;
 | |
|       SELECT NEXT VALUE FOR s1, PREVIOUS VALUE FOR s1;
 | |
| 
 | |
|   - VERSIONING: changes SYSTEM from identifier to SYSTEM VERSIONING
 | |
|       SELECT system FROM t1;
 | |
|       ALTER TABLE t1 ADD SYSTEM VERSIONING;
 | |
|   - OF: changes TYPE from a pluggable data type name to TYPE OF anchor
 | |
|       CREATE FUNCTION f1() RETURNS TYPE RETURN 1; -- pluggable data type 'TYPE'
 | |
|       CREATE FUNCTION f1() RETURNS TYPE OF t1.col; -- the data type of t1.col1
 | |
| 
 | |
| */
 | |
| %left   PREC_BELOW_CONTRACTION_TOKEN2
 | |
| %left   TEXT_STRING '(' ')' VALUE_SYM VERSIONING_SYM BODY_MARIADB_SYM OF_SYM
 | |
| %left EMPTY_FROM_CLAUSE
 | |
| %right INTO
 | |
| 
 | |
| %type <lex_str>
 | |
|         DECIMAL_NUM FLOAT_NUM NUM LONG_NUM
 | |
|         HEX_NUM HEX_STRING
 | |
|         LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident_or_text
 | |
|         TEXT_STRING_sys TEXT_STRING_literal
 | |
|         key_cache_name
 | |
|         sp_opt_label BIN_NUM TEXT_STRING_filesystem
 | |
|         opt_constraint constraint opt_ident
 | |
|         sp_block_label sp_control_label opt_place opt_db
 | |
|         udt_name
 | |
| 
 | |
| %type <ident_sys>
 | |
|         IDENT_sys
 | |
|         ident_func
 | |
|         ident
 | |
|         label_ident
 | |
|         sp_decl_ident
 | |
|         ident_options
 | |
|         ident_or_empty
 | |
|         ident_table_alias
 | |
|         ident_sysvar_name
 | |
|         ident_for_loop_index
 | |
| 
 | |
| %type <lex_string_with_metadata>
 | |
|         TEXT_STRING
 | |
|         NCHAR_STRING
 | |
|         json_text_literal
 | |
| 
 | |
| %type <lex_str_ptr>
 | |
|         opt_table_alias_clause
 | |
|         table_alias_clause
 | |
| 
 | |
| %type <ident_cli>
 | |
|         IDENT
 | |
|         IDENT_QUOTED
 | |
|         IDENT_cli
 | |
|         ident_cli
 | |
|         ident_cli_set_usual_case
 | |
|         ident_cli_func
 | |
| 
 | |
| %type <ident_sys_ptr>
 | |
|         ident_sys_alloc
 | |
| 
 | |
| %type <kwd>
 | |
|         keyword_data_type
 | |
|         keyword_cast_type
 | |
|         keyword_ident
 | |
|         keyword_label
 | |
|         keyword_options
 | |
|         keyword_set_special_case
 | |
|         keyword_set_usual_case
 | |
|         keyword_sp_block_section
 | |
|         keyword_sp_decl
 | |
|         keyword_sp_head
 | |
|         keyword_func_sp_var_and_label
 | |
|         keyword_func_sp_var_not_label
 | |
|         keyword_sp_var_and_label
 | |
|         keyword_sp_var_not_label
 | |
|         keyword_sysvar_name
 | |
|         keyword_sysvar_type
 | |
|         keyword_table_alias
 | |
|         keyword_verb_clause
 | |
|         charset
 | |
|         reserved_keyword_udt
 | |
|         reserved_keyword_udt_not_param_type
 | |
|         non_reserved_keyword_udt
 | |
| 
 | |
| %type <table>
 | |
|         table_ident table_ident_nodb references xid
 | |
|         table_ident_opt_wild create_like
 | |
| 
 | |
| %type <qualified_column_ident>
 | |
|         optionally_qualified_column_ident
 | |
| 
 | |
| %type <simple_string>
 | |
|         remember_name remember_end
 | |
|         remember_tok_start
 | |
|         remember_cpp_ptr
 | |
|         wild_and_where
 | |
|         remember_start_opt
 | |
|         remember_end_opt
 | |
| 
 | |
| %type <const_simple_string>
 | |
|         field_length_str
 | |
|         opt_compression_method
 | |
| 
 | |
| %type <string>
 | |
|         text_string hex_or_bin_String opt_gconcat_separator
 | |
| 
 | |
| %type <type_handler> int_type real_type
 | |
| 
 | |
| %type <sp_handler> sp_handler
 | |
|                    sp_handler_package_spec
 | |
|                    sp_handler_package_body
 | |
| 
 | |
| %type <json_on_response> json_on_response
 | |
| 
 | |
| %type <Lex_field_type> field_type field_type_all field_type_all_builtin
 | |
|         field_type_all_with_record
 | |
|         qualified_field_type
 | |
|         field_type_numeric
 | |
|         field_type_string
 | |
|         field_type_lob
 | |
|         field_type_temporal
 | |
|         field_type_misc
 | |
|         json_table_field_type
 | |
| 
 | |
| %type <Lex_exact_charset_extended_collation_attrs>
 | |
|         binary
 | |
|         opt_binary
 | |
|         opt_binary_and_compression
 | |
|         attribute
 | |
|         attribute_list
 | |
|         field_def
 | |
| 
 | |
| %type <Lex_extended_collation>
 | |
|         collation_name
 | |
|         collation_name_or_default
 | |
| 
 | |
| 
 | |
| %type <Lex_dyncol_type> opt_dyncol_type dyncol_type
 | |
|         numeric_dyncol_type temporal_dyncol_type string_dyncol_type
 | |
| 
 | |
| %type <column_list_privilege>
 | |
|         column_list_privilege
 | |
| 
 | |
| %type <create_field> field_spec column_def
 | |
| 
 | |
| %type <num>
 | |
|         order_dir lock_option
 | |
|         udf_type opt_local opt_no_write_to_binlog
 | |
|         opt_temporary all_or_any opt_distinct opt_glimit_clause
 | |
|         opt_ignore_leaves fulltext_options union_option
 | |
|         opt_not
 | |
|         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_time_precision kill_type kill_option int_num
 | |
|         opt_default_time_precision
 | |
|         case_stmt_body opt_bin_mod opt_for_system_time_clause
 | |
|         opt_if_exists_table_element opt_if_not_exists_table_element
 | |
|         opt_recursive opt_format_xid opt_for_portion_of_time_clause
 | |
|         ignorability
 | |
| 
 | |
| %type <object_ddl_options>
 | |
|         create_or_replace
 | |
|         opt_if_not_exists
 | |
|         opt_if_exists
 | |
| 
 | |
| /*
 | |
|   Bit field of MYSQL_START_TRANS_OPT_* flags.
 | |
| */
 | |
| %type <num> opt_start_transaction_option_list
 | |
| %type <num> start_transaction_option_list
 | |
| %type <num> start_transaction_option
 | |
| 
 | |
| %type <m_yes_no_unk>
 | |
|         opt_chain opt_release
 | |
| 
 | |
| %type <m_fk_option>
 | |
|         delete_option
 | |
| 
 | |
| %type <privilege>
 | |
|         column_privilege
 | |
|         object_privilege
 | |
|         opt_grant_options
 | |
|         opt_grant_option
 | |
|         grant_option_list
 | |
|         grant_option
 | |
| 
 | |
| %type <lex_grant>
 | |
|         object_privilege_list
 | |
|         grant_privileges
 | |
| 
 | |
| %type <lex_grant_ident>
 | |
|         grant_ident
 | |
| 
 | |
| %type <ulong_num>
 | |
|         ulong_num real_ulong_num merge_insert_types
 | |
|         ws_nweights
 | |
|         ws_level_flag_desc ws_level_flag_reverse ws_level_flags
 | |
|         opt_ws_levels ws_level_list ws_level_list_item ws_level_number
 | |
|         ws_level_range ws_level_list_or_range bool
 | |
|         field_options last_field_options
 | |
| 
 | |
| %type <ulonglong_number>
 | |
|         ulonglong_num real_ulonglong_num
 | |
| 
 | |
| %type <longlong_number>
 | |
|         sequence_value_num
 | |
| 
 | |
| %type <longlong_hybrid_number>
 | |
|         sequence_value_hybrid_num sequence_truncated_value_hybrid_num
 | |
| 
 | |
| %type <choice> choice
 | |
| 
 | |
| %type <lock_type>
 | |
|         replace_lock_option opt_low_priority insert_lock_option load_data_lock
 | |
|         insert_replace_option
 | |
| 
 | |
| %type <item>
 | |
|         literal insert_ident order_ident temporal_literal
 | |
|         simple_ident expr sum_expr in_sum_expr
 | |
|         search_condition
 | |
|         variable variable_aux
 | |
|         boolean_test
 | |
|         predicate bit_expr parenthesized_expr
 | |
|         table_wild simple_expr column_default_non_parenthesized_expr udf_expr
 | |
|         primary_expr string_factor_expr mysql_concatenation_expr
 | |
|         select_sublist_qualified_asterisk
 | |
|         expr_or_ignore expr_or_ignore_or_default
 | |
|         signed_literal expr_or_literal
 | |
|         simple_ident_nospvar
 | |
|         field_or_var limit_option
 | |
|         part_func_expr
 | |
|         window_func_expr
 | |
|         window_func
 | |
|         simple_window_func
 | |
|         inverse_distribution_function
 | |
|         percentile_function
 | |
|         inverse_distribution_function_def
 | |
|         explicit_cursor_attr
 | |
|         function_call_keyword
 | |
|         function_call_keyword_timestamp
 | |
|         function_call_nonkeyword
 | |
|         function_call_generic
 | |
|         function_call_conflict kill_expr
 | |
|         signal_allowed_expr
 | |
|         simple_target_specification
 | |
|         condition_number
 | |
|         opt_versioning_interval_start
 | |
|         json_default_literal
 | |
|         set_expr_misc
 | |
| 
 | |
| %type <num> opt_vers_auto_part
 | |
| 
 | |
| %type <item_param> param_marker
 | |
| 
 | |
| %type <item_num>
 | |
|         NUM_literal
 | |
| 
 | |
| %type <item_basic_constant> text_literal
 | |
| 
 | |
| %type <item_list>
 | |
|         expr_list opt_udf_expr_list udf_expr_list when_list when_list_opt_else
 | |
|         ident_list ident_list_arg opt_expr_list
 | |
|         execute_using
 | |
|         execute_params
 | |
| 
 | |
| %type <sp_cursor_stmt>
 | |
|         sp_cursor_stmt_lex
 | |
|         sp_cursor_stmt
 | |
| 
 | |
| %type <instr_fetch_cursor>
 | |
|         sp_proc_stmt_fetch_head
 | |
| 
 | |
| %type <fetch_target_list>
 | |
|         sp_fetch_list
 | |
| 
 | |
| %type <expr_lex>
 | |
|         expr_lex
 | |
| 
 | |
| %destructor
 | |
| {
 | |
|   /*
 | |
|      In case of a syntax/oom error let's free the sp_expr_lex
 | |
|      instance, but only if it has not been linked to any structures
 | |
|      such as sp_instr_jump_if_not::m_lex_keeper yet, e.g.:
 | |
|        IF f1() THEN1
 | |
|      i.e. THEN1 came instead of the expected THEN causing a syntax error.
 | |
|   */
 | |
|   if (!$$->sp_lex_in_use)
 | |
|     delete $$;
 | |
| } <expr_lex>
 | |
| 
 | |
| %type <expr_and_query_str> sp_opt_default set_expr_or_default
 | |
| 
 | |
| /*
 | |
| 
 | |
| // COMMENT_FOR_DESCTRUCTOR:
 | |
| //
 | |
| // %destructor is only invoked if the rule parsing fails in the middle.
 | |
| // If we call YYABORT from the last code block %destructor is not called,
 | |
| // because Bison's stack already contains the reduced upper level rule.
 | |
| // If we need to invoke the %destructor after the YYABORT in the last code
 | |
| // block, we have to add another dummy empty end-of-rule action {} at the end.
 | |
| 
 | |
| // So to have a %destructor work properly with YYABORT,
 | |
| // make sure to turn a grammar like this:
 | |
| 
 | |
| rule:
 | |
|         KEYWORD expr_lex
 | |
|         {
 | |
|           if (condition) // End-of-rule action
 | |
|             YYABORT;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| // into:
 | |
| 
 | |
| rule:
 | |
|         KEYWORD expr_lex
 | |
|         {
 | |
|           if (condition) // This is now a mid-rule action
 | |
|             YYABORT;
 | |
|         }
 | |
|         {
 | |
|           // A dummy empty end-of-rule action.
 | |
|         }
 | |
|         ;
 | |
| */
 | |
| 
 | |
| 
 | |
| %type <assignment_lex>
 | |
|         assignment_source_lex
 | |
|         assignment_source_expr
 | |
|         for_loop_bound_expr
 | |
| 
 | |
| %type <sp_assignment_lex_list>
 | |
|         cursor_actual_parameters
 | |
|         opt_parenthesized_cursor_actual_parameters
 | |
| 
 | |
| %destructor
 | |
| {
 | |
|   if ($$)
 | |
|   {
 | |
|     sp_assignment_lex *elem;
 | |
|     List_iterator<sp_assignment_lex> li(*$$);
 | |
|     while ((elem= li++))
 | |
|     {
 | |
|       if (!elem->sp_lex_in_use)
 | |
|         delete elem;
 | |
|     }
 | |
|   }
 | |
| } <sp_assignment_lex_list>
 | |
| 
 | |
| 
 | |
| %type <var_type>
 | |
|         option_type opt_var_type opt_var_ident_type
 | |
| 
 | |
| %type <key_type>
 | |
|         constraint_key_type fulltext spatial_or_vector
 | |
| 
 | |
| %type <key_alg>
 | |
|         btree_or_rtree opt_key_algorithm_clause opt_USING_key_algorithm
 | |
| 
 | |
| %type <string_list>
 | |
|         using_list opt_use_partition use_partition
 | |
| 
 | |
| %type <key_part>
 | |
|         key_part key_part_simple
 | |
| 
 | |
| %type <table_list>
 | |
|         join_table_list  join_table
 | |
|         table_factor table_ref esc_table_ref
 | |
|         table_primary_ident table_primary_ident_opt_parens
 | |
|         table_primary_derived table_primary_derived_opt_parens
 | |
|         derived_table_list table_reference_list_parens
 | |
|         nested_table_reference_list join_table_parens
 | |
|         update_table_list table_function
 | |
| %type <date_time_type> date_time_type;
 | |
| %type <interval> interval
 | |
| 
 | |
| %type <interval_time_st> interval_time_stamp
 | |
| 
 | |
| %type <db_type> storage_engines known_storage_engines
 | |
| 
 | |
| %type <row_type> row_types
 | |
| 
 | |
| %type <tx_isolation> isolation_types
 | |
| 
 | |
| %type <ha_rkey_mode> handler_rkey_mode
 | |
| 
 | |
| %type <Lex_cast_type> cast_type cast_type_numeric cast_type_temporal
 | |
| 
 | |
| %type <Lex_length_and_dec> precision opt_precision float_options
 | |
|                            field_length opt_field_length
 | |
|                            field_scale opt_field_scale
 | |
| 
 | |
| %type <lex_user> user grant_user grant_role user_or_role current_role
 | |
|                  admin_option_for_role user_maybe_role role_name
 | |
| 
 | |
| %type <user_auth> opt_auth_str auth_expression auth_token
 | |
|                   text_or_password
 | |
| 
 | |
| %type <charset>
 | |
|         charset_name
 | |
|         charset_or_alias
 | |
|         charset_name_or_default
 | |
|         old_or_new_charset_name
 | |
|         old_or_new_charset_name_or_default
 | |
|         opt_load_data_charset
 | |
|         UNDERSCORE_CHARSET
 | |
| 
 | |
| %type <select_lex> subselect
 | |
|         query_specification
 | |
|         table_value_constructor
 | |
|         simple_table
 | |
|         query_simple
 | |
|         query_primary
 | |
|         subquery
 | |
|         select_into_query_specification
 | |
| 
 | |
| %type <select_lex_unit>
 | |
|         query_expression
 | |
|         query_expression_no_with_clause
 | |
|         query_expression_body_ext
 | |
|         query_expression_body_ext_parens
 | |
|         query_expression_body
 | |
|         query_specification_start
 | |
| 
 | |
| %type <boolfunc2creator> comp_op
 | |
| 
 | |
| %type <dyncol_def> dyncall_create_element
 | |
| 
 | |
| %type <dyncol_def_list> dyncall_create_list
 | |
| 
 | |
| %type <myvar> select_outvar
 | |
| 
 | |
| %type <virtual_column> opt_check_constraint check_constraint virtual_column_func
 | |
|         column_default_expr
 | |
| 
 | |
| %type <unit_operation> unit_type_decl
 | |
| 
 | |
| %type <select_lock>
 | |
|         opt_procedure_or_into
 | |
|         opt_select_lock_type
 | |
|         select_lock_type
 | |
|         opt_lock_wait_timeout_new
 | |
| 
 | |
| %type <select_limit> opt_limit_clause limit_clause limit_options
 | |
|                      fetch_first_clause
 | |
| 
 | |
| %type <order_limit_lock>
 | |
|         query_expression_tail
 | |
|         opt_query_expression_tail
 | |
|         order_or_limit
 | |
|         opt_order_or_limit
 | |
|         order_limit_lock
 | |
|         opt_order_limit_lock
 | |
| 
 | |
| %type <select_order> opt_order_clause order_clause order_list
 | |
| 
 | |
| %type <NONE>
 | |
|         directly_executable_statement
 | |
|         analyze_stmt_command backup backup_statements
 | |
|         query verb_clause create create_routine change select select_into
 | |
|         do drop drop_routine insert replace insert_start stmt_end
 | |
|         insert_values update delete truncate rename compound_statement
 | |
|         show describe load alter optimize keycache preload flush
 | |
|         reset purge begin_stmt_mariadb commit rollback savepoint release
 | |
|         slave master_def master_defs master_file_def slave_until_opts
 | |
|         repair analyze opt_with_admin opt_with_admin_option
 | |
|         analyze_table_list analyze_table_elem_spec
 | |
|         opt_persistent_stat_clause persistent_stat_spec
 | |
|         persistent_index_stat_spec
 | |
|         table_index_list table_index_name
 | |
|         check start checksum opt_returning
 | |
|         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
 | |
|         select_item_list select_item values_list no_braces
 | |
|         delete_limit_clause fields opt_values values
 | |
|         no_braces_with_names opt_values_with_names values_with_names
 | |
|         procedure_list procedure_list2 procedure_item
 | |
|         handler opt_generated_always
 | |
|         opt_ignore opt_column opt_restrict
 | |
|         grant revoke set lock unlock string_list
 | |
|         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
 | |
|         grant_list
 | |
|         user_list user_and_role_list
 | |
|         rename_list table_or_tables
 | |
|         clear_privileges flush_options flush_option
 | |
|         opt_flush_lock flush_lock flush_options_list
 | |
|         equal optional_braces
 | |
|         opt_mi_check_type opt_to mi_check_types 
 | |
|         table_to_table_list table_to_table opt_table_list opt_as
 | |
|         handler_rkey_function handler_read_or_scan
 | |
|         single_multi opt_wild
 | |
|         opt_and
 | |
|         select_var_list select_var_list_init help
 | |
|         opt_extended_describe shutdown
 | |
|         opt_format_json
 | |
|         prepare execute deallocate
 | |
|         statement
 | |
|         sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
 | |
|         opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
 | |
|         view_list_opt view_list view_select
 | |
|         trigger_tail event_tail
 | |
|         install uninstall partition_entry binlog_base64_event
 | |
|         normal_key_options normal_key_opts all_key_opt 
 | |
|         spatial_key_options fulltext_key_options normal_key_opt 
 | |
|         fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
 | |
|         explain_for_connection
 | |
| 	keep_gcc_happy
 | |
|         key_using_alg
 | |
|         part_column_list
 | |
|         period_for_system_time
 | |
|         period_for_application_time
 | |
|         server_def server_options_list server_option
 | |
|         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_lock_wait_timeout
 | |
|         opt_delete_gtid_domain
 | |
|         asrow_attribute
 | |
|         opt_constraint_no_id
 | |
|         json_table_columns_clause json_table_columns_list json_table_column
 | |
|         json_table_column_type json_opt_on_empty_or_error
 | |
|         json_on_error_response json_on_empty_response
 | |
| 
 | |
| %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
 | |
| %type <NONE> sp_if_then_statements sp_case_then_statements
 | |
| %type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
 | |
| %type <NONE> sp_proc_stmt_compound_ok
 | |
| %type <NONE> sp_proc_stmt_if
 | |
| %type <NONE> sp_labeled_control sp_unlabeled_control
 | |
| %type <NONE> sp_labeled_block sp_unlabeled_block
 | |
| %type <NONE> sp_proc_stmt_continue_oracle
 | |
| %type <NONE> sp_proc_stmt_exit_oracle
 | |
| %type <NONE> sp_proc_stmt_leave
 | |
| %type <NONE> sp_proc_stmt_iterate
 | |
| %type <NONE> sp_proc_stmt_goto_oracle
 | |
| %type <NONE> sp_proc_stmt_with_cursor
 | |
| %type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
 | |
| %type <NONE> case_stmt_specification
 | |
| %type <NONE> loop_body while_body repeat_body
 | |
| %type <NONE> for_loop_statements
 | |
| 
 | |
| %type <num> view_algorithm view_check_option
 | |
| %type <view_suid> view_suid opt_view_suid
 | |
| %type <num> only_or_with_ties
 | |
| 
 | |
| %type <plsql_cursor_attr> plsql_cursor_attr
 | |
| %type <sp_suid> sp_suid
 | |
| %type <sp_aggregate_type> opt_aggregate
 | |
| 
 | |
| %type <num> sp_decl_idents sp_decl_idents_init_vars
 | |
| %type <num> sp_handler_type sp_hcond_list
 | |
| %type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
 | |
| %type <spname> sp_name
 | |
| %type <spvar> sp_param_name sp_param_name_and_mode sp_param
 | |
| %type <spvar> sp_param_init_vars sp_param_default
 | |
| %type <spvar> sp_param_name_and_mode_init_vars
 | |
| %type <spvar> sp_param_anchored
 | |
| %type <for_loop> sp_for_loop_index_and_bounds
 | |
| %type <for_loop_bounds> sp_for_loop_bounds
 | |
| 
 | |
| %type <trim>
 | |
|         trim_operands
 | |
|         trim_operands_regular
 | |
|         trim_operands_special
 | |
| 
 | |
| %type <substring_spec>
 | |
|         substring_operands
 | |
|         substring_operands_regular
 | |
|         substring_operands_special
 | |
| 
 | |
| %type <num> opt_sp_for_loop_direction
 | |
| %type <spvar_mode> sp_parameter_type
 | |
| %type <index_hint> index_hint_type
 | |
| %type <num> index_hint_clause normal_join inner_join
 | |
| %type <filetype> data_or_xml
 | |
| 
 | |
| %type <NONE> signal_stmt resignal_stmt raise_stmt_oracle
 | |
| %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;
 | |
| %type <stmt_info_item_name> statement_information_item_name;
 | |
| %type <stmt_info_list> statement_information;
 | |
| %type <cond_info_item> condition_information_item;
 | |
| %type <cond_info_item_name> condition_information_item_name;
 | |
| %type <cond_info_list> condition_information;
 | |
| 
 | |
| %type <spvar_definition> row_field_name row_field_definition
 | |
| %type <spvar_definition_list> row_field_definition_list row_type_body
 | |
| %ifdef ORACLE
 | |
| %type <spvar_definition> rec_field_definition
 | |
| %type <spvar_definition> rec_field_definition_anchored
 | |
| %type <spvar_definition_list> rec_field_definition_list rec_type_body
 | |
| %endif
 | |
| 
 | |
| %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 <kwd>
 | |
|         '-' '+' '*' '/' '%' '(' ')'
 | |
|         ',' '!' '{' '}' '&' '|'
 | |
| 
 | |
| %type <with_clause> with_clause
 | |
| 
 | |
| %type <with_element_head> with_element_head
 | |
| 
 | |
| %type <ident_sys_list>
 | |
|         comma_separated_ident_list
 | |
|         with_column_list
 | |
|         derived_column_list
 | |
|         opt_column_name_list
 | |
|         persistent_column_stat_spec
 | |
|         opt_cycle
 | |
| 
 | |
| %type <vers_range_unit> opt_history_unit
 | |
| %type <vers_history_point> history_point
 | |
| %type <vers_column_versioning> with_or_without_system
 | |
| %type <engine_option_value_ptr> engine_defined_option;
 | |
| 
 | |
| %type <lex>
 | |
|         remember_lex
 | |
|         package_specification_function
 | |
|         package_specification_procedure
 | |
| %type <spname> opt_trailing_sp_name
 | |
| %type <lex_str> opt_package_routine_end_name
 | |
| 
 | |
| %type <spblock>
 | |
|         package_implementation_declare_section
 | |
|         package_implementation_declare_section_list
 | |
|         package_implementation_routine_definition
 | |
|         package_implementation_item_declaration
 | |
|         package_implementation_declare_section_list1
 | |
|         package_implementation_declare_section_list2
 | |
| 
 | |
| %type <spblock_handlers> package_implementation_executable_section
 | |
| 
 | |
| %type <NONE>
 | |
|         sp_package_function_body
 | |
|         sp_package_procedure_body
 | |
| 
 | |
| 
 | |
| %ifdef MARIADB
 | |
| %type <NONE> sp_tail_standalone
 | |
| %type <NONE> sp_unlabeled_block_not_atomic
 | |
| %type <NONE> sp_proc_stmt_in_returns_clause
 | |
| %type <lex_str> sp_label
 | |
| %type <spblock> sp_decl_handler
 | |
| %type <spblock> sp_decls
 | |
| %type <spblock> sp_decl
 | |
| %type <spblock> sp_decl_body
 | |
| %type <spblock> sp_decl_variable_list
 | |
| %type <spblock> sp_decl_variable_list_anchored
 | |
| %type <kwd> reserved_keyword_udt_param_type
 | |
| %else
 | |
| %type <NONE> set_assign
 | |
| %type <spvar_mode> sp_opt_inout
 | |
| %type <NONE> sp_tail_standalone
 | |
| %type <NONE> sp_labelable_stmt
 | |
| %type <lex_str> label_declaration_oracle
 | |
| %type <lex_str> labels_declaration_oracle
 | |
| %type <kwd> keyword_directly_assignable
 | |
| %type <ident_sys> ident_directly_assignable
 | |
| %type <ident_cli> ident_cli_directly_assignable
 | |
| %type <spblock> sp_decl_body_list
 | |
| %type <spblock> opt_sp_decl_body_list
 | |
| %type <spblock> sp_decl_variable_list
 | |
| %type <spblock> sp_decl_variable_list_anchored
 | |
| %type <spblock> sp_decl_non_handler
 | |
| %type <spblock> sp_decl_non_handler_list
 | |
| %type <spblock> sp_decl_handler
 | |
| %type <spblock> sp_decl_handler_list
 | |
| %type <spblock> opt_sp_decl_handler_list
 | |
| %type <spblock_handlers> sp_block_statements_and_exceptions
 | |
| %type <sp_instr_addr> sp_instr_addr
 | |
| %type <num> opt_exception_clause exception_handlers
 | |
| %endif ORACLE
 | |
| 
 | |
| %%
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Indentation of grammar rules:
 | |
| 
 | |
| rule: <-- starts at col 1
 | |
|           rule1a rule1b rule1c <-- starts at col 11
 | |
|           { <-- starts at col 11
 | |
|             code <-- starts at col 13, indentation is 2 spaces
 | |
|           }
 | |
|         | rule2a rule2b
 | |
|           {
 | |
|             code
 | |
|           }
 | |
|         ; <-- on a line by itself, starts at col 9
 | |
| 
 | |
|   Also, please do not use any <TAB>, but spaces.
 | |
|   Having a uniform indentation in this file helps
 | |
|   code reviews, patches, merges, and make maintenance easier.
 | |
|   Tip: grep [[:cntrl:]] sql_yacc.yy
 | |
|   Thanks.
 | |
| */
 | |
| 
 | |
| query:
 | |
|           END_OF_INPUT
 | |
|           {
 | |
|             if (!thd->bootstrap &&
 | |
|               (!(thd->lex->lex_options & OPTION_LEX_FOUND_COMMENT)))
 | |
|               my_yyabort_error((ER_EMPTY_QUERY, MYF(0)));
 | |
| 
 | |
|             thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
 | |
|             YYLIP->found_semicolon= NULL;
 | |
|           }
 | |
|         | directly_executable_statement
 | |
|           {
 | |
|             Lex_input_stream *lip = YYLIP;
 | |
| 
 | |
|             if ((thd->client_capabilities & CLIENT_MULTI_QUERIES) &&
 | |
|                 lip->multi_statements &&
 | |
|                 ! lip->eof())
 | |
|             {
 | |
|               /*
 | |
|                 We found a well formed query, and multi queries are allowed:
 | |
|                 - force the parser to stop after the ';'
 | |
|                 - mark the start of the next query for the next invocation
 | |
|                   of the parser.
 | |
|               */
 | |
|               lip->next_state= MY_LEX_END;
 | |
|               lip->found_semicolon= lip->get_ptr();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               /* Single query, terminated. */
 | |
|               lip->found_semicolon= NULL;
 | |
|             }
 | |
|           }
 | |
|           ';'
 | |
|           opt_end_of_input
 | |
|         | directly_executable_statement END_OF_INPUT
 | |
|           {
 | |
|             /* Single query, not terminated. */
 | |
|             YYLIP->found_semicolon= NULL;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_end_of_input:
 | |
|           /* empty */
 | |
|         | END_OF_INPUT
 | |
|         ;
 | |
| 
 | |
| directly_executable_statement:
 | |
|           statement
 | |
|         | begin_stmt_mariadb
 | |
|         | compound_statement
 | |
|         ;
 | |
| 
 | |
| /* Verb clauses, except begin and compound_statement */
 | |
| verb_clause:
 | |
|           alter
 | |
|         | analyze
 | |
|         | analyze_stmt_command
 | |
|         | backup
 | |
|         | binlog_base64_event
 | |
|         | call
 | |
|         | change
 | |
|         | check
 | |
|         | checksum
 | |
|         | commit
 | |
|         | create
 | |
|         | deallocate
 | |
|         | delete
 | |
|         | describe
 | |
|         | do
 | |
|         | drop
 | |
|         | execute
 | |
|         | explain_for_connection
 | |
|         | flush
 | |
|         | get_diagnostics
 | |
|         | grant
 | |
|         | handler
 | |
|         | help
 | |
|         | insert
 | |
|         | install
 | |
| 	| keep_gcc_happy
 | |
|         | keycache
 | |
|         | kill
 | |
|         | load
 | |
|         | lock
 | |
|         | optimize
 | |
|         | parse_vcol_expr
 | |
|         | partition_entry
 | |
|         | preload
 | |
|         | prepare
 | |
|         | purge
 | |
|         | raise_stmt_oracle
 | |
|         | release
 | |
|         | rename
 | |
|         | repair
 | |
|         | replace
 | |
|         | reset
 | |
|         | resignal_stmt
 | |
|         | revoke
 | |
|         | rollback
 | |
|         | savepoint
 | |
|         | select
 | |
|         | select_into
 | |
|         | set
 | |
|         | signal_stmt
 | |
|         | show
 | |
|         | shutdown
 | |
|         | slave
 | |
|         | start
 | |
|         | truncate
 | |
|         | uninstall
 | |
|         | unlock
 | |
|         | update
 | |
|         | use
 | |
|         | xa
 | |
|         ;
 | |
| 
 | |
| deallocate:
 | |
|           deallocate_or_drop PREPARE_SYM ident
 | |
|           {
 | |
|             Lex->stmt_deallocate_prepare($3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| deallocate_or_drop:
 | |
|           DEALLOCATE_SYM
 | |
|         | DROP
 | |
|         ;
 | |
| 
 | |
| prepare:
 | |
|           PREPARE_SYM ident FROM
 | |
|           {
 | |
|             thd->where= THD_WHERE::USE_WHERE_STRING;
 | |
|             thd->where_str=
 | |
|             Lex->clause_that_disallows_subselect= "PREPARE..FROM";
 | |
|           }
 | |
|           expr
 | |
|           {
 | |
|             Lex->clause_that_disallows_subselect= NULL;
 | |
|             if (Lex->stmt_prepare($2, $5))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| execute:
 | |
|           EXECUTE_SYM ident execute_using
 | |
|           {
 | |
|             if (Lex->stmt_execute($2, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | EXECUTE_SYM IMMEDIATE_SYM
 | |
|           {
 | |
|             thd->where= THD_WHERE::USE_WHERE_STRING;
 | |
|             thd->where_str=
 | |
|             Lex->clause_that_disallows_subselect= "EXECUTE IMMEDIATE";
 | |
|           }
 | |
|           expr
 | |
|           { Lex->clause_that_disallows_subselect= NULL; }
 | |
|           execute_using
 | |
|           {
 | |
|             if (Lex->stmt_execute_immediate($4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| execute_using:
 | |
|           /* nothing */    { $$= NULL; }
 | |
|         | USING
 | |
|           { Lex->clause_that_disallows_subselect= "EXECUTE..USING"; }
 | |
|           execute_params
 | |
|           {
 | |
|             $$= $3;
 | |
|             Lex->clause_that_disallows_subselect= NULL;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| execute_params:
 | |
|           expr_or_ignore_or_default
 | |
|           {
 | |
|             if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | execute_params ',' expr_or_ignore_or_default
 | |
|           {
 | |
|             if (($$= $1)->push_back($3, thd->mem_root))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| /* help */
 | |
| 
 | |
| help:
 | |
|           HELP_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HELP"));
 | |
|           }
 | |
|           ident_or_text
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_HELP;
 | |
|             lex->help_arg= $3.str;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* change master */
 | |
| 
 | |
| change:
 | |
|           CHANGE MASTER_SYM optional_connection_name TO_SYM
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_CHANGE_MASTER;
 | |
|           }
 | |
|           master_defs
 | |
|           optional_for_channel
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| master_defs:
 | |
|           master_def
 | |
|         | master_defs ',' master_def
 | |
|         ;
 | |
| 
 | |
| master_def:
 | |
|           MASTER_HOST_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.host = $3.str;
 | |
|           }
 | |
|         | MASTER_USER_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.user = $3.str;
 | |
|           }
 | |
|         | MASTER_PASSWORD_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.password = $3.str;
 | |
|           }
 | |
|         | MASTER_PORT_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.port = $3;
 | |
|           }
 | |
|         | MASTER_CONNECT_RETRY_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.connect_retry = $3;
 | |
|           }
 | |
|         | MASTER_RETRY_COUNT_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.retry_count = $3;
 | |
|           }
 | |
|         | MASTER_DELAY_SYM '=' ulong_num
 | |
|           {
 | |
|             if ($3 > MASTER_DELAY_MAX)
 | |
|             {
 | |
|               my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0),
 | |
|                        (ulong) $3, (ulong) MASTER_DELAY_MAX);
 | |
|             }
 | |
|             else
 | |
|               Lex->mi.sql_delay = $3;
 | |
|           }
 | |
|         | MASTER_SSL_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.ssl= $3 ? 
 | |
|               LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
 | |
|           }
 | |
|         | MASTER_SSL_CA_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_ca= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_CAPATH_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_capath= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_CERT_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_cert= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_CIPHER_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_cipher= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_KEY_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_key= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_VERIFY_SERVER_CERT_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.ssl_verify_server_cert= $3 ?
 | |
|               LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
 | |
|           }
 | |
|         | MASTER_SSL_CRL_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_crl= $3.str;
 | |
|           }
 | |
|         | MASTER_SSL_CRLPATH_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.ssl_crlpath= $3.str;
 | |
|           }
 | |
| 
 | |
|         | MASTER_HEARTBEAT_PERIOD_SYM '=' NUM_literal
 | |
|           {
 | |
|             Lex->mi.heartbeat_period= (float) $3->val_real();
 | |
|             if (unlikely(Lex->mi.heartbeat_period >
 | |
|                          SLAVE_MAX_HEARTBEAT_PERIOD) ||
 | |
|                 unlikely(Lex->mi.heartbeat_period < 0.0))
 | |
|                my_yyabort_error((ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0),
 | |
|                                  SLAVE_MAX_HEARTBEAT_PERIOD));
 | |
| 
 | |
|             if (unlikely(Lex->mi.heartbeat_period > slave_net_timeout))
 | |
|             {
 | |
|               push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
 | |
|                            ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX,
 | |
|                            ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX));
 | |
|             }
 | |
|             if (unlikely(Lex->mi.heartbeat_period < 0.001))
 | |
|             {
 | |
|               if (unlikely(Lex->mi.heartbeat_period != 0.0))
 | |
|               {
 | |
|                 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
 | |
|                              ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN,
 | |
|                              ER_THD(thd, ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN));
 | |
|                 Lex->mi.heartbeat_period= 0.0;
 | |
|               }
 | |
|               Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_DISABLE;
 | |
|             }
 | |
|             Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_ENABLE;
 | |
|           }
 | |
|         | IGNORE_SERVER_IDS_SYM '=' '(' ignore_server_id_list ')'
 | |
|           {
 | |
|             Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
 | |
|            }
 | |
|         | DO_DOMAIN_IDS_SYM '=' '(' do_domain_id_list ')'
 | |
|           {
 | |
|             Lex->mi.repl_do_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
 | |
|           }
 | |
|         | IGNORE_DOMAIN_IDS_SYM '=' '(' ignore_domain_id_list ')'
 | |
|           {
 | |
|             Lex->mi.repl_ignore_domain_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
 | |
|           }
 | |
|         |
 | |
|         master_file_def
 | |
|         ;
 | |
| 
 | |
| ignore_server_id_list:
 | |
|           /* Empty */
 | |
|           | ignore_server_id
 | |
|           | ignore_server_id_list ',' ignore_server_id
 | |
|         ;
 | |
| 
 | |
| ignore_server_id:
 | |
|           ulong_num
 | |
|           {
 | |
|             insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1));
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| do_domain_id_list:
 | |
|           /* Empty */
 | |
|           | do_domain_id
 | |
|           | do_domain_id_list ',' do_domain_id
 | |
|         ;
 | |
| 
 | |
| do_domain_id:
 | |
|           ulong_num
 | |
|           {
 | |
|             insert_dynamic(&Lex->mi.repl_do_domain_ids, (uchar*) &($1));
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| ignore_domain_id_list:
 | |
|           /* Empty */
 | |
|           | ignore_domain_id
 | |
|           | ignore_domain_id_list ',' ignore_domain_id
 | |
|         ;
 | |
| 
 | |
| ignore_domain_id:
 | |
|           ulong_num
 | |
|           {
 | |
|             insert_dynamic(&Lex->mi.repl_ignore_domain_ids, (uchar*) &($1));
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| master_file_def:
 | |
|           MASTER_LOG_FILE_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.log_file_name = $3.str;
 | |
|           }
 | |
|         | MASTER_LOG_POS_SYM '=' ulonglong_num
 | |
|           {
 | |
|             /* 
 | |
|                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 explicitly specified. On the contrary
 | |
|                in change_master() (sql_repl.cc) we cannot distinguish between 0
 | |
|                (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)").
 | |
|             */
 | |
|             Lex->mi.pos= MY_MAX(BIN_LOG_HEADER_SIZE, $3);
 | |
|           }
 | |
|         | RELAY_LOG_FILE_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.relay_log_name = $3.str;
 | |
|           }
 | |
|         | RELAY_LOG_POS_SYM '=' ulong_num
 | |
|           {
 | |
|             Lex->mi.relay_log_pos = $3;
 | |
|             /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
 | |
|             Lex->mi.relay_log_pos= MY_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
 | |
|           }
 | |
|         | MASTER_USE_GTID_SYM '=' CURRENT_POS_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid"));
 | |
|             Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_CURRENT_POS;
 | |
|           }
 | |
|         | MASTER_USE_GTID_SYM '=' SLAVE_POS_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid"));
 | |
|             Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_SLAVE_POS;
 | |
|           }
 | |
|         | MASTER_USE_GTID_SYM '=' NO_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->mi.use_gtid_opt != LEX_MASTER_INFO::LEX_GTID_UNCHANGED))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MASTER_use_gtid"));
 | |
|             Lex->mi.use_gtid_opt= LEX_MASTER_INFO::LEX_GTID_NO;
 | |
|           }
 | |
|         | MASTER_DEMOTE_TO_SLAVE_SYM '=' bool
 | |
|           {
 | |
|             Lex->mi.is_demotion_opt= (bool) $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| optional_connection_name:
 | |
|           /* empty */
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->mi.connection_name= null_clex_str;
 | |
|           }
 | |
|         | connection_name
 | |
|         ;
 | |
| 
 | |
| connection_name:
 | |
|         TEXT_STRING_sys
 | |
|         {
 | |
|            Lex->mi.connection_name= $1;
 | |
| #ifdef HAVE_REPLICATION
 | |
|            if (unlikely(check_master_connection_name(&$1)))
 | |
|               my_yyabort_error((ER_WRONG_ARGUMENTS, MYF(0), "MASTER_CONNECTION_NAME"));
 | |
| #endif
 | |
|          }
 | |
|          ;
 | |
| 
 | |
| optional_for_channel:
 | |
|         /* empty */
 | |
|           {
 | |
|             /*do nothing */
 | |
|           }
 | |
|         | for_channel
 | |
| 
 | |
|         ;
 | |
| 
 | |
| for_channel:
 | |
|         FOR_SYM CHANNEL_SYM TEXT_STRING_sys
 | |
|         {
 | |
|           if (Lex->mi.connection_name.str != NULL)
 | |
|           {
 | |
|             my_yyabort_error((ER_WRONG_ARGUMENTS, MYF(0), "CONNECTION_NAME AND FOR CHANNEL CAN NOT BE SPECIFIED AT THE SAME TIME)"));
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             Lex->mi.connection_name= $3;
 | |
| #ifdef HAVE_REPLICATION
 | |
|            if (unlikely(check_master_connection_name(&$3)))
 | |
|               my_yyabort_error((ER_WRONG_ARGUMENTS, MYF(0), "MASTER_CONNECTION_NAME"));
 | |
| #endif
 | |
|           }
 | |
| 
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| /* create a table */
 | |
| 
 | |
| create:
 | |
|           create_or_replace opt_temporary TABLE_SYM opt_if_not_exists
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             if (!(lex->m_sql_cmd= new (thd) Sql_cmd_create_table()))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->create_info.init();
 | |
|             if (lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->current_select->parsing_place= BEFORE_OPT_LIST;
 | |
|             if (lex->set_command_with_check(SQLCOM_CREATE_TABLE, $2, $1 | $4))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|           table_ident
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             if (!lex->first_select_lex()->
 | |
|                   add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING,
 | |
|                                     TL_WRITE, MDL_SHARED_UPGRADABLE))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.reset();
 | |
|             /*
 | |
|               For CREATE TABLE we should not open the table even if it exists.
 | |
|               If the table exists, we should either not create it or replace it
 | |
|             */
 | |
|             lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
 | |
|             lex->name= null_clex_str;
 | |
|             lex->create_last_non_select_table= lex->last_table();
 | |
|             lex->inc_select_stack_outer_barrier();
 | |
|           }
 | |
|           create_body
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             create_table_set_open_action_and_adjust_tables(lex);
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|        | create_or_replace opt_temporary SEQUENCE_SYM opt_if_not_exists table_ident
 | |
|          {
 | |
|            LEX *lex= thd->lex;
 | |
|            if (lex->main_select_push())
 | |
|              MYSQL_YYABORT;
 | |
|            if (!(lex->m_sql_cmd= new (thd) Sql_cmd_create_sequence()))
 | |
|               MYSQL_YYABORT;
 | |
|            lex->create_info.init();
 | |
|            if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_SEQUENCE, $2,
 | |
|                         $1 | $4)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|            if (!lex->first_select_lex()->
 | |
|                  add_table_to_list(thd, $5, NULL, TL_OPTION_UPDATING,
 | |
|                                    TL_WRITE, MDL_EXCLUSIVE))
 | |
|              MYSQL_YYABORT;
 | |
| 
 | |
|                /*
 | |
|                  For CREATE TABLE, an non-existing table is not an error.
 | |
|                  Instruct open_tables() to just take an MDL lock if the
 | |
|                  table does not exist.
 | |
|                */
 | |
|              lex->alter_info.reset();
 | |
|              lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
 | |
|              lex->name= null_clex_str;
 | |
|              lex->create_last_non_select_table= lex->last_table();
 | |
|              if (unlikely(!(lex->create_info.seq_create_info=
 | |
|                             new (thd) sequence_definition())))
 | |
|                MYSQL_YYABORT;
 | |
|          }
 | |
|          opt_sequence opt_create_table_options
 | |
|          {
 | |
|             LEX *lex= thd->lex;
 | |
| 
 | |
|             if (unlikely(lex->create_info.seq_create_info->
 | |
|                          check_and_adjust(thd, 1)))
 | |
|             {
 | |
|               my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
 | |
|                        lex->first_select_lex()->table_list.first->db.str,
 | |
|                        lex->first_select_lex()->table_list.first->
 | |
|                          table_name.str);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             /* No fields specified, generate them */
 | |
|             if (unlikely(
 | |
|                 lex->create_info.seq_create_info->prepare_sequence_fields(
 | |
|                 &lex->alter_info.create_list, false)))
 | |
|                MYSQL_YYABORT;
 | |
| 
 | |
|             /* CREATE SEQUENCE always creates a sequence */
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE;
 | |
|             Lex->create_info.sequence= 1;
 | |
| 
 | |
|             create_table_set_open_action_and_adjust_tables(lex);
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace INDEX_SYM opt_if_not_exists
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           ident
 | |
|           opt_key_algorithm_clause
 | |
|           ON table_ident
 | |
|           {
 | |
|             if (Lex->add_create_index_prepare($8))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_create_index(Key::MULTIPLE, &$5, $6, $1 | $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list ')' opt_lock_wait_timeout normal_key_options
 | |
|           opt_index_lock_algorithm
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace UNIQUE_SYM INDEX_SYM opt_if_not_exists
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           ident
 | |
|           opt_key_algorithm_clause
 | |
|           ON table_ident
 | |
|           {
 | |
|             if (Lex->add_create_index_prepare($9))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_create_index(Key::UNIQUE, &$6, $7, $1 | $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list opt_without_overlaps ')'
 | |
|           opt_lock_wait_timeout normal_key_options
 | |
|           opt_index_lock_algorithm
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace fulltext INDEX_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_if_not_exists ident
 | |
|           ON table_ident
 | |
|           {
 | |
|             if (Lex->add_create_index_prepare($8))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list ')' opt_lock_wait_timeout fulltext_key_options
 | |
|           opt_index_lock_algorithm
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace spatial_or_vector INDEX_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_if_not_exists ident
 | |
|           ON table_ident
 | |
|           {
 | |
|             if (Lex->add_create_index_prepare($8))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_create_index($2, &$6, HA_KEY_ALG_UNDEF, $1 | $5))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_part_simple ')' opt_lock_wait_timeout spatial_key_options
 | |
|           opt_index_lock_algorithm
 | |
|           {
 | |
|             Lex->last_key->columns.push_back($11, thd->mem_root);
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace DATABASE opt_if_not_exists ident
 | |
|           {
 | |
|             Lex->create_info.init();
 | |
|           }
 | |
|           opt_create_database_options
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(lex->set_command_with_check(SQLCOM_CREATE_DB, 0,
 | |
|                          $1 | $3)))
 | |
|                MYSQL_YYABORT;
 | |
|             lex->name= $4;
 | |
|           }
 | |
|         | create_or_replace definer_opt opt_view_suid VIEW_SYM
 | |
|           opt_if_not_exists table_ident
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->inc_select_stack_outer_barrier();
 | |
|             if (Lex->add_create_view(thd, $1 | $5,
 | |
|                                      DTYPE_ALGORITHM_UNDEFINED, $3, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           view_list_opt AS view_select
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace view_algorithm definer_opt opt_view_suid VIEW_SYM
 | |
|           opt_if_not_exists table_ident
 | |
|           {
 | |
|             if (unlikely(Lex->add_create_view(thd, $1 | $6, $2, $4, $7)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->inc_select_stack_outer_barrier();
 | |
|           }
 | |
|           view_list_opt AS view_select
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace definer_opt TRIGGER_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->create_info.set($1);
 | |
|           }
 | |
|           trigger_tail
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace definer_opt EVENT_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->create_info.set($1);
 | |
|           }
 | |
|           event_tail
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | create_or_replace USER_SYM opt_if_not_exists clear_privileges
 | |
|           grant_list opt_require_clause opt_resource_options opt_account_locking_and_opt_password_expiration
 | |
|           {
 | |
|             if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_USER,
 | |
|                                                      $1 | $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace ROLE_SYM opt_if_not_exists
 | |
|           clear_privileges role_list opt_with_admin
 | |
|           {
 | |
|             if (unlikely(Lex->set_command_with_check(SQLCOM_CREATE_ROLE,
 | |
|                          $1 | $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace { Lex->set_command(SQLCOM_CREATE_SERVER, $1); }
 | |
|           server_def
 | |
|           { }
 | |
|         | create_routine
 | |
|         ;
 | |
| 
 | |
| opt_sequence:
 | |
|          /* empty */ { }
 | |
|         | sequence_defs
 | |
|         ;
 | |
| 
 | |
| sequence_defs:
 | |
|           sequence_def
 | |
|         | sequence_defs sequence_def
 | |
|         ;
 | |
| 
 | |
| sequence_def:
 | |
|           AS int_type field_options
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_as))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "AS"));
 | |
|             if ($3 & ZEROFILL_FLAG)
 | |
|                 my_yyabort_error((ER_BAD_OPTION_VALUE, MYF(0), "ZEROFILL",
 | |
|                                   "AS"));
 | |
|             seq->value_type = $2->field_type();
 | |
|             seq->is_unsigned= $3 & UNSIGNED_FLAG ? true : false;
 | |
|             seq->used_fields|= seq_field_used_as;
 | |
|           }
 | |
|         | MINVALUE_SYM opt_equal sequence_truncated_value_hybrid_num
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_min_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
 | |
|             seq->min_value_from_parser= $3;
 | |
|             seq->used_fields|=
 | |
|               seq_field_used_min_value;
 | |
|             seq->used_fields|=
 | |
|               seq_field_specified_min_value;
 | |
|           }
 | |
|         | NO_SYM MINVALUE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_min_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
 | |
|             seq->used_fields|= seq_field_used_min_value;
 | |
|           }
 | |
|         | NOMINVALUE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_min_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
 | |
|             seq->used_fields|= seq_field_used_min_value;
 | |
|           }
 | |
|         | MAXVALUE_SYM opt_equal sequence_truncated_value_hybrid_num
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_max_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
 | |
|             seq->max_value_from_parser= $3;
 | |
|             seq->used_fields|= seq_field_used_max_value;
 | |
|             seq->used_fields|= seq_field_specified_max_value;
 | |
|           }
 | |
|         | NO_SYM MAXVALUE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_max_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
 | |
|             seq->used_fields|= seq_field_used_max_value;
 | |
|           }
 | |
|         | NOMAXVALUE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_max_value))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
 | |
|             seq->used_fields|= seq_field_used_max_value;
 | |
|           }
 | |
|         | START_SYM opt_with sequence_value_hybrid_num
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_start))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START"));
 | |
|             seq->start_from_parser= $3;
 | |
|             seq->used_fields|= seq_field_used_start;
 | |
|           }
 | |
|         | INCREMENT_SYM opt_by sequence_value_num
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_increment))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "INCREMENT"));
 | |
|             seq->increment= $3;
 | |
|             seq->used_fields|= seq_field_used_increment;
 | |
|           }
 | |
|         | CACHE_SYM opt_equal sequence_value_num
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_cache))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
 | |
|             seq->cache= $3;
 | |
|             seq->used_fields|= seq_field_used_cache;
 | |
|           }
 | |
|         | NOCACHE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_cache))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CACHE"));
 | |
|             seq->cache= 0;
 | |
|             seq->used_fields|= seq_field_used_cache;
 | |
|           }
 | |
|         | CYCLE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_cycle))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
 | |
|             seq->cycle= 1;
 | |
|             seq->used_fields|= seq_field_used_cycle;
 | |
|           }
 | |
|         | NOCYCLE_SYM
 | |
|           {
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_cycle))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CYCLE"));
 | |
|             seq->cycle= 0;
 | |
|             seq->used_fields|= seq_field_used_cycle;
 | |
|           }
 | |
|         | RESTART_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE))
 | |
|             {
 | |
|               thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_restart))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
 | |
|             seq->used_fields|= seq_field_used_restart;
 | |
|           }
 | |
|         | RESTART_SYM opt_with sequence_value_hybrid_num
 | |
|           {
 | |
|             if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE))
 | |
|             {
 | |
|               thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             sequence_definition *seq= Lex->create_info.seq_create_info;
 | |
|             if (unlikely(seq->used_fields & seq_field_used_restart))
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
 | |
|             seq->restart_from_parser= $3;
 | |
|             seq->used_fields|=
 | |
|               seq_field_used_restart | seq_field_used_restart_value;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* this rule is used to force look-ahead in the parser */
 | |
| force_lookahead: {} | FORCE_LOOKAHEAD {} ;
 | |
| 
 | |
| server_def:
 | |
|           SERVER_SYM opt_if_not_exists ident_or_text
 | |
|           {
 | |
|             if (unlikely(Lex->add_create_options_with_check($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->server_options.reset($3);
 | |
|           }
 | |
|           FOREIGN DATA_SYM WRAPPER_SYM ident_or_text
 | |
|           OPTIONS_SYM '(' server_options_list ')'
 | |
|           { Lex->server_options.scheme= $8; }
 | |
|         ;
 | |
| 
 | |
| server_options_list:
 | |
|           server_option
 | |
|         | server_options_list ',' server_option
 | |
|         ;
 | |
| 
 | |
| server_option:
 | |
|           USER_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.username.str == 0);
 | |
|             Lex->server_options.username= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | HOST_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.host.str == 0);
 | |
|             Lex->server_options.host= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | DATABASE TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.db.str == 0);
 | |
|             Lex->server_options.db= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | OWNER_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.owner.str == 0);
 | |
|             Lex->server_options.owner= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | PASSWORD_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.password.str == 0);
 | |
|             Lex->server_options.password= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | SOCKET_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS(Lex->server_options.socket.str == 0);
 | |
|             Lex->server_options.socket= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | PORT_SYM ulong_num
 | |
|           {
 | |
|             Lex->server_options.port= $2;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 $2, thd->mem_root);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         /* port can be a quoted number */
 | |
|         | PORT_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             int error;
 | |
|             char *end= (char *) $2.str + $2.length;
 | |
|             longlong p= my_strtoll10($2.str, &end, &error);
 | |
|             if (error > 0 || end != (char *) $2.str + $2.length ||
 | |
|                 p > LONG_MAX || p < LONG_MIN)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->server_options.port= (long) p;
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         | IDENT_sys TEXT_STRING_sys
 | |
|           {
 | |
|             engine_option_value *new_option=
 | |
|               new (thd) engine_option_value(
 | |
|                 engine_option_value::Name(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $1)),
 | |
|                 engine_option_value::Value(
 | |
|                   safe_lexcstrdup_root(thd->mem_root, $2)), true);
 | |
|             new_option->link(&Lex->server_options.option_list,
 | |
|                              &Lex->option_list_last);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| event_tail:
 | |
|           remember_name opt_if_not_exists sp_name
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
| 
 | |
|             lex->stmt_definition_begin= $1;
 | |
|             if (unlikely(lex->add_create_options_with_check($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(!(lex->event_parse_data=
 | |
|                            Event_parse_data::new_instance(thd))))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->event_parse_data->identifier= $3;
 | |
|             lex->event_parse_data->on_completion=
 | |
|                                   Event_parse_data::ON_COMPLETION_DROP;
 | |
| 
 | |
|             lex->sql_command= SQLCOM_CREATE_EVENT;
 | |
|             /* We need that for disallowing subqueries */
 | |
|           }
 | |
|           ON SCHEDULE_SYM ev_schedule_time
 | |
|           opt_ev_on_completion
 | |
|           opt_ev_status
 | |
|           opt_ev_comment
 | |
|           DO_SYM ev_sql_stmt
 | |
|           {
 | |
|             /*
 | |
|               sql_command is set here because some rules in ev_sql_stmt
 | |
|               can overwrite it
 | |
|             */
 | |
|             Lex->sql_command= SQLCOM_CREATE_EVENT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ev_schedule_time:
 | |
|           EVERY_SYM expr interval
 | |
|           {
 | |
|             Lex->event_parse_data->item_expression= $2;
 | |
|             Lex->event_parse_data->interval= $3;
 | |
|           }
 | |
|           ev_starts
 | |
|           ev_ends
 | |
|         | AT_SYM expr
 | |
|           {
 | |
|             Lex->event_parse_data->item_execute_at= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_ev_status:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | ENABLE_SYM
 | |
|           {
 | |
|             Lex->event_parse_data->status= Event_parse_data::ENABLED;
 | |
|             Lex->event_parse_data->status_changed= true;
 | |
|             $$= 1;
 | |
|           }
 | |
|         | DISABLE_SYM ON SLAVE
 | |
|           {
 | |
|             Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
 | |
|             Lex->event_parse_data->status_changed= true; 
 | |
|             $$= 1;
 | |
|           }
 | |
|         | DISABLE_SYM
 | |
|           {
 | |
|             Lex->event_parse_data->status= Event_parse_data::DISABLED;
 | |
|             Lex->event_parse_data->status_changed= true;
 | |
|             $$= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ev_starts:
 | |
|           /* empty */
 | |
|           {
 | |
|             Item *item= new (thd) Item_func_current_timestamp(thd, 0);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->event_parse_data->item_starts= item;
 | |
|           }
 | |
|         | STARTS_SYM expr
 | |
|           {
 | |
|             Lex->event_parse_data->item_starts= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ev_ends:
 | |
|           /* empty */
 | |
|         | ENDS_SYM expr
 | |
|           {
 | |
|             Lex->event_parse_data->item_ends= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_ev_on_completion:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | ev_on_completion
 | |
|         ;
 | |
| 
 | |
| ev_on_completion:
 | |
|           ON COMPLETION_SYM opt_not PRESERVE_SYM
 | |
|           {
 | |
|             Lex->event_parse_data->on_completion= $3
 | |
|                                     ? Event_parse_data::ON_COMPLETION_DROP
 | |
|                                     : Event_parse_data::ON_COMPLETION_PRESERVE;
 | |
|             $$= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_ev_comment:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | COMMENT_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->comment= Lex->event_parse_data->comment= $2;
 | |
|             $$= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ev_sql_stmt:
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             Lex_input_stream *lip= YYLIP;
 | |
| 
 | |
|             /*
 | |
|               This stops the following :
 | |
|               - CREATE EVENT ... DO CREATE EVENT ...;
 | |
|               - ALTER  EVENT ... DO CREATE EVENT ...;
 | |
|               - CREATE EVENT ... DO ALTER EVENT DO ....;
 | |
|               - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END|
 | |
|               This allows:
 | |
|               - CREATE EVENT ... DO DROP EVENT yyy;
 | |
|               - CREATE EVENT ... DO ALTER EVENT yyy;
 | |
|                 (the nested ALTER EVENT can have anything but DO clause)
 | |
|               - ALTER  EVENT ... DO ALTER EVENT yyy;
 | |
|                 (the nested ALTER EVENT can have anything but DO clause)
 | |
|               - ALTER  EVENT ... DO DROP EVENT yyy;
 | |
|               - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END|
 | |
|                 (the nested ALTER EVENT can have anything but DO clause)
 | |
|               - CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
 | |
|             */
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_EVENT_RECURSION_FORBIDDEN, MYF(0)));
 | |
|               
 | |
|             if (unlikely(!lex->make_sp_head(thd,
 | |
|                                             lex->event_parse_data->identifier,
 | |
|                                             &sp_handler_procedure,
 | |
|                                             DEFAULT_AGGREGATE)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
 | |
|           }
 | |
|           sp_proc_stmt force_lookahead
 | |
|           {
 | |
|             /* return back to the original memory root ASAP */
 | |
|             if (Lex->sp_body_finalize_event(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| clear_privileges:
 | |
|           /* Nothing */
 | |
|           {
 | |
|            LEX *lex=Lex;
 | |
|            lex->users_list.empty();
 | |
|            lex->first_select_lex()->db= null_clex_str;
 | |
|            lex->account_options.reset();
 | |
|          }
 | |
|         ;
 | |
| 
 | |
| opt_aggregate:
 | |
|           /* Empty */   { $$= NOT_AGGREGATE; }
 | |
|         | AGGREGATE_SYM { $$= GROUP_AGGREGATE; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_handler:
 | |
|           FUNCTION_SYM                       { $$= &sp_handler_function; }
 | |
|         | PROCEDURE_SYM                      { $$= &sp_handler_procedure; }
 | |
|         | sp_handler_package_spec
 | |
|         | sp_handler_package_body
 | |
|         ;
 | |
| 
 | |
| sp_handler_package_spec:
 | |
|          PACKAGE_ORACLE_SYM                   { $$= &sp_handler_package_spec; }
 | |
|        | PACKAGE_MARIADB_SYM                  { $$= &sp_handler_package_spec; }
 | |
|        ;
 | |
| 
 | |
| sp_handler_package_body:
 | |
|          PACKAGE_ORACLE_SYM BODY_ORACLE_SYM   { $$= &sp_handler_package_body; }
 | |
|        | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM { $$= &sp_handler_package_body; }
 | |
|        ;
 | |
| 
 | |
| drop_routine:
 | |
|           DROP sp_handler opt_if_exists ident '.' ident
 | |
|           {
 | |
|             if (Lex->stmt_drop_routine($2, $3, $4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DROP sp_handler opt_if_exists ident
 | |
|           {
 | |
|             if (Lex->stmt_drop_routine($2, $3, Lex_ident_sys(), $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_name:
 | |
|           ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_sp_name(thd, $1, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_sp_name(thd, $1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_a_chistics:
 | |
|           /* Empty */ {}
 | |
|         | sp_a_chistics sp_chistic {}
 | |
|         ;
 | |
| 
 | |
| sp_c_chistics:
 | |
|           /* Empty */ {}
 | |
|         | sp_c_chistics sp_c_chistic {}
 | |
|         ;
 | |
| 
 | |
| /* Characteristics for both create and alter */
 | |
| sp_chistic:
 | |
|           COMMENT_SYM TEXT_STRING_sys
 | |
|           { Lex->sp_chistics.comment= $2; }
 | |
|         | LANGUAGE_SYM SQL_SYM
 | |
|           { /* Just parse it, we only have one language for now. */ }
 | |
|         | NO_SYM SQL_SYM
 | |
|           { Lex->sp_chistics.daccess= SP_NO_SQL; }
 | |
|         | CONTAINS_SYM SQL_SYM
 | |
|           { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; }
 | |
|         | READS_SYM SQL_SYM DATA_SYM
 | |
|           { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; }
 | |
|         | MODIFIES_SYM SQL_SYM DATA_SYM
 | |
|           { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; }
 | |
|         | sp_suid
 | |
|           { Lex->sp_chistics.suid= $1; }
 | |
|         ;
 | |
| 
 | |
| /* Create characteristics */
 | |
| sp_c_chistic:
 | |
|           sp_chistic            { }
 | |
|         | opt_not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= ! $1; }
 | |
|         ;
 | |
| 
 | |
| sp_suid:
 | |
|           SQL_SYM SECURITY_SYM DEFINER_SYM { $$= SP_IS_SUID; }
 | |
|         | SQL_SYM SECURITY_SYM INVOKER_SYM { $$= SP_IS_NOT_SUID; }
 | |
|         ;
 | |
| 
 | |
| call:
 | |
|           CALL_SYM ident
 | |
|           {
 | |
|             if (unlikely(Lex->call_statement_start(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CALL_SYM ident '.' ident
 | |
|           {
 | |
|             if (unlikely(Lex->call_statement_start(thd, &$2, &$4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CALL_SYM ident '.' ident '.' ident
 | |
|           {
 | |
|             if (unlikely(Lex->call_statement_start(thd, &$2, &$4, &$6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* CALL parameters */
 | |
| opt_sp_cparam_list:
 | |
|           /* Empty */
 | |
|         | '('
 | |
|         {
 | |
|           thd->where= THD_WHERE::USE_WHERE_STRING;
 | |
|           thd->where_str= "CALL";
 | |
|         } opt_sp_cparams ')'
 | |
|         ;
 | |
| 
 | |
| opt_sp_cparams:
 | |
|           /* Empty */
 | |
|         | sp_cparams
 | |
|         ;
 | |
| 
 | |
| sp_cparams:
 | |
|           sp_cparams ',' expr
 | |
|           {
 | |
|            Lex->value_list.push_back($3, thd->mem_root);
 | |
|           }
 | |
|         | expr
 | |
|           {
 | |
|             Lex->value_list.push_back($1, thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Stored FUNCTION parameter declaration list */
 | |
| sp_fdparam_list:
 | |
|           /* Empty */
 | |
|           {
 | |
|             Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
 | |
|             Lex->sphead->m_param_end= Lex->sphead->m_param_begin;
 | |
|           }
 | |
|         |
 | |
|           {
 | |
|             Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start();
 | |
|           }
 | |
|           sp_fdparams
 | |
|           {
 | |
|             Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_fdparams:
 | |
|           sp_fdparams ',' sp_param_default
 | |
|         | sp_param_default
 | |
|         ;
 | |
| 
 | |
| sp_fdparams_no_default:
 | |
|           sp_fdparams_no_default ',' sp_param
 | |
|         | sp_param
 | |
|         ;
 | |
| 
 | |
| sp_param_name:
 | |
|           ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->sp_param_init(&$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param_name_and_mode_init_vars:
 | |
|           sp_param_name_and_mode
 | |
|           {
 | |
|             Lex->sp_variable_declarations_init(thd, 1);
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Stored PROCEDURE parameter declaration list */
 | |
| sp_pdparam_list:
 | |
|           /* Empty */
 | |
|         | sp_pdparams
 | |
|         ;
 | |
| 
 | |
| sp_pdparams:
 | |
|           sp_pdparams ',' sp_param_default
 | |
|         | sp_param_default
 | |
|         ;
 | |
| 
 | |
| sp_parameter_type:
 | |
|           IN_SYM      { $$= sp_variable::MODE_IN; }
 | |
|         | OUT_SYM     { $$= sp_variable::MODE_OUT; }
 | |
|         | INOUT_SYM   { $$= sp_variable::MODE_INOUT; }
 | |
|         ;
 | |
| 
 | |
| sp_parenthesized_pdparam_list:
 | |
|           '('
 | |
|           {
 | |
|             Lex->sphead->m_param_begin= YYLIP->get_cpp_tok_start() + 1;
 | |
|           }
 | |
|           sp_pdparam_list
 | |
|           ')'
 | |
|           {
 | |
|             Lex->sphead->m_param_end= YYLIP->get_cpp_tok_start();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param_default:
 | |
|           sp_param_init_vars sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_param_set_default_and_finalize(($$= $1), $2.expr, $2.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param:
 | |
|           sp_param_init_vars
 | |
|           {
 | |
|             if (unlikely(Lex->sp_param_set_default_and_finalize(($$= $1), nullptr, empty_clex_str)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_parenthesized_fdparam_list:
 | |
|         '(' sp_fdparam_list ')'
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmts:
 | |
|           /* Empty */ {}
 | |
|         | sp_proc_stmts  sp_proc_stmt ';'
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmts1:
 | |
|           sp_proc_stmt ';' {}
 | |
|         | sp_proc_stmts1  sp_proc_stmt ';'
 | |
|         ;
 | |
| 
 | |
| 
 | |
| optionally_qualified_column_ident:
 | |
|           sp_decl_ident
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                          Qualified_column_ident(&$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                            Qualified_column_ident(&$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident '.' ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                            Qualified_column_ident(thd, &$1, &$3, &$5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| row_field_definition:
 | |
|           row_field_name field_type
 | |
|           {
 | |
|             Lex->last_field->set_attributes(thd, $2,
 | |
|                                             COLUMN_DEFINITION_ROUTINE_LOCAL);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| row_field_definition_list:
 | |
|           row_field_definition
 | |
|           {
 | |
|             if (!($$= Row_definition_list::make(thd->mem_root, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | row_field_definition_list ',' row_field_definition
 | |
|           {
 | |
|             if (($$= $1)->append_uniq(thd->mem_root, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| row_type_body:
 | |
|           '(' row_field_definition_list ')' { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| %ifdef ORACLE
 | |
| rec_field_definition:
 | |
|           row_field_name field_type
 | |
|           {
 | |
|             Lex->last_field->set_attributes(thd, $2,
 | |
|                                             COLUMN_DEFINITION_ROUTINE_LOCAL);
 | |
|           }
 | |
|         | rec_field_definition_anchored
 | |
|         ;
 | |
| 
 | |
| rec_field_definition_anchored:
 | |
|           row_field_name sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_def_fill_type_reference(thd,
 | |
|                                                                     $1, $2,
 | |
|                                                                     $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | row_field_name sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_def_fill_type_reference(thd,
 | |
|                                                                     $1, $2,
 | |
|                                                                     $4, $6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| rec_field_definition_list:
 | |
|           rec_field_definition
 | |
|           {
 | |
|             if (!($$= Row_definition_list::make(thd->mem_root, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | rec_field_definition_list ',' rec_field_definition
 | |
|           {
 | |
|             if (($$= $1)->append_uniq(thd->mem_root, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| rec_type_body:
 | |
|           '(' rec_field_definition_list ')' { $$= $2; }
 | |
|         ;
 | |
| %endif
 | |
| 
 | |
| sp_decl_idents_init_vars:
 | |
|           sp_decl_idents
 | |
|           {
 | |
|             Lex->sp_variable_declarations_init(thd, $1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_decl_variable_list:
 | |
|           sp_decl_idents_init_vars
 | |
|           field_type_all_with_record
 | |
|           {
 | |
|             Lex->last_field->set_attributes(thd, $2,
 | |
|                                             COLUMN_DEFINITION_ROUTINE_LOCAL);
 | |
|           }
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_finalize(thd, $1,
 | |
|                                                                 &Lex->last_field[0],
 | |
|                                                                 $4.expr,
 | |
|                                                                 $4.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         | sp_decl_idents_init_vars
 | |
|           ROW_SYM row_type_body
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_row_finalize(thd, $1, $3,
 | |
|                                                                     $4.expr,
 | |
|                                                                     $4.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         | sp_decl_variable_list_anchored
 | |
|         ;
 | |
| 
 | |
| sp_decl_handler:
 | |
|           sp_handler_type HANDLER_SYM FOR_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_handler_declaration_init(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_hcond_list sp_proc_stmt
 | |
|           {
 | |
|             if (unlikely(Lex->sp_handler_declaration_finalize(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.conds= $$.curs= 0;
 | |
|             $$.hndlrs= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_parenthesized_cursor_formal_parameters:
 | |
|           /* Empty */
 | |
|         | '(' sp_fdparams_no_default ')'
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_cursor_stmt_lex:
 | |
|           {
 | |
|             DBUG_ASSERT(thd->lex->sphead);
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                            sp_lex_cursor(thd, thd->lex))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_cursor_stmt:
 | |
|           sp_cursor_stmt_lex
 | |
|           {
 | |
|             DBUG_ASSERT(thd->free_list == NULL);
 | |
|             Lex->sphead->reset_lex(thd, $1);
 | |
|             if (Lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           remember_name select remember_end
 | |
|           {
 | |
|             DBUG_ASSERT(Lex == $1);
 | |
|             Lex->pop_select(); //main select
 | |
|             if (unlikely($1->stmt_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
| 	    if (Lex->is_metadata_used())
 | |
|             {
 | |
|               LEX_CSTRING expr_str= make_string(thd, $3, $5);
 | |
| 
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|               $1->set_expr_str(expr_str);
 | |
|             }
 | |
|             if (unlikely($1->sphead->restore_lex(thd)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_handler_type:
 | |
|           EXIT_MARIADB_SYM      { $$= sp_handler::EXIT; }
 | |
|         | CONTINUE_MARIADB_SYM  { $$= sp_handler::CONTINUE; }
 | |
|         | EXIT_ORACLE_SYM      { $$= sp_handler::EXIT; }
 | |
|         | CONTINUE_ORACLE_SYM  { $$= sp_handler::CONTINUE; }
 | |
|        /*| UNDO_SYM      { QQ No yet } */
 | |
|         ;
 | |
| 
 | |
| sp_hcond_list:
 | |
|           sp_hcond_element
 | |
|           { $$= 1; }
 | |
|         | sp_hcond_list ',' sp_hcond_element
 | |
|           { $$+= 1; }
 | |
|         ;
 | |
| 
 | |
| sp_hcond_element:
 | |
|           sp_hcond
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             sp_head *sp= lex->sphead;
 | |
|             sp_pcontext *ctx= lex->spcont->parent_context();
 | |
| 
 | |
|             if (unlikely(ctx->check_duplicate_handler($1)))
 | |
|               my_yyabort_error((ER_SP_DUP_HANDLER, MYF(0)));
 | |
| 
 | |
|             sp_instr_hpush_jump *i= (sp_instr_hpush_jump *)sp->last_instruction();
 | |
|             i->add_condition($1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_cond:
 | |
|           ulong_num
 | |
|           { /* mysql errno */
 | |
|             if (unlikely($1 == 0))
 | |
|               my_yyabort_error((ER_WRONG_VALUE, MYF(0), "CONDITION", "0"));
 | |
|             $$= new (thd) sp_condition_value($1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sqlstate
 | |
|         ;
 | |
| 
 | |
| sqlstate:
 | |
|           SQLSTATE_SYM opt_value TEXT_STRING_literal
 | |
|           { /* SQLSTATE */
 | |
| 
 | |
|             /*
 | |
|               An error is triggered:
 | |
|                 - if the specified string is not a valid SQLSTATE,
 | |
|                 - or if it represents the completion condition -- it is not
 | |
|                   allowed to SIGNAL, or declare a handler for the completion
 | |
|                   condition.
 | |
|             */
 | |
|             if (unlikely(!is_sqlstate_valid(&$3) ||
 | |
|                          is_sqlstate_completion($3.str)))
 | |
|               my_yyabort_error((ER_SP_BAD_SQLSTATE, MYF(0), $3.str));
 | |
|             $$= new (thd) sp_condition_value($3.str);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_value:
 | |
|           /* Empty */  {}
 | |
|         | VALUE_SYM    {}
 | |
|         ;
 | |
| 
 | |
| sp_hcond:
 | |
|           sp_cond
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         | ident /* CONDITION name */
 | |
|           {
 | |
|             $$= Lex->spcont->find_declared_or_predefined_condition(thd, &$1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               my_yyabort_error((ER_SP_COND_MISMATCH, MYF(0), $1.str));
 | |
|           }
 | |
|         | SQLWARNING_SYM /* SQLSTATEs 01??? */
 | |
|           {
 | |
|             $$= new (thd) sp_condition_value(sp_condition_value::WARNING);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | not FOUND_SYM /* SQLSTATEs 02??? */
 | |
|           {
 | |
|             $$= new (thd) sp_condition_value(sp_condition_value::NOT_FOUND);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SQLEXCEPTION_SYM /* All other SQLSTATEs */
 | |
|           {
 | |
|             $$= new (thd) sp_condition_value(sp_condition_value::EXCEPTION);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | OTHERS_ORACLE_SYM /* All other SQLSTATEs */
 | |
|           {
 | |
|             $$= new (thd) sp_condition_value(sp_condition_value::EXCEPTION);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| raise_stmt_oracle:
 | |
|           RAISE_ORACLE_SYM opt_set_signal_information
 | |
|           {
 | |
|             if (unlikely(Lex->add_resignal_statement(thd, NULL)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | RAISE_ORACLE_SYM signal_value opt_set_signal_information
 | |
|           {
 | |
|             if (unlikely(Lex->add_signal_statement(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| signal_stmt:
 | |
|           SIGNAL_SYM signal_value opt_set_signal_information
 | |
|           {
 | |
|             if (Lex->add_signal_statement(thd, $2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| signal_value:
 | |
|           ident
 | |
|           {
 | |
|             if (!($$= Lex->stmt_signal_value($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sqlstate
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| opt_signal_value:
 | |
|           /* empty */
 | |
|           { $$= NULL; }
 | |
|         | signal_value
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| opt_set_signal_information:
 | |
|           /* empty */
 | |
|           {
 | |
|             thd->m_parser_state->m_yacc.m_set_signal_info.clear();
 | |
|           }
 | |
|         | SET signal_information_item_list
 | |
|         ;
 | |
| 
 | |
| signal_information_item_list:
 | |
|           signal_condition_information_item_name '=' signal_allowed_expr
 | |
|           {
 | |
|             Set_signal_information *info;
 | |
|             info= &thd->m_parser_state->m_yacc.m_set_signal_info;
 | |
|             int index= (int) $1;
 | |
|             info->clear();
 | |
|             info->m_item[index]= $3;
 | |
|           }
 | |
|         | signal_information_item_list ','
 | |
|           signal_condition_information_item_name '=' signal_allowed_expr
 | |
|           {
 | |
|             Set_signal_information *info;
 | |
|             info= &thd->m_parser_state->m_yacc.m_set_signal_info;
 | |
|             int index= (int) $3;
 | |
|             if (unlikely(info->m_item[index] != NULL))
 | |
|               my_yyabort_error((ER_DUP_SIGNAL_SET, MYF(0),
 | |
|                                 Diag_condition_item_names[index].str));
 | |
|             info->m_item[index]= $5;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Only a limited subset of <expr> are allowed in SIGNAL/RESIGNAL.
 | |
| */
 | |
| signal_allowed_expr:
 | |
|           literal
 | |
|           { $$= $1; }
 | |
|         | variable
 | |
|           {
 | |
|             if ($1->type() == Item::FUNC_ITEM)
 | |
|             {
 | |
|               Item_func *item= (Item_func*) $1;
 | |
|               if (unlikely(item->functype() == Item_func::SUSERVAR_FUNC))
 | |
|               {
 | |
|                 /*
 | |
|                   Don't allow the following syntax:
 | |
|                     SIGNAL/RESIGNAL ...
 | |
|                     SET <signal condition item name> = @foo := expr
 | |
|                 */
 | |
|                 thd->parse_error();
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|             }
 | |
|             $$= $1;
 | |
|           }
 | |
|         | simple_ident
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| /* conditions that can be set in signal / resignal */
 | |
| signal_condition_information_item_name:
 | |
|           CLASS_ORIGIN_SYM
 | |
|           { $$= DIAG_CLASS_ORIGIN; }
 | |
|         | SUBCLASS_ORIGIN_SYM
 | |
|           { $$= DIAG_SUBCLASS_ORIGIN; }
 | |
|         | CONSTRAINT_CATALOG_SYM
 | |
|           { $$= DIAG_CONSTRAINT_CATALOG; }
 | |
|         | CONSTRAINT_SCHEMA_SYM
 | |
|           { $$= DIAG_CONSTRAINT_SCHEMA; }
 | |
|         | CONSTRAINT_NAME_SYM
 | |
|           { $$= DIAG_CONSTRAINT_NAME; }
 | |
|         | CATALOG_NAME_SYM
 | |
|           { $$= DIAG_CATALOG_NAME; }
 | |
|         | SCHEMA_NAME_SYM
 | |
|           { $$= DIAG_SCHEMA_NAME; }
 | |
|         | TABLE_NAME_SYM
 | |
|           { $$= DIAG_TABLE_NAME; }
 | |
|         | COLUMN_NAME_SYM
 | |
|           { $$= DIAG_COLUMN_NAME; }
 | |
|         | CURSOR_NAME_SYM
 | |
|           { $$= DIAG_CURSOR_NAME; }
 | |
|         | MESSAGE_TEXT_SYM
 | |
|           { $$= DIAG_MESSAGE_TEXT; }
 | |
|         | MYSQL_ERRNO_SYM
 | |
|           { $$= DIAG_MYSQL_ERRNO; }
 | |
|         | ROW_NUMBER_SYM
 | |
|           { $$= DIAG_ROW_NUMBER; }
 | |
|         ;
 | |
| 
 | |
| resignal_stmt:
 | |
|           RESIGNAL_SYM opt_signal_value opt_set_signal_information
 | |
|           {
 | |
|             if (unlikely(Lex->add_resignal_statement(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| get_diagnostics:
 | |
|           GET_SYM which_area DIAGNOSTICS_SYM
 | |
|           {
 | |
|             thd->where= THD_WHERE::USE_WHERE_STRING;
 | |
|             thd->where_str= "GET DIAGNOSTICS";
 | |
|           }
 | |
|           diagnostics_information
 | |
|           {
 | |
|             Diagnostics_information *info= $5;
 | |
| 
 | |
|             info->set_which_da($2);
 | |
| 
 | |
|             Lex->sql_command= SQLCOM_GET_DIAGNOSTICS;
 | |
|             Lex->m_sql_cmd= new (thd) Sql_cmd_get_diagnostics(info);
 | |
| 
 | |
|             if (unlikely(Lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| which_area:
 | |
|         /* If <which area> is not specified, then CURRENT is implicit. */
 | |
|           { $$= Diagnostics_information::CURRENT_AREA; }
 | |
|         | CURRENT_SYM
 | |
|           { $$= Diagnostics_information::CURRENT_AREA; }
 | |
|         ;
 | |
| 
 | |
| diagnostics_information:
 | |
|           statement_information
 | |
|           {
 | |
|             $$= new (thd) Statement_information($1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONDITION_SYM condition_number condition_information
 | |
|           {
 | |
|             $$= new (thd) Condition_information($2, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| statement_information:
 | |
|           statement_information_item
 | |
|           {
 | |
|             $$= new (thd) List<Statement_information_item>;
 | |
|             if (unlikely($$ == NULL) ||
 | |
|                 unlikely($$->push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | statement_information ',' statement_information_item
 | |
|           {
 | |
|             if (unlikely($1->push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| statement_information_item:
 | |
|           simple_target_specification '=' statement_information_item_name
 | |
|           {
 | |
|             $$= new (thd) Statement_information_item($3, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| simple_target_specification:
 | |
|           ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= thd->lex->create_item_for_sp_var(&$1, NULL))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' ident_or_text
 | |
|           {
 | |
|             if (!$2.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             $$= new (thd) Item_func_get_user_var(thd, &$2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| statement_information_item_name:
 | |
|           NUMBER_MARIADB_SYM
 | |
|           { $$= Statement_information_item::NUMBER; }
 | |
|         | NUMBER_ORACLE_SYM
 | |
|           { $$= Statement_information_item::NUMBER; }
 | |
|         | ROW_COUNT_SYM
 | |
|           { $$= Statement_information_item::ROW_COUNT; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|    Only a limited subset of <expr> are allowed in GET DIAGNOSTICS
 | |
|    <condition number>, same subset as for SIGNAL/RESIGNAL.
 | |
| */
 | |
| condition_number:
 | |
|           signal_allowed_expr
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| condition_information:
 | |
|           condition_information_item
 | |
|           {
 | |
|             $$= new (thd) List<Condition_information_item>;
 | |
|             if (unlikely($$ == NULL) ||
 | |
|                 unlikely($$->push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | condition_information ',' condition_information_item
 | |
|           {
 | |
|             if (unlikely($1->push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| condition_information_item:
 | |
|           simple_target_specification '=' condition_information_item_name
 | |
|           {
 | |
|             $$= new (thd) Condition_information_item($3, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| condition_information_item_name:
 | |
|           CLASS_ORIGIN_SYM
 | |
|           { $$= Condition_information_item::CLASS_ORIGIN; }
 | |
|         | SUBCLASS_ORIGIN_SYM
 | |
|           { $$= Condition_information_item::SUBCLASS_ORIGIN; }
 | |
|         | CONSTRAINT_CATALOG_SYM
 | |
|           { $$= Condition_information_item::CONSTRAINT_CATALOG; }
 | |
|         | CONSTRAINT_SCHEMA_SYM
 | |
|           { $$= Condition_information_item::CONSTRAINT_SCHEMA; }
 | |
|         | CONSTRAINT_NAME_SYM
 | |
|           { $$= Condition_information_item::CONSTRAINT_NAME; }
 | |
|         | CATALOG_NAME_SYM
 | |
|           { $$= Condition_information_item::CATALOG_NAME; }
 | |
|         | SCHEMA_NAME_SYM
 | |
|           { $$= Condition_information_item::SCHEMA_NAME; }
 | |
|         | TABLE_NAME_SYM
 | |
|           { $$= Condition_information_item::TABLE_NAME; }
 | |
|         | COLUMN_NAME_SYM
 | |
|           { $$= Condition_information_item::COLUMN_NAME; }
 | |
|         | CURSOR_NAME_SYM
 | |
|           { $$= Condition_information_item::CURSOR_NAME; }
 | |
|         | MESSAGE_TEXT_SYM
 | |
|           { $$= Condition_information_item::MESSAGE_TEXT; }
 | |
|         | MYSQL_ERRNO_SYM
 | |
|           { $$= Condition_information_item::MYSQL_ERRNO; }
 | |
|         | RETURNED_SQLSTATE_SYM
 | |
|           { $$= Condition_information_item::RETURNED_SQLSTATE; }
 | |
|         | ROW_NUMBER_SYM
 | |
|           { $$= Condition_information_item::ROW_NUMBER; }
 | |
|         ;
 | |
| 
 | |
| sp_decl_ident:
 | |
|           IDENT_sys
 | |
|         | keyword_sp_decl
 | |
|           {
 | |
|             if (unlikely($$.copy_ident_cli(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_decl_idents:
 | |
|           sp_decl_ident
 | |
|           {
 | |
|             /* NOTE: field definition is filled in sp_decl section. */
 | |
| 
 | |
|             LEX *lex= Lex;
 | |
|             sp_pcontext *spc= lex->spcont;
 | |
| 
 | |
|             if (unlikely(spc->find_variable(&$1, TRUE)))
 | |
|               my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $1.str));
 | |
|             spc->add_variable(thd, &$1);
 | |
|             $$= 1;
 | |
|           }
 | |
|         | sp_decl_idents ',' ident
 | |
|           {
 | |
|             /* NOTE: field definition is filled in sp_decl section. */
 | |
| 
 | |
|             LEX *lex= Lex;
 | |
|             sp_pcontext *spc= lex->spcont;
 | |
| 
 | |
|             if (unlikely(spc->find_variable(&$3, TRUE)))
 | |
|               my_yyabort_error((ER_SP_DUP_VAR, MYF(0), $3.str));
 | |
|             spc->add_variable(thd, &$3);
 | |
|             $$= $1 + 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_if:
 | |
|           IF_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sphead->new_cont_backpatch(NULL);
 | |
|           }
 | |
|           sp_if END IF_SYM
 | |
|           { Lex->sphead->do_cont_backpatch(); }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_statement:
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             Lex_input_stream *lip= YYLIP;
 | |
| 
 | |
|             lex->sphead->reset_lex(thd);
 | |
|             /*
 | |
|               We should not push main select here, it will be done or not
 | |
|               done by the statement, we just provide only a new LEX for the
 | |
|               statement here as if it is start of parsing a new statement.
 | |
|             */
 | |
|             lex->sphead->m_tmp_query= lip->get_tok_start();
 | |
|           }
 | |
|           sp_statement
 | |
|           {
 | |
|             if (Lex->sp_proc_stmt_statement_finalize(thd, yychar == YYEMPTY) ||
 | |
|                 Lex->sphead->restore_lex(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| RETURN_ALLMODES_SYM:
 | |
|           RETURN_MARIADB_SYM
 | |
|         | RETURN_ORACLE_SYM
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_return:
 | |
|           RETURN_ALLMODES_SYM expr_lex
 | |
|           {
 | |
|             sp_head *sp= $2->sphead;
 | |
|             if (unlikely(sp->m_handler->add_instr_freturn(thd, sp, $2->spcont,
 | |
|                                                           $2->get_item(), $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           { /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
 | |
|         | RETURN_ORACLE_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             sp_head *sp= lex->sphead;
 | |
|             if (unlikely(sp->m_handler->add_instr_preturn(thd, sp,
 | |
|                                                                lex->spcont)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_exit_oracle:
 | |
|           EXIT_ORACLE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_exit_statement(thd, nullptr, empty_clex_str)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | EXIT_ORACLE_SYM label_ident
 | |
|           {
 | |
|             if (unlikely(Lex->sp_exit_statement(thd, &$2, nullptr,
 | |
|                                                 empty_clex_str)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | EXIT_ORACLE_SYM WHEN_SYM expr_lex
 | |
|           {
 | |
|             if (unlikely($3->sp_exit_statement(thd, $3->get_item(),
 | |
|                                                $3->get_expr_str())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           { /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
 | |
|         | EXIT_ORACLE_SYM label_ident WHEN_SYM expr_lex
 | |
|           {
 | |
|             if (unlikely($4->sp_exit_statement(thd, &$2, $4->get_item(),
 | |
|                                                $4->get_expr_str())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           { /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_continue_oracle:
 | |
|           CONTINUE_ORACLE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_continue_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONTINUE_ORACLE_SYM label_ident
 | |
|           {
 | |
|             if (unlikely(Lex->sp_continue_statement(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONTINUE_ORACLE_SYM WHEN_SYM expr_lex
 | |
|           {
 | |
|             if (unlikely($3->sp_continue_when_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           { /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
 | |
|         | CONTINUE_ORACLE_SYM label_ident WHEN_SYM expr_lex
 | |
|           {
 | |
|             if (unlikely($4->sp_continue_when_statement(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           { /* See the comment 'COMMENT_FOR_DESCTRUCTOR' near %destructor */ }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_proc_stmt_leave:
 | |
|           LEAVE_SYM label_ident
 | |
|           {
 | |
|             if (unlikely(Lex->sp_leave_statement(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_iterate:
 | |
|           ITERATE_SYM label_ident
 | |
|           {
 | |
|             if (unlikely(Lex->sp_iterate_statement(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_goto_oracle:
 | |
|           GOTO_ORACLE_SYM label_ident
 | |
|           {
 | |
|             if (unlikely(Lex->sp_goto_statement(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| expr_lex:
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->sphead);
 | |
|             if (unlikely(!($<expr_lex>$= new (thd)
 | |
|                            sp_expr_lex(thd, thd->lex))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sphead->reset_lex(thd, $<expr_lex>$);
 | |
|             if (Lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           remember_start_opt expr remember_end
 | |
|           {
 | |
|             $$= $<expr_lex>1;
 | |
|             $$->set_item($3);
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               LEX_CSTRING expr_str= make_string(thd, $2, $4);
 | |
| 
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|               $$->set_expr_str(expr_str);
 | |
|             }
 | |
| 
 | |
|             Lex->pop_select(); //min select
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|             if ($$->sphead->restore_lex(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| assignment_source_lex:
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->sphead);
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                            sp_assignment_lex(thd, thd->lex))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| assignment_source_expr:
 | |
|           assignment_source_lex
 | |
|           {
 | |
|             DBUG_ASSERT(thd->free_list == NULL);
 | |
|             Lex->sphead->reset_lex(thd, $1);
 | |
|             if (Lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             DBUG_ASSERT($1 == thd->lex);
 | |
|             $$= $1;
 | |
|             $$->set_item_and_free_list($4, thd->free_list);
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               LEX_CSTRING expr_str= make_string(thd, $3, $5);
 | |
| 
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|               $$->set_expr_str(expr_str);
 | |
|             }
 | |
| 
 | |
|             thd->free_list= NULL;
 | |
|             Lex->pop_select(); //min select
 | |
|             if ($$->sphead->restore_lex(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| for_loop_bound_expr:
 | |
|           assignment_source_lex
 | |
|           {
 | |
|             Lex->sphead->reset_lex(thd, $1);
 | |
|             if (Lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->current_select->parsing_place= FOR_LOOP_BOUND;
 | |
|           }
 | |
|           remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             DBUG_ASSERT($1 == thd->lex);
 | |
|             $$= $1;
 | |
|             $$->set_item_and_free_list($4, nullptr);
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               LEX_CSTRING expr_str= make_string(thd, $3, $5);
 | |
| 
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|               $$->set_expr_str(expr_str);
 | |
|             }
 | |
| 
 | |
|             Lex->pop_select(); //main select
 | |
|             if (unlikely($$->sphead->restore_lex(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->current_select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| cursor_actual_parameters:
 | |
|           assignment_source_expr
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd) List<sp_assignment_lex>)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->push_back($1, thd->mem_root);
 | |
|           }
 | |
|         | cursor_actual_parameters ',' assignment_source_expr
 | |
|           {
 | |
|             $$= $1;
 | |
|             $$->push_back($3, thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_parenthesized_cursor_actual_parameters:
 | |
|           /* Empty */                        { $$= NULL; }
 | |
|         | '(' cursor_actual_parameters ')'   { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_with_cursor:
 | |
|          sp_proc_stmt_open
 | |
|        | sp_proc_stmt_fetch
 | |
|        | sp_proc_stmt_close
 | |
|        ;
 | |
| 
 | |
| sp_proc_stmt_open:
 | |
|           OPEN_SYM ident opt_parenthesized_cursor_actual_parameters
 | |
|           {
 | |
|             if (unlikely(Lex->sp_open_cursor(thd, &$2, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | OPEN_SYM ident FOR_SYM sp_cursor_stmt
 | |
|           {
 | |
|             if (Lex->sp_open_cursor_for_stmt(thd, &$2, $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_fetch_head:
 | |
|           FETCH_SYM ident INTO
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->sp_add_instr_fetch_cursor(thd, &$2))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | FETCH_SYM FROM ident INTO
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->sp_add_instr_fetch_cursor(thd, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|        | FETCH_SYM NEXT_SYM FROM ident INTO
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->sp_add_instr_fetch_cursor(thd, &$4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_fetch:
 | |
|          sp_proc_stmt_fetch_head sp_fetch_list
 | |
|          {
 | |
|            $1->set_fetch_target_list($2);
 | |
|          }
 | |
|        | FETCH_SYM GROUP_SYM NEXT_SYM ROW_SYM
 | |
|          {
 | |
|            if (unlikely(Lex->sp_add_agg_cfetch()))
 | |
|              MYSQL_YYABORT;
 | |
|          }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_close:
 | |
|           CLOSE_SYM ident
 | |
|           {
 | |
|             if (Lex->sp_close(thd, $2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_fetch_list:
 | |
|           ident
 | |
|           {
 | |
|             sp_fetch_target *target= Lex->make_fetch_target(thd, $1);
 | |
|             if (!target ||
 | |
|                 !($$= List<sp_fetch_target>::make(thd->mem_root, target)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_fetch_list ',' ident
 | |
|           {
 | |
|             sp_fetch_target *target= Lex->make_fetch_target(thd, $3);
 | |
|             if (!target || $1->push_back(target, thd->mem_root))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_if:
 | |
|           expr_lex THEN_SYM
 | |
|           {
 | |
|             if (unlikely($1->sp_if_expr(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_if_then_statements
 | |
|           {
 | |
|             if (unlikely($1->sp_if_after_statements(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_elseifs
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             lex->sphead->backpatch(lex->spcont->pop_label());
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_elseifs:
 | |
|           /* Empty */
 | |
|         | ELSEIF_MARIADB_SYM sp_if
 | |
|         | ELSIF_ORACLE_SYM sp_if
 | |
|         | ELSE sp_if_then_statements
 | |
|         ;
 | |
| 
 | |
| case_stmt_specification:
 | |
|           CASE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             /**
 | |
|               An example of the CASE statement in use is
 | |
|             <pre>
 | |
|             CREATE PROCEDURE proc_19194_simple(i int)
 | |
|             BEGIN
 | |
|               DECLARE str CHAR(10);
 | |
| 
 | |
|               CASE i
 | |
|                 WHEN 1 THEN SET str="1";
 | |
|                 WHEN 2 THEN SET str="2";
 | |
|                 WHEN 3 THEN SET str="3";
 | |
|                 ELSE SET str="unknown";
 | |
|               END CASE;
 | |
| 
 | |
|               SELECT str;
 | |
|             END
 | |
|             </pre>
 | |
|               The actions are used to generate the following code:
 | |
|             <pre>
 | |
|             SHOW PROCEDURE CODE proc_19194_simple;
 | |
|             Pos     Instruction
 | |
|             0       set str@1 NULL
 | |
|             1       set_case_expr (12) 0 i@0
 | |
|             2       jump_if_not 5(12) (case_expr@0 = 1)
 | |
|             3       set str@1 _latin1'1'
 | |
|             4       jump 12
 | |
|             5       jump_if_not 8(12) (case_expr@0 = 2)
 | |
|             6       set str@1 _latin1'2'
 | |
|             7       jump 12
 | |
|             8       jump_if_not 11(12) (case_expr@0 = 3)
 | |
|             9       set str@1 _latin1'3'
 | |
|             10      jump 12
 | |
|             11      set str@1 _latin1'unknown'
 | |
|             12      stmt 0 "SELECT str"
 | |
|             </pre>
 | |
|             */
 | |
| 
 | |
|             Lex->sphead->new_cont_backpatch(NULL);
 | |
| 
 | |
|             /*
 | |
|               BACKPATCH: Creating target label for the jump to after END CASE
 | |
|               (instruction 12 in the example)
 | |
|             */
 | |
|             Lex->spcont->push_label(thd, &empty_clex_str, Lex->sphead->instructions());
 | |
|           }
 | |
|           case_stmt_body
 | |
|           else_clause_opt
 | |
|           END
 | |
|           CASE_SYM
 | |
|           {
 | |
|             /*
 | |
|               BACKPATCH: Resolving forward jump from
 | |
|               "case_stmt_action_then" to after END CASE
 | |
|               (jump from instruction 4 to 12, 7 to 12 ... in the example)
 | |
|             */
 | |
|             Lex->sphead->backpatch(Lex->spcont->pop_label());
 | |
| 
 | |
|             if ($3)
 | |
|               Lex->spcont->pop_case_expr_id();
 | |
| 
 | |
|             Lex->sphead->do_cont_backpatch();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| case_stmt_body:
 | |
|           expr_lex
 | |
|           {
 | |
|             if (unlikely($1->case_stmt_action_expr()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           simple_when_clause_list
 | |
|           { $$= 1; }
 | |
|         | searched_when_clause_list
 | |
|           { $$= 0; }
 | |
|         ;
 | |
| 
 | |
| simple_when_clause_list:
 | |
|           simple_when_clause
 | |
|         | simple_when_clause_list simple_when_clause
 | |
|         ;
 | |
| 
 | |
| searched_when_clause_list:
 | |
|           searched_when_clause
 | |
|         | searched_when_clause_list searched_when_clause
 | |
|         ;
 | |
| 
 | |
| simple_when_clause:
 | |
|           WHEN_SYM expr_lex
 | |
|           {
 | |
|             /* Simple case: <caseval> = <whenval> */
 | |
|             if (unlikely($2->case_stmt_action_when(true)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           THEN_SYM
 | |
|           sp_case_then_statements
 | |
|           {
 | |
|             if (unlikely(Lex->case_stmt_action_then()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| searched_when_clause:
 | |
|           WHEN_SYM expr_lex
 | |
|           {
 | |
|             $2->get_item()->base_flags|= item_base_t::IS_COND;
 | |
|             if (unlikely($2->case_stmt_action_when(false)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           THEN_SYM
 | |
|           sp_case_then_statements
 | |
|           {
 | |
|             if (unlikely(Lex->case_stmt_action_then()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| else_clause_opt:
 | |
|           /* empty */
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             sp_head *sp= lex->sphead;
 | |
|             uint ip= sp->instructions();
 | |
|             sp_instr_error *i= new (thd)
 | |
|               sp_instr_error(ip, lex->spcont, ER_SP_CASE_NOT_FOUND);
 | |
|             if (unlikely(i == NULL) ||
 | |
|                 unlikely(sp->add_instr(i)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ELSE sp_case_then_statements
 | |
|         ;
 | |
| 
 | |
| sp_opt_label:
 | |
|           /* Empty  */  { $$= null_clex_str; }
 | |
|         | label_ident   { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| /* This adds one shift/reduce conflict */
 | |
| opt_sp_for_loop_direction:
 | |
|             /* Empty */ { $$= 1; }
 | |
|           | REVERSE_SYM { $$= -1; }
 | |
|         ;
 | |
| 
 | |
| sp_for_loop_index_and_bounds:
 | |
|           ident_for_loop_index sp_for_loop_bounds
 | |
|           {
 | |
|             if (unlikely(Lex->sp_for_loop_declarations(thd, &$$, &$1, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_for_loop_bounds:
 | |
|           IN_SYM opt_sp_for_loop_direction for_loop_bound_expr
 | |
|           DOT_DOT_SYM for_loop_bound_expr
 | |
|           {
 | |
|             $$= Lex_for_loop_bounds_intrange($2, $3, $5);
 | |
|           }
 | |
|         | IN_SYM opt_sp_for_loop_direction for_loop_bound_expr
 | |
|           {
 | |
|             $$.m_direction= $2;
 | |
|             $$.m_index= $3;
 | |
|             $$.m_target_bound= NULL;
 | |
|             $$.m_implicit_cursor= false;
 | |
|           }
 | |
|         | IN_SYM opt_sp_for_loop_direction '(' sp_cursor_stmt ')'
 | |
|           {
 | |
|             if (unlikely(Lex->sp_for_loop_implicit_cursor_statement(thd, &$$,
 | |
|                                                                     $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| loop_body:
 | |
|           sp_proc_stmts1 END LOOP_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             uint ip= lex->sphead->instructions();
 | |
|             sp_label *lab= lex->spcont->last_label();  /* Jumping back */
 | |
|             sp_instr_jump *i= new (thd)
 | |
|               sp_instr_jump(ip, lex->spcont, lab->ip);
 | |
|             if (unlikely(i == NULL) ||
 | |
|                 unlikely(lex->sphead->add_instr(i)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| repeat_body:
 | |
|           sp_proc_stmts1 UNTIL_SYM expr_lex END REPEAT_SYM
 | |
|           {
 | |
|             if ($3->sp_repeat_loop_finalize(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| pop_sp_loop_label:
 | |
|           sp_opt_label
 | |
|           {
 | |
|             if (unlikely(Lex->sp_pop_loop_label(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_labeled_control:
 | |
|           sp_control_label LOOP_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_label(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           loop_body pop_sp_loop_label
 | |
|           { }
 | |
|         | sp_control_label WHILE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_label(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           while_body pop_sp_loop_label
 | |
|           { }
 | |
|         | sp_control_label FOR_SYM
 | |
|           {
 | |
|             // See "The FOR LOOP statement" comments in sql_lex.cc
 | |
|             Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block
 | |
|           }
 | |
|           sp_for_loop_index_and_bounds
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_label(thd, &$1))) // The inner WHILE block
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Lex->sp_for_loop_condition_test(thd, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           for_loop_statements
 | |
|           {
 | |
|             if (unlikely(Lex->sp_for_loop_finalize(thd, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           pop_sp_loop_label                    // The inner WHILE block
 | |
|           {
 | |
|             if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_control_label REPEAT_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_label(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           repeat_body pop_sp_loop_label
 | |
|           { }
 | |
|         ;
 | |
| 
 | |
| sp_unlabeled_control:
 | |
|           LOOP_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_empty_label(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           loop_body
 | |
|           {
 | |
|             Lex->sp_pop_loop_empty_label(thd);
 | |
|           }
 | |
|         | WHILE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_empty_label(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           while_body
 | |
|           {
 | |
|             Lex->sp_pop_loop_empty_label(thd);
 | |
|           }
 | |
|         | FOR_SYM
 | |
|           {
 | |
|             // See "The FOR LOOP statement" comments in sql_lex.cc
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sp_block_init(thd); // The outer DECLARE..BEGIN..END block
 | |
|           }
 | |
|           sp_for_loop_index_and_bounds
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_empty_label(thd))) // The inner WHILE block
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Lex->sp_for_loop_condition_test(thd, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           for_loop_statements
 | |
|           {
 | |
|             if (unlikely(Lex->sp_for_loop_finalize(thd, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sp_pop_loop_empty_label(thd); // The inner WHILE block
 | |
|             if (unlikely(Lex->sp_for_loop_outer_block_finalize(thd, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | REPEAT_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_loop_empty_label(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           repeat_body
 | |
|           {
 | |
|             Lex->sp_pop_loop_empty_label(thd);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| trg_action_time:
 | |
|             BEFORE_SYM
 | |
|             { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; }
 | |
|           | AFTER_SYM
 | |
|             { Lex->trg_chistics.action_time= TRG_ACTION_AFTER; }
 | |
|           ;
 | |
| 
 | |
| trg_event:
 | |
|             INSERT
 | |
|             { Lex->trg_chistics.events|= trg2bit(TRG_EVENT_INSERT); }
 | |
|           | UPDATE_SYM
 | |
|             { Lex->trg_chistics.events|= trg2bit(TRG_EVENT_UPDATE); }
 | |
|           | DELETE_SYM
 | |
|             { Lex->trg_chistics.events|= trg2bit(TRG_EVENT_DELETE); }
 | |
|           ;
 | |
| 
 | |
| trg_events:
 | |
|             trg_event
 | |
|           | trg_events OR_SYM trg_event
 | |
|           ;
 | |
| 
 | |
| create_body:
 | |
|           create_field_list_parens
 | |
|           { Lex->create_info.option_list= NULL; }
 | |
|           opt_create_table_options opt_create_partitioning opt_create_select {}
 | |
|         | opt_create_table_options opt_create_partitioning opt_create_select {}
 | |
|         | create_like
 | |
|           {
 | |
| 
 | |
|             Lex->create_info.add(DDL_options_st::OPT_LIKE);
 | |
|             TABLE_LIST *src_table= Lex->first_select_lex()->
 | |
|               add_table_to_list(thd, $1, NULL, 0, TL_READ, MDL_SHARED_READ);
 | |
|             if (unlikely(! src_table))
 | |
|               MYSQL_YYABORT;
 | |
|             /* CREATE TABLE ... LIKE is not allowed for views. */
 | |
|             src_table->required_type= TABLE_TYPE_NORMAL;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| create_like:
 | |
|           LIKE table_ident                      { $$= $2; }
 | |
|         | LEFT_PAREN_LIKE LIKE table_ident ')'  { $$= $3; }
 | |
|         ;
 | |
| 
 | |
| opt_create_select:
 | |
|           /* empty */ {}
 | |
|         | opt_duplicate opt_as create_select_query_expression
 | |
|         opt_versioning_option
 | |
|           {
 | |
|             Lex->create_info.add(DDL_options_st::OPT_CREATE_SELECT);
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| create_select_query_expression:
 | |
|           query_expression
 | |
|           {
 | |
|             if (Lex->parsed_insert_select($1->first_select()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LEFT_PAREN_WITH with_clause query_expression_no_with_clause ')'
 | |
|           {
 | |
|             SELECT_LEX *first_select= $3->first_select();
 | |
|             $3->set_with_clause($2);
 | |
|             $2->attach_to(first_select);
 | |
|             if (Lex->parsed_insert_select(first_select))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_create_partitioning:
 | |
|           opt_partitioning
 | |
|           {
 | |
|             /*
 | |
|               Remove all tables used in PARTITION clause from the global table
 | |
|               list. Partitioning with subqueries is not allowed anyway.
 | |
|             */
 | |
|             TABLE_LIST *last_non_sel_table= Lex->create_last_non_select_table;
 | |
|             last_non_sel_table->next_global= 0;
 | |
|             Lex->query_tables_last= &last_non_sel_table->next_global;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|  This part of the parser is about handling of the partition information.
 | |
| 
 | |
|  Its first version was written by Mikael Ronström with lots of answers to
 | |
|  questions provided by Antony Curtis.
 | |
| 
 | |
|  The partition grammar can be called from three places.
 | |
|  1) CREATE TABLE ... PARTITION ..
 | |
|  2) ALTER TABLE table_name PARTITION ...
 | |
|  3) PARTITION ...
 | |
| 
 | |
|  The first place is called when a new table is created from a MySQL client.
 | |
|  The second place is called when a table is altered with the ALTER TABLE
 | |
|  command from a MySQL client.
 | |
|  The third place is called when opening an frm file and finding partition
 | |
|  info in the .frm file. It is necessary to avoid allowing PARTITION to be
 | |
|  an allowed entry point for SQL client queries. This is arranged by setting
 | |
|  some state variables before arriving here.
 | |
| 
 | |
|  To be able to handle errors we will only set error code in this code
 | |
|  and handle the error condition in the function calling the parser. This
 | |
|  is necessary to ensure we can also handle errors when calling the parser
 | |
|  from the openfrm function.
 | |
| */
 | |
| opt_partitioning:
 | |
|           /* empty */ {}
 | |
|         | partitioning
 | |
|         ;
 | |
| 
 | |
| partitioning:
 | |
|           PARTITION_SYM have_partitioning
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->part_info= new (thd) partition_info();
 | |
|             if (unlikely(!lex->part_info))
 | |
|               MYSQL_YYABORT;
 | |
|             if (lex->sql_command == SQLCOM_ALTER_TABLE)
 | |
|             {
 | |
|               lex->alter_info.partition_flags|= ALTER_PARTITION_INFO;
 | |
|             }
 | |
|           }
 | |
|           partition
 | |
|         ;
 | |
| 
 | |
| have_partitioning:
 | |
|           /* empty */
 | |
|           {
 | |
| #ifdef WITH_PARTITION_STORAGE_ENGINE
 | |
|             LEX_CSTRING partition_name={STRING_WITH_LEN("partition")};
 | |
|             if (unlikely(!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN)))
 | |
|               my_yyabort_error((ER_OPTION_PREVENTS_STATEMENT, MYF(0),
 | |
|                                 "--skip-partition"));
 | |
| #else
 | |
|             my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), "partitioning",
 | |
|                               "--with-plugin-partition"));
 | |
| #endif
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| partition_entry:
 | |
|           PARTITION_SYM
 | |
|           {
 | |
|             if (unlikely(!Lex->part_info))
 | |
|             {
 | |
|               thd->parse_error(ER_PARTITION_ENTRY_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             /*
 | |
|               We enter here when opening the frm file to translate
 | |
|               partition info string into part_info data structure.
 | |
|             */
 | |
|           }
 | |
|           partition
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| partition:
 | |
|           BY
 | |
| 	  { Lex->safe_to_cache_query= 1; }
 | |
| 	   part_type_def opt_num_parts opt_sub_part part_defs
 | |
|         ;
 | |
| 
 | |
| part_type_def:
 | |
|           opt_linear KEY_SYM opt_key_algo '(' part_field_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->list_of_part_fields= TRUE;
 | |
|             part_info->column_list= FALSE;
 | |
|             part_info->part_type= HASH_PARTITION;
 | |
|           }
 | |
|         | opt_linear HASH_SYM
 | |
|           { Lex->part_info->part_type= HASH_PARTITION; }
 | |
|           part_func {}
 | |
|         | RANGE_SYM part_func
 | |
|           { Lex->part_info->part_type= RANGE_PARTITION; }
 | |
|         | RANGE_SYM part_column_list
 | |
|           { Lex->part_info->part_type= RANGE_PARTITION; }
 | |
|         | LIST_SYM 
 | |
| 	  {
 | |
| 	    Select->parsing_place= IN_PART_FUNC;
 | |
|           }
 | |
|           part_func
 | |
|           { 
 | |
| 	    Lex->part_info->part_type= LIST_PARTITION; 
 | |
| 	    Select->parsing_place= NO_MATTER;
 | |
| 	  }
 | |
|         | LIST_SYM part_column_list
 | |
|           { Lex->part_info->part_type= LIST_PARTITION; }
 | |
|         | SYSTEM_TIME_SYM
 | |
|           {
 | |
|              if (unlikely(Lex->part_info->vers_init_info(thd)))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_versioning_rotation
 | |
|         ;
 | |
| 
 | |
| opt_linear:
 | |
|           /* empty */ {}
 | |
|         | LINEAR_SYM
 | |
|           { Lex->part_info->linear_hash_ind= TRUE;}
 | |
|         ;
 | |
| 
 | |
| opt_key_algo:
 | |
|           /* empty */
 | |
|           { Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_NONE;}
 | |
|         | ALGORITHM_SYM '=' real_ulong_num
 | |
|           {
 | |
|             switch ($3) {
 | |
|             case 1:
 | |
|               Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_51;
 | |
|               break;
 | |
|             case 2:
 | |
|               Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_55;
 | |
|               break;
 | |
|             default:
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_field_list:
 | |
|           /* empty */ {}
 | |
|         | part_field_item_list {}
 | |
|         ;
 | |
| 
 | |
| part_field_item_list:
 | |
|           part_field_item {}
 | |
|         | part_field_item_list ',' part_field_item {}
 | |
|         ;
 | |
| 
 | |
| part_field_item:
 | |
|           ident
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->num_columns++;
 | |
|             if (unlikely(part_info->part_field_list.push_back($1.str,
 | |
|                          thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(part_info->num_columns > MAX_REF_PARTS))
 | |
|               my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
 | |
|                                 "list of partition fields"));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_column_list:
 | |
|           COLUMNS '(' part_field_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->column_list= TRUE;
 | |
|             part_info->list_of_part_fields= TRUE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| part_func:
 | |
|           '(' part_func_expr ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->set_part_expr(thd, $2, FALSE)))
 | |
|               MYSQL_YYABORT;
 | |
|             part_info->num_columns= 1;
 | |
|             part_info->column_list= FALSE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sub_part_func:
 | |
|           '(' part_func_expr ')'
 | |
|           {
 | |
|             if (unlikely(Lex->part_info->set_part_expr(thd, $2, TRUE)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_num_parts:
 | |
|           /* empty */ {}
 | |
|         | PARTITIONS_SYM real_ulong_num
 | |
|           { 
 | |
|             uint num_parts= $2;
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(num_parts == 0))
 | |
|               my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "partitions"));
 | |
| 
 | |
|             part_info->num_parts= num_parts;
 | |
|             part_info->use_default_num_partitions= FALSE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_sub_part:
 | |
|           /* empty */ {}
 | |
|         | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func
 | |
|           { Lex->part_info->subpart_type= HASH_PARTITION; }
 | |
|           opt_num_subparts {}
 | |
|         | SUBPARTITION_SYM BY opt_linear KEY_SYM opt_key_algo
 | |
|           '(' sub_part_field_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->subpart_type= HASH_PARTITION;
 | |
|             part_info->list_of_subpart_fields= TRUE;
 | |
|           }
 | |
|           opt_num_subparts {}
 | |
|         ;
 | |
| 
 | |
| sub_part_field_list:
 | |
|           sub_part_field_item {}
 | |
|         | sub_part_field_list ',' sub_part_field_item {}
 | |
|         ;
 | |
| 
 | |
| sub_part_field_item:
 | |
|           ident
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->subpart_field_list.push_back($1.str,
 | |
|                          thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             if (unlikely(part_info->subpart_field_list.elements > MAX_REF_PARTS))
 | |
|               my_yyabort_error((ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
 | |
|                                 "list of subpartition fields"));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_func_expr:
 | |
|           bit_expr
 | |
|           {
 | |
|             if (unlikely(!Lex->safe_to_cache_query))
 | |
|             {
 | |
|               thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             $$=$1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_num_subparts:
 | |
|           /* empty */ {}
 | |
|         | SUBPARTITIONS_SYM real_ulong_num
 | |
|           {
 | |
|             uint num_parts= $2;
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(num_parts == 0))
 | |
|               my_yyabort_error((ER_NO_PARTS_ERROR, MYF(0), "subpartitions"));
 | |
|             lex->part_info->num_subparts= num_parts;
 | |
|             lex->part_info->use_default_num_subpartitions= FALSE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_defs:
 | |
|           /* empty */
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->part_type == RANGE_PARTITION))
 | |
|               my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
 | |
|                                 "RANGE"));
 | |
|             if (unlikely(part_info->part_type == LIST_PARTITION))
 | |
|               my_yyabort_error((ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
 | |
|                                 "LIST"));
 | |
|           }
 | |
|         | '(' part_def_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             uint count_curr_parts= part_info->partitions.elements;
 | |
|             if (part_info->num_parts != 0)
 | |
|             {
 | |
|               if (unlikely(part_info->num_parts !=
 | |
|                            count_curr_parts))
 | |
|               {
 | |
|                 thd->parse_error(ER_PARTITION_WRONG_NO_PART_ERROR);
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|             }
 | |
|             else if (count_curr_parts > 0)
 | |
|             {
 | |
|               part_info->num_parts= count_curr_parts;
 | |
|             }
 | |
|             part_info->count_curr_subparts= 0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_def_list:
 | |
|           part_definition {}
 | |
|         | part_def_list ',' part_definition {}
 | |
|         ;
 | |
| 
 | |
| opt_partition:
 | |
|           /* empty */
 | |
|           | PARTITION_SYM
 | |
|           ;
 | |
| 
 | |
| part_definition:
 | |
|           opt_partition
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             partition_element *p_elem= new (thd) partition_element();
 | |
| 
 | |
|             if (unlikely(!p_elem) ||
 | |
|                 unlikely(part_info->partitions.push_back(p_elem, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             p_elem->part_state= PART_NORMAL;
 | |
|             p_elem->id= part_info->partitions.elements - 1;
 | |
|             part_info->curr_part_elem= p_elem;
 | |
|             part_info->current_partition= p_elem;
 | |
|             part_info->use_default_partitions= FALSE;
 | |
|             part_info->use_default_num_partitions= FALSE;
 | |
|           }
 | |
|           part_name
 | |
|           opt_part_values
 | |
|           opt_part_options
 | |
|           opt_sub_partition
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| part_name:
 | |
|           ident
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             partition_element *p_elem= part_info->curr_part_elem;
 | |
|             if (unlikely(check_ident_length(&$1)))
 | |
|               MYSQL_YYABORT;
 | |
|             p_elem->partition_name= Lex_ident_partition($1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_part_values:
 | |
|           /* empty */
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             if (! lex->is_partition_management())
 | |
|             {
 | |
|               if (unlikely(part_info->error_if_requires_values()))
 | |
|                 MYSQL_YYABORT;
 | |
|               if (unlikely(part_info->part_type == VERSIONING_PARTITION))
 | |
|                 my_yyabort_error((ER_VERS_WRONG_PARTS, MYF(0),
 | |
|                                   lex->create_last_non_select_table->
 | |
|                                   table_name.str));
 | |
|             }
 | |
|             else
 | |
|               part_info->part_type= HASH_PARTITION;
 | |
|           }
 | |
|         | VALUES_LESS_SYM THAN_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             if (! lex->is_partition_management())
 | |
|             {
 | |
|               if (unlikely(part_info->part_type != RANGE_PARTITION))
 | |
|                 my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
 | |
|                                   "RANGE", "LESS THAN"));
 | |
|             }
 | |
|             else
 | |
|               part_info->part_type= RANGE_PARTITION;
 | |
|           }
 | |
|           part_func_max {}
 | |
|         | VALUES_IN_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             if (! lex->is_partition_management())
 | |
|             {
 | |
|               if (unlikely(part_info->part_type != LIST_PARTITION))
 | |
|                 my_yyabort_error((ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
 | |
|                                   "LIST", "IN"));
 | |
|             }
 | |
|             else
 | |
|               part_info->part_type= LIST_PARTITION;
 | |
|           }
 | |
|           part_values_in {}
 | |
|         | CURRENT_SYM
 | |
|           {
 | |
| #ifdef WITH_PARTITION_STORAGE_ENGINE
 | |
|             if (Lex->part_values_current(thd))
 | |
|               MYSQL_YYABORT;
 | |
| #endif
 | |
|           }
 | |
|         | HISTORY_SYM
 | |
|           {
 | |
| #ifdef WITH_PARTITION_STORAGE_ENGINE
 | |
|             if (Lex->part_values_history(thd))
 | |
|               MYSQL_YYABORT;
 | |
| #endif
 | |
|           }
 | |
|         | DEFAULT
 | |
|          {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             if (! lex->is_partition_management())
 | |
|             {
 | |
|               if (unlikely(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 (unlikely(part_info->init_column_part(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(part_info->add_max_value(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|          }
 | |
|         ;
 | |
| 
 | |
| part_func_max:
 | |
|           MAXVALUE_SYM
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
| 
 | |
|             if (unlikely(part_info->num_columns &&
 | |
|                          part_info->num_columns != 1U))
 | |
|             {
 | |
|               part_info->print_debug("Kilroy II", NULL);
 | |
|               thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             else
 | |
|               part_info->num_columns= 1U;
 | |
|             if (unlikely(part_info->init_column_part(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(part_info->add_max_value(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | part_value_item {}
 | |
|         ;
 | |
| 
 | |
| part_values_in:
 | |
|           part_value_item
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             part_info->print_debug("part_values_in: part_value_item", NULL);
 | |
| 
 | |
|             if (part_info->num_columns != 1U)
 | |
|             {
 | |
|               if (unlikely(!lex->is_partition_management() ||
 | |
|                            part_info->num_columns == 0 ||
 | |
|                            part_info->num_columns > MAX_REF_PARTS))
 | |
|               {
 | |
|                 part_info->print_debug("Kilroy III", NULL);
 | |
|                 thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR);
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|               /*
 | |
|                 Reorganize the current large array into a list of small
 | |
|                 arrays with one entry in each array. This can happen
 | |
|                 in the first partition of an ALTER TABLE statement where
 | |
|                 we ADD or REORGANIZE partitions. Also can only happen
 | |
|                 for LIST partitions.
 | |
|               */
 | |
|               if (unlikely(part_info->reorganize_into_single_field_col_val(thd)))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | '(' part_value_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->num_columns < 2U))
 | |
|             {
 | |
|               thd->parse_error(ER_ROW_SINGLE_PARTITION_FIELD_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_value_list:
 | |
|           part_value_item {}
 | |
|         | part_value_list ',' part_value_item {}
 | |
|         ;
 | |
| 
 | |
| part_value_item:
 | |
|           '('
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->print_debug("( part_value_item", NULL);
 | |
|             /* Initialisation code needed for each list of value expressions */
 | |
|             if (unlikely(!(part_info->part_type == LIST_PARTITION &&
 | |
|                            part_info->num_columns == 1U) &&
 | |
|                            part_info->init_column_part(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           part_value_item_list {}
 | |
|           ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->print_debug(") part_value_item", NULL);
 | |
|             if (part_info->num_columns == 0)
 | |
|               part_info->num_columns= part_info->curr_list_object;
 | |
|             if (unlikely(part_info->num_columns != part_info->curr_list_object))
 | |
|             {
 | |
|               /*
 | |
|                 All value items lists must be of equal length, in some cases
 | |
|                 which is covered by the above if-statement we don't know yet
 | |
|                 how many columns is in the partition so the assignment above
 | |
|                 ensures that we only report errors when we know we have an
 | |
|                 error.
 | |
|               */
 | |
|               part_info->print_debug("Kilroy I", NULL);
 | |
|               thd->parse_error(ER_PARTITION_COLUMN_LIST_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             part_info->curr_list_object= 0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| part_value_item_list:
 | |
|           part_value_expr_item {}
 | |
|         | part_value_item_list ',' part_value_expr_item {}
 | |
|         ;
 | |
| 
 | |
| part_value_expr_item:
 | |
|           MAXVALUE_SYM
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->part_type == LIST_PARTITION))
 | |
|             {
 | |
|               thd->parse_error(ER_MAXVALUE_IN_VALUES_IN);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (unlikely(part_info->add_max_value(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             partition_info *part_info= lex->part_info;
 | |
|             Item *part_expr= $1;
 | |
| 
 | |
|             if (unlikely(!lex->safe_to_cache_query))
 | |
|             {
 | |
|               thd->parse_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (unlikely(part_info->add_column_list_value(thd, part_expr)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_sub_partition:
 | |
|           /* empty */
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (unlikely(part_info->num_subparts != 0 &&
 | |
|                          !part_info->use_default_subpartitions))
 | |
|             {
 | |
|               /*
 | |
|                 We come here when we have defined subpartitions on the first
 | |
|                 partition but not on all the subsequent partitions. 
 | |
|               */
 | |
|               thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | '(' sub_part_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             if (part_info->num_subparts != 0)
 | |
|             {
 | |
|               if (unlikely(part_info->num_subparts !=
 | |
|                            part_info->count_curr_subparts))
 | |
|               {
 | |
|                 thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR);
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|             }
 | |
|             else if (part_info->count_curr_subparts > 0)
 | |
|             {
 | |
|               if (unlikely(part_info->partitions.elements > 1))
 | |
|               {
 | |
|                 thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR);
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|               part_info->num_subparts= part_info->count_curr_subparts;
 | |
|             }
 | |
|             part_info->count_curr_subparts= 0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sub_part_list:
 | |
|           sub_part_definition {}
 | |
|         | sub_part_list ',' sub_part_definition {}
 | |
|         ;
 | |
| 
 | |
| sub_part_definition:
 | |
|           SUBPARTITION_SYM
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             partition_element *curr_part= part_info->current_partition;
 | |
|             partition_element *sub_p_elem= new (thd)
 | |
|                                            partition_element(curr_part);
 | |
|             if (unlikely(part_info->use_default_subpartitions &&
 | |
|                          part_info->partitions.elements >= 2))
 | |
|             {
 | |
|               /*
 | |
|                 create table t1 (a int)
 | |
|                 partition by list (a) subpartition by hash (a)
 | |
|                 (partition p0 values in (1),
 | |
|                  partition p1 values in (2) subpartition sp11);
 | |
|                 causes use to arrive since we are on the second
 | |
|                 partition, but still use_default_subpartitions
 | |
|                 is set. When we come here we're processing at least
 | |
|                 the second partition (the current partition processed
 | |
|                 have already been put into the partitions list.
 | |
|               */
 | |
|               thd->parse_error(ER_PARTITION_WRONG_NO_SUBPART_ERROR);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (unlikely(!sub_p_elem) ||
 | |
|                 unlikely(curr_part->subpartitions.push_back(sub_p_elem, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             sub_p_elem->id= curr_part->subpartitions.elements - 1;
 | |
|             part_info->curr_part_elem= sub_p_elem;
 | |
|             part_info->use_default_subpartitions= FALSE;
 | |
|             part_info->use_default_num_subpartitions= FALSE;
 | |
|             part_info->count_curr_subparts++;
 | |
|           }
 | |
|           sub_name opt_subpart_options {}
 | |
|         ;
 | |
| 
 | |
| sub_name:
 | |
|           ident_or_text
 | |
|           {
 | |
|             if (unlikely(check_ident_length(&$1)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->part_info->curr_part_elem->partition_name=
 | |
|               Lex_ident_partition($1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_part_options:
 | |
|          /* empty */ {}
 | |
|        | part_option_list {}
 | |
|        ;
 | |
| 
 | |
| part_option_list:
 | |
|          part_option_list part_option {}
 | |
|        | part_option {}
 | |
|        ;
 | |
| 
 | |
| part_option:
 | |
|           server_part_option {}
 | |
|         | engine_defined_option
 | |
|           {
 | |
|             $1->link(&Lex->part_info->curr_part_elem->option_list,
 | |
|                      &Lex->option_list_last);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_subpart_options:
 | |
|          /* empty */ {}
 | |
|        | subpart_option_list {}
 | |
|        ;
 | |
| 
 | |
| subpart_option_list:
 | |
|          subpart_option_list server_part_option {}
 | |
|        | server_part_option {}
 | |
|        ;
 | |
| 
 | |
| server_part_option:
 | |
|           TABLESPACE opt_equal ident_or_text
 | |
|           { /* Compatibility with MySQL */ }
 | |
|         | opt_storage ENGINE_SYM opt_equal storage_engines
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->curr_part_elem->engine_type= $4;
 | |
|             part_info->default_engine_type= $4;
 | |
|           }
 | |
|         | CONNECTION_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->part_info->curr_part_elem->connect_string.str= $3.str;
 | |
|             lex->part_info->curr_part_elem->connect_string.length= $3.length;
 | |
|           }
 | |
|         | NODEGROUP_SYM opt_equal real_ulong_num
 | |
|           { Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; }
 | |
|         | MAX_ROWS opt_equal real_ulonglong_num
 | |
|           { Lex->part_info->curr_part_elem->part_max_rows= (ha_rows) $3; }
 | |
|         | MIN_ROWS opt_equal real_ulonglong_num
 | |
|           { Lex->part_info->curr_part_elem->part_min_rows= (ha_rows) $3; }
 | |
|         | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
 | |
|           { Lex->part_info->curr_part_elem->data_file_name= $4.str; }
 | |
|         | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
 | |
|           { Lex->part_info->curr_part_elem->index_file_name= $4.str; }
 | |
|         | COMMENT_SYM opt_equal TEXT_STRING_sys
 | |
|           { Lex->part_info->curr_part_elem->part_comment= $3.str; }
 | |
|         ;
 | |
| 
 | |
| opt_versioning_rotation:
 | |
|          /* empty */ {}
 | |
|        | { Lex->clause_that_disallows_subselect= "INTERVAL"; }
 | |
|          INTERVAL_SYM expr interval opt_versioning_interval_start opt_vers_auto_part
 | |
|          {
 | |
|            partition_info *part_info= Lex->part_info;
 | |
|            const char *table_name= Lex->create_last_non_select_table->table_name.str;
 | |
|            if (unlikely(part_info->vers_set_interval(thd, $3, $4, $5, $6,
 | |
|                                                      table_name)))
 | |
|              MYSQL_YYABORT;
 | |
|          }
 | |
|        | LIMIT ulonglong_num opt_vers_auto_part
 | |
|          {
 | |
|            partition_info *part_info= Lex->part_info;
 | |
|            const char *table_name= Lex->create_last_non_select_table->table_name.str;
 | |
|            if (unlikely(part_info->vers_set_limit($2, $3, table_name)))
 | |
|              MYSQL_YYABORT;
 | |
|          }
 | |
|        ;
 | |
| 
 | |
| 
 | |
| opt_versioning_interval_start:
 | |
|          /* empty */
 | |
|          {
 | |
|            $$= NULL;
 | |
|          }
 | |
|        | STARTS_SYM literal
 | |
|          {
 | |
|            $$= $2;
 | |
|          }
 | |
|        ;
 | |
| 
 | |
| opt_vers_auto_part:
 | |
|          /* empty */
 | |
|          {
 | |
|            $$= 0;
 | |
|          }
 | |
|        | AUTO_SYM
 | |
|          {
 | |
|            $$= 1;
 | |
|          }
 | |
|        ;
 | |
| /*
 | |
|  End of partition parser part
 | |
| */
 | |
| 
 | |
| opt_as:
 | |
|           /* empty */ {}
 | |
|         | AS {}
 | |
|         ;
 | |
| 
 | |
| opt_create_database_options:
 | |
|           /* empty */ {}
 | |
|         | create_database_options {}
 | |
|         ;
 | |
| 
 | |
| create_database_options:
 | |
|           create_database_option {}
 | |
|         | create_database_options create_database_option {}
 | |
|         ;
 | |
| 
 | |
| create_database_option:
 | |
|           default_collation {}
 | |
|         | default_charset {}
 | |
|         | COMMENT_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.schema_comment= thd->make_clex_string($3);
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_if_not_exists_table_element:
 | |
|           /* empty */
 | |
|           {
 | |
|             Lex->check_exists= FALSE;
 | |
|           }
 | |
|         | IF_SYM not EXISTS
 | |
|           {
 | |
|             Lex->check_exists= TRUE;
 | |
|           }
 | |
|          ;
 | |
| 
 | |
| opt_if_not_exists:
 | |
|           /* empty */        %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|           {
 | |
|             $$.init();
 | |
|           }
 | |
|         | IF_SYM not EXISTS
 | |
|           {
 | |
|             $$.set(DDL_options_st::OPT_IF_NOT_EXISTS);
 | |
|           }
 | |
|          ;
 | |
| 
 | |
| create_or_replace:
 | |
|           CREATE /* empty */
 | |
|           {
 | |
|             $$.init();
 | |
|           }
 | |
|         | CREATE OR_SYM REPLACE
 | |
|           {
 | |
|             $$.set(DDL_options_st::OPT_OR_REPLACE);
 | |
|           }
 | |
|          ;
 | |
| 
 | |
| opt_create_table_options:
 | |
|           /* empty */
 | |
|         | create_table_options
 | |
|         ;
 | |
| 
 | |
| create_table_options_space_separated:
 | |
|           create_table_option
 | |
|         | create_table_option create_table_options_space_separated
 | |
|         ;
 | |
| 
 | |
| create_table_options:
 | |
|           create_table_option
 | |
|         | create_table_option     create_table_options
 | |
|         | create_table_option ',' create_table_options
 | |
|         ;
 | |
| 
 | |
| create_table_option:
 | |
|           ENGINE_SYM opt_equal ident_or_text
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (!lex->m_sql_cmd)
 | |
|             {
 | |
|               DBUG_ASSERT(lex->sql_command == SQLCOM_ALTER_TABLE);
 | |
|               if (!(lex->m_sql_cmd= new (thd) Sql_cmd_alter_table()))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             Storage_engine_name *opt=
 | |
|               lex->m_sql_cmd->option_storage_engine_name();
 | |
|             DBUG_ASSERT(opt); // Expect a proper Sql_cmd
 | |
|             *opt= Storage_engine_name($3);
 | |
|             lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
 | |
|           }
 | |
|         | MAX_ROWS opt_equal ulonglong_num
 | |
|           {
 | |
|             Lex->create_info.max_rows= $3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;
 | |
|           }
 | |
|         | MIN_ROWS opt_equal ulonglong_num
 | |
|           {
 | |
|             Lex->create_info.min_rows= $3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;
 | |
|           }
 | |
|         | AVG_ROW_LENGTH opt_equal ulong_num
 | |
|           {
 | |
|             Lex->create_info.avg_row_length=$3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;
 | |
|           }
 | |
|         | PASSWORD_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.password=$3.str;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD;
 | |
|           }
 | |
|         | COMMENT_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.comment=$3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
 | |
|           }
 | |
|         | AUTO_INC opt_equal ulonglong_num
 | |
|           {
 | |
|             Lex->create_info.auto_increment_value=$3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;
 | |
|           }
 | |
|         | PACK_KEYS_SYM opt_equal ulong_num
 | |
|           {
 | |
|             switch($3) {
 | |
|             case 0:
 | |
|                 Lex->create_info.table_options|= HA_OPTION_NO_PACK_KEYS;
 | |
|                 break;
 | |
|             case 1:
 | |
|                 Lex->create_info.table_options|= HA_OPTION_PACK_KEYS;
 | |
|                 break;
 | |
|             default:
 | |
|                 thd->parse_error();
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
 | |
|           }
 | |
|         | PACK_KEYS_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->create_info.table_options&=
 | |
|               ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
 | |
|           }
 | |
|         | STATS_AUTO_RECALC_SYM opt_equal ulong_num
 | |
|           {
 | |
|             switch($3) {
 | |
|             case 0:
 | |
|                 Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_OFF;
 | |
|                 break;
 | |
|             case 1:
 | |
|                 Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_ON;
 | |
|                 break;
 | |
|             default:
 | |
|                 thd->parse_error();
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
 | |
|           }
 | |
|         | STATS_AUTO_RECALC_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_DEFAULT;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
 | |
|           }
 | |
|         | STATS_PERSISTENT_SYM opt_equal ulong_num
 | |
|           {
 | |
|             switch($3) {
 | |
|             case 0:
 | |
|                 Lex->create_info.table_options|= HA_OPTION_NO_STATS_PERSISTENT;
 | |
|                 break;
 | |
|             case 1:
 | |
|                 Lex->create_info.table_options|= HA_OPTION_STATS_PERSISTENT;
 | |
|                 break;
 | |
|             default:
 | |
|                 thd->parse_error();
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
 | |
|           }
 | |
|         | STATS_PERSISTENT_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->create_info.table_options&=
 | |
|               ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
 | |
|           }
 | |
|         | STATS_SAMPLE_PAGES_SYM opt_equal ulong_num
 | |
|           {
 | |
|             /* From user point of view STATS_SAMPLE_PAGES can be specified as
 | |
|             STATS_SAMPLE_PAGES=N (where 0<N<=65535, it does not make sense to
 | |
|             scan 0 pages) or STATS_SAMPLE_PAGES=default. Internally we record
 | |
|             =default as 0. See create_frm() in sql/table.cc, we use only two
 | |
|             bytes for stats_sample_pages and this is why we do not allow
 | |
|             larger values. 65535 pages, 16kb each means to sample 1GB, which
 | |
|             is impractical. If at some point this needs to be extended, then
 | |
|             we can store the higher bits from stats_sample_pages in .frm too. */
 | |
|             if (unlikely($3 == 0 || $3 > 0xffff))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->create_info.stats_sample_pages=$3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
 | |
|           }
 | |
|         | STATS_SAMPLE_PAGES_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->create_info.stats_sample_pages=0;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
 | |
|           }
 | |
|         | CHECKSUM_SYM opt_equal ulong_num
 | |
|           {
 | |
|             Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
 | |
|           }
 | |
|         | TABLE_CHECKSUM_SYM opt_equal ulong_num
 | |
|           {
 | |
|              Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
 | |
|              Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
 | |
|           }
 | |
|         | PAGE_CHECKSUM_SYM opt_equal choice
 | |
|           {
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_PAGE_CHECKSUM;
 | |
|             Lex->create_info.page_checksum= $3;
 | |
|           }
 | |
|         | DELAY_KEY_WRITE_SYM opt_equal ulong_num
 | |
|           {
 | |
|             Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE;
 | |
|           }
 | |
|         | ROW_FORMAT_SYM opt_equal row_types
 | |
|           {
 | |
|             Lex->create_info.row_type= $3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
 | |
|           }
 | |
|         | UNION_SYM opt_equal
 | |
|           {
 | |
|             Lex->first_select_lex()->table_list.save_and_clear(&Lex->save_list);
 | |
|           }
 | |
|           '(' opt_table_list ')'
 | |
|           {
 | |
|             /*
 | |
|               Move the union list to the merge_list and exclude its tables
 | |
|               from the global list.
 | |
|             */
 | |
|             LEX *lex=Lex;
 | |
|             lex->create_info.merge_list= lex->first_select_lex()->table_list.first;
 | |
|             lex->first_select_lex()->table_list= lex->save_list;
 | |
|             /*
 | |
|               When excluding union list from the global list we assume that
 | |
|               elements of the former immediately follow elements which represent
 | |
|               table being created/altered and parent tables.
 | |
|             */
 | |
|             TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
 | |
|             DBUG_ASSERT(last_non_sel_table->next_global ==
 | |
|                         lex->create_info.merge_list);
 | |
|             last_non_sel_table->next_global= 0;
 | |
|             Lex->query_tables_last= &last_non_sel_table->next_global;
 | |
| 
 | |
|             lex->create_info.used_fields|= HA_CREATE_USED_UNION;
 | |
|           }
 | |
|         | default_charset
 | |
|         | default_collation
 | |
|         | INSERT_METHOD opt_equal merge_insert_types
 | |
|           {
 | |
|             Lex->create_info.merge_insert_method= $3;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;
 | |
|           }
 | |
|         | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.data_file_name= $4.str;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR;
 | |
|           }
 | |
|         | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.index_file_name= $4.str;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR;
 | |
|           }
 | |
|         | TABLESPACE ident
 | |
|           { /* Compatiblity with MySQL */ }
 | |
|         | STORAGE_SYM DISK_SYM
 | |
|           {Lex->create_info.storage_media= HA_SM_DISK;}
 | |
|         | STORAGE_SYM MEMORY_SYM
 | |
|           {Lex->create_info.storage_media= HA_SM_MEMORY;}
 | |
|         | CONNECTION_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.connect_string.str= $3.str;
 | |
|             Lex->create_info.connect_string.length= $3.length;
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION;
 | |
|           }
 | |
|         | KEY_BLOCK_SIZE opt_equal ulong_num
 | |
|           {
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
 | |
|             Lex->create_info.key_block_size= $3;
 | |
|           }
 | |
|         | TRANSACTIONAL_SYM opt_equal choice
 | |
|           {
 | |
| 	    Lex->create_info.used_fields|= HA_CREATE_USED_TRANSACTIONAL;
 | |
|             Lex->create_info.transactional= $3;
 | |
|           }
 | |
|         | engine_defined_option
 | |
|           {
 | |
|             $1->link(&Lex->create_info.option_list, &Lex->option_list_last);
 | |
|           }
 | |
|         | SEQUENCE_SYM opt_equal choice
 | |
|           {
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_SEQUENCE;
 | |
|             Lex->create_info.sequence= ($3 == HA_CHOICE_YES);
 | |
|           }
 | |
|         | versioning_option
 | |
|         ;
 | |
| 
 | |
| engine_defined_option:
 | |
|           ident_options equal TEXT_STRING_sys
 | |
|           {
 | |
|             if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH))
 | |
|               my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
 | |
|             $$= new (thd) engine_option_value(
 | |
|                                       engine_option_value::Name($1),
 | |
|                                       engine_option_value::Value($3), true);
 | |
|             MYSQL_YYABORT_UNLESS($$);
 | |
|           }
 | |
|         | ident_options equal ident
 | |
|           {
 | |
|             if (unlikely($3.length > ENGINE_OPTION_MAX_LENGTH))
 | |
|               my_yyabort_error((ER_VALUE_TOO_LONG, MYF(0), $1.str));
 | |
|             $$= new (thd) engine_option_value(
 | |
|                                       engine_option_value::Name($1),
 | |
|                                       engine_option_value::Value($3), false);
 | |
|             MYSQL_YYABORT_UNLESS($$);
 | |
|           }
 | |
|         | ident_options equal real_ulonglong_num
 | |
|           {
 | |
|             $$= new (thd) engine_option_value(
 | |
|                                       engine_option_value::Name($1),
 | |
|                                       $3, thd->mem_root);
 | |
|             MYSQL_YYABORT_UNLESS($$);
 | |
|           }
 | |
|         | ident_options equal DEFAULT
 | |
|           {
 | |
|             $$= new (thd) engine_option_value(
 | |
|                                       engine_option_value::Name($1));
 | |
|             MYSQL_YYABORT_UNLESS($$);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_options:
 | |
|           IDENT_sys
 | |
|         | keyword_options
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   These keywords are fine for option names.
 | |
| */
 | |
| keyword_options:
 | |
|           READ_ONLY_SYM
 | |
|         | WRAPPER_SYM
 | |
|         ;
 | |
| 
 | |
| opt_versioning_option:
 | |
|           /* empty */
 | |
|         | versioning_option
 | |
|         ;
 | |
| 
 | |
| versioning_option:
 | |
|         WITH_SYSTEM_SYM VERSIONING_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
 | |
|             {
 | |
|               if (!DBUG_IF("sysvers_force"))
 | |
|               {
 | |
|                 my_error(ER_VERS_NOT_SUPPORTED, MYF(0), "CREATE TEMPORARY TABLE");
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               Lex->alter_info.flags|= ALTER_ADD_SYSTEM_VERSIONING;
 | |
|               Lex->create_info.options|= HA_VERSIONED_TABLE;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| default_charset:
 | |
|           opt_default charset opt_equal charset_name_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->create_info.add_table_option_default_charset(
 | |
|                            thd, thd->variables.character_set_collations, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| default_collation:
 | |
|           opt_default COLLATE_SYM opt_equal collation_name_or_default
 | |
|           {
 | |
|             Table_specification_st *cinfo= &Lex->create_info;
 | |
|             if (unlikely(cinfo->add_table_option_default_collation(
 | |
|                            thd, thd->variables.character_set_collations, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| storage_engines:
 | |
|           ident_or_text
 | |
|           {
 | |
|             if (Storage_engine_name($1).
 | |
|                  resolve_storage_engine_with_error(thd, &$$,
 | |
|                                             thd->lex->create_info.tmp_table()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| known_storage_engines:
 | |
|           ident_or_text
 | |
|           {
 | |
|             plugin_ref plugin;
 | |
|             if (likely((plugin= ha_resolve_by_name(thd, &$1, false))))
 | |
|               $$= plugin_hton(plugin);
 | |
|             else
 | |
|               my_yyabort_error((ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| row_types:
 | |
|           DEFAULT        { $$= ROW_TYPE_DEFAULT; }
 | |
|         | FIXED_SYM      { $$= ROW_TYPE_FIXED; }
 | |
|         | DYNAMIC_SYM    { $$= ROW_TYPE_DYNAMIC; }
 | |
|         | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
 | |
|         | REDUNDANT_SYM  { $$= ROW_TYPE_REDUNDANT; }
 | |
|         | COMPACT_SYM    { $$= ROW_TYPE_COMPACT; }
 | |
|         | PAGE_SYM       { $$= ROW_TYPE_PAGE; }
 | |
|         ;
 | |
| 
 | |
| merge_insert_types:
 | |
|          NO_SYM          { $$= MERGE_INSERT_DISABLED; }
 | |
|        | FIRST_SYM       { $$= MERGE_INSERT_TO_FIRST; }
 | |
|        | LAST_SYM        { $$= MERGE_INSERT_TO_LAST; }
 | |
|        ;
 | |
| 
 | |
| udf_type:
 | |
|           STRING_SYM {$$ = (int) STRING_RESULT; }
 | |
|         | REAL {$$ = (int) REAL_RESULT; }
 | |
|         | DECIMAL_SYM {$$ = (int) DECIMAL_RESULT; }
 | |
|         | INT_SYM {$$ = (int) INT_RESULT; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| create_field_list:
 | |
|         field_list
 | |
|         {
 | |
|           Lex->create_last_non_select_table= Lex->last_table();
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| create_field_list_parens:
 | |
|         LEFT_PAREN_ALT field_list ')'
 | |
|         {
 | |
|           Lex->create_last_non_select_table= Lex->last_table();
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| field_list:
 | |
|           field_list_item
 | |
|         | field_list ',' field_list_item
 | |
|         ;
 | |
| 
 | |
| field_list_item:
 | |
|           column_def { }
 | |
|         | key_def
 | |
|         | constraint_def
 | |
|         | period_for_system_time
 | |
|         | PERIOD_SYM period_for_application_time { }
 | |
|         ;
 | |
| 
 | |
| column_def:
 | |
|           field_spec
 | |
|           { $$= $1; }
 | |
|         | field_spec opt_constraint references
 | |
|           {
 | |
|             if (unlikely(Lex->add_column_foreign_key(&($1->field_name), &$2,
 | |
|                                                      $3, DDL_options())))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| key_def:
 | |
|           key_or_index opt_if_not_exists opt_ident opt_USING_key_algorithm
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $4, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list ')' normal_key_options { }
 | |
|         | key_or_index opt_if_not_exists ident TYPE_SYM btree_or_rtree
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key(Key::MULTIPLE, &$3, $5, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list ')' normal_key_options { }
 | |
|         | fulltext opt_key_or_index opt_if_not_exists opt_ident
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list ')' fulltext_key_options { }
 | |
|         | spatial_or_vector opt_key_or_index opt_if_not_exists opt_ident
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key($1, &$4, HA_KEY_ALG_UNDEF, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_part_simple ')' spatial_key_options
 | |
|           {
 | |
|             Lex->last_key->columns.push_back($7, thd->mem_root);
 | |
|           }
 | |
|         | opt_constraint constraint_key_type
 | |
|           opt_if_not_exists opt_ident
 | |
|           opt_USING_key_algorithm
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $5, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list opt_without_overlaps ')' normal_key_options { }
 | |
|         | opt_constraint constraint_key_type opt_if_not_exists ident
 | |
|           TYPE_SYM btree_or_rtree
 | |
|           {
 | |
|             Lex->option_list= NULL;
 | |
|             if (unlikely(Lex->add_key($2, $4.str ? &$4 : &$1, $6, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' key_list opt_without_overlaps ')' normal_key_options { }
 | |
|         | opt_constraint FOREIGN KEY_SYM opt_if_not_exists opt_ident
 | |
|           {
 | |
|             if (unlikely(Lex->check_add_key($4)) ||
 | |
|                 unlikely(!(Lex->last_key= (new (thd)
 | |
|                                            Key(Key::MULTIPLE,
 | |
|                                            $1.str ? &$1 : &$5,
 | |
|                                            HA_KEY_ALG_UNDEF, true, $4)))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->option_list= NULL;
 | |
|           }
 | |
|           '(' key_list ')' references
 | |
|           {
 | |
|             if (unlikely(Lex->add_table_foreign_key($5.str ? &$5 : &$1,
 | |
|                                                     $1.str ? &$1 : &$5, $10, $4)))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
| 	;
 | |
| 
 | |
| constraint_def:
 | |
|          opt_constraint check_constraint
 | |
|          {
 | |
|            Lex->add_constraint($1, $2, FALSE);
 | |
|          }
 | |
|        ;
 | |
| 
 | |
| period_for_system_time:
 | |
|           // If FOR_SYM is followed by SYSTEM_TIME_SYM then they are merged to: FOR_SYSTEM_TIME_SYM .
 | |
|           PERIOD_SYM FOR_SYSTEM_TIME_SYM '(' ident ',' ident ')'
 | |
|           {
 | |
|             Vers_parse_info &info= Lex->vers_get_info();
 | |
|             info.set_period(Lex_ident_column($4), Lex_ident_column($6));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| period_for_application_time:
 | |
|           FOR_SYM ident '(' ident ',' ident ')'
 | |
|           {
 | |
|             if (Lex->add_period(Lex_ident_column($2), $4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_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 (unlikely(!v))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= v;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_constraint_no_id:
 | |
|           /* Empty */  {}
 | |
|         | CONSTRAINT   {}
 | |
|         ;
 | |
| 
 | |
| opt_constraint:
 | |
|           /* empty */ { $$= null_clex_str; }
 | |
|         | constraint { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| constraint:
 | |
|           CONSTRAINT opt_ident { $$=$2; }
 | |
|         ;
 | |
| 
 | |
| field_spec:
 | |
|           field_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Create_field *f= new (thd) Create_field();
 | |
| 
 | |
|             if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN,
 | |
|                                                   system_charset_info, 1)))
 | |
|               my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str));
 | |
| 
 | |
|             if (unlikely(!f))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->init_last_field(f, &$1);
 | |
|             $<create_field>$= f;
 | |
|             lex->parsing_options.lookup_keywords_after_qualifier= true;
 | |
|           }
 | |
|           field_type_or_serial opt_check_constraint
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->parsing_options.lookup_keywords_after_qualifier= false;
 | |
|             $$= $<create_field>2;
 | |
| 
 | |
|             $$->check_constraint= $4;
 | |
| 
 | |
|             if (unlikely($$->check(thd)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->alter_info.create_list.push_back($$, thd->mem_root);
 | |
| 
 | |
|             $$->create_if_not_exists= Lex->check_exists;
 | |
|             if ($$->flags & PRI_KEY_FLAG)
 | |
|               lex->add_key_to_list(&$1, Key::PRIMARY, lex->check_exists);
 | |
|             else if ($$->flags & UNIQUE_KEY_FLAG)
 | |
|               lex->add_key_to_list(&$1, Key::UNIQUE, lex->check_exists);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type_or_serial:
 | |
|           qualified_field_type
 | |
|           {
 | |
|              Lex->last_field->set_attributes(thd, $1,
 | |
|                                              COLUMN_DEFINITION_TABLE_FIELD);
 | |
|           }
 | |
|           field_def
 | |
|           {
 | |
|             auto tmp= $1.charset_collation_attrs();
 | |
|             if (tmp.merge_column_charset_clause_and_collate_clause(
 | |
|                      thd, thd->variables.character_set_collations, $3))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->last_field->set_charset_collation_attrs(
 | |
|                                thd, thd->variables.character_set_collations,
 | |
|                                tmp);
 | |
|           }
 | |
|         | SERIAL_SYM
 | |
|           {
 | |
|             Lex->last_field->set_handler(&type_handler_ulonglong);
 | |
|             Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG
 | |
|                                      | UNSIGNED_FLAG | UNIQUE_KEY_FLAG;
 | |
|             Lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|           }
 | |
|           opt_serial_attribute
 | |
|         ;
 | |
| 
 | |
| opt_serial_attribute:
 | |
|           /* empty */ {}
 | |
|         | opt_serial_attribute_list {}
 | |
|         ;
 | |
| 
 | |
| opt_serial_attribute_list:
 | |
|           opt_serial_attribute_list serial_attribute {}
 | |
|         | serial_attribute
 | |
|         ;
 | |
| 
 | |
| opt_asrow_attribute:
 | |
|           /* empty */ {}
 | |
|         | opt_asrow_attribute_list {}
 | |
|         ;
 | |
| 
 | |
| opt_asrow_attribute_list:
 | |
|           opt_asrow_attribute_list asrow_attribute {}
 | |
|         | asrow_attribute
 | |
|         ;
 | |
| 
 | |
| field_def:
 | |
|           /* empty */     { $$.init(); }
 | |
|         | attribute_list
 | |
|         | opt_generated_always AS virtual_column_func
 | |
|          {
 | |
|            Lex->last_field->vcol_info= $3;
 | |
|          }
 | |
|           vcol_opt_specifier vcol_opt_attribute
 | |
|           {
 | |
|             $$.init();
 | |
|           }
 | |
|         | opt_generated_always AS ROW_SYM START_SYM opt_asrow_attribute
 | |
|           {
 | |
|             if (Lex->last_field_generated_always_as_row_start())
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init();
 | |
|           }
 | |
|         | opt_generated_always AS ROW_SYM END opt_asrow_attribute
 | |
|           {
 | |
|             if (Lex->last_field_generated_always_as_row_end())
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_generated_always:
 | |
|           /* empty */ {}
 | |
|         | GENERATED_SYM ALWAYS_SYM {}
 | |
|         ;
 | |
| 
 | |
| vcol_opt_specifier:
 | |
|           /* empty */
 | |
|           {
 | |
|             Lex->last_field->vcol_info->set_vcol_type(VCOL_GENERATED_VIRTUAL);
 | |
|           }
 | |
|         | VIRTUAL_SYM
 | |
|           {
 | |
|             Lex->last_field->vcol_info->set_vcol_type(VCOL_GENERATED_VIRTUAL);
 | |
|           }
 | |
|         | PERSISTENT_SYM
 | |
|           {
 | |
|             Lex->last_field->vcol_info->set_vcol_type(VCOL_GENERATED_STORED);
 | |
|           }
 | |
|         | STORED_SYM
 | |
|           {
 | |
|             Lex->last_field->vcol_info->set_vcol_type(VCOL_GENERATED_STORED);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| vcol_opt_attribute:
 | |
|           /* empty */ {}
 | |
|         | vcol_opt_attribute_list {}
 | |
|         ;
 | |
| 
 | |
| vcol_opt_attribute_list:
 | |
|           vcol_opt_attribute_list vcol_attribute {}
 | |
|         | vcol_attribute
 | |
|         ;
 | |
| 
 | |
| vcol_attribute:
 | |
|           UNIQUE_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->last_field->flags|= UNIQUE_KEY_FLAG;
 | |
|             lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|           }
 | |
|         | UNIQUE_SYM KEY_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->last_field->flags|= UNIQUE_KEY_FLAG;
 | |
|             lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|           }
 | |
|         | COMMENT_SYM TEXT_STRING_sys { Lex->last_field->comment= $2; }
 | |
|         | INVISIBLE_SYM
 | |
|           {
 | |
|             Lex->last_field->invisible= INVISIBLE_USER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| parse_vcol_expr:
 | |
|           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.
 | |
|             */
 | |
|             MYSQL_YYABORT_UNLESS(Lex->parse_vcol_expr);
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           expr
 | |
|           {
 | |
|             Virtual_column_info *v= add_virtual_expression(thd, $3);
 | |
|             if (unlikely(!v))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->last_field->vcol_info= v;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| parenthesized_expr:
 | |
|           expr
 | |
|         | expr ',' expr_list
 | |
|           {
 | |
|             $3->push_front($1, thd->mem_root);
 | |
|             $$= new (thd) Item_row(thd, *$3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| virtual_column_func:
 | |
|           '(' parenthesized_expr ')'
 | |
|           {
 | |
|             Virtual_column_info *v=
 | |
|               add_virtual_expression(thd, $2);
 | |
|             if (unlikely(!v))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= v;
 | |
|           }
 | |
|         | subquery
 | |
|           {
 | |
|             Item *item;
 | |
|             if (!(item= new (thd) Item_singlerow_subselect(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|             Virtual_column_info *v= add_virtual_expression(thd, item);
 | |
|             if (unlikely(!v))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= v;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| expr_or_literal: column_default_non_parenthesized_expr | signed_literal ;
 | |
| 
 | |
| column_default_expr:
 | |
|           virtual_column_func
 | |
|         | expr_or_literal
 | |
|           {
 | |
|             if (unlikely(!($$= add_virtual_expression(thd, $1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type: field_type_all
 | |
|         {
 | |
|           Lex->map_data_type(Lex_ident_sys(), &($$= $1));
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| qualified_field_type:
 | |
|           field_type_all
 | |
|           {
 | |
|             Lex->map_data_type(Lex_ident_sys(), &($$= $1));
 | |
|           }
 | |
|         | sp_decl_ident '.' field_type_all
 | |
|           {
 | |
|             if (Lex->map_data_type($1, &($$= $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| udt_name:
 | |
|           IDENT_sys                     { $$= $1; }
 | |
|         | reserved_keyword_udt          { $$= $1; }
 | |
|         | non_reserved_keyword_udt      { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| field_type_all_builtin:
 | |
|           field_type_numeric
 | |
|         | field_type_temporal
 | |
|         | field_type_string
 | |
|         | field_type_lob
 | |
|         | field_type_misc
 | |
|       ;
 | |
| 
 | |
| field_type_all:
 | |
|           field_type_all_builtin
 | |
|         | udt_name float_options srid_option
 | |
|           {
 | |
|             if (Lex->set_field_type_udt(&$$, $1, $2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type_all_with_record:
 | |
|           field_type_all_builtin
 | |
|           {
 | |
|             Lex->map_data_type(Lex_ident_sys(), &($$= $1));
 | |
|           }
 | |
|         | udt_name float_options srid_option
 | |
|           {
 | |
|             sp_record *sprec = NULL;
 | |
|             if (Lex->spcont)
 | |
|               sprec = Lex->spcont->find_record(&$1, false);
 | |
| 
 | |
|             if (sprec == NULL)
 | |
|             {
 | |
|               if (Lex->set_field_type_udt(&$$, $1, $2))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               $$.set(&type_handler_row, NULL);
 | |
|               Lex->last_field->set_attr_const_void_ptr(0, sprec);
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type_numeric:
 | |
|           int_type opt_field_length last_field_options
 | |
|           {
 | |
|             $$.set_handler_length_flags($1, $2, (uint32) $3);
 | |
|           }
 | |
|         | real_type opt_precision last_field_options   { $$.set($1, $2); }
 | |
|         | FLOAT_SYM float_options last_field_options
 | |
|           {
 | |
|             $$.set(&type_handler_float, $2);
 | |
|             if ($2.has_explicit_length() && !$2.has_explicit_dec())
 | |
|             {
 | |
|               if (unlikely($2.length() > PRECISION_FOR_DOUBLE))
 | |
|                 my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0),
 | |
|                                   Lex->last_field->field_name.str));
 | |
|               if ($2.length() > PRECISION_FOR_FLOAT)
 | |
|                 $$.set(&type_handler_double);
 | |
|               else
 | |
|                 $$.set(&type_handler_float);
 | |
|             }
 | |
|           }
 | |
|         | BIT_SYM opt_field_length
 | |
|           {
 | |
|             $$.set(&type_handler_bit, $2);
 | |
|           }
 | |
|         | BOOL_SYM
 | |
|           {
 | |
|             $$.set_handler_length(&type_handler_stiny, 1);
 | |
|           }
 | |
|         | BOOLEAN_SYM
 | |
|           {
 | |
|             $$.set_handler_length(&type_handler_stiny, 1);
 | |
|           }
 | |
|         | DECIMAL_SYM float_options last_field_options
 | |
|           { $$.set(&type_handler_newdecimal, $2);}
 | |
|         | NUMBER_ORACLE_SYM float_options last_field_options
 | |
|           {
 | |
|             if ($2.has_explicit_length())
 | |
|               $$.set(&type_handler_newdecimal, $2);
 | |
|             else
 | |
|               $$.set(&type_handler_double);
 | |
|           }
 | |
|         | NUMERIC_SYM float_options last_field_options
 | |
|           { $$.set(&type_handler_newdecimal, $2);}
 | |
|         | FIXED_SYM float_options last_field_options
 | |
|           { $$.set(&type_handler_newdecimal, $2);}
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_binary_and_compression:
 | |
|           /* empty */                                      { $$.init(); }
 | |
|         | binary                                           { $$= $1; }
 | |
|         | compressed opt_binary                            { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| field_type_string:
 | |
|           char opt_field_length opt_binary
 | |
|           {
 | |
|             $$.set(&type_handler_string, $2, $3);
 | |
|           }
 | |
|         | nchar opt_field_length opt_bin_mod
 | |
|           {
 | |
|             $$.set(&type_handler_string, $2,
 | |
|                    Lex_exact_charset_extended_collation_attrs::national($3));
 | |
|           }
 | |
|         | BINARY opt_field_length
 | |
|           {
 | |
|             $$.set(&type_handler_string, $2, &my_charset_bin);
 | |
|           }
 | |
|         | varchar opt_field_length opt_binary_and_compression
 | |
|           {
 | |
|             $$.set(&type_handler_varchar, $2, $3);
 | |
|           }
 | |
|         | VARCHAR2_ORACLE_SYM opt_field_length opt_binary_and_compression
 | |
|           {
 | |
|             $$.set(&type_handler_varchar, $2, $3);
 | |
|           }
 | |
|         | nvarchar opt_field_length opt_compressed opt_bin_mod
 | |
|           {
 | |
|             $$.set(&type_handler_varchar, $2,
 | |
|                    Lex_exact_charset_extended_collation_attrs::national($4));
 | |
|           }
 | |
|         | VARBINARY opt_field_length opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_varchar, $2, &my_charset_bin);
 | |
|           }
 | |
|         | RAW_ORACLE_SYM opt_field_length opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_varchar, $2, &my_charset_bin);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type_temporal:
 | |
|           YEAR_SYM opt_field_length last_field_options
 | |
|           {
 | |
|             if ($2.has_explicit_length())
 | |
|             {
 | |
|               if ($2.length() != 4)
 | |
|               {
 | |
|                 char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
 | |
|                 my_snprintf(buff, sizeof(buff), "YEAR(%u)", (uint) $2.length());
 | |
|                 warn_deprecated<1007>(thd, buff, "YEAR(4)");
 | |
|               }
 | |
|             }
 | |
|             $$.set(&type_handler_year, $2);
 | |
|           }
 | |
|         | DATE_SYM { $$.set(&type_handler_newdate); }
 | |
|         | TIME_SYM opt_field_length
 | |
|           {
 | |
|             $$.set(opt_mysql56_temporal_format ?
 | |
|                    static_cast<const Type_handler*>(&type_handler_time2) :
 | |
|                    static_cast<const Type_handler*>(&type_handler_time),
 | |
|                    $2);
 | |
|           }
 | |
|         | TIMESTAMP opt_field_length
 | |
|           {
 | |
|             $$.set(opt_mysql56_temporal_format ?
 | |
|                    static_cast<const Type_handler*>(&type_handler_timestamp2):
 | |
|                    static_cast<const Type_handler*>(&type_handler_timestamp),
 | |
|                    $2);
 | |
|           }
 | |
|         | DATETIME opt_field_length
 | |
|           {
 | |
|             $$.set(thd->type_handler_for_datetime(), $2);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| field_type_lob:
 | |
|           TINYBLOB opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_tiny_blob, &my_charset_bin);
 | |
|           }
 | |
|         | BLOB_MARIADB_SYM opt_field_length opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_blob, $2, &my_charset_bin);
 | |
|           }
 | |
|         | BLOB_ORACLE_SYM field_length opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_blob, $2, &my_charset_bin);
 | |
|           }
 | |
|         | BLOB_ORACLE_SYM opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_long_blob, &my_charset_bin);
 | |
|           }
 | |
|         | MEDIUMBLOB opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_medium_blob, &my_charset_bin);
 | |
|           }
 | |
|         | LONGBLOB opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_long_blob, &my_charset_bin);
 | |
|           }
 | |
|         | LONG_SYM VARBINARY opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_medium_blob, &my_charset_bin);
 | |
|           }
 | |
|         | LONG_SYM varchar opt_binary_and_compression
 | |
|           { $$.set(&type_handler_medium_blob, $3); }
 | |
|         | TINYTEXT opt_binary_and_compression
 | |
|           { $$.set(&type_handler_tiny_blob, $2); }
 | |
|         | TEXT_SYM opt_field_length opt_binary_and_compression
 | |
|           { $$.set(&type_handler_blob, $2, $3); }
 | |
|         | MEDIUMTEXT opt_binary_and_compression
 | |
|           { $$.set(&type_handler_medium_blob, $2); }
 | |
|         | LONGTEXT opt_binary_and_compression
 | |
|           { $$.set(&type_handler_long_blob, $2); }
 | |
|         | CLOB_ORACLE_SYM opt_binary_and_compression
 | |
|           { $$.set(&type_handler_long_blob, $2); }
 | |
|         | LONG_SYM opt_binary_and_compression
 | |
|           { $$.set(&type_handler_medium_blob, $2); }
 | |
|         | JSON_SYM opt_compressed
 | |
|           {
 | |
|             $$.set(&type_handler_long_blob_json, &my_charset_utf8mb4_bin);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_type_misc:
 | |
|           ENUM '(' string_list ')' opt_binary
 | |
|           { $$.set(&type_handler_enum, $5); }
 | |
|         | SET '(' string_list ')' opt_binary
 | |
|           { $$.set(&type_handler_set, $5); }
 | |
|         ;
 | |
| 
 | |
| char:
 | |
|           CHAR_SYM {}
 | |
|         ;
 | |
| 
 | |
| nchar:
 | |
|           NCHAR_SYM {}
 | |
|         | NATIONAL_SYM CHAR_SYM {}
 | |
|         ;
 | |
| 
 | |
| varchar:
 | |
|           char VARYING {}
 | |
|         | VARCHAR {}
 | |
|         ;
 | |
| 
 | |
| nvarchar:
 | |
|           NATIONAL_SYM VARCHAR {}
 | |
|         | NVARCHAR_SYM {}
 | |
|         | NCHAR_SYM VARCHAR {}
 | |
|         | NATIONAL_SYM CHAR_SYM VARYING {}
 | |
|         | NCHAR_SYM VARYING {}
 | |
|         ;
 | |
| 
 | |
| int_type:
 | |
|           INT_SYM   { $$= &type_handler_slong; }
 | |
|         | TINYINT   { $$= &type_handler_stiny; }
 | |
|         | SMALLINT  { $$= &type_handler_sshort; }
 | |
|         | MEDIUMINT { $$= &type_handler_sint24; }
 | |
|         | BIGINT    { $$= &type_handler_slonglong; }
 | |
|         ;
 | |
| 
 | |
| real_type:
 | |
|           REAL
 | |
|           {
 | |
|             $$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ?
 | |
|               static_cast<const Type_handler *>(&type_handler_float) :
 | |
|               static_cast<const Type_handler *>(&type_handler_double);
 | |
|           }
 | |
|         | DOUBLE_SYM           { $$= &type_handler_double; }
 | |
|         | DOUBLE_SYM PRECISION { $$= &type_handler_double; }
 | |
|         ;
 | |
| 
 | |
| srid_option:
 | |
|           /* empty */
 | |
|           { Lex->last_field->set_attr_uint32(0, 0); }
 | |
|         |
 | |
|           REF_SYSTEM_ID_SYM '=' NUM
 | |
|           {
 | |
|             Lex->last_field->set_attr_uint32(0, (uint32) atoi($3.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| float_options:
 | |
|           /* empty */  { $$.reset();  }
 | |
|         | field_length
 | |
|         | precision
 | |
|         ;
 | |
| 
 | |
| precision:
 | |
|           '(' NUM ',' NUM ')' { $$.set($2.str, $4.str); }
 | |
|         ;
 | |
| 
 | |
| field_options:
 | |
|           /* empty */       { $$= 0; }
 | |
|         | SIGNED_SYM        { $$= 0; }
 | |
|         | UNSIGNED          { $$= UNSIGNED_FLAG; }
 | |
|         | ZEROFILL          { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; }
 | |
|         | UNSIGNED ZEROFILL { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; }
 | |
|         | ZEROFILL UNSIGNED { $$= UNSIGNED_FLAG | ZEROFILL_FLAG; }
 | |
|         ;
 | |
| 
 | |
| last_field_options:
 | |
|           field_options { Lex->last_field->flags|= ($$= $1); }
 | |
|         ;
 | |
| 
 | |
| field_length_str:
 | |
|           '(' LONG_NUM ')'      { $$= $2.str; }
 | |
|         | '(' ULONGLONG_NUM ')' { $$= $2.str; }
 | |
|         | '(' DECIMAL_NUM ')'   { $$= $2.str; }
 | |
|         | '(' NUM ')'           { $$= $2.str; }
 | |
|         ;
 | |
| 
 | |
| field_length: field_length_str  { $$.set($1, NULL); }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| field_scale: field_length_str   { $$.set(NULL, $1); }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_field_length:
 | |
|           /* empty */  { $$.reset(); /* use default length */ }
 | |
|         | field_length
 | |
|         ;
 | |
| 
 | |
| opt_field_scale:
 | |
|           /* empty */ { $$.reset(); }
 | |
|         | field_scale
 | |
|         ;
 | |
| 
 | |
| opt_precision:
 | |
|           /* empty */    { $$.reset(); }
 | |
|         | precision      { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| attribute_list:
 | |
|           attribute_list attribute
 | |
|           {
 | |
|             if (($$= $1).merge_column_collate_clause_and_collate_clause(
 | |
|                            thd, thd->variables.character_set_collations, $2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | attribute
 | |
|         ;
 | |
| 
 | |
| attribute:
 | |
|           NULL_SYM
 | |
|           {
 | |
|             Lex->last_field->flags&= ~NOT_NULL_FLAG;
 | |
|             Lex->last_field->explicitly_nullable= true;
 | |
|             $$.init();
 | |
|           }
 | |
|         | DEFAULT column_default_expr
 | |
|           {
 | |
|             Lex->last_field->default_value= $2;
 | |
|             $$.init();
 | |
|           }
 | |
|         | ON UPDATE_SYM NOW_SYM opt_default_time_precision
 | |
|           {
 | |
|             Item *item= new (thd) Item_func_current_timestamp(thd, $4);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->last_field->on_update= item;
 | |
|             $$.init();
 | |
|           }
 | |
|         | AUTO_INC { Lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; $$.init(); }
 | |
|         | SERIAL_SYM DEFAULT VALUE_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->last_field->flags|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_KEY_FLAG;
 | |
|             lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|             $$.init();
 | |
|           }
 | |
|         | COLLATE_SYM collation_name
 | |
|           {
 | |
|             $$= Lex_exact_charset_extended_collation_attrs($2);
 | |
|           }
 | |
|         | serial_attribute { $$.init(); }
 | |
|         ;
 | |
| 
 | |
| opt_compression_method:
 | |
|           /* empty */ { $$= NULL; }
 | |
|         | equal ident { $$= $2.str; }
 | |
|         ;
 | |
| 
 | |
| opt_compressed:
 | |
|           /* empty */ {}
 | |
|         | compressed { }
 | |
|         ;
 | |
| 
 | |
| opt_enable:
 | |
|           /* empty */ {}
 | |
|         | ENABLE_SYM { }
 | |
|         ;
 | |
| 
 | |
| compressed:
 | |
|           COMPRESSED_SYM opt_compression_method
 | |
|           {
 | |
|             if (unlikely(Lex->last_field->set_compressed($2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| asrow_attribute:
 | |
|           not NULL_SYM opt_enable
 | |
|           {
 | |
|             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_ADD_INDEX;
 | |
|           }
 | |
|         | vcol_attribute
 | |
|         ;
 | |
| 
 | |
| serial_attribute:
 | |
|           asrow_attribute
 | |
|         | engine_defined_option
 | |
|           {
 | |
|             $1->link(&Lex->last_field->option_list, &Lex->option_list_last);
 | |
|           }
 | |
|         | with_or_without_system VERSIONING_SYM
 | |
|           {
 | |
|             Lex->last_field->versioning= $1;
 | |
|             Lex->create_info.options|= HA_VERSIONED_TABLE;
 | |
|             if (Lex->alter_info.flags & ALTER_DROP_SYSTEM_VERSIONING)
 | |
|             {
 | |
|               my_yyabort_error((ER_VERS_NOT_VERSIONED, MYF(0),
 | |
|                        Lex->create_last_non_select_table->table_name.str));
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| with_or_without_system:
 | |
|         WITH_SYSTEM_SYM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_COLUMN_UNVERSIONED;
 | |
|             Lex->create_info.vers_info.versioned_fields= true;
 | |
|             $$= Column_definition::WITH_VERSIONING;
 | |
|           }
 | |
|         | WITHOUT SYSTEM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_COLUMN_UNVERSIONED;
 | |
|             Lex->create_info.vers_info.unversioned_fields= true;
 | |
|             $$= Column_definition::WITHOUT_VERSIONING;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| charset:
 | |
|           CHAR_SYM SET { $$= $1; }
 | |
|         | CHARSET { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| charset_name:
 | |
|           ident_or_text
 | |
|           {
 | |
|             myf utf8_flag= thd->get_utf8_flag();
 | |
|             if (unlikely(!($$=get_charset_by_csname($1.str, MY_CS_PRIMARY,
 | |
|                                                     MYF(utf8_flag)))))
 | |
|               my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str));
 | |
|           }
 | |
|         | BINARY { $$= &my_charset_bin; }
 | |
|         ;
 | |
| 
 | |
| charset_name_or_default:
 | |
|           charset_name { $$=$1;   }
 | |
|         | DEFAULT    { $$=NULL; }
 | |
|         ;
 | |
| 
 | |
| opt_load_data_charset:
 | |
|           /* Empty */ { $$= NULL; }
 | |
|         | charset charset_name_or_default { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| old_or_new_charset_name:
 | |
|           ident_or_text
 | |
|           {
 | |
|             myf utf8_flag= thd->get_utf8_flag();
 | |
|             if (unlikely(!($$=get_charset_by_csname($1.str,
 | |
|                                                     MY_CS_PRIMARY,
 | |
|                                                     MYF(utf8_flag))) &&
 | |
|                          !($$=get_old_charset_by_name($1))))
 | |
|               my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str));
 | |
|           }
 | |
|         | BINARY { $$= &my_charset_bin; }
 | |
|         ;
 | |
| 
 | |
| old_or_new_charset_name_or_default:
 | |
|           old_or_new_charset_name { $$=$1;   }
 | |
|         | DEFAULT    { $$=NULL; }
 | |
|         ;
 | |
| 
 | |
| collation_name:
 | |
|           ident_or_text
 | |
|           {
 | |
|             if ($$.set_by_name($1.str, thd->get_utf8_flag()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| collation_name_or_default:
 | |
|           collation_name { $$=$1; }
 | |
|         | DEFAULT        { $$.set_collate_default(); }
 | |
|         | BINARY // MySQL compatibility
 | |
|           {
 | |
|             const Lex_exact_collation bin(&my_charset_bin);
 | |
|             $$= Lex_extended_collation(bin);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_default:
 | |
|           /* empty */ {}
 | |
|         | DEFAULT {}
 | |
|         ;
 | |
| 
 | |
| charset_or_alias:
 | |
|           charset charset_name { $$= $2; }
 | |
|         | ASCII_SYM { $$= &my_charset_latin1; }
 | |
|         | UNICODE_SYM
 | |
|           {
 | |
|             if (unlikely(!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0)))))
 | |
|               my_yyabort_error((ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2"));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_binary:
 | |
|           /* empty */             { $$.init(); }
 | |
|         | binary
 | |
|         ;
 | |
| 
 | |
| binary:
 | |
|           BYTE_SYM
 | |
|           {
 | |
|             $$.set_charset(Lex_exact_charset(&my_charset_bin));
 | |
|           }
 | |
|         | charset_or_alias
 | |
|           {
 | |
|             $$.set_charset(Lex_exact_charset($1));
 | |
|           }
 | |
|         | charset_or_alias BINARY
 | |
|           {
 | |
|             if ($$.set_charset_collate_binary(Lex_exact_charset($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | BINARY { $$.set_contextually_typed_binary_style(); }
 | |
|         | BINARY charset_or_alias
 | |
|           {
 | |
|             if ($$.set_charset_collate_binary(Lex_exact_charset($2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | charset_or_alias COLLATE_SYM DEFAULT
 | |
|           {
 | |
|             $$.set_charset_collate_default(
 | |
|                  thd,
 | |
|                  thd->variables.character_set_collations,
 | |
|                  Lex_exact_charset($1));
 | |
|           }
 | |
|         | charset_or_alias COLLATE_SYM collation_name
 | |
|           {
 | |
|             if ($3.merge_exact_charset(
 | |
|                      thd,
 | |
|                      thd->variables.character_set_collations,
 | |
|                      Lex_exact_charset($1)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= Lex_exact_charset_extended_collation_attrs($3);
 | |
|           }
 | |
|         | COLLATE_SYM collation_name
 | |
|           {
 | |
|             $$= Lex_exact_charset_extended_collation_attrs($2);
 | |
|           }
 | |
|         | COLLATE_SYM DEFAULT
 | |
|           {
 | |
|             $$.set_collate_default();
 | |
|           }
 | |
|         | charset_or_alias COLLATE_SYM BINARY // MySQL compatibility
 | |
|           {
 | |
|             const Lex_exact_collation bin(&my_charset_bin);
 | |
|             Lex_extended_collation tmp(bin);
 | |
|             if (tmp.merge_exact_charset(thd,
 | |
|                                         thd->variables.character_set_collations,
 | |
|                                         Lex_exact_charset($1)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= Lex_exact_charset_extended_collation_attrs(tmp);
 | |
|           }
 | |
|         | COLLATE_SYM BINARY // MySQL compatibility
 | |
|           {
 | |
|             const Lex_exact_collation bin(&my_charset_bin);
 | |
|             const Lex_extended_collation tmp(bin);
 | |
|             $$= Lex_exact_charset_extended_collation_attrs(tmp);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_bin_mod:
 | |
|           /* empty */   { $$= false; }
 | |
|         | BINARY        { $$= true; }
 | |
|         ;
 | |
| 
 | |
| ws_nweights:
 | |
|         '(' real_ulong_num
 | |
|         {
 | |
|           if (unlikely($2 == 0))
 | |
|           {
 | |
|             thd->parse_error();
 | |
|             MYSQL_YYABORT;
 | |
|           }
 | |
|         }
 | |
|         ')'
 | |
|         { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| ws_level_flag_desc:
 | |
|         ASC { $$= 0; }
 | |
|         | DESC { $$= 1 << MY_STRXFRM_DESC_SHIFT; }
 | |
|         ;
 | |
| 
 | |
| ws_level_flag_reverse:
 | |
|         REVERSE_SYM { $$= 1 << MY_STRXFRM_REVERSE_SHIFT; } ;
 | |
| 
 | |
| ws_level_flags:
 | |
|         /* empty */ { $$= 0; }
 | |
|         | ws_level_flag_desc { $$= $1; }
 | |
|         | ws_level_flag_desc ws_level_flag_reverse { $$= $1 | $2; }
 | |
|         | ws_level_flag_reverse { $$= $1 ; }
 | |
|         ;
 | |
| 
 | |
| ws_level_number:
 | |
|         real_ulong_num
 | |
|         {
 | |
|           $$= $1 < 1 ? 1 : ($1 > MY_STRXFRM_NLEVELS ? MY_STRXFRM_NLEVELS : $1);
 | |
|           $$--;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| ws_level_list_item:
 | |
|         ws_level_number ws_level_flags
 | |
|         {
 | |
|           $$= (1 | $2) << $1;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| ws_level_list:
 | |
|         ws_level_list_item { $$= $1; }
 | |
|         | ws_level_list ',' ws_level_list_item { $$|= $3; }
 | |
|         ;
 | |
| 
 | |
| ws_level_range:
 | |
|         ws_level_number '-' ws_level_number
 | |
|         {
 | |
|           uint start= $1;
 | |
|           uint end= $3;
 | |
|           for ($$= 0; start <= end; start++)
 | |
|             $$|= (1 << start);
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| ws_level_list_or_range:
 | |
|         ws_level_list { $$= $1; }
 | |
|         | ws_level_range { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| opt_ws_levels:
 | |
|         /* empty*/ { $$= 0; }
 | |
|         | LEVEL_SYM ws_level_list_or_range { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| opt_primary:
 | |
|           /* empty */
 | |
|         | PRIMARY_SYM
 | |
|         ;
 | |
| 
 | |
| references:
 | |
|           REFERENCES
 | |
|           table_ident
 | |
|           opt_ref_list
 | |
|           opt_match_clause
 | |
|           opt_on_update_delete
 | |
|           {
 | |
|             $$=$2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_ref_list:
 | |
|           /* empty */
 | |
|           { Lex->ref_list.empty(); }
 | |
|         | '(' ref_list ')'
 | |
|         ;
 | |
| 
 | |
| ref_list:
 | |
|           ref_list ',' ident
 | |
|           {
 | |
|             Key_part_spec *key= new (thd) Key_part_spec(&$3, 0);
 | |
|             if (unlikely(key == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->ref_list.push_back(key, thd->mem_root);
 | |
|           }
 | |
|         | ident
 | |
|           {
 | |
|             Key_part_spec *key= new (thd) Key_part_spec(&$1, 0);
 | |
|             if (unlikely(key == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex= Lex;
 | |
|             lex->ref_list.empty();
 | |
|             lex->ref_list.push_back(key, thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_match_clause:
 | |
|           /* empty */
 | |
|           { Lex->fk_match_option= Foreign_key::FK_MATCH_UNDEF; }
 | |
|         | MATCH FULL
 | |
|           { Lex->fk_match_option= Foreign_key::FK_MATCH_FULL; }
 | |
|         | MATCH PARTIAL
 | |
|           { Lex->fk_match_option= Foreign_key::FK_MATCH_PARTIAL; }
 | |
|         | MATCH SIMPLE_SYM
 | |
|           { Lex->fk_match_option= Foreign_key::FK_MATCH_SIMPLE; }
 | |
|         ;
 | |
| 
 | |
| opt_on_update_delete:
 | |
|           /* empty */
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->fk_update_opt= FK_OPTION_UNDEF;
 | |
|             lex->fk_delete_opt= FK_OPTION_UNDEF;
 | |
|           }
 | |
|         | ON UPDATE_SYM delete_option
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->fk_update_opt= $3;
 | |
|             lex->fk_delete_opt= FK_OPTION_UNDEF;
 | |
|           }
 | |
|         | ON DELETE_SYM delete_option
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->fk_update_opt= FK_OPTION_UNDEF;
 | |
|             lex->fk_delete_opt= $3;
 | |
|           }
 | |
|         | ON UPDATE_SYM delete_option
 | |
|           ON DELETE_SYM delete_option
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->fk_update_opt= $3;
 | |
|             lex->fk_delete_opt= $6;
 | |
|           }
 | |
|         | ON DELETE_SYM delete_option
 | |
|           ON UPDATE_SYM delete_option
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->fk_update_opt= $6;
 | |
|             lex->fk_delete_opt= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| delete_option:
 | |
|           RESTRICT      { $$= FK_OPTION_RESTRICT; }
 | |
|         | CASCADE       { $$= FK_OPTION_CASCADE; }
 | |
|         | SET NULL_SYM  { $$= FK_OPTION_SET_NULL; }
 | |
|         | NO_SYM ACTION { $$= FK_OPTION_NO_ACTION; }
 | |
|         | SET DEFAULT   { $$= FK_OPTION_SET_DEFAULT; }
 | |
|         ;
 | |
| 
 | |
| constraint_key_type:
 | |
|           PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
 | |
|         | UNIQUE_SYM opt_key_or_index { $$= Key::UNIQUE; }
 | |
|         ;
 | |
| 
 | |
| key_or_index:
 | |
|           KEY_SYM {}
 | |
|         | INDEX_SYM {}
 | |
|         ;
 | |
| 
 | |
| opt_key_or_index:
 | |
|           /* empty */ {}
 | |
|         | key_or_index
 | |
|         ;
 | |
| 
 | |
| keys_or_index:
 | |
|           KEYS {}
 | |
|         | INDEX_SYM {}
 | |
|         | INDEXES {}
 | |
|         ;
 | |
| 
 | |
| fulltext:
 | |
|           FULLTEXT_SYM { $$= Key::FULLTEXT;}
 | |
|         ;
 | |
| 
 | |
| spatial_or_vector:
 | |
|           SPATIAL_SYM
 | |
|           {
 | |
|             $$= Key::SPATIAL;
 | |
|           }
 | |
|         | VECTOR_SYM { $$= Key::VECTOR;}
 | |
|         ;
 | |
| 
 | |
| normal_key_options:
 | |
|           /* empty */ {}
 | |
|         | normal_key_opts { Lex->last_key->option_list= Lex->option_list; }
 | |
|         ;
 | |
| 
 | |
| fulltext_key_options:
 | |
|           /* empty */ {}
 | |
|         | fulltext_key_opts { Lex->last_key->option_list= Lex->option_list; }
 | |
|         ;
 | |
| 
 | |
| spatial_key_options:
 | |
|           /* empty */ {}
 | |
|         | spatial_key_opts { Lex->last_key->option_list= Lex->option_list; }
 | |
|         ;
 | |
| 
 | |
| normal_key_opts:
 | |
|           normal_key_opt
 | |
|         | normal_key_opts normal_key_opt
 | |
|         ;
 | |
| 
 | |
| spatial_key_opts:
 | |
|           spatial_key_opt
 | |
|         | spatial_key_opts spatial_key_opt
 | |
|         ;
 | |
| 
 | |
| fulltext_key_opts:
 | |
|           fulltext_key_opt
 | |
|         | fulltext_key_opts fulltext_key_opt
 | |
|         ;
 | |
| 
 | |
| 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
 | |
|           { Lex->last_key->key_create_info.algorithm= $2; }
 | |
|         | TYPE_SYM btree_or_rtree
 | |
|           { Lex->last_key->key_create_info.algorithm= $2; }
 | |
|         ;
 | |
| 
 | |
| all_key_opt:
 | |
|           KEY_BLOCK_SIZE opt_equal ulong_num
 | |
|           {
 | |
|             Lex->last_key->key_create_info.block_size= $3;
 | |
|             Lex->last_key->key_create_info.flags|= HA_USES_BLOCK_SIZE;
 | |
|          }
 | |
|         | COMMENT_SYM TEXT_STRING_sys
 | |
|           { Lex->last_key->key_create_info.comment= $2; }
 | |
|         | VISIBLE_SYM
 | |
|           {
 | |
|             /* This is mainly for MySQL 8.0 compatibility */
 | |
|           }
 | |
|         | ignorability
 | |
|           {
 | |
|             Lex->last_key->key_create_info.is_ignored= $1;
 | |
|           }
 | |
|         | engine_defined_option
 | |
|           {
 | |
|             $1->link(&Lex->option_list, &Lex->option_list_last);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| normal_key_opt:
 | |
|           all_key_opt
 | |
|         | key_using_alg
 | |
|         ;
 | |
| 
 | |
| spatial_key_opt:
 | |
|           all_key_opt
 | |
|         ;
 | |
| 
 | |
| fulltext_key_opt:
 | |
|           all_key_opt
 | |
|         | WITH PARSER_SYM IDENT_sys
 | |
|           {
 | |
|             if (likely(plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)))
 | |
|               Lex->last_key->key_create_info.parser_name= $3;
 | |
|             else
 | |
|               my_yyabort_error((ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| btree_or_rtree:
 | |
|           BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
 | |
|         | RTREE_SYM { $$= HA_KEY_ALG_RTREE; }
 | |
|         | HASH_SYM  { $$= HA_KEY_ALG_HASH; }
 | |
|         ;
 | |
| 
 | |
| ignorability:
 | |
|           IGNORED_SYM { $$= true; }
 | |
|         | NOT_SYM IGNORED_SYM { $$= false; }
 | |
|         ;
 | |
| 
 | |
| key_list:
 | |
|           key_list ',' key_part order_dir
 | |
|           {
 | |
|             $3->asc= $4;
 | |
|             Lex->last_key->columns.push_back($3, thd->mem_root);
 | |
|           }
 | |
|         | key_part order_dir
 | |
|           {
 | |
|             $1->asc= $2;
 | |
|             Lex->last_key->columns.push_back($1, thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_without_overlaps:
 | |
|          /* nothing */ {}
 | |
|          | ',' ident WITHOUT OVERLAPS_SYM
 | |
|           {
 | |
|             Lex->last_key->without_overlaps= true;
 | |
|             Lex->last_key->period= Lex_ident_column($2);
 | |
|           }
 | |
|          ;
 | |
| 
 | |
| key_part:
 | |
|           key_part_simple
 | |
|         | ident '(' NUM ')'
 | |
|           {
 | |
|             int key_part_len= atoi($3.str);
 | |
|             if (unlikely(!key_part_len))
 | |
|               my_yyabort_error((ER_KEY_PART_0, MYF(0), $1.str));
 | |
|             $$= new (thd) Key_part_spec(&$1, (uint) key_part_len);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| key_part_simple:
 | |
|           ident
 | |
|           {
 | |
|             $$= new (thd) Key_part_spec(&$1, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| opt_ident:
 | |
|           /* empty */ { $$= null_clex_str; }
 | |
|         | field_ident { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| 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); }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
| ** Alter table
 | |
| */
 | |
| 
 | |
| alter:
 | |
|           ALTER
 | |
|           {
 | |
|             Lex->name= null_clex_str;
 | |
|             Lex->table_type= TABLE_TYPE_UNKNOWN;
 | |
|             Lex->sql_command= SQLCOM_ALTER_TABLE;
 | |
|             Lex->duplicates= DUP_ERROR;
 | |
|             Lex->first_select_lex()->order_list.empty();
 | |
|             Lex->create_info.init();
 | |
|             Lex->create_info.row_type= ROW_TYPE_NOT_USED;
 | |
|             Lex->alter_info.reset();
 | |
|             Lex->no_write_to_binlog= 0;
 | |
|             Lex->create_info.storage_media= HA_SM_DEFAULT;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             DBUG_ASSERT(!Lex->m_sql_cmd);
 | |
|           }
 | |
|           alter_options TABLE_SYM opt_if_exists table_ident opt_lock_wait_timeout
 | |
|           {
 | |
|             Lex->create_info.set($5);
 | |
|             if (!Lex->first_select_lex()->
 | |
|                  add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING,
 | |
|                                    TL_READ_NO_INSERT, MDL_SHARED_UPGRADABLE))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->first_select_lex()->db=
 | |
|               (Lex->first_select_lex()->table_list.first)->db;
 | |
|             Lex->create_last_non_select_table= Lex->last_table();
 | |
|             Lex->mark_first_table_as_inserting();
 | |
|           }
 | |
|           alter_commands
 | |
|           {
 | |
|             if (likely(!Lex->m_sql_cmd))
 | |
|             {
 | |
|               /* Create a generic ALTER TABLE statment. */
 | |
|               Lex->m_sql_cmd= new (thd) Sql_cmd_alter_table();
 | |
|               if (unlikely(Lex->m_sql_cmd == NULL))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | ALTER DATABASE ident_or_empty
 | |
|           {
 | |
|             Lex->create_info.init();
 | |
|             if (Lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           create_database_options
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command=SQLCOM_ALTER_DB;
 | |
|             lex->name= $3;
 | |
|             if (lex->name.str == NULL &&
 | |
|                 unlikely(lex->copy_db_to(&lex->name)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | ALTER DATABASE COMMENT_SYM opt_equal TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->create_info.init();
 | |
|             Lex->create_info.schema_comment= thd->make_clex_string($5);
 | |
|             Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
 | |
|           }
 | |
|           opt_create_database_options
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command=SQLCOM_ALTER_DB;
 | |
|             lex->name= Lex_ident_sys();
 | |
|             if (lex->name.str == NULL &&
 | |
|                 unlikely(lex->copy_db_to(&lex->name)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_NO_DROP_SP, MYF(0), "DATABASE"));
 | |
|             lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
 | |
|             lex->name= $3;
 | |
|           }
 | |
|         | ALTER PROCEDURE_SYM sp_name
 | |
|           {
 | |
|             if (Lex->stmt_alter_procedure_start($3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_a_chistics
 | |
|           stmt_end {}
 | |
|         | ALTER FUNCTION_SYM sp_name
 | |
|           {
 | |
|             if (Lex->stmt_alter_function_start($3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_a_chistics
 | |
|           stmt_end {}
 | |
|         | ALTER view_algorithm definer_opt opt_view_suid VIEW_SYM table_ident
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_alter_view(thd, $2, $4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           view_list_opt AS view_select stmt_end {}
 | |
|         | ALTER definer_opt opt_view_suid VIEW_SYM table_ident
 | |
|           /*
 | |
|             We have two separate rules for ALTER VIEW rather that
 | |
|             optional view_algorithm above, to resolve the ambiguity
 | |
|             with the ALTER EVENT below.
 | |
|           */
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->add_alter_view(thd, VIEW_ALGORITHM_INHERIT, $3, $5))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           view_list_opt AS view_select stmt_end {}
 | |
|         | ALTER definer_opt remember_name EVENT_SYM sp_name
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             /*
 | |
|               It is safe to use Lex->spname because
 | |
|               ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
 | |
|               is not allowed. Lex->spname is used in the case of RENAME TO
 | |
|               If it had to be supported spname had to be added to
 | |
|               Event_parse_data.
 | |
|             */
 | |
| 
 | |
|             if (unlikely(!(Lex->event_parse_data= Event_parse_data::new_instance(thd))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->event_parse_data->identifier= $5;
 | |
| 
 | |
|             Lex->sql_command= SQLCOM_ALTER_EVENT;
 | |
|             Lex->stmt_definition_begin= $3;
 | |
|           }
 | |
|           ev_alter_on_schedule_completion
 | |
|           opt_ev_rename_to
 | |
|           opt_ev_status
 | |
|           opt_ev_comment
 | |
|           opt_ev_sql_stmt
 | |
|           {
 | |
|             if (unlikely(!($7 || $8 || $9 || $10 || $11)))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             /*
 | |
|               sql_command is set here because some rules in ev_sql_stmt
 | |
|               can overwrite it
 | |
|             */
 | |
|             Lex->sql_command= SQLCOM_ALTER_EVENT;
 | |
|             Lex->stmt_definition_end= (char*)YYLIP->get_cpp_ptr();
 | |
| 
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | ALTER SERVER_SYM ident_or_text
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             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 USER_SYM opt_if_exists clear_privileges grant_list
 | |
|           opt_require_clause opt_resource_options opt_account_locking_and_opt_password_expiration
 | |
|           {
 | |
|             Lex->create_info.set($3);
 | |
|             Lex->sql_command= SQLCOM_ALTER_USER;
 | |
|           }
 | |
|         | ALTER SEQUENCE_SYM opt_if_exists
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_ALTER_SEQUENCE;
 | |
|             lex->create_info.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (!(lex->create_info.seq_create_info= new (thd)
 | |
|                                                      sequence_definition()) ||
 | |
|                 !lex->first_select_lex()->
 | |
|                   add_table_to_list(thd, $5, NULL, TL_OPTION_SEQUENCE,
 | |
|                                     TL_WRITE, MDL_EXCLUSIVE))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sequence_defs
 | |
|           {
 | |
|             /* Create a generic ALTER SEQUENCE statment. */
 | |
|             Lex->m_sql_cmd= new (thd) Sql_cmd_alter_sequence($3);
 | |
|             if ((Lex->create_info.seq_create_info->used_fields &
 | |
|                  seq_field_used_as) &&
 | |
|                 (Lex->create_info.seq_create_info->used_fields -
 | |
|                  seq_field_used_as))
 | |
|               my_yyabort_error((ER_NOT_SUPPORTED_YET, MYF(0),
 | |
|                                 "ALTER SEQUENCE with both AS <type> and "
 | |
|                                 "something else."));
 | |
|             if (unlikely(Lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           } stmt_end {}
 | |
|         ;
 | |
| 
 | |
| account_locking_option:
 | |
|           LOCK_SYM
 | |
|           {
 | |
|             Lex->account_options.account_locked= ACCOUNTLOCK_LOCKED;
 | |
|           }
 | |
|         | UNLOCK_SYM
 | |
|           {
 | |
|             Lex->account_options.account_locked= ACCOUNTLOCK_UNLOCKED;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_password_expire_option:
 | |
|           /* empty */
 | |
|           {
 | |
|             Lex->account_options.password_expire= PASSWORD_EXPIRE_NOW;
 | |
|           }
 | |
|         | NEVER_SYM
 | |
|           {
 | |
|             Lex->account_options.password_expire= PASSWORD_EXPIRE_NEVER;
 | |
|           }
 | |
|         | DEFAULT
 | |
|           {
 | |
|             Lex->account_options.password_expire= PASSWORD_EXPIRE_DEFAULT;
 | |
|           }
 | |
|         | INTERVAL_SYM NUM DAY_SYM
 | |
|           {
 | |
|             Lex->account_options.password_expire= PASSWORD_EXPIRE_INTERVAL;
 | |
|             if (!(Lex->account_options.num_expiration_days= atoi($2.str)))
 | |
|               my_yyabort_error((ER_WRONG_VALUE, MYF(0), "DAY", $2.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_account_locking_and_opt_password_expiration:
 | |
|           /* empty */
 | |
|         | ACCOUNT_SYM account_locking_option
 | |
|         | PASSWORD_SYM EXPIRE_SYM opt_password_expire_option
 | |
|         | ACCOUNT_SYM account_locking_option PASSWORD_SYM EXPIRE_SYM opt_password_expire_option
 | |
|         | PASSWORD_SYM EXPIRE_SYM opt_password_expire_option ACCOUNT_SYM account_locking_option
 | |
|         ;
 | |
| 
 | |
| ev_alter_on_schedule_completion:
 | |
|           /* empty */ { $$= 0;}
 | |
|         | ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
 | |
|         | ev_on_completion { $$= 1; }
 | |
|         | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; }
 | |
|         ;
 | |
| 
 | |
| opt_ev_rename_to:
 | |
|           /* empty */ { $$= 0;}
 | |
|         | RENAME TO_SYM sp_name
 | |
|           {
 | |
|             /*
 | |
|               Use lex's spname to hold the new name.
 | |
|               The original name is in the Event_parse_data object
 | |
|             */
 | |
|             Lex->spname= $3; 
 | |
|             $$= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_ev_sql_stmt:
 | |
|           /* empty*/ { $$= 0;}
 | |
|         | DO_SYM ev_sql_stmt { $$= 1; }
 | |
|         ;
 | |
| 
 | |
| ident_or_empty:
 | |
|           /* empty */
 | |
|           %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE { $$= Lex_ident_sys(); }
 | |
|         | ident
 | |
|         ;
 | |
| 
 | |
| alter_commands:
 | |
|           /* empty */
 | |
|         | DISCARD TABLESPACE
 | |
|           {
 | |
|             Lex->m_sql_cmd= new (thd)
 | |
|               Sql_cmd_discard_import_tablespace(
 | |
|                 Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE);
 | |
|             if (unlikely(Lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | IMPORT TABLESPACE
 | |
|           {
 | |
|             Lex->m_sql_cmd= new (thd)
 | |
|               Sql_cmd_discard_import_tablespace(
 | |
|                 Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE);
 | |
|             Lex->create_info.add(DDL_options_st::OPT_IMPORT_TABLESPACE);
 | |
|             if (unlikely(Lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | alter_list
 | |
|           opt_partitioning
 | |
|         | alter_list
 | |
|           remove_partitioning
 | |
|         | remove_partitioning
 | |
|         | partitioning
 | |
| /*
 | |
|   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
 | |
|   will be longer.
 | |
| */
 | |
|         | add_partition_rule
 | |
|         | DROP PARTITION_SYM opt_if_exists alt_part_name_list
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_DROP;
 | |
|             DBUG_ASSERT(!Lex->if_exists());
 | |
|             Lex->create_info.add($3);
 | |
|           }
 | |
|         | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog
 | |
|           all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->alter_info.partition_flags|= ALTER_PARTITION_REBUILD;
 | |
|             lex->no_write_to_binlog= $3;
 | |
|           }
 | |
|         | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog
 | |
|           all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->no_write_to_binlog= $3;
 | |
|             lex->check_opt.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd)
 | |
|                               Sql_cmd_alter_table_optimize_partition();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_no_write_to_binlog
 | |
|         | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog
 | |
|           all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->no_write_to_binlog= $3;
 | |
|             lex->check_opt.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd)
 | |
|                               Sql_cmd_alter_table_analyze_partition();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|         | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->check_opt.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd)
 | |
|                               Sql_cmd_alter_table_check_partition();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_mi_check_type
 | |
|         | REPAIR PARTITION_SYM opt_no_write_to_binlog
 | |
|           all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->no_write_to_binlog= $3;
 | |
|             lex->check_opt.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd)
 | |
|                               Sql_cmd_alter_table_repair_partition();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_mi_repair_type
 | |
|         | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->alter_info.partition_flags|= ALTER_PARTITION_COALESCE;
 | |
|             lex->no_write_to_binlog= $3;
 | |
|             lex->alter_info.num_parts= $4;
 | |
|           }
 | |
|         | TRUNCATE_SYM PARTITION_SYM all_or_alt_part_name_list
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->check_opt.init();
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd)
 | |
|                               Sql_cmd_alter_table_truncate_partition();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | reorg_partition_rule
 | |
|         | EXCHANGE_SYM PARTITION_SYM alt_part_name_item
 | |
|           WITH TABLE_SYM table_ident opt_without_validation have_partitioning
 | |
|           {
 | |
|             if (Lex->stmt_alter_table_exchange_partition($6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONVERT_SYM PARTITION_SYM alt_part_name_item
 | |
|           TO_SYM TABLE_SYM table_ident opt_without_validation have_partitioning
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (Lex->stmt_alter_table($6))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_alter_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.partition_flags|= ALTER_PARTITION_CONVERT_OUT;
 | |
|           }
 | |
|         | CONVERT_SYM TABLE_SYM table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (!lex->first_select_lex()->add_table_to_list(thd, $3, nullptr, 0,
 | |
|                                                             TL_READ_NO_INSERT,
 | |
|                                                             MDL_SHARED_NO_WRITE))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             /*
 | |
|               This will appear as (new_db, new_name) in alter_ctx.
 | |
|               new_db will be IX-locked and new_name X-locked.
 | |
|             */
 | |
|             lex->first_select_lex()->db= $3->db;
 | |
|             lex->name= $3->table;
 | |
|             if (lex->first_select_lex()->db.str == NULL &&
 | |
|                 lex->copy_db_to(&lex->first_select_lex()->db))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->part_info= new (thd) partition_info();
 | |
|             if (unlikely(!lex->part_info))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->part_info->num_parts= 1;
 | |
|             /*
 | |
|               OR-ed with ALTER_PARTITION_ADD because too many checks of
 | |
|               ALTER_PARTITION_ADD required.
 | |
|             */
 | |
|             lex->alter_info.partition_flags|= ALTER_PARTITION_ADD |
 | |
|                                               ALTER_PARTITION_CONVERT_IN;
 | |
|           }
 | |
|           TO_SYM PARTITION_SYM part_definition opt_without_validation have_partitioning
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_alter_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remove_partitioning:
 | |
|           REMOVE_SYM PARTITIONING_SYM
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_REMOVE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| all_or_alt_part_name_list:
 | |
|           ALL
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_ALL;
 | |
|           }
 | |
|         | alt_part_name_list
 | |
|         ;
 | |
| 
 | |
| add_partition_rule:
 | |
|           ADD PARTITION_SYM opt_if_not_exists
 | |
|           opt_no_write_to_binlog
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->part_info= new (thd) partition_info();
 | |
|             if (unlikely(!lex->part_info))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->alter_info.partition_flags|= ALTER_PARTITION_ADD;
 | |
|             DBUG_ASSERT(!Lex->create_info.if_not_exists());
 | |
|             lex->create_info.set($3);
 | |
|             lex->no_write_to_binlog= $4;
 | |
|           }
 | |
|           add_part_extra
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| add_part_extra:
 | |
|           /* empty */
 | |
|         | '(' part_def_list ')'
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->part_info->num_parts= lex->part_info->partitions.elements;
 | |
|           }
 | |
|         | PARTITIONS_SYM real_ulong_num
 | |
|           {
 | |
|             Lex->part_info->num_parts= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| reorg_partition_rule:
 | |
|           REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->part_info= new (thd) partition_info();
 | |
|             if (unlikely(!lex->part_info))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->no_write_to_binlog= $3;
 | |
|           }
 | |
|           reorg_parts_rule
 | |
|         ;
 | |
| 
 | |
| reorg_parts_rule:
 | |
|           /* empty */
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_TABLE_REORG;
 | |
|           }
 | |
|         | alt_part_name_list
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_REORGANIZE;
 | |
|           }
 | |
|           INTO '(' part_def_list ')'
 | |
|           {
 | |
|             partition_info *part_info= Lex->part_info;
 | |
|             part_info->num_parts= part_info->partitions.elements;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| alt_part_name_list:
 | |
|           alt_part_name_item {}
 | |
|         | alt_part_name_list ',' alt_part_name_item {}
 | |
|         ;
 | |
| 
 | |
| alt_part_name_item:
 | |
|           ident
 | |
|           {
 | |
|             if (unlikely(Lex->alter_info.partition_names.push_back($1.str,
 | |
|                                                                    thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   End of management of partition commands
 | |
| */
 | |
| 
 | |
| alter_list:
 | |
|           alter_list_item
 | |
|         | alter_list ',' alter_list_item
 | |
|         ;
 | |
| 
 | |
| add_column:
 | |
|           ADD opt_column opt_if_not_exists_table_element
 | |
|         ;
 | |
| 
 | |
| alter_list_item:
 | |
|           add_column column_def opt_place
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->create_last_non_select_table= lex->last_table();
 | |
|             lex->alter_info.flags|= ALTER_PARSER_ADD_COLUMN;
 | |
|             $2->after= Lex_ident_column($3);
 | |
|           }
 | |
|         | ADD key_def
 | |
|           {
 | |
|             Lex->create_last_non_select_table= Lex->last_table();
 | |
|             Lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|           }
 | |
|         | ADD period_for_system_time
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_ADD_PERIOD;
 | |
|           }
 | |
|         | ADD
 | |
|           PERIOD_SYM opt_if_not_exists_table_element period_for_application_time
 | |
|           {
 | |
|             Table_period_info &period= Lex->create_info.period_info;
 | |
|             period.create_if_not_exists= Lex->check_exists;
 | |
|             Lex->alter_info.flags|= ALTER_ADD_CHECK_CONSTRAINT;
 | |
|           }
 | |
|         | add_column '(' create_field_list ')'
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->alter_info.flags|= ALTER_PARSER_ADD_COLUMN;
 | |
|             if (!lex->alter_info.key_list.is_empty())
 | |
|               lex->alter_info.flags|= ALTER_ADD_INDEX;
 | |
|           }
 | |
|         | ADD constraint_def
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_ADD_CHECK_CONSTRAINT;
 | |
| 	  }
 | |
|         | ADD CONSTRAINT IF_SYM not EXISTS field_ident check_constraint
 | |
|          {
 | |
|            Lex->alter_info.flags|= 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_CHANGE_COLUMN | ALTER_RENAME_COLUMN;
 | |
|             Lex->create_last_non_select_table= Lex->last_table();
 | |
|             $5->change= Lex_ident_column($4);
 | |
|             $5->after= Lex_ident_column($6);
 | |
|           }
 | |
|         | MODIFY_SYM opt_column opt_if_exists_table_element
 | |
|           field_spec opt_place
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
 | |
|             Lex->create_last_non_select_table= Lex->last_table();
 | |
|             $4->change= $4->field_name;
 | |
|             $4->after= Lex_ident_column($5);
 | |
|           }
 | |
|         | DROP opt_column opt_if_exists_table_element field_ident opt_restrict
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::COLUMN, $4, $3));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             lex->alter_info.flags|= ALTER_PARSER_DROP_COLUMN;
 | |
|           }
 | |
| 	| DROP CONSTRAINT opt_if_exists_table_element field_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::CHECK_CONSTRAINT,
 | |
|                                         $4, $3));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             lex->alter_info.flags|= ALTER_DROP_CHECK_CONSTRAINT;
 | |
|           }
 | |
|         | DROP FOREIGN KEY_SYM opt_if_exists_table_element field_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::FOREIGN_KEY, $5, $4));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             lex->alter_info.flags|= ALTER_DROP_FOREIGN_KEY;
 | |
|           }
 | |
|         | DROP opt_constraint_no_id PRIMARY_SYM KEY_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::KEY, primary_key_name,
 | |
|                                         FALSE));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             lex->alter_info.flags|= ALTER_DROP_INDEX;
 | |
|           }
 | |
|         | DROP key_or_index opt_if_exists_table_element field_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::KEY, $4, $3));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             lex->alter_info.flags|= ALTER_DROP_INDEX;
 | |
|           }
 | |
|         | DISABLE_SYM KEYS
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->alter_info.keys_onoff= Alter_info::DISABLE;
 | |
|             lex->alter_info.flags|= ALTER_KEYS_ONOFF;
 | |
|           }
 | |
|         | ENABLE_SYM KEYS
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->alter_info.keys_onoff= Alter_info::ENABLE;
 | |
|             lex->alter_info.flags|= ALTER_KEYS_ONOFF;
 | |
|           }
 | |
|         | ALTER opt_column opt_if_exists_table_element field_ident SET DEFAULT column_default_expr
 | |
|           {
 | |
|             if (check_expression($7, Lex_ident_column($4), VCOL_DEFAULT))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Lex->add_alter_list($4, $7, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ALTER key_or_index opt_if_exists_table_element ident ignorability
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             Alter_index_ignorability *ac= new (thd)
 | |
|                                         Alter_index_ignorability($4, $5, $3);
 | |
|             if (ac == NULL)
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.alter_index_ignorability_list.push_back(ac);
 | |
|             lex->alter_info.flags|= ALTER_INDEX_IGNORABILITY;
 | |
|           }
 | |
|         | ALTER opt_column opt_if_exists_table_element field_ident DROP DEFAULT
 | |
|           {
 | |
|             if (unlikely(Lex->add_alter_list($4, (Virtual_column_info*) 0, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | RENAME opt_to table_ident
 | |
|           {
 | |
|             if (Lex->stmt_alter_table($3))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->alter_info.flags|= ALTER_RENAME;
 | |
|           }
 | |
|         | RENAME COLUMN_SYM opt_if_exists_table_element ident TO_SYM ident
 | |
|           {
 | |
|             if (unlikely(Lex->add_alter_list($4, $6, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | RENAME key_or_index opt_if_exists_table_element field_ident TO_SYM field_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_rename_key *ak= new (thd)
 | |
|                                     Alter_rename_key($4, $6, $3);
 | |
|             if (ak == NULL)
 | |
|               MYSQL_YYABORT;
 | |
|             lex->alter_info.alter_rename_key_list.push_back(ak);
 | |
|             lex->alter_info.flags|= ALTER_RENAME_INDEX;
 | |
|           }
 | |
|         | CONVERT_SYM TO_SYM charset charset_name_or_default
 | |
|           {
 | |
|             if (Lex->add_alter_list_item_convert_to_charset(
 | |
|                        thd, thd->variables.character_set_collations, $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONVERT_SYM TO_SYM charset charset_name_or_default
 | |
|                              COLLATE_SYM collation_name_or_default
 | |
|           {
 | |
|             if (Lex->add_alter_list_item_convert_to_charset(
 | |
|                        thd, thd->variables.character_set_collations, $4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_table_options_space_separated
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->alter_info.flags|= ALTER_OPTIONS;
 | |
|           }
 | |
|         | FORCE_SYM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_RECREATE;
 | |
|           }
 | |
|         | alter_order_clause
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->alter_info.flags|= ALTER_ORDER;
 | |
|           }
 | |
|         | alter_algorithm_option
 | |
|         | alter_lock_option
 | |
|         | ADD SYSTEM VERSIONING_SYM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_ADD_SYSTEM_VERSIONING;
 | |
|             Lex->create_info.options|= HA_VERSIONED_TABLE;
 | |
|           }
 | |
|         | DROP SYSTEM VERSIONING_SYM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_DROP_SYSTEM_VERSIONING;
 | |
|             Lex->create_info.options&= ~HA_VERSIONED_TABLE;
 | |
|           }
 | |
|         | DROP PERIOD_SYM FOR_SYSTEM_TIME_SYM
 | |
|           {
 | |
|             Lex->alter_info.flags|= ALTER_DROP_PERIOD;
 | |
|           }
 | |
|         | DROP PERIOD_SYM opt_if_exists_table_element FOR_SYM ident
 | |
|           {
 | |
|             Alter_drop *ad= new Alter_drop(Alter_drop::PERIOD, $5, $3);
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             Lex->alter_info.flags|= ALTER_DROP_CHECK_CONSTRAINT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_without_validation:
 | |
|           /* empty */
 | |
|         | WITH VALIDATION_SYM
 | |
|         {
 | |
|           Lex->without_validation= 0;
 | |
|         }
 | |
|         | WITHOUT VALIDATION_SYM
 | |
|         {
 | |
|           Lex->without_validation= 1;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_index_lock_algorithm:
 | |
|           /* empty */
 | |
|         | alter_lock_option
 | |
|         | alter_algorithm_option
 | |
|         | alter_lock_option alter_algorithm_option
 | |
|         | alter_algorithm_option alter_lock_option
 | |
|         ;
 | |
| 
 | |
| alter_algorithm_option:
 | |
|           ALGORITHM_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->alter_info.set_requested_algorithm(Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT);
 | |
|           }
 | |
|         | ALGORITHM_SYM opt_equal ident
 | |
|           {
 | |
|             if (unlikely(Lex->alter_info.set_requested_algorithm(&$3)))
 | |
|               my_yyabort_error((ER_UNKNOWN_ALTER_ALGORITHM, MYF(0), $3.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| alter_lock_option:
 | |
|           LOCK_SYM opt_equal DEFAULT
 | |
|           {
 | |
|             Lex->alter_info.requested_lock=
 | |
|               Alter_info::ALTER_TABLE_LOCK_DEFAULT;
 | |
|           }
 | |
|         | LOCK_SYM opt_equal ident
 | |
|           {
 | |
|             if (unlikely(Lex->alter_info.set_requested_lock(&$3)))
 | |
|               my_yyabort_error((ER_UNKNOWN_ALTER_LOCK, MYF(0), $3.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_column:
 | |
|           /* empty */ {}     %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE
 | |
|         | COLUMN_SYM {}
 | |
|         ;
 | |
| 
 | |
| opt_ignore:
 | |
|           /* empty */ { Lex->ignore= 0;}
 | |
|         | IGNORE_SYM { Lex->ignore= 1;}
 | |
|         ;
 | |
| 
 | |
| alter_options:
 | |
|         { Lex->ignore= 0;} alter_options_part2
 | |
| 	;
 | |
| 	
 | |
| alter_options_part2:
 | |
|           /* empty */ 
 | |
|         | alter_option_list
 | |
|         ;
 | |
| 
 | |
| alter_option_list:
 | |
|         alter_option_list alter_option
 | |
|         | alter_option
 | |
|         ;
 | |
| 
 | |
| alter_option:
 | |
| 	  IGNORE_SYM { Lex->ignore= 1;}
 | |
|         | ONLINE_SYM
 | |
|           {
 | |
|             Lex->alter_info.requested_lock=
 | |
|               Alter_info::ALTER_TABLE_LOCK_NONE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_restrict:
 | |
|           /* empty */ { Lex->drop_mode= DROP_DEFAULT; }
 | |
|         | RESTRICT    { Lex->drop_mode= DROP_RESTRICT; }
 | |
|         | CASCADE     { Lex->drop_mode= DROP_CASCADE; }
 | |
|         ;
 | |
| 
 | |
| opt_place:
 | |
|         /* empty */ { $$= null_clex_str; }
 | |
|         | AFTER_SYM ident
 | |
|           {
 | |
|             $$= $2;
 | |
|             Lex->alter_info.flags |= ALTER_COLUMN_ORDER;
 | |
|           }
 | |
|         | FIRST_SYM
 | |
|           {
 | |
|             $$.str=    first_keyword;
 | |
| 	    $$.length= 5; /* Length of "first" */
 | |
|             Lex->alter_info.flags |= ALTER_COLUMN_ORDER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_to:
 | |
|           /* empty */ {}
 | |
|         | TO_SYM {}
 | |
|         | '=' {}
 | |
|         | AS {}
 | |
|         ;
 | |
| 
 | |
| slave:
 | |
|           START_SYM SLAVE optional_connection_name slave_thread_opts optional_for_channel
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_SLAVE_START;
 | |
|             lex->type = 0;
 | |
|             /* If you change this code don't forget to update SLAVE START too */
 | |
|           }
 | |
|           slave_until
 | |
|           {}
 | |
|         | START_SYM ALL SLAVES slave_thread_opts
 | |
|           {
 | |
|             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 optional_for_channel
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_SLAVE_STOP;
 | |
|             lex->type = 0;
 | |
|             /* If you change this code don't forget to update SLAVE STOP too */
 | |
|           }
 | |
|         | STOP_SYM ALL SLAVES slave_thread_opts
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_SLAVE_ALL_STOP;
 | |
|             lex->type = 0;
 | |
|             /* If you change this code don't forget to update SLAVE STOP too */
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| start:
 | |
|           START_SYM TRANSACTION_SYM opt_start_transaction_option_list
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_BEGIN;
 | |
|             /* READ ONLY and READ WRITE are mutually exclusive. */
 | |
|             if (unlikely(($3 & MYSQL_START_TRANS_OPT_READ_WRITE) &&
 | |
|                          ($3 & MYSQL_START_TRANS_OPT_READ_ONLY)))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             lex->start_transaction_opt= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_start_transaction_option_list:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= 0;
 | |
|           }
 | |
|         | start_transaction_option_list
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| start_transaction_option_list:
 | |
|           start_transaction_option
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         | start_transaction_option_list ',' start_transaction_option
 | |
|           {
 | |
|             $$= $1 | $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| start_transaction_option:
 | |
|           WITH CONSISTENT_SYM SNAPSHOT_SYM
 | |
|           {
 | |
|             $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
 | |
|           }
 | |
|         | READ_SYM ONLY_SYM
 | |
|           {
 | |
|             $$= MYSQL_START_TRANS_OPT_READ_ONLY;
 | |
|           }
 | |
|         | READ_SYM WRITE_SYM
 | |
|           {
 | |
|             $$= MYSQL_START_TRANS_OPT_READ_WRITE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| slave_thread_opts:
 | |
|           { Lex->slave_thd_opt= 0; }
 | |
|           slave_thread_opt_list
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| slave_thread_opt_list:
 | |
|           slave_thread_opt
 | |
|         | slave_thread_opt_list ',' slave_thread_opt
 | |
|         ;
 | |
| 
 | |
| slave_thread_opt:
 | |
|           /*empty*/ {}
 | |
|         | SQL_THREAD   { Lex->slave_thd_opt|=SLAVE_SQL; }
 | |
|         | RELAY_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
 | |
|         ;
 | |
| 
 | |
| slave_until:
 | |
|           /*empty*/ {}
 | |
|         | UNTIL_SYM slave_until_opts
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(((lex->mi.log_file_name || lex->mi.pos) &&
 | |
|                          (lex->mi.relay_log_name || lex->mi.relay_log_pos)) ||
 | |
|                          !((lex->mi.log_file_name && lex->mi.pos) ||
 | |
|                            (lex->mi.relay_log_name && lex->mi.relay_log_pos))))
 | |
|                my_yyabort_error((ER_BAD_SLAVE_UNTIL_COND, MYF(0)));
 | |
|           }
 | |
|         | UNTIL_SYM MASTER_GTID_POS_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.gtid_pos_str = $4;
 | |
|             Lex->mi.is_until_before_gtids= false;
 | |
|           }
 | |
|         | UNTIL_SYM SQL_AFTER_GTIDS_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.gtid_pos_str = $4;
 | |
|             Lex->mi.is_until_before_gtids= false;
 | |
|           }
 | |
|         | UNTIL_SYM SQL_BEFORE_GTIDS_SYM '=' TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->mi.gtid_pos_str = $4;
 | |
|             Lex->mi.is_until_before_gtids= true;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| slave_until_opts:
 | |
|           master_file_def
 | |
|         | slave_until_opts ',' master_file_def
 | |
|         ;
 | |
| 
 | |
| checksum:
 | |
|           CHECKSUM_SYM table_or_tables
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_CHECKSUM;
 | |
|             /* Will be overridden during execution. */
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|           }
 | |
|           table_list opt_checksum_type
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| opt_checksum_type:
 | |
|           /* nothing */ { Lex->check_opt.flags= 0; }
 | |
|         | QUICK         { Lex->check_opt.flags= T_QUICK; }
 | |
|         | EXTENDED_SYM  { Lex->check_opt.flags= T_EXTEND; }
 | |
|         ;
 | |
| 
 | |
| repair_table_or_view:
 | |
|           table_or_tables table_list opt_mi_repair_type
 | |
|         | VIEW_SYM
 | |
|           { Lex->table_type= TABLE_TYPE_VIEW; }
 | |
|           table_list opt_view_repair_type
 | |
|         ;
 | |
| 
 | |
| repair:
 | |
|           REPAIR opt_no_write_to_binlog
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_REPAIR;
 | |
|             lex->no_write_to_binlog= $2;
 | |
|             lex->check_opt.init();
 | |
|             lex->alter_info.reset();
 | |
|             /* Will be overridden during execution. */
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|           }
 | |
|           repair_table_or_view
 | |
|           {
 | |
|             LEX* lex= thd->lex;
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_repair_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_mi_repair_type:
 | |
|           /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
 | |
|         | mi_repair_types {}
 | |
|         ;
 | |
| 
 | |
| mi_repair_types:
 | |
|           mi_repair_type {}
 | |
|         | mi_repair_type mi_repair_types {}
 | |
|         ;
 | |
| 
 | |
| mi_repair_type:
 | |
|           QUICK        { Lex->check_opt.flags|= T_QUICK; }
 | |
|         | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
 | |
|         | USE_FRM      { Lex->check_opt.sql_flags|= TT_USEFRM; }
 | |
|         | FORCE_SYM    { Lex->check_opt.sql_flags|= TT_FORCE; }
 | |
|         ;
 | |
| 
 | |
| opt_view_repair_type:
 | |
|           /* empty */    { }
 | |
|         | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
 | |
|         | FROM MYSQL_SYM { Lex->check_opt.sql_flags|= TT_FROM_MYSQL; }
 | |
|         ;
 | |
| 
 | |
| analyze:
 | |
|           ANALYZE_SYM opt_no_write_to_binlog table_or_tables
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_ANALYZE;
 | |
|             lex->no_write_to_binlog= $2;
 | |
|             lex->check_opt.init();
 | |
|             lex->alter_info.reset();
 | |
|             /* Will be overridden during execution. */
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|           }
 | |
|           analyze_table_list
 | |
|           {
 | |
|             LEX* lex= thd->lex;
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_analyze_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| analyze_table_list:
 | |
|           analyze_table_elem_spec
 | |
|         | analyze_table_list ',' analyze_table_elem_spec
 | |
|         ;
 | |
| 
 | |
| analyze_table_elem_spec:
 | |
|           table_name opt_persistent_stat_clause
 | |
|         ;
 | |
| 
 | |
| opt_persistent_stat_clause:
 | |
|           /* empty */
 | |
|           {}        
 | |
|         | PERSISTENT_SYM FOR_SYM persistent_stat_spec  
 | |
|           { 
 | |
|             thd->lex->with_persistent_for_clause= TRUE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| persistent_stat_spec:
 | |
|           ALL
 | |
|           {}
 | |
|         | COLUMNS persistent_column_stat_spec INDEXES persistent_index_stat_spec
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| persistent_column_stat_spec:
 | |
|           ALL {}
 | |
|         | '('
 | |
|           { 
 | |
|             LEX* lex= thd->lex;
 | |
|             lex->column_list= new (thd) List<LEX_STRING>;
 | |
|             if (unlikely(lex->column_list == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           table_column_list
 | |
|           ')' 
 | |
|           { }
 | |
|         ;
 | |
|  
 | |
| persistent_index_stat_spec:
 | |
|           ALL {}
 | |
|         | '('
 | |
|           { 
 | |
|             LEX* lex= thd->lex;
 | |
|             lex->index_list= new (thd) List<LEX_STRING>;
 | |
|             if (unlikely(lex->index_list == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           table_index_list
 | |
|           ')' 
 | |
|           { }
 | |
|         ;
 | |
| 
 | |
| table_column_list:
 | |
|           /* empty */
 | |
|           {}
 | |
|         | ident
 | |
|           {
 | |
|             Lex->column_list->push_back((LEX_STRING*)
 | |
|                 thd->memdup(&$1, sizeof(LEX_STRING)), thd->mem_root);
 | |
|           }
 | |
|         | table_column_list ',' ident
 | |
|           {
 | |
|             Lex->column_list->push_back((LEX_STRING*)
 | |
|                 thd->memdup(&$3, sizeof(LEX_STRING)), thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_index_list:
 | |
|           /* empty */
 | |
|           {}
 | |
|         | table_index_name 
 | |
|         | table_index_list ',' table_index_name
 | |
|         ;
 | |
| 
 | |
| table_index_name:
 | |
|           ident
 | |
|           {
 | |
|             Lex->index_list->push_back((LEX_STRING*)
 | |
|                                        thd->memdup(&$1, sizeof(LEX_STRING)),
 | |
|                                        thd->mem_root);
 | |
|           }
 | |
|         |
 | |
|           PRIMARY_SYM
 | |
|           {
 | |
|             LEX_STRING str= {(char*) "PRIMARY", 7};
 | |
|             Lex->index_list->push_back((LEX_STRING*)
 | |
|                                         thd->memdup(&str, sizeof(LEX_STRING)),
 | |
|                                         thd->mem_root);
 | |
|           }  
 | |
|         ;  
 | |
| 
 | |
| binlog_base64_event:
 | |
|           BINLOG_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
 | |
|             Lex->comment= $2;
 | |
|             Lex->ident.str=    NULL;
 | |
|             Lex->ident.length= 0;
 | |
|           }
 | |
|           |
 | |
|           BINLOG_SYM '@' ident_or_text ',' '@' ident_or_text
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
 | |
|             Lex->comment= $3;
 | |
|             Lex->ident=   $6;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| check_view_or_table:
 | |
|           table_or_tables table_list opt_mi_check_type
 | |
|         | VIEW_SYM
 | |
|           { Lex->table_type= TABLE_TYPE_VIEW; }
 | |
|           table_list opt_view_check_type
 | |
|         ;
 | |
| 
 | |
| check:    CHECK_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
| 
 | |
|             lex->sql_command = SQLCOM_CHECK;
 | |
|             lex->check_opt.init();
 | |
|             lex->alter_info.reset();
 | |
|             /* Will be overridden during execution. */
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|           }
 | |
|           check_view_or_table
 | |
|           {
 | |
|             LEX* lex= thd->lex;
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "CHECK"));
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_check_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_mi_check_type:
 | |
|           /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
 | |
|         | mi_check_types {}
 | |
|         ;
 | |
| 
 | |
| mi_check_types:
 | |
|           mi_check_type {}
 | |
|         | mi_check_type mi_check_types {}
 | |
|         ;
 | |
| 
 | |
| mi_check_type:
 | |
|           QUICK               { Lex->check_opt.flags|= T_QUICK; }
 | |
|         | FAST_SYM            { Lex->check_opt.flags|= T_FAST; }
 | |
|         | MEDIUM_SYM          { Lex->check_opt.flags|= T_MEDIUM; }
 | |
|         | EXTENDED_SYM        { Lex->check_opt.flags|= T_EXTEND; }
 | |
|         | CHANGED             { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
 | |
|         | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
 | |
|         ;
 | |
| 
 | |
| opt_view_check_type:
 | |
|           /* empty */         { }
 | |
|         | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
 | |
|         ;
 | |
| 
 | |
| optimize:
 | |
|           OPTIMIZE opt_no_write_to_binlog table_or_tables
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_OPTIMIZE;
 | |
|             lex->no_write_to_binlog= $2;
 | |
|             lex->check_opt.init();
 | |
|             lex->alter_info.reset();
 | |
|             /* Will be overridden during execution. */
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|           }
 | |
|           table_list opt_lock_wait_timeout
 | |
|           {
 | |
|             LEX* lex= thd->lex;
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_optimize_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_no_write_to_binlog:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | NO_WRITE_TO_BINLOG { $$= 1; }
 | |
|         | LOCAL_SYM { $$= 1; }
 | |
|         ;
 | |
| 
 | |
| rename:
 | |
|           RENAME table_or_tables opt_if_exists
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_RENAME_TABLE;
 | |
|             Lex->create_info.set($3);
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           table_to_table_list
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | RENAME USER_SYM clear_privileges rename_list
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_RENAME_USER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| rename_list:
 | |
|           user TO_SYM user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($1, thd->mem_root) ||
 | |
|                          Lex->users_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | rename_list ',' user TO_SYM user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($3, thd->mem_root) ||
 | |
|                          Lex->users_list.push_back($5, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_to_table_list:
 | |
|           table_to_table
 | |
|         | table_to_table_list ',' table_to_table
 | |
|         ;
 | |
| 
 | |
| table_to_table:
 | |
|           table_ident opt_lock_wait_timeout TO_SYM table_ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             SELECT_LEX *sl= lex->current_select;
 | |
|             if (unlikely(!sl->add_table_to_list(thd, $1,NULL,
 | |
|                                                 TL_OPTION_UPDATING,
 | |
|                                                 TL_IGNORE, MDL_EXCLUSIVE)) ||
 | |
|                 unlikely(!sl->add_table_to_list(thd, $4, NULL,
 | |
|                                                 TL_OPTION_UPDATING,
 | |
|                                                 TL_IGNORE, MDL_EXCLUSIVE)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| keycache:
 | |
|           CACHE_SYM INDEX_SYM
 | |
|           {
 | |
|             Lex->alter_info.reset();
 | |
|           }
 | |
|           keycache_list_or_parts IN_SYM key_cache_name
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
 | |
|             lex->ident= $6;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| keycache_list_or_parts:
 | |
|           keycache_list
 | |
|         | assign_to_keycache_parts
 | |
|         ;
 | |
| 
 | |
| keycache_list:
 | |
|           assign_to_keycache
 | |
|         | keycache_list ',' assign_to_keycache
 | |
|         ;
 | |
| 
 | |
| assign_to_keycache:
 | |
|           table_ident cache_keys_spec
 | |
|           {
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ,
 | |
|                                                     MDL_SHARED_READ,
 | |
|                                                     Select->
 | |
|                                                     pop_index_hints())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| assign_to_keycache_parts:
 | |
|           table_ident adm_partition cache_keys_spec
 | |
|           {
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $1, NULL, 0, TL_READ,
 | |
|                                                     MDL_SHARED_READ,
 | |
|                                                     Select->
 | |
|                                                     pop_index_hints())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| key_cache_name:
 | |
|           ident    { $$= $1; }
 | |
|         | DEFAULT  { $$ = default_base; }
 | |
|         ;
 | |
| 
 | |
| preload:
 | |
|           LOAD INDEX_SYM INTO CACHE_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command=SQLCOM_PRELOAD_KEYS;
 | |
|             lex->alter_info.reset();
 | |
|             if (lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           preload_list_or_parts
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| preload_list_or_parts:
 | |
|           preload_keys_parts
 | |
|         | preload_list
 | |
|         ;
 | |
| 
 | |
| preload_list:
 | |
|           preload_keys
 | |
|         | preload_list ',' preload_keys
 | |
|         ;
 | |
| 
 | |
| preload_keys:
 | |
|           table_ident cache_keys_spec opt_ignore_leaves
 | |
|           {
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $3, TL_READ,
 | |
|                                                     MDL_SHARED_READ,
 | |
|                                                     Select->
 | |
|                                                     pop_index_hints())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| preload_keys_parts:
 | |
|           table_ident adm_partition cache_keys_spec opt_ignore_leaves
 | |
|           {
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $1, NULL, $4, TL_READ,
 | |
|                                                     MDL_SHARED_READ,
 | |
|                                                     Select->
 | |
|                                                     pop_index_hints())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| adm_partition:
 | |
|           PARTITION_SYM have_partitioning
 | |
|           {
 | |
|             Lex->alter_info.partition_flags|= ALTER_PARTITION_ADMIN;
 | |
|           }
 | |
|           '(' all_or_alt_part_name_list ')'
 | |
|         ;
 | |
| 
 | |
| cache_keys_spec:
 | |
|           {
 | |
|             Lex->first_select_lex()->alloc_index_hints(thd);
 | |
|             Select->set_index_hint_type(INDEX_HINT_USE,
 | |
|                                         INDEX_HINT_MASK_ALL);
 | |
|           }
 | |
|           cache_key_list_or_empty
 | |
|         ;
 | |
| 
 | |
| cache_key_list_or_empty:
 | |
|           /* empty */ { }
 | |
|         | key_or_index '(' opt_key_usage_list ')'
 | |
|         ;
 | |
| 
 | |
| opt_ignore_leaves:
 | |
|           /* empty */
 | |
|           { $$= 0; }
 | |
|         | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Select : retrieve data from table
 | |
| */
 | |
| 
 | |
| 
 | |
| select:
 | |
|           query_expression_no_with_clause
 | |
|           {
 | |
|             if (Lex->push_select($1->fake_select_lex ?
 | |
|                                  $1->fake_select_lex :
 | |
|                                  $1->first_select()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_procedure_or_into
 | |
|           {
 | |
|             Lex->pop_select();
 | |
|             $1->set_with_clause(NULL);
 | |
|             if (Lex->select_finalize($1, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | with_clause query_expression_no_with_clause
 | |
|           {
 | |
|             if (Lex->push_select($2->fake_select_lex ?
 | |
|                                  $2->fake_select_lex :
 | |
|                                  $2->first_select()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_procedure_or_into
 | |
|           {
 | |
|             Lex->pop_select();
 | |
|             $2->set_with_clause($1);
 | |
|             $1->attach_to($2->first_select());
 | |
|             if (Lex->select_finalize($2, $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_into:
 | |
|           select_into_query_specification
 | |
|           {
 | |
|             if (Lex->push_select($1))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_order_limit_lock
 | |
|           {
 | |
|             SELECT_LEX_UNIT *unit;
 | |
|             if (!(unit  = Lex->create_unit($1)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($3)
 | |
|               unit= Lex->add_tail_to_query_expression_body(unit, $3);
 | |
|             if (Lex->select_finalize(unit))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | with_clause
 | |
|           select_into_query_specification
 | |
|           {
 | |
|             if (Lex->push_select($2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_order_limit_lock
 | |
|           {
 | |
|             SELECT_LEX_UNIT *unit;
 | |
|             if (!(unit  = Lex->create_unit($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($4)
 | |
|               unit= Lex->add_tail_to_query_expression_body(unit, $4);
 | |
|             unit->set_with_clause($1);
 | |
|             $1->attach_to($2);
 | |
|             if (Lex->select_finalize(unit))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| simple_table:
 | |
|           query_specification      { $$= $1; }
 | |
|         | table_value_constructor  { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| table_value_constructor:
 | |
| 	  VALUES
 | |
| 	  {
 | |
|             if (Lex->parsed_TVC_start())
 | |
|               MYSQL_YYABORT;
 | |
| 	  }
 | |
| 	  values_list
 | |
| 	  {
 | |
|             if (!($$= Lex->parsed_TVC_end()))
 | |
| 	      MYSQL_YYABORT;
 | |
| 	  }
 | |
| 	;
 | |
| 
 | |
| query_specification_start:
 | |
|           SELECT_SYM
 | |
|           {
 | |
|             SELECT_LEX *sel;
 | |
|             LEX *lex= Lex;
 | |
|             if (!(sel= lex->alloc_select(TRUE)) || lex->push_select(sel))
 | |
|               MYSQL_YYABORT;
 | |
|             sel->init_select();
 | |
|             sel->braces= FALSE;
 | |
|           }
 | |
|           select_options
 | |
|           {
 | |
|             Select->parsing_place= SELECT_LIST;
 | |
|           }
 | |
|           select_item_list
 | |
|           {
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| query_specification:
 | |
|           query_specification_start
 | |
|           opt_from_clause
 | |
|           opt_where_clause
 | |
|           opt_group_clause
 | |
|           opt_having_clause
 | |
|           opt_window_clause
 | |
|           {
 | |
|             $$= Lex->pop_select();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_into_query_specification:
 | |
|           query_specification_start
 | |
|           into
 | |
|           opt_from_clause
 | |
|           opt_where_clause
 | |
|           opt_group_clause
 | |
|           opt_having_clause
 | |
|           opt_window_clause
 | |
|           {
 | |
|             $$= Lex->pop_select();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /**
 | |
| 
 | |
|   The following grammar for query expressions conformant to
 | |
|   the latest SQL Standard is supported:
 | |
| 
 | |
|     <query expression> ::=
 | |
|      [ <with clause> ] <query expression body>
 | |
|        [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
 | |
| 
 | |
|    <with clause> ::=
 | |
|      WITH [ RECURSIVE ] <with_list
 | |
| 
 | |
|    <with list> ::=
 | |
|      <with list element> [ { <comma> <with list element> }... ]
 | |
| 
 | |
|    <with list element> ::=
 | |
|      <query name> [ '(' <with column list> ')' ]
 | |
|          AS <table subquery>
 | |
| 
 | |
|    <with column list> ::=
 | |
|      <column name list>
 | |
| 
 | |
|    <query expression body> ::
 | |
|        <query term>
 | |
|      | <query expression body> UNION [ ALL | DISTINCT ] <query term>
 | |
|      | <query expression body> EXCEPT [ DISTINCT ] <query term>
 | |
| 
 | |
|    <query term> ::=
 | |
|        <query primary>
 | |
|      | <query term> INTERSECT [ DISTINCT ] <query primary>
 | |
| 
 | |
|    <query primary> ::=
 | |
|        <simple table>
 | |
|      | '(' <query expression body>
 | |
|        [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
 | |
|        ')'
 | |
| 
 | |
|    <simple table>
 | |
|        <query specification>
 | |
|      | <table value constructor>
 | |
| 
 | |
|   <subquery>
 | |
|        '(' <query_expression> ')'
 | |
| 
 | |
| */
 | |
| 
 | |
| /*
 | |
|   query_expression produces the same expressions as
 | |
|       <query expression>
 | |
| */
 | |
| 
 | |
| query_expression:
 | |
|           query_expression_no_with_clause
 | |
|           {
 | |
|             $1->set_with_clause(NULL);
 | |
|             $$= $1;
 | |
|           }
 | |
|         | with_clause
 | |
|           query_expression_no_with_clause
 | |
|           {
 | |
|             $2->set_with_clause($1);
 | |
|             $1->attach_to($2->first_select());
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|    query_expression_no_with_clause produces the same expressions as
 | |
|        <query expression> without [ <with clause> ]
 | |
| */
 | |
| 
 | |
| query_expression_no_with_clause:
 | |
|           query_expression_body_ext { $$= $1; }
 | |
|         | query_expression_body_ext_parens { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   query_expression_body_ext produces the same expressions as
 | |
|       <query expression body>
 | |
|        [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
 | |
|     | '('... <query expression body>
 | |
|        [ <order by clause> ] [ <result offset clause> ] [ <fetch first clause> ]
 | |
|       ')'...
 | |
|   Note: number of ')' must be equal to the number of '(' in the rule above
 | |
| */
 | |
| 
 | |
| query_expression_body_ext:
 | |
|           query_expression_body
 | |
|           {
 | |
|             if ($1->first_select()->next_select())
 | |
|             {
 | |
|               if (Lex->parsed_multi_operand_query_expression_body($1))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|           opt_query_expression_tail
 | |
|           {
 | |
|             if (!$3)
 | |
|               $$= $1;
 | |
|             else
 | |
|               $$= Lex->add_tail_to_query_expression_body($1, $3);
 | |
|           }
 | |
|         | query_expression_body_ext_parens
 | |
|           {
 | |
|             Lex->push_select(!$1->first_select()->next_select() ?
 | |
|                                $1->first_select() : $1->fake_select_lex);
 | |
|           }
 | |
|           query_expression_tail
 | |
|           {
 | |
|             if (!($$= Lex->add_tail_to_query_expression_body_ext_parens($1, $3)))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| query_expression_body_ext_parens:
 | |
|           '(' query_expression_body_ext_parens ')'
 | |
|           { $$= $2; }
 | |
|         | '(' query_expression_body_ext ')'
 | |
|           {
 | |
|             SELECT_LEX *sel= $2->first_select()->next_select() ?
 | |
|                                $2->fake_select_lex : $2->first_select();
 | |
|             sel->braces= true;
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   query_expression_body produces the same expressions as
 | |
|       <query expression body>
 | |
| */
 | |
| 
 | |
| query_expression_body:
 | |
|           query_simple
 | |
|           {
 | |
|             Lex->push_select($1);
 | |
|             if (!($$= Lex->create_unit($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | query_expression_body
 | |
|           unit_type_decl
 | |
|           {
 | |
|             if (!$1->first_select()->next_select())
 | |
|             {
 | |
|               Lex->pop_select();
 | |
|             }
 | |
|           }
 | |
|           query_primary
 | |
|           {
 | |
|             if (!($$= Lex->add_primary_to_query_expression_body($1, $4,
 | |
|                                                                 $2.unit_type,
 | |
|                                                                 $2.distinct)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | query_expression_body_ext_parens
 | |
|           unit_type_decl
 | |
|           query_primary
 | |
|           {
 | |
|             if (!($$= Lex->add_primary_to_query_expression_body_ext_parens(
 | |
|                                                                 $1, $3,
 | |
|                                                                 $2.unit_type,
 | |
|                                                                 $2.distinct)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   query_primary produces the same expressions as
 | |
|       <query primary>
 | |
| */
 | |
| 
 | |
| query_primary:
 | |
|           query_simple
 | |
|           { $$= $1; }
 | |
|         | query_expression_body_ext_parens
 | |
|           { $$= $1->first_select(); }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   query_simple produces the same expressions as
 | |
|       <simple table>
 | |
| */
 | |
| 
 | |
| query_simple:
 | |
|           simple_table { $$= $1;}
 | |
|         ;
 | |
| 
 | |
| subselect:
 | |
|           query_expression
 | |
|           {
 | |
|             if (!($$= Lex->parsed_subselect($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   subquery produces the same expressions as
 | |
|      <subquery>
 | |
| 
 | |
|   Consider the production rule of the SQL Standard
 | |
|      subquery:
 | |
|         '(' query_expression ')'
 | |
| 
 | |
|   This rule is equivalent to the rule
 | |
|      subquery:
 | |
|           '(' query_expression_no_with_clause ')'
 | |
|         | '(' with_clause query_expression_no_with_clause ')'
 | |
|   that in its turn is equivalent to
 | |
|      subquery:
 | |
|           '(' query_expression_body_ext ')'
 | |
|         | query_expression_body_ext_parens
 | |
|         | '(' with_clause query_expression_no_with_clause ')'
 | |
| 
 | |
|   The latter can be re-written into
 | |
|      subquery:
 | |
|           query_expression_body_ext_parens
 | |
|         | '(' with_clause query_expression_no_with_clause ')'
 | |
| 
 | |
|   The last rule allows us to resolve properly the shift/reduce conflict
 | |
|   when subquery is used in expressions such as in the following queries
 | |
|      select (select * from t1 limit 1) + t2.a from t2
 | |
|      select * from t1 where t1.a [not] in (select t2.a from t2)
 | |
| 
 | |
|   In the rule below %prec SUBQUERY_AS_EXPR forces the parser to perform a shift
 | |
|   operation rather then a reduce operation when ')' is encountered and can be
 | |
|   considered as the last symbol a query expression.
 | |
| */
 | |
| 
 | |
| subquery:
 | |
|           query_expression_body_ext_parens %prec SUBQUERY_AS_EXPR
 | |
|           {
 | |
|             if (!$1->fake_select_lex)
 | |
|               $1->first_select()->braces= false;
 | |
|             else
 | |
|               $1->fake_select_lex->braces= false;
 | |
|             if (!($$= Lex->parsed_subselect($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '(' with_clause query_expression_no_with_clause ')'
 | |
|           {
 | |
|             $3->set_with_clause($2);
 | |
|             $2->attach_to($3->first_select());
 | |
|             if (!($$= Lex->parsed_subselect($3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_from_clause:
 | |
|         /* empty */ %prec EMPTY_FROM_CLAUSE
 | |
|         | from_clause
 | |
|         ;
 | |
| 
 | |
| from_clause:
 | |
|           FROM table_reference_list
 | |
|         ;
 | |
| 
 | |
| table_reference_list:
 | |
|           join_table_list
 | |
|           {
 | |
|             Select->context.table_list=
 | |
|               Select->context.first_name_resolution_table=
 | |
|                 Select->table_list.first;
 | |
|           }
 | |
|         | DUAL_SYM
 | |
|           /* oracle compatibility: oracle always requires FROM clause,
 | |
|              and DUAL is system table without fields.
 | |
|              Is "SELECT 1 FROM DUAL" any better than "SELECT 1" ?
 | |
|           Hmmm :) */
 | |
|         ;
 | |
| 
 | |
| select_options:
 | |
|           /* empty*/
 | |
|         | select_option_list
 | |
|           {
 | |
|             if (unlikely((Select->options & SELECT_DISTINCT) &&
 | |
|                          (Select->options & SELECT_ALL)))
 | |
|               my_yyabort_error((ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT"));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_history_unit:
 | |
|           /* empty*/         %prec PREC_BELOW_IDENTIFIER_OPT_SPECIAL_CASE
 | |
|           {
 | |
|             $$= VERS_TIMESTAMP;
 | |
|           }
 | |
|         | TRANSACTION_SYM
 | |
|           {
 | |
|             $$= VERS_TRX_ID;
 | |
|           }
 | |
|         | TIMESTAMP
 | |
|           {
 | |
|             $$= VERS_TIMESTAMP;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| history_point:
 | |
|           TIMESTAMP TEXT_STRING
 | |
|           {
 | |
|             Item *item;
 | |
|             if (!(item= type_handler_datetime.create_literal_item(thd,
 | |
|                                                      $2.str, $2.length,
 | |
|                                                      YYCSCL, true)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= Vers_history_point(VERS_TIMESTAMP, item);
 | |
|           }
 | |
|         | function_call_keyword_timestamp
 | |
|           {
 | |
|             $$= Vers_history_point(VERS_TIMESTAMP, $1);
 | |
|           }
 | |
|         | opt_history_unit bit_expr
 | |
|           {
 | |
|             $$= Vers_history_point($1, $2);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| for_portion_of_time_clause:
 | |
|           FOR_SYM PORTION_SYM OF_SYM remember_tok_start ident FROM
 | |
|           bit_expr TO_SYM bit_expr
 | |
|           {
 | |
|             if (unlikely(0 == strcasecmp($5.str, "SYSTEM_TIME")))
 | |
|             {
 | |
|               thd->parse_error(ER_SYNTAX_ERROR, $4);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             Lex->period_conditions.init(SYSTEM_TIME_FROM_TO,
 | |
|                                         Vers_history_point(VERS_TIMESTAMP, $7),
 | |
|                                         Vers_history_point(VERS_TIMESTAMP, $9),
 | |
|                                         Lex_ident_column($5));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_for_portion_of_time_clause:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= false;
 | |
|           }
 | |
|         | for_portion_of_time_clause
 | |
|           {
 | |
|             $$= true;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_for_system_time_clause:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= false;
 | |
|           }
 | |
|         | FOR_SYSTEM_TIME_SYM system_time_expr
 | |
|           {
 | |
|             $$= true;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| system_time_expr:
 | |
|           AS OF_SYM history_point
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_AS_OF, $3);
 | |
|           }
 | |
|         | ALL
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_ALL);
 | |
|           }
 | |
|         | FROM history_point TO_SYM history_point
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_FROM_TO, $2, $4);
 | |
|           }
 | |
|         | BETWEEN_SYM history_point AND_SYM history_point
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_BETWEEN, $2, $4);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_option_list:
 | |
|           select_option_list select_option
 | |
|         | select_option
 | |
|         ;
 | |
| 
 | |
| select_option:
 | |
|           query_expression_option
 | |
|         | SQL_NO_CACHE_SYM
 | |
|           {
 | |
|             /*
 | |
|               Allow this flag once per query.
 | |
|             */
 | |
|             if (Select->options & OPTION_NO_QUERY_CACHE)
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE"));
 | |
|             Select->options|= OPTION_NO_QUERY_CACHE;
 | |
|           }
 | |
|         | SQL_CACHE_SYM
 | |
|           {
 | |
|             /*
 | |
|               Allow this flag once per query.
 | |
|             */
 | |
|             if (Select->options & OPTION_TO_QUERY_CACHE)
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE"));
 | |
|             Select->options|= OPTION_TO_QUERY_CACHE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| select_lock_type:
 | |
|           FOR_SYM UPDATE_SYM opt_lock_wait_timeout_new
 | |
|           {
 | |
|             $$= $3;
 | |
|             $$.defined_lock= TRUE;
 | |
|             $$.update_lock= TRUE;
 | |
|           }
 | |
|         | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM opt_lock_wait_timeout_new
 | |
|           {
 | |
|             $$= $5;
 | |
|             $$.defined_lock= TRUE;
 | |
|             $$.update_lock= FALSE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_select_lock_type:
 | |
|         /* empty */
 | |
|         {
 | |
|           $$.empty();
 | |
|         }
 | |
|         | select_lock_type
 | |
|         {
 | |
|           $$= $1;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_lock_wait_timeout_new:
 | |
|         /* empty */
 | |
|         {
 | |
|           $$.empty();
 | |
|         }
 | |
|         | WAIT_SYM ulong_num
 | |
|         {
 | |
|           $$.empty();
 | |
|           $$.defined_timeout= TRUE;
 | |
|           $$.timeout= $2;
 | |
|         }
 | |
|         | NOWAIT_SYM
 | |
|         {
 | |
|           $$.empty();
 | |
|           $$.defined_timeout= TRUE;
 | |
|           $$.timeout= 0;
 | |
|         }
 | |
|         | SKIP_SYM LOCKED_SYM
 | |
|         {
 | |
|           $$.empty();
 | |
|           $$.skip_locked= 1;
 | |
|           Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SKIP_LOCKED);
 | |
|         }
 | |
|       ;
 | |
| 
 | |
| select_item_list:
 | |
|           select_item_list ',' select_item
 | |
|         | select_item
 | |
|         | '*'
 | |
|           {
 | |
|             bool is_parsing_returning=
 | |
|                               thd->lex->current_select->parsing_place ==
 | |
|                                                 IN_RETURNING;
 | |
|             SELECT_LEX *correct_select= is_parsing_returning ?
 | |
|                                               thd->lex->returning() :
 | |
|                                               thd->lex->current_select;
 | |
|             Item *item= new (thd)
 | |
|                           Item_field(thd, &correct_select->context,
 | |
|                                      star_clex_str);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(add_item_to_list(thd, item)))
 | |
|               MYSQL_YYABORT;
 | |
|             correct_select->with_wild++;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_item:
 | |
|           remember_name select_sublist_qualified_asterisk remember_end
 | |
|           {
 | |
|             if (unlikely(add_item_to_list(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | remember_name expr remember_end select_alias
 | |
|           {
 | |
|             DBUG_ASSERT($1 < $3);
 | |
| 
 | |
|             if (unlikely(add_item_to_list(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($4.str)
 | |
|             {
 | |
|               if (unlikely(Lex->sql_command == SQLCOM_CREATE_VIEW &&
 | |
|                           check_column_name($4.str)))
 | |
|                 my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), $4.str));
 | |
|               $2->base_flags|= item_base_t::IS_EXPLICIT_NAME;
 | |
|               $2->set_name(thd, $4);
 | |
|             }
 | |
|             else if (!$2->name.str || $2->name.str == item_empty_name)
 | |
|             {
 | |
|               $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_tok_start:
 | |
|           {
 | |
|             $$= (char*) YYLIP->get_tok_start();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_name:
 | |
|           {
 | |
|             $$= (char*) YYLIP->get_cpp_tok_start();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_end:
 | |
|           {
 | |
|             $$= (char*) YYLIP->get_cpp_tok_end_rtrim();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_cpp_ptr:
 | |
|           {
 | |
|             $$= (char*) YYLIP->get_cpp_ptr();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_start_opt:
 | |
|           {
 | |
|             if (yychar == YYEMPTY)
 | |
|               $$= (char*) YYLIP->get_cpp_ptr();
 | |
|             else
 | |
|               $$= (char*) YYLIP->get_cpp_tok_start();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_end_opt:
 | |
|           {
 | |
|             if (yychar == YYEMPTY)
 | |
|               $$= (char*) YYLIP->get_cpp_ptr_rtrim();
 | |
|             else
 | |
|               $$= (char*) YYLIP->get_cpp_tok_end_rtrim();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| remember_lex:
 | |
|           {
 | |
|             $$= thd->lex;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_alias:
 | |
|           /* empty */ { $$=null_clex_str;}
 | |
|         | AS ident { $$=$2; }
 | |
|         | AS TEXT_STRING_sys { $$=$2; }
 | |
|         | ident { $$=$1; }
 | |
|         | TEXT_STRING_sys { $$=$1; }
 | |
|         ;
 | |
| 
 | |
| opt_default_time_precision:
 | |
|           /* empty */             { $$= NOT_FIXED_DEC;  }
 | |
|         | '(' ')'                 { $$= NOT_FIXED_DEC;  }
 | |
|         | '(' real_ulong_num ')'  { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| opt_time_precision:
 | |
|           /* empty */             { $$= 0;  }
 | |
|         | '(' ')'                 { $$= 0;  }
 | |
|         | '(' real_ulong_num ')'  { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| optional_braces:
 | |
|           /* empty */ {}
 | |
|         | '(' ')' {}
 | |
|         ;
 | |
| 
 | |
| search_condition:
 | |
|           expr { ($$= $1)->base_flags|= item_base_t::IS_COND ; }
 | |
|         ;
 | |
| 
 | |
| /* all possible expressions */
 | |
| expr:
 | |
|           expr or expr %prec OR_SYM
 | |
|           {
 | |
|             /*
 | |
|               Design notes:
 | |
|               Do not use a manually maintained stack like thd->lex->xxx_list,
 | |
|               but use the internal bison stack ($$, $1 and $3) instead.
 | |
|               Using the bison stack is:
 | |
|               - more robust to changes in the grammar,
 | |
|               - guaranteed to be in sync with the parser state,
 | |
|               - better for performances (no memory allocation).
 | |
|             */
 | |
|             Item_cond_or *item1;
 | |
|             Item_cond_or *item3;
 | |
|             if (is_cond_or($1))
 | |
|             {
 | |
|               item1= (Item_cond_or*) $1;
 | |
|               if (is_cond_or($3))
 | |
|               {
 | |
|                 item3= (Item_cond_or*) $3;
 | |
|                 /*
 | |
|                   (X1 OR X2) OR (Y1 OR Y2) ==> OR (X1, X2, Y1, Y2)
 | |
|                 */
 | |
|                 item3->add_at_head(item1->argument_list());
 | |
|                 $$ = $3;
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 /*
 | |
|                   (X1 OR X2) OR Y ==> OR (X1, X2, Y)
 | |
|                 */
 | |
|                 item1->add($3, thd->mem_root);
 | |
|                 $$ = $1;
 | |
|               }
 | |
|             }
 | |
|             else if (is_cond_or($3))
 | |
|             {
 | |
|               item3= (Item_cond_or*) $3;
 | |
|               /*
 | |
|                 X OR (Y1 OR Y2) ==> OR (X, Y1, Y2)
 | |
|               */
 | |
|               item3->add_at_head($1, thd->mem_root);
 | |
|               $$ = $3;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               /* X OR Y */
 | |
|               $$= new (thd) Item_cond_or(thd, $1, $3);
 | |
|               if (unlikely($$ == NULL))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | expr XOR expr %prec XOR
 | |
|           {
 | |
|             /* XOR is a proprietary extension */
 | |
|             $$= new (thd) Item_func_xor(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | expr and expr %prec AND_SYM
 | |
|           {
 | |
|             /* See comments in rule expr: expr or expr */
 | |
|             Item_cond_and *item1;
 | |
|             Item_cond_and *item3;
 | |
|             if (is_cond_and($1))
 | |
|             {
 | |
|               item1= (Item_cond_and*) $1;
 | |
|               if (is_cond_and($3))
 | |
|               {
 | |
|                 item3= (Item_cond_and*) $3;
 | |
|                 /*
 | |
|                   (X1 AND X2) AND (Y1 AND Y2) ==> AND (X1, X2, Y1, Y2)
 | |
|                 */
 | |
|                 item3->add_at_head(item1->argument_list());
 | |
|                 $$ = $3;
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 /*
 | |
|                   (X1 AND X2) AND Y ==> AND (X1, X2, Y)
 | |
|                 */
 | |
|                 item1->add($3, thd->mem_root);
 | |
|                 $$ = $1;
 | |
|               }
 | |
|             }
 | |
|             else if (is_cond_and($3))
 | |
|             {
 | |
|               item3= (Item_cond_and*) $3;
 | |
|               /*
 | |
|                 X AND (Y1 AND Y2) ==> AND (X, Y1, Y2)
 | |
|               */
 | |
|               item3->add_at_head($1, thd->mem_root);
 | |
|               $$ = $3;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               /* X AND Y */
 | |
|               $$= new (thd) Item_cond_and(thd, $1, $3);
 | |
|               if (unlikely($$ == NULL))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | NOT_SYM expr
 | |
|           {
 | |
|             $$= negate_expression(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test %prec PREC_BELOW_NOT
 | |
|         ;
 | |
| 
 | |
| boolean_test:
 | |
|           boolean_test IS TRUE_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_istrue(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS not TRUE_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnottrue(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS FALSE_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isfalse(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS not FALSE_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnotfalse(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS UNKNOWN_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnull(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS not UNKNOWN_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnotnull(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS NULL_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnull(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test IS not NULL_SYM %prec IS
 | |
|           {
 | |
|             $$= new (thd) Item_func_isnotnull(thd, $1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test EQUAL_SYM predicate %prec EQUAL_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_func_equal(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test comp_op predicate %prec '='
 | |
|           {
 | |
|             $$= (*$2)(0)->create(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | boolean_test comp_op all_or_any '(' subselect ')' %prec '='
 | |
|           {
 | |
|             $$= all_any_subquery_creator(thd, $1, $2, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate %prec BETWEEN_SYM
 | |
|         ;
 | |
| 
 | |
| predicate:
 | |
|           predicate IN_SYM subquery
 | |
|           {
 | |
|             $$= new (thd) Item_in_subselect(thd, $1, $3);
 | |
|             if (unlikely(!$$))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not IN_SYM subquery
 | |
|           {
 | |
|             Item *item= new (thd) Item_in_subselect(thd, $1, $4);
 | |
|             if (unlikely(!item))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= negate_expression(thd, item);
 | |
|             if (unlikely(!$$))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate IN_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= handle_sql2003_note184_exception(thd, $1, true, $4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate IN_SYM '(' expr ',' expr_list ')'
 | |
|           {
 | |
|             $6->push_front($4, thd->mem_root);
 | |
|             $6->push_front($1, thd->mem_root);
 | |
|             $$= new (thd) Item_func_in(thd, *$6);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not IN_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= handle_sql2003_note184_exception(thd, $1, false, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not IN_SYM '(' expr ',' expr_list ')'
 | |
|           {
 | |
|             $7->push_front($5, thd->mem_root);
 | |
|             $7->push_front($1, thd->mem_root);
 | |
|             Item_func_in *item= new (thd) Item_func_in(thd, *$7);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= item->neg_transformer(thd);
 | |
|           }
 | |
|         | predicate BETWEEN_SYM predicate AND_SYM predicate %prec BETWEEN_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_func_between(thd, $1, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not BETWEEN_SYM predicate AND_SYM predicate %prec BETWEEN_SYM
 | |
|           {
 | |
|             Item_func_between *item;
 | |
|             item= new (thd) Item_func_between(thd, $1, $4, $6);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= item->neg_transformer(thd);
 | |
|           }
 | |
|         | predicate SOUNDS_SYM LIKE predicate
 | |
|           {
 | |
|             Item *item1= new (thd) Item_func_soundex(thd, $1);
 | |
|             Item *item4= new (thd) Item_func_soundex(thd, $4);
 | |
|             if (unlikely(item1 == NULL) || unlikely(item4 == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_func_eq(thd, item1, item4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate LIKE predicate
 | |
|           {
 | |
|             $$= new (thd) Item_func_like(thd, $1, $3, escape(thd), false);
 | |
|             if (unlikely(!$$))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate LIKE predicate ESCAPE_SYM predicate %prec LIKE
 | |
|           {
 | |
|             Lex->escape_used= true;
 | |
|             $$= new (thd) Item_func_like(thd, $1, $3, $5, true);
 | |
|             if (unlikely(!$$))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not LIKE predicate
 | |
|           {
 | |
|             Item *item= new (thd) Item_func_like(thd, $1, $4, escape(thd), false);
 | |
|             if (unlikely(!item))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= item->neg_transformer(thd);
 | |
|           }
 | |
|         | predicate not LIKE predicate ESCAPE_SYM predicate %prec LIKE
 | |
|           {
 | |
|             Lex->escape_used= true;
 | |
|             Item *item= new (thd) Item_func_like(thd, $1, $4, $6, true);
 | |
|             if (unlikely(!item))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= item->neg_transformer(thd);
 | |
|           }
 | |
|         | predicate REGEXP predicate
 | |
|           {
 | |
|             $$= new (thd) Item_func_regex(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | predicate not REGEXP predicate
 | |
|           {
 | |
|             Item *item= new (thd) Item_func_regex(thd, $1, $4);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= negate_expression(thd, item);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr %prec PREC_BELOW_NOT
 | |
|         ;
 | |
| 
 | |
| bit_expr:
 | |
|           bit_expr '|' bit_expr %prec '|'
 | |
|           {
 | |
|             $$= new (thd) Item_func_bit_or(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '&' bit_expr %prec '&'
 | |
|           {
 | |
|             $$= new (thd) Item_func_bit_and(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
 | |
|           {
 | |
|             $$= new (thd) Item_func_shift_left(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
 | |
|           {
 | |
|             $$= new (thd) Item_func_shift_right(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr ORACLE_CONCAT_SYM bit_expr
 | |
|           {
 | |
|             $$= new (thd) Item_func_concat_operator_oracle(thd,
 | |
|                                                                      $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '+' bit_expr %prec '+'
 | |
|           {
 | |
|             $$= new (thd) Item_func_plus(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '-' bit_expr %prec '-'
 | |
|           {
 | |
|             $$= new (thd) Item_func_minus(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '+' INTERVAL_SYM expr interval %prec '+'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $1, $4, $5, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '-' INTERVAL_SYM expr interval %prec '-'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $1, $4, $5, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | INTERVAL_SYM expr interval '+' expr
 | |
|           /* we cannot put interval before - */
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $5, $2, $3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '+' INTERVAL_SYM expr interval '+' expr %prec NEG
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $6, $3, $4, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '-' INTERVAL_SYM expr interval '+' expr %prec NEG
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $6, $3, $4, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '*' bit_expr %prec '*'
 | |
|           {
 | |
|             $$= new (thd) Item_func_mul(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '/' bit_expr %prec '/'
 | |
|           {
 | |
|             $$= new (thd) Item_func_div(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '%' bit_expr %prec '%'
 | |
|           {
 | |
|             $$= new (thd) Item_func_mod(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr DIV_SYM bit_expr %prec DIV_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_func_int_div(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr MOD_SYM bit_expr %prec MOD_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_func_mod(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | bit_expr '^' bit_expr
 | |
|           {
 | |
|             $$= new (thd) Item_func_bit_xor(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | mysql_concatenation_expr %prec '^'
 | |
|         ;
 | |
| 
 | |
| or:
 | |
|           OR_SYM
 | |
|        | OR2_SYM
 | |
|        ;
 | |
| 
 | |
| and:
 | |
|           AND_SYM
 | |
|        | AND_AND_SYM
 | |
|        ;
 | |
| 
 | |
| not:
 | |
|           NOT_SYM
 | |
|         | NOT2_SYM
 | |
|         ;
 | |
| 
 | |
| not2:
 | |
|           '!'
 | |
|         | NOT2_SYM
 | |
|         ;
 | |
| 
 | |
| comp_op:
 | |
|           '='     { $$ = &comp_eq_creator; }
 | |
|         | GE     { $$ = &comp_ge_creator; }
 | |
|         | '>' { $$ = &comp_gt_creator; }
 | |
|         | LE     { $$ = &comp_le_creator; }
 | |
|         | '<'     { $$ = &comp_lt_creator; }
 | |
|         | NE     { $$ = &comp_ne_creator; }
 | |
|         ;
 | |
| 
 | |
| all_or_any:
 | |
|           ALL     { $$ = 1; }
 | |
|         | ANY_SYM { $$ = 0; }
 | |
|         ;
 | |
| 
 | |
| opt_dyncol_type:
 | |
|           /* empty */ 
 | |
|           {
 | |
|             $$.set(DYN_COL_NULL); /* automatic type */
 | |
| 	  }
 | |
|         | AS dyncol_type { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| dyncol_type:
 | |
|           numeric_dyncol_type
 | |
|         | temporal_dyncol_type
 | |
|         | string_dyncol_type
 | |
|         ;
 | |
| 
 | |
| 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_scale        { $$.set(DYN_COL_TIME, $2); }
 | |
|         | DATETIME opt_field_scale        { $$.set(DYN_COL_DATETIME, $2); }
 | |
|         ;
 | |
| 
 | |
| string_dyncol_type:
 | |
|           char opt_binary
 | |
|           {
 | |
|             if ($$.set(DYN_COL_STRING, thd,
 | |
|                        thd->variables.character_set_collations,
 | |
|                        $2, thd->variables.collation_connection))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | nchar
 | |
|           {
 | |
|             $$.set(DYN_COL_STRING, national_charset_info);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| dyncall_create_element:
 | |
|    expr ',' expr opt_dyncol_type
 | |
|    {
 | |
|      $$= (DYNCALL_CREATE_DEF *)
 | |
|        alloc_root(thd->mem_root, sizeof(DYNCALL_CREATE_DEF));
 | |
|      if (unlikely($$ == NULL))
 | |
|        MYSQL_YYABORT;
 | |
|      $$->key= $1;
 | |
|      $$->value= $3;
 | |
|      $$->type= (DYNAMIC_COLUMN_TYPE)$4.dyncol_type();
 | |
|      $$->cs= $4.charset_collation();
 | |
|      if ($4.has_explicit_length())
 | |
|        $$->len= $4.length();
 | |
|      else
 | |
|        $$->len= 0;
 | |
|      if ($4.has_explicit_dec())
 | |
|        $$->frac= $4.dec();
 | |
|      else
 | |
|        $$->len= 0;
 | |
|    }
 | |
|    ;
 | |
| 
 | |
| dyncall_create_list:
 | |
|      dyncall_create_element
 | |
|        {
 | |
|          $$= new (thd) List<DYNCALL_CREATE_DEF>;
 | |
|          if (unlikely($$ == NULL))
 | |
|            MYSQL_YYABORT;
 | |
|          $$->push_back($1, thd->mem_root);
 | |
|        }
 | |
|    | dyncall_create_list ',' dyncall_create_element
 | |
|        {
 | |
|          $1->push_back($3, thd->mem_root);
 | |
|          $$= $1;
 | |
|        }
 | |
|    ;
 | |
| 
 | |
| 
 | |
| plsql_cursor_attr:
 | |
|           ISOPEN_SYM    { $$= PLSQL_CURSOR_ATTR_ISOPEN; }
 | |
|         | FOUND_SYM     { $$= PLSQL_CURSOR_ATTR_FOUND; }
 | |
|         | NOTFOUND_SYM  { $$= PLSQL_CURSOR_ATTR_NOTFOUND; }
 | |
|         | ROWCOUNT_SYM  { $$= PLSQL_CURSOR_ATTR_ROWCOUNT; }
 | |
|         ;
 | |
| 
 | |
| explicit_cursor_attr:
 | |
|           ident PERCENT_ORACLE_SYM plsql_cursor_attr
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_plsql_cursor_attr(thd, &$1, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| trim_operands:
 | |
|           trim_operands_regular
 | |
|         | trim_operands_special
 | |
|         ;
 | |
| 
 | |
| trim_operands_regular:
 | |
|           expr                     { $$.set(TRIM_BOTH, $1);         }
 | |
|         ;
 | |
| 
 | |
| trim_operands_special:
 | |
|           LEADING  expr FROM expr  { $$.set(TRIM_LEADING, $2, $4);  }
 | |
|         | TRAILING expr FROM expr  { $$.set(TRIM_TRAILING, $2, $4); }
 | |
|         | BOTH     expr FROM expr  { $$.set(TRIM_BOTH, $2, $4);     }
 | |
|         | LEADING       FROM expr  { $$.set(TRIM_LEADING, $3);      }
 | |
|         | TRAILING      FROM expr  { $$.set(TRIM_TRAILING, $3);     }
 | |
|         | BOTH          FROM expr  { $$.set(TRIM_BOTH, $3);         }
 | |
|         | expr          FROM expr  { $$.set(TRIM_BOTH, $1, $3);     }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   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
 | |
|         | literal
 | |
|         | param_marker { $$= $1; }
 | |
|         | variable
 | |
|         | sum_expr
 | |
|           {
 | |
|             if (!Lex->select_stack_top || Lex->json_table)
 | |
|             {
 | |
|               my_error(ER_INVALID_GROUP_FUNC_USE, MYF(0));
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | window_func_expr
 | |
|           {
 | |
|             if (!Lex->select_stack_top)
 | |
|             {
 | |
|                my_error(ER_WRONG_PLACEMENT_OF_WINDOW_FUNCTION, MYF(0));
 | |
|                MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | inverse_distribution_function
 | |
|         | ROW_SYM '(' expr ',' expr_list ')'
 | |
|           {
 | |
|             $5->push_front($3, thd->mem_root);
 | |
|             $$= new (thd) Item_row(thd, *$5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | EXISTS '(' subselect ')'
 | |
|           {
 | |
|             $$= new (thd) Item_exists_subselect(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '{' ident expr '}'
 | |
|           {
 | |
|             if (unlikely(!($$= $3->make_odbc_literal(thd, &$2))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
 | |
|           {
 | |
|             $2->push_front($5, thd->mem_root);
 | |
|             Item_func_match *i1= new (thd) Item_func_match(thd, *$2,
 | |
|                                                                      $6);
 | |
|             if (unlikely(i1 == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->add_ftfunc_to_list(thd, i1);
 | |
|             $$= i1;
 | |
|           }
 | |
|         | CAST_SYM '(' expr AS cast_type ')'
 | |
|           {
 | |
|             if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CASE_SYM when_list_opt_else END
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd) Item_func_case_searched(thd, *$2))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CASE_SYM expr when_list_opt_else END
 | |
|           {
 | |
|             $3->push_front($2, thd->mem_root);
 | |
|             if (unlikely(!($$= new (thd) Item_func_case_simple(thd, *$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONVERT_SYM '(' expr ',' cast_type ')'
 | |
|           {
 | |
|             if (unlikely(!($$= $5.create_typecast_item_or_error(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONVERT_SYM '(' expr USING charset_name ')'
 | |
|           {
 | |
|             $5= thd->variables.character_set_collations.
 | |
|                                  get_collation_for_charset(thd, $5);
 | |
|             $$= new (thd) Item_func_conv_charset(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DEFAULT '(' simple_ident ')'
 | |
|           {
 | |
|             Item_splocal *il= $3->get_item_splocal();
 | |
|             if (unlikely(il))
 | |
|               my_yyabort_error((ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str));
 | |
|             $$= new (thd) Item_default_value(thd, Lex->current_context(),
 | |
|                                                          $3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->default_used= TRUE;
 | |
|           }
 | |
|         | VALUE_SYM '(' simple_ident_nospvar ')'
 | |
|           {
 | |
|             $$= new (thd) Item_insert_value(thd, Lex->current_context(),
 | |
|                                                         $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NEXT_SYM VALUE_SYM FOR_SYM table_ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_nextval(thd, $4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NEXTVAL_SYM '(' table_ident ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_nextval(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_lastval(thd, $4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LASTVAL_SYM '(' table_ident ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_lastval(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SETVAL_SYM '(' table_ident ',' sequence_value_hybrid_num ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0,
 | |
|                                                             1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SETVAL_SYM '(' table_ident ',' sequence_value_hybrid_num ',' bool ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, 0,
 | |
|                                                             $7))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SETVAL_SYM '(' table_ident ',' sequence_value_hybrid_num ',' bool ','
 | |
|           ulonglong_num ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_func_setval(thd, $3, $5, $9,
 | |
|                                                             $7))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| primary_expr:
 | |
|           column_default_non_parenthesized_expr
 | |
|         | explicit_cursor_attr
 | |
|         | '(' parenthesized_expr ')' { $$= $2; }
 | |
|         | subquery
 | |
|           {
 | |
|             if (!($$= Lex->create_item_query_expression(thd, $1->master_unit())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| string_factor_expr:
 | |
|           primary_expr
 | |
|         | string_factor_expr COLLATE_SYM collation_name
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd)
 | |
|                                Item_func_set_collation(thd, $1, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| simple_expr:
 | |
|           string_factor_expr %prec NEG
 | |
|         | BINARY simple_expr
 | |
|           {
 | |
|             Type_cast_attributes at(&my_charset_bin);
 | |
|             if (unlikely(!($$= type_handler_long_blob.create_typecast_item(thd, $2, at))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '+' simple_expr %prec NEG
 | |
|           {
 | |
|             $$= $2;
 | |
|           }
 | |
|         | '-' simple_expr %prec NEG
 | |
|           {
 | |
|             $$= $2->neg(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '~' simple_expr %prec NEG
 | |
|           {
 | |
|             $$= new (thd) Item_func_bit_neg(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | not2 simple_expr %prec NEG
 | |
|           {
 | |
|             $$= negate_expression(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| mysql_concatenation_expr:
 | |
|           simple_expr
 | |
|         | mysql_concatenation_expr MYSQL_CONCAT_SYM simple_expr
 | |
|           {
 | |
|             $$= new (thd) Item_func_concat(thd, $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| function_call_keyword_timestamp:
 | |
|           TIMESTAMP '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_datetime_typecast(thd, $3,
 | |
|                                       AUTO_SEC_PART_DIGITS);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TIMESTAMP '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_timestamp(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| /*
 | |
|   Function call syntax using official SQL 2003 keywords.
 | |
|   Because the function name is an official token,
 | |
|   a dedicated grammar rule is needed in the parser.
 | |
|   There is no potential for conflicts
 | |
| */
 | |
| function_call_keyword:
 | |
|           CHAR_SYM '(' expr_list ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_char(thd, *$3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CHAR_SYM '(' expr_list USING charset_name ')'
 | |
|           {
 | |
|             $5= thd->variables.character_set_collations.
 | |
|                                  get_collation_for_charset(thd, $5);
 | |
|             $$= new (thd) Item_func_char(thd, *$3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CURRENT_USER optional_braces
 | |
|           {
 | |
|             $$= new (thd) Item_func_current_user(thd,
 | |
|                                       Lex->current_context());
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->safe_to_cache_query= 0;
 | |
|           }
 | |
|         | CURRENT_ROLE optional_braces
 | |
|           {
 | |
|             $$= new (thd) Item_func_current_role(thd,
 | |
|                                       Lex->current_context());
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->safe_to_cache_query= 0;
 | |
|           }
 | |
|         | DATE_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_typecast(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_date_funcs_used_flag();
 | |
|           }
 | |
|         | DAY_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_dayofmonth(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | HOUR_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_hour(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | INSERT '(' expr ',' expr ',' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_insert(thd, $3, $5, $7, $9);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | INTERVAL_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             List<Item> *list= new (thd) List<Item>;
 | |
|             if (unlikely(list == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(list->push_front($5, thd->mem_root)) ||
 | |
|                 unlikely(list->push_front($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             Item_row *item= new (thd) Item_row(thd, *list);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_func_interval(thd, item);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')'
 | |
|           {
 | |
|             $7->push_front($5, thd->mem_root);
 | |
|             $7->push_front($3, thd->mem_root);
 | |
|             Item_row *item= new (thd) Item_row(thd, *$7);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_func_interval(thd, item);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LEFT '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_left(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MINUTE_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_minute(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MONTH_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_month(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_date_funcs_used_flag();
 | |
|           }
 | |
|         | RIGHT '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_right(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SECOND_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_second(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SQL_SYM PERCENT_ORACLE_SYM ROWCOUNT_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_func_oracle_sql_rowcount(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->safe_to_cache_query= 0;
 | |
|           }
 | |
|         | SESSION_USER_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_session_user(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | TIME_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_time_typecast(thd, $3,
 | |
|                                       AUTO_SEC_PART_DIGITS);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | function_call_keyword_timestamp
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         | TRIM '(' trim_operands ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Schema::find_implied(thd)->
 | |
|                                  make_item_func_trim(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | USER_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_user(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | YEAR_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_year(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|              Lex->set_date_funcs_used_flag();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| substring_operands:
 | |
|           substring_operands_regular
 | |
|         | substring_operands_special
 | |
|         ;
 | |
| 
 | |
| substring_operands_regular:
 | |
|           expr ',' expr ',' expr
 | |
|           {
 | |
|             $$= Lex_substring_spec_st::init($1, $3, $5);
 | |
|           }
 | |
|         | expr ',' expr
 | |
|           {
 | |
|             $$= Lex_substring_spec_st::init($1, $3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| substring_operands_special:
 | |
|           expr FROM expr FOR_SYM expr
 | |
|           {
 | |
|             $$= Lex_substring_spec_st::init($1, $3, $5);
 | |
|           }
 | |
|         | expr FROM expr
 | |
|           {
 | |
|             $$= Lex_substring_spec_st::init($1, $3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| /*
 | |
|   Function calls using non reserved keywords, with special syntaxic forms.
 | |
|   Dedicated grammar rules are needed because of the syntax,
 | |
|   but also have the potential to cause incompatibilities with other
 | |
|   parts of the language.
 | |
|   MAINTAINER:
 | |
|   The only reasons a function should be added here are:
 | |
|   - for compatibility reasons with another SQL syntax (CURDATE),
 | |
|   - for typing reasons (GET_FORMAT)
 | |
|   Any other 'Syntaxic sugar' enhancements should be *STRONGLY*
 | |
|   discouraged.
 | |
| */
 | |
| function_call_nonkeyword:
 | |
|         ADDDATE_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $5,
 | |
|                                                              INTERVAL_DAY, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $6, $7, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CURDATE optional_braces
 | |
|           {
 | |
|             $$= new (thd) Item_func_curdate_local(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | CURTIME opt_time_precision
 | |
|           {
 | |
|             $$= new (thd) Item_func_curtime_local(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $6, $7, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $6, $7, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | EXTRACT_SYM '(' interval FROM expr ')'
 | |
|           {
 | |
|             $$=new (thd) Item_extract(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | GET_FORMAT '(' date_time_type  ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_get_format(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LOCALTIMESTAMP opt_time_precision
 | |
|           {
 | |
|             $$= new (thd) Item_func_now_local(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query= false;
 | |
|           }
 | |
|         | NOW_SYM opt_time_precision
 | |
|           {
 | |
|             $$= new (thd) Item_func_current_timestamp(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | POSITION_SYM '(' bit_expr IN_SYM expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_locate(thd, $5, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|          | ROWNUM_SYM
 | |
| %ifdef MARIADB
 | |
|            '(' ')'
 | |
| %else
 | |
|            optional_braces
 | |
| %endif ORACLE
 | |
|           {
 | |
|             $$= new (thd) Item_func_rownum(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SUBDATE_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $5,
 | |
|                                                              INTERVAL_DAY, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $3, $6, $7, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SUBSTRING '(' substring_operands ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Schema::find_implied(thd)->
 | |
|                                  make_item_func_substr(thd, $3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
| %ifdef ORACLE
 | |
|         | SYSDATE
 | |
|           {
 | |
|              if (unlikely(!($$= Lex->make_item_func_sysdate(thd, 0))))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
| %endif
 | |
|         | SYSDATE '(' ')'
 | |
|           {
 | |
|              if (unlikely(!($$= Lex->make_item_func_sysdate(thd, 0))))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|         | SYSDATE '(' real_ulong_num ')'
 | |
|           {
 | |
|              if (unlikely(!($$= Lex->make_item_func_sysdate(thd, (uint) $3))))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|         | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_date_add_interval(thd, $7, $5, $3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_timestamp_diff(thd, $5, $7, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TRIM_ORACLE '(' trim_operands ')'
 | |
|           {
 | |
|             if (unlikely(!($$= $3.make_item_func_trim_oracle(thd))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | UTC_DATE_SYM optional_braces
 | |
|           {
 | |
|             $$= new (thd) Item_func_curdate_utc(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | UTC_TIME_SYM opt_time_precision
 | |
|           {
 | |
|             $$= new (thd) Item_func_curtime_utc(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         | UTC_TIMESTAMP_SYM opt_time_precision
 | |
|           {
 | |
|             $$= new (thd) Item_func_now_utc(thd, $2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->safe_to_cache_query=0;
 | |
|           }
 | |
|         |
 | |
|           COLUMN_ADD_SYM '(' expr ',' dyncall_create_list ')'
 | |
|           {
 | |
|             $$= create_func_dyncol_add(thd, $3, *$5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           COLUMN_DELETE_SYM '(' expr ',' expr_list ')'
 | |
|           {
 | |
|             $$= create_func_dyncol_delete(thd, $3, *$5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           COLUMN_CREATE_SYM '(' dyncall_create_list ')'
 | |
|           {
 | |
|             $$= create_func_dyncol_create(thd, *$3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
 | |
|           {
 | |
|             $$= create_func_dyncol_get(thd, $3, $5, $7.type_handler(),
 | |
|                                         $7, $7.charset());
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Functions calls using a non reserved keyword, and using a regular syntax.
 | |
|   Because the non reserved keyword is used in another part of the grammar,
 | |
|   a dedicated rule is needed here.
 | |
| */
 | |
| function_call_conflict:
 | |
|           ASCII_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_ascii(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CHARSET '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_charset(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | IF_SYM '(' expr ',' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_if(thd, $3, $5, $7);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           /* 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) List<Item>;
 | |
|             if (unlikely(list == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             list->push_back($3, thd->mem_root);
 | |
| 
 | |
|             $$= new (thd) Item_func_last_value(thd, *list);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LAST_VALUE '(' expr_list ',' expr ')'
 | |
|           {
 | |
|             $3->push_back($5, thd->mem_root);
 | |
|             $$= new (thd) Item_func_last_value(thd, *$3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MOD_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_mod(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PASSWORD_SYM '(' expr ')'
 | |
|           {
 | |
|             Item* i1;
 | |
|             i1= new (thd) Item_func_password(thd, $3);
 | |
|             if (unlikely(i1 == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= i1;
 | |
|           }
 | |
|         | REPEAT_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_repeat(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | REPLACE '(' expr ',' expr ',' expr ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Schema::find_implied(thd)->
 | |
|                                  make_item_func_replace(thd, $3, $5, $7))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TRUNCATE_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_round(thd, $3, $5, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_weight_string(thd, $3, 0, 0, $4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | WEIGHT_STRING_SYM '(' expr AS CHAR_SYM ws_nweights opt_ws_levels ')'
 | |
|           {
 | |
|             $$= new (thd)
 | |
|                 Item_func_weight_string(thd, $3, 0, $6,
 | |
|                                         $7 | MY_STRXFRM_PAD_WITH_SPACE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | WEIGHT_STRING_SYM '(' expr AS BINARY ws_nweights ')'
 | |
|           {
 | |
|             Item *item= new (thd) Item_char_typecast(thd, $3, $6,
 | |
|                                                                &my_charset_bin);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd)
 | |
|                 Item_func_weight_string(thd, item, 0, $6,
 | |
|                                         MY_STRXFRM_PAD_WITH_SPACE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | WEIGHT_STRING_SYM '(' expr ',' ulong_num ',' ulong_num ',' ulong_num ')'
 | |
|           {
 | |
|             $$= new (thd) Item_func_weight_string(thd, $3, $5, $7,
 | |
|                                                             $9);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Regular function calls.
 | |
|   The function name is *not* a token, and therefore is guaranteed to not
 | |
|   introduce side effects to the language in general.
 | |
|   MAINTAINER:
 | |
|   All the new functions implemented for new features should fit into
 | |
|   this category. The place to implement the function itself is
 | |
|   in sql/item_create.cc
 | |
| */
 | |
| function_call_generic:
 | |
|           ident_func '('
 | |
|           {
 | |
| #ifdef HAVE_DLOPEN
 | |
|             udf_func *udf= 0;
 | |
|             LEX *lex= Lex;
 | |
|             if (using_udf_functions &&
 | |
|                 (udf= find_udf($1.str, $1.length)) &&
 | |
|                 udf->type == UDFTYPE_AGGREGATE)
 | |
|             {
 | |
|               if (unlikely(lex->current_select->inc_in_sum_expr()))
 | |
|               {
 | |
|                 thd->parse_error();
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
|             }
 | |
|             /* Temporary placing the result of find_udf in $3 */
 | |
|             $<udf>$= udf;
 | |
| #endif
 | |
|           }
 | |
|           opt_udf_expr_list ')'
 | |
|           {
 | |
|             const Type_handler *h;
 | |
|             Create_func *builder;
 | |
|             Item *item= NULL;
 | |
|             sp_record* rec= NULL;
 | |
| 
 | |
|             if (unlikely(Lex_ident_routine::check_name_with_error($1)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             /*
 | |
|               Implementation note:
 | |
|               names are resolved with the following order:
 | |
|               - MySQL native functions,
 | |
|               - User Defined Functions,
 | |
|               - Constructors, like POINT(1,1)
 | |
|               - Stored Functions (assuming the current <use> database)
 | |
| 
 | |
|               This will be revised with WL#2128 (SQL PATH)
 | |
|             */
 | |
|             builder= Schema::find_implied(thd)->
 | |
|                        find_native_function_builder(thd, $1);
 | |
|             if (builder)
 | |
|             {
 | |
|               item= builder->create_func(thd, &$1, $4);
 | |
|             }
 | |
|             else if ((h= Type_handler::handler_by_name(thd, $1)) &&
 | |
|                      (item= h->make_constructor_item(thd, $4)))
 | |
|             {
 | |
|               // Found a constructor with a proper argument count
 | |
|             }
 | |
|             else if (Lex->spcont &&
 | |
|                     (rec = Lex->spcont->find_record(&$1, false)))
 | |
|             {
 | |
|               item= new (thd->mem_root) Item_row(thd, *$4);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
| #ifdef HAVE_DLOPEN
 | |
|               /* Retrieving the result of find_udf */
 | |
|               udf_func *udf= $<udf>3;
 | |
| 
 | |
|               if (udf)
 | |
|               {
 | |
|                 if (udf->type == UDFTYPE_AGGREGATE)
 | |
|                 {
 | |
|                   Select->in_sum_expr--;
 | |
|                 }
 | |
| 
 | |
|                 item= Create_udf_func::s_singleton.create(thd, udf, $4);
 | |
|               }
 | |
|               else
 | |
| #endif
 | |
|               {
 | |
|                 builder= find_qualified_function_builder(thd);
 | |
|                 DBUG_ASSERT(builder);
 | |
|                 item= builder->create_func(thd, &$1, $4);
 | |
|               }
 | |
|             }
 | |
| 
 | |
|             if (unlikely(! ($$= item)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | CONTAINS_SYM '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
 | |
|                                                                      $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | OVERLAPS_SYM '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
 | |
|                                                                      $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | WITHIN '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (!($$= Lex->make_item_func_call_native_or_parse_error(thd,
 | |
|                                                                      $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli '.' ident_cli '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_call_generic(thd, &$1, &$3, &$5, $7))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' REPLACE '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_replace(thd, $1, $3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' SUBSTRING '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_substr(thd, $1, $3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' SUBSTRING '(' substring_operands_special ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_substr(thd, $1, $3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' TRIM '(' opt_expr_list ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_trim(thd, $1, $3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' TRIM '(' trim_operands_special ')'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_func_trim(thd, $1, $3, $5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           /*
 | |
|             We don't add a qualified syntax for TRIM_ORACLE here,
 | |
|             as this syntax is not absolutely required:
 | |
|               SELECT mariadb_schema.TRIM_ORACLE(..);
 | |
|             What absolutely required is only:
 | |
|               SELECT mariadb_schema.TRIM(..);
 | |
|             Adding a qualified syntax for TRIM_ORACLE would be tricky because
 | |
|             it is a non-reserved keyword. To avoid new shift/reduce conflicts
 | |
|             it would require grammar changes, like introducing a new rule
 | |
|             ident_step2_cli (which would include everything that ident_cli
 | |
|             includes but TRIM_ORACLE).
 | |
|           */
 | |
|         ;
 | |
| 
 | |
| fulltext_options:
 | |
|           opt_natural_language_mode opt_query_expansion
 | |
|           { $$= $1 | $2; }
 | |
|         | IN_SYM BOOLEAN_SYM MODE_SYM
 | |
|           { $$= FT_BOOL; }
 | |
|         ;
 | |
| 
 | |
| opt_natural_language_mode:
 | |
|           /* nothing */                         { $$= FT_NL; }
 | |
|         | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM  { $$= FT_NL; }
 | |
|         ;
 | |
| 
 | |
| opt_query_expansion:
 | |
|           /* nothing */                         { $$= 0;         }
 | |
|         | WITH QUERY_SYM EXPANSION_SYM          { $$= FT_EXPAND; }
 | |
|         ;
 | |
| 
 | |
| opt_udf_expr_list:
 | |
|         /* empty */     { $$= NULL; }
 | |
|         | udf_expr_list { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| udf_expr_list:
 | |
|           udf_expr
 | |
|           {
 | |
|             $$= new (thd) List<Item>;
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->push_back($1, thd->mem_root);
 | |
|           }
 | |
|         | udf_expr_list ',' udf_expr
 | |
|           {
 | |
|             $1->push_back($3, thd->mem_root);
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| udf_expr:
 | |
|           remember_name expr remember_end select_alias
 | |
|           {
 | |
|             /*
 | |
|              Use Item::name as a storage for the attribute value of user
 | |
|              defined function argument. It is safe to use Item::name
 | |
|              because the syntax will not allow having an explicit name here.
 | |
|              See WL#1017 re. udf attributes.
 | |
|             */
 | |
|             if ($4.str)
 | |
|             {
 | |
|               $2->base_flags|= item_base_t::IS_EXPLICIT_NAME;
 | |
|               $2->set_name(thd, $4);
 | |
|             }
 | |
|             /* 
 | |
|                A field has to have its proper name in order for name
 | |
|                resolution to work, something we are only guaranteed if we
 | |
|                parse it out. If we hijack the input stream with
 | |
|                remember_name we may get quoted or escaped names.
 | |
|             */
 | |
|             else if ($2->type() != Item::FIELD_ITEM &&
 | |
|                      $2->type() != Item::REF_ITEM /* For HAVING */ )
 | |
|               $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sum_expr:
 | |
|           AVG_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_avg(thd, $3, FALSE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | AVG_SYM '(' DISTINCT in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_avg(thd, $4, TRUE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | BIT_AND  '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_and(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | BIT_OR  '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_or(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | BIT_XOR  '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_xor(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COUNT_SYM '(' opt_all '*' ')'
 | |
|           {
 | |
|             Item *item= new (thd) Item_int(thd, (int32) 0L, 1);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_sum_count(thd, item);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COUNT_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_count(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COUNT_SYM '(' DISTINCT
 | |
|           { Select->in_sum_expr++; }
 | |
|           expr_list
 | |
|           { Select->in_sum_expr--; }
 | |
|           ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_count(thd, *$5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MIN_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_min(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         /*
 | |
|           According to ANSI SQL, DISTINCT is allowed and has
 | |
|           no sense inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...)
 | |
|           is processed like an ordinary MIN | MAX()
 | |
|         */
 | |
|         | MIN_SYM '(' DISTINCT in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_min(thd, $4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MAX_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_max(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | MAX_SYM '(' DISTINCT in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_max(thd, $4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | STD_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_std(thd, $3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | VARIANCE_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_variance(thd, $3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | STDDEV_SAMP_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_std(thd, $3, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | VAR_SAMP_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_variance(thd, $3, 1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SUM_SYM '(' in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_sum(thd, $3, FALSE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SUM_SYM '(' DISTINCT in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_sum(thd, $4, TRUE);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | GROUP_CONCAT_SYM '(' opt_distinct
 | |
|           { Select->in_sum_expr++; }
 | |
|           expr_list opt_gorder_clause
 | |
|           opt_gconcat_separator opt_glimit_clause
 | |
|           ')'
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             sel->in_sum_expr--;
 | |
|             $$= new (thd)
 | |
|                   Item_func_group_concat(thd, Lex->current_context(),
 | |
|                                         $3, $5,
 | |
|                                         sel->gorder_list, $7, $8,
 | |
|                                         sel->limit_params.select_limit,
 | |
|                                         sel->limit_params.offset_limit);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             sel->limit_params.clear();
 | |
|             $5->empty();
 | |
|             sel->gorder_list.empty();
 | |
|           }
 | |
|         | JSON_ARRAYAGG_SYM '(' opt_distinct
 | |
|           { Select->in_sum_expr++; }
 | |
|           expr_list opt_gorder_clause opt_glimit_clause
 | |
|           ')'
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             List<Item> *args= $5;
 | |
|             sel->in_sum_expr--;
 | |
|             if (args && args->elements > 1)
 | |
|             {
 | |
|               /* JSON_ARRAYAGG supports only one parameter */
 | |
|               my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), "JSON_ARRAYAGG");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             String* s= new (thd) String(",", 1, &my_charset_latin1);
 | |
|             if (unlikely(s == NULL))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             $$= new (thd)
 | |
|                   Item_func_json_arrayagg(thd, Lex->current_context(),
 | |
|                                           $3, args,
 | |
|                                           sel->gorder_list, s, $7,
 | |
|                                           sel->limit_params.select_limit,
 | |
|                                           sel->limit_params.offset_limit);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             sel->limit_params.clear();
 | |
|             $5->empty();
 | |
|             sel->gorder_list.empty();
 | |
|           }
 | |
|         | JSON_OBJECTAGG_SYM '('
 | |
|           { Select->in_sum_expr++; }
 | |
|           expr ',' expr ')'
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             sel->in_sum_expr--;
 | |
| 
 | |
|             $$= new (thd) Item_func_json_objectagg(thd, $4, $6);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ST_COLLECT_SYM '(' opt_distinct in_sum_expr ')'
 | |
|           {
 | |
|             $$= new (thd->mem_root) Item_func_collect(thd, $3, $4);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| window_func_expr:
 | |
|           window_func OVER_SYM window_name
 | |
|           {
 | |
|             $$= new (thd) Item_window_func(thd, (Item_sum *) $1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Select->add_window_func((Item_window_func *) $$)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           window_func OVER_SYM window_spec
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(Select->add_window_spec(thd, lex->win_ref,
 | |
|                                                  Select->group_list,
 | |
|                                                  Select->order_list,
 | |
|                                                  lex->win_frame)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_window_func(thd, (Item_sum *) $1,
 | |
|                                                       thd->lex->win_spec); 
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Select->add_window_func((Item_window_func *) $$)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| window_func:
 | |
|           simple_window_func
 | |
|         |
 | |
|           sum_expr
 | |
|         |
 | |
|           function_call_generic
 | |
|           {
 | |
|             Item* item = (Item*)$1;
 | |
|             /* Only UDF aggregate here possible */
 | |
|             if ((item == NULL) ||
 | |
|                 (item->type() != Item::SUM_FUNC_ITEM)
 | |
|                 || (((Item_sum *)item)->sum_func() != Item_sum::UDF_SUM_FUNC))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| simple_window_func:
 | |
|           ROW_NUMBER_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_row_number(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           RANK_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_rank(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           DENSE_RANK_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_dense_rank(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           PERCENT_RANK_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_percent_rank(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           CUME_DIST_SYM '(' ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_cume_dist(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           NTILE_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_ntile(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           FIRST_VALUE_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_first_value(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           LAST_VALUE '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_last_value(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           NTH_VALUE_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_nth_value(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           LEAD_SYM '(' expr ')'
 | |
|           {
 | |
|             /* No second argument defaults to 1. */
 | |
|             Item* item_offset= new (thd) Item_uint(thd, 1);
 | |
|             if (unlikely(item_offset == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_sum_lead(thd, $3, item_offset);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           LEAD_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_lead(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           LAG_SYM '(' expr ')'
 | |
|           {
 | |
|             /* No second argument defaults to 1. */
 | |
|             Item* item_offset= new (thd) Item_uint(thd, 1);
 | |
|             if (unlikely(item_offset == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_sum_lag(thd, $3, item_offset);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |
 | |
|           LAG_SYM '(' expr ',' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_lag(thd, $3, $5);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| 
 | |
| inverse_distribution_function:
 | |
|           percentile_function OVER_SYM
 | |
|           '(' opt_window_partition_clause ')'
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(Select->add_window_spec(thd, lex->win_ref,
 | |
|                                                  Select->group_list,
 | |
|                                                  Select->order_list,
 | |
|                                                  NULL)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= new (thd) Item_window_func(thd, (Item_sum *) $1,
 | |
|                                                      thd->lex->win_spec);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Select->add_window_func((Item_window_func *) $$)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| percentile_function:
 | |
|           inverse_distribution_function_def  WITHIN GROUP_SYM '('
 | |
|            { Select->prepare_add_window_spec(thd); }
 | |
|            order_by_single_element_list ')'
 | |
|            {
 | |
|              $$= $1;
 | |
|            }
 | |
|         | MEDIAN_SYM '(' expr ')'
 | |
|           {
 | |
|             Item *args= new (thd) Item_decimal(thd, "0.5", 3,
 | |
|                                                    thd->charset());
 | |
|             if (unlikely(args == NULL) || unlikely(thd->is_error()))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->prepare_add_window_spec(thd);
 | |
|             if (unlikely(add_order_to_list(thd, $3,FALSE)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             $$= new (thd) Item_sum_percentile_cont(thd, args);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| inverse_distribution_function_def:
 | |
|           PERCENTILE_CONT_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_percentile_cont(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         |  PERCENTILE_DISC_SYM '(' expr ')'
 | |
|           {
 | |
|             $$= new (thd) Item_sum_percentile_disc(thd, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| order_by_single_element_list:
 | |
|           ORDER_SYM BY order_ident order_dir
 | |
|           {
 | |
|             if (unlikely(add_order_to_list(thd, $3,(bool) $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| window_name:
 | |
|           ident
 | |
|           {
 | |
|             $$= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| variable:
 | |
|           '@'
 | |
|           {
 | |
|             if (unlikely(! Lex->parsing_options.allows_variable))
 | |
|               my_yyabort_error((ER_VIEW_SELECT_VARIABLE, MYF(0)));
 | |
|           }
 | |
|           variable_aux
 | |
|           {
 | |
|             $$= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| variable_aux:
 | |
|           ident_or_text SET_VAR expr
 | |
|           {
 | |
|             Item_func_set_user_var *item;
 | |
|             if (!$1.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             $$= item= new (thd) Item_func_set_user_var(thd, &$1, $3);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex= Lex;
 | |
|             lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
|             lex->set_var_list.push_back(item, thd->mem_root);
 | |
|           }
 | |
|         | ident_or_text
 | |
|           {
 | |
|             if (!$1.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             $$= new (thd) Item_func_get_user_var(thd, &$1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex= Lex;
 | |
|             lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
|           }
 | |
|         | '@' opt_var_ident_type ident_sysvar_name
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' opt_var_ident_type ident_sysvar_name '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_sysvar(thd, $2, &$3, &$5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_distinct:
 | |
|           /* empty */ { $$ = 0; }
 | |
|         | DISTINCT    { $$ = 1; }
 | |
|         ;
 | |
| 
 | |
| opt_gconcat_separator:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= new (thd) String(",", 1, &my_charset_latin1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | SEPARATOR_SYM text_string { $$ = $2; }
 | |
|         ;
 | |
| 
 | |
| opt_gorder_clause:
 | |
|           /* empty */
 | |
|         | ORDER_SYM BY gorder_list
 | |
|         ;
 | |
| 
 | |
| gorder_list:
 | |
|           gorder_list ',' order_ident order_dir
 | |
|           {
 | |
|             if (unlikely(add_gorder_to_list(thd, $3,(bool) $4)))
 | |
|               MYSQL_YYABORT;
 | |
|            }
 | |
|         | order_ident order_dir
 | |
|           {
 | |
|             if (unlikely(add_gorder_to_list(thd, $1,(bool) $2)))
 | |
|               MYSQL_YYABORT;
 | |
|            }
 | |
|         ;
 | |
| 
 | |
| opt_glimit_clause:
 | |
|           /* empty */ { $$ = 0; }
 | |
|         | glimit_clause { $$ = 1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| glimit_clause:
 | |
|           LIMIT glimit_options
 | |
|           {
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| glimit_options:
 | |
|           limit_options
 | |
|           {
 | |
|             Select->limit_params= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| 
 | |
| in_sum_expr:
 | |
|           opt_all
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->current_select->inc_in_sum_expr()))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|           expr
 | |
|           {
 | |
|             Select->in_sum_expr--;
 | |
|             $$= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| cast_type:
 | |
|           BINARY opt_field_length
 | |
|           { $$.set(&type_handler_long_blob, $2, &my_charset_bin); }
 | |
|         | CHAR_SYM opt_field_length opt_binary
 | |
|           {
 | |
|             if ($$.set(&type_handler_long_blob,
 | |
|                        $2, thd, thd->variables.character_set_collations, $3,
 | |
|                        thd->variables.collation_connection))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | VARCHAR field_length opt_binary
 | |
|           {
 | |
|             if ($$.set(&type_handler_long_blob,
 | |
|                        $2, thd, thd->variables.character_set_collations, $3,
 | |
|                        thd->variables.collation_connection))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | VARCHAR2_ORACLE_SYM field_length opt_binary
 | |
|           {
 | |
|             if ($$.set(&type_handler_long_blob,
 | |
|                        $2, thd, thd->variables.character_set_collations, $3,
 | |
|                        thd->variables.collation_connection))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NCHAR_SYM opt_field_length
 | |
|           {
 | |
|             $$.set(&type_handler_long_blob, $2, national_charset_info);
 | |
|           }
 | |
|         | cast_type_numeric  { $$= $1; }
 | |
|         | cast_type_temporal { $$= $1; }
 | |
|         | udt_name
 | |
|           {
 | |
|             if (Lex->set_cast_type_udt(&$$, $1))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| cast_type_numeric:
 | |
|           INT_SYM                        { $$.set(&type_handler_slonglong); }
 | |
|         | SIGNED_SYM                     { $$.set(&type_handler_slonglong); }
 | |
|         | SIGNED_SYM INT_SYM             { $$.set(&type_handler_slonglong); }
 | |
|         | UNSIGNED                       { $$.set(&type_handler_ulonglong); }
 | |
|         | UNSIGNED INT_SYM               { $$.set(&type_handler_ulonglong); }
 | |
|         | DECIMAL_SYM float_options      { $$.set(&type_handler_newdecimal, $2); }
 | |
|         | FLOAT_SYM                      { $$.set(&type_handler_float); }
 | |
|         | DOUBLE_SYM opt_precision       { $$.set(&type_handler_double, $2);  }
 | |
|         ;
 | |
| 
 | |
| cast_type_temporal:
 | |
|           DATE_SYM                       { $$.set(&type_handler_newdate); }
 | |
|         | TIME_SYM opt_field_scale       { $$.set(&type_handler_time2, $2); }
 | |
|         | DATETIME opt_field_scale       { $$.set(&type_handler_datetime2, $2); }
 | |
|         | INTERVAL_SYM DAY_SECOND_SYM field_scale
 | |
|           {
 | |
|             $$.set(&type_handler_interval_DDhhmmssff, $3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_expr_list:
 | |
|           /* empty */ { $$= NULL; }
 | |
|         | expr_list { $$= $1;}
 | |
|         ;
 | |
| 
 | |
| expr_list:
 | |
|           expr
 | |
|           {
 | |
|             if (unlikely(!($$= List<Item>::make(thd->mem_root, $1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | expr_list ',' expr
 | |
|           {
 | |
|             $1->push_back($3, thd->mem_root);
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_list_arg:
 | |
|           ident_list          { $$= $1; }
 | |
|         | '(' ident_list ')'  { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| ident_list:
 | |
|           simple_ident
 | |
|           {
 | |
|             $$= new (thd) List<Item>;
 | |
|             if (unlikely($$ == NULL) ||
 | |
|                 unlikely($$->push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_list ',' simple_ident
 | |
|           {
 | |
|             $1->push_back($3, thd->mem_root);
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| when_list:
 | |
|           WHEN_SYM expr THEN_SYM expr
 | |
|           {
 | |
|             $$= new (thd) List<Item>;
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely($$->push_back($2, thd->mem_root) ||
 | |
|                          $$->push_back($4, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | when_list WHEN_SYM expr THEN_SYM expr
 | |
|           {
 | |
|             if (unlikely($1->push_back($3, thd->mem_root) ||
 | |
|                          $1->push_back($5, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| when_list_opt_else:
 | |
|           when_list
 | |
|         | when_list ELSE expr
 | |
|           {
 | |
|             if (unlikely($1->push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Equivalent to <table reference> in the SQL:2003 standard. */
 | |
| /* Warning - may return NULL in case of incomplete SELECT */
 | |
| table_ref:
 | |
|           table_factor     { $$= $1; }
 | |
|         | join_table
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(!($$= lex->current_select->nest_last_join(thd))))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| json_text_literal:
 | |
|           TEXT_STRING
 | |
|         | NCHAR_STRING
 | |
|         | UNDERSCORE_CHARSET TEXT_STRING
 | |
|           {
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| join_table_list:
 | |
|           derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); }
 | |
|         ;
 | |
| 
 | |
| json_table_columns_clause:
 | |
|           COLUMNS '(' json_table_columns_list ')'
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| json_table_columns_list:
 | |
|           json_table_column
 | |
|         | json_table_columns_list ',' json_table_column
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| json_table_column:
 | |
|           ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Create_field *f= new (thd) Create_field();
 | |
| 
 | |
|             if (unlikely(check_string_char_length(&$1, 0, NAME_CHAR_LEN,
 | |
|                                                   system_charset_info, 1)))
 | |
|               my_yyabort_error((ER_TOO_LONG_IDENT, MYF(0), $1.str));
 | |
| 
 | |
|             lex->json_table->m_cur_json_table_column=
 | |
|               new (thd) Json_table_column(f,
 | |
|                                     lex->json_table->get_cur_nested_path());
 | |
| 
 | |
|             if (unlikely(!f ||
 | |
|                 !lex->json_table->m_cur_json_table_column))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->init_last_field(f, &$1);
 | |
|           }
 | |
|           json_table_column_type
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(lex->json_table->
 | |
|                            m_cur_json_table_column->m_field->check(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->json_table->m_columns.push_back(
 | |
|                lex->json_table->m_cur_json_table_column, thd->mem_root);
 | |
|           }
 | |
|         | NESTED_SYM PATH_SYM json_text_literal
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Json_table_nested_path *np= new (thd)
 | |
|               Json_table_nested_path();
 | |
|             np->set_path(thd, $3);
 | |
|             lex->json_table->start_nested_path(np);
 | |
|           }
 | |
|           json_table_columns_clause
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->json_table->end_nested_path();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| json_table_column_type:
 | |
|           FOR_SYM ORDINALITY_SYM
 | |
|           {
 | |
|             Lex_field_type_st type;
 | |
|             type.set(&type_handler_slong);
 | |
|             Lex->last_field->set_attributes(thd, type,
 | |
|                                             COLUMN_DEFINITION_TABLE_FIELD);
 | |
|             Lex->json_table->m_cur_json_table_column->
 | |
|               set(Json_table_column::FOR_ORDINALITY);
 | |
|           }
 | |
|         | json_table_field_type PATH_SYM json_text_literal
 | |
|             json_opt_on_empty_or_error
 | |
|           {
 | |
|             Lex->last_field->set_attributes(thd, $1,
 | |
|                                             COLUMN_DEFINITION_TABLE_FIELD);
 | |
|             if (Lex->json_table->m_cur_json_table_column->
 | |
|                   set(thd, Json_table_column::PATH, $3,
 | |
|                       $1.charset_collation_attrs()))
 | |
|             {
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | json_table_field_type EXISTS PATH_SYM json_text_literal
 | |
|           {
 | |
|             Lex->last_field->set_attributes(thd, $1,
 | |
|                                             COLUMN_DEFINITION_TABLE_FIELD);
 | |
|             if (Lex->json_table->m_cur_json_table_column->
 | |
|                   set(thd, Json_table_column::EXISTS_PATH, $4,
 | |
|                       $1.charset_collation_attrs()))
 | |
|                MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| json_table_field_type:
 | |
|           field_type_numeric
 | |
|         | field_type_temporal
 | |
|         | field_type_string
 | |
|         | field_type_lob
 | |
|         ;
 | |
| 
 | |
| json_opt_on_empty_or_error:
 | |
|           /* none */
 | |
|           {}
 | |
|         | json_on_error_response
 | |
|         | json_on_error_response json_on_empty_response
 | |
|         | json_on_empty_response
 | |
|         | json_on_empty_response json_on_error_response
 | |
|         ;
 | |
| 
 | |
| json_default_literal:
 | |
|           literal
 | |
|         | signed_literal
 | |
|         ;
 | |
| 
 | |
| 
 | |
| json_on_response:
 | |
|           ERROR_SYM
 | |
|           {
 | |
|             $$.m_response= Json_table_column::RESPONSE_ERROR;
 | |
|           }
 | |
|         | NULL_SYM
 | |
|           {
 | |
|             $$.m_response= Json_table_column::RESPONSE_NULL;
 | |
|           }
 | |
|         | DEFAULT json_default_literal
 | |
|           {
 | |
|             $$.m_response= Json_table_column::RESPONSE_DEFAULT;
 | |
|             $$.m_default= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| json_on_error_response:
 | |
|           json_on_response ON ERROR_SYM
 | |
|           {
 | |
|             Lex->json_table->m_cur_json_table_column->m_on_error= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| json_on_empty_response:
 | |
|           json_on_response ON EMPTY_SYM
 | |
|           {
 | |
|             Lex->json_table->m_cur_json_table_column->m_on_empty= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_function:
 | |
|           JSON_TABLE_SYM '('
 | |
|           {
 | |
|             push_table_function_arg_context(Lex, thd->mem_root);
 | |
|             //TODO: introduce IN_TABLE_FUNC_ARGUMENT?
 | |
|             Select->parsing_place= IN_ON;
 | |
|           }
 | |
|           expr ','
 | |
|           {
 | |
|             Table_function_json_table *jt=
 | |
|               new (thd) Table_function_json_table($4);
 | |
|             if (unlikely(!jt))
 | |
|               MYSQL_YYABORT;
 | |
|             /* See comment for class Table_function_json_table: */
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
 | |
|             Lex->json_table= jt;
 | |
| 
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|             jt->set_name_resolution_context(Lex->pop_context());
 | |
|           }
 | |
|           json_text_literal json_table_columns_clause ')' opt_table_alias_clause
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             if (unlikely($10 == NULL))
 | |
|             {
 | |
|               /* Alias is not optional. */
 | |
|               my_error(ER_JSON_TABLE_ALIAS_REQUIRED, MYF(0));
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (unlikely(Lex->json_table->m_nested_path.set_path(thd, $7)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (!($$= sel->add_table_to_list(thd,
 | |
|                            new (thd) Table_ident(thd, &any_db,
 | |
|                                                            $10, TRUE),
 | |
|                            NULL,
 | |
|                            TL_OPTION_TABLE_FUNCTION,
 | |
|                            YYPS->m_lock_type,
 | |
|                            YYPS->m_mdl_type,
 | |
|                            0,0,0)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->table_function= Lex->json_table;
 | |
|             Lex->json_table= 0;
 | |
|             status_var_increment(thd->status_var.feature_json);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   The ODBC escape syntax for Outer Join is: '{' OJ join_table '}'
 | |
|   The parser does not define OJ as a token, any ident is accepted
 | |
|   instead in $2 (ident). Also, all productions from table_ref can
 | |
|   be escaped, not only join_table. Both syntax extensions are safe
 | |
|   and are ignored.
 | |
| */
 | |
| esc_table_ref:
 | |
|           table_ref { $$=$1; }
 | |
|         | '{' ident table_ref '}' { $$=$3; }
 | |
|         ;
 | |
| 
 | |
| /* Equivalent to <table reference list> in the SQL:2003 standard. */
 | |
| /* Warning - may return NULL in case of incomplete SELECT */
 | |
| derived_table_list:
 | |
|           esc_table_ref
 | |
|           {
 | |
|             $$=$1;
 | |
|             Select->add_joined_table($1);
 | |
|           }
 | |
|         | derived_table_list ',' esc_table_ref
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && ($$=$3));
 | |
|             Select->add_joined_table($3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Notice that JOIN can be a left-associative operator in one context and
 | |
|   a right-associative operator in another context (see the comment for
 | |
|   st_select_lex::add_cross_joined_table).
 | |
| */
 | |
| join_table:
 | |
|           /* INNER JOIN variants */
 | |
|           table_ref normal_join table_ref %prec CONDITIONLESS_JOIN
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && ($$=$3));
 | |
|             if (unlikely(Select->add_cross_joined_table($1, $3, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | table_ref normal_join table_ref
 | |
|           ON
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $3);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($3);
 | |
|             /* Change the current name resolution context to a local context. */
 | |
|             if (unlikely(push_new_name_resolution_context(thd, $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->parsing_place= IN_ON;
 | |
|           }
 | |
|           expr
 | |
|           {
 | |
|             $3->straight=$2;
 | |
|             add_join_on(thd, $3, $6);
 | |
|             $3->on_context= Lex->pop_context();
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         | table_ref normal_join table_ref
 | |
|           USING
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $3);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($3);
 | |
|           }
 | |
|           '(' using_list ')'
 | |
|           {
 | |
| 	    $3->straight=$2;
 | |
|             add_join_natural($1,$3,$7,Select); 
 | |
| 	    $$=$3; 
 | |
|           }
 | |
|         | table_ref NATURAL inner_join table_factor
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && ($$=$4));
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($4);
 | |
| 	    $4->straight=$3;
 | |
|             add_join_natural($1,$4,NULL,Select);
 | |
|           }
 | |
| 
 | |
|           /* LEFT JOIN variants */
 | |
|         | table_ref LEFT opt_outer JOIN_SYM table_ref
 | |
|           ON
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $5);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($5);
 | |
|             /* Change the current name resolution context to a local context. */
 | |
|             if (unlikely(push_new_name_resolution_context(thd, $1, $5)))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->parsing_place= IN_ON;
 | |
|           }
 | |
|           search_condition
 | |
|           {
 | |
|             add_join_on(thd, $5, $8);
 | |
|             $5->on_context= Lex->pop_context();
 | |
|             $5->outer_join|=JOIN_TYPE_LEFT;
 | |
|             $$=$5;
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         | table_ref LEFT opt_outer JOIN_SYM table_factor
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $5);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($5);
 | |
|           }
 | |
|           USING '(' using_list ')'
 | |
|           { 
 | |
|             add_join_natural($1,$5,$9,Select); 
 | |
|             $5->outer_join|=JOIN_TYPE_LEFT; 
 | |
|             $$=$5; 
 | |
|           }
 | |
|         | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $6);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($6);
 | |
|             add_join_natural($1,$6,NULL,Select);
 | |
|             $6->outer_join|=JOIN_TYPE_LEFT;
 | |
|             $$=$6;
 | |
|           }
 | |
| 
 | |
|           /* RIGHT JOIN variants */
 | |
|         | table_ref RIGHT opt_outer JOIN_SYM table_ref
 | |
|           ON
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $5);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($5);
 | |
|             /* Change the current name resolution context to a local context. */
 | |
|             if (unlikely(push_new_name_resolution_context(thd, $1, $5)))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->parsing_place= IN_ON;
 | |
|           }
 | |
|           expr
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(!($$= lex->current_select->convert_right_join())))
 | |
|               MYSQL_YYABORT;
 | |
|             add_join_on(thd, $$, $8);
 | |
|             $1->on_context= Lex->pop_context();
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         | table_ref RIGHT opt_outer JOIN_SYM table_factor
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $5);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($5);
 | |
|           }
 | |
|           USING '(' using_list ')'
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(!($$= lex->current_select->convert_right_join())))
 | |
|               MYSQL_YYABORT;
 | |
|             add_join_natural($$,$5,$9,Select);
 | |
|           }
 | |
|         | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1 && $6);
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($6);
 | |
|             add_join_natural($6,$1,NULL,Select);
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(!($$= lex->current_select->convert_right_join())))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| inner_join: /* $$ set if using STRAIGHT_JOIN, false otherwise */
 | |
|           JOIN_SYM           { $$ = 0; }
 | |
|         | INNER_SYM JOIN_SYM { $$ = 0; }
 | |
|         | STRAIGHT_JOIN      { $$ = 1; }
 | |
|         ;
 | |
| 
 | |
| normal_join:
 | |
|           inner_join         { $$ = $1; }
 | |
|         | CROSS JOIN_SYM     { $$ = 0; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   table PARTITION (list of partitions), reusing using_list instead of creating
 | |
|   a new rule for partition_list.
 | |
| */
 | |
| opt_use_partition:
 | |
|           /* empty */ { $$= 0;}
 | |
|         | use_partition
 | |
|         ;
 | |
|         
 | |
| use_partition:
 | |
|           PARTITION_SYM '(' using_list ')' have_partitioning
 | |
|           {
 | |
|             $$= $3;
 | |
|             Select->parsing_place= Select->save_parsing_place;
 | |
|             Select->save_parsing_place= NO_MATTER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_factor:
 | |
|           table_primary_ident_opt_parens { $$= $1; }
 | |
|         | table_primary_derived_opt_parens { $$= $1; }
 | |
|         | join_table_parens
 | |
|           { 
 | |
|             $1->nested_join->nest_type= 0;
 | |
|             $$= $1;
 | |
|           }
 | |
|         | table_reference_list_parens { $$= $1; }
 | |
|         | table_function { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| table_primary_ident_opt_parens:
 | |
|           table_primary_ident { $$= $1; }
 | |
|         | '(' table_primary_ident_opt_parens ')' { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| table_primary_derived_opt_parens:
 | |
|           table_primary_derived { $$= $1; }
 | |
|         | '(' table_primary_derived_opt_parens ')' { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| table_reference_list_parens:
 | |
|           '(' table_reference_list_parens ')' { $$= $2; }
 | |
|         | '(' nested_table_reference_list ')'
 | |
|           {
 | |
|             if (!($$= Select->end_nested_join(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| nested_table_reference_list:
 | |
|           table_ref ',' table_ref
 | |
|           {
 | |
|             if (Select->init_nested_join(thd))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->add_joined_table($1);
 | |
|             Select->add_joined_table($3);
 | |
|             $$= $1->embedding;
 | |
|           }
 | |
|         | nested_table_reference_list ',' table_ref
 | |
|           {
 | |
|             Select->add_joined_table($3);
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| join_table_parens:
 | |
|           '(' join_table_parens ')' { $$= $2; }
 | |
|         | '(' join_table ')'
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (!($$= lex->current_select->nest_last_join(thd)))
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| table_primary_ident:
 | |
|           table_ident opt_use_partition opt_for_system_time_clause
 | |
|           opt_table_alias_clause opt_key_definition
 | |
|           {
 | |
|             if (!($$= Select->add_table_to_list(thd, $1, $4,
 | |
|                                                 0,
 | |
|                                                 YYPS->m_lock_type,
 | |
|                                                 YYPS->m_mdl_type,
 | |
|                                                 Select->pop_index_hints(),
 | |
|                                                 $2)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($3)
 | |
|               $$->vers_conditions= Lex->vers_conditions;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| derived_column_list:
 | |
|         opt_column_name_list
 | |
|         ;
 | |
| 
 | |
| table_primary_derived:
 | |
|           subquery
 | |
|           opt_for_system_time_clause
 | |
|           table_alias_clause
 | |
|           derived_column_list
 | |
|           {
 | |
|             if (!($$= Lex->parsed_derived_table($1->master_unit(), $2, $3, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
| %ifdef ORACLE
 | |
|         | subquery
 | |
|           opt_for_system_time_clause
 | |
|           {
 | |
|             LEX_CSTRING alias;
 | |
|             if ($1->make_unique_derived_name(thd, &alias) ||
 | |
|                 !($$= Lex->parsed_derived_table($1->master_unit(), $2, &alias)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
| %endif
 | |
|         ;
 | |
| 
 | |
| opt_outer:
 | |
|           /* empty */ {}
 | |
|         | OUTER {}
 | |
|         ;
 | |
| 
 | |
| index_hint_clause:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= (thd->variables.old_behavior & OLD_MODE_IGNORE_INDEX_ONLY_FOR_JOIN) ?
 | |
|                 INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
 | |
|           }
 | |
|         | FOR_SYM JOIN_SYM      { $$= INDEX_HINT_MASK_JOIN;  }
 | |
|         | FOR_SYM ORDER_SYM BY  { $$= INDEX_HINT_MASK_ORDER; }
 | |
|         | FOR_SYM GROUP_SYM BY  { $$= INDEX_HINT_MASK_GROUP; }
 | |
|         ;
 | |
| 
 | |
| index_hint_type:
 | |
|           FORCE_SYM  { $$= INDEX_HINT_FORCE; }
 | |
|         | IGNORE_SYM { $$= INDEX_HINT_IGNORE; } 
 | |
|         ;
 | |
| 
 | |
| index_hint_definition:
 | |
|           index_hint_type key_or_index index_hint_clause
 | |
|           {
 | |
|             Select->set_index_hint_type($1, $3);
 | |
|           }
 | |
|           '(' key_usage_list ')'
 | |
|         | USE_SYM key_or_index index_hint_clause
 | |
|           {
 | |
|             Select->set_index_hint_type(INDEX_HINT_USE, $3);
 | |
|           }
 | |
|           '(' opt_key_usage_list ')'
 | |
|        ;
 | |
| 
 | |
| index_hints_list:
 | |
|           index_hint_definition
 | |
|         | index_hints_list index_hint_definition
 | |
|         ;
 | |
| 
 | |
| opt_index_hints_list:
 | |
|           /* empty */
 | |
|         | { Select->alloc_index_hints(thd); } index_hints_list
 | |
|         ;
 | |
| 
 | |
| opt_key_definition:
 | |
|           {  Select->clear_index_hints(); }
 | |
|           opt_index_hints_list
 | |
|         ;
 | |
| 
 | |
| opt_key_usage_list:
 | |
|           /* empty */ { Select->add_index_hint(thd, NULL, 0); }
 | |
|         | key_usage_list {}
 | |
|         ;
 | |
| 
 | |
| key_usage_element:
 | |
|           ident
 | |
|           { Select->add_index_hint(thd, $1.str, $1.length); }
 | |
|         | PRIMARY_SYM
 | |
|           { Select->add_index_hint(thd, "PRIMARY", 7); }
 | |
|         ;
 | |
| 
 | |
| key_usage_list:
 | |
|           key_usage_element
 | |
|         | key_usage_list ',' key_usage_element
 | |
|         ;
 | |
| 
 | |
| using_list:
 | |
|           ident
 | |
|           {
 | |
|             if (unlikely(!($$= new (thd) List<String>)))
 | |
|               MYSQL_YYABORT;
 | |
|             String *s= new (thd) String((const char*) $1.str,
 | |
|                                                   $1.length,
 | |
|                                                   system_charset_info);
 | |
|             if (unlikely(unlikely(s == NULL)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->push_back(s, thd->mem_root);
 | |
|           }
 | |
|         | using_list ',' ident
 | |
|           {
 | |
|             String *s= new (thd) String((const char*) $3.str,
 | |
|                                                   $3.length,
 | |
|                                                   system_charset_info);
 | |
|             if (unlikely(unlikely(s == NULL)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely($1->push_back(s, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| interval:
 | |
|           interval_time_stamp    {}
 | |
|         | DAY_HOUR_SYM           { $$=INTERVAL_DAY_HOUR; }
 | |
|         | DAY_MICROSECOND_SYM    { $$=INTERVAL_DAY_MICROSECOND; }
 | |
|         | DAY_MINUTE_SYM         { $$=INTERVAL_DAY_MINUTE; }
 | |
|         | DAY_SECOND_SYM         { $$=INTERVAL_DAY_SECOND; }
 | |
|         | HOUR_MICROSECOND_SYM   { $$=INTERVAL_HOUR_MICROSECOND; }
 | |
|         | HOUR_MINUTE_SYM        { $$=INTERVAL_HOUR_MINUTE; }
 | |
|         | HOUR_SECOND_SYM        { $$=INTERVAL_HOUR_SECOND; }
 | |
|         | MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; }
 | |
|         | MINUTE_SECOND_SYM      { $$=INTERVAL_MINUTE_SECOND; }
 | |
|         | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; }
 | |
|         | YEAR_MONTH_SYM         { $$=INTERVAL_YEAR_MONTH; }
 | |
|         ;
 | |
| 
 | |
| interval_time_stamp:
 | |
|           DAY_SYM         { $$=INTERVAL_DAY; }
 | |
|         | WEEK_SYM        { $$=INTERVAL_WEEK; }
 | |
|         | HOUR_SYM        { $$=INTERVAL_HOUR; }
 | |
|         | MINUTE_SYM      { $$=INTERVAL_MINUTE; }
 | |
|         | MONTH_SYM       { $$=INTERVAL_MONTH; }
 | |
|         | QUARTER_SYM     { $$=INTERVAL_QUARTER; }
 | |
|         | SECOND_SYM      { $$=INTERVAL_SECOND; }
 | |
|         | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
 | |
|         | YEAR_SYM        { $$=INTERVAL_YEAR; }
 | |
|         ;
 | |
| 
 | |
| date_time_type:
 | |
|           DATE_SYM  {$$=MYSQL_TIMESTAMP_DATE;}
 | |
|         | TIME_SYM  {$$=MYSQL_TIMESTAMP_TIME;}
 | |
|         | DATETIME  {$$=MYSQL_TIMESTAMP_DATETIME;}
 | |
|         | TIMESTAMP {$$=MYSQL_TIMESTAMP_DATETIME;}
 | |
|         ;
 | |
| 
 | |
| table_alias:
 | |
|           /* empty */
 | |
|         | AS
 | |
|         | '='
 | |
|         ;
 | |
| 
 | |
| opt_table_alias_clause:
 | |
|           /* empty */ { $$=0; }
 | |
|         | table_alias_clause { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| table_alias_clause:
 | |
|           table_alias ident_table_alias
 | |
|           {
 | |
|             $$= (LEX_CSTRING*) thd->memdup(&$2,sizeof(LEX_STRING));
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_all:
 | |
|           /* empty */
 | |
|         | ALL
 | |
|         ;
 | |
| 
 | |
| opt_where_clause:
 | |
|           /* empty */  { Select->where= 0; }
 | |
|         | WHERE
 | |
|           {
 | |
|             Select->parsing_place= IN_WHERE;
 | |
|           }
 | |
|           search_condition
 | |
|           {
 | |
|             SELECT_LEX *select= Select;
 | |
|             select->where= normalize_cond(thd, $3);
 | |
|             select->parsing_place= NO_MATTER;
 | |
|             if ($3)
 | |
|               $3->top_level_item();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_having_clause:
 | |
|           /* empty */
 | |
|         | HAVING
 | |
|           {
 | |
|             Select->parsing_place= IN_HAVING;
 | |
|           }
 | |
|           search_condition
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             sel->having= normalize_cond(thd, $3);
 | |
|             sel->parsing_place= NO_MATTER;
 | |
|             if ($3)
 | |
|               $3->top_level_item();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|    group by statement in select
 | |
| */
 | |
| 
 | |
| opt_group_clause:
 | |
|           /* empty */
 | |
|         | GROUP_SYM BY group_list olap_opt
 | |
|         ;
 | |
| 
 | |
| group_list:
 | |
|           group_list ',' order_ident order_dir
 | |
|           {
 | |
|              if (unlikely(add_group_to_list(thd, $3,(bool) $4)))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|         | order_ident order_dir
 | |
|           {
 | |
|             if (unlikely(add_group_to_list(thd, $1,(bool) $2)))
 | |
|               MYSQL_YYABORT;
 | |
|            }
 | |
|         ;
 | |
| 
 | |
| olap_opt:
 | |
|           /* empty */ {}
 | |
|         | WITH_CUBE_SYM
 | |
|           {
 | |
|             /*
 | |
|               'WITH CUBE' is reserved in the MySQL syntax, but not implemented,
 | |
|               and cause LALR(2) conflicts.
 | |
|               This syntax is not standard.
 | |
|               MySQL syntax: GROUP BY col1, col2, col3 WITH CUBE
 | |
|               SQL-2003: GROUP BY ... CUBE(col1, col2, col3)
 | |
|             */
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(lex->current_select->get_linkage() == GLOBAL_OPTIONS_TYPE))
 | |
|               my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH CUBE",
 | |
|                                 "global union parameters"));
 | |
|             lex->current_select->olap= CUBE_TYPE;
 | |
| 
 | |
|             my_yyabort_error((ER_NOT_SUPPORTED_YET, MYF(0), "CUBE"));
 | |
|           }
 | |
|         | WITH_ROLLUP_SYM
 | |
|           {
 | |
|             /*
 | |
|               'WITH ROLLUP' is needed for backward compatibility,
 | |
|               and cause LALR(2) conflicts.
 | |
|               This syntax is not standard.
 | |
|               MySQL syntax: GROUP BY col1, col2, col3 WITH ROLLUP
 | |
|               SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3)
 | |
|             */
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->current_select->get_linkage() == GLOBAL_OPTIONS_TYPE))
 | |
|               my_yyabort_error((ER_WRONG_USAGE, MYF(0), "WITH ROLLUP",
 | |
|                                 "global union parameters"));
 | |
|             lex->current_select->olap= ROLLUP_TYPE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   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 (unlikely(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_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
 | |
|             if (unlikely(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 { Select->order_list= *($3); } 
 | |
|         ;
 | |
| 
 | |
| opt_window_frame_clause:
 | |
|           /* empty */ {}
 | |
|         | window_frame_units window_frame_extent opt_window_frame_exclusion
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->win_frame=
 | |
|               new (thd) Window_frame($1,
 | |
|                                                lex->frame_top_bound,
 | |
|                                                lex->frame_bottom_bound,
 | |
|                                                $3);
 | |
|             if (unlikely(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)
 | |
|                 Window_frame_bound(Window_frame_bound::CURRENT, NULL);
 | |
|             if (unlikely(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)
 | |
|                   Window_frame_bound(Window_frame_bound::PRECEDING, NULL); 
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           } 
 | |
|         | CURRENT_SYM ROW_SYM
 | |
|           { 
 | |
|             $$= new (thd)
 | |
|                   Window_frame_bound(Window_frame_bound::CURRENT, NULL); 
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | literal PRECEDING_SYM
 | |
|           {
 | |
|             $$= new (thd)
 | |
|                   Window_frame_bound(Window_frame_bound::PRECEDING, $1); 
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| window_frame_bound:
 | |
|           window_frame_start { $$= $1; }
 | |
|         | UNBOUNDED_SYM FOLLOWING_SYM        
 | |
|           {
 | |
|             $$= new (thd)
 | |
|                   Window_frame_bound(Window_frame_bound::FOLLOWING, NULL); 
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           } 
 | |
|         | literal FOLLOWING_SYM
 | |
|           {
 | |
|             $$= new (thd)
 | |
|                   Window_frame_bound(Window_frame_bound::FOLLOWING, $1); 
 | |
|             if (unlikely($$ == 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_MARIADB_SYM
 | |
|           { $$= Window_frame::EXCL_NONE; }
 | |
|         | EXCLUDE_SYM NO_SYM OTHERS_ORACLE_SYM
 | |
|           { $$= Window_frame::EXCL_NONE; }
 | |
|         ;      
 | |
|        
 | |
| /*
 | |
|   Order by statement in ALTER TABLE
 | |
| */
 | |
| 
 | |
| alter_order_clause:
 | |
|           ORDER_SYM BY alter_order_list
 | |
|         ;
 | |
| 
 | |
| alter_order_list:
 | |
|           alter_order_list ',' alter_order_item
 | |
|         | alter_order_item
 | |
|         ;
 | |
| 
 | |
| alter_order_item:
 | |
|           simple_ident_nospvar order_dir
 | |
|           {
 | |
|             bool ascending= ($2 == 1) ? true : false;
 | |
|             if (unlikely(add_order_to_list(thd, $1, ascending)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|    Order by statement in select
 | |
| */
 | |
| 
 | |
| opt_order_clause:
 | |
|           /* empty */
 | |
|           { $$= NULL; }
 | |
|         | order_clause
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| order_clause:
 | |
|           ORDER_SYM BY
 | |
|           {
 | |
|             thd->where= THD_WHERE::ORDER_CLAUSE;
 | |
|           }
 | |
|           order_list
 | |
|           {
 | |
|             $$= $4;
 | |
|           }
 | |
|          ;
 | |
| 
 | |
| order_list:
 | |
|           order_list ',' order_ident order_dir
 | |
|           {
 | |
|             $$= $1;
 | |
|             if (add_to_list(thd, *$$, $3,(bool) $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | order_ident order_dir
 | |
|           {
 | |
|             $$= new (thd) SQL_I_List<ORDER>();
 | |
|             if (add_to_list(thd, *$$, $1, (bool) $2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| order_dir:
 | |
|           /* empty */ { $$= 1; }
 | |
|         | ASC  { $$= 1; }
 | |
|         | DESC { $$= 0; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_limit_clause:
 | |
|           /* empty */
 | |
|           { $$.clear(); }
 | |
|         | limit_clause
 | |
|           { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| limit_clause:
 | |
|           LIMIT limit_options
 | |
|           {
 | |
|             $$= $2;
 | |
|             if (!$$.select_limit->basic_const_item() ||
 | |
|                 $$.select_limit->val_int() > 0)
 | |
|               Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|           }
 | |
|         | LIMIT limit_options
 | |
|           ROWS_SYM EXAMINED_SYM limit_rows_option
 | |
|           {
 | |
|             $$= $2;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|           }
 | |
|         | LIMIT ROWS_SYM EXAMINED_SYM limit_rows_option
 | |
|           {
 | |
|             $$.clear();
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|           }
 | |
|         | fetch_first_clause
 | |
|           {
 | |
|             $$= $1;
 | |
|             if (!$$.select_limit ||
 | |
|                 !$$.select_limit->basic_const_item() ||
 | |
|                  $$.select_limit->val_int() > 0)
 | |
|               Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| fetch_first_clause:
 | |
|           FETCH_SYM first_or_next row_or_rows only_or_with_ties
 | |
|           {
 | |
|             Item *one= new (thd) Item_int(thd, (int32) 1);
 | |
|             if (unlikely(one == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.select_limit= one;
 | |
|             $$.offset_limit= 0;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= $4;
 | |
|           }
 | |
|         | OFFSET_SYM limit_option row_or_rows
 | |
|           FETCH_SYM first_or_next row_or_rows only_or_with_ties
 | |
|           {
 | |
|             Item *one= new (thd) Item_int(thd, (int32) 1);
 | |
|             if (unlikely(one == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.select_limit= one;
 | |
|             $$.offset_limit= $2;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= $7;
 | |
|           }
 | |
|         | FETCH_SYM first_or_next limit_option row_or_rows only_or_with_ties
 | |
|           {
 | |
|             $$.select_limit= $3;
 | |
|             $$.offset_limit= 0;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= $5;
 | |
|           }
 | |
|         | OFFSET_SYM limit_option row_or_rows
 | |
|           FETCH_SYM first_or_next limit_option row_or_rows only_or_with_ties
 | |
|           {
 | |
|             $$.select_limit= $6;
 | |
|             $$.offset_limit= $2;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= $8;
 | |
|           }
 | |
|         | OFFSET_SYM limit_option row_or_rows
 | |
|           {
 | |
|             $$.select_limit= 0;
 | |
|             $$.offset_limit= $2;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= false;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| first_or_next:
 | |
|           FIRST_SYM
 | |
|         | NEXT_SYM
 | |
|         ;
 | |
| 
 | |
| row_or_rows:
 | |
|           ROW_SYM
 | |
|         | ROWS_SYM
 | |
|         ;
 | |
| 
 | |
| only_or_with_ties:
 | |
|           ONLY_SYM      { $$= 0; }
 | |
|         | WITH TIES_SYM { $$= 1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_global_limit_clause:
 | |
|           opt_limit_clause
 | |
|           {
 | |
|             Select->limit_params= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| limit_options:
 | |
|           limit_option
 | |
|           {
 | |
|             $$.select_limit= $1;
 | |
|             $$.offset_limit= NULL;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= false;
 | |
|           }
 | |
|         | limit_option ',' limit_option
 | |
|           {
 | |
|             $$.select_limit= $3;
 | |
|             $$.offset_limit= $1;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= false;
 | |
|           }
 | |
|         | limit_option OFFSET_SYM limit_option
 | |
|           {
 | |
|             $$.select_limit= $1;
 | |
|             $$.offset_limit= $3;
 | |
|             $$.explicit_limit= true;
 | |
|             $$.with_ties= false;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| limit_option:
 | |
|           ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_limit(thd, &$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_limit(thd, &$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | param_marker
 | |
|           {
 | |
|             $1->limit_clause_param= TRUE;
 | |
|           }
 | |
|         | ULONGLONG_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_uint(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LONG_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_uint(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NUM
 | |
|           {
 | |
|             $$= new (thd) Item_uint(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| limit_rows_option:
 | |
|           limit_option
 | |
|           { 
 | |
|             Lex->limit_rows_examined= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| delete_limit_clause:
 | |
|           /* empty */
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->current_select->limit_params.select_limit= 0;
 | |
|           }
 | |
|         | LIMIT limit_option
 | |
|           {
 | |
|             SELECT_LEX *sel= Select;
 | |
|             sel->limit_params.select_limit= $2;
 | |
|             Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
 | |
|             sel->limit_params.explicit_limit= 1;
 | |
|           }
 | |
|        | LIMIT ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
 | |
|        | LIMIT limit_option ROWS_SYM EXAMINED_SYM { thd->parse_error(); MYSQL_YYABORT; }
 | |
|         ;
 | |
| 
 | |
| order_limit_lock:
 | |
|           order_or_limit
 | |
|           {
 | |
|             $$= $1;
 | |
|             $$->lock.empty();
 | |
|           }
 | |
|         | order_or_limit select_lock_type
 | |
|           {
 | |
|             $$= $1;
 | |
|             $$->lock= $2;
 | |
|           }
 | |
|         | select_lock_type
 | |
|           {
 | |
|             $$= new (thd) Lex_order_limit_lock;
 | |
|             if (!$$)
 | |
|               YYABORT;
 | |
|             $$->order_list= NULL;
 | |
|             $$->limit.clear();
 | |
|             $$->lock= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_order_limit_lock:
 | |
|           /* empty */
 | |
|           {
 | |
|             Lex->pop_select();
 | |
|             $$= NULL;
 | |
|           }
 | |
|         | order_limit_lock { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| query_expression_tail:
 | |
|           order_limit_lock
 | |
|         ;
 | |
| 
 | |
| opt_query_expression_tail:
 | |
|           opt_order_limit_lock
 | |
|         ;
 | |
| 
 | |
| opt_procedure_or_into:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$.empty();
 | |
|           }
 | |
|         | procedure_clause opt_select_lock_type
 | |
|           {
 | |
|             $$= $2;
 | |
|           }
 | |
|         | into opt_select_lock_type
 | |
|           {
 | |
|             $$= $2;
 | |
|             status_var_increment(thd->status_var.feature_into_outfile);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_order_or_limit:
 | |
|           /* empty */
 | |
|           {
 | |
|             $$= NULL;
 | |
|           }
 | |
|         |
 | |
|           order_or_limit
 | |
|           {
 | |
|             $1->lock.empty();
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| order_or_limit:
 | |
|           order_clause opt_limit_clause
 | |
|           {
 | |
|             $$= new (thd) Lex_order_limit_lock;
 | |
|             if (!$$)
 | |
|               YYABORT;
 | |
|             $$->order_list= $1;
 | |
|             $$->limit= $2;
 | |
|           }
 | |
|         | limit_clause
 | |
|           {
 | |
|             $$= new (thd) Lex_order_limit_lock;
 | |
|             if (!$$)
 | |
|               YYABORT;
 | |
|             $$->order_list= NULL;
 | |
|             $$->limit= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_plus:
 | |
|           /* empty */
 | |
|         | '+'
 | |
|         ;
 | |
| 
 | |
| int_num:
 | |
|           opt_plus NUM           { int error; $$= (int) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | '-' NUM       { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         ;
 | |
| 
 | |
| ulong_num:
 | |
|           opt_plus NUM           { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | HEX_NUM       { $$= strtoul($1.str, (char**) 0, 16); }
 | |
|         | opt_plus LONG_NUM      { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus DECIMAL_NUM   { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus FLOAT_NUM     { int error; $$= (ulong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         ;
 | |
| 
 | |
| real_ulong_num:
 | |
|           NUM           { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | HEX_NUM       { $$= (ulong) strtol($1.str, (char**) 0, 16); }
 | |
|         | LONG_NUM      { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | dec_num_error { MYSQL_YYABORT; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   For simple sequence metadata values that are signed and do not need
 | |
|   truncation
 | |
| */
 | |
| sequence_value_num:
 | |
|           opt_plus NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= (longlong) my_strtoll10($2.str, (char**) 0, &error);
 | |
|           }
 | |
|         | opt_plus LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= (longlong) my_strtoll10($2.str, (char**) 0, &error);
 | |
|           }
 | |
|         | '-' NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error);
 | |
|           }
 | |
|         | '-' LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error);
 | |
|           }
 | |
|         | '-' ULONGLONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             const ulonglong abs= my_strtoll10($2.str, (char**) 0, &error);
 | |
|             if (abs == 1 + (ulonglong) LONGLONG_MAX)
 | |
|               $$= LONGLONG_MIN;
 | |
|             else
 | |
|               thd->parse_error(ER_DATA_OUT_OF_RANGE);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   For sequence metadata values that may be unsigned but do not need
 | |
|   truncation (start, restart)
 | |
| */
 | |
| sequence_value_hybrid_num:
 | |
|           opt_plus NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | opt_plus LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | opt_plus ULONGLONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 true);
 | |
|           }
 | |
|         | '-' NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | '-' LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | '-' ULONGLONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             const ulonglong abs= my_strtoll10($2.str, (char**) 0, &error);
 | |
|             if (abs == 1 + (ulonglong) LONGLONG_MAX)
 | |
|               $$= Longlong_hybrid(LONGLONG_MIN, false);
 | |
|             else
 | |
|               thd->parse_error(ER_DATA_OUT_OF_RANGE);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   For sequence metadata values that may be unsigned and need
 | |
|   truncation (maxvalue, minvalue)
 | |
| */
 | |
| sequence_truncated_value_hybrid_num:
 | |
|           opt_plus NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | opt_plus LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | opt_plus ULONGLONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 true);
 | |
|           }
 | |
|         | opt_plus DECIMAL_NUM { $$= Longlong_hybrid(ULONGLONG_MAX, true); }
 | |
|         | '-' NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | '-' LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error),
 | |
|                                 false);
 | |
|           }
 | |
|         | '-' ULONGLONG_NUM { $$= Longlong_hybrid(LONGLONG_MIN, false); }
 | |
|         | '-' DECIMAL_NUM { $$= Longlong_hybrid(LONGLONG_MIN, false); }
 | |
|         ;
 | |
| 
 | |
| ulonglong_num:
 | |
|           opt_plus NUM           { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus DECIMAL_NUM   { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         | opt_plus FLOAT_NUM     { int error; $$= (ulonglong) my_strtoll10($2.str, (char**) 0, &error); }
 | |
|         ;
 | |
| 
 | |
| real_ulonglong_num:
 | |
|           NUM           { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | HEX_NUM       { $$= strtoull($1.str, (char**) 0, 16); }
 | |
|         | LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
 | |
|         | dec_num_error { MYSQL_YYABORT; }
 | |
|         ;
 | |
| 
 | |
| dec_num_error:
 | |
|           dec_num
 | |
|           { thd->parse_error(ER_ONLY_INTEGERS_ALLOWED); }
 | |
|         ;
 | |
| 
 | |
| dec_num:
 | |
|           DECIMAL_NUM
 | |
|         | FLOAT_NUM
 | |
|         ;
 | |
| 
 | |
| choice:
 | |
| 	ulong_num { $$= $1 != 0 ? HA_CHOICE_YES : HA_CHOICE_NO; }
 | |
| 	| DEFAULT { $$= HA_CHOICE_UNDEF; }
 | |
| 	;
 | |
| 
 | |
| bool:
 | |
|         ulong_num   { $$= $1 != 0; }
 | |
|         | TRUE_SYM  { $$= 1; }
 | |
|         | FALSE_SYM { $$= 0; }
 | |
|         ;
 | |
| 
 | |
| procedure_clause:
 | |
|           PROCEDURE_SYM ident /* Procedure name */
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
| 
 | |
|             lex->proc_list.elements=0;
 | |
|             lex->proc_list.first=0;
 | |
|             lex->proc_list.next= &lex->proc_list.first;
 | |
|             Item_field *item= new (thd)
 | |
|                                 Item_field(thd, &lex->current_select->context,
 | |
|                                            $2);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(add_proc_to_list(thd, item)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
| 
 | |
|             /*
 | |
|               PROCEDURE CLAUSE cannot handle subquery as one of its parameter,
 | |
|               so disallow any subqueries further.
 | |
|               Alow subqueries back once the parameters are reduced.
 | |
|             */
 | |
|             Lex->clause_that_disallows_subselect= "PROCEDURE";
 | |
|             Select->options|= OPTION_PROCEDURE_CLAUSE;
 | |
|           }
 | |
|           '(' procedure_list ')'
 | |
|           {
 | |
|             /* Subqueries are allowed from now.*/
 | |
|             Lex->clause_that_disallows_subselect= NULL;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| procedure_list:
 | |
|           /* empty */ {}
 | |
|         | procedure_list2 {}
 | |
|         ;
 | |
| 
 | |
| procedure_list2:
 | |
|           procedure_list2 ',' procedure_item
 | |
|         | procedure_item
 | |
|         ;
 | |
| 
 | |
| procedure_item:
 | |
|           remember_name expr remember_end
 | |
|           {
 | |
|             if (unlikely(add_proc_to_list(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (!$2->name.str || $2->name.str == item_empty_name)
 | |
|               $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_var_list_init:
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (!lex->describe &&
 | |
|                 unlikely((!(lex->result= new (thd)
 | |
|                             select_dumpvar(thd)))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           select_var_list
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| select_var_list:
 | |
|           select_var_list ',' select_var_ident
 | |
|         | select_var_ident {}
 | |
|         ;
 | |
| 
 | |
| select_var_ident: select_outvar
 | |
|           {
 | |
|             if (Lex->result)
 | |
|             {
 | |
|               if (unlikely($1 == NULL))
 | |
|                 MYSQL_YYABORT;
 | |
|               ((select_dumpvar *)Lex->result)->var_list.push_back($1, thd->mem_root);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               /*
 | |
|                 The parser won't create select_result instance only
 | |
|                 if it's an EXPLAIN.
 | |
|               */
 | |
|               DBUG_ASSERT(Lex->describe);
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_outvar:
 | |
|           '@' ident_or_text
 | |
|           {
 | |
|             if (!$2.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             $$ = Lex->result ? new (thd) my_var_user(&$2) : NULL;
 | |
|           }
 | |
|         | ident_or_text
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_outvar(thd, &$1)) && Lex->result))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_outvar(thd, &$1, &$3)) && Lex->result))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| into:
 | |
|           INTO into_destination
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| into_destination:
 | |
|           OUTFILE TEXT_STRING_filesystem
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
|             if (unlikely(!(lex->exchange=
 | |
|                          new (thd) sql_exchange($2.str, 0))) ||
 | |
|                 unlikely(!(lex->result=
 | |
|                          new (thd)
 | |
|                          select_export(thd, lex->exchange))))
 | |
|               MYSQL_YYABORT;
 | |
|             status_var_increment(thd->status_var.feature_into_outfile);
 | |
|           }
 | |
|           opt_load_data_charset
 | |
|           { Lex->exchange->cs= $4; }
 | |
|           opt_field_term opt_line_term
 | |
|         | DUMPFILE TEXT_STRING_filesystem
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (!lex->describe)
 | |
|             {
 | |
|               lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
|               if (unlikely(!(lex->exchange=
 | |
|                              new (thd) sql_exchange($2.str,1))))
 | |
|                 MYSQL_YYABORT;
 | |
|               if (unlikely(!(lex->result=
 | |
|                            new (thd)
 | |
|                            select_dump(thd, lex->exchange))))
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         | select_var_list_init
 | |
|           {
 | |
|             Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 | |
|             status_var_increment(thd->status_var.feature_into_variable);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   DO statement
 | |
| */
 | |
| 
 | |
| do:
 | |
|           DO_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_DO;
 | |
|             if (lex->main_select_push(true))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|           }
 | |
|           expr_list
 | |
|           {
 | |
|             Lex->insert_list= $3;
 | |
|             Lex->pop_select(); //main select
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Drop : delete tables or index or user
 | |
| */
 | |
| 
 | |
| drop:
 | |
|           DROP opt_temporary table_or_tables opt_if_exists
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->set_command(SQLCOM_DROP_TABLE, $2, $4);
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|             YYPS->m_mdl_type= MDL_EXCLUSIVE;
 | |
|           }
 | |
|           table_list opt_lock_wait_timeout opt_restrict
 | |
|           {}
 | |
|         | DROP INDEX_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_if_exists_table_element ident ON table_ident opt_lock_wait_timeout
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Alter_drop *ad= (new (thd)
 | |
|                              Alter_drop(Alter_drop::KEY, $5, $4));
 | |
|             if (unlikely(ad == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->sql_command= SQLCOM_DROP_INDEX;
 | |
|             lex->alter_info.reset();
 | |
|             lex->alter_info.flags= ALTER_DROP_INDEX;
 | |
|             lex->alter_info.drop_list.push_back(ad, thd->mem_root);
 | |
|             if (unlikely(!lex->current_select->
 | |
|                          add_table_to_list(thd, $7, NULL, TL_OPTION_UPDATING,
 | |
|                                            TL_READ_NO_INSERT,
 | |
|                                            MDL_SHARED_UPGRADABLE)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | DROP DATABASE opt_if_exists ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->set_command(SQLCOM_DROP_DB, $3);
 | |
|             lex->name= $4;
 | |
|           }
 | |
|         | DROP USER_SYM opt_if_exists clear_privileges user_list
 | |
|           {
 | |
|             Lex->set_command(SQLCOM_DROP_USER, $3);
 | |
|           }
 | |
|         | DROP ROLE_SYM opt_if_exists clear_privileges role_list
 | |
|           {
 | |
|             Lex->set_command(SQLCOM_DROP_ROLE, $3);
 | |
|           }
 | |
|         | DROP VIEW_SYM opt_if_exists
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->set_command(SQLCOM_DROP_VIEW, $3);
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|             YYPS->m_mdl_type= MDL_EXCLUSIVE;
 | |
|           }
 | |
|           table_list opt_restrict
 | |
|           {}
 | |
|         | DROP EVENT_SYM opt_if_exists sp_name
 | |
|           {
 | |
|             Lex->spname= $4;
 | |
|             Lex->set_command(SQLCOM_DROP_EVENT, $3);
 | |
|           }
 | |
|         | DROP TRIGGER_SYM opt_if_exists sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->set_command(SQLCOM_DROP_TRIGGER, $3);
 | |
|             lex->spname= $4;
 | |
|           }
 | |
|         | DROP SERVER_SYM opt_if_exists ident_or_text
 | |
|           {
 | |
|             Lex->set_command(SQLCOM_DROP_SERVER, $3);
 | |
|             Lex->server_options.reset($4);
 | |
|           }
 | |
|         | DROP opt_temporary SEQUENCE_SYM opt_if_exists
 | |
| 
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->set_command(SQLCOM_DROP_SEQUENCE, $2, $4);
 | |
|             lex->table_type= TABLE_TYPE_SEQUENCE;
 | |
|             YYPS->m_lock_type= TL_UNLOCK;
 | |
|             YYPS->m_mdl_type= MDL_EXCLUSIVE;
 | |
|           }
 | |
|           table_list
 | |
|           {}
 | |
|         | drop_routine
 | |
|         ;
 | |
| 
 | |
| table_list:
 | |
|           table_name
 | |
|         | table_list ',' table_name
 | |
|         ;
 | |
| 
 | |
| table_name:
 | |
|           table_ident
 | |
|           {
 | |
|             if (!thd->lex->current_select_or_default()->
 | |
|                                            add_table_to_list(thd, $1, NULL,
 | |
|                                            TL_OPTION_UPDATING,
 | |
|                                            YYPS->m_lock_type,
 | |
|                                            YYPS->m_mdl_type))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_name_with_opt_use_partition:
 | |
|           table_ident opt_use_partition
 | |
|           {
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $1, NULL,
 | |
|                                                     TL_OPTION_UPDATING,
 | |
|                                                     YYPS->m_lock_type,
 | |
|                                                     YYPS->m_mdl_type,
 | |
|                                                     NULL,
 | |
|                                                     $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_alias_ref_list:
 | |
|           table_alias_ref
 | |
|         | table_alias_ref_list ',' table_alias_ref
 | |
|         ;
 | |
| 
 | |
| table_alias_ref:
 | |
|           table_ident_opt_wild
 | |
|           {
 | |
|             if (unlikely(!Select->
 | |
|                          add_table_to_list(thd, $1, NULL,
 | |
|                                            (TL_OPTION_UPDATING |
 | |
|                                             TL_OPTION_ALIAS),
 | |
|                                            YYPS->m_lock_type,
 | |
|                                            YYPS->m_mdl_type)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_if_exists_table_element:
 | |
|           /* empty */
 | |
|         {
 | |
|           Lex->check_exists= FALSE;
 | |
|           $$= 0;
 | |
|         }
 | |
|         | IF_SYM EXISTS
 | |
|         {
 | |
|           Lex->check_exists= TRUE;
 | |
|           $$= 1;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_if_exists:
 | |
|           /* empty */        %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         {
 | |
|           $$.set(DDL_options_st::OPT_NONE);
 | |
|         }
 | |
|         | IF_SYM EXISTS
 | |
|         {
 | |
|           $$.set(DDL_options_st::OPT_IF_EXISTS);
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_temporary:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | TEMPORARY { $$= HA_LEX_CREATE_TMP_TABLE; }
 | |
|         ;
 | |
| /*
 | |
| ** Insert : add new data to table
 | |
| */
 | |
| 
 | |
| insert:
 | |
|           INSERT
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_INSERT;
 | |
|             Lex->duplicates= DUP_ERROR;
 | |
|             thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
 | |
|             thd->get_stmt_da()->reset_current_row_for_warning(1);
 | |
|           }
 | |
|           insert_start insert_lock_option opt_ignore opt_into insert_table
 | |
|           {
 | |
|             Select->set_lock_for_tables($4, true, false);
 | |
|           }
 | |
|           insert_field_spec opt_insert_update opt_returning
 | |
|           stmt_end
 | |
|           {
 | |
|             Lex->mark_first_table_as_inserting();
 | |
|             thd->get_stmt_da()->reset_current_row_for_warning(0);
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| replace:
 | |
|           REPLACE
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_REPLACE;
 | |
|             Lex->duplicates= DUP_REPLACE;
 | |
|             thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
 | |
|             thd->get_stmt_da()->reset_current_row_for_warning(1);
 | |
|           }
 | |
|           insert_start replace_lock_option opt_into insert_table
 | |
|           {
 | |
|             Select->set_lock_for_tables($4, true, false);
 | |
|           }
 | |
|           insert_field_spec opt_returning
 | |
|           stmt_end
 | |
|           {
 | |
|             Lex->mark_first_table_as_inserting();
 | |
|             thd->get_stmt_da()->reset_current_row_for_warning(0);
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| insert_start: {
 | |
|                 if (Lex->main_select_push())
 | |
|                   MYSQL_YYABORT;
 | |
|                 Lex->init_select();
 | |
|                 Lex->inc_select_stack_outer_barrier();
 | |
|                 Lex->current_select->parsing_place= BEFORE_OPT_LIST;
 | |
|               }
 | |
|               ;
 | |
| 
 | |
| stmt_end: {
 | |
|               Lex->pop_select(); //main select
 | |
|               if (Lex->check_main_unit_semantics())
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             ;
 | |
| 
 | |
| insert_lock_option:
 | |
|           /* empty */
 | |
|           {
 | |
|             /*
 | |
|               If it is SP we do not allow insert optimisation when result of
 | |
|               insert visible only after the table unlocking but everyone can
 | |
|               read table.
 | |
|             */
 | |
|             $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
 | |
|           }
 | |
|         | insert_replace_option
 | |
|         | HIGH_PRIORITY { $$= TL_WRITE; }
 | |
|         ;
 | |
| 
 | |
| replace_lock_option:
 | |
|           /* empty */ { $$= TL_WRITE_DEFAULT; }
 | |
|         | insert_replace_option
 | |
|         ;
 | |
| 
 | |
| insert_replace_option:
 | |
|           LOW_PRIORITY  { $$= TL_WRITE_LOW_PRIORITY; }
 | |
|         | DELAYED_SYM
 | |
|         {
 | |
|           Lex->keyword_delayed_begin_offset= (uint)($1.pos() - thd->query());
 | |
|           Lex->keyword_delayed_end_offset= (uint)($1.end() - thd->query());
 | |
|           $$= TL_WRITE_DELAYED;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_into: /* nothing */ | INTO ;
 | |
| 
 | |
| insert_table:
 | |
|           {
 | |
|             Select->save_parsing_place= Select->parsing_place;
 | |
|           }
 | |
|           table_name_with_opt_use_partition
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             //lex->field_list.empty();
 | |
|             lex->many_values.empty();
 | |
|             lex->insert_list=0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| insert_field_spec:
 | |
|           insert_values {}
 | |
|         | insert_field_list insert_values {}
 | |
|         | SET
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(!(lex->insert_list= new (thd) List_item)) ||
 | |
|                 unlikely(lex->many_values.push_back(lex->insert_list,
 | |
|                          thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->current_select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|           ident_eq_list
 | |
|         ;
 | |
| 
 | |
| insert_field_list:
 | |
|           LEFT_PAREN_ALT opt_fields ')'
 | |
|           {
 | |
|             Lex->current_select->parsing_place= AFTER_LIST;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_fields:
 | |
|           /* empty */
 | |
|         | fields
 | |
|         ;
 | |
| 
 | |
| fields:
 | |
|           fields ',' insert_ident
 | |
|           { Lex->field_list.push_back($3, thd->mem_root); }
 | |
|         | insert_ident { Lex->field_list.push_back($1, thd->mem_root); }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| 
 | |
| insert_values:
 | |
|          create_select_query_expression {}
 | |
|         ;
 | |
| 
 | |
| values_list:
 | |
|           values_list ','  no_braces
 | |
|         | no_braces_with_names
 | |
|         ;
 | |
| 
 | |
| ident_eq_list:
 | |
|           ident_eq_list ',' ident_eq_value
 | |
|         | ident_eq_value
 | |
|         ;
 | |
| 
 | |
| ident_eq_value:
 | |
|           simple_ident_nospvar equal expr_or_ignore_or_default
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(lex->field_list.push_back($1, thd->mem_root)) ||
 | |
|                 unlikely(lex->insert_list->push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| equal:
 | |
|           '=' {}
 | |
|         | SET_VAR {}
 | |
|         ;
 | |
| 
 | |
| opt_equal:
 | |
|           /* empty */ {}
 | |
|         | equal {}
 | |
|         ;
 | |
| 
 | |
| opt_with:
 | |
|           opt_equal {}
 | |
|         | WITH {}
 | |
|         ;
 | |
| 
 | |
| opt_by:
 | |
|           opt_equal {}
 | |
|         | BY {}
 | |
|         ;
 | |
| 
 | |
| no_braces:
 | |
|           '('
 | |
|           {
 | |
|             if (unlikely(!(Lex->insert_list= new (thd) List_item)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_values ')'
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             thd->get_stmt_da()->inc_current_row_for_warning();
 | |
|             if (unlikely(lex->many_values.push_back(lex->insert_list,
 | |
|                                                     thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| no_braces_with_names:
 | |
|           '('
 | |
|           {
 | |
|             if (unlikely(!(Lex->insert_list= new (thd) List_item)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_values_with_names ')'
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             thd->get_stmt_da()->inc_current_row_for_warning();
 | |
|             if (unlikely(lex->many_values.push_back(lex->insert_list,
 | |
|                                                     thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_values:
 | |
|           /* empty */ {}
 | |
|         | values
 | |
|         ;
 | |
| 
 | |
| opt_values_with_names:
 | |
|           /* empty */ {}
 | |
|         | values_with_names
 | |
|         ;
 | |
| 
 | |
| values:
 | |
|           values ','  expr_or_ignore_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->insert_list->push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | expr_or_ignore_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->insert_list->push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| values_with_names:
 | |
|           values_with_names ','  remember_name expr_or_ignore_or_default remember_end
 | |
|           {
 | |
|             if (unlikely(Lex->insert_list->push_back($4, thd->mem_root)))
 | |
|                MYSQL_YYABORT;
 | |
|             // give some name in case of using in table value constuctor (TVC)
 | |
|             if (!$4->name.str || $4->name.str == item_empty_name)
 | |
|               $4->set_name(thd, $3, (uint) ($5 - $3), thd->charset());
 | |
|            }
 | |
|         | remember_name expr_or_ignore_or_default remember_end
 | |
|           {
 | |
|             if (unlikely(Lex->insert_list->push_back($2, thd->mem_root)))
 | |
|                MYSQL_YYABORT;
 | |
|             // give some name in case of using in table value constuctor (TVC)
 | |
|             if (!$2->name.str || $2->name.str == item_empty_name)
 | |
|               $2->set_name(thd, $1, (uint) ($3 - $1), thd->charset());
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| expr_or_ignore:
 | |
|           expr { $$= $1;}
 | |
|         | IGNORE_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_ignore_specification(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| expr_or_ignore_or_default:
 | |
|           expr_or_ignore { $$= $1;}
 | |
|         | DEFAULT
 | |
|           {
 | |
|             $$= new (thd) Item_default_specification(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_insert_update:
 | |
|           /* empty */
 | |
|         | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
 | |
|           KEY_SYM UPDATE_SYM 
 | |
|           {
 | |
| 	    Select->parsing_place= IN_UPDATE_ON_DUP_KEY;
 | |
|           }
 | |
|           insert_update_list
 | |
|           {
 | |
| 	    Select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| update_table_list:
 | |
|           table_ident opt_use_partition for_portion_of_time_clause
 | |
|           opt_table_alias_clause opt_key_definition
 | |
|           {
 | |
|             if (!($$= Select->add_table_to_list(thd, $1, $4,
 | |
|                                                 0,
 | |
|                                                 YYPS->m_lock_type,
 | |
|                                                 YYPS->m_mdl_type,
 | |
|                                                 Select->pop_index_hints(),
 | |
|                                                 $2)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->period_conditions= Lex->period_conditions;
 | |
|           }
 | |
|         | join_table_list { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| /* Update rows in a table */
 | |
| 
 | |
| update:
 | |
|           UPDATE_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|             lex->sql_command= SQLCOM_UPDATE;
 | |
|             lex->duplicates= DUP_ERROR; 
 | |
|           }
 | |
|           opt_low_priority opt_ignore update_table_list
 | |
|           SET update_list
 | |
|           {
 | |
|             bool is_multiupdate= false;
 | |
|             LEX *lex= Lex;
 | |
|             SELECT_LEX *slex= Lex->first_select_lex();
 | |
|             if (slex->table_list.elements > 1)
 | |
|             {
 | |
|               Lex->sql_command= SQLCOM_UPDATE_MULTI;
 | |
|               is_multiupdate= true;
 | |
|             }
 | |
|             else if (slex->get_table_list()->derived)
 | |
|             {
 | |
|               /* it is single table update and it is update of derived table */
 | |
|               my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
 | |
|                        slex->get_table_list()->alias.str, "UPDATE");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (!(lex->m_sql_cmd=
 | |
|                   new (thd) Sql_cmd_update(is_multiupdate)))
 | |
|               MYSQL_YYABORT;
 | |
|             /*
 | |
|               In case of multi-update setting write lock for all tables may
 | |
|               be too pessimistic. We will decrease lock level if possible
 | |
|               later while processing the statement.
 | |
|             */
 | |
|             slex->set_lock_for_tables($3, slex->table_list.elements == 1, false);
 | |
|           }
 | |
|           opt_where_clause opt_order_clause delete_limit_clause
 | |
|           {
 | |
|             if ($10)
 | |
|               Select->order_list= *($10);
 | |
|           } stmt_end {}
 | |
|         ;
 | |
| 
 | |
| update_list:
 | |
|           update_list ',' update_elem
 | |
|         | update_elem
 | |
|         ;
 | |
| 
 | |
| update_elem:
 | |
|           simple_ident_nospvar equal DEFAULT
 | |
|           {
 | |
|             Item *def= new (thd) Item_default_value(thd,
 | |
|                                              Lex->current_context(), $1, 1);
 | |
|             if (!def || add_item_to_list(thd, $1) || add_value_to_list(thd, def))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | simple_ident_nospvar equal expr_or_ignore
 | |
|           {
 | |
|             if (add_item_to_list(thd, $1) || add_value_to_list(thd, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| insert_update_list:
 | |
|           insert_update_list ',' insert_update_elem
 | |
|         | insert_update_elem
 | |
|         ;
 | |
| 
 | |
| insert_update_elem:
 | |
|           simple_ident_nospvar equal expr_or_ignore_or_default
 | |
|           {
 | |
|           LEX *lex= Lex;
 | |
|           if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
 | |
|               unlikely(lex->value_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_low_priority:
 | |
|           /* empty */ { $$= TL_WRITE_DEFAULT; }
 | |
|         | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
 | |
|         ;
 | |
| 
 | |
| /* Delete rows from a table */
 | |
| 
 | |
| delete:
 | |
|           DELETE_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             YYPS->m_lock_type= TL_WRITE_DEFAULT;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_WRITE;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             mysql_init_delete(lex);
 | |
|             lex->ignore= 0;
 | |
|             lex->first_select_lex()->order_list.empty();
 | |
|           }
 | |
|           delete_part2
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| opt_delete_system_time:
 | |
|             /* empty */
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_HISTORY);
 | |
|           }
 | |
|           | BEFORE_SYM SYSTEM_TIME_SYM history_point
 | |
|           {
 | |
|             Lex->vers_conditions.init(SYSTEM_TIME_BEFORE, $3);
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| delete_part2:
 | |
|           opt_delete_options single_multi {}
 | |
|         | HISTORY_SYM delete_single_table opt_delete_system_time
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->last_table()->vers_conditions= lex->vers_conditions;
 | |
|             lex->sql_command= SQLCOM_DELETE;
 | |
|             if (!(lex->m_sql_cmd=
 | |
|                   new (thd) Sql_cmd_delete(false)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (lex->check_main_unit_semantics())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           stmt_end
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| delete_single_table:
 | |
|           FROM table_ident opt_table_alias_clause opt_key_definition opt_use_partition
 | |
|           {
 | |
|             if (unlikely(!Select->
 | |
|                          add_table_to_list(thd, $2, $3, TL_OPTION_UPDATING,
 | |
|                                            YYPS->m_lock_type,
 | |
|                                            YYPS->m_mdl_type,
 | |
|                                            NULL,
 | |
|                                            0)))
 | |
|               MYSQL_YYABORT;
 | |
|             Select->table_list.save_and_clear(&Lex->auxiliary_table_list);
 | |
|             /* Save the number of auxiliary tables */
 | |
|             Lex->table_count_update= 1;
 | |
| 
 | |
|             Lex->query_tables= 0;
 | |
|             Lex->query_tables_last= &Lex->query_tables;
 | |
|             if (unlikely(!Select->
 | |
|                          add_table_to_list(thd, $2, $3, TL_OPTION_UPDATING,
 | |
|                                            YYPS->m_lock_type,
 | |
|                                            YYPS->m_mdl_type,
 | |
|                                            Select->pop_index_hints(),
 | |
|                                            $5)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->auxiliary_table_list.first->correspondent_table=
 | |
|               Lex->query_tables;
 | |
|             YYPS->m_lock_type= TL_READ_DEFAULT;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_READ;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| delete_single_table_for_period:
 | |
|           delete_single_table opt_for_portion_of_time_clause
 | |
|           {
 | |
|             if ($2)
 | |
|               Lex->last_table()->period_conditions= Lex->period_conditions;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| single_multi:
 | |
|           delete_single_table_for_period
 | |
|           opt_where_clause
 | |
|           opt_order_clause
 | |
|           delete_limit_clause
 | |
|           opt_returning
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if ($3)
 | |
|               Select->order_list= *($3);
 | |
|             lex->sql_command= SQLCOM_DELETE;
 | |
|             if (!(lex->m_sql_cmd=
 | |
|                   new (thd) Sql_cmd_delete(false)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (Lex->check_main_unit_semantics())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           stmt_end {}
 | |
|         | table_alias_ref_list
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_DELETE_MULTI;
 | |
|             if (!(lex->m_sql_cmd=
 | |
|                   new (thd) Sql_cmd_delete(true)))
 | |
|               MYSQL_YYABORT;
 | |
|             mysql_init_multi_delete(Lex);
 | |
|             YYPS->m_lock_type= TL_READ_DEFAULT;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_READ;
 | |
|           }
 | |
|           FROM join_table_list opt_where_clause opt_order_or_limit
 | |
|           {
 | |
|             if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($6)
 | |
|             {
 | |
|               DBUG_ASSERT(Lex->select_stack_head() == Select);
 | |
|               $6->set_to(Lex->select_stack_head());
 | |
|             }
 | |
|           } stmt_end {}
 | |
|         | FROM table_alias_ref_list
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_DELETE_MULTI;
 | |
|             if (!(lex->m_sql_cmd=
 | |
|                   new (thd) Sql_cmd_delete(true)))
 | |
|               MYSQL_YYABORT;
 | |
|             mysql_init_multi_delete(Lex);
 | |
|             YYPS->m_lock_type= TL_READ_DEFAULT;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_READ;
 | |
|           }
 | |
|           USING join_table_list opt_where_clause opt_order_or_limit
 | |
|           {
 | |
|             if (unlikely(multi_delete_set_locks_and_link_aux_tables(Lex)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($7)
 | |
|             {
 | |
|               DBUG_ASSERT(Lex->select_stack_head() == Select);
 | |
|               $7->set_to(Lex->select_stack_head());
 | |
|             }
 | |
|           } stmt_end {}
 | |
|         ;
 | |
| 
 | |
| opt_returning:
 | |
|           /* empty */
 | |
|           {
 | |
|             DBUG_ASSERT(!Lex->has_returning());
 | |
|           }
 | |
|         | RETURNING_SYM
 | |
|           {
 | |
|             DBUG_ASSERT(!Lex->has_returning());
 | |
|             /*
 | |
|               When parsing_place is IN_RETURNING, we push select items to
 | |
|               item_list of builtin_select instead of current_select.
 | |
|               But set parsing_place of current_select to true.
 | |
| 
 | |
|               Because parsing_place for builtin_select will be IN_RETURNING,
 | |
|               regardless there is SELECT in RETURNING. Example, if
 | |
|               there is RETURNING (SELECT...), then when we parse
 | |
|               SELECT inside RETURNING, builtin_select->parsing_place
 | |
|               will still be true. So the select items of SELECT inside
 | |
|               RETURNING will be added to item_list of builtin_select which
 | |
|               is incorrect. We want to prevent this from happening.
 | |
|               Since for every new select, a new SELECT_LEX
 | |
|               object is created and pushed to select stack, current_select
 | |
|               will point to SELECT inside RETURNING, and also has
 | |
|               parsing_place not set to IN_RETURNING by default.
 | |
|               So items are correctly added to item_list of SELECT inside
 | |
|               RETURNING instead of builtin_select.
 | |
|             */
 | |
| 
 | |
|             thd->lex->current_select->parsing_place= IN_RETURNING;
 | |
|             thd->lex->push_context(&thd->lex->returning()->context);
 | |
|           }
 | |
|           select_item_list
 | |
|           {
 | |
|             thd->lex->pop_context();
 | |
|             thd->lex->current_select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_wild:
 | |
|           /* empty */ {}
 | |
|         | '.' '*' {}
 | |
|         ;
 | |
| 
 | |
| opt_delete_options:
 | |
|           /* empty */ {}
 | |
|         | opt_delete_option opt_delete_options {}
 | |
|         ;
 | |
| 
 | |
| opt_delete_option:
 | |
|           QUICK        { Select->options|= OPTION_QUICK; }
 | |
|         | LOW_PRIORITY { YYPS->m_lock_type= TL_WRITE_LOW_PRIORITY; }
 | |
|         | IGNORE_SYM   { Lex->ignore= 1; }
 | |
|         ;
 | |
| 
 | |
| truncate:
 | |
|           TRUNCATE_SYM
 | |
|           {
 | |
|             LEX* lex= Lex;
 | |
|             lex->sql_command= SQLCOM_TRUNCATE;
 | |
|             lex->alter_info.reset();
 | |
|             lex->first_select_lex()->options= 0;
 | |
|             lex->sql_cache= LEX::SQL_CACHE_UNSPECIFIED;
 | |
|             lex->first_select_lex()->order_list.empty();
 | |
|             YYPS->m_lock_type= TL_WRITE;
 | |
|             YYPS->m_mdl_type= MDL_EXCLUSIVE;
 | |
|           }
 | |
|           opt_table_sym table_name opt_lock_wait_timeout
 | |
|           {
 | |
|             LEX* lex= thd->lex;
 | |
|             DBUG_ASSERT(!lex->m_sql_cmd);
 | |
|             lex->m_sql_cmd= new (thd) Sql_cmd_truncate_table();
 | |
|             if (unlikely(lex->m_sql_cmd == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_truncate_table_storage_clause { }
 | |
|         ;
 | |
| 
 | |
| opt_table_sym:
 | |
|           /* empty */
 | |
|         | TABLE_SYM
 | |
|         ;
 | |
| 
 | |
| opt_profile_defs:
 | |
|   /* empty */
 | |
|   | profile_defs;
 | |
| 
 | |
| profile_defs:
 | |
|   profile_def
 | |
|   | profile_defs ',' profile_def;
 | |
| 
 | |
| profile_def:
 | |
|   CPU_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_CPU;
 | |
|     }
 | |
|   | MEMORY_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_MEMORY;
 | |
|     }
 | |
|   | BLOCK_SYM IO_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_BLOCK_IO;
 | |
|     }
 | |
|   | CONTEXT_SYM SWITCHES_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_CONTEXT;
 | |
|     }
 | |
|   | PAGE_SYM FAULTS_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_PAGE_FAULTS;
 | |
|     }
 | |
|   | IPC_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_IPC;
 | |
|     }
 | |
|   | SWAPS_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_SWAPS;
 | |
|     }
 | |
|   | SOURCE_SYM
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_SOURCE;
 | |
|     }
 | |
|   | ALL
 | |
|     {
 | |
|       Lex->profile_options|= PROFILE_ALL;
 | |
|     }
 | |
|   ;
 | |
| 
 | |
| opt_profile_args:
 | |
|   /* empty */
 | |
|     {
 | |
|       Lex->profile_query_id= 0;
 | |
|     }
 | |
|   | FOR_SYM QUERY_SYM NUM
 | |
|     {
 | |
|       Lex->profile_query_id= atoi($3.str);
 | |
|     }
 | |
|   ;
 | |
| 
 | |
| /* Show things */
 | |
| 
 | |
| show:
 | |
|           SHOW
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->wild=0;
 | |
|             lex->ident= null_clex_str;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|             lex->current_select->parsing_place= SELECT_LIST;
 | |
|             lex->create_info.init();
 | |
|           }
 | |
|           show_param
 | |
|           {
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| show_param:
 | |
|            DATABASES wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              lex->sql_command= SQLCOM_SHOW_DATABASES;
 | |
|              if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SCHEMATA)))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|          | opt_full TABLES opt_db wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              lex->sql_command= SQLCOM_SHOW_TABLES;
 | |
|              lex->first_select_lex()->db= $3;
 | |
|              if (prepare_schema_table(thd, lex, 0, SCH_TABLE_NAMES))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|          | opt_full TRIGGERS_SYM opt_db wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              lex->sql_command= SQLCOM_SHOW_TRIGGERS;
 | |
|              lex->first_select_lex()->db= $3;
 | |
|              if (prepare_schema_table(thd, lex, 0, SCH_TRIGGERS))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|          | EVENTS_SYM opt_db wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              lex->sql_command= SQLCOM_SHOW_EVENTS;
 | |
|              lex->first_select_lex()->db= $2;
 | |
|              if (prepare_schema_table(thd, lex, 0, SCH_EVENTS))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|          | TABLE_SYM STATUS_SYM opt_db wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
 | |
|              lex->first_select_lex()->db= $3;
 | |
|              if (prepare_schema_table(thd, lex, 0, SCH_TABLES))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|         | OPEN_SYM TABLES opt_db wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
 | |
|             lex->first_select_lex()->db= $3;
 | |
|             if (prepare_schema_table(thd, lex, 0, SCH_OPEN_TABLES))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PLUGINS_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_PLUGINS;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PLUGINS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PLUGINS_SYM SONAME_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->ident= $3;
 | |
|             Lex->sql_command= SQLCOM_SHOW_PLUGINS;
 | |
|             if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PLUGINS_SYM SONAME_SYM wild_and_where
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_PLUGINS;
 | |
|             if (unlikely(prepare_schema_table(thd, Lex, 0, SCH_ALL_PLUGINS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ENGINE_SYM known_storage_engines show_engine_param
 | |
|           { Lex->create_info.db_type= $2; }
 | |
|         | ENGINE_SYM ALL show_engine_param
 | |
|           { Lex->create_info.db_type= NULL; }
 | |
|         | opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_FIELDS;
 | |
|             if ($5.str)
 | |
|               $4->change_db(&$5);
 | |
|             if (unlikely(prepare_schema_table(thd, lex, $4, SCH_COLUMNS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | master_or_binary LOGS_SYM
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_SHOW_BINLOGS;
 | |
|           }
 | |
|         | SLAVE HOSTS_SYM
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
 | |
|           }
 | |
|         | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
 | |
|           }
 | |
|           opt_global_limit_clause
 | |
|         | RELAYLOG_SYM optional_connection_name EVENTS_SYM binlog_in binlog_from
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS;
 | |
|           }
 | |
|           opt_global_limit_clause optional_for_channel
 | |
|           { }
 | |
|         | keys_or_index from_or_in table_ident opt_db opt_where_clause
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_KEYS;
 | |
|             if ($4.str)
 | |
|               $3->change_db(&$4);
 | |
|             if (unlikely(prepare_schema_table(thd, lex, $3, SCH_STATISTICS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | opt_storage ENGINES_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_ENGINES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | AUTHORS_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_AUTHORS;
 | |
|           }
 | |
|         | CONTRIBUTORS_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_CONTRIBUTORS;
 | |
|           }
 | |
|         | PRIVILEGES
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_PRIVILEGES;
 | |
|           }
 | |
|         | COUNT_SYM '(' '*' ')' WARNINGS
 | |
|           {
 | |
|             LEX_CSTRING var= {STRING_WITH_LEN("warning_count")};
 | |
|             (void) create_select_for_variable(thd, &var);
 | |
|           }
 | |
|         | COUNT_SYM '(' '*' ')' ERRORS
 | |
|           {
 | |
|             LEX_CSTRING var= {STRING_WITH_LEN("error_count")};
 | |
|             (void) create_select_for_variable(thd, &var);
 | |
|           }
 | |
|         | WARNINGS opt_global_limit_clause
 | |
|           { Lex->sql_command = SQLCOM_SHOW_WARNS;}
 | |
|         | ERRORS opt_global_limit_clause
 | |
|           { Lex->sql_command = SQLCOM_SHOW_ERRORS;}
 | |
|         | PROFILES_SYM
 | |
|           { Lex->sql_command = SQLCOM_SHOW_PROFILES; }
 | |
|         | PROFILE_SYM opt_profile_defs opt_profile_args opt_global_limit_clause
 | |
|           { 
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_PROFILE;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, NULL, SCH_PROFILES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | opt_var_type STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS;
 | |
|             lex->option_type= $1;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_STATUS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | opt_full PROCESSLIST_SYM
 | |
|           { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
 | |
|         | opt_var_type  VARIABLES wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_VARIABLES;
 | |
|             lex->option_type= $1;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_SESSION_VARIABLES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | charset wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_CHARSETS;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_CHARSETS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLLATION_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_COLLATIONS;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_COLLATIONS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | GRANTS
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_GRANTS;
 | |
|             if (unlikely(!(Lex->grant_user= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->grant_user->user= current_user_and_current_role;
 | |
|           }
 | |
|         | GRANTS FOR_SYM user_or_role clear_privileges
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_GRANTS;
 | |
|             lex->grant_user=$3;
 | |
|           }
 | |
|         | CREATE DATABASE opt_if_not_exists ident
 | |
|           {
 | |
|             Lex->set_command(SQLCOM_SHOW_CREATE_DB, $3);
 | |
|             Lex->name= $4;
 | |
|           }
 | |
|         | CREATE TABLE_SYM table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE;
 | |
|             if (!lex->first_select_lex()->add_table_to_list(thd, $3, NULL,0))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->create_info.storage_media= HA_SM_DEFAULT;
 | |
|           }
 | |
|         | CREATE VIEW_SYM table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE;
 | |
|             if (!lex->first_select_lex()->add_table_to_list(thd, $3, NULL, 0))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->table_type= TABLE_TYPE_VIEW;
 | |
|           }
 | |
|         | CREATE SEQUENCE_SYM table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE;
 | |
|             if (!lex->first_select_lex()->add_table_to_list(thd, $3, NULL, 0))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->table_type= TABLE_TYPE_SEQUENCE;
 | |
|           }
 | |
|         | BINLOG_SYM STATUS_SYM
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_SHOW_BINLOG_STAT;
 | |
|           }
 | |
|         | MASTER_SYM STATUS_SYM
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_SHOW_BINLOG_STAT;
 | |
|           }
 | |
|         | ALL SLAVES STATUS_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_SLAVE_STAT;
 | |
|             lex->mi.show_all_slaves= 1;
 | |
| #ifdef HAVE_REPLICATION
 | |
|             if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS))
 | |
|               MYSQL_YYABORT;
 | |
| #endif
 | |
|           }
 | |
|         | SLAVE optional_connection_name STATUS_SYM optional_for_channel
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_SLAVE_STAT;
 | |
|             lex->mi.show_all_slaves= 0;
 | |
| #ifdef HAVE_REPLICATION
 | |
|             if (prepare_schema_table(thd, lex, 0, SCH_SLAVE_STATUS))
 | |
|               MYSQL_YYABORT;
 | |
| #endif
 | |
|           }
 | |
|         | CREATE PROCEDURE_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_PROC;
 | |
|             lex->spname= $3;
 | |
|           }
 | |
|         | CREATE FUNCTION_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_FUNC;
 | |
|             lex->spname= $3;
 | |
|           }
 | |
|         | CREATE PACKAGE_MARIADB_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE;
 | |
|             lex->spname= $3;
 | |
|           }
 | |
|         | CREATE PACKAGE_ORACLE_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE;
 | |
|             lex->spname= $3;
 | |
|           }
 | |
|         | CREATE PACKAGE_MARIADB_SYM BODY_MARIADB_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE_BODY;
 | |
|             lex->spname= $4;
 | |
|           }
 | |
|         | CREATE PACKAGE_ORACLE_SYM BODY_ORACLE_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_PACKAGE_BODY;
 | |
|             lex->spname= $4;
 | |
|           }
 | |
|         | CREATE SERVER_SYM ident_or_text
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command = SQLCOM_SHOW_CREATE_SERVER;
 | |
|             lex->name= $3;
 | |
|           }
 | |
|         | CREATE TRIGGER_SYM sp_name
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER;
 | |
|             lex->spname= $3;
 | |
|           }
 | |
|         | CREATE USER_SYM
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_CREATE_USER;
 | |
|             if (unlikely(!(Lex->grant_user= thd->calloc<LEX_USER>(1))))
 | |
|               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;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | FUNCTION_SYM STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PACKAGE_MARIADB_SYM STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PACKAGE_ORACLE_SYM STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM STATUS_SYM wild_and_where
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_SHOW_STATUS_PACKAGE_BODY;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, 0, SCH_PROCEDURES)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PROCEDURE_SYM CODE_SYM sp_name
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
 | |
|             Lex->spname= $3;
 | |
|           }
 | |
|         | FUNCTION_SYM CODE_SYM sp_name
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
 | |
|             Lex->spname= $3;
 | |
|           }
 | |
|         | PACKAGE_MARIADB_SYM BODY_MARIADB_SYM CODE_SYM sp_name
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
 | |
|             Lex->spname= $4;
 | |
|           }
 | |
|         | PACKAGE_ORACLE_SYM BODY_ORACLE_SYM CODE_SYM sp_name
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
 | |
|             Lex->spname= $4;
 | |
|           }
 | |
|         | CREATE EVENT_SYM sp_name
 | |
|           {
 | |
|             Lex->spname= $3;
 | |
|             Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
 | |
|           }
 | |
|         | describe_command opt_format_json FOR_SYM expr
 | |
|           /*
 | |
|             The alternaltive syntax for this command is MySQL-compatible
 | |
|             EXPLAIN FOR CONNECTION
 | |
|           */
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_EXPLAIN;
 | |
|             if (unlikely(prepare_schema_table(thd, Lex, 0,
 | |
|                 Lex->explain_json ? SCH_EXPLAIN_JSON : SCH_EXPLAIN_TABULAR)))
 | |
|               MYSQL_YYABORT;
 | |
|             add_value_to_list(thd, $4);
 | |
|           }
 | |
|         | ANALYZE_SYM opt_format_json FOR_SYM expr
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_SHOW_ANALYZE;
 | |
|             if (unlikely(prepare_schema_table(thd, Lex, 0,
 | |
|                 Lex->explain_json ? SCH_ANALYZE_JSON : SCH_ANALYZE_TABULAR)))
 | |
|               MYSQL_YYABORT;
 | |
|             add_value_to_list(thd, $4);
 | |
|           }
 | |
|         | IDENT_sys remember_tok_start wild_and_where
 | |
|            {
 | |
|              LEX *lex= Lex;
 | |
|              bool in_plugin;
 | |
|              lex->sql_command= SQLCOM_SHOW_GENERIC;
 | |
|              ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1, &in_plugin);
 | |
|              if (unlikely(!table || !table->old_format || !in_plugin))
 | |
|              {
 | |
|                thd->parse_error(ER_SYNTAX_ERROR, $2);
 | |
|                MYSQL_YYABORT;
 | |
|              }
 | |
|              if (unlikely(lex->wild && table->idx_field1 < 0))
 | |
|              {
 | |
|                thd->parse_error(ER_SYNTAX_ERROR, $3);
 | |
|                MYSQL_YYABORT;
 | |
|              }
 | |
|              if (unlikely(make_schema_select(thd, Lex->current_select, table)))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|         ;
 | |
| 
 | |
| show_engine_param:
 | |
|           STATUS_SYM
 | |
|           { Lex->sql_command= SQLCOM_SHOW_ENGINE_STATUS; }
 | |
|         | MUTEX_SYM
 | |
|           { Lex->sql_command= SQLCOM_SHOW_ENGINE_MUTEX; }
 | |
|         | LOGS_SYM
 | |
|           { Lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS; }
 | |
|         ;
 | |
| 
 | |
| master_or_binary:
 | |
|           MASTER_SYM
 | |
|         | BINARY
 | |
|         ;
 | |
| 
 | |
| opt_storage:
 | |
|           /* empty */
 | |
|         | STORAGE_SYM
 | |
|         ;
 | |
| 
 | |
| opt_db:
 | |
|           /* empty */      { $$= null_clex_str; }
 | |
|         | from_or_in ident { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| opt_full:
 | |
|           /* empty */ { Lex->verbose=0; }
 | |
|         | FULL        { Lex->verbose=1; }
 | |
|         ;
 | |
| 
 | |
| from_or_in:
 | |
|           FROM
 | |
|         | IN_SYM
 | |
|         ;
 | |
| 
 | |
| binlog_in:
 | |
|           /* empty */            { Lex->mi.log_file_name = 0; }
 | |
|         | IN_SYM TEXT_STRING_sys { Lex->mi.log_file_name = $2.str; }
 | |
|         ;
 | |
| 
 | |
| binlog_from:
 | |
|           /* empty */        { Lex->mi.pos = 4; /* skip magic number */ }
 | |
|         | FROM ulonglong_num { Lex->mi.pos = $2; }
 | |
|         ;
 | |
| 
 | |
| wild_and_where:
 | |
|           /* empty */ { $$= 0; }
 | |
|         | LIKE remember_tok_start TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->wild= new (thd) String((const char*) $3.str,
 | |
|                                                    $3.length,
 | |
|                                                    system_charset_info);
 | |
|             if (unlikely(Lex->wild == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $2;
 | |
|           }
 | |
|         | WHERE remember_tok_start search_condition
 | |
|           {
 | |
|             Select->where= normalize_cond(thd, $3);
 | |
|             if ($3)
 | |
|               $3->top_level_item();
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* A Oracle compatible synonym for show */
 | |
| describe:
 | |
|           describe_command table_ident
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|             lex->current_select->parsing_place= SELECT_LIST;
 | |
|             lex->sql_command= SQLCOM_SHOW_FIELDS;
 | |
|             lex->first_select_lex()->db= null_clex_str;
 | |
|             lex->verbose= 0;
 | |
|             if (unlikely(prepare_schema_table(thd, lex, $2, SCH_COLUMNS)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_describe_column
 | |
|           {
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | describe_command opt_extended_describe
 | |
|           { Lex->describe|= DESCRIBE_NORMAL; }
 | |
|           explainable_command
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->first_select_lex()->options|= SELECT_DESCRIBE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| explainable_command:
 | |
|           select
 | |
|         | select_into
 | |
|         | insert
 | |
|         | replace
 | |
|         | update
 | |
|         | delete
 | |
|         ;
 | |
| 
 | |
| describe_command:
 | |
|           DESC
 | |
|         | DESCRIBE
 | |
|         ;
 | |
| 
 | |
| analyze_stmt_command:
 | |
|           ANALYZE_SYM opt_format_json explainable_command
 | |
|           {
 | |
|             Lex->analyze_stmt= true;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_extended_describe:
 | |
|           EXTENDED_SYM   { Lex->describe|= DESCRIBE_EXTENDED; }
 | |
|         | EXTENDED_SYM ALL
 | |
|           { Lex->describe|= DESCRIBE_EXTENDED | DESCRIBE_EXTENDED2; }
 | |
|         | PARTITIONS_SYM { Lex->describe|= DESCRIBE_PARTITIONS; }
 | |
|         | opt_format_json {}
 | |
|         ;
 | |
| 
 | |
| opt_format_json:
 | |
|           /* empty */ {}
 | |
|         | FORMAT_SYM '=' ident_or_text
 | |
|           {
 | |
|             if (lex_string_eq(&$3, STRING_WITH_LEN("JSON")))
 | |
|               Lex->explain_json= true;
 | |
|             else if (lex_string_eq(&$3, STRING_WITH_LEN("TRADITIONAL")))
 | |
|               DBUG_ASSERT(Lex->explain_json==false);
 | |
|             else
 | |
|               my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0),
 | |
|                                 "EXPLAIN/ANALYZE", $3.str));
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_describe_column:
 | |
|           /* empty */ {}
 | |
|         | text_string { Lex->wild= $1; }
 | |
|         | ident
 | |
|           {
 | |
|             Lex->wild= new (thd) String((const char*) $1.str,
 | |
|                                                     $1.length,
 | |
|                                                     system_charset_info);
 | |
|             if (unlikely(Lex->wild == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| explain_for_connection:
 | |
|           /*
 | |
|             EXPLAIN FOR CONNECTION is an alternative syntax for
 | |
|             SHOW EXPLAIN FOR command. It was introduced for compatibility
 | |
|             with MySQL which implements EXPLAIN FOR CONNECTION command
 | |
|           */
 | |
|           describe_command opt_format_json FOR_SYM CONNECTION_SYM expr
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->wild=0;
 | |
|             lex->ident= null_clex_str;
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|             lex->current_select->parsing_place= SELECT_LIST;
 | |
|             lex->create_info.init();
 | |
|             Select->parsing_place= NO_MATTER;
 | |
|             Lex->pop_select(); //main select
 | |
|             Lex->sql_command= SQLCOM_SHOW_EXPLAIN;
 | |
|             if (unlikely(prepare_schema_table(thd, Lex, 0,
 | |
|                 Lex->explain_json ? SCH_EXPLAIN_JSON : SCH_EXPLAIN_TABULAR)))
 | |
|               MYSQL_YYABORT;
 | |
|             add_value_to_list(thd, $5);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* flush things */
 | |
| 
 | |
| flush:
 | |
|           FLUSH_SYM opt_no_write_to_binlog
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_FLUSH;
 | |
|             lex->type= 0;
 | |
|             lex->no_write_to_binlog= $2;
 | |
|           }
 | |
|           flush_options {}
 | |
|         ;
 | |
| 
 | |
| flush_options:
 | |
|           table_or_tables
 | |
|           {
 | |
|             Lex->type|= REFRESH_TABLES;
 | |
|             /*
 | |
|               Set type of metadata and table locks for
 | |
|               FLUSH TABLES table_list [WITH READ LOCK].
 | |
|             */
 | |
|             YYPS->m_lock_type= TL_READ_NO_INSERT;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_HIGH_PRIO;
 | |
|           }
 | |
|           opt_table_list opt_flush_lock
 | |
|           {}
 | |
|         | flush_options_list
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| opt_flush_lock:
 | |
|           /* empty */ {}
 | |
|         | flush_lock
 | |
|         {
 | |
|           TABLE_LIST *tables= Lex->query_tables;
 | |
|           for (; tables; tables= tables->next_global)
 | |
|           {
 | |
|             tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
 | |
|             /* Ignore temporary tables. */
 | |
|             tables->open_type= OT_BASE_ONLY;
 | |
|           }
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| flush_lock:
 | |
|           WITH READ_SYM LOCK_SYM optional_flush_tables_arguments
 | |
|           { Lex->type|= REFRESH_READ_LOCK | $4; }
 | |
|         | FOR_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->query_tables == NULL))
 | |
|             {
 | |
|               // Table list can't be empty
 | |
|               thd->parse_error(ER_NO_TABLES_USED);
 | |
|               MYSQL_YYABORT;
 | |
|             } 
 | |
|             Lex->type|= REFRESH_FOR_EXPORT;
 | |
|           } EXPORT_SYM {}
 | |
|         ;
 | |
| 
 | |
| flush_options_list:
 | |
|           flush_options_list ',' flush_option
 | |
|         | flush_option
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| flush_option:
 | |
|           ERROR_SYM LOGS_SYM
 | |
|           { Lex->type|= REFRESH_ERROR_LOG; }
 | |
|         | ENGINE_SYM LOGS_SYM
 | |
|           { Lex->type|= REFRESH_ENGINE_LOG; } 
 | |
|         | GENERAL LOGS_SYM
 | |
|           { Lex->type|= REFRESH_GENERAL_LOG; }
 | |
|         | SLOW LOGS_SYM
 | |
|           { Lex->type|= REFRESH_SLOW_LOG; }
 | |
|         | BINARY LOGS_SYM opt_delete_gtid_domain
 | |
|           { Lex->type|= REFRESH_BINARY_LOG; }
 | |
|         | RELAY LOGS_SYM optional_connection_name optional_for_channel
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->type & REFRESH_RELAY_LOG))
 | |
|               my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH", "RELAY LOGS"));
 | |
|             lex->type|= REFRESH_RELAY_LOG;
 | |
|             lex->relay_log_connection_name= lex->mi.connection_name;
 | |
|            }
 | |
|         | QUERY_SYM CACHE_SYM
 | |
|           { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
 | |
|         | HOSTS_SYM
 | |
|           { Lex->type|= REFRESH_HOSTS; }
 | |
|         | PRIVILEGES
 | |
|           { Lex->type|= REFRESH_GRANT; }
 | |
|         | LOGS_SYM
 | |
|           {
 | |
|             Lex->type|= REFRESH_LOG;
 | |
|             Lex->relay_log_connection_name= empty_clex_str;
 | |
|           }
 | |
|         | STATUS_SYM
 | |
|           {
 | |
|             if (thd->variables.old_behavior & OLD_MODE_OLD_FLUSH_STATUS)
 | |
|               Lex->type|= REFRESH_STATUS;
 | |
|             else
 | |
|               Lex->type|= REFRESH_SESSION_STATUS;
 | |
|           }
 | |
|         | SESSION_SYM STATUS_SYM
 | |
|           { Lex->type|= REFRESH_SESSION_STATUS; }
 | |
|         | GLOBAL_SYM STATUS_SYM
 | |
|           { Lex->type|= REFRESH_GLOBAL_STATUS; }
 | |
|         | SLAVE optional_connection_name 
 | |
|           { 
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->type & REFRESH_SLAVE))
 | |
|               my_yyabort_error((ER_WRONG_USAGE, MYF(0), "FLUSH","SLAVE"));
 | |
|             lex->type|= REFRESH_SLAVE;
 | |
|             lex->reset_slave_info.all= false;
 | |
|           }
 | |
|         | MASTER_SYM
 | |
|           { Lex->type|= REFRESH_MASTER; }
 | |
|         | DES_KEY_FILE
 | |
|           { Lex->type|= REFRESH_DES_KEY_FILE; }
 | |
|         | RESOURCES
 | |
|           { Lex->type|= REFRESH_USER_RESOURCES; }
 | |
|         | SSL_SYM
 | |
|           { Lex->type|= REFRESH_SSL;}
 | |
|         | THREADS_SYM
 | |
|           { Lex->type|= REFRESH_THREADS;}        
 | |
|         | IDENT_sys remember_tok_start
 | |
|            {
 | |
|              Lex->type|= REFRESH_GENERIC;
 | |
|              ST_SCHEMA_TABLE *table= find_schema_table(thd, &$1);
 | |
|              if (unlikely(!table || !table->reset_table))
 | |
|              {
 | |
|                thd->parse_error(ER_SYNTAX_ERROR, $2);
 | |
|                MYSQL_YYABORT;
 | |
|              }
 | |
|              if (unlikely(Lex->view_list.push_back((LEX_CSTRING*)
 | |
|                                                    thd->memdup(&$1, sizeof(LEX_CSTRING)),
 | |
|                                                    thd->mem_root)))
 | |
|                MYSQL_YYABORT;
 | |
|            }
 | |
|         ;
 | |
| 
 | |
| opt_table_list:
 | |
|           /* empty */  {}
 | |
|         | table_list {}
 | |
|         ;
 | |
| 
 | |
| backup:
 | |
|         BACKUP_SYM backup_statements {}
 | |
| 	;
 | |
| 
 | |
| backup_statements:
 | |
| 	STAGE_SYM ident
 | |
|         {
 | |
|           int type;
 | |
|           if (unlikely(Lex->sphead))
 | |
|             my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "BACKUP STAGE"));
 | |
|           if ((type= find_type($2.str, &backup_stage_names,
 | |
|                                FIND_TYPE_NO_PREFIX)) <= 0)
 | |
|             my_yyabort_error((ER_BACKUP_UNKNOWN_STAGE, MYF(0), $2.str));
 | |
|           Lex->sql_command= SQLCOM_BACKUP;
 | |
|           Lex->backup_stage= (backup_stages) (type-1);
 | |
|           break;
 | |
|         }
 | |
| 	| LOCK_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "BACKUP LOCK"));
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           table_ident
 | |
|           {
 | |
| 	    if (unlikely(!Select->add_table_to_list(thd, $3, NULL, 0,
 | |
|                                                     TL_READ, MDL_SHARED_HIGH_PRIO)))
 | |
|              MYSQL_YYABORT;
 | |
|             Lex->sql_command= SQLCOM_BACKUP_LOCK;
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         | UNLOCK_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "BACKUP UNLOCK"));
 | |
| 	    /* Table list is empty for unlock */
 | |
|             Lex->sql_command= SQLCOM_BACKUP_LOCK;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_delete_gtid_domain:
 | |
|           /* empty */ {}
 | |
|         | DELETE_DOMAIN_ID_SYM '=' '(' delete_domain_id_list ')'
 | |
|           {}
 | |
|         ;
 | |
| delete_domain_id_list:
 | |
|           /* Empty */
 | |
|         | delete_domain_id
 | |
|         | delete_domain_id_list ',' delete_domain_id
 | |
|         ;
 | |
| 
 | |
| delete_domain_id:
 | |
|           ulonglong_num
 | |
|           {
 | |
|             uint32 value= (uint32) $1;
 | |
|             if ($1 > UINT_MAX32)
 | |
|             {
 | |
|               my_printf_error(ER_BINLOG_CANT_DELETE_GTID_DOMAIN,
 | |
|                               "The value of gtid domain being deleted ('%llu') "
 | |
|                               "exceeds its maximum size "
 | |
|                               "of 32 bit unsigned integer", MYF(0), $1);
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             insert_dynamic(&Lex->delete_gtid_domain, (uchar*) &value);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| optional_flush_tables_arguments:
 | |
|           /* empty */        {$$= 0;}
 | |
|         | AND_SYM DISABLE_SYM CHECKPOINT_SYM {$$= REFRESH_CHECKPOINT; } 
 | |
|         ;
 | |
| 
 | |
| reset:
 | |
|           RESET_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_RESET; lex->type=0;
 | |
|           }
 | |
|           reset_options
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| reset_options:
 | |
|           reset_options ',' reset_option
 | |
|         | reset_option
 | |
|         ;
 | |
| 
 | |
| reset_option:
 | |
|           SLAVE               { Lex->type|= REFRESH_SLAVE; }
 | |
|           optional_connection_name
 | |
|           slave_reset_options optional_for_channel
 | |
|           { }
 | |
|         | MASTER_SYM
 | |
|           {
 | |
|              Lex->type|= REFRESH_MASTER;
 | |
|              Lex->next_binlog_file_number= 0;
 | |
|           }
 | |
|           master_reset_options
 | |
|         | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}
 | |
|         ;
 | |
| 
 | |
| slave_reset_options:
 | |
|           /* empty */ { Lex->reset_slave_info.all= false; }
 | |
|         | ALL         { Lex->reset_slave_info.all= true; }
 | |
|         ;
 | |
| 
 | |
| master_reset_options:
 | |
|           /* empty */ {}
 | |
|         | TO_SYM ulong_num
 | |
|           {
 | |
|             Lex->next_binlog_file_number = $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| purge:
 | |
|           PURGE master_or_binary LOGS_SYM TO_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->stmt_purge_to($5);
 | |
|           }
 | |
|         | PURGE master_or_binary LOGS_SYM BEFORE_SYM
 | |
|           { Lex->clause_that_disallows_subselect= "PURGE..BEFORE"; }
 | |
|           expr
 | |
|           {
 | |
|             Lex->clause_that_disallows_subselect= NULL;
 | |
|             if (Lex->stmt_purge_before($6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| /* kill threads */
 | |
| 
 | |
| kill:
 | |
|           KILL_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->value_list.empty();
 | |
|             lex->users_list.empty();
 | |
|             lex->sql_command= SQLCOM_KILL;
 | |
|             lex->kill_type= KILL_TYPE_ID;
 | |
|             thd->where= THD_WHERE::USE_WHERE_STRING;
 | |
|             thd->where_str= "KILL";
 | |
|           }
 | |
|           kill_type kill_option
 | |
|           {
 | |
|             Lex->kill_signal= (killed_state) ($3 | $4);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| kill_type:
 | |
|         /* Empty */    { $$= (int) KILL_HARD_BIT; }
 | |
|         | HARD_SYM     { $$= (int) KILL_HARD_BIT; }
 | |
|         | SOFT_SYM     { $$= 0; }
 | |
|         ;
 | |
| 
 | |
| kill_option:
 | |
|           opt_connection kill_expr { $$= (int) KILL_CONNECTION; }
 | |
|         | QUERY_SYM      kill_expr { $$= (int) KILL_QUERY; }
 | |
|         | QUERY_SYM ID_SYM expr
 | |
|           {
 | |
|             $$= (int) KILL_QUERY;
 | |
|             Lex->kill_type= KILL_TYPE_QUERY;
 | |
|             Lex->value_list.push_front($3, thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_connection:
 | |
|           /* empty */    { }
 | |
|         | CONNECTION_SYM { }
 | |
|         ;
 | |
| 
 | |
| kill_expr:
 | |
|         expr
 | |
|         {
 | |
|           Lex->value_list.push_front($$, thd->mem_root);
 | |
|          }
 | |
|         | USER_SYM user
 | |
|           {
 | |
|             Lex->users_list.push_back($2, thd->mem_root);
 | |
|             Lex->kill_type= KILL_TYPE_USER;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| shutdown:
 | |
|         SHUTDOWN { Lex->sql_command= SQLCOM_SHUTDOWN; }
 | |
|         shutdown_option {}
 | |
|         ;
 | |
| 
 | |
| shutdown_option:
 | |
|         /*  Empty */    { Lex->is_shutdown_wait_for_slaves= false; }
 | |
|         | WAIT_SYM FOR_SYM ALL SLAVES
 | |
|         {
 | |
|           Lex->is_shutdown_wait_for_slaves= true;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| /* change database */
 | |
| 
 | |
| use:
 | |
|           USE_SYM ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command=SQLCOM_CHANGE_DB;
 | |
|             lex->first_select_lex()->db= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* import, export of files */
 | |
| 
 | |
| load:
 | |
|           LOAD data_or_xml
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
| 
 | |
|             if (unlikely(lex->sphead))
 | |
|             {
 | |
|               my_error(ER_SP_BADSTATEMENT, MYF(0), 
 | |
|                        $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             if (lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|             lex->init_select();
 | |
|           }
 | |
|           load_data_lock opt_local INFILE TEXT_STRING_filesystem
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_LOAD;
 | |
|             lex->local_file=  $5;
 | |
|             lex->duplicates= DUP_ERROR;
 | |
|             lex->ignore= 0;
 | |
|             if (unlikely(!(lex->exchange= new (thd)
 | |
|                          sql_exchange($7.str, 0, $2))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_duplicate INTO TABLE_SYM table_ident opt_use_partition
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (unlikely(!Select->add_table_to_list(thd, $12, NULL,
 | |
|                                                    TL_OPTION_UPDATING,
 | |
|                                                    $4, MDL_SHARED_WRITE,
 | |
|                                                    NULL, $13)))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->field_list.empty();
 | |
|             lex->update_list.empty();
 | |
|             lex->value_list.empty();
 | |
|             lex->many_values.empty();
 | |
|           }
 | |
|           opt_load_data_charset
 | |
|           { Lex->exchange->cs= $15; }
 | |
|           opt_xml_rows_identified_by
 | |
|           opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
 | |
|           opt_load_data_set_spec
 | |
|           stmt_end
 | |
|           {
 | |
|             Lex->mark_first_table_as_inserting();
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| data_or_xml:
 | |
|         DATA_SYM  { $$= FILETYPE_CSV; }
 | |
|         | XML_SYM { $$= FILETYPE_XML; }
 | |
|         ;
 | |
| 
 | |
| opt_local:
 | |
|           /* empty */ { $$=0;}
 | |
|         | LOCAL_SYM { $$=1;}
 | |
|         ;
 | |
| 
 | |
| load_data_lock:
 | |
|           /* empty */ { $$= TL_WRITE_DEFAULT; }
 | |
|         | CONCURRENT
 | |
|           {
 | |
|             /*
 | |
|               Ignore this option in SP to avoid problem with query cache and
 | |
|               triggers with non default priority locks
 | |
|             */
 | |
|             $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
 | |
|           }
 | |
|         | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
 | |
|         ;
 | |
| 
 | |
| opt_duplicate:
 | |
|           /* empty */ { Lex->duplicates=DUP_ERROR; }
 | |
|         | REPLACE { Lex->duplicates=DUP_REPLACE; }
 | |
|         | IGNORE_SYM { Lex->ignore= 1; }
 | |
|         ;
 | |
| 
 | |
| opt_field_term:
 | |
|           /* empty */
 | |
|         | COLUMNS field_term_list
 | |
|         ;
 | |
| 
 | |
| field_term_list:
 | |
|           field_term_list field_term
 | |
|         | field_term
 | |
|         ;
 | |
| 
 | |
| field_term:
 | |
|           TERMINATED BY text_string 
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->field_term= $3;
 | |
|           }
 | |
|         | OPTIONALLY ENCLOSED BY text_string
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             DBUG_ASSERT(lex->exchange != 0);
 | |
|             lex->exchange->enclosed= $4;
 | |
|             lex->exchange->opt_enclosed= 1;
 | |
|           }
 | |
|         | ENCLOSED BY text_string
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->enclosed= $3;
 | |
|           }
 | |
|         | ESCAPED BY text_string
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->escaped= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_line_term:
 | |
|           /* empty */
 | |
|         | LINES line_term_list
 | |
|         ;
 | |
| 
 | |
| line_term_list:
 | |
|           line_term_list line_term
 | |
|         | line_term
 | |
|         ;
 | |
| 
 | |
| line_term:
 | |
|           TERMINATED BY text_string
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->line_term= $3;
 | |
|           }
 | |
|         | STARTING BY text_string
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->line_start= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_xml_rows_identified_by:
 | |
|         /* empty */ { }
 | |
|         | ROWS_SYM IDENTIFIED_SYM BY text_string
 | |
|           { Lex->exchange->line_term = $4; }
 | |
|         ;
 | |
| 
 | |
| opt_ignore_lines:
 | |
|           /* empty */
 | |
|         | IGNORE_SYM NUM lines_or_rows
 | |
|           {
 | |
|             DBUG_ASSERT(Lex->exchange != 0);
 | |
|             Lex->exchange->skip_lines= atol($2.str);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| lines_or_rows:
 | |
|           LINES { }
 | |
|         | ROWS_SYM { }
 | |
|         ;
 | |
| 
 | |
| opt_field_or_var_spec:
 | |
|           /* empty */ {}
 | |
|         | '(' fields_or_vars ')' {}
 | |
|         | '(' ')' {}
 | |
|         ;
 | |
| 
 | |
| fields_or_vars:
 | |
|           fields_or_vars ',' field_or_var
 | |
|           { Lex->field_list.push_back($3, thd->mem_root); }
 | |
|         | field_or_var
 | |
|           { Lex->field_list.push_back($1, thd->mem_root); }
 | |
|         ;
 | |
| 
 | |
| field_or_var:
 | |
|           simple_ident_nospvar {$$= $1;}
 | |
|         | '@' ident_or_text
 | |
|           {
 | |
|             if (!$2.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             $$= new (thd) Item_user_var_as_out_param(thd, &$2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_load_data_set_spec:
 | |
|           /* empty */ {}
 | |
|         | SET load_data_set_list {}
 | |
|         ;
 | |
| 
 | |
| load_data_set_list:
 | |
|           load_data_set_list ',' load_data_set_elem
 | |
|         | load_data_set_elem
 | |
|         ;
 | |
| 
 | |
| load_data_set_elem:
 | |
|           simple_ident_nospvar equal remember_name expr_or_ignore_or_default remember_end
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->update_list.push_back($1, thd->mem_root)) ||
 | |
|                 unlikely(lex->value_list.push_back($4, thd->mem_root)))
 | |
|                 MYSQL_YYABORT;
 | |
|             $4->set_name_no_truncate(thd, $3, (uint) ($5 - $3), thd->charset());
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Common definitions */
 | |
| 
 | |
| text_literal:
 | |
|           TEXT_STRING
 | |
|           {
 | |
|             if (unlikely(!($$= thd->make_string_literal($1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NCHAR_STRING
 | |
|           {
 | |
|             if (unlikely(!($$= thd->make_string_literal_nchar($1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | UNDERSCORE_CHARSET TEXT_STRING
 | |
|           {
 | |
|             $1= thd->variables.character_set_collations.
 | |
|                                  get_collation_for_charset(thd, $1);
 | |
|             if (unlikely(!($$= thd->make_string_literal_charset($2, $1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | text_literal TEXT_STRING_literal
 | |
|           {
 | |
|             if (unlikely(!($$= $1->make_string_literal_concat(thd, &$2))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| text_string:
 | |
|           TEXT_STRING_literal
 | |
|           {
 | |
|             $$= new (thd) String((const char*) $1.str,
 | |
|                                            $1.length,
 | |
|                                            thd->variables.collation_connection);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           | hex_or_bin_String { $$= $1; }
 | |
|           ;
 | |
| 
 | |
| 
 | |
| hex_or_bin_String:
 | |
|           HEX_NUM
 | |
|           {
 | |
|             Item *tmp= new (thd) Item_hex_hybrid(thd, $1.str,
 | |
|                                                            $1.length);
 | |
|             if (unlikely(tmp == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= tmp->val_str((String*) 0);
 | |
|           }
 | |
|         | HEX_STRING
 | |
|           {
 | |
|             Item *tmp= new (thd) Item_hex_string(thd, $1.str,
 | |
|                                                            $1.length);
 | |
|             if (unlikely(tmp == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= tmp->val_str((String*) 0);
 | |
|           }
 | |
|         | BIN_NUM
 | |
|           {
 | |
|             Item *tmp= new (thd) Item_bin_string(thd, $1.str,
 | |
|                                                            $1.length);
 | |
|             if (unlikely(tmp == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             /*
 | |
|               it is OK only emulate fix_fields, because we need only
 | |
|               value of constant
 | |
|             */
 | |
|             $$= tmp->val_str((String*) 0);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| param_marker:
 | |
|           PARAM_MARKER
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->add_placeholder(thd, ¶m_clex_str,
 | |
|                                                     YYLIP->get_tok_start(),
 | |
|                                                     YYLIP->get_tok_start() + 1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLON_ORACLE_SYM ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str,
 | |
|                                                     $1.pos(), $2.end()))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLON_ORACLE_SYM NUM
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->add_placeholder(thd, &null_clex_str,
 | |
|                                                     $1.pos(),
 | |
|                                                     YYLIP->get_ptr()))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| signed_literal:
 | |
|         '+' NUM_literal { $$ = $2; }
 | |
|         | '-' NUM_literal
 | |
|           {
 | |
|             $2->max_length++;
 | |
|             $$= $2->neg(thd);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| literal:
 | |
|           text_literal { $$ = $1; }
 | |
|         | NUM_literal { $$ = $1; }
 | |
|         | temporal_literal { $$= $1; }
 | |
|         | NULL_SYM
 | |
|           {
 | |
|             /*
 | |
|               For the digest computation, in this context only,
 | |
|               NULL is considered a literal, hence reduced to '?'
 | |
|               REDUCE:
 | |
|                 TOK_GENERIC_VALUE := NULL_SYM
 | |
|             */
 | |
|             YYLIP->reduce_digest_token(TOK_GENERIC_VALUE, NULL_SYM);
 | |
|             $$= new (thd) Item_null(thd);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
 | |
|           }
 | |
|         | FALSE_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_bool(thd, (char*) "FALSE",0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TRUE_SYM
 | |
|           {
 | |
|             $$= new (thd) Item_bool(thd, (char*) "TRUE",1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | HEX_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_hex_hybrid(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | HEX_STRING
 | |
|           {
 | |
|             $$= new (thd) Item_hex_string(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | BIN_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_bin_string(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | UNDERSCORE_CHARSET hex_or_bin_String
 | |
|           {
 | |
|             Item_string_with_introducer *item_str;
 | |
|             LEX_CSTRING tmp;
 | |
|             $2->get_value(&tmp);
 | |
|             $1= thd->variables.character_set_collations.
 | |
|                                  get_collation_for_charset(thd, $1);
 | |
|             /*
 | |
|               Pass NULL as name. Name will be set in the "select_item" rule and
 | |
|               will include the introducer and the original hex/bin notation.
 | |
|             */
 | |
|             item_str= new (thd)
 | |
|                Item_string_with_introducer(thd, null_clex_str,
 | |
|                                            tmp, $1);
 | |
|             if (unlikely(!item_str ||
 | |
|                          !item_str->check_well_formed_result(true)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             $$= item_str;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| NUM_literal:
 | |
|           NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= new (thd)
 | |
|                   Item_int(thd, $1.str,
 | |
|                            (longlong) my_strtoll10($1.str, NULL, &error),
 | |
|                            $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | LONG_NUM
 | |
|           {
 | |
|             int error;
 | |
|             $$= new (thd)
 | |
|                   Item_int(thd, $1.str,
 | |
|                            (longlong) my_strtoll10($1.str, NULL, &error),
 | |
|                            $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ULONGLONG_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_uint(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DECIMAL_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_decimal(thd, $1.str, $1.length,
 | |
|                                                    thd->charset());
 | |
|             if (unlikely($$ == NULL) || unlikely(thd->is_error()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | FLOAT_NUM
 | |
|           {
 | |
|             $$= new (thd) Item_float(thd, $1.str, $1.length);
 | |
|             if (unlikely($$ == NULL) || unlikely(thd->is_error()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| temporal_literal:
 | |
|         DATE_SYM TEXT_STRING
 | |
|           {
 | |
|             if (unlikely(!($$= type_handler_newdate.create_literal_item(thd,
 | |
|                                                            $2.str, $2.length,
 | |
|                                                            YYCSCL, true))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TIME_SYM TEXT_STRING
 | |
|           {
 | |
|             if (unlikely(!($$= type_handler_time2.create_literal_item(thd,
 | |
|                                                          $2.str, $2.length,
 | |
|                                                          YYCSCL, true))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TIMESTAMP TEXT_STRING
 | |
|           {
 | |
|             if (unlikely(!($$= type_handler_datetime.create_literal_item(thd,
 | |
|                                                             $2.str, $2.length,
 | |
|                                                             YYCSCL, true))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| with_clause:
 | |
|           WITH opt_recursive
 | |
|           {
 | |
|              LEX *lex= Lex;
 | |
|              With_clause *with_clause=
 | |
|              new With_clause($2, Lex->curr_with_clause);
 | |
|              if (unlikely(with_clause == NULL))
 | |
|                MYSQL_YYABORT;
 | |
|              lex->derived_tables|= DERIVED_WITH;
 | |
|              lex->with_cte_resolution= true;
 | |
|              lex->curr_with_clause= with_clause;
 | |
|              with_clause->add_to_list(&lex->with_clauses_list,
 | |
|                                       lex->with_clauses_list_last_next);
 | |
|              if (lex->current_select &&
 | |
|                  lex->current_select->parsing_place == BEFORE_OPT_LIST)
 | |
|                lex->current_select->parsing_place= NO_MATTER;
 | |
|           }
 | |
|           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_column_list:
 | |
|         opt_column_name_list
 | |
|         ;
 | |
| 
 | |
| with_list_element:
 | |
|           with_element_head
 | |
| 	  with_column_list
 | |
|           AS '(' query_expression ')' opt_cycle
 | |
|  	  {
 | |
|             LEX *lex= thd->lex;
 | |
|             const char *query_start= lex->sphead ? lex->sphead->m_tmp_query
 | |
|                                                  : thd->query();
 | |
|             const char *spec_start= $4.pos() + 1;
 | |
|             With_element *elem= new With_element($1, *$2, $5);
 | |
| 	    if (elem == NULL || Lex->curr_with_clause->add_with_element(elem))
 | |
| 	      MYSQL_YYABORT;
 | |
|             if (elem->set_unparsed_spec(thd, spec_start, $6.pos(),
 | |
|                                         spec_start - query_start))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($7)
 | |
|             {
 | |
|               elem->set_cycle_list($7);
 | |
|             }
 | |
|             elem->set_tables_end_pos(lex->query_tables_last);
 | |
| 	  }
 | |
| 	;
 | |
| 
 | |
| opt_cycle:
 | |
|          /* empty */
 | |
|          { $$= NULL; }
 | |
|          |
 | |
|          CYCLE_SYM
 | |
|          {
 | |
|            if (!Lex->curr_with_clause->with_recursive)
 | |
|            {
 | |
|              thd->parse_error(ER_SYNTAX_ERROR, $1.pos());
 | |
|            }
 | |
|          }
 | |
|          comma_separated_ident_list RESTRICT
 | |
|          {
 | |
|            $$= $3;
 | |
|          }
 | |
|          ;
 | |
| 
 | |
| opt_column_name_list:
 | |
|           /* empty */
 | |
|           {
 | |
|             if (($$= new (thd) List<Lex_ident_sys>) == NULL)
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '(' comma_separated_ident_list ')'
 | |
|           { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| ident_sys_alloc:
 | |
|           ident_cli
 | |
|           {
 | |
|             $$= new (thd) Lex_ident_sys(thd, &$1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| comma_separated_ident_list:
 | |
|           ident_sys_alloc
 | |
|           {
 | |
|             $$= new (thd) List<Lex_ident_sys>;
 | |
|             if (unlikely($$ == NULL || $$->push_back($1)))
 | |
|               MYSQL_YYABORT;
 | |
| 	  }
 | |
|         | comma_separated_ident_list ',' ident_sys_alloc
 | |
|           {
 | |
|             if (($$= $1)->push_back($3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| with_element_head:
 | |
|           ident
 | |
|           {
 | |
|             $$= new (thd) With_element_head(
 | |
|                                       Lex_ident_with_element($1));
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->tables_pos.set_start_pos(Lex->query_tables_last);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| 	
 | |
| /**********************************************************************
 | |
| ** Creating different items.
 | |
| **********************************************************************/
 | |
| 
 | |
| insert_ident:
 | |
|           simple_ident_nospvar { $$=$1; }
 | |
|         | table_wild { $$=$1; }
 | |
|         ;
 | |
| 
 | |
| table_wild:
 | |
|           ident '.' '*'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident '.' '*'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| select_sublist_qualified_asterisk:
 | |
|           ident_cli '.' '*'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli '.' '*'
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_qualified_asterisk(thd, &$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| order_ident:
 | |
|           expr { $$=$1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| simple_ident:
 | |
|           ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '.' ident_cli '.' ident_cli
 | |
|           {
 | |
|             Lex_ident_cli empty($2.pos(), 0);
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &empty, &$2, &$4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident_cli '.' ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLON_ORACLE_SYM ident_cli '.' ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| simple_ident_nospvar:
 | |
|           ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident_nosp(thd, &$1))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident_nospvar(thd, &$1, &$3))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLON_ORACLE_SYM ident_cli '.' ident_cli
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->make_item_colon_ident_ident(thd, &$2, &$4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '.' ident '.' ident
 | |
|           {
 | |
|             Lex_ident_sys none;
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &none, &$2, &$4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident '.' ident
 | |
|           {
 | |
|             if (unlikely(!($$= Lex->create_item_ident(thd, &$1, &$3, &$5))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| field_ident:
 | |
|           ident { $$=$1;}
 | |
|         | ident '.' ident '.' ident
 | |
|           {
 | |
|             TABLE_LIST *table= Select->table_list.first;
 | |
|             if (unlikely(!table->db.streq($1)))
 | |
|               my_yyabort_error((ER_WRONG_DB_NAME, MYF(0), $1.str));
 | |
|             if (unlikely(!table->table_name.streq($3)))
 | |
|               my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $3.str));
 | |
|             $$=$5;
 | |
|           }
 | |
|         | ident '.' ident
 | |
|           {
 | |
|             TABLE_LIST *table= Select->table_list.first;
 | |
|             if (unlikely(!table->alias.streq($1)))
 | |
|               my_yyabort_error((ER_WRONG_TABLE_NAME, MYF(0), $1.str));
 | |
|             $$=$3;
 | |
|           }
 | |
|         | '.' ident { $$=$2;} /* For Delphi */
 | |
|         ;
 | |
| 
 | |
| table_ident:
 | |
|           ident
 | |
|           {
 | |
|             $$= new (thd) Table_ident(&$1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident
 | |
|           {
 | |
|             $$= new (thd) Table_ident(thd, &$1, &$3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '.' ident
 | |
|           {
 | |
|             /* For Delphi */
 | |
|             $$= new (thd) Table_ident(&$2);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_ident_opt_wild:
 | |
|           ident opt_wild
 | |
|           {
 | |
|             $$= new (thd) Table_ident(&$1);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' ident opt_wild
 | |
|           {
 | |
|             $$= new (thd) Table_ident(thd, &$1, &$3, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| table_ident_nodb:
 | |
|           ident
 | |
|           {
 | |
|             LEX_CSTRING db= any_db;
 | |
|             $$= new (thd) Table_ident(thd, &db, &$1, 0);
 | |
|             if (unlikely($$ == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| IDENT_cli:
 | |
|           IDENT
 | |
|         | IDENT_QUOTED
 | |
|         ;
 | |
| 
 | |
| ident_cli:
 | |
|           IDENT
 | |
|         | IDENT_QUOTED
 | |
|         | keyword_ident { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| IDENT_sys:
 | |
|           IDENT_cli
 | |
|           {
 | |
|             if (unlikely(thd->to_ident_sys_alloc(&$$, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_cli_func:
 | |
|           IDENT
 | |
|         | IDENT_QUOTED
 | |
|         | keyword_func_sp_var_and_label  { $$= $1; }
 | |
|         | keyword_func_sp_var_not_label  { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| ident_func:
 | |
|           ident_cli_func
 | |
|           {
 | |
|             if (unlikely(thd->to_ident_sys_alloc(&$$, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| TEXT_STRING_sys:
 | |
|           TEXT_STRING
 | |
|           {
 | |
|             if (thd->make_text_string_sys(&$$, &$1))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| TEXT_STRING_literal:
 | |
|           TEXT_STRING
 | |
|           {
 | |
|             if (thd->make_text_string_connection(&$$, &$1))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| TEXT_STRING_filesystem:
 | |
|           TEXT_STRING
 | |
|           {
 | |
|             if (thd->make_text_string_filesystem(&$$, &$1))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_table_alias:
 | |
|           IDENT_sys
 | |
|         | keyword_table_alias
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_cli_set_usual_case:
 | |
|           IDENT_cli { $$= $1; }
 | |
|         | keyword_set_usual_case { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| ident_sysvar_name:
 | |
|           IDENT_sys
 | |
|         | keyword_sysvar_name
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TEXT_STRING_sys
 | |
|           {
 | |
|             if (unlikely($$.copy_sys(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| ident:
 | |
|           IDENT_sys
 | |
|         | keyword_ident
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| label_ident:
 | |
|           IDENT_sys
 | |
|         | keyword_label
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_or_text:
 | |
|           ident           { $$=$1;}
 | |
|         | TEXT_STRING_sys { $$=$1;}
 | |
|         | LEX_HOSTNAME { $$=$1;}
 | |
|         ;
 | |
| 
 | |
| user_maybe_role:
 | |
|           ident_or_text
 | |
|           {
 | |
|             if (unlikely(!($$= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->user = $1;
 | |
| 
 | |
|             if (unlikely(check_string_char_length(&$$->user, ER_USERNAME,
 | |
|                                                   username_char_length,
 | |
|                                                   system_charset_info, 0)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_or_text '@' ident_or_text
 | |
|           {
 | |
|             if (unlikely(!($$= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->user = $1; $$->host=$3;
 | |
| 
 | |
|             if (unlikely(check_string_char_length(&$$->user, ER_USERNAME,
 | |
|                                                   username_char_length,
 | |
|                                                  system_charset_info, 0)) ||
 | |
|                 unlikely(check_host_name(&$$->host)))
 | |
|               MYSQL_YYABORT;
 | |
|             if ($$->host.str[0])
 | |
|             {
 | |
|               $$->host= thd->make_ident_casedn($$->host);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               /*
 | |
|                 fix historical undocumented convention that empty host is the
 | |
|                 same as '%'
 | |
|               */
 | |
|               $$->host= host_not_specified;
 | |
|             }
 | |
|           }
 | |
|         | CURRENT_USER optional_braces
 | |
|           {
 | |
|             if (unlikely(!($$= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->user= current_user;
 | |
|             $$->auth= new (thd) USER_AUTH();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| user_or_role: user_maybe_role | current_role;
 | |
| 
 | |
| user: user_maybe_role
 | |
|          {
 | |
|            if ($1->user.str != current_user.str && $1->host.str == 0)
 | |
|              $1->host= host_not_specified;
 | |
|            $$= $1;
 | |
|          }
 | |
|          ;
 | |
| 
 | |
| /* Keywords which we allow as table aliases. */
 | |
| keyword_table_alias:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sp_head
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_verb_clause
 | |
|         | FUNCTION_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
|         ;
 | |
| 
 | |
| /* Keyword that we allow for identifiers (except SP labels) */
 | |
| keyword_ident:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sp_head
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_verb_clause
 | |
|         | FUNCTION_SYM
 | |
|         | WINDOW_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
| %ifdef ORACLE
 | |
|         | TYPE_SYM
 | |
| %endif
 | |
|         ;
 | |
| 
 | |
| keyword_sysvar_name:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sp_head
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_verb_clause
 | |
|         | FUNCTION_SYM
 | |
|         | WINDOW_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
|         | OFFSET_SYM
 | |
|         ;
 | |
| 
 | |
| keyword_set_usual_case:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sp_head
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_verb_clause
 | |
|         | FUNCTION_SYM
 | |
|         | WINDOW_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
|         | OFFSET_SYM
 | |
|         ;
 | |
| 
 | |
| non_reserved_keyword_udt:
 | |
|           keyword_sp_var_not_label
 | |
|         | keyword_sp_head
 | |
|         | keyword_verb_clause
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_sp_var_and_label
 | |
|         | OFFSET_SYM
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Keywords that we allow in Oracle-style direct assignments:
 | |
|     xxx := 10;
 | |
|   but do not allow in labels in the default sql_mode:
 | |
|     label:
 | |
|       stmt1;
 | |
|       stmt2;
 | |
|   TODO: check if some of them can migrate to keyword_sp_var_and_label.
 | |
| */
 | |
| keyword_sp_var_not_label:
 | |
|         keyword_func_sp_var_not_label
 | |
|         | ASCII_SYM
 | |
|         | BACKUP_SYM
 | |
|         | BINLOG_SYM
 | |
|         | BYTE_SYM
 | |
|         | CACHE_SYM
 | |
|         | CHECKSUM_SYM
 | |
|         | CHECKPOINT_SYM
 | |
|         | COLUMN_ADD_SYM
 | |
|         | COLUMN_CREATE_SYM
 | |
|         | COLUMN_DELETE_SYM
 | |
|         | COLUMN_GET_SYM
 | |
|         | COMMENT_SYM
 | |
|         | COMPRESSED_SYM
 | |
|         | DEALLOCATE_SYM
 | |
|         | EXAMINED_SYM
 | |
|         | EXCLUDE_SYM
 | |
|         | EXECUTE_SYM
 | |
|         | FLUSH_SYM
 | |
|         | FOLLOWING_SYM
 | |
|         | GET_SYM
 | |
|         | HELP_SYM
 | |
|         | HOST_SYM
 | |
|         | INSTALL_SYM
 | |
|         | OPTION
 | |
|         | OPTIONS_SYM
 | |
|         | OTHERS_MARIADB_SYM
 | |
|         | OWNER_SYM
 | |
|         | PARSER_SYM
 | |
|         | PERIOD_SYM
 | |
|         | PORT_SYM
 | |
|         | PRECEDING_SYM
 | |
|         | PREPARE_SYM
 | |
|         | REMOVE_SYM
 | |
|         | RESET_SYM
 | |
|         | RESTORE_SYM
 | |
|         | SECURITY_SYM
 | |
|         | SERVER_SYM
 | |
|         | SOCKET_SYM
 | |
|         | SLAVE
 | |
|         | SLAVES
 | |
|         | SONAME_SYM
 | |
|         | START_SYM
 | |
|         | STOP_SYM
 | |
|         | STORED_SYM
 | |
|         | TIES_SYM
 | |
|         | UNICODE_SYM
 | |
|         | UNINSTALL_SYM
 | |
|         | UNBOUNDED_SYM
 | |
|         | WITHIN
 | |
|         | WRAPPER_SYM
 | |
|         | XA_SYM
 | |
|         | UPGRADE_SYM
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Keywords that can start optional clauses in SP or trigger declarations
 | |
|   Allowed as identifiers (e.g. table, column names),
 | |
|   but:
 | |
|   - not allowed as SP label names
 | |
|   - not allowed as variable names in Oracle-style assignments:
 | |
|     xxx := 10;
 | |
| 
 | |
|   If we allowed these variables in assignments, there would be conflicts
 | |
|   with SP characteristics, or verb clauses, or compound statements, e.g.:
 | |
|     CREATE PROCEDURE p1 LANGUAGE ...
 | |
|   would be either:
 | |
|     CREATE PROCEDURE p1 LANGUAGE SQL BEGIN END;
 | |
|   or
 | |
|     CREATE PROCEDURE p1 LANGUAGE:=10;
 | |
| 
 | |
|   Note, these variables can still be assigned using quoted identifiers:
 | |
|     `do`:= 10;
 | |
|     "do":= 10; (when ANSI_QUOTES)
 | |
|   or using a SET statement:
 | |
|     SET do= 10;
 | |
| 
 | |
|   Note, some of these keywords are reserved keywords in Oracle.
 | |
|   In case if heavy grammar conflicts are found in the future,
 | |
|   we'll possibly need to make them reserved for sql_mode=ORACLE.
 | |
| 
 | |
|   TODO: Allow these variables as SP lables when sql_mode=ORACLE.
 | |
|   TODO: Allow assigning of "SP characteristics" marked variables
 | |
|         inside compound blocks.
 | |
|   TODO: Allow "follows" and "precedes" as variables in compound blocks:
 | |
|         BEGIN
 | |
|           follows := 10;
 | |
|         END;
 | |
|         as they conflict only with non-block FOR EACH ROW statement:
 | |
|           CREATE TRIGGER .. FOR EACH ROW follows:= 10;
 | |
|           CREATE TRIGGER .. FOR EACH ROW FOLLOWS tr1 a:= 10;
 | |
| */
 | |
| keyword_sp_head:
 | |
|           CONTAINS_SYM           /* SP characteristic               */
 | |
|         | LANGUAGE_SYM           /* SP characteristic               */
 | |
|         | NO_SYM                 /* SP characteristic               */
 | |
|         | CHARSET                /* SET CHARSET utf8;               */
 | |
|         | FOLLOWS_SYM            /* Conflicts with assignment in FOR EACH */
 | |
|         | PRECEDES_SYM           /* Conflicts with assignment in FOR EACH */
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Keywords that start a statement.
 | |
|   Generally allowed as identifiers (e.g. table, column names)
 | |
|   - not allowed as SP label names
 | |
|   - not allowed as variable names in Oracle-style assignments:
 | |
|     xxx:=10
 | |
| */
 | |
| keyword_verb_clause:
 | |
|           CLOSE_SYM             /* Verb clause. Reserved in Oracle */
 | |
|         | COMMIT_SYM            /* Verb clause. Reserved in Oracle */
 | |
|         | DO_SYM                /* Verb clause                     */
 | |
|         | HANDLER_SYM           /* Verb clause                     */
 | |
|         | OPEN_SYM              /* Verb clause. Reserved in Oracle */
 | |
|         | REPAIR                /* Verb clause                     */
 | |
|         | ROLLBACK_SYM          /* Verb clause. Reserved in Oracle */
 | |
|         | SAVEPOINT_SYM         /* Verb clause. Reserved in Oracle */
 | |
|         | SHUTDOWN              /* Verb clause                     */
 | |
|         | TRUNCATE_SYM          /* Verb clause. Reserved in Oracle */
 | |
|         ;
 | |
| 
 | |
| keyword_set_special_case:
 | |
|           NAMES_SYM
 | |
|         | ROLE_SYM
 | |
|         | PASSWORD_SYM
 | |
|         ;
 | |
| 
 | |
| keyword_sysvar_type:
 | |
|           GLOBAL_SYM
 | |
|         | LOCAL_SYM
 | |
|         | SESSION_SYM
 | |
|         ;
 | |
| 
 | |
| 
 | |
| /*
 | |
|   These keywords are generally allowed as identifiers,
 | |
|   but not allowed as non-delimited SP variable names in sql_mode=ORACLE.
 | |
| */
 | |
| keyword_data_type:
 | |
|           BIT_SYM
 | |
|         | BOOLEAN_SYM
 | |
|         | BOOL_SYM
 | |
|         | CLOB_MARIADB_SYM
 | |
|         | CLOB_ORACLE_SYM
 | |
|         | DATE_SYM           %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | DATETIME
 | |
|         | ENUM
 | |
|         | FIXED_SYM
 | |
|         | JSON_SYM
 | |
|         | MEDIUM_SYM
 | |
|         | NATIONAL_SYM
 | |
|         | NCHAR_SYM
 | |
|         | NUMBER_MARIADB_SYM
 | |
|         | NUMBER_ORACLE_SYM
 | |
|         | NVARCHAR_SYM
 | |
|         | RAW_MARIADB_SYM
 | |
|         | RAW_ORACLE_SYM
 | |
|         | ROW_SYM
 | |
|         | SERIAL_SYM
 | |
|         | TEXT_SYM
 | |
|         | TIMESTAMP          %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | TIME_SYM           %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | VARCHAR2_MARIADB_SYM
 | |
|         | VARCHAR2_ORACLE_SYM
 | |
|         | YEAR_SYM
 | |
|         ;
 | |
| 
 | |
| 
 | |
| keyword_cast_type:
 | |
|           SIGNED_SYM
 | |
|         ;
 | |
| 
 | |
| 
 | |
| keyword_func_sp_var_and_label:
 | |
|         ACTION
 | |
|         | ACCOUNT_SYM
 | |
|         | ADMIN_SYM
 | |
|         | AFTER_SYM
 | |
|         | AGAINST
 | |
|         | AGGREGATE_SYM
 | |
|         | ALGORITHM_SYM
 | |
|         | ALWAYS_SYM
 | |
|         | AT_SYM
 | |
|         | ATOMIC_SYM
 | |
|         | AUTHORS_SYM
 | |
|         | AUTO_INC
 | |
|         | AUTOEXTEND_SIZE_SYM
 | |
|         | AUTO_SYM
 | |
|         | AVG_ROW_LENGTH
 | |
|         | BLOCK_SYM
 | |
|         | BODY_MARIADB_SYM
 | |
|         | BTREE_SYM
 | |
|         | CASCADED
 | |
|         | CATALOG_NAME_SYM
 | |
|         | CHAIN_SYM
 | |
|         | CHANNEL_SYM
 | |
|         | CHANGED
 | |
|         | CIPHER_SYM
 | |
|         | CLIENT_SYM
 | |
|         | CLASS_ORIGIN_SYM
 | |
|         | COALESCE
 | |
|         | COLLATION_SYM
 | |
|         | COLUMN_NAME_SYM
 | |
|         | COLUMNS
 | |
|         | COMMITTED_SYM
 | |
|         | COMPACT_SYM
 | |
|         | COMPLETION_SYM
 | |
|         | CONCURRENT
 | |
|         | CONNECTION_SYM
 | |
|         | CONSISTENT_SYM
 | |
|         | CONSTRAINT_CATALOG_SYM
 | |
|         | CONSTRAINT_SCHEMA_SYM
 | |
|         | CONSTRAINT_NAME_SYM
 | |
|         | CONTEXT_SYM
 | |
|         | CONTRIBUTORS_SYM
 | |
|         | CURRENT_POS_SYM
 | |
|         | CPU_SYM
 | |
|         | CUBE_SYM
 | |
|         /*
 | |
|           Although a reserved keyword in SQL:2003 (and :2008),
 | |
|           not reserved in MySQL per WL#2111 specification.
 | |
|         */
 | |
|         | CURRENT_SYM
 | |
|         | CURSOR_NAME_SYM
 | |
|         | CYCLE_SYM
 | |
|         | DATA_SYM
 | |
|         | DATABASE
 | |
|         | DATAFILE_SYM
 | |
|         | DEFINER_SYM
 | |
|         | DELAY_KEY_WRITE_SYM
 | |
|         | DES_KEY_FILE
 | |
|         | DIAGNOSTICS_SYM
 | |
|         | DISCARD
 | |
|         | DIRECTORY_SYM
 | |
|         | DISABLE_SYM
 | |
|         | DISK_SYM
 | |
|         | DUMPFILE
 | |
|         | DUPLICATE_SYM
 | |
|         | DYNAMIC_SYM
 | |
|         | ELSEIF_ORACLE_SYM
 | |
|         | ELSIF_MARIADB_SYM
 | |
|         | EMPTY_SYM
 | |
|         | EXPIRE_SYM
 | |
|         | EXPORT_SYM
 | |
|         | EXTENDED_SYM
 | |
|         | EXTENT_SIZE_SYM
 | |
|         | ENABLE_SYM
 | |
|         | ENDS_SYM
 | |
|         | ENGINE_SYM
 | |
|         | ENGINES_SYM
 | |
|         | ERROR_SYM
 | |
|         | ERRORS
 | |
|         | ESCAPE_SYM
 | |
|         | EVENT_SYM
 | |
|         | EVENTS_SYM
 | |
|         | EVERY_SYM
 | |
|         | EXCEPTION_MARIADB_SYM
 | |
|         | EXCHANGE_SYM
 | |
|         | EXPANSION_SYM
 | |
|         | FAULTS_SYM
 | |
|         | FAST_SYM
 | |
|         | FEDERATED_SYM
 | |
|         | FILE_SYM
 | |
|         | FIRST_SYM
 | |
|         | FOUND_SYM
 | |
|         | FULL
 | |
|         | GENERAL
 | |
|         | GENERATED_SYM
 | |
|         | GRANTS
 | |
|         | GOTO_MARIADB_SYM
 | |
|         | HASH_SYM
 | |
|         | HARD_SYM
 | |
|         | HISTORY_SYM
 | |
|         | HOSTS_SYM
 | |
|         | IDENTIFIED_SYM
 | |
|         | IGNORE_SERVER_IDS_SYM
 | |
|         | INCREMENT_SYM
 | |
|         | IMMEDIATE_SYM
 | |
|         | INVOKER_SYM
 | |
|         | IMPORT
 | |
|         | INDEXES
 | |
|         | INITIAL_SIZE_SYM
 | |
|         | IO_SYM
 | |
|         | IPC_SYM
 | |
|         | ISOLATION
 | |
|         | ISOPEN_SYM
 | |
|         | ISSUER_SYM
 | |
|         | INSERT_METHOD
 | |
|         | INVISIBLE_SYM
 | |
|         | JSON_TABLE_SYM
 | |
|         | KEY_BLOCK_SIZE
 | |
|         | LAST_SYM
 | |
|         | LEAVES
 | |
|         | LESS_SYM
 | |
|         | LEVEL_SYM
 | |
|         | LIST_SYM
 | |
|         | LOCKED_SYM
 | |
|         | LOCKS_SYM
 | |
|         | LOGFILE_SYM
 | |
|         | LOGS_SYM
 | |
|         | MAX_ROWS
 | |
|         | MASTER_SYM
 | |
|         | MASTER_HEARTBEAT_PERIOD_SYM
 | |
|         | MASTER_GTID_POS_SYM
 | |
|         | MASTER_HOST_SYM
 | |
|         | MASTER_PORT_SYM
 | |
|         | MASTER_LOG_FILE_SYM
 | |
|         | MASTER_LOG_POS_SYM
 | |
|         | MASTER_USER_SYM
 | |
|         | MASTER_USE_GTID_SYM
 | |
|         | MASTER_PASSWORD_SYM
 | |
|         | MASTER_SERVER_ID_SYM
 | |
|         | MASTER_CONNECT_RETRY_SYM
 | |
|         | MASTER_DELAY_SYM
 | |
|         | MASTER_RETRY_COUNT_SYM
 | |
|         | MASTER_SSL_SYM
 | |
|         | MASTER_SSL_CA_SYM
 | |
|         | MASTER_SSL_CAPATH_SYM
 | |
|         | MASTER_SSL_CERT_SYM
 | |
|         | MASTER_SSL_CIPHER_SYM
 | |
|         | MASTER_SSL_CRL_SYM
 | |
|         | MASTER_SSL_CRLPATH_SYM
 | |
|         | MASTER_SSL_KEY_SYM
 | |
|         | MAX_CONNECTIONS_PER_HOUR
 | |
|         | MAX_QUERIES_PER_HOUR
 | |
|         | MAX_SIZE_SYM
 | |
|         | MAX_STATEMENT_TIME_SYM
 | |
|         | MAX_UPDATES_PER_HOUR
 | |
|         | MAX_USER_CONNECTIONS_SYM
 | |
|         | MEMORY_SYM
 | |
|         | MERGE_SYM
 | |
|         | MESSAGE_TEXT_SYM
 | |
|         | MICROSECOND_SYM
 | |
|         | MIGRATE_SYM
 | |
| %ifdef MARIADB
 | |
|         | MINUS_ORACLE_SYM
 | |
| %endif
 | |
|         | MINVALUE_SYM
 | |
|         | MIN_ROWS
 | |
|         | MODIFY_SYM
 | |
|         | MODE_SYM
 | |
|         | MONITOR_SYM
 | |
|         | MUTEX_SYM
 | |
|         | MYSQL_SYM
 | |
|         | MYSQL_ERRNO_SYM
 | |
|         | NAME_SYM
 | |
|         | NESTED_SYM
 | |
|         | NEVER_SYM
 | |
|         | NEXT_SYM           %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | NOCACHE_SYM
 | |
|         | NOCYCLE_SYM
 | |
|         | NOMINVALUE_SYM
 | |
|         | NOMAXVALUE_SYM
 | |
|         | NO_WAIT_SYM
 | |
|         | NOCOPY_SYM
 | |
|         | NOWAIT_SYM
 | |
|         | NODEGROUP_SYM
 | |
|         | NONE_SYM
 | |
|         | NOTFOUND_SYM
 | |
|         | OF_SYM
 | |
|         | OLD_PASSWORD_SYM
 | |
|         | ONE_SYM
 | |
|         | ONLINE_SYM
 | |
|         | ONLY_SYM
 | |
|         | ORDINALITY_SYM
 | |
|         | PACKAGE_MARIADB_SYM %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | PACK_KEYS_SYM
 | |
|         | PAGE_SYM
 | |
|         | PARTIAL
 | |
|         | PARTITIONING_SYM
 | |
|         | PARTITIONS_SYM
 | |
|         | PATH_SYM
 | |
|         | PERSISTENT_SYM
 | |
|         | PHASE_SYM
 | |
|         | PLUGIN_SYM
 | |
|         | PLUGINS_SYM
 | |
|         | PRESERVE_SYM
 | |
|         | PREV_SYM
 | |
|         | PREVIOUS_SYM       %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | PRIVILEGES
 | |
|         | PROCESS
 | |
|         | PROCESSLIST_SYM
 | |
|         | PROFILE_SYM
 | |
|         | PROFILES_SYM
 | |
|         | PROXY_SYM
 | |
|         | QUARTER_SYM
 | |
|         | QUERY_SYM
 | |
|         | QUICK
 | |
|         | RAISE_MARIADB_SYM
 | |
|         | READ_ONLY_SYM
 | |
|         | REBUILD_SYM
 | |
|         | RECOVER_SYM
 | |
|         | REDO_BUFFER_SIZE_SYM
 | |
|         | REDOFILE_SYM
 | |
|         | REDUNDANT_SYM
 | |
|         | RELAY
 | |
|         | RELAY_LOG_FILE_SYM
 | |
|         | RELAY_LOG_POS_SYM
 | |
|         | RELAY_THREAD
 | |
|         | RELAYLOG_SYM
 | |
|         | RELOAD
 | |
|         | REORGANIZE_SYM
 | |
|         | REPEATABLE_SYM
 | |
|         | REPLAY_SYM
 | |
|         | REPLICATION
 | |
|         | RESOURCES
 | |
|         | RESTART_SYM
 | |
|         | RESUME_SYM
 | |
|         | RETURNED_SQLSTATE_SYM
 | |
|         | RETURNS_SYM
 | |
|         | REUSE_SYM
 | |
|         | REVERSE_SYM
 | |
|         | ROLLUP_SYM
 | |
|         | ROUTINE_SYM
 | |
|         | ROW_COUNT_SYM
 | |
|         | ROWCOUNT_SYM
 | |
|         | ROWTYPE_MARIADB_SYM
 | |
|         | ROW_FORMAT_SYM
 | |
|         | RTREE_SYM
 | |
|         | SCHEDULE_SYM
 | |
|         | SCHEMA_NAME_SYM
 | |
|         | SEQUENCE_SYM
 | |
|         | SERIALIZABLE_SYM
 | |
|         | SIMPLE_SYM
 | |
|         | SHARE_SYM
 | |
|         | SKIP_SYM
 | |
|         | SLAVE_POS_SYM
 | |
|         | SLOW
 | |
|         | SNAPSHOT_SYM
 | |
|         | SOFT_SYM
 | |
|         | SOURCE_SYM
 | |
|         | SQL_CACHE_SYM
 | |
|         | SQL_BUFFER_RESULT
 | |
|         | SQL_NO_CACHE_SYM
 | |
|         | SQL_THREAD
 | |
|         | STAGE_SYM
 | |
|         | STARTS_SYM
 | |
|         | STATEMENT_SYM
 | |
|         | STATUS_SYM
 | |
|         | STORAGE_SYM
 | |
|         | STRING_SYM
 | |
|         | SUBCLASS_ORIGIN_SYM
 | |
|         | SUBJECT_SYM
 | |
|         | SUBPARTITION_SYM
 | |
|         | SUBPARTITIONS_SYM
 | |
|         | SUPER_SYM
 | |
|         | SUSPEND_SYM
 | |
|         | SWAPS_SYM
 | |
|         | SWITCHES_SYM
 | |
|         | SYSTEM
 | |
|         | SYSTEM_TIME_SYM
 | |
|         | TABLE_NAME_SYM
 | |
|         | TABLES
 | |
|         | TABLE_CHECKSUM_SYM
 | |
|         | TABLESPACE
 | |
|         | TEMPORARY
 | |
|         | TEMPTABLE_SYM
 | |
|         | THAN_SYM
 | |
|         | TRANSACTION_SYM    %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | TRANSACTIONAL_SYM
 | |
|         | THREADS_SYM
 | |
|         | TRIGGERS_SYM
 | |
| %ifdef MARIADB
 | |
|         | TYPE_SYM           %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
| %endif
 | |
|         | UDF_RETURNS_SYM
 | |
|         | UNCOMMITTED_SYM
 | |
|         | UNDEFINED_SYM
 | |
|         | UNDO_BUFFER_SIZE_SYM
 | |
|         | UNDOFILE_SYM
 | |
|         | UNKNOWN_SYM
 | |
|         | UNTIL_SYM
 | |
|         | USE_FRM
 | |
|         | VARIABLES
 | |
|         | VERSIONING_SYM
 | |
|         | VIEW_SYM
 | |
|         | VIRTUAL_SYM
 | |
|         | VISIBLE_SYM
 | |
|         | VALIDATION_SYM
 | |
|         | WARNINGS
 | |
|         | WAIT_SYM
 | |
|         | WITHOUT
 | |
|         | WORK_SYM
 | |
|         | X509_SYM
 | |
|         | XML_SYM
 | |
|         | VIA_SYM
 | |
|         | WEEK_SYM
 | |
|         ;
 | |
| 
 | |
| keyword_func_sp_var_not_label:
 | |
|         FORMAT_SYM
 | |
|         | COLUMN_CHECK_SYM
 | |
|         ;
 | |
| /*
 | |
|   These keywords are fine for both SP variable names and SP labels.
 | |
| */
 | |
| keyword_sp_var_and_label:
 | |
|         keyword_func_sp_var_and_label
 | |
|         | ADDDATE_SYM
 | |
|         | ANY_SYM
 | |
|         | AVG_SYM
 | |
|         | CODE_SYM
 | |
|         | DAY_SYM
 | |
|         | GET_FORMAT
 | |
|         | HOUR_SYM
 | |
|         | ID_SYM
 | |
|         | LAST_VALUE
 | |
|         | LASTVAL_SYM
 | |
|         | MINUTE_SYM
 | |
|         | MONTH_SYM
 | |
|         | NEXTVAL_SYM
 | |
|         | OVERLAPS_SYM
 | |
|         | RECORD_SYM
 | |
| %ifdef MARIADB
 | |
|         | ROWNUM_SYM
 | |
| %endif
 | |
|         | SECOND_SYM
 | |
|         | SETVAL_SYM
 | |
|         | SOUNDS_SYM
 | |
|         | SUBDATE_SYM
 | |
| %ifdef MARIADB
 | |
|         | SYSDATE
 | |
| %endif
 | |
|         | TRIM_ORACLE
 | |
|         | TIMESTAMP_ADD
 | |
|         | TIMESTAMP_DIFF
 | |
|         | USER_SYM           %prec PREC_BELOW_CONTRACTION_TOKEN2
 | |
|         | VALUE_SYM
 | |
|         | WEIGHT_STRING_SYM
 | |
|         | SESSION_USER_SYM
 | |
|         ;
 | |
| 
 | |
| 
 | |
| reserved_keyword_udt_not_param_type:
 | |
|           ACCESSIBLE_SYM
 | |
|         | ADD
 | |
|         | ALL
 | |
|         | ALTER
 | |
|         | ANALYZE_SYM
 | |
|         | AND_SYM
 | |
|         | AS
 | |
|         | ASC
 | |
|         | ASENSITIVE_SYM
 | |
|         | BEFORE_SYM
 | |
|         | BETWEEN_SYM
 | |
|         | BIT_AND
 | |
|         | BIT_OR
 | |
|         | BIT_XOR
 | |
|         | BODY_ORACLE_SYM
 | |
|         | BOTH
 | |
|         | BY
 | |
|         | CALL_SYM
 | |
|         | CASCADE
 | |
|         | CASE_SYM
 | |
|         | CAST_SYM
 | |
|         | CHANGE
 | |
|         | CHECK_SYM
 | |
|         | COLLATE_SYM
 | |
|         | CONSTRAINT
 | |
|         | CONTINUE_MARIADB_SYM
 | |
|         | CONTINUE_ORACLE_SYM
 | |
|         | CONVERT_SYM
 | |
|         | COUNT_SYM
 | |
|         | CREATE
 | |
|         | CROSS
 | |
|         | CUME_DIST_SYM
 | |
|         | CURDATE
 | |
|         | CURRENT_USER
 | |
|         | CURRENT_ROLE
 | |
|         | CURTIME
 | |
|         | DATABASES
 | |
|         | DATE_ADD_INTERVAL
 | |
|         | DATE_SUB_INTERVAL
 | |
|         | DAY_HOUR_SYM
 | |
|         | DAY_MICROSECOND_SYM
 | |
|         | DAY_MINUTE_SYM
 | |
|         | DAY_SECOND_SYM
 | |
|         | DECLARE_MARIADB_SYM
 | |
|         | DECLARE_ORACLE_SYM
 | |
|         | DEFAULT
 | |
|         | DELETE_DOMAIN_ID_SYM
 | |
|         | DELETE_SYM
 | |
|         | DENSE_RANK_SYM
 | |
|         | DESC
 | |
|         | DESCRIBE
 | |
|         | DETERMINISTIC_SYM
 | |
|         | DISTINCT
 | |
|         | DIV_SYM
 | |
|         | DO_DOMAIN_IDS_SYM
 | |
|         | DROP
 | |
|         | DUAL_SYM
 | |
|         | EACH_SYM
 | |
|         | ELSE
 | |
|         | ELSEIF_MARIADB_SYM
 | |
|         | ELSIF_ORACLE_SYM
 | |
|         | ENCLOSED
 | |
|         | ESCAPED
 | |
|         | EXCEPT_SYM
 | |
|         | EXISTS
 | |
|         | EXTRACT_SYM
 | |
|         | FALSE_SYM
 | |
|         | FETCH_SYM
 | |
|         | FIRST_VALUE_SYM
 | |
|         | FOREIGN
 | |
|         | FROM
 | |
|         | FULLTEXT_SYM
 | |
|         | GOTO_ORACLE_SYM
 | |
|         | GRANT
 | |
|         | GROUP_SYM
 | |
|         | GROUP_CONCAT_SYM
 | |
|         | LAG_SYM
 | |
|         | LEAD_SYM
 | |
|         | HAVING
 | |
|         | HOUR_MICROSECOND_SYM
 | |
|         | HOUR_MINUTE_SYM
 | |
|         | HOUR_SECOND_SYM
 | |
|         | IF_SYM
 | |
|         | IGNORE_DOMAIN_IDS_SYM
 | |
|         | IGNORE_SYM
 | |
|         | IGNORED_SYM
 | |
|         | INDEX_SYM
 | |
|         | INFILE
 | |
|         | INNER_SYM
 | |
|         | INSENSITIVE_SYM
 | |
|         | INSERT
 | |
|         | INTERSECT_SYM
 | |
|         | INTERVAL_SYM
 | |
|         | INTO
 | |
|         | IS
 | |
|         | ITERATE_SYM
 | |
|         | JOIN_SYM
 | |
|         | KEYS
 | |
|         | KEY_SYM
 | |
|         | KILL_SYM
 | |
|         | LEADING
 | |
|         | LEAVE_SYM
 | |
|         | LEFT
 | |
|         | LIKE
 | |
|         | LIMIT
 | |
|         | LINEAR_SYM
 | |
|         | LINES
 | |
|         | LOAD
 | |
|         | LOCATOR_SYM
 | |
|         | LOCK_SYM
 | |
|         | LOOP_SYM
 | |
|         | LOW_PRIORITY
 | |
|         | MASTER_SSL_VERIFY_SERVER_CERT_SYM
 | |
|         | MATCH
 | |
|         | MAX_SYM
 | |
|         | MAXVALUE_SYM
 | |
|         | MEDIAN_SYM
 | |
|         | MINUTE_MICROSECOND_SYM
 | |
|         | MINUTE_SECOND_SYM
 | |
|         | MIN_SYM
 | |
| %ifdef ORACLE
 | |
|         | MINUS_ORACLE_SYM
 | |
| %endif
 | |
|         | MODIFIES_SYM
 | |
|         | MOD_SYM
 | |
|         | NATURAL
 | |
|         | NEG
 | |
|         | NOT_SYM
 | |
|         | NOW_SYM
 | |
|         | NO_WRITE_TO_BINLOG
 | |
|         | NTILE_SYM
 | |
|         | NULL_SYM
 | |
|         | NTH_VALUE_SYM
 | |
|         | ON
 | |
|         | OPTIMIZE
 | |
|         | OPTIONALLY
 | |
|         | ORDER_SYM
 | |
|         | OR_SYM
 | |
|         | OTHERS_ORACLE_SYM
 | |
|         | OUTER
 | |
|         | OUTFILE
 | |
|         | OVER_SYM
 | |
|         | PACKAGE_ORACLE_SYM
 | |
|         | PAGE_CHECKSUM_SYM
 | |
|         | PARSE_VCOL_EXPR_SYM
 | |
|         | PARTITION_SYM
 | |
|         | PERCENT_RANK_SYM
 | |
|         | PERCENTILE_CONT_SYM
 | |
|         | PERCENTILE_DISC_SYM
 | |
|         | PORTION_SYM
 | |
|         | POSITION_SYM
 | |
|         | PRECISION
 | |
|         | PRIMARY_SYM
 | |
|         | PROCEDURE_SYM
 | |
|         | PURGE
 | |
|         | RAISE_ORACLE_SYM
 | |
|         | RANGE_SYM
 | |
|         | RANK_SYM
 | |
|         | READS_SYM
 | |
|         | READ_SYM
 | |
|         | READ_WRITE_SYM
 | |
|         | RECURSIVE_SYM
 | |
|         | REF_SYSTEM_ID_SYM
 | |
|         | REFERENCES
 | |
|         | REGEXP
 | |
|         | RELEASE_SYM
 | |
|         | RENAME
 | |
|         | REPEAT_SYM
 | |
|         | REPLACE
 | |
|         | REQUIRE_SYM
 | |
|         | RESIGNAL_SYM
 | |
|         | RESTRICT
 | |
|         | RETURNING_SYM
 | |
|         | RETURN_MARIADB_SYM
 | |
|         | RETURN_ORACLE_SYM
 | |
|         | REVOKE
 | |
|         | RIGHT
 | |
|         | ROWS_SYM
 | |
|         | ROWTYPE_ORACLE_SYM
 | |
|         | ROW_NUMBER_SYM
 | |
|         | SECOND_MICROSECOND_SYM
 | |
|         | SELECT_SYM
 | |
|         | SENSITIVE_SYM
 | |
|         | SEPARATOR_SYM
 | |
|         | SERVER_OPTIONS
 | |
|         | SHOW
 | |
|         | SIGNAL_SYM
 | |
|         | SPATIAL_SYM
 | |
|         | SPECIFIC_SYM
 | |
|         | SQLEXCEPTION_SYM
 | |
|         | SQLSTATE_SYM
 | |
|         | SQLWARNING_SYM
 | |
|         | SQL_BIG_RESULT
 | |
|         | SQL_SMALL_RESULT
 | |
|         | SQL_SYM
 | |
|         | SSL_SYM
 | |
|         | STARTING
 | |
|         | STATS_AUTO_RECALC_SYM
 | |
|         | STATS_PERSISTENT_SYM
 | |
|         | STATS_SAMPLE_PAGES_SYM
 | |
|         | STDDEV_SAMP_SYM
 | |
|         | STD_SYM
 | |
|         | STRAIGHT_JOIN
 | |
|         | SUBSTRING
 | |
|         | SUM_SYM
 | |
|         | TABLE_REF_PRIORITY
 | |
|         | TABLE_SYM
 | |
|         | TERMINATED
 | |
|         | THEN_SYM
 | |
|         | TO_SYM
 | |
|         | TRAILING
 | |
|         | TRIGGER_SYM
 | |
|         | TRIM
 | |
|         | TRUE_SYM
 | |
|         | UNDO_SYM
 | |
|         | UNION_SYM
 | |
|         | UNIQUE_SYM
 | |
|         | UNLOCK_SYM
 | |
|         | UPDATE_SYM
 | |
|         | USAGE
 | |
|         | USE_SYM
 | |
|         | USING
 | |
|         | UTC_DATE_SYM
 | |
|         | UTC_TIMESTAMP_SYM
 | |
|         | UTC_TIME_SYM
 | |
|         | VALUES
 | |
|         | VALUES_IN_SYM
 | |
|         | VALUES_LESS_SYM
 | |
|         | VARIANCE_SYM
 | |
|         | VARYING
 | |
|         | VAR_SAMP_SYM
 | |
|         | VECTOR_SYM
 | |
|         | WHEN_SYM
 | |
|         | WHERE
 | |
|         | WHILE_SYM
 | |
|         | WITH
 | |
|         | XOR
 | |
|         | YEAR_MONTH_SYM
 | |
|         | ZEROFILL
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   SQLCOM_SET_OPTION statement.
 | |
| 
 | |
|   Note that to avoid shift/reduce conflicts, we have separate rules for the
 | |
|   first option listed in the statement.
 | |
| */
 | |
| 
 | |
| set:
 | |
|           SET
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->set_stmt_init();
 | |
|           }
 | |
|           set_param
 | |
|           {
 | |
|             if (Lex->check_main_unit_semantics())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| set_param:
 | |
|           option_value_no_option_type
 | |
|         | option_value_no_option_type ',' option_value_list
 | |
|         | TRANSACTION_SYM
 | |
|           {
 | |
|             Lex->option_type= OPT_DEFAULT;
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           transaction_characteristics
 | |
|           {
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | option_type
 | |
|           {
 | |
|             Lex->option_type= $1;
 | |
|           }
 | |
|           start_option_value_list_following_option_type
 | |
|         | STATEMENT_SYM
 | |
|           set_stmt_option_list
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->table_or_sp_used()))
 | |
|               my_yyabort_error((ER_SUBQUERIES_NOT_SUPPORTED, MYF(0), "SET STATEMENT"));
 | |
|             lex->stmt_var_list= lex->var_list;
 | |
|             lex->var_list.empty();
 | |
|             if (Lex->check_main_unit_semantics())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           FOR_SYM directly_executable_statement
 | |
|         ;
 | |
| 
 | |
| set_stmt_option_list:
 | |
|        /*
 | |
|          Only system variables can be used here. If this condition is changed
 | |
|          please check careful code under lex->option_type == OPT_STATEMENT
 | |
|          condition on wrong type casts.
 | |
|        */
 | |
|           set_stmt_option
 | |
|         | set_stmt_option_list ',' set_stmt_option
 | |
|         ;
 | |
| 
 | |
| /* Start of option value list, option_type was given */
 | |
| start_option_value_list_following_option_type:
 | |
|           option_value_following_option_type
 | |
|         | option_value_following_option_type ',' option_value_list
 | |
|         | TRANSACTION_SYM
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           transaction_characteristics
 | |
|           {
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Repeating list of option values after first option value. */
 | |
| option_value_list:
 | |
|           option_value
 | |
|         | option_value_list ',' option_value
 | |
|         ;
 | |
| 
 | |
| /* Wrapper around option values following the first option value in the stmt. */
 | |
| option_value:
 | |
|           option_type
 | |
|           {
 | |
|             Lex->option_type= $1;
 | |
|           }
 | |
|           option_value_following_option_type
 | |
|         | option_value_no_option_type
 | |
|         ;
 | |
| 
 | |
| option_type:
 | |
|           GLOBAL_SYM  { $$=OPT_GLOBAL; }
 | |
|         | LOCAL_SYM   { $$=OPT_SESSION; }
 | |
|         | SESSION_SYM { $$=OPT_SESSION; }
 | |
|         ;
 | |
| 
 | |
| opt_var_type:
 | |
|           /* empty */ { $$=OPT_SESSION; }
 | |
|         | GLOBAL_SYM  { $$=OPT_GLOBAL; }
 | |
|         | LOCAL_SYM   { $$=OPT_SESSION; }
 | |
|         | SESSION_SYM { $$=OPT_SESSION; }
 | |
|         ;
 | |
| 
 | |
| opt_var_ident_type:
 | |
|           /* empty */     { $$=OPT_DEFAULT; }
 | |
|         | GLOBAL_SYM '.'  { $$=OPT_GLOBAL; }
 | |
|         | LOCAL_SYM '.'   { $$=OPT_SESSION; }
 | |
|         | SESSION_SYM '.' { $$=OPT_SESSION; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   SET STATEMENT options do not need their own LEX or Query_arena.
 | |
|   Let's put them to the main ones.
 | |
| */
 | |
| set_stmt_option:
 | |
|           ident_cli equal
 | |
|           {
 | |
|             if (Lex->main_select_push(false))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_system_variable(Lex->option_type, &tmp,
 | |
|                                                   $4.expr)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->pop_select(); //min select
 | |
|           }
 | |
|         | ident_cli '.' ident equal
 | |
|           {
 | |
|             if (Lex->main_select_push(false))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_system_variable(thd, Lex->option_type,
 | |
|                          &tmp, &$3, $6.expr)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->pop_select(); //min select
 | |
|           }
 | |
|         | DEFAULT '.' ident equal
 | |
|           {
 | |
|             if (Lex->main_select_push(false))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_default_system_variable(Lex->option_type,
 | |
|                                                           &$3, $6.expr)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->pop_select(); //min select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| /* Option values with preceding option_type. */
 | |
| option_value_following_option_type:
 | |
|           ident_cli equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_system_variable(Lex->option_type, &tmp,
 | |
|                                                   $4.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_system_variable(thd, Lex->option_type, &tmp,
 | |
|                                                   &$3, $6.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DEFAULT '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_default_system_variable(Lex->option_type,
 | |
|                                                           &$3, $6.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Option values without preceding option_type. */
 | |
| option_value_no_option_type:
 | |
|           ident_cli_set_usual_case equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
| 
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_variable(&tmp, $4.expr, $4.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli_set_usual_case '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
| 
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_variable(&tmp, &$3, $6.expr, $6.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DEFAULT '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_default_system_variable(Lex->option_type,
 | |
|                                                           &$3, $6.expr)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' ident_or_text equal
 | |
|           {
 | |
|             if (!$2.length)
 | |
|             {
 | |
|               thd->parse_error();
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             if (sp_create_assignment_lex(thd, $1.str))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             LEX_CSTRING expr_str= empty_clex_str;
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               expr_str= make_string(thd, $5, $7);
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
|             if (unlikely(Lex->set_user_variable(thd, &$2, $6)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' '@' opt_var_ident_type ident_sysvar_name equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.str))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_system_variable($3, &$4, $7.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' '@' opt_var_ident_type ident_sysvar_name '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.str))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_system_variable(thd, $3, &$4, &$6,
 | |
|                                                   $9.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '@' '@' opt_var_ident_type DEFAULT '.' ident equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.str))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             if (unlikely(Lex->set_default_system_variable($3, &$6, $9.expr)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | charset old_or_new_charset_name_or_default
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex= thd->lex;
 | |
|             CHARSET_INFO *cs2;
 | |
|             cs2= $2 ? $2: global_system_variables.character_set_client;
 | |
|             set_var_collation_client *var;
 | |
|             var= (new (thd)
 | |
|                   set_var_collation_client(cs2,
 | |
|                                            thd->variables.collation_database,
 | |
|                                             cs2));
 | |
|             if (unlikely(var == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             lex->var_list.push_back(var, thd->mem_root);
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NAMES_SYM equal expr
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             sp_pcontext *spc= lex->spcont;
 | |
|             LEX_CSTRING names= { STRING_WITH_LEN("names") };
 | |
|             if (unlikely(spc && spc->find_variable(&names, false)))
 | |
|               my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
 | |
|             else
 | |
|               thd->parse_error();
 | |
|             MYSQL_YYABORT;
 | |
|           }
 | |
|         | NAMES_SYM charset_name_or_default
 | |
|           {
 | |
|             if (Lex->set_names($1.pos(), $2,
 | |
|                                Lex_extended_collation_st::collate_default(),
 | |
|                                yychar == YYEMPTY))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | NAMES_SYM charset_name_or_default
 | |
|                     COLLATE_SYM collation_name_or_default
 | |
|           {
 | |
|             if (Lex->set_names($1.pos(), $2, $4, yychar == YYEMPTY))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DEFAULT ROLE_SYM grant_role
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex = Lex;
 | |
|             LEX_USER *user;
 | |
|             if (unlikely(!(user= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             user->user= current_user;
 | |
|             set_var_default_role *var= (new (thd)
 | |
|                                         set_var_default_role(user,
 | |
|                                                              $3->user));
 | |
|             if (unlikely(var == NULL) ||
 | |
|                 unlikely(lex->var_list.push_back(var, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             thd->lex->autocommit= TRUE;
 | |
|             if (lex->sphead)
 | |
|               lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DEFAULT ROLE_SYM grant_role FOR_SYM user
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex = Lex;
 | |
|             set_var_default_role *var= (new (thd)
 | |
|                                         set_var_default_role($5, $3->user));
 | |
|             if (unlikely(var == NULL) ||
 | |
|                 unlikely(lex->var_list.push_back(var, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|             thd->lex->autocommit= TRUE;
 | |
|             if (lex->sphead)
 | |
|               lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
 | |
|             if (unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROLE_SYM role_name
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|             LEX *lex = Lex;
 | |
|             set_var_role *var= new (thd) set_var_role($2->user);
 | |
|             if (unlikely(var == NULL) ||
 | |
|                 unlikely(lex->var_list.push_back(var, thd->mem_root)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROLE_SYM equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
| 
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_variable(&tmp, $4.expr, $4.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PASSWORD_SYM equal
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           text_or_password
 | |
|           {
 | |
|             if (unlikely(Lex->sp_create_set_password_instr(thd, $4,
 | |
|                                                            yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PASSWORD_SYM FOR_SYM
 | |
|           {
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           user equal text_or_password
 | |
|           {
 | |
|             if (unlikely(Lex->sp_create_set_password_instr(thd, $4, $6,
 | |
|                                                            yychar == YYEMPTY)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| transaction_characteristics:
 | |
|           transaction_access_mode
 | |
|         | isolation_level
 | |
|         | transaction_access_mode ',' isolation_level
 | |
|         | isolation_level ',' transaction_access_mode
 | |
|         ;
 | |
| 
 | |
| transaction_access_mode:
 | |
|           transaction_access_mode_types
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Item *item= new (thd) Item_int(thd, (int32) $1);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             set_var *var= (new (thd)
 | |
|                            set_var(thd, lex->option_type,
 | |
|                                    find_sys_var(thd, "transaction_read_only"),
 | |
|                                    &null_clex_str,
 | |
|                                    item));
 | |
|             if (unlikely(var == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(lex->var_list.push_back(var, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| isolation_level:
 | |
|           ISOLATION LEVEL_SYM isolation_types
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             Item *item= new (thd) Item_int(thd, (int32) $3);
 | |
|             if (unlikely(item == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             set_var *var= (new (thd)
 | |
|                            set_var(thd, lex->option_type,
 | |
|                                    find_sys_var(thd, "transaction_isolation"),
 | |
|                                    &null_clex_str,
 | |
|                                    item));
 | |
|             if (unlikely(var == NULL) ||
 | |
|                 unlikely(lex->var_list.push_back(var, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| transaction_access_mode_types:
 | |
|           READ_SYM ONLY_SYM { $$= true; }
 | |
|         | READ_SYM WRITE_SYM { $$= false; }
 | |
|         ;
 | |
| 
 | |
| isolation_types:
 | |
|           READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
 | |
|         | READ_SYM COMMITTED_SYM   { $$= ISO_READ_COMMITTED; }
 | |
|         | REPEATABLE_SYM READ_SYM  { $$= ISO_REPEATABLE_READ; }
 | |
|         | SERIALIZABLE_SYM         { $$= ISO_SERIALIZABLE; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| text_or_password:
 | |
|           TEXT_STRING
 | |
|           {
 | |
|             $$= new (thd) USER_AUTH();
 | |
|             $$->auth_str= $1;
 | |
|           }
 | |
|         | PASSWORD_SYM '(' TEXT_STRING ')'
 | |
|           {
 | |
|             $$= new (thd) USER_AUTH();
 | |
|             $$->pwtext= $3;
 | |
|           }
 | |
|         | OLD_PASSWORD_SYM '(' TEXT_STRING ')'
 | |
|           {
 | |
|             $$= new (thd) USER_AUTH();
 | |
|             $$->pwtext= $3;
 | |
|             $$->auth_str.str= Item_func_password::alloc(thd,
 | |
|                                    $3.str, $3.length, Item_func_password::OLD);
 | |
|             $$->auth_str.length=  SCRAMBLED_PASSWORD_CHAR_LENGTH_323;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| set_expr_or_default:
 | |
|           remember_cpp_ptr expr remember_end
 | |
|           {
 | |
| 	      LEX_CSTRING expr_str= empty_clex_str;
 | |
| 
 | |
|               if (Lex->is_metadata_used())
 | |
|               {
 | |
|                 expr_str= make_string(thd, $1, $3);
 | |
|                 if (expr_str.str == nullptr)
 | |
|                   MYSQL_YYABORT;
 | |
|               }
 | |
| 
 | |
|               $$= { $2, expr_str };
 | |
|           }
 | |
|         | remember_cpp_ptr set_expr_misc remember_end
 | |
|           {
 | |
|             if (unlikely($2 == nullptr))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= {$2, empty_clex_str};
 | |
|           }
 | |
|         | remember_cpp_ptr DEFAULT remember_end
 | |
|           {
 | |
|             $$= { nullptr, empty_clex_str };
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| set_expr_misc:
 | |
|           ON     { $$= new (thd) Item_string_sys(thd, "ON",  2); }
 | |
|         | ALL    { $$= new (thd) Item_string_sys(thd, "ALL", 3); }
 | |
|         | BINARY { $$= new (thd) Item_string_sys(thd, "binary", 6); }
 | |
|         ;
 | |
| 
 | |
| /* Lock function */
 | |
| 
 | |
| lock:
 | |
|           LOCK_SYM table_or_tables
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "LOCK"));
 | |
|             lex->sql_command= SQLCOM_LOCK_TABLES;
 | |
|           }
 | |
|           table_lock_list opt_lock_wait_timeout
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| opt_lock_wait_timeout:
 | |
|         /* empty */
 | |
|         {}
 | |
|         | WAIT_SYM ulong_num
 | |
|         {
 | |
|           if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), $2)) ||
 | |
|               unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), $2)))
 | |
|             MYSQL_YYABORT;
 | |
|         }
 | |
|         | NOWAIT_SYM
 | |
|         {
 | |
|           if (unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("lock_wait_timeout"), 0)) ||
 | |
|               unlikely(set_statement_var_if_exists(thd, STRING_WITH_LEN("innodb_lock_wait_timeout"), 0)))
 | |
|             MYSQL_YYABORT;
 | |
|         }
 | |
|       ;
 | |
| 
 | |
| table_or_tables:
 | |
|           TABLE_SYM        { }
 | |
|         | TABLES           { }
 | |
|         ;
 | |
| 
 | |
| table_lock_list:
 | |
|           table_lock
 | |
|         | table_lock_list ',' table_lock
 | |
|         ;
 | |
| 
 | |
| table_lock:
 | |
|           table_ident opt_table_alias_clause lock_option
 | |
|           {
 | |
|             thr_lock_type lock_type= (thr_lock_type) $3;
 | |
|             bool lock_for_write= (lock_type >= TL_FIRST_WRITE);
 | |
|             ulong table_options= lock_for_write ? TL_OPTION_UPDATING : 0;
 | |
|             enum_mdl_type mdl_type= !lock_for_write
 | |
|                                     ? MDL_SHARED_READ
 | |
|                                     : lock_type == TL_WRITE_CONCURRENT_INSERT
 | |
|                                       ? MDL_SHARED_WRITE
 | |
|                                       : MDL_SHARED_NO_READ_WRITE;
 | |
| 
 | |
|             if (unlikely(!Lex->current_select_or_default()->
 | |
|                          add_table_to_list(thd, $1, $2, table_options,
 | |
|                                            lock_type, mdl_type)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| lock_option:
 | |
|           READ_SYM               { $$= TL_READ_NO_INSERT; }
 | |
|         | WRITE_SYM              { $$= TL_WRITE_DEFAULT; }
 | |
|         | WRITE_SYM CONCURRENT
 | |
|           {
 | |
|             $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
 | |
|           }
 | |
| 
 | |
|         | LOW_PRIORITY WRITE_SYM { $$= TL_WRITE_LOW_PRIORITY; }
 | |
|         | READ_SYM LOCAL_SYM     { $$= TL_READ; }
 | |
|         ;
 | |
| 
 | |
| unlock:
 | |
|           UNLOCK_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"));
 | |
|             lex->sql_command= SQLCOM_UNLOCK_TABLES;
 | |
|           }
 | |
|           table_or_tables
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| /*
 | |
| ** Handler: direct access to ISAM functions
 | |
| */
 | |
| 
 | |
| handler:
 | |
|           HANDLER_SYM
 | |
|           {
 | |
|             if (Lex->main_select_push())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           handler_tail
 | |
|           {
 | |
|             Lex->pop_select(); //main select
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| handler_tail:
 | |
|           table_ident OPEN_SYM opt_table_alias_clause
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
 | |
|             lex->sql_command = SQLCOM_HA_OPEN;
 | |
|             if (!lex->current_select->add_table_to_list(thd, $1, $3, 0))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | table_ident_nodb CLOSE_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
 | |
|             lex->sql_command = SQLCOM_HA_CLOSE;
 | |
|             if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | table_ident_nodb READ_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             SELECT_LEX *select= Select;
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_BADSTATEMENT, MYF(0), "HANDLER"));
 | |
|             lex->clause_that_disallows_subselect= "HANDLER..READ";
 | |
|             lex->sql_command = SQLCOM_HA_READ;
 | |
|             lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */
 | |
|             Item *one= new (thd) Item_int(thd, (int32) 1);
 | |
|             if (unlikely(one == NULL))
 | |
|               MYSQL_YYABORT;
 | |
|             select->limit_params.select_limit= one;
 | |
|             select->limit_params.offset_limit= 0;
 | |
|             lex->limit_rows_examined= 0;
 | |
|             if (!lex->current_select->add_table_to_list(thd, $1, 0, 0))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           handler_read_or_scan opt_where_clause opt_global_limit_clause
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             SELECT_LEX *select= Select;
 | |
|             lex->clause_that_disallows_subselect= NULL;
 | |
|             if (!lex->current_select->limit_params.explicit_limit)
 | |
|             {
 | |
|               Item *one= new (thd) Item_int(thd, (int32) 1);
 | |
|               if (one == NULL)
 | |
|                 MYSQL_YYABORT;
 | |
|               select->limit_params.select_limit= one;
 | |
|               select->limit_params.offset_limit= 0;
 | |
|               lex->limit_rows_examined= 0;
 | |
|             }
 | |
|             /* Stored functions are not supported for HANDLER READ. */
 | |
|             if (lex->uses_stored_routines())
 | |
|             {
 | |
|               my_error(ER_NOT_SUPPORTED_YET, MYF(0),
 | |
|                        "stored functions in HANDLER ... READ");
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| handler_read_or_scan:
 | |
|           handler_scan_function       { Lex->ident= null_clex_str; }
 | |
|         | ident handler_rkey_function { Lex->ident= $1; }
 | |
|         ;
 | |
| 
 | |
| handler_scan_function:
 | |
|           FIRST_SYM { Lex->ha_read_mode = RFIRST; }
 | |
|         | NEXT_SYM  { Lex->ha_read_mode = RNEXT;  }
 | |
|         ;
 | |
| 
 | |
| handler_rkey_function:
 | |
|           FIRST_SYM { Lex->ha_read_mode = RFIRST; }
 | |
|         | NEXT_SYM  { Lex->ha_read_mode = RNEXT;  }
 | |
|         | PREV_SYM  { Lex->ha_read_mode = RPREV;  }
 | |
|         | LAST_SYM  { Lex->ha_read_mode = RLAST;  }
 | |
|         | handler_rkey_mode
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->ha_read_mode = RKEY;
 | |
|             lex->ha_rkey_mode=$1;
 | |
|             if (unlikely(!(lex->insert_list= new (thd) List_item)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           '(' values ')'
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| handler_rkey_mode:
 | |
|           '='     { $$=HA_READ_KEY_EXACT;   }
 | |
|         | GE     { $$=HA_READ_KEY_OR_NEXT; }
 | |
|         | LE     { $$=HA_READ_KEY_OR_PREV; }
 | |
|         | '>' { $$=HA_READ_AFTER_KEY;   }
 | |
|         | '<'     { $$=HA_READ_BEFORE_KEY;  }
 | |
|         ;
 | |
| 
 | |
| /* GRANT / REVOKE */
 | |
| 
 | |
| revoke:
 | |
|           REVOKE clear_privileges revoke_command
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| revoke_command:
 | |
|           grant_privileges ON opt_table grant_ident FROM user_and_role_list
 | |
|           {
 | |
|             if (Lex->stmt_revoke_table(thd, $1, *$4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | grant_privileges ON sp_handler grant_ident FROM user_and_role_list
 | |
|           {
 | |
|             if (Lex->stmt_revoke_sp(thd, $1, *$4, *$3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ALL opt_privileges ',' GRANT OPTION FROM user_and_role_list
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_REVOKE_ALL;
 | |
|           }
 | |
|         | PROXY_SYM ON user FROM user_list
 | |
|           {
 | |
|             if (Lex->stmt_revoke_proxy(thd, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | admin_option_for_role FROM user_and_role_list
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_REVOKE_ROLE;
 | |
|             if (unlikely(Lex->users_list.push_front($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| admin_option_for_role:
 | |
|         ADMIN_SYM OPTION FOR_SYM grant_role
 | |
|         { Lex->with_admin_option= true; $$= $4; }
 | |
|       | grant_role
 | |
|         { Lex->with_admin_option= false; $$= $1; }
 | |
|       ;
 | |
| 
 | |
| grant:
 | |
|           GRANT clear_privileges grant_command
 | |
|           {}
 | |
|         ;
 | |
| 
 | |
| grant_command:
 | |
|           grant_privileges ON opt_table grant_ident TO_SYM grant_list
 | |
|           opt_require_clause opt_grant_options
 | |
|           {
 | |
|             if (Lex->stmt_grant_table(thd, $1, *$4, $8))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | grant_privileges ON sp_handler grant_ident TO_SYM grant_list
 | |
|           opt_require_clause opt_grant_options
 | |
|           {
 | |
|             if (Lex->stmt_grant_sp(thd, $1, *$4, *$3, $8))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | PROXY_SYM ON user TO_SYM grant_list opt_grant_option
 | |
|           {
 | |
|             if (Lex->stmt_grant_proxy(thd, $3, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | grant_role TO_SYM grant_list opt_with_admin_option
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->sql_command= SQLCOM_GRANT_ROLE;
 | |
|             /* The first role is the one that is granted */
 | |
|             if (unlikely(Lex->users_list.push_front($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
| 
 | |
|         ;
 | |
| 
 | |
| opt_with_admin:
 | |
|           /* 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; }
 | |
|         ;
 | |
| 
 | |
| role_list:
 | |
|           grant_role
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | role_list ',' grant_role
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| current_role:
 | |
|           CURRENT_ROLE optional_braces
 | |
|           {
 | |
|             if (unlikely(!($$= thd->calloc<LEX_USER>(1))))
 | |
|               MYSQL_YYABORT;
 | |
|             $$->user= current_role;
 | |
|           }
 | |
|           ;
 | |
| 
 | |
| 
 | |
| role_name: ident_or_text
 | |
|            {
 | |
|              CHARSET_INFO *cs= system_charset_info;
 | |
|              /* trim end spaces (as they'll be lost in mysql.user anyway) */
 | |
|              $1.length= cs->lengthsp($1.str, $1.length);
 | |
|              ((char*) $1.str)[$1.length] = '\0';
 | |
|              if (unlikely($1.length == 0))
 | |
|                my_yyabort_error((ER_INVALID_ROLE, MYF(0), ""));
 | |
|              if (unlikely(!($$= thd->calloc<LEX_USER>(1))))
 | |
|                MYSQL_YYABORT;
 | |
|              if (lex_string_eq(&$1, &none))
 | |
|                $$->user= none;
 | |
|              else if (lex_string_eq(&$1, &public_name))
 | |
|                $$->user= public_name;
 | |
|              else if (check_string_char_length(&($$->user= $1), ER_USERNAME,
 | |
|                                                username_char_length, cs, 0))
 | |
|                MYSQL_YYABORT;
 | |
|              $$->host= empty_clex_str;
 | |
|            }
 | |
|            ;
 | |
| 
 | |
| grant_role: role_name | current_role ;
 | |
| 
 | |
| opt_table:
 | |
|           /* Empty */        %prec PREC_BELOW_SP_OBJECT_TYPE
 | |
|         | TABLE_SYM
 | |
|         ;
 | |
| 
 | |
| grant_privileges:
 | |
|           object_privilege_list
 | |
|         | ALL opt_privileges
 | |
|           { 
 | |
|             if (!($$= new (thd) Lex_grant_privilege(GLOBAL_ACLS, true)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_privileges:
 | |
|           /* empty */
 | |
|         | PRIVILEGES
 | |
|         ;
 | |
| 
 | |
| object_privilege_list:
 | |
|           object_privilege
 | |
|           {
 | |
|             if (!($$= new (thd) Lex_grant_privilege($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | column_list_privilege
 | |
|           {
 | |
|             if (!($$= new (thd) Lex_grant_privilege()) ||
 | |
|                 $$->add_column_list_privilege(thd, $1.m_columns[0],
 | |
|                                                    $1.m_privilege))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | object_privilege_list ',' object_privilege
 | |
|           {
 | |
|             ($$= $1)->add_object_privilege($3);
 | |
|           }
 | |
|         | object_privilege_list ',' column_list_privilege
 | |
|           {
 | |
|             if (($$= $1)->add_column_list_privilege(thd, $3.m_columns[0],
 | |
|                                                          $3.m_privilege))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| column_list_privilege:
 | |
|           column_privilege '(' comma_separated_ident_list ')'
 | |
|           {
 | |
|             $$= Lex_column_list_privilege($3, $1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| column_privilege:
 | |
|           SELECT_SYM              { $$= SELECT_ACL; }
 | |
|         | INSERT                  { $$= INSERT_ACL; }
 | |
|         | UPDATE_SYM              { $$= UPDATE_ACL; }
 | |
|         | REFERENCES              { $$= REFERENCES_ACL; }
 | |
|         ;
 | |
| 
 | |
| object_privilege:
 | |
|           SELECT_SYM              { $$= SELECT_ACL; }
 | |
|         | INSERT                  { $$= INSERT_ACL; }
 | |
|         | UPDATE_SYM              { $$= UPDATE_ACL; }
 | |
|         | REFERENCES              { $$= REFERENCES_ACL; }
 | |
|         | DELETE_SYM              { $$= DELETE_ACL;}
 | |
|         | USAGE                   { $$= NO_ACL; }
 | |
|         | INDEX_SYM               { $$= INDEX_ACL;}
 | |
|         | ALTER                   { $$= ALTER_ACL;}
 | |
|         | CREATE                  { $$= CREATE_ACL;}
 | |
|         | DROP                    { $$= DROP_ACL;}
 | |
|         | EXECUTE_SYM             { $$= EXECUTE_ACL;}
 | |
|         | RELOAD                  { $$= RELOAD_ACL;}
 | |
|         | SHUTDOWN                { $$= SHUTDOWN_ACL;}
 | |
|         | PROCESS                 { $$= PROCESS_ACL;}
 | |
|         | FILE_SYM                { $$= FILE_ACL;}
 | |
|         | GRANT OPTION            { $$= GRANT_ACL;}
 | |
|         | SHOW DATABASES          { $$= SHOW_DB_ACL;}
 | |
|         | SUPER_SYM               { $$= SUPER_ACL;}
 | |
|         | CREATE TEMPORARY TABLES { $$= CREATE_TMP_ACL;}
 | |
|         | LOCK_SYM TABLES         { $$= LOCK_TABLES_ACL; }
 | |
|         | REPLICATION SLAVE       { $$= REPL_SLAVE_ACL; }
 | |
|         | REPLICATION CLIENT_SYM  { $$= BINLOG_MONITOR_ACL; /*Compatibility*/ }
 | |
|         | CREATE VIEW_SYM         { $$= CREATE_VIEW_ACL; }
 | |
|         | SHOW VIEW_SYM           { $$= SHOW_VIEW_ACL; }
 | |
|         | CREATE ROUTINE_SYM      { $$= CREATE_PROC_ACL; }
 | |
|         | ALTER ROUTINE_SYM       { $$= ALTER_PROC_ACL; }
 | |
|         | CREATE USER_SYM         { $$= CREATE_USER_ACL; }
 | |
|         | EVENT_SYM               { $$= EVENT_ACL;}
 | |
|         | TRIGGER_SYM             { $$= TRIGGER_ACL; }
 | |
|         | CREATE TABLESPACE       { $$= CREATE_TABLESPACE_ACL; }
 | |
|         | DELETE_SYM HISTORY_SYM  { $$= DELETE_HISTORY_ACL; }
 | |
|         | SET USER_SYM            { $$= SET_USER_ACL; }
 | |
|         | FEDERATED_SYM ADMIN_SYM { $$= FEDERATED_ADMIN_ACL; }
 | |
|         | CONNECTION_SYM ADMIN_SYM         { $$= CONNECTION_ADMIN_ACL; }
 | |
|         | READ_SYM ONLY_SYM ADMIN_SYM      { $$= READ_ONLY_ADMIN_ACL; }
 | |
|         | READ_ONLY_SYM ADMIN_SYM          { $$= READ_ONLY_ADMIN_ACL; }
 | |
|         | BINLOG_SYM MONITOR_SYM           { $$= BINLOG_MONITOR_ACL; }
 | |
|         | BINLOG_SYM ADMIN_SYM             { $$= BINLOG_ADMIN_ACL; }
 | |
|         | BINLOG_SYM REPLAY_SYM            { $$= BINLOG_REPLAY_ACL; }
 | |
|         | REPLICATION MASTER_SYM ADMIN_SYM { $$= REPL_MASTER_ADMIN_ACL; }
 | |
|         | REPLICATION SLAVE ADMIN_SYM      { $$= REPL_SLAVE_ADMIN_ACL; }
 | |
|         | SLAVE MONITOR_SYM                { $$= SLAVE_MONITOR_ACL; }
 | |
|         | SHOW CREATE ROUTINE_SYM          { $$= SHOW_CREATE_ROUTINE_ACL; }
 | |
|         ;
 | |
| 
 | |
| opt_and:
 | |
|           /* empty */ {}
 | |
|         | AND_SYM {}
 | |
|         ;
 | |
| 
 | |
| require_list:
 | |
|           require_list_element opt_and require_list
 | |
|         | require_list_element
 | |
|         ;
 | |
| 
 | |
| require_list_element:
 | |
|           SUBJECT_SYM TEXT_STRING
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (lex->account_options.x509_subject.str)
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "SUBJECT"));
 | |
|             lex->account_options.x509_subject= $2;
 | |
|           }
 | |
|         | ISSUER_SYM TEXT_STRING
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (lex->account_options.x509_issuer.str)
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "ISSUER"));
 | |
|             lex->account_options.x509_issuer= $2;
 | |
|           }
 | |
|         | CIPHER_SYM TEXT_STRING
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             if (lex->account_options.ssl_cipher.str)
 | |
|               my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "CIPHER"));
 | |
|             lex->account_options.ssl_cipher= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| grant_ident:
 | |
|           '*'
 | |
|           {
 | |
|             LEX_CSTRING db;
 | |
|             if (unlikely(Lex->copy_db_to(&db)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (!($$= new (thd) Lex_grant_object_name(db,
 | |
|                                             Lex_grant_object_name::STAR)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident '.' '*'
 | |
|           {
 | |
|             if (!($$= new (thd) Lex_grant_object_name($1,
 | |
|                                             Lex_grant_object_name::IDENT_STAR)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | '*' '.' '*'
 | |
|           {
 | |
|             if (!($$= new (thd) Lex_grant_object_name(
 | |
|                                             null_clex_str,
 | |
|                                             Lex_grant_object_name::STAR_STAR)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | table_ident
 | |
|           {
 | |
|             if (!($$= new (thd) Lex_grant_object_name($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| user_list:
 | |
|           user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | user_list ',' user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| grant_list:
 | |
|           grant_user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | grant_list ',' grant_user
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| user_and_role_list:
 | |
|           user_or_role
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($1, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | user_and_role_list ',' user_or_role
 | |
|           {
 | |
|             if (unlikely(Lex->users_list.push_back($3, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| via_or_with: VIA_SYM | WITH ;
 | |
| using_or_as: USING | AS ;
 | |
| 
 | |
| grant_user:
 | |
|           user IDENTIFIED_SYM BY TEXT_STRING
 | |
|           {
 | |
|             $$= $1;
 | |
|             $1->auth= new (thd) USER_AUTH();
 | |
|             $1->auth->pwtext= $4;
 | |
|           }
 | |
|         | user IDENTIFIED_SYM BY PASSWORD_SYM TEXT_STRING
 | |
|           { 
 | |
|             $$= $1; 
 | |
|             $1->auth= new (thd) USER_AUTH();
 | |
|             $1->auth->auth_str= $5;
 | |
|           }
 | |
|         | user IDENTIFIED_SYM via_or_with auth_expression
 | |
|           {
 | |
|             $$= $1;
 | |
|             $1->auth= $4;
 | |
|           }
 | |
|         | user_or_role
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| auth_expression:
 | |
|           auth_token OR_SYM auth_expression
 | |
|           {
 | |
|             $$= $1;
 | |
|             DBUG_ASSERT($$->next == NULL);
 | |
|             $$->next= $3;
 | |
|           }
 | |
|         | auth_token
 | |
|           {
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| auth_token:
 | |
|           ident_or_text opt_auth_str
 | |
|         {
 | |
|           $$= $2;
 | |
|           $$->plugin= $1;
 | |
|         }
 | |
|         ;
 | |
| 
 | |
| opt_auth_str:
 | |
|         /* empty */
 | |
|         {
 | |
|           if (!($$=thd->calloc<USER_AUTH>(1)))
 | |
|             MYSQL_YYABORT;
 | |
|         }
 | |
|       | using_or_as TEXT_STRING_sys
 | |
|         {
 | |
|           if (!($$=thd->calloc<USER_AUTH>(1)))
 | |
|             MYSQL_YYABORT;
 | |
|           $$->auth_str= $2;
 | |
|         }
 | |
|       | using_or_as PASSWORD_SYM '(' TEXT_STRING ')'
 | |
|         {
 | |
|           if (!($$=thd->calloc<USER_AUTH>(1)))
 | |
|             MYSQL_YYABORT;
 | |
|           $$->pwtext= $4;
 | |
|         }
 | |
|       ;
 | |
| 
 | |
| opt_require_clause:
 | |
|           /* empty */
 | |
|         | REQUIRE_SYM require_list
 | |
|           {
 | |
|             Lex->account_options.ssl_type= SSL_TYPE_SPECIFIED;
 | |
|           }
 | |
|         | REQUIRE_SYM SSL_SYM
 | |
|           {
 | |
|             Lex->account_options.ssl_type= SSL_TYPE_ANY;
 | |
|           }
 | |
|         | REQUIRE_SYM X509_SYM
 | |
|           {
 | |
|             Lex->account_options.ssl_type= SSL_TYPE_X509;
 | |
|           }
 | |
|         | REQUIRE_SYM NONE_SYM
 | |
|           {
 | |
|             Lex->account_options.ssl_type= SSL_TYPE_NONE;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| resource_option:
 | |
|         MAX_QUERIES_PER_HOUR ulong_num
 | |
|           {
 | |
|             Lex->account_options.questions=$2;
 | |
|             Lex->account_options.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
 | |
|           }
 | |
|         | MAX_UPDATES_PER_HOUR ulong_num
 | |
|           {
 | |
|             Lex->account_options.updates=$2;
 | |
|             Lex->account_options.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
 | |
|           }
 | |
|         | MAX_CONNECTIONS_PER_HOUR ulong_num
 | |
|           {
 | |
|             Lex->account_options.conn_per_hour= $2;
 | |
|             Lex->account_options.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
 | |
|           }
 | |
|         | MAX_USER_CONNECTIONS_SYM int_num
 | |
|           {
 | |
|             Lex->account_options.user_conn= $2;
 | |
|             Lex->account_options.specified_limits|= USER_RESOURCES::USER_CONNECTIONS;
 | |
|           }
 | |
|         | MAX_STATEMENT_TIME_SYM NUM_literal
 | |
|           {
 | |
|             Lex->account_options.max_statement_time= $2->val_real();
 | |
|             Lex->account_options.specified_limits|= USER_RESOURCES::MAX_STATEMENT_TIME;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| resource_option_list:
 | |
| 	  resource_option_list resource_option {}
 | |
| 	| resource_option {}
 | |
|         ;
 | |
| 
 | |
| opt_resource_options:
 | |
| 	  /* empty */ {}
 | |
| 	| WITH resource_option_list
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_grant_options:
 | |
|           /* empty */            { $$= NO_ACL;  }
 | |
|         | WITH grant_option_list { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| opt_grant_option:
 | |
|           /* empty */       { $$= NO_ACL;    }
 | |
|         | WITH GRANT OPTION { $$= GRANT_ACL; }
 | |
|         ;
 | |
| 
 | |
| grant_option_list:
 | |
|           grant_option_list grant_option { $$= $1 | $2; }
 | |
|         | grant_option
 | |
|         ;
 | |
| 
 | |
| grant_option:
 | |
|           GRANT OPTION    { $$= GRANT_ACL;}
 | |
| 	| resource_option { $$= NO_ACL; }
 | |
|         ;
 | |
| 
 | |
| begin_stmt_mariadb:
 | |
|           BEGIN_MARIADB_SYM
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command = SQLCOM_BEGIN;
 | |
|             lex->start_transaction_opt= 0;
 | |
|           }
 | |
|           opt_work {}
 | |
|           ;
 | |
| 
 | |
| compound_statement:
 | |
|           sp_proc_stmt_compound_ok
 | |
|           {
 | |
|             Lex->sql_command= SQLCOM_COMPOUND;
 | |
|             if (Lex->sp_body_finalize_procedure(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_not:
 | |
|         /* nothing */  { $$= 0; }
 | |
|         | not          { $$= 1; }
 | |
|         ;
 | |
| 
 | |
| opt_work:
 | |
|           /* empty */ {}
 | |
|         | WORK_SYM  {}
 | |
|         ;
 | |
| 
 | |
| opt_chain:
 | |
|           /* empty */
 | |
|           { $$= TVL_UNKNOWN; }
 | |
|         | AND_SYM NO_SYM CHAIN_SYM { $$= TVL_NO; }
 | |
|         | AND_SYM CHAIN_SYM        { $$= TVL_YES; }
 | |
|         ;
 | |
| 
 | |
| opt_release:
 | |
|           /* empty */
 | |
|           { $$= TVL_UNKNOWN; }
 | |
|         | RELEASE_SYM        { $$= TVL_YES; }
 | |
|         | NO_SYM RELEASE_SYM { $$= TVL_NO; }
 | |
|         ;
 | |
| 
 | |
| commit:
 | |
|           COMMIT_SYM opt_work opt_chain opt_release
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_COMMIT;
 | |
|             /* Don't allow AND CHAIN RELEASE. */
 | |
|             MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
 | |
|             lex->tx_chain= $3;
 | |
|             lex->tx_release= $4;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| rollback:
 | |
|           ROLLBACK_SYM opt_work opt_chain opt_release
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_ROLLBACK;
 | |
|             /* Don't allow AND CHAIN RELEASE. */
 | |
|             MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
 | |
|             lex->tx_chain= $3;
 | |
|             lex->tx_release= $4;
 | |
|           }
 | |
|         | ROLLBACK_SYM opt_work TO_SYM SAVEPOINT_SYM ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT;
 | |
|             lex->ident= $5;
 | |
|           }
 | |
|         | ROLLBACK_SYM opt_work TO_SYM ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT;
 | |
|             lex->ident= $4;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| savepoint:
 | |
|           SAVEPOINT_SYM ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_SAVEPOINT;
 | |
|             lex->ident= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| release:
 | |
|           RELEASE_SYM SAVEPOINT_SYM ident
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->sql_command= SQLCOM_RELEASE_SAVEPOINT;
 | |
|             lex->ident= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|    UNIONS : glue selects together
 | |
| */
 | |
| 
 | |
| unit_type_decl:
 | |
|           UNION_SYM union_option
 | |
|           { $$.unit_type= UNION_TYPE; $$.distinct= $2; }
 | |
|         | INTERSECT_SYM union_option
 | |
|           { $$.unit_type= INTERSECT_TYPE; $$.distinct= $2; }
 | |
|         | EXCEPT_SYM union_option
 | |
|           { $$.unit_type= EXCEPT_TYPE; $$.distinct= $2; }
 | |
|         ;
 | |
| 
 | |
| /*
 | |
|   Start a UNION, for non-top level query expressions.
 | |
| */
 | |
| union_option:
 | |
|           /* empty */ { $$=1; }
 | |
|         | DISTINCT  { $$=1; }
 | |
|         | ALL       { $$=0; }
 | |
|         ;
 | |
| 
 | |
| query_expression_option:
 | |
|           STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
 | |
|         | HIGH_PRIORITY
 | |
|           {
 | |
|             YYPS->m_lock_type= TL_READ_HIGH_PRIORITY;
 | |
|             YYPS->m_mdl_type= MDL_SHARED_READ;
 | |
|             Select->options|= SELECT_HIGH_PRIORITY;
 | |
|           }
 | |
|         | DISTINCT         { Select->options|= SELECT_DISTINCT; }
 | |
|         | UNIQUE_SYM       { Select->options|= SELECT_DISTINCT; }
 | |
|         | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
 | |
|         | SQL_BIG_RESULT   { Select->options|= SELECT_BIG_RESULT; }
 | |
|         | SQL_BUFFER_RESULT { Select->options|= OPTION_BUFFER_RESULT; }
 | |
|         | SQL_CALC_FOUND_ROWS { Select->options|= OPTION_FOUND_ROWS; }
 | |
|         | ALL { Select->options|= SELECT_ALL; }
 | |
|         ;
 | |
| 
 | |
| /**************************************************************************
 | |
| 
 | |
|  DEFINER clause support.
 | |
| 
 | |
| **************************************************************************/
 | |
| 
 | |
| definer_opt:
 | |
|           no_definer
 | |
|         | definer
 | |
|         ;
 | |
| 
 | |
| no_definer:
 | |
|           /* empty */
 | |
|           {
 | |
|             /*
 | |
|               We have to distinguish missing DEFINER-clause from case when
 | |
|               CURRENT_USER specified as definer explicitly in order to properly
 | |
|               handle CREATE TRIGGER statements which come to replication thread
 | |
|               from older master servers (i.e. to create non-suid trigger in this
 | |
|               case).
 | |
|             */
 | |
|             thd->lex->definer= 0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| definer:
 | |
|           DEFINER_SYM '=' user_or_role
 | |
|           {
 | |
|             Lex->definer= $3;
 | |
|             Lex->account_options.reset();
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /**************************************************************************
 | |
| 
 | |
|  CREATE VIEW statement parts.
 | |
| 
 | |
| **************************************************************************/
 | |
| 
 | |
| view_algorithm:
 | |
|           ALGORITHM_SYM '=' UNDEFINED_SYM { $$= DTYPE_ALGORITHM_UNDEFINED; }
 | |
|         | ALGORITHM_SYM '=' MERGE_SYM     { $$= VIEW_ALGORITHM_MERGE; }
 | |
|         | ALGORITHM_SYM '=' TEMPTABLE_SYM { $$= VIEW_ALGORITHM_TMPTABLE; }
 | |
|         ;
 | |
| 
 | |
| opt_view_suid:
 | |
|           /* empty */                      { $$= VIEW_SUID_DEFAULT; }
 | |
|         | view_suid                        { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| view_suid:
 | |
|           SQL_SYM SECURITY_SYM DEFINER_SYM { $$= VIEW_SUID_DEFINER; }
 | |
|         | SQL_SYM SECURITY_SYM INVOKER_SYM { $$= VIEW_SUID_INVOKER; }
 | |
|         ;
 | |
| 
 | |
| view_list_opt:
 | |
|           /* empty */
 | |
|           {}
 | |
|         | '(' view_list ')' { }
 | |
|         ;
 | |
| 
 | |
| view_list:
 | |
|           ident 
 | |
|           {
 | |
|             Lex->view_list.push_back((LEX_CSTRING*)
 | |
|                                      thd->memdup(&$1, sizeof(LEX_CSTRING)),
 | |
|                                      thd->mem_root);
 | |
|           }
 | |
|         | view_list ',' ident
 | |
|           {
 | |
|             Lex->view_list.push_back((LEX_CSTRING*)
 | |
|                                      thd->memdup(&$3, sizeof(LEX_CSTRING)),
 | |
|                                      thd->mem_root);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| view_select:
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->parsing_options.allows_variable= FALSE;
 | |
|             lex->create_view->select.str= (char *) YYLIP->get_cpp_ptr();
 | |
|           }
 | |
|           query_expression
 | |
|           view_check_option
 | |
|           {
 | |
|             if (Lex->parsed_create_view($2, $3))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| view_check_option:
 | |
|           /* empty */                     { $$= VIEW_CHECK_NONE; }
 | |
|         | WITH CHECK_SYM OPTION           { $$= VIEW_CHECK_CASCADED; }
 | |
|         | WITH CASCADED CHECK_SYM OPTION  { $$= VIEW_CHECK_CASCADED; }
 | |
|         | WITH LOCAL_SYM CHECK_SYM OPTION { $$= VIEW_CHECK_LOCAL; }
 | |
|         ;
 | |
| 
 | |
| /**************************************************************************
 | |
| 
 | |
|  CREATE TRIGGER statement parts.
 | |
| 
 | |
| **************************************************************************/
 | |
| 
 | |
| 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= null_clex_str;
 | |
|             }
 | |
|           |
 | |
|             trigger_action_order ident_or_text
 | |
|             {
 | |
|               $$.ordering_clause= $1;
 | |
|               $$.anchor_trigger_name= $2;
 | |
|             }
 | |
|           ;
 | |
| 
 | |
| opt_on_update_cols:
 | |
|             /* empty */
 | |
|             {
 | |
|               Lex->trg_chistics.on_update_col_names= NULL;
 | |
|             }
 | |
|           | OF_SYM on_update_cols
 | |
|             {
 | |
|               if (!is_trg_event_on(Lex->trg_chistics.events, TRG_EVENT_UPDATE))
 | |
|               {
 | |
|                 thd->parse_error(ER_SYNTAX_ERROR, $1.pos());
 | |
|                 MYSQL_YYABORT;
 | |
|               }
 | |
| 	    }
 | |
|           ;
 | |
| 
 | |
| on_update_cols:
 | |
|           ident
 | |
|           {
 | |
|             List<LEX_CSTRING> *col_names_list;
 | |
|             LEX_CSTRING *col_name;
 | |
| 
 | |
|             col_names_list=
 | |
|               new (thd->mem_root) List<LEX_CSTRING>;
 | |
| 
 | |
|             col_name= (LEX_CSTRING *) thd->memdup(&$1, sizeof(LEX_CSTRING));
 | |
| 
 | |
|             if (unlikely(col_names_list == NULL) ||
 | |
|                 unlikely(col_name == NULL) ||
 | |
|                 unlikely(col_names_list->push_back(col_name, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             Lex->trg_chistics.on_update_col_names= col_names_list;
 | |
|           }
 | |
|         | on_update_cols ',' ident
 | |
|           {
 | |
|             LEX_CSTRING *col_name;
 | |
| 
 | |
|             col_name= (LEX_CSTRING *) thd->memdup(&$3, sizeof(LEX_CSTRING));
 | |
| 
 | |
|             if (unlikely(col_name == NULL) ||
 | |
|                 unlikely(Lex->trg_chistics.on_update_col_names->push_back
 | |
|                   (col_name, thd->mem_root)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
| 	;
 | |
| 
 | |
| trigger_tail:
 | |
|           remember_name
 | |
|           opt_if_not_exists
 | |
|           {
 | |
|             if (unlikely(Lex->add_create_options_with_check($2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_name
 | |
|           trg_action_time
 | |
|           trg_events
 | |
|           opt_on_update_cols
 | |
|           ON
 | |
|           remember_name /* $9 */
 | |
|           { /* $10 */
 | |
|             Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start();
 | |
|           }
 | |
|           table_ident /* $11 */
 | |
|           FOR_SYM
 | |
|           remember_name /* $13 */
 | |
|           { /* $14 */
 | |
|             Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
 | |
|           }
 | |
|           EACH_SYM
 | |
|           ROW_SYM
 | |
|           {
 | |
|             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;
 | |
| 
 | |
|             if (unlikely(lex->sphead))
 | |
|               my_yyabort_error((ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER"));
 | |
| 
 | |
|             lex->stmt_definition_begin= $1;
 | |
|             lex->ident.str= $9;
 | |
|             lex->ident.length= $13 - $9;
 | |
|             lex->spname= $4;
 | |
|             (*static_cast<st_trg_execution_order*>(&lex->trg_chistics))= ($18);
 | |
|             lex->trg_chistics.ordering_clause_end= lip->get_cpp_ptr();
 | |
| 
 | |
|             if (unlikely(!lex->make_sp_head(thd, $4, &sp_handler_trigger,
 | |
|                                             DEFAULT_AGGREGATE)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_proc_stmt /* $20 */ force_lookahead /* $21 */
 | |
|           { /* $22 */
 | |
|             LEX *lex= Lex;
 | |
| 
 | |
|             lex->sql_command= SQLCOM_CREATE_TRIGGER;
 | |
|             if (lex->sp_body_finalize_trigger(thd))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             /*
 | |
|               We have to do it after parsing trigger body, because some of
 | |
|               sp_proc_stmt alternatives are not saving/restoring LEX, so
 | |
|               lex->query_tables can be wiped out.
 | |
|             */
 | |
|             if (!lex->first_select_lex()->
 | |
|                  add_table_to_list(thd, $11, (LEX_CSTRING*) 0,
 | |
|                                    TL_OPTION_UPDATING, TL_READ_NO_INSERT,
 | |
|                                    MDL_SHARED_NO_WRITE))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /**************************************************************************
 | |
| 
 | |
|  CREATE FUNCTION | PROCEDURE statements parts.
 | |
| 
 | |
| **************************************************************************/
 | |
| 
 | |
| 
 | |
| create_package_chistic:
 | |
|           COMMENT_SYM TEXT_STRING_sys
 | |
|           { Lex->sp_chistics.comment= $2; }
 | |
|         | sp_suid
 | |
|           { Lex->sp_chistics.suid= $1; }
 | |
|         ;
 | |
| 
 | |
| create_package_chistics:
 | |
|           create_package_chistic {}
 | |
|         | create_package_chistics create_package_chistic { }
 | |
|         ;
 | |
| 
 | |
| opt_create_package_chistics:
 | |
|           /*empty*/ { }
 | |
|         | create_package_chistics { }
 | |
|         ;
 | |
| 
 | |
| opt_create_package_chistics_init:
 | |
|           { Lex->sp_chistics.init(); }
 | |
|           opt_create_package_chistics
 | |
|         ;
 | |
| 
 | |
| /*************************************************************************/
 | |
| 
 | |
| xa:
 | |
|           XA_SYM begin_or_start xid opt_join_or_resume
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_START;
 | |
|           }
 | |
|         | XA_SYM END xid opt_suspend
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_END;
 | |
|           }
 | |
|         | XA_SYM PREPARE_SYM xid
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_PREPARE;
 | |
|           }
 | |
|         | XA_SYM COMMIT_SYM xid opt_one_phase
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_COMMIT;
 | |
|           }
 | |
|         | XA_SYM ROLLBACK_SYM xid
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_ROLLBACK;
 | |
|           }
 | |
|         | XA_SYM RECOVER_SYM opt_format_xid
 | |
|           {
 | |
|             Lex->sql_command = SQLCOM_XA_RECOVER;
 | |
|             Lex->verbose= $3;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_format_xid:
 | |
|          /* empty */ { $$= false; }
 | |
|         | FORMAT_SYM '=' ident_or_text
 | |
|           {
 | |
|             if (lex_string_eq(&$3, STRING_WITH_LEN("SQL")))
 | |
|               $$= true;
 | |
|             else if (lex_string_eq(&$3, STRING_WITH_LEN("RAW")))
 | |
|               $$= false;
 | |
|             else
 | |
|             {
 | |
|               my_yyabort_error((ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0),
 | |
|                                "XA RECOVER", $3.str));
 | |
|               $$= false;
 | |
|             }
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| xid:
 | |
|           text_string
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
 | |
|             if (unlikely(!(Lex->xid= new(thd) XID())))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
 | |
|           }
 | |
|           | text_string ',' text_string
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
 | |
|             if (unlikely(!(Lex->xid= new(thd) XID())))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
 | |
|           }
 | |
|           | text_string ',' text_string ',' ulong_num
 | |
|           {
 | |
|             MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE &&
 | |
|                                  $3->length() <= MAXBQUALSIZE &&
 | |
|                                  $5 <= static_cast<ulong>(
 | |
|                                          std::numeric_limits<int32_t>::max()));
 | |
|             if (unlikely(!(Lex->xid= new(thd) XID())))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| begin_or_start:
 | |
|           BEGIN_MARIADB_SYM {}
 | |
|         | BEGIN_ORACLE_SYM {}
 | |
|         | START_SYM {}
 | |
|         ;
 | |
| 
 | |
| opt_join_or_resume:
 | |
|           /* nothing */ { Lex->xa_opt=XA_NONE;        }
 | |
|         | JOIN_SYM      { Lex->xa_opt=XA_JOIN;        }
 | |
|         | RESUME_SYM    { Lex->xa_opt=XA_RESUME;      }
 | |
|         ;
 | |
| 
 | |
| opt_one_phase:
 | |
|           /* nothing */     { Lex->xa_opt=XA_NONE;        }
 | |
|         | ONE_SYM PHASE_SYM { Lex->xa_opt=XA_ONE_PHASE;   }
 | |
|         ;
 | |
| 
 | |
| opt_suspend:
 | |
|           /* nothing */
 | |
|           { Lex->xa_opt=XA_NONE;        }
 | |
|         | SUSPEND_SYM
 | |
|           { Lex->xa_opt=XA_SUSPEND;     }
 | |
|           opt_migrate
 | |
|         ;
 | |
| 
 | |
| opt_migrate:
 | |
|           /* nothing */       {}
 | |
|         | FOR_SYM MIGRATE_SYM { Lex->xa_opt=XA_FOR_MIGRATE; }
 | |
|         ;
 | |
| 
 | |
| install:
 | |
|           INSTALL_SYM PLUGIN_SYM opt_if_not_exists ident SONAME_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             if (Lex->stmt_install_plugin($3, $4, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | INSTALL_SYM SONAME_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             Lex->stmt_install_plugin($3);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| uninstall:
 | |
|           UNINSTALL_SYM PLUGIN_SYM opt_if_exists ident
 | |
|           {
 | |
|             if (Lex->stmt_uninstall_plugin_by_name($3, $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | UNINSTALL_SYM SONAME_SYM opt_if_exists TEXT_STRING_sys
 | |
|           {
 | |
|             if (Lex->stmt_uninstall_plugin_by_soname($3, $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| /* Avoid compiler warning from yy_*.cc where yyerrlab1 is not used */
 | |
| keep_gcc_happy:
 | |
|           IMPOSSIBLE_ACTION
 | |
|           {
 | |
|             YYERROR;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| _empty:
 | |
|           /* Empty */
 | |
|         ;
 | |
| 
 | |
| %ifdef MARIADB
 | |
| 
 | |
| 
 | |
| statement:
 | |
|           verb_clause
 | |
|         ;
 | |
| 
 | |
| sp_statement:
 | |
|           statement
 | |
|         ;
 | |
| 
 | |
| sp_if_then_statements:
 | |
|           sp_proc_stmts1
 | |
|         ;
 | |
| 
 | |
| sp_case_then_statements:
 | |
|           sp_proc_stmts1
 | |
|         ;
 | |
| 
 | |
| sp_tail_is:
 | |
|           /*empty*/ { }
 | |
|         ;
 | |
| 
 | |
| sp_package_function_body:
 | |
|           sp_proc_stmt_in_returns_clause
 | |
|         ;
 | |
| 
 | |
| sp_package_procedure_body:
 | |
|           sp_proc_stmt
 | |
|         ;
 | |
| 
 | |
| opt_trailing_sp_name:
 | |
|           /*empty*/ { $$= NULL; }
 | |
|         ;
 | |
| 
 | |
| opt_package_routine_end_name:
 | |
|           /*empty*/       { $$= null_clex_str; }
 | |
|         | FORCE_LOOKAHEAD { $$= null_clex_str; }
 | |
|         ;
 | |
| 
 | |
| sf_parameters:
 | |
|           sp_parenthesized_fdparam_list
 | |
|         ;
 | |
| 
 | |
| sp_parameters:
 | |
|           sp_parenthesized_pdparam_list
 | |
|         ;
 | |
| 
 | |
| sf_returned_type_clause:
 | |
|           RETURNS_SYM
 | |
|           {
 | |
|             Lex->init_last_field(&Lex->sphead->m_return_field_def,
 | |
|                                  &empty_clex_str);
 | |
|           }
 | |
|           sf_return_type
 | |
|         ;
 | |
| 
 | |
| sf_return_type:
 | |
|           field_type
 | |
|           {
 | |
|             if (unlikely(Lex->sf_return_fill_definition($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROW_SYM row_type_body
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_row($2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROW_SYM TYPE_SYM OF_SYM ident
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_rowtype_of(
 | |
|                        Qualified_column_ident(&$4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROW_SYM TYPE_SYM OF_SYM ident '.' ident
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_rowtype_of(
 | |
|                        Qualified_column_ident(&$4, &$6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TYPE_SYM OF_SYM ident '.' ident
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_type_of(
 | |
|                        Qualified_column_ident(&$3, &$5)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | TYPE_SYM OF_SYM ident '.' ident '.' ident
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_type_of(
 | |
|                        Qualified_column_ident(thd, &$3, &$5, &$7)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| package_implementation_item_declaration:
 | |
|           DECLARE_MARIADB_SYM sp_decl_variable_list ';' { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| //  Inside CREATE PACKAGE BODY, package-wide items (e.g. variables)
 | |
| //  must be declared before routine definitions.
 | |
| 
 | |
| package_implementation_declare_section_list:
 | |
|           package_implementation_declare_section_list1 %prec PREC_BELOW_SP_OBJECT_TYPE
 | |
|         | package_implementation_declare_section_list2 %prec PREC_BELOW_SP_OBJECT_TYPE
 | |
|         | package_implementation_declare_section_list1
 | |
|           package_implementation_declare_section_list2 %prec PREC_BELOW_SP_OBJECT_TYPE
 | |
|           { $$.join($1, $2); }
 | |
|         ;
 | |
| 
 | |
| package_implementation_declare_section:
 | |
|           package_implementation_declare_section_list
 | |
|         ;
 | |
| 
 | |
| package_implementation_executable_section:
 | |
|           sp_proc_stmts END
 | |
|           {
 | |
|             $$.init(0);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| reserved_keyword_udt_param_type:
 | |
|           INOUT_SYM
 | |
|         | IN_SYM
 | |
|         | OUT_SYM
 | |
|         ;
 | |
| 
 | |
| reserved_keyword_udt:
 | |
|           reserved_keyword_udt_not_param_type
 | |
|         | reserved_keyword_udt_param_type
 | |
|         ;
 | |
| 
 | |
| // Keywords that start an SP block section
 | |
| keyword_sp_block_section:
 | |
|           BEGIN_MARIADB_SYM
 | |
|         | END
 | |
|         ;
 | |
| 
 | |
| // Keywords that we allow for labels in SPs.
 | |
| // Should not include keywords that start a statement or SP characteristics.
 | |
| keyword_label:
 | |
|           keyword_data_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sysvar_type
 | |
|         | FUNCTION_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
|         ;
 | |
| 
 | |
| keyword_sp_decl:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_block_section
 | |
|         | keyword_sp_head
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_verb_clause
 | |
|         | FUNCTION_SYM
 | |
|         | WINDOW_SYM
 | |
|         | IGNORED_SYM
 | |
|         ;
 | |
| 
 | |
| opt_truncate_table_storage_clause:
 | |
|           _empty
 | |
|         ;
 | |
| 
 | |
| 
 | |
| ident_for_loop_index:
 | |
|           ident
 | |
|         ;
 | |
| 
 | |
| row_field_name:
 | |
|           ident
 | |
|           {
 | |
|             if (!($$= Lex->row_field_name(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| while_body:
 | |
|           expr_lex DO_SYM
 | |
|           {
 | |
|             if (unlikely($1->sp_while_loop_expression(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_proc_stmts1 END WHILE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_while_loop_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| for_loop_statements:
 | |
|           DO_SYM sp_proc_stmts1 END FOR_SYM
 | |
|           { }
 | |
|         ;
 | |
| 
 | |
| sp_label:
 | |
|           label_ident ':' { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| sp_control_label:
 | |
|           sp_label
 | |
|         ;
 | |
| 
 | |
| sp_block_label:
 | |
|           sp_label
 | |
|           {
 | |
|             if (unlikely(Lex->spcont->block_label_declare(&$1)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_opt_default:
 | |
|           _empty       { $$= { nullptr, empty_clex_str}; }
 | |
|         | DEFAULT remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             LEX_CSTRING expr_str= empty_clex_str;
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               expr_str= make_string(thd, $2, $4);
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             $$= { $3, expr_str };
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_decl_variable_list_anchored:
 | |
|           sp_decl_idents_init_vars
 | |
|           TYPE_SYM OF_SYM optionally_qualified_column_ident
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(
 | |
|                            thd, $1, $4, $5.expr, $5.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         | sp_decl_idents_init_vars
 | |
|           ROW_SYM TYPE_SYM OF_SYM optionally_qualified_column_ident
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(
 | |
|                            thd, $1, $5, $6.expr, $6.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param_name_and_mode:
 | |
|           sp_parameter_type sp_param_name
 | |
|           {
 | |
|             $2->mode= $1;
 | |
|             $$= $2;
 | |
|           }
 | |
|         | sp_param_name
 | |
|         ;
 | |
| 
 | |
| sp_param_init_vars:
 | |
|           sp_param_name_and_mode_init_vars field_type
 | |
|           {
 | |
|             if (unlikely(Lex->sp_param_fill_definition($$= $1, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars ROW_SYM row_type_body
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_anchored
 | |
|         ;
 | |
| 
 | |
| sp_param_anchored:
 | |
|           sp_param_name_and_mode_init_vars TYPE_SYM OF_SYM ident '.' ident
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_type_reference(thd,
 | |
|                                                                 $$= $1, $4,
 | |
|                                                                 $6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars TYPE_SYM OF_SYM ident '.' ident '.' ident
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1,
 | |
|                                                                 $4, $6, $8)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars ROW_SYM TYPE_SYM OF_SYM ident
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars ROW_SYM TYPE_SYM OF_SYM ident '.' ident
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $5, $7)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sf_c_chistics_and_body_standalone:
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->sphead->set_c_chistics(lex->sp_chistics);
 | |
|             lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_proc_stmt_in_returns_clause force_lookahead
 | |
|           {
 | |
|             if (unlikely(Lex->sp_body_finalize_function(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_tail_standalone:
 | |
|           sp_name
 | |
|           {
 | |
|             if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
 | |
|                                                          &sp_handler_procedure,
 | |
|                                                          DEFAULT_AGGREGATE)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_parenthesized_pdparam_list
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             Lex->sphead->set_c_chistics(Lex->sp_chistics);
 | |
|             Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_proc_stmt force_lookahead
 | |
|           {
 | |
|             if (unlikely(Lex->sp_body_finalize_procedure(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_decls:
 | |
|           _empty
 | |
|           {
 | |
|             $$.init();
 | |
|           }
 | |
|         | sp_decls sp_decl ';'
 | |
|           {
 | |
|             // We check for declarations out of (standard) order this way
 | |
|             // because letting the grammar rules reflect it caused tricky
 | |
|             //  shift/reduce conflicts with the wrong result. (And we get
 | |
|             //  better error handling this way.)
 | |
|             if (unlikely(Lex->sp_declarations_join(&$$, $1, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_decl:
 | |
|           DECLARE_MARIADB_SYM sp_decl_body { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_decl_body:
 | |
|           sp_decl_variable_list
 | |
|         | sp_decl_ident CONDITION_SYM FOR_SYM sp_cond
 | |
|           {
 | |
|             if (unlikely(Lex->spcont->declare_condition(thd,
 | |
|                                                         Lex_ident_column($1),
 | |
|                                                         $4)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.hndlrs= $$.curs= 0;
 | |
|             $$.conds= 1;
 | |
|           }
 | |
|         | sp_decl_handler
 | |
|         | sp_decl_ident CURSOR_SYM
 | |
|           {
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           opt_parenthesized_cursor_formal_parameters
 | |
|           FOR_SYM sp_cursor_stmt
 | |
|           {
 | |
|             sp_pcontext *param_ctx= Lex->spcont;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Lex->sp_declare_cursor(thd, &$1, $6, param_ctx, true)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.conds= $$.hndlrs= 0;
 | |
|             $$.curs= 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| 
 | |
| //  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_continue_oracle
 | |
|         | sp_proc_stmt_exit_oracle
 | |
|         | sp_proc_stmt_leave
 | |
|         | sp_proc_stmt_iterate
 | |
|         | sp_proc_stmt_goto_oracle
 | |
|         | sp_proc_stmt_with_cursor
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_compound_ok:
 | |
|           sp_proc_stmt_if
 | |
|         | case_stmt_specification
 | |
|         | sp_unlabeled_block_not_atomic
 | |
|         | sp_unlabeled_control
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_labeled_block:
 | |
|           sp_block_label
 | |
|           BEGIN_MARIADB_SYM
 | |
|           {
 | |
|             Lex->sp_block_init(thd, &$1);
 | |
|           }
 | |
|           sp_decls
 | |
|           sp_proc_stmts
 | |
|           END
 | |
|           sp_opt_label
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $4, &$7)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_unlabeled_block:
 | |
|           BEGIN_MARIADB_SYM
 | |
|           {
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           sp_decls
 | |
|           sp_proc_stmts
 | |
|           END
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_unlabeled_block_not_atomic:
 | |
|           BEGIN_MARIADB_SYM not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
 | |
|           {
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           sp_decls
 | |
|           sp_proc_stmts
 | |
|           END
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $5)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| %endif MARIADB
 | |
| 
 | |
| 
 | |
| %ifdef ORACLE
 | |
| 
 | |
| statement:
 | |
|           verb_clause
 | |
|         | set_assign
 | |
|         ;
 | |
| 
 | |
| sp_statement:
 | |
|           statement
 | |
|         | ident_cli_directly_assignable
 | |
|           {
 | |
|             // Direct procedure call (without the CALL keyword)
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->call_statement_start(thd, &tmp)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli_directly_assignable '.' ident
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->call_statement_start(thd, &tmp, &$3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli_directly_assignable '.' ident '.' ident
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
|             if (unlikely(Lex->call_statement_start(thd, &tmp, &$3, &$5)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_cparam_list
 | |
|           {
 | |
|             if (Lex->check_cte_dependencies_and_resolve_references())
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_if_then_statements:
 | |
|           sp_proc_stmts1_implicit_block { }
 | |
|         ;
 | |
| 
 | |
| sp_case_then_statements:
 | |
|           sp_proc_stmts1_implicit_block { }
 | |
|         ;
 | |
| 
 | |
| sp_parameters:
 | |
|           opt_sp_parenthesized_pdparam_list
 | |
|         ;
 | |
| 
 | |
| sf_parameters:
 | |
|           opt_sp_parenthesized_fdparam_list
 | |
|         ;
 | |
| 
 | |
| sf_returned_type_clause:
 | |
|           RETURN_ORACLE_SYM
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             lex->init_last_field(&lex->sphead->m_return_field_def,
 | |
|                                  &empty_clex_str);
 | |
|           }
 | |
|           sf_return_type
 | |
|         ;
 | |
| 
 | |
| sf_return_type:
 | |
|           field_type
 | |
|           {
 | |
|             if (unlikely(Lex->sf_return_fill_definition($1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ROW_SYM row_type_body
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_row($2))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_rowtype_of(
 | |
|                        Qualified_column_ident(&$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_rowtype_of(
 | |
|                        Qualified_column_ident(&$1, &$3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_type_of(
 | |
|                        Qualified_column_ident(&$1, &$3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (Lex->sf_return_fill_definition_type_of(
 | |
|                        Qualified_column_ident(thd, &$1, &$3, &$5)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| package_implementation_item_declaration:
 | |
|           sp_decl_variable_list ';'
 | |
|         ;
 | |
| 
 | |
| sp_package_function_body:
 | |
|           sp_body { }
 | |
|         ;
 | |
| 
 | |
| sp_package_procedure_body:
 | |
|           sp_body { }
 | |
|         ;
 | |
| 
 | |
| reserved_keyword_udt:
 | |
|           reserved_keyword_udt_not_param_type
 | |
|         ;
 | |
| 
 | |
| // Keywords that start an SP block section.
 | |
| keyword_sp_block_section:
 | |
|           BEGIN_ORACLE_SYM
 | |
|         | END
 | |
|         ;
 | |
| 
 | |
| // Keywords that we allow for labels in SPs.
 | |
| // Should not include keywords that start a statement or SP characteristics.
 | |
| keyword_label:
 | |
|           keyword_data_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sysvar_type
 | |
|         | FUNCTION_SYM
 | |
|         | COMPRESSED_SYM
 | |
|         | EXCEPTION_ORACLE_SYM
 | |
|         | IGNORED_SYM
 | |
|         ;
 | |
| 
 | |
| keyword_sp_decl:
 | |
|           keyword_sp_head
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | keyword_verb_clause
 | |
|         | WINDOW_SYM
 | |
|         | IGNORED_SYM
 | |
|         ;
 | |
| 
 | |
| opt_truncate_table_storage_clause:
 | |
|           _empty
 | |
|         | DROP STORAGE_SYM
 | |
|         | REUSE_SYM STORAGE_SYM
 | |
|         ;
 | |
| 
 | |
| 
 | |
| ident_for_loop_index:
 | |
|           ident_directly_assignable
 | |
|         ;
 | |
| 
 | |
| row_field_name:
 | |
|           ident_directly_assignable
 | |
|           {
 | |
|             if (!($$= Lex->row_field_name(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| while_body:
 | |
|           expr_lex LOOP_SYM
 | |
|           {
 | |
|             if (unlikely($1->sp_while_loop_expression(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_proc_stmts1 END LOOP_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_while_loop_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| for_loop_statements:
 | |
|           LOOP_SYM sp_proc_stmts1 END LOOP_SYM
 | |
|           { }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_control_label:
 | |
|           labels_declaration_oracle
 | |
|         ;
 | |
| 
 | |
| sp_block_label:
 | |
|           labels_declaration_oracle
 | |
|           {
 | |
|             if (unlikely(Lex->spcont->block_label_declare(&$1)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_opt_default:
 | |
|           _empty       { $$= { nullptr, empty_clex_str}; }
 | |
|         | DEFAULT remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             LEX_CSTRING expr_str= empty_clex_str;
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               expr_str= make_string(thd, $2, $4);
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             $$= { $3, expr_str };
 | |
|           }
 | |
|         | SET_VAR remember_cpp_ptr expr remember_end
 | |
|           {
 | |
|             LEX_CSTRING expr_str= empty_clex_str;
 | |
| 
 | |
|             if (Lex->is_metadata_used())
 | |
|             {
 | |
|               expr_str= make_string(thd, $2, $4 );
 | |
|               if (expr_str.str == nullptr)
 | |
|                 MYSQL_YYABORT;
 | |
|             }
 | |
| 
 | |
|             $$= { $3, expr_str };
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_opt_nocopy:
 | |
|           _empty
 | |
|         | NOCOPY_SYM
 | |
|         ;
 | |
| 
 | |
| sp_opt_inout:
 | |
|           _empty         { $$= sp_variable::MODE_IN; }
 | |
|         | sp_parameter_type
 | |
|         | IN_SYM OUT_SYM { $$= sp_variable::MODE_INOUT; }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmts1_implicit_block:
 | |
|           {
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           sp_proc_stmts1
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| keyword_directly_assignable:
 | |
|           keyword_data_type
 | |
|         | keyword_cast_type
 | |
|         | keyword_set_special_case
 | |
|         | keyword_sp_var_and_label
 | |
|         | keyword_sp_var_not_label
 | |
|         | keyword_sysvar_type
 | |
|         | FUNCTION_SYM
 | |
|         | WINDOW_SYM
 | |
|         ;
 | |
| 
 | |
| ident_directly_assignable:
 | |
|           IDENT_sys
 | |
|         | keyword_directly_assignable
 | |
|           {
 | |
|             if (unlikely($$.copy_keyword(thd, &$1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| ident_cli_directly_assignable:
 | |
|           IDENT_cli
 | |
|         | keyword_directly_assignable { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| set_assign:
 | |
|           ident_cli_directly_assignable SET_VAR
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->set_stmt_init();
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
| 
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(Lex->set_variable(&tmp, $4.expr, $4.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
 | |
|                                                     false)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | ident_cli_directly_assignable '.' ident SET_VAR
 | |
|           {
 | |
|             LEX *lex=Lex;
 | |
|             lex->set_stmt_init();
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             DBUG_ASSERT(lex->var_list.is_empty());
 | |
|             Lex_ident_sys tmp(thd, &$1);
 | |
| 
 | |
|             if (unlikely(!tmp.str) ||
 | |
|                 unlikely(lex->set_variable(&tmp, &$3, $6.expr, $6.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
 | |
|                                                     false)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | COLON_ORACLE_SYM ident '.' ident SET_VAR
 | |
|           {
 | |
|             LEX *lex= Lex;
 | |
|             if (unlikely(!lex->is_trigger_new_or_old_reference(&$2)))
 | |
|             {
 | |
|               thd->parse_error(ER_SYNTAX_ERROR, $1.pos());
 | |
|               MYSQL_YYABORT;
 | |
|             }
 | |
|             lex->set_stmt_init();
 | |
|             if (sp_create_assignment_lex(thd, $1.pos()))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           set_expr_or_default
 | |
|           {
 | |
|             LEX_CSTRING tmp= { $2.str, $2.length };
 | |
|             if (unlikely(Lex->set_trigger_field(&tmp, &$4, $7.expr,
 | |
|                                                 $7.expr_str)) ||
 | |
|                 unlikely(sp_create_assignment_instr(thd, yychar == YYEMPTY,
 | |
|                                                     false)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| labels_declaration_oracle:
 | |
|           label_declaration_oracle { $$= $1; }
 | |
|         | labels_declaration_oracle label_declaration_oracle { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| label_declaration_oracle:
 | |
|           SHIFT_LEFT label_ident SHIFT_RIGHT
 | |
|           {
 | |
|             if (unlikely(Lex->sp_push_goto_label(thd, &$2)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_exception_clause:
 | |
|           _empty                                  { $$= 0; }
 | |
|         | EXCEPTION_ORACLE_SYM exception_handlers { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| exception_handlers:
 | |
|            exception_handler                    { $$= 1; }
 | |
|          | exception_handlers exception_handler { $$= $1 + 1; }
 | |
|         ;
 | |
| 
 | |
| exception_handler:
 | |
|           WHEN_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sp_handler_declaration_init(thd, sp_handler::EXIT)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_hcond_list
 | |
|           THEN_SYM
 | |
|           sp_proc_stmts1_implicit_block
 | |
|           {
 | |
|             if (unlikely(Lex->sp_handler_declaration_finalize(thd, sp_handler::EXIT)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_no_param:
 | |
|           _empty
 | |
|           {
 | |
|             Lex->sphead->m_param_begin= Lex->sphead->m_param_end=
 | |
|               YYLIP->get_cpp_tok_start() + 1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_sp_parenthesized_fdparam_list:
 | |
|           sp_no_param
 | |
|         | sp_parenthesized_fdparam_list
 | |
|         ;
 | |
| 
 | |
| opt_sp_parenthesized_pdparam_list:
 | |
|           sp_no_param
 | |
|         | sp_parenthesized_pdparam_list
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_trailing_sp_name:
 | |
|           _empty      { $$= NULL; }
 | |
|         | sp_name     { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_package_routine_end_name:
 | |
|           _empty      { $$= null_clex_str; }
 | |
|         | ident       { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| sp_tail_is:
 | |
|           IS
 | |
|         | AS
 | |
|         ;
 | |
| 
 | |
| sp_instr_addr:
 | |
|           { $$= Lex->sphead->instructions(); }
 | |
|         ;
 | |
| 
 | |
| sp_body:
 | |
|           {
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           opt_sp_decl_body_list
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           BEGIN_ORACLE_SYM
 | |
|           sp_block_statements_and_exceptions
 | |
|           {
 | |
|             $2.hndlrs+= $5.hndlrs;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           END
 | |
|         ;
 | |
| 
 | |
| //  Inside CREATE PACKAGE BODY, package-wide items (e.g. variables)
 | |
| //  must be declared before routine definitions.
 | |
| 
 | |
| package_implementation_declare_section_list:
 | |
|           package_implementation_declare_section_list1
 | |
|         | package_implementation_declare_section_list2
 | |
|         | package_implementation_declare_section_list1
 | |
|           package_implementation_declare_section_list2
 | |
|           { $$.join($1, $2); }
 | |
|         ;
 | |
| 
 | |
| package_implementation_declare_section:
 | |
|           package_implementation_declare_section_list
 | |
|           {
 | |
|             /*
 | |
|               Add a jump "end of declarations -> start of exceptions"
 | |
|               (over the executable sectition).
 | |
|             */
 | |
|             if (Lex->sp_block_with_exceptions_finalize_declarations(thd))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| package_implementation_executable_section:
 | |
|           END
 | |
|           {
 | |
|             /*
 | |
|               Backpatch the jump generated in
 | |
|               package_implementation_declare_section
 | |
|               and generate a backward jump:
 | |
|               "end of exceptions -> start of the executable section".
 | |
|             */
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_add_empty(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init(0);
 | |
|           }
 | |
|         | BEGIN_ORACLE_SYM sp_block_statements_and_exceptions END { $$= $2; }
 | |
|         ;
 | |
| 
 | |
| %endif ORACLE
 | |
| 
 | |
| 
 | |
| package_implementation_declare_section_list1:
 | |
|           package_implementation_item_declaration
 | |
|         | package_implementation_declare_section_list1
 | |
|           package_implementation_item_declaration
 | |
|           { $$.join($1, $2); }
 | |
|         ;
 | |
| 
 | |
| package_implementation_declare_section_list2:
 | |
|           package_implementation_routine_definition
 | |
|         | package_implementation_declare_section_list2
 | |
|           package_implementation_routine_definition
 | |
|           { $$.join($1, $2); }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| package_specification_function:
 | |
|           remember_lex ident
 | |
|           {
 | |
|             LEX *lex= thd->lex->package_routine_start(thd,
 | |
|                                    &sp_handler_package_function, $2);
 | |
|             if (!lex)
 | |
|               MYSQL_YYABORT;
 | |
|             thd->lex= lex;
 | |
|           }
 | |
|           sf_parameters
 | |
|           sf_returned_type_clause
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             $$= thd->lex;
 | |
|             sp_head *sp= thd->lex->sphead;
 | |
|             sp->restore_thd_mem_root(thd);
 | |
|             thd->lex= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| package_specification_procedure:
 | |
|           remember_lex ident
 | |
|           {
 | |
|             LEX *lex= thd->lex->package_routine_start(thd,
 | |
|                                    &sp_handler_package_procedure, $2);
 | |
|             if (!lex)
 | |
|               MYSQL_YYABORT;
 | |
|             thd->lex= lex;
 | |
|           }
 | |
|           sp_parameters
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             $$= thd->lex;
 | |
|             sp_head *sp= thd->lex->sphead;
 | |
|             sp->restore_thd_mem_root(thd);
 | |
|             thd->lex= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| package_implementation_routine_definition:
 | |
|           FUNCTION_SYM package_specification_function
 | |
|                        package_implementation_function_body   ';'
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             if (unlikely(pkg->add_routine_implementation($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             pkg->m_current_routine= NULL;
 | |
|             $$.init();
 | |
|           }
 | |
|         | PROCEDURE_SYM package_specification_procedure
 | |
|                         package_implementation_procedure_body ';'
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             if (unlikely(pkg->add_routine_implementation($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             pkg->m_current_routine= NULL;
 | |
|             $$.init();
 | |
|           }
 | |
|         | package_specification_element { $$.init(); }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| package_implementation_function_body:
 | |
|           sp_tail_is remember_lex
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             sp_head *sp= pkg->m_current_routine->sphead;
 | |
|             thd->lex= pkg->m_current_routine;
 | |
|             sp->reset_thd_mem_root(thd);
 | |
|             sp->set_c_chistics(thd->lex->sp_chistics);
 | |
|             sp->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_package_function_body opt_package_routine_end_name
 | |
|           {
 | |
|             if (unlikely(thd->lex->sp_body_finalize_function(thd) ||
 | |
|                          thd->lex->sphead->check_package_routine_end_name($5)))
 | |
|               MYSQL_YYABORT;
 | |
|             thd->lex= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| package_implementation_procedure_body:
 | |
|           sp_tail_is remember_lex
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             sp_head *sp= pkg->m_current_routine->sphead;
 | |
|             thd->lex= pkg->m_current_routine;
 | |
|             sp->reset_thd_mem_root(thd);
 | |
|             sp->set_c_chistics(thd->lex->sp_chistics);
 | |
|             sp->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_package_procedure_body opt_package_routine_end_name
 | |
|           {
 | |
|             if (unlikely(thd->lex->sp_body_finalize_procedure(thd) ||
 | |
|                          thd->lex->sphead->check_package_routine_end_name($5)))
 | |
|               MYSQL_YYABORT;
 | |
|             thd->lex= $2;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| opt_package_specification_element_list:
 | |
|           _empty
 | |
|         | package_specification_element_list
 | |
|         ;
 | |
| 
 | |
| package_specification_element_list:
 | |
|           package_specification_element
 | |
|         | package_specification_element_list package_specification_element
 | |
|         ;
 | |
| 
 | |
| package_specification_element:
 | |
|           FUNCTION_SYM package_specification_function ';'
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             if (unlikely(pkg->add_routine_declaration($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             pkg->m_current_routine= NULL;
 | |
|           }
 | |
|         | PROCEDURE_SYM package_specification_procedure ';'
 | |
|           {
 | |
|             sp_package *pkg= Lex->get_sp_package();
 | |
|             if (unlikely(pkg->add_routine_declaration($2)))
 | |
|               MYSQL_YYABORT;
 | |
|             pkg->m_current_routine= NULL;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| %ifdef ORACLE
 | |
| 
 | |
| sp_decl_variable_list_anchored:
 | |
|           sp_decl_idents_init_vars
 | |
|           optionally_qualified_column_ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_with_ref_finalize(thd, $1, $2,
 | |
|                            $5.expr, $5.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         | sp_decl_idents_init_vars
 | |
|           optionally_qualified_column_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
 | |
|           sp_opt_default
 | |
|           {
 | |
|             if (unlikely(Lex->sp_variable_declarations_rowtype_finalize(thd, $1,
 | |
| 			   $2, $5.expr, $5.expr_str)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init_using_vars($1);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param_name_and_mode:
 | |
|           sp_param_name sp_opt_inout sp_opt_nocopy
 | |
|           {
 | |
|              $1->mode= $2;
 | |
|              $$= $1;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_param_init_vars:
 | |
|           sp_param_name_and_mode_init_vars field_type
 | |
|           {
 | |
|             if (unlikely(Lex->sp_param_fill_definition($$= $1, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars ROW_SYM row_type_body
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_row(thd, $$= $1, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_anchored
 | |
|         ;
 | |
| 
 | |
| sp_param_anchored:
 | |
|           sp_param_name_and_mode_init_vars sp_decl_ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars sp_decl_ident '.' ident '.' ident PERCENT_ORACLE_SYM TYPE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_type_reference(thd, $$= $1, $2, $4, $6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars sp_decl_ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_param_name_and_mode_init_vars sp_decl_ident '.' ident PERCENT_ORACLE_SYM ROWTYPE_ORACLE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->spvar_fill_table_rowtype_reference(thd, $$= $1, $2, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sf_c_chistics_and_body_standalone:
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             LEX *lex= thd->lex;
 | |
|             lex->sphead->set_c_chistics(lex->sp_chistics);
 | |
|             lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_tail_is sp_body force_lookahead
 | |
|           {
 | |
|             if (unlikely(Lex->sp_body_finalize_function(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_tail_standalone:
 | |
|           sp_name
 | |
|           {
 | |
|             if (unlikely(!Lex->make_sp_head_no_recursive(thd, $1,
 | |
|                                                          &sp_handler_procedure,
 | |
|                                                          DEFAULT_AGGREGATE)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_parenthesized_pdparam_list
 | |
|           sp_c_chistics
 | |
|           {
 | |
|             Lex->sphead->set_c_chistics(Lex->sp_chistics);
 | |
|             Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_tail_is
 | |
|           sp_body
 | |
|           opt_trailing_sp_name
 | |
|           {
 | |
|             if (unlikely(Lex->sp_body_finalize_procedure_standalone(thd, $8)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| %endif ORACLE
 | |
| 
 | |
| 
 | |
| create_routine:
 | |
|           create_or_replace definer_opt PROCEDURE_SYM opt_if_not_exists
 | |
|           {
 | |
|             if (Lex->stmt_create_procedure_start($1 | $4))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_tail_standalone
 | |
|           {
 | |
|             Lex->stmt_create_routine_finalize();
 | |
|           }
 | |
|         | create_or_replace definer opt_aggregate FUNCTION_SYM opt_if_not_exists
 | |
|           sp_name
 | |
|           {
 | |
|             if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sf_parameters
 | |
|           sf_returned_type_clause
 | |
|           sf_c_chistics_and_body_standalone
 | |
|           opt_trailing_sp_name
 | |
|           {
 | |
|             if (Lex->stmt_create_stored_function_finalize_standalone($11))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
 | |
|           sp_name
 | |
|           {
 | |
|             if (Lex->stmt_create_stored_function_start($1 | $5, $3, $6))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sf_parameters
 | |
|           sf_returned_type_clause
 | |
|           sf_c_chistics_and_body_standalone
 | |
|           opt_trailing_sp_name
 | |
|           {
 | |
|             if (Lex->stmt_create_stored_function_finalize_standalone($11))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace no_definer opt_aggregate FUNCTION_SYM opt_if_not_exists
 | |
|           ident RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
 | |
|           {
 | |
|             if (Lex->stmt_create_udf_function($1 | $5, $3, $6,
 | |
|                                               (Item_result) $8, $10))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace definer_opt sp_handler_package_spec
 | |
|           opt_if_not_exists sp_name opt_create_package_chistics_init
 | |
|           {
 | |
|             sp_package *pkg;
 | |
|             if (unlikely(!(pkg= Lex->
 | |
|                            create_package_start(thd, &sp_handler_package_spec,
 | |
|                                                 $5, $1 | $4,
 | |
|                                                 Lex->sp_chistics))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|           }
 | |
|           sp_tail_is
 | |
|           opt_package_specification_element_list END
 | |
|           remember_end_opt opt_trailing_sp_name
 | |
|           {
 | |
|             if (unlikely(Lex->create_package_finalize(thd, $5, $12, $11)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | create_or_replace definer_opt sp_handler_package_body
 | |
|           opt_if_not_exists sp_name opt_create_package_chistics_init
 | |
|           {
 | |
|             sp_package *pkg;
 | |
|             if (unlikely(!(pkg= Lex->
 | |
|                            create_package_start(thd, &sp_handler_package_body,
 | |
|                                                 $5, $1 | $4,
 | |
|                                                 Lex->sp_chistics))))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
 | |
|             Lex->sp_block_init_package_body(thd);
 | |
|           }
 | |
|           sp_tail_is
 | |
|           package_implementation_declare_section
 | |
|           package_implementation_executable_section
 | |
|           {
 | |
|             $9.hndlrs+= $10.hndlrs;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $9)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           remember_end_opt opt_trailing_sp_name
 | |
|           {
 | |
|             if (unlikely(Lex->create_package_finalize(thd, $5, $13, $12)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| %ifdef ORACLE
 | |
| 
 | |
| opt_sp_decl_body_list:
 | |
|           _empty
 | |
|           {
 | |
|             $$.init();
 | |
|           }
 | |
|         | sp_decl_body_list { $$= $1; }
 | |
|         ;
 | |
| 
 | |
| sp_decl_body_list:
 | |
|           sp_decl_non_handler_list
 | |
|           {
 | |
|             if (unlikely(Lex->sphead->sp_add_instr_cpush_for_cursors(thd, Lex->spcont)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_sp_decl_handler_list
 | |
|           {
 | |
|             $$.join($1, $3);
 | |
|           }
 | |
|         | sp_decl_handler_list
 | |
|         ;
 | |
| 
 | |
| sp_decl_non_handler_list:
 | |
|           sp_decl_non_handler ';' { $$= $1; }
 | |
|         | sp_decl_non_handler_list sp_decl_non_handler ';'
 | |
|           {
 | |
|             $$.join($1, $2);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_decl_handler_list:
 | |
|           sp_decl_handler ';' { $$= $1; }
 | |
|         | sp_decl_handler_list sp_decl_handler ';'
 | |
|           {
 | |
|             $$.join($1, $2);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_sp_decl_handler_list:
 | |
|           _empty   { $$.init(); }
 | |
|         | sp_decl_handler_list
 | |
|         ;
 | |
| 
 | |
| sp_decl_non_handler:
 | |
|           sp_decl_variable_list
 | |
|         | ident_directly_assignable CONDITION_SYM FOR_SYM sp_cond
 | |
|           {
 | |
|             if (unlikely(Lex->spcont->declare_condition(thd,
 | |
|                                                         Lex_ident_column($1),
 | |
|                                                         $4)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.hndlrs= $$.curs= 0;
 | |
|             $$.conds= 1;
 | |
|           }
 | |
|         | ident_directly_assignable EXCEPTION_ORACLE_SYM
 | |
|           {
 | |
|             sp_condition_value *spcond= new (thd)
 | |
|                                         sp_condition_value_user_defined();
 | |
|             if (unlikely(!spcond) ||
 | |
|                 unlikely(Lex->spcont->declare_condition(thd,
 | |
|                                                         Lex_ident_column($1),
 | |
|                                                         spcond)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.hndlrs= $$.curs= 0;
 | |
|             $$.conds= 1;
 | |
|           }
 | |
|         | CURSOR_SYM ident_directly_assignable
 | |
|           {
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           opt_parenthesized_cursor_formal_parameters
 | |
|           IS sp_cursor_stmt
 | |
|           {
 | |
|             sp_pcontext *param_ctx= Lex->spcont;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             if (unlikely(Lex->sp_declare_cursor(thd, &$2, $6, param_ctx, false)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.vars= $$.conds= $$.hndlrs= 0;
 | |
|             $$.curs= 1;
 | |
|           }
 | |
|         | TYPE_SYM ident_directly_assignable IS RECORD_SYM rec_type_body
 | |
|           {
 | |
|             if (unlikely(Lex->spcont->
 | |
|                           declare_record(thd, Lex_ident_column($2), $5)))
 | |
|               MYSQL_YYABORT;
 | |
| 
 | |
|             $$.vars= $$.conds= $$.hndlrs= $$.curs= 0;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_proc_stmt:
 | |
|           sp_labeled_block
 | |
|         | sp_unlabeled_block
 | |
|         | sp_labeled_control
 | |
|         | sp_unlabeled_control
 | |
|         | sp_labelable_stmt
 | |
|         | labels_declaration_oracle sp_labelable_stmt {}
 | |
|         ;
 | |
| 
 | |
| sp_labelable_stmt:
 | |
|           sp_proc_stmt_statement
 | |
|         | sp_proc_stmt_continue_oracle
 | |
|         | sp_proc_stmt_exit_oracle
 | |
|         | sp_proc_stmt_leave
 | |
|         | sp_proc_stmt_iterate
 | |
|         | sp_proc_stmt_goto_oracle
 | |
|         | sp_proc_stmt_with_cursor
 | |
|         | sp_proc_stmt_return
 | |
|         | sp_proc_stmt_if
 | |
|         | case_stmt_specification
 | |
|         | NULL_SYM { }
 | |
|         ;
 | |
| 
 | |
| sp_proc_stmt_compound_ok:
 | |
|           sp_proc_stmt_if
 | |
|         | case_stmt_specification
 | |
|         | sp_unlabeled_block
 | |
|         | sp_unlabeled_control
 | |
|         ;
 | |
| 
 | |
| 
 | |
| sp_labeled_block:
 | |
|           sp_block_label
 | |
|           BEGIN_ORACLE_SYM
 | |
|           {
 | |
|             Lex->sp_block_init(thd, &$1);
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_block_statements_and_exceptions
 | |
|           END
 | |
|           sp_opt_label
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4), &$6)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | sp_block_label
 | |
|           DECLARE_ORACLE_SYM
 | |
|           {
 | |
|             Lex->sp_block_init(thd, &$1);
 | |
|           }
 | |
|           opt_sp_decl_body_list
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           BEGIN_ORACLE_SYM
 | |
|           sp_block_statements_and_exceptions
 | |
|           END
 | |
|           sp_opt_label
 | |
|           {
 | |
|             $4.hndlrs+= $7.hndlrs;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $4, &$9)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| opt_not_atomic:
 | |
|           _empty
 | |
|         | not ATOMIC_SYM // TODO: BEGIN ATOMIC (not -> opt_not)
 | |
|         ;
 | |
| 
 | |
| sp_unlabeled_block:
 | |
|           BEGIN_ORACLE_SYM opt_not_atomic
 | |
|           {
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sp_block_init(thd);
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           sp_block_statements_and_exceptions
 | |
|           END
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, Lex_spblock($4))))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         | DECLARE_ORACLE_SYM
 | |
|           {
 | |
|             if (unlikely(Lex->maybe_start_compound_statement(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|             Lex->sp_block_init(thd);
 | |
|           }
 | |
|           opt_sp_decl_body_list
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_declarations(thd)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           BEGIN_ORACLE_SYM
 | |
|           sp_block_statements_and_exceptions
 | |
|           END
 | |
|           {
 | |
|             $3.hndlrs+= $6.hndlrs;
 | |
|             if (unlikely(Lex->sp_block_finalize(thd, $3)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| sp_block_statements_and_exceptions:
 | |
|           sp_instr_addr
 | |
|           sp_proc_stmts
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_executable_section(thd, $1)))
 | |
|               MYSQL_YYABORT;
 | |
|           }
 | |
|           opt_exception_clause
 | |
|           {
 | |
|             if (unlikely(Lex->sp_block_with_exceptions_finalize_exceptions(thd, $1, $4)))
 | |
|               MYSQL_YYABORT;
 | |
|             $$.init($4);
 | |
|           }
 | |
|         ;
 | |
| 
 | |
| %endif ORACLE
 | |
| 
 | |
| /**
 | |
|   @} (end of group Parser)
 | |
| */
 |