1/*
2   Copyright (c) 2000, 2021, Oracle and/or its affiliates.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License, version 2.0,
6   as published by the Free Software Foundation.
7
8   This program is also distributed with certain software (including
9   but not limited to OpenSSL) that is licensed under separate terms,
10   as designated in a particular file or component or in included license
11   documentation.  The authors of MySQL hereby grant you an additional
12   permission to link the program and your derivative works with the
13   separately licensed software that they have included with MySQL.
14
15   This program is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License, version 2.0, for more details.
19
20   You should have received a copy of the GNU General Public License
21   along with this program; if not, write to the Free Software
22   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
23
24/* sql_yacc.yy */
25
26/**
27  @defgroup Parser Parser
28  @{
29*/
30
31%{
32/*
33Note: YYTHD is passed as an argument to yyparse(), and subsequently to yylex().
34*/
35#define YYLIP (& YYTHD->m_parser_state->m_lip)
36#define YYPS (& YYTHD->m_parser_state->m_yacc)
37#define YYCSCL (YYLIP->query_charset)
38#define YYCLIENT_NO_SCHEMA (YYTHD->get_protocol()->has_client_capability(CLIENT_NO_SCHEMA))
39
40#define YYINITDEPTH 100
41#define YYMAXDEPTH 3200                        /* Because of 64K stack */
42#define Lex (YYTHD->lex)
43#define Select Lex->current_select()
44#include "sql_parse.h"                        /* comp_*_creator */
45#include "sql_table.h"                        /* primary_key_name */
46#include "partition_info.h"                   /* partition_info */
47#include "sql_partition.h"                    /* mem_alloc_error */
48#include "auth_common.h"                      /* *_ACL */
49#include "password.h"       /* my_make_scrambled_password_323, my_make_scrambled_password */
50#include "sql_class.h"      /* Key_part_spec, enum_filetype */
51#include "rpl_slave.h"
52#include "rpl_msr.h"       /* multisource replication */
53#include "rpl_filter.h"
54#include "log_event.h"
55#include "lex_symbol.h"
56#include "item_create.h"
57#include "sp_head.h"
58#include "sp_instr.h"
59#include "sp_pcontext.h"
60#include "sp_rcontext.h"
61#include "sp.h"
62#include "sql_alter.h"                         // Sql_cmd_alter_table*
63#include "sql_truncate.h"                      // Sql_cmd_truncate_table
64#include "sql_admin.h"                         // Sql_cmd_analyze/Check..._table
65#include "sql_partition_admin.h"               // Sql_cmd_alter_table_*_part.
66#include "sql_handler.h"                       // Sql_cmd_handler_*
67#include "sql_signal.h"
68#include "sql_get_diagnostics.h"               // Sql_cmd_get_diagnostics
69#include "sql_servers.h"
70#include "event_parse_data.h"
71#include <myisam.h>
72#include <myisammrg.h>
73#include "keycaches.h"
74#include "set_var.h"
75#include "opt_explain_traditional.h"
76#include "opt_explain_json.h"
77#include "rpl_slave.h"                       // Sql_cmd_change_repl_filter
78#include "sql_show_status.h"                 // build_show_session_status, ...
79#include "parse_location.h"
80#include "parse_tree_helpers.h"
81#include "lex_token.h"
82#include "item_cmpfunc.h"
83#include "item_geofunc.h"
84#include "item_json_func.h"
85#include "sql_plugin.h"                      // plugin_is_ready
86#include "parse_tree_hints.h"
87
88/* this is to get the bison compilation windows warnings out */
89#ifdef _MSC_VER
90/* warning C4065: switch statement contains 'default' but no 'case' labels */
91#pragma warning (disable : 4065)
92#endif
93
94using std::min;
95using std::max;
96
97int yylex(void *yylval, void *yythd);
98
99#define yyoverflow(A,B,C,D,E,F,G,H)           \
100  {                                           \
101    ulong val= *(H);                          \
102    if (my_yyoverflow((B), (D), (F), &val))   \
103    {                                         \
104      yyerror(NULL, YYTHD, (char*) (A));      \
105      return 2;                               \
106    }                                         \
107    else                                      \
108    {                                         \
109      *(H)= (YYSIZE_T)val;                    \
110    }                                         \
111  }
112
113#define MYSQL_YYABORT                         \
114  do                                          \
115  {                                           \
116    LEX::cleanup_lex_after_parse_error(YYTHD);\
117    YYABORT;                                  \
118  } while (0)
119
120#define MYSQL_YYABORT_UNLESS(A)         \
121  if (!(A))                             \
122  {                                     \
123    my_syntax_error(ER(ER_SYNTAX_ERROR));\
124    MYSQL_YYABORT;                      \
125  }
126
127#define NEW_PTN new(YYTHD->mem_root)
128
129
130/**
131  Parse_tree_node::contextualize_() function call wrapper
132*/
133#define TMP_CONTEXTUALIZE(x)        \
134  do                                \
135  {                                 \
136    Parse_context pc(YYTHD, Select);\
137    if ((x)->contextualize_(&pc))   \
138      MYSQL_YYABORT;                \
139  } while(0)
140
141
142/**
143  Parse_tree_node::contextualize() function call wrapper
144*/
145#define CONTEXTUALIZE(x)                                \
146  do                                                    \
147  {                                                     \
148    Parse_context pc(YYTHD, Select);                    \
149    if (YYTHD->is_error() || (x)->contextualize(&pc))   \
150      MYSQL_YYABORT;                                    \
151  } while(0)
152
153
154/**
155  Item::itemize() function call wrapper
156*/
157#define ITEMIZE(x, y)                                  \
158  do                                                   \
159  {                                                    \
160    Parse_context pc(YYTHD, Select);                   \
161    if (YYTHD->is_error() || (x)->itemize(&pc, (y)))   \
162      MYSQL_YYABORT;                                   \
163  } while(0)
164
165/**
166  PT_statement::make_cmd() wrapper to raise postponed error message on OOM
167
168  @note x may be NULL because of OOM error.
169*/
170#define MAKE_CMD(x)                                     \
171  do                                                    \
172  {                                                     \
173    if (YYTHD->is_error())                              \
174      MYSQL_YYABORT;                                    \
175    Lex->m_sql_cmd= (x)->make_cmd(YYTHD);               \
176  } while(0)
177
178
179#ifndef NDEBUG
180#define YYDEBUG 1
181#else
182#define YYDEBUG 0
183#endif
184
185
186/**
187  @brief Bison callback to report a syntax/OOM error
188
189  This function is invoked by the bison-generated parser
190  when a syntax error, a parse error or an out-of-memory
191  condition occurs. This function is not invoked when the
192  parser is requested to abort by semantic action code
193  by means of YYABORT or YYACCEPT macros. This is why these
194  macros should not be used (use MYSQL_YYABORT/MYSQL_YYACCEPT
195  instead).
196
197  The parser will abort immediately after invoking this callback.
198
199  This function is not for use in semantic actions and is internal to
200  the parser, as it performs some pre-return cleanup.
201  In semantic actions, please use my_syntax_error or my_error to
202  push an error into the error stack and MYSQL_YYABORT
203  to abort from the parser.
204*/
205
206void MYSQLerror(YYLTYPE *, THD *thd, const char *s)
207{
208  /*
209    Restore the original LEX if it was replaced when parsing
210    a stored procedure. We must ensure that a parsing error
211    does not leave any side effects in the THD.
212  */
213  LEX::cleanup_lex_after_parse_error(thd);
214
215  /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
216  if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
217    s= ER(ER_SYNTAX_ERROR);
218  my_syntax_error(s);
219}
220
221
222#ifndef NDEBUG
223void turn_parser_debug_on()
224{
225  /*
226     MYSQLdebug is in sql/sql_yacc.cc, in bison generated code.
227     Turning this option on is **VERY** verbose, and should be
228     used when investigating a syntax error problem only.
229
230     The syntax to run with bison traces is as follows :
231     - Starting a server manually :
232       mysqld --debug="d,parser_debug" ...
233     - Running a test :
234       mysql-test-run.pl --mysqld="--debug=d,parser_debug" ...
235
236     The result will be in the process stderr (var/log/master.err)
237   */
238
239  extern int yydebug;
240  yydebug= 1;
241}
242#endif
243
244static bool is_native_function(THD *thd, const LEX_STRING *name)
245{
246  if (find_native_function_builder(thd, *name))
247    return true;
248
249  if (is_lex_native_function(name))
250    return true;
251
252  return false;
253}
254
255
256/**
257  Helper action for a case statement (entering the CASE).
258  This helper is used for both 'simple' and 'searched' cases.
259  This helper, with the other case_stmt_action_..., is executed when
260  the following SQL code is parsed:
261<pre>
262CREATE PROCEDURE proc_19194_simple(i int)
263BEGIN
264  DECLARE str CHAR(10);
265
266  CASE i
267    WHEN 1 THEN SET str="1";
268    WHEN 2 THEN SET str="2";
269    WHEN 3 THEN SET str="3";
270    ELSE SET str="unknown";
271  END CASE;
272
273  SELECT str;
274END
275</pre>
276  The actions are used to generate the following code:
277<pre>
278SHOW PROCEDURE CODE proc_19194_simple;
279Pos     Instruction
2800       set str@1 NULL
2811       set_case_expr (12) 0 i@0
2822       jump_if_not 5(12) (case_expr@0 = 1)
2833       set str@1 _latin1'1'
2844       jump 12
2855       jump_if_not 8(12) (case_expr@0 = 2)
2866       set str@1 _latin1'2'
2877       jump 12
2888       jump_if_not 11(12) (case_expr@0 = 3)
2899       set str@1 _latin1'3'
29010      jump 12
29111      set str@1 _latin1'unknown'
29212      stmt 0 "SELECT str"
293</pre>
294
295  @param thd thread handler
296*/
297
298void case_stmt_action_case(THD *thd)
299{
300  LEX *lex= thd->lex;
301  sp_head *sp= lex->sphead;
302  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
303
304  sp->m_parser_data.new_cont_backpatch();
305
306  /*
307    BACKPATCH: Creating target label for the jump to
308    "case_stmt_action_end_case"
309    (Instruction 12 in the example)
310  */
311
312  pctx->push_label(thd, EMPTY_STR, sp->instructions());
313}
314
315/**
316  Helper action for a case then statements.
317  This helper is used for both 'simple' and 'searched' cases.
318  @param lex the parser lex context
319*/
320
321bool case_stmt_action_then(THD *thd, LEX *lex)
322{
323  sp_head *sp= lex->sphead;
324  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
325
326  sp_instr_jump *i =
327    new (thd->mem_root) sp_instr_jump(sp->instructions(), pctx);
328
329  if (!i || sp->add_instr(thd, i))
330    return true;
331
332  /*
333    BACKPATCH: Resolving forward jump from
334    "case_stmt_action_when" to "case_stmt_action_then"
335    (jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
336  */
337
338  sp->m_parser_data.do_backpatch(pctx->pop_label(), sp->instructions());
339
340  /*
341    BACKPATCH: Registering forward jump from
342    "case_stmt_action_then" to "case_stmt_action_end_case"
343    (jump from instruction 4 to 12, 7 to 12 ... in the example)
344  */
345
346  return sp->m_parser_data.add_backpatch_entry(i, pctx->last_label());
347}
348
349/**
350  Helper action for an end case.
351  This helper is used for both 'simple' and 'searched' cases.
352  @param lex the parser lex context
353  @param simple true for simple cases, false for searched cases
354*/
355
356void case_stmt_action_end_case(LEX *lex, bool simple)
357{
358  sp_head *sp= lex->sphead;
359  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
360
361  /*
362    BACKPATCH: Resolving forward jump from
363    "case_stmt_action_then" to "case_stmt_action_end_case"
364    (jump from instruction 4 to 12, 7 to 12 ... in the example)
365  */
366  sp->m_parser_data.do_backpatch(pctx->pop_label(), sp->instructions());
367
368  if (simple)
369    pctx->pop_case_expr_id();
370
371  sp->m_parser_data.do_cont_backpatch(sp->instructions());
372}
373
374
375static bool add_create_index_prepare (LEX *lex, Table_ident *table)
376{
377  lex->sql_command= SQLCOM_CREATE_INDEX;
378  if (!lex->current_select()->add_table_to_list(lex->thd, table, NULL,
379                                              TL_OPTION_UPDATING,
380                                              TL_READ_NO_INSERT,
381                                              MDL_SHARED_UPGRADABLE))
382    return TRUE;
383  lex->alter_info.reset();
384  lex->alter_info.flags= Alter_info::ALTER_ADD_INDEX;
385  lex->col_list.empty();
386  lex->change= NullS;
387  return FALSE;
388}
389
390static bool add_create_index (LEX *lex, keytype type,
391                              const LEX_STRING &name,
392                              KEY_CREATE_INFO *info= NULL, bool generated= 0)
393{
394  Key *key;
395  key= new Key(type, name, info ? info : &lex->key_create_info, generated,
396               lex->col_list);
397  if (key == NULL)
398    return TRUE;
399
400  lex->alter_info.key_list.push_back(key);
401  lex->col_list.empty();
402  return FALSE;
403}
404
405/**
406  Compare a LEX_USER against the current user as defined by the exact user and
407  host used during authentication.
408
409  @param user A pointer to a user which needs to be matched against the
410              current.
411
412  @see SET PASSWORD rules
413
414  @retval true The specified user is the authorized user
415  @retval false The user doesn't match
416*/
417
418bool match_authorized_user(Security_context *ctx, LEX_USER *user)
419{
420  if(user->user.str && my_strcasecmp(system_charset_info,
421                                     ctx->priv_user().str,
422                                     user->user.str) == 0)
423  {
424    /*
425      users match; let's compare hosts.
426      1. first compare with the host we actually authorized,
427      2. then see if we match the host mask of the priv_host
428    */
429    if (user->host.str && my_strcasecmp(system_charset_info,
430                                        user->host.str,
431                                        ctx->priv_host().str) == 0)
432    {
433      /* specified user exactly match the authorized user */
434      return true;
435    }
436  }
437  return false;
438}
439
440static void init_index_hints(List<Index_hint> *hints, index_hint_type type,
441                             index_clause_map clause)
442{
443  List_iterator<Index_hint> it(*hints);
444  Index_hint *hint;
445  while ((hint= it++))
446  {
447    hint->type= type;
448    hint->clause= clause;
449  }
450}
451
452bool my_yyoverflow(short **a, YYSTYPE **b, YYLTYPE **c, ulong *yystacksize);
453
454#include "parse_tree_nodes.h"
455#include "parse_tree_items.h"
456
457%}
458
459%yacc
460
461%parse-param { class THD *YYTHD }
462%lex-param { class THD *YYTHD }
463%pure-parser                                    /* We have threads */
464/*
465  Currently there are 158 shift/reduce conflicts.
466  We should not introduce new conflicts any more.
467*/
468%expect 158
469
470/*
471   Comments for TOKENS.
472   For each token, please include in the same line a comment that contains
473   the following tags:
474   SQL-2015-R : Reserved keyword as per SQL-2015 draft
475   SQL-2003-R : Reserved keyword as per SQL-2003
476   SQL-2003-N : Non Reserved keyword as per SQL-2003
477   SQL-1999-R : Reserved keyword as per SQL-1999
478   SQL-1999-N : Non Reserved keyword as per SQL-1999
479   MYSQL      : MySQL extention (unspecified)
480   MYSQL-FUNC : MySQL extention, function
481   INTERNAL   : Not a real token, lex optimization
482   OPERATOR   : SQL operator
483   FUTURE-USE : Reserved for futur use
484
485   This makes the code grep-able, and helps maintenance.
486*/
487
488%token  ABORT_SYM                     /* INTERNAL (used in lex) */
489%token  ACCESSIBLE_SYM
490%token  ACCOUNT_SYM
491%token  ACTION                        /* SQL-2003-N */
492%token  ADD                           /* SQL-2003-R */
493%token  ADDDATE_SYM                   /* MYSQL-FUNC */
494%token  AFTER_SYM                     /* SQL-2003-N */
495%token  AGAINST
496%token  AGGREGATE_SYM
497%token  ALGORITHM_SYM
498%token  ALL                           /* SQL-2003-R */
499%token  ALTER                         /* SQL-2003-R */
500%token  ALWAYS_SYM
501%token  ANALYSE_SYM
502%token  ANALYZE_SYM
503%token  AND_AND_SYM                   /* OPERATOR */
504%token  AND_SYM                       /* SQL-2003-R */
505%token  ANY_SYM                       /* SQL-2003-R */
506%token  AS                            /* SQL-2003-R */
507%token  ASC                           /* SQL-2003-N */
508%token  ASCII_SYM                     /* MYSQL-FUNC */
509%token  ASENSITIVE_SYM                /* FUTURE-USE */
510%token  AT_SYM                        /* SQL-2003-R */
511%token  AUTOEXTEND_SIZE_SYM
512%token  AUTO_INC
513%token  AVG_ROW_LENGTH
514%token  AVG_SYM                       /* SQL-2003-N */
515%token  BACKUP_SYM
516%token  BEFORE_SYM                    /* SQL-2003-N */
517%token  BEGIN_SYM                     /* SQL-2003-R */
518%token  BETWEEN_SYM                   /* SQL-2003-R */
519%token  BIGINT                        /* SQL-2003-R */
520%token  BINARY                        /* SQL-2003-R */
521%token  BINLOG_SYM
522%token  BIN_NUM
523%token  BIT_AND                       /* MYSQL-FUNC */
524%token  BIT_OR                        /* MYSQL-FUNC */
525%token  BIT_SYM                       /* MYSQL-FUNC */
526%token  BIT_XOR                       /* MYSQL-FUNC */
527%token  BLOB_SYM                      /* SQL-2003-R */
528%token  BLOCK_SYM
529%token  BOOLEAN_SYM                   /* SQL-2003-R */
530%token  BOOL_SYM
531%token  BOTH                          /* SQL-2003-R */
532%token  BTREE_SYM
533%token  BY                            /* SQL-2003-R */
534%token  BYTE_SYM
535%token  CACHE_SYM
536%token  CALL_SYM                      /* SQL-2003-R */
537%token  CASCADE                       /* SQL-2003-N */
538%token  CASCADED                      /* SQL-2003-R */
539%token  CASE_SYM                      /* SQL-2003-R */
540%token  CAST_SYM                      /* SQL-2003-R */
541%token  CATALOG_NAME_SYM              /* SQL-2003-N */
542%token  CHAIN_SYM                     /* SQL-2003-N */
543%token  CHANGE
544%token  CHANGED
545%token  CHANGED_PAGE_BITMAPS_SYM      /* MYSQL      */
546%token  CHANNEL_SYM
547%token  CHARSET
548%token  CHAR_SYM                      /* SQL-2003-R */
549%token  CHECKSUM_SYM
550%token  CHECK_SYM                     /* SQL-2003-R */
551%token  CIPHER_SYM
552%token  CLASS_ORIGIN_SYM              /* SQL-2003-N */
553%token  CLIENT_SYM
554%token  CLIENT_STATS_SYM
555%token  CLOSE_SYM                     /* SQL-2003-R */
556%token  CLUSTERING_SYM
557%token  COALESCE                      /* SQL-2003-N */
558%token  CODE_SYM
559%token  COLLATE_SYM                   /* SQL-2003-R */
560%token  COLLATION_SYM                 /* SQL-2003-N */
561%token  COLUMNS
562%token  COLUMN_SYM                    /* SQL-2003-R */
563%token  COLUMN_FORMAT_SYM
564%token  COLUMN_NAME_SYM               /* SQL-2003-N */
565%token  COMMENT_SYM
566%token  COMMITTED_SYM                 /* SQL-2003-N */
567%token  COMMIT_SYM                    /* SQL-2003-R */
568%token  COMPACT_SYM
569%token  COMPLETION_SYM
570%token  COMPRESSED_SYM
571%token  COMPRESSION_DICTIONARY_SYM
572%token  COMPRESSION_SYM
573%token  ENCRYPTION_SYM
574%token  ENCRYPTION_KEY_ID_SYM
575%token  CONCURRENT
576%token  CONDITION_SYM                 /* SQL-2003-R, SQL-2008-R */
577%token  CONNECTION_SYM
578%token  CONSISTENT_SYM
579%token  CONSTRAINT                    /* SQL-2003-R */
580%token  CONSTRAINT_CATALOG_SYM        /* SQL-2003-N */
581%token  CONSTRAINT_NAME_SYM           /* SQL-2003-N */
582%token  CONSTRAINT_SCHEMA_SYM         /* SQL-2003-N */
583%token  CONTAINS_SYM                  /* SQL-2003-N */
584%token  CONTEXT_SYM
585%token  CONTINUE_SYM                  /* SQL-2003-R */
586%token  CONVERT_SYM                   /* SQL-2003-N */
587%token  COUNT_SYM                     /* SQL-2003-N */
588%token  CPU_SYM
589%token  CREATE                        /* SQL-2003-R */
590%token  CROSS                         /* SQL-2003-R */
591%token  CUBE_SYM                      /* SQL-2003-R */
592%token  CURDATE                       /* MYSQL-FUNC */
593%token  CURRENT_SYM                   /* SQL-2003-R */
594%token  CURRENT_USER                  /* SQL-2003-R */
595%token  CURSOR_SYM                    /* SQL-2003-R */
596%token  CURSOR_NAME_SYM               /* SQL-2003-N */
597%token  CURTIME                       /* MYSQL-FUNC */
598%token  DATABASE
599%token  DATABASES
600%token  DATAFILE_SYM
601%token  DATA_SYM                      /* SQL-2003-N */
602%token  DATETIME
603%token  DATE_ADD_INTERVAL             /* MYSQL-FUNC */
604%token  DATE_SUB_INTERVAL             /* MYSQL-FUNC */
605%token  DATE_SYM                      /* SQL-2003-R */
606%token  DAY_HOUR_SYM
607%token  DAY_MICROSECOND_SYM
608%token  DAY_MINUTE_SYM
609%token  DAY_SECOND_SYM
610%token  DAY_SYM                       /* SQL-2003-R */
611%token  DEALLOCATE_SYM                /* SQL-2003-R */
612%token  DECIMAL_NUM
613%token  DECIMAL_SYM                   /* SQL-2003-R */
614%token  DECLARE_SYM                   /* SQL-2003-R */
615%token  DEFAULT                       /* SQL-2003-R */
616%token  DEFAULT_AUTH_SYM              /* INTERNAL */
617%token  DEFINER_SYM
618%token  DELAYED_SYM
619%token  DELAY_KEY_WRITE_SYM
620%token  DELETE_SYM                    /* SQL-2003-R */
621%token  DESC                          /* SQL-2003-N */
622%token  DESCRIBE                      /* SQL-2003-R */
623%token  DES_KEY_FILE
624%token  DETERMINISTIC_SYM             /* SQL-2003-R */
625%token  DIAGNOSTICS_SYM               /* SQL-2003-N */
626%token  DIRECTORY_SYM
627%token  DISABLE_SYM
628%token  DISCARD
629%token  DISK_SYM
630%token  DISTINCT                      /* SQL-2003-R */
631%token  DIV_SYM
632%token  DOUBLE_SYM                    /* SQL-2003-R */
633%token  DO_SYM
634%token  DROP                          /* SQL-2003-R */
635%token  DUAL_SYM
636%token  DUMPFILE
637%token  DUPLICATE_SYM
638%token  DYNAMIC_SYM                   /* SQL-2003-R */
639%token  EACH_SYM                      /* SQL-2003-R */
640%token  ELSE                          /* SQL-2003-R */
641%token  ELSEIF_SYM
642%token  ENABLE_SYM
643%token  ENCLOSED
644%token  END                           /* SQL-2003-R */
645%token  ENDS_SYM
646%token  END_OF_INPUT                  /* INTERNAL */
647%token  ENGINES_SYM
648%token  ENGINE_SYM
649%token  ENUM
650%token  EQ                            /* OPERATOR */
651%token  EQUAL_SYM                     /* OPERATOR */
652%token  ERROR_SYM
653%token  ERRORS
654%token  ESCAPED
655%token  ESCAPE_SYM                    /* SQL-2003-R */
656%token  EVENTS_SYM
657%token  EVENT_SYM
658%token  EVERY_SYM                     /* SQL-2003-N */
659%token  EXCHANGE_SYM
660%token  EXECUTE_SYM                   /* SQL-2003-R */
661%token  EXISTS                        /* SQL-2003-R */
662%token  EXIT_SYM
663%token  EXPANSION_SYM
664%token  EXPIRE_SYM
665%token  EXPORT_SYM
666%token  EXTENDED_SYM
667%token  EXTENT_SIZE_SYM
668%token  EXTRACT_SYM                   /* SQL-2003-N */
669%token  FALSE_SYM                     /* SQL-2003-R */
670%token  FAST_SYM
671%token  FAULTS_SYM
672%token  FETCH_SYM                     /* SQL-2003-R */
673%token  FILE_SYM
674%token  FILE_BLOCK_SIZE_SYM
675%token  FILTER_SYM
676%token  FIRST_SYM                     /* SQL-2003-N */
677%token  FIXED_SYM
678%token  FLOAT_NUM
679%token  FLOAT_SYM                     /* SQL-2003-R */
680%token  FLUSH_SYM
681%token  FOLLOWS_SYM                  /* MYSQL */
682%token  FORCE_SYM
683%token  FOREIGN                       /* SQL-2003-R */
684%token  FOR_SYM                       /* SQL-2003-R */
685%token  FORMAT_SYM
686%token  FOUND_SYM                     /* SQL-2003-R */
687%token  FROM
688%token  FULL                          /* SQL-2003-R */
689%token  FULLTEXT_SYM
690%token  FUNCTION_SYM                  /* SQL-2003-R */
691%token  GE
692%token  GENERAL
693%token  GENERATED
694%token  GROUP_REPLICATION
695%token  GEOMETRYCOLLECTION
696%token  GEOMETRY_SYM
697%token  GET_FORMAT                    /* MYSQL-FUNC */
698%token  GET_SYM                       /* SQL-2003-R */
699%token  GLOBAL_SYM                    /* SQL-2003-R */
700%token  GRANT                         /* SQL-2003-R */
701%token  GRANTS
702%token  GROUP_SYM                     /* SQL-2003-R */
703%token  GROUP_CONCAT_SYM
704%token  GT_SYM                        /* OPERATOR */
705%token  HANDLER_SYM
706%token  HASH_SYM
707%token  HAVING                        /* SQL-2003-R */
708%token  HELP_SYM
709%token  HEX_NUM
710%token  HIGH_PRIORITY
711%token  HOST_SYM
712%token  HOSTS_SYM
713%token  HOUR_MICROSECOND_SYM
714%token  HOUR_MINUTE_SYM
715%token  HOUR_SECOND_SYM
716%token  HOUR_SYM                      /* SQL-2003-R */
717%token  IDENT
718%token  IDENTIFIED_SYM
719%token  IDENT_QUOTED
720%token  IF
721%token  IGNORE_SYM
722%token  IGNORE_SERVER_IDS_SYM
723%token  IMPORT
724%token  INDEXES
725%token  INDEX_SYM
726%token  INDEX_STATS_SYM
727%token  INFILE
728%token  INITIAL_SIZE_SYM
729%token  INNER_SYM                     /* SQL-2003-R */
730%token  INOUT_SYM                     /* SQL-2003-R */
731%token  INSENSITIVE_SYM               /* SQL-2003-R */
732%token  INSERT                        /* SQL-2003-R */
733%token  INSERT_METHOD
734%token  INSTANCE_SYM
735%token  INSTALL_SYM
736%token  INTERVAL_SYM                  /* SQL-2003-R */
737%token  INTO                          /* SQL-2003-R */
738%token  INT_SYM                       /* SQL-2003-R */
739%token  INVOKER_SYM
740%token  IN_SYM                        /* SQL-2003-R */
741%token  IO_AFTER_GTIDS                /* MYSQL, FUTURE-USE */
742%token  IO_BEFORE_GTIDS               /* MYSQL, FUTURE-USE */
743%token  IO_SYM
744%token  IPC_SYM
745%token  IS                            /* SQL-2003-R */
746%token  ISOLATION                     /* SQL-2003-R */
747%token  ISSUER_SYM
748%token  ITERATE_SYM
749%token  JOIN_SYM                      /* SQL-2003-R */
750%token  JSON_SEPARATOR_SYM            /* MYSQL */
751%token  JSON_UNQUOTED_SEPARATOR_SYM   /* MYSQL */
752%token  JSON_SYM                      /* MYSQL */
753%token  KEYS
754%token  KEY_BLOCK_SIZE
755%token  KEY_SYM                       /* SQL-2003-N */
756%token  KILL_SYM
757%token  LANGUAGE_SYM                  /* SQL-2003-R */
758%token  LAST_SYM                      /* SQL-2003-N */
759%token  LE                            /* OPERATOR */
760%token  LEADING                       /* SQL-2003-R */
761%token  LEAVES
762%token  LEAVE_SYM
763%token  LEFT                          /* SQL-2003-R */
764%token  LESS_SYM
765%token  LEVEL_SYM
766%token  LEX_HOSTNAME
767%token  LIKE                          /* SQL-2003-R */
768%token  LIMIT
769%token  LINEAR_SYM
770%token  LINES
771%token  LINESTRING
772%token  LIST_SYM
773%token  LOAD
774%token  LOCAL_SYM                     /* SQL-2003-R */
775%token  LOCATOR_SYM                   /* SQL-2003-N */
776%token  LOCKS_SYM
777%token  LOCK_SYM
778%token  LOGFILE_SYM
779%token  LOGS_SYM
780%token  LONGBLOB
781%token  LONGTEXT
782%token  LONG_NUM
783%token  LONG_SYM
784%token  LOOP_SYM
785%token  LOW_PRIORITY
786%token  LT                            /* OPERATOR */
787%token  MASTER_AUTO_POSITION_SYM
788%token  MASTER_BIND_SYM
789%token  MASTER_CONNECT_RETRY_SYM
790%token  MASTER_DELAY_SYM
791%token  MASTER_HOST_SYM
792%token  MASTER_LOG_FILE_SYM
793%token  MASTER_LOG_POS_SYM
794%token  MASTER_PASSWORD_SYM
795%token  MASTER_PORT_SYM
796%token  MASTER_RETRY_COUNT_SYM
797%token  MASTER_SERVER_ID_SYM
798%token  MASTER_SSL_CAPATH_SYM
799%token  MASTER_TLS_VERSION_SYM
800%token  MASTER_SSL_CA_SYM
801%token  MASTER_SSL_CERT_SYM
802%token  MASTER_SSL_CIPHER_SYM
803%token  MASTER_SSL_CRL_SYM
804%token  MASTER_SSL_CRLPATH_SYM
805%token  MASTER_SSL_KEY_SYM
806%token  MASTER_SSL_SYM
807%token  MASTER_SSL_VERIFY_SERVER_CERT_SYM
808%token  MASTER_SYM
809%token  MASTER_USER_SYM
810%token  MASTER_HEARTBEAT_PERIOD_SYM
811%token  MATCH                         /* SQL-2003-R */
812%token  MAX_CONNECTIONS_PER_HOUR
813%token  MAX_QUERIES_PER_HOUR
814%token  MAX_ROWS
815%token  MAX_SIZE_SYM
816%token  MAX_SYM                       /* SQL-2003-N */
817%token  MAX_UPDATES_PER_HOUR
818%token  MAX_USER_CONNECTIONS_SYM
819%token  MAX_VALUE_SYM                 /* SQL-2003-N */
820%token  MEDIUMBLOB
821%token  MEDIUMINT
822%token  MEDIUMTEXT
823%token  MEDIUM_SYM
824%token  MEMORY_SYM
825%token  MERGE_SYM                     /* SQL-2003-R */
826%token  MESSAGE_TEXT_SYM              /* SQL-2003-N */
827%token  MICROSECOND_SYM               /* MYSQL-FUNC */
828%token  MIGRATE_SYM
829%token  MINUTE_MICROSECOND_SYM
830%token  MINUTE_SECOND_SYM
831%token  MINUTE_SYM                    /* SQL-2003-R */
832%token  MIN_ROWS
833%token  MIN_SYM                       /* SQL-2003-N */
834%token  MODE_SYM
835%token  MODIFIES_SYM                  /* SQL-2003-R */
836%token  MODIFY_SYM
837%token  MOD_SYM                       /* SQL-2003-N */
838%token  MONTH_SYM                     /* SQL-2003-R */
839%token  MULTILINESTRING
840%token  MULTIPOINT
841%token  MULTIPOLYGON
842%token  MUTEX_SYM
843%token  MYSQL_ERRNO_SYM
844%token  NAMES_SYM                     /* SQL-2003-N */
845%token  NAME_SYM                      /* SQL-2003-N */
846%token  NATIONAL_SYM                  /* SQL-2003-R */
847%token  NATURAL                       /* SQL-2003-R */
848%token  NCHAR_STRING
849%token  NCHAR_SYM                     /* SQL-2003-R */
850%token  NDBCLUSTER_SYM
851%token  NE                            /* OPERATOR */
852%token  NEG
853%token  NEVER_SYM
854%token  NEW_SYM                       /* SQL-2003-R */
855%token  NEXT_SYM                      /* SQL-2003-N */
856%token  NODEGROUP_SYM
857%token  NONE_SYM                      /* SQL-2003-R */
858%token  NOT2_SYM
859%token  NOT_SYM                       /* SQL-2003-R */
860%token  NOW_SYM
861%token  NO_SYM                        /* SQL-2003-R */
862%token  NO_WAIT_SYM
863%token  NO_WRITE_TO_BINLOG
864%token  NULL_SYM                      /* SQL-2003-R */
865%token  NUM
866%token  NUMBER_SYM                    /* SQL-2003-N */
867%token  NUMERIC_SYM                   /* SQL-2003-R */
868%token  NVARCHAR_SYM
869%token  OFFSET_SYM
870%token  ON                            /* SQL-2003-R */
871%token  ONE_SYM
872%token  ONLY_SYM                      /* SQL-2003-R */
873%token  OPEN_SYM                      /* SQL-2003-R */
874%token  OPTIMIZE
875%token  OPTIMIZER_COSTS_SYM
876%token  OPTIONS_SYM
877%token  OPTION                        /* SQL-2003-N */
878%token  OPTIONALLY
879%token  OR2_SYM
880%token  ORDER_SYM                     /* SQL-2003-R */
881%token  OR_OR_SYM                     /* OPERATOR */
882%token  OR_SYM                        /* SQL-2003-R */
883%token  OUTER
884%token  OUTFILE
885%token  OUT_SYM                       /* SQL-2003-R */
886%token  OWNER_SYM
887%token  PACK_KEYS_SYM
888%token  PAGE_SYM
889%token  PARAM_MARKER
890%token  PARSER_SYM
891%token  PARSE_GCOL_EXPR_SYM
892%token  PARTIAL                       /* SQL-2003-N */
893%token  PARTITION_SYM                 /* SQL-2003-R */
894%token  PARTITIONS_SYM
895%token  PARTITIONING_SYM
896%token  PASSWORD
897%token  PHASE_SYM
898%token  PLUGIN_DIR_SYM                /* INTERNAL */
899%token  PLUGIN_SYM
900%token  PLUGINS_SYM
901%token  POINT_SYM
902%token  POLYGON
903%token  PORT_SYM
904%token  POSITION_SYM                  /* SQL-2003-N */
905%token  PRECEDES_SYM                  /* MYSQL */
906%token  PRECISION                     /* SQL-2003-R */
907%token  PREPARE_SYM                   /* SQL-2003-R */
908%token  PRESERVE_SYM
909%token  PREV_SYM
910%token  PRIMARY_SYM                   /* SQL-2003-R */
911%token  PRIVILEGES                    /* SQL-2003-N */
912%token  PROCEDURE_SYM                 /* SQL-2003-R */
913%token  PROCESS
914%token  PROCESSLIST_SYM
915%token  PROFILE_SYM
916%token  PROFILES_SYM
917%token  PROXY_SYM
918%token  PURGE
919%token  QUARTER_SYM
920%token  QUERY_SYM
921%token  QUICK
922%token  RANGE_SYM                     /* SQL-2003-R */
923%token  READS_SYM                     /* SQL-2003-R */
924%token  READ_ONLY_SYM
925%token  READ_SYM                      /* SQL-2003-N */
926%token  READ_WRITE_SYM
927%token  REAL                          /* SQL-2003-R */
928%token  REBUILD_SYM
929%token  RECOVER_SYM
930%token  REDOFILE_SYM
931%token  REDO_BUFFER_SIZE_SYM
932%token  REDUNDANT_SYM
933%token  REFERENCES                    /* SQL-2003-R */
934%token  REGEXP
935%token  RELAY
936%token  RELAYLOG_SYM
937%token  RELAY_LOG_FILE_SYM
938%token  RELAY_LOG_POS_SYM
939%token  RELAY_THREAD
940%token  RELEASE_SYM                   /* SQL-2003-R */
941%token  RELOAD
942%token  REMOVE_SYM
943%token  RENAME
944%token  REORGANIZE_SYM
945%token  REPAIR
946%token  REPEATABLE_SYM                /* SQL-2003-N */
947%token  REPEAT_SYM                    /* MYSQL-FUNC */
948%token  REPLACE                       /* MYSQL-FUNC */
949%token  REPLICATION
950%token  REPLICATE_DO_DB
951%token  REPLICATE_IGNORE_DB
952%token  REPLICATE_DO_TABLE
953%token  REPLICATE_IGNORE_TABLE
954%token  REPLICATE_WILD_DO_TABLE
955%token  REPLICATE_WILD_IGNORE_TABLE
956%token  REPLICATE_REWRITE_DB
957%token  REQUIRE_SYM
958%token  RESET_SYM
959%token  RESIGNAL_SYM                  /* SQL-2003-R */
960%token  RESOURCES
961%token  RESTORE_SYM
962%token  RESTRICT
963%token  RESUME_SYM
964%token  RETURNED_SQLSTATE_SYM         /* SQL-2003-N */
965%token  RETURNS_SYM                   /* SQL-2003-R */
966%token  RETURN_SYM                    /* SQL-2003-R */
967%token  REVERSE_SYM
968%token  REVOKE                        /* SQL-2003-R */
969%token  RIGHT                         /* SQL-2003-R */
970%token  ROLLBACK_SYM                  /* SQL-2003-R */
971%token  ROLLUP_SYM                    /* SQL-2003-R */
972%token  ROTATE_SYM
973%token  ROUTINE_SYM                   /* SQL-2003-N */
974%token  ROWS_SYM                      /* SQL-2003-R */
975%token  ROW_FORMAT_SYM
976%token  ROW_SYM                       /* SQL-2003-R */
977%token  ROW_COUNT_SYM                 /* SQL-2003-N */
978%token  RTREE_SYM
979%token  SAVEPOINT_SYM                 /* SQL-2003-R */
980%token  SCHEDULE_SYM
981%token  SCHEMA_NAME_SYM               /* SQL-2003-N */
982%token  SECOND_MICROSECOND_SYM
983%token  SECOND_SYM                    /* SQL-2003-R */
984%token  SECURITY_SYM                  /* SQL-2003-N */
985%token  SELECT_SYM                    /* SQL-2003-R */
986%token  SENSITIVE_SYM                 /* FUTURE-USE */
987%token  SEPARATOR_SYM
988%token  SERIALIZABLE_SYM              /* SQL-2003-N */
989%token  SERIAL_SYM
990%token  SESSION_SYM                   /* SQL-2003-N */
991%token  SERVER_SYM
992%token  SERVER_OPTIONS
993%token  SET                           /* SQL-2003-R */
994%token  SET_VAR
995%token  SHARE_SYM
996%token  SHIFT_LEFT                    /* OPERATOR */
997%token  SHIFT_RIGHT                   /* OPERATOR */
998%token  SHOW
999%token  SHUTDOWN
1000%token  SIGNAL_SYM                    /* SQL-2003-R */
1001%token  SIGNED_SYM
1002%token  SIMPLE_SYM                    /* SQL-2003-N */
1003%token  SLAVE
1004%token  SLOW
1005%token  SMALLINT                      /* SQL-2003-R */
1006%token  SNAPSHOT_SYM
1007%token  SOCKET_SYM
1008%token  SONAME_SYM
1009%token  SOUNDS_SYM
1010%token  SOURCE_SYM
1011%token  SPATIAL_SYM
1012%token  SPECIFIC_SYM                  /* SQL-2003-R */
1013%token  SQLEXCEPTION_SYM              /* SQL-2003-R */
1014%token  SQLSTATE_SYM                  /* SQL-2003-R */
1015%token  SQLWARNING_SYM                /* SQL-2003-R */
1016%token  SQL_AFTER_GTIDS               /* MYSQL */
1017%token  SQL_AFTER_MTS_GAPS            /* MYSQL */
1018%token  SQL_BEFORE_GTIDS              /* MYSQL */
1019%token  SQL_BIG_RESULT
1020%token  SQL_BUFFER_RESULT
1021%token  SQL_CACHE_SYM
1022%token  SQL_CALC_FOUND_ROWS
1023%token  SQL_NO_CACHE_SYM
1024%token  SQL_SMALL_RESULT
1025%token  SQL_SYM                       /* SQL-2003-R */
1026%token  SQL_THREAD
1027%token  SSL_SYM
1028%token  STACKED_SYM                   /* SQL-2003-N */
1029%token  STARTING
1030%token  STARTS_SYM
1031%token  START_SYM                     /* SQL-2003-R */
1032%token  STATEMENT_SYM
1033%token  STATS_AUTO_RECALC_SYM
1034%token  STATS_PERSISTENT_SYM
1035%token  STATS_SAMPLE_PAGES_SYM
1036%token  STATUS_SYM
1037%token  STDDEV_SAMP_SYM               /* SQL-2003-N */
1038%token  STD_SYM
1039%token  STOP_SYM
1040%token  STORAGE_SYM
1041%token  STORED_SYM
1042%token  STRAIGHT_JOIN
1043%token  STRING_SYM
1044%token  SUBCLASS_ORIGIN_SYM           /* SQL-2003-N */
1045%token  SUBDATE_SYM
1046%token  SUBJECT_SYM
1047%token  SUBPARTITIONS_SYM
1048%token  SUBPARTITION_SYM
1049%token  SUBSTRING                     /* SQL-2003-N */
1050%token  SUM_SYM                       /* SQL-2003-N */
1051%token  SUPER_SYM
1052%token  SUSPEND_SYM
1053%token  SWAPS_SYM
1054%token  SWITCHES_SYM
1055%token  SYSDATE
1056%token  TABLES
1057%token  TABLESPACE_SYM
1058%token  TABLE_REF_PRIORITY
1059%token  TABLE_SYM                     /* SQL-2003-R */
1060%token  TABLE_STATS_SYM
1061%token  TABLE_CHECKSUM_SYM
1062%token  TABLE_NAME_SYM                /* SQL-2003-N */
1063%token  TEMPORARY                     /* SQL-2003-N */
1064%token  TEMPTABLE_SYM
1065%token  TERMINATED
1066%token  TEXT_STRING
1067%token  TEXT_SYM
1068%token  THAN_SYM
1069%token  THEN_SYM                      /* SQL-2003-R */
1070%token  THREAD_STATS_SYM
1071%token  TIMESTAMP                     /* SQL-2003-R */
1072%token  TIMESTAMP_ADD
1073%token  TIMESTAMP_DIFF
1074%token  TIME_SYM                      /* SQL-2003-R */
1075%token  TINYBLOB
1076%token  TINYINT
1077%token  TINYTEXT
1078%token  TO_SYM                        /* SQL-2003-R */
1079%token  TOKU_UNCOMPRESSED_SYM
1080%token  TOKU_ZLIB_SYM
1081%token  TOKU_SNAPPY_SYM
1082%token  TOKU_QUICKLZ_SYM
1083%token  TOKU_LZMA_SYM
1084%token  TOKU_FAST_SYM
1085%token  TOKU_SMALL_SYM
1086%token  TOKU_DEFAULT_SYM
1087%token  TRAILING                      /* SQL-2003-R */
1088%token  TRANSACTION_SYM
1089%token  TRIGGERS_SYM
1090%token  TRIGGER_SYM                   /* SQL-2003-R */
1091%token  TRIM                          /* SQL-2003-N */
1092%token  TRUE_SYM                      /* SQL-2003-R */
1093%token  TRUNCATE_SYM
1094%token  TYPES_SYM
1095%token  TYPE_SYM                      /* SQL-2003-N */
1096%token  UDF_RETURNS_SYM
1097%token  ULONGLONG_NUM
1098%token  UNCOMMITTED_SYM               /* SQL-2003-N */
1099%token  UNDEFINED_SYM
1100%token  UNDERSCORE_CHARSET
1101%token  UNDOFILE_SYM
1102%token  UNDO_BUFFER_SIZE_SYM
1103%token  UNDO_SYM                      /* FUTURE-USE */
1104%token  UNICODE_SYM
1105%token  UNINSTALL_SYM
1106%token  UNION_SYM                     /* SQL-2003-R */
1107%token  UNIQUE_SYM
1108%token  UNKNOWN_SYM                   /* SQL-2003-R */
1109%token  UNLOCK_SYM
1110%token  UNSIGNED
1111%token  UNTIL_SYM
1112%token  UPDATE_SYM                    /* SQL-2003-R */
1113%token  UPGRADE_SYM
1114%token  USAGE                         /* SQL-2003-N */
1115%token  USER                          /* SQL-2003-R */
1116%token  USER_STATS_SYM
1117%token  USE_FRM
1118%token  USE_SYM
1119%token  USING                         /* SQL-2003-R */
1120%token  UTC_DATE_SYM
1121%token  UTC_TIMESTAMP_SYM
1122%token  UTC_TIME_SYM
1123%token  VALIDATION_SYM                /* MYSQL */
1124%token  VALUES                        /* SQL-2003-R */
1125%token  VALUE_SYM                     /* SQL-2003-R */
1126%token  VARBINARY
1127%token  VARCHAR                       /* SQL-2003-R */
1128%token  VARIABLES
1129%token  VARIANCE_SYM
1130%token  VARYING                       /* SQL-2003-R */
1131%token  VAR_SAMP_SYM
1132%token  VIEW_SYM                      /* SQL-2003-N */
1133%token  VIRTUAL_SYM
1134%token  WAIT_SYM
1135%token  WARNINGS
1136%token  WEEK_SYM
1137%token  WEIGHT_STRING_SYM
1138%token  WHEN_SYM                      /* SQL-2003-R */
1139%token  WHERE                         /* SQL-2003-R */
1140%token  WHILE_SYM
1141%token  WITH                          /* SQL-2003-R */
1142%token  WITH_CUBE_SYM                 /* INTERNAL */
1143%token  WITH_ROLLUP_SYM               /* INTERNAL */
1144%token  WITHOUT_SYM                   /* SQL-2003-R */
1145%token  WORK_SYM                      /* SQL-2003-N */
1146%token  WRAPPER_SYM
1147%token  WRITE_SYM                     /* SQL-2003-N */
1148%token  X509_SYM
1149%token  XA_SYM
1150%token  XID_SYM                       /* MYSQL */
1151%token  XML_SYM
1152%token  XOR
1153%token  YEAR_MONTH_SYM
1154%token  YEAR_SYM                      /* SQL-2003-R */
1155%token  ZEROFILL
1156
1157/*
1158   Tokens from MySQL 8.0
1159*/
1160%token  JSON_OBJECTAGG                /* SQL-2015-R */
1161%token  JSON_ARRAYAGG                 /* SQL-2015-R */
1162
1163/*
1164  Resolve column attribute ambiguity -- force precedence of "UNIQUE KEY" against
1165  simple "UNIQUE" and "KEY" attributes:
1166*/
1167%right UNIQUE_SYM KEY_SYM
1168
1169%left   JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
1170/* A dummy token to force the priority of table_ref production in a join. */
1171%left   TABLE_REF_PRIORITY
1172%left   SET_VAR
1173%left   OR_OR_SYM OR_SYM OR2_SYM
1174%left   XOR
1175%left   AND_SYM AND_AND_SYM
1176%left   BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
1177%left   EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
1178%left   '|'
1179%left   '&'
1180%left   SHIFT_LEFT SHIFT_RIGHT
1181%left   '-' '+'
1182%left   '*' '/' '%' DIV_SYM MOD_SYM
1183%left   '^'
1184%left   NEG '~'
1185%right  NOT_SYM NOT2_SYM
1186%right  BINARY COLLATE_SYM
1187%left  INTERVAL_SYM
1188
1189%type <lex_str>
1190        IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM
1191        LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
1192        IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
1193        NCHAR_STRING opt_component key_cache_name
1194        sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
1195        opt_constraint constraint opt_ident TEXT_STRING_sys_nonewline
1196        filter_wild_db_table_string
1197
1198%type <lex_cstr>
1199        opt_with_compression_dictionary
1200
1201%type <lex_str_ptr>
1202        opt_table_alias
1203
1204%type <table>
1205        table_ident table_ident_nodb references
1206
1207%type <simple_string>
1208        opt_db password
1209
1210%type <string>
1211        text_string opt_gconcat_separator
1212
1213%type <num>
1214        type type_with_opt_collate int_type real_type lock_option
1215        udf_type if_exists opt_local opt_table_options table_options
1216        table_option opt_if_not_exists opt_no_write_to_binlog
1217        opt_temporary all_or_any opt_distinct
1218        opt_ignore_leaves fulltext_options spatial_type union_option
1219        transaction_access_mode_types
1220        opt_natural_language_mode opt_query_expansion
1221        opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
1222        ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
1223        trg_action_time trg_event field_def
1224        ordering_direction opt_ordering_direction
1225
1226/*
1227  Bit field of MYSQL_START_TRANS_OPT_* flags.
1228*/
1229%type <num> opt_start_transaction_option_list
1230%type <num> start_transaction_option_list
1231%type <num> start_transaction_option
1232
1233%type <m_yes_no_unk>
1234        opt_chain opt_release
1235
1236%type <m_fk_option>
1237        delete_option
1238
1239%type <ulong_num>
1240        ulong_num real_ulong_num merge_insert_types
1241        ws_nweights func_datetime_precision
1242        ws_level_flag_desc ws_level_flag_reverse ws_level_flags
1243        opt_ws_levels ws_level_list ws_level_list_item ws_level_number
1244        ws_level_range ws_level_list_or_range
1245        now
1246
1247%type <ulonglong_number>
1248        ulonglong_num real_ulonglong_num size_number
1249        procedure_analyse_param
1250
1251%type <lock_type>
1252        replace_lock_option opt_low_priority insert_lock_option load_data_lock
1253
1254%type <item>
1255        literal insert_ident temporal_literal
1256        simple_ident expr opt_expr opt_else sum_expr in_sum_expr
1257        variable variable_aux bool_pri
1258        predicate bit_expr
1259        table_wild simple_expr udf_expr
1260        expr_or_default set_expr_or_default
1261        geometry_function
1262        signed_literal now_or_signed_literal opt_escape
1263        sp_opt_default
1264        simple_ident_nospvar simple_ident_q
1265        field_or_var limit_option
1266        part_func_expr
1267        function_call_keyword
1268        function_call_nonkeyword
1269        function_call_generic
1270        function_call_conflict
1271        signal_allowed_expr
1272        simple_target_specification
1273        condition_number
1274        create_compression_dictionary_allowed_expr
1275        filter_db_ident
1276        filter_table_ident
1277        filter_string
1278        NUM_literal
1279        select_item
1280        opt_where_clause
1281        opt_having_clause
1282        opt_simple_limit
1283
1284%type <item_list>
1285        when_list
1286        opt_filter_db_list filter_db_list
1287        opt_filter_table_list filter_table_list
1288        opt_filter_string_list filter_string_list
1289        opt_filter_db_pair_list filter_db_pair_list
1290
1291%type <item_list2>
1292        expr_list udf_expr_list opt_udf_expr_list opt_expr_list select_item_list
1293        ident_list ident_list_arg
1294
1295%type <var_type>
1296        option_type opt_var_type opt_var_ident_type
1297
1298%type <key_type>
1299        normal_key_type opt_unique_combo_clustering constraint_key_type
1300        fulltext spatial unique_opt_clustering unique_combo_clustering unique clustering
1301
1302%type <key_alg>
1303        btree_or_rtree
1304
1305%type <string_list>
1306        using_list opt_use_partition use_partition
1307
1308%type <key_part>
1309        key_part
1310
1311%type <date_time_type> date_time_type;
1312%type <interval> interval
1313
1314%type <interval_time_st> interval_time_stamp
1315
1316%type <db_type> storage_engines known_storage_engines
1317
1318%type <row_type> row_types
1319
1320%type <tx_isolation> isolation_types
1321
1322%type <ha_rkey_mode> handler_rkey_mode
1323
1324%type <ha_read_mode> handler_read_or_scan handler_scan_function
1325        handler_rkey_function
1326
1327%type <cast_type> cast_type
1328
1329%type <symbol> keyword keyword_sp
1330
1331%type <lex_user> user grant_user user_func
1332
1333%type <charset>
1334        opt_collate
1335        opt_collate_explicit
1336        charset_name
1337        charset_name_or_default
1338        old_or_new_charset_name
1339        old_or_new_charset_name_or_default
1340        collation_name
1341        collation_name_or_default
1342        opt_load_data_charset
1343        UNDERSCORE_CHARSET
1344        ascii unicode
1345
1346%type <boolfunc2creator> comp_op
1347
1348%type <NONE>
1349        create change drop
1350        truncate rename
1351        show describe load alter optimize keycache preload flush
1352        reset purge begin commit rollback savepoint release
1353        slave master_def master_defs master_file_def slave_until_opts
1354        repair analyze check start checksum filter_def filter_defs
1355        field_list field_list_item field_spec kill column_def key_def
1356        keycache_list keycache_list_or_parts assign_to_keycache
1357        assign_to_keycache_parts
1358        preload_list preload_list_or_parts preload_keys preload_keys_parts
1359        handler
1360        opt_column opt_restrict
1361        grant revoke lock unlock string_list field_options field_option
1362        field_opt_list table_lock_list table_lock
1363        ref_list opt_match_clause opt_on_update_delete use
1364        varchar nchar nvarchar
1365        opt_outer table_list table_name
1366        opt_place
1367        opt_attribute opt_attribute_list attribute column_list column_list_id
1368        opt_column_list grant_privileges grant_ident grant_list grant_option
1369        object_privilege object_privilege_list user_list rename_list
1370        clear_privileges flush_options flush_option
1371        opt_flush_lock flush_options_list
1372        equal optional_braces
1373        opt_mi_check_type opt_to mi_check_types normal_join
1374        table_to_table_list table_to_table opt_table_list opt_as
1375        opt_and charset
1376        help
1377        opt_extended_describe
1378        prepare prepare_src execute deallocate
1379        sp_suid
1380        sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
1381        opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
1382        view_replace_or_algorithm view_replace
1383        view_algorithm view_or_trigger_or_sp_or_event
1384        definer_tail no_definer_tail
1385        view_suid view_tail view_list_opt view_list view_select
1386        view_check_option trigger_tail
1387        sp_tail sf_tail udf_tail event_tail
1388        install uninstall partition_entry binlog_base64_event
1389        init_key_options normal_key_options normal_key_opts all_key_opt
1390        spatial_key_options fulltext_key_options normal_key_opt
1391        fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
1392        key_using_alg
1393        part_column_list
1394        server_options_list server_option
1395        definer_opt no_definer definer get_diagnostics
1396        alter_user_command password_expire
1397        group_replication
1398END_OF_INPUT
1399
1400%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
1401%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
1402%type <NONE> sp_proc_stmt_if
1403%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled
1404%type <NONE> sp_labeled_block sp_unlabeled_block
1405%type <NONE> sp_proc_stmt_leave
1406%type <NONE> sp_proc_stmt_iterate
1407%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
1408%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
1409
1410%type <num>  sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
1411%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
1412%type <spblock> sp_decls sp_decl
1413%type <spname> sp_name
1414%type <index_hint> index_hint_type
1415%type <num> index_hint_clause
1416%type <filetype> data_or_xml
1417
1418%type <NONE> signal_stmt resignal_stmt
1419%type <da_condition_item_name> signal_condition_information_item_name
1420
1421%type <diag_area> which_area;
1422%type <diag_info> diagnostics_information;
1423%type <stmt_info_item> statement_information_item;
1424%type <stmt_info_item_name> statement_information_item_name;
1425%type <stmt_info_list> statement_information;
1426%type <cond_info_item> condition_information_item;
1427%type <cond_info_item_name> condition_information_item_name;
1428%type <cond_info_list> condition_information;
1429%type <signal_item_list> signal_information_item_list;
1430%type <signal_item_list> opt_set_signal_information;
1431
1432%type <trg_characteristics> trigger_follows_precedes_clause;
1433%type <trigger_action_order_type> trigger_action_order;
1434
1435%type <xid> xid;
1436%type <xa_option_type> opt_join_or_resume;
1437%type <xa_option_type> opt_suspend;
1438%type <xa_option_type> opt_one_phase;
1439
1440%type <is_not_empty> opt_convert_xid opt_ignore
1441
1442%type <NONE>
1443        '-' '+' '*' '/' '%' '(' ')'
1444        ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
1445        THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM
1446
1447%type<NONE> SHOW DESC DESCRIBE describe_command
1448
1449/*
1450  A bit field of SLAVE_IO, SLAVE_SQL flags.
1451*/
1452%type <num> opt_slave_thread_option_list
1453%type <num> slave_thread_option_list
1454%type <num> slave_thread_option
1455
1456%type <key_usage_element> key_usage_element
1457
1458%type <key_usage_list> key_usage_list opt_key_usage_list index_hint_definition
1459        index_hints_list opt_index_hints_list opt_key_definition
1460        cache_key_list_or_empty cache_keys_spec
1461
1462%type <subselect> subselect
1463
1464%type <order_expr> order_expr
1465        grouping_expr
1466
1467%type <order_list> order_list group_list gorder_list opt_gorder_clause
1468
1469%type <c_str> field_length opt_field_length type_datetime_precision
1470
1471%type <ulong_num> opt_bin_mod
1472
1473%type <precision> precision opt_precision float_options
1474
1475%type <charset_with_flags> opt_binary
1476
1477%type <limit_options> limit_options
1478
1479%type <limit_clause> limit_clause opt_limit_clause
1480
1481%type <ulonglong_number> query_spec_option query_spec_option_list
1482        opt_query_spec_options
1483
1484%type <select_options> select_option select_option_list select_options
1485        empty_select_options
1486
1487%type <node> join_table order_or_limit opt_union_order_or_limit
1488        option_value union_opt
1489
1490%type <table_reference_list> table_reference_list from_clause opt_from_clause
1491
1492%type <select_part2_derived> select_part2_derived
1493
1494%type <olap_type> olap_opt
1495
1496%type <group> opt_group_clause
1497
1498%type <order> order_clause opt_order_clause
1499
1500%type <procedure_analyse_params> opt_procedure_analyse_params
1501
1502%type <procedure_analyse> opt_procedure_analyse_clause
1503
1504%type <select_lock_type> opt_select_lock_type
1505
1506%type <union_order_or_limit> union_order_or_limit
1507
1508%type <table_expression> table_expression
1509
1510%type <table_list2> select_derived_union
1511        table_factor table_ref esc_table_ref derived_table_list select_derived
1512
1513%type <join_table_list> join_table_list
1514
1515%type <select_paren_derived> select_paren_derived
1516
1517%type <select_lex2> query_specification query_expression_body
1518
1519%type <internal_variable_name> internal_variable_name
1520
1521%type <option_value_following_option_type> option_value_following_option_type
1522
1523%type <option_value_no_option_type> option_value_no_option_type
1524
1525%type <option_value_list> option_value_list option_value_list_continued
1526        set_stmt_option_value_list set_stmt_option_value_list_continued
1527
1528%type <start_option_value_list> start_option_value_list
1529
1530%type <transaction_access_mode> transaction_access_mode
1531        opt_transaction_access_mode
1532
1533%type <isolation_level> isolation_level opt_isolation_level
1534
1535%type <transaction_characteristics> transaction_characteristics
1536
1537%type <start_option_value_list_following_option_type>
1538        start_option_value_list_following_option_type
1539
1540%type <set> set
1541
1542%type <union_list> union_list opt_union_clause
1543
1544%type <line_separators> line_term line_term_list opt_line_term
1545
1546%type <field_separators> field_term field_term_list opt_field_term
1547
1548%type <into_destination> into_destination into opt_into
1549
1550%type <select_var_ident> select_var_ident
1551
1552%type <select_var_list> select_var_list
1553
1554%type <select_options_and_item_list> select_options_and_item_list
1555
1556%type <select_part2> select_part2
1557
1558%type <select_paren> select_paren
1559
1560%type <select_init> select_init
1561
1562%type <select> select do_stmt
1563
1564%type <param_marker> param_marker
1565
1566%type <text_literal> text_literal
1567
1568%type <item_list2> values opt_values row_value fields
1569
1570%type <statement>
1571        delete_stmt
1572        update_stmt
1573        insert_stmt
1574        replace_stmt
1575        shutdown_stmt
1576	alter_instance_stmt
1577
1578%type <table_ident> table_ident_opt_wild
1579
1580%type <table_ident_list> table_alias_ref_list
1581
1582%type <num> opt_delete_options
1583
1584%type <opt_delete_option> opt_delete_option
1585
1586%type <column_value_pair>
1587        update_elem
1588
1589%type <column_value_list_pair>
1590        update_list
1591        opt_insert_update_list
1592
1593%type <create_select> create_select
1594
1595%type <values_list> values_list insert_values
1596
1597%type <insert_from_subquery> insert_from_subquery
1598
1599%type <insert_query_expression> insert_query_expression
1600
1601%type <column_row_value_list_pair> insert_from_constructor
1602
1603%type <optimizer_hints> SELECT_SYM INSERT REPLACE UPDATE_SYM DELETE_SYM
1604
1605%type <alter_instance_action> alter_instance_action
1606
1607
1608%%
1609
1610/*
1611  Indentation of grammar rules:
1612
1613rule: <-- starts at col 1
1614          rule1a rule1b rule1c <-- starts at col 11
1615          { <-- starts at col 11
1616            code <-- starts at col 13, indentation is 2 spaces
1617          }
1618        | rule2a rule2b
1619          {
1620            code
1621          }
1622        ; <-- on a line by itself, starts at col 9
1623
1624  Also, please do not use any <TAB>, but spaces.
1625  Having a uniform indentation in this file helps
1626  code reviews, patches, merges, and make maintenance easier.
1627  Tip: grep [[:cntrl:]] sql_yacc.yy
1628  Thanks.
1629*/
1630
1631query:
1632          END_OF_INPUT
1633          {
1634            THD *thd= YYTHD;
1635            if (!thd->bootstrap &&
1636                !thd->m_parser_state->has_comment())
1637            {
1638              my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
1639              MYSQL_YYABORT;
1640            }
1641            thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
1642            YYLIP->found_semicolon= NULL;
1643          }
1644        | verb_clause
1645          {
1646            Lex_input_stream *lip = YYLIP;
1647
1648            if (YYTHD->get_protocol()->has_client_capability(CLIENT_MULTI_QUERIES) &&
1649                lip->multi_statements &&
1650                ! lip->eof())
1651            {
1652              /*
1653                We found a well formed query, and multi queries are allowed:
1654                - force the parser to stop after the ';'
1655                - mark the start of the next query for the next invocation
1656                  of the parser.
1657              */
1658              lip->next_state= MY_LEX_END;
1659              lip->found_semicolon= lip->get_ptr();
1660            }
1661            else
1662            {
1663              /* Single query, terminated. */
1664              lip->found_semicolon= NULL;
1665            }
1666          }
1667          ';'
1668          opt_end_of_input
1669        | verb_clause END_OF_INPUT
1670          {
1671            /* Single query, not terminated. */
1672            YYLIP->found_semicolon= NULL;
1673          }
1674        ;
1675
1676opt_end_of_input:
1677          /* empty */
1678        | END_OF_INPUT
1679        ;
1680
1681verb_clause:
1682          statement
1683        | begin
1684        ;
1685
1686/* Verb clauses, except begin */
1687statement:
1688          alter
1689        | analyze
1690        | binlog_base64_event
1691        | call
1692        | change
1693        | check
1694        | checksum
1695        | commit
1696        | create
1697        | deallocate
1698        | delete_stmt           {  MAKE_CMD($1); }
1699        | describe
1700        | do_stmt               { CONTEXTUALIZE($1); }
1701        | drop
1702        | execute
1703        | flush
1704        | get_diagnostics
1705        | group_replication
1706        | grant
1707        | handler
1708        | help
1709        | insert_stmt           { MAKE_CMD($1); }
1710        | install
1711        | kill
1712        | load
1713        | lock
1714        | optimize
1715        | keycache
1716        | parse_gcol_expr
1717        | partition_entry
1718        | preload
1719        | prepare
1720        | purge
1721        | release
1722        | rename
1723        | repair
1724        | replace_stmt          { MAKE_CMD($1); }
1725        | reset
1726        | resignal_stmt
1727        | revoke
1728        | rollback
1729        | savepoint
1730        | select                { CONTEXTUALIZE($1); }
1731        | set                   { CONTEXTUALIZE($1); }
1732        | signal_stmt
1733        | show
1734        | shutdown_stmt         { MAKE_CMD($1); }
1735        | slave
1736        | start
1737        | truncate
1738        | uninstall
1739        | unlock
1740        | update_stmt           { MAKE_CMD($1); }
1741        | use
1742        | xa
1743        ;
1744
1745deallocate:
1746          deallocate_or_drop PREPARE_SYM ident
1747          {
1748            THD *thd= YYTHD;
1749            LEX *lex= thd->lex;
1750            lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
1751            lex->prepared_stmt_name= to_lex_cstring($3);
1752          }
1753        ;
1754
1755deallocate_or_drop:
1756          DEALLOCATE_SYM
1757        | DROP
1758        ;
1759
1760prepare:
1761          PREPARE_SYM ident FROM prepare_src
1762          {
1763            THD *thd= YYTHD;
1764            LEX *lex= thd->lex;
1765            lex->sql_command= SQLCOM_PREPARE;
1766            lex->prepared_stmt_name= to_lex_cstring($2);
1767            /*
1768              We don't know know at this time whether there's a password
1769              in prepare_src, so we err on the side of caution.  Setting
1770              the flag will force a rewrite which will obscure all of
1771              prepare_src in the "Query" log line.  We'll see the actual
1772              query (with just the passwords obscured, if any) immediately
1773              afterwards in the "Prepare" log lines anyway, and then again
1774              in the "Execute" log line if and when prepare_src is executed.
1775            */
1776            lex->contains_plaintext_password= true;
1777          }
1778        ;
1779
1780prepare_src:
1781          TEXT_STRING_sys
1782          {
1783            THD *thd= YYTHD;
1784            LEX *lex= thd->lex;
1785            lex->prepared_stmt_code= $1;
1786            lex->prepared_stmt_code_is_varref= FALSE;
1787          }
1788        | '@' ident_or_text
1789          {
1790            THD *thd= YYTHD;
1791            LEX *lex= thd->lex;
1792            lex->prepared_stmt_code= $2;
1793            lex->prepared_stmt_code_is_varref= TRUE;
1794          }
1795        ;
1796
1797execute:
1798          EXECUTE_SYM ident
1799          {
1800            THD *thd= YYTHD;
1801            LEX *lex= thd->lex;
1802            lex->sql_command= SQLCOM_EXECUTE;
1803            lex->prepared_stmt_name= to_lex_cstring($2);
1804          }
1805          execute_using
1806          {}
1807        ;
1808
1809execute_using:
1810          /* nothing */
1811        | USING execute_var_list
1812        ;
1813
1814execute_var_list:
1815          execute_var_list ',' execute_var_ident
1816        | execute_var_ident
1817        ;
1818
1819execute_var_ident:
1820          '@' ident_or_text
1821          {
1822            LEX *lex=Lex;
1823            LEX_STRING *lexstr= (LEX_STRING*)sql_memdup(&$2, sizeof(LEX_STRING));
1824            if (!lexstr || lex->prepared_stmt_params.push_back(lexstr))
1825              MYSQL_YYABORT;
1826          }
1827        ;
1828
1829/* help */
1830
1831help:
1832          HELP_SYM
1833          {
1834            if (Lex->sphead)
1835            {
1836              my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP");
1837              MYSQL_YYABORT;
1838            }
1839          }
1840          ident_or_text
1841          {
1842            LEX *lex= Lex;
1843            lex->sql_command= SQLCOM_HELP;
1844            lex->help_arg= $3.str;
1845          }
1846        ;
1847
1848/* change master */
1849
1850change:
1851          CHANGE MASTER_SYM TO_SYM
1852          {
1853            LEX *lex = Lex;
1854            lex->sql_command = SQLCOM_CHANGE_MASTER;
1855            /*
1856              Clear LEX_MASTER_INFO struct. repl_ignore_server_ids is cleared
1857              in THD::cleanup_after_query. So it is guaranteed to be empty here.
1858            */
1859            assert(Lex->mi.repl_ignore_server_ids.empty());
1860            lex->mi.set_unspecified();
1861          }
1862          master_defs opt_channel
1863          {}
1864        | CHANGE REPLICATION FILTER_SYM
1865          {
1866            THD *thd= YYTHD;
1867            LEX* lex= thd->lex;
1868            assert(!lex->m_sql_cmd);
1869            lex->sql_command = SQLCOM_CHANGE_REPLICATION_FILTER;
1870            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_change_repl_filter();
1871            if (lex->m_sql_cmd == NULL)
1872              MYSQL_YYABORT;
1873          }
1874          filter_defs
1875          {}
1876        ;
1877
1878filter_defs:
1879          filter_def
1880        | filter_defs ',' filter_def
1881        ;
1882filter_def:
1883          REPLICATE_DO_DB EQ opt_filter_db_list
1884          {
1885            Sql_cmd_change_repl_filter * filter_sql_cmd=
1886              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1887              assert(filter_sql_cmd);
1888            filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_DO_DB);
1889          }
1890        | REPLICATE_IGNORE_DB EQ opt_filter_db_list
1891          {
1892            Sql_cmd_change_repl_filter * filter_sql_cmd=
1893              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1894              assert(filter_sql_cmd);
1895            filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_IGNORE_DB);
1896          }
1897        | REPLICATE_DO_TABLE EQ opt_filter_table_list
1898          {
1899            Sql_cmd_change_repl_filter * filter_sql_cmd=
1900              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1901              assert(filter_sql_cmd);
1902           filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_DO_TABLE);
1903          }
1904        | REPLICATE_IGNORE_TABLE EQ opt_filter_table_list
1905          {
1906            Sql_cmd_change_repl_filter * filter_sql_cmd=
1907              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1908              assert(filter_sql_cmd);
1909            filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_IGNORE_TABLE);
1910          }
1911        | REPLICATE_WILD_DO_TABLE EQ opt_filter_string_list
1912          {
1913            Sql_cmd_change_repl_filter * filter_sql_cmd=
1914              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1915              assert(filter_sql_cmd);
1916            filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_WILD_DO_TABLE);
1917          }
1918        | REPLICATE_WILD_IGNORE_TABLE EQ opt_filter_string_list
1919          {
1920            Sql_cmd_change_repl_filter * filter_sql_cmd=
1921              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1922              assert(filter_sql_cmd);
1923            filter_sql_cmd->set_filter_value($3,
1924                                             OPT_REPLICATE_WILD_IGNORE_TABLE);
1925          }
1926        | REPLICATE_REWRITE_DB EQ opt_filter_db_pair_list
1927          {
1928            Sql_cmd_change_repl_filter * filter_sql_cmd=
1929              (Sql_cmd_change_repl_filter*) Lex->m_sql_cmd;
1930              assert(filter_sql_cmd);
1931            filter_sql_cmd->set_filter_value($3, OPT_REPLICATE_REWRITE_DB);
1932          }
1933        ;
1934opt_filter_db_list:
1935          '(' ')'
1936          {
1937            $$= new (YYTHD->mem_root) List<Item>;
1938            if ($$ == NULL)
1939              MYSQL_YYABORT;
1940          }
1941        | '(' filter_db_list ')'
1942          {
1943            $$= $2;
1944          }
1945        ;
1946
1947filter_db_list:
1948          filter_db_ident
1949          {
1950            $$= new (YYTHD->mem_root) List<Item>;
1951            if ($$ == NULL)
1952              MYSQL_YYABORT;
1953            $$->push_back($1);
1954          }
1955        | filter_db_list ',' filter_db_ident
1956          {
1957            $1->push_back($3);
1958            $$= $1;
1959          }
1960        ;
1961
1962filter_db_ident:
1963          ident /* DB name */
1964          {
1965            THD *thd= YYTHD;
1966            Item *db_item= new (thd->mem_root) Item_string($1.str,
1967                                                           $1.length,
1968                                                           thd->charset());
1969            $$= db_item;
1970          }
1971        ;
1972opt_filter_db_pair_list:
1973          '(' ')'
1974          {
1975            $$= new (YYTHD->mem_root) List<Item>;
1976            if ($$ == NULL)
1977              MYSQL_YYABORT;
1978          }
1979        |'(' filter_db_pair_list ')'
1980          {
1981            $$= $2;
1982          }
1983        ;
1984filter_db_pair_list:
1985          '(' filter_db_ident ',' filter_db_ident ')'
1986          {
1987            $$= new (YYTHD->mem_root) List<Item>;
1988            if ($$ == NULL)
1989              MYSQL_YYABORT;
1990            $$->push_back($2);
1991            $$->push_back($4);
1992          }
1993        | filter_db_pair_list ',' '(' filter_db_ident ',' filter_db_ident ')'
1994          {
1995            $1->push_back($4);
1996            $1->push_back($6);
1997            $$= $1;
1998          }
1999        ;
2000opt_filter_table_list:
2001          '(' ')'
2002          {
2003            $$= new (YYTHD->mem_root) List<Item>;
2004            if ($$ == NULL)
2005              MYSQL_YYABORT;
2006          }
2007        |'(' filter_table_list ')'
2008          {
2009            $$= $2;
2010          }
2011        ;
2012
2013filter_table_list:
2014          filter_table_ident
2015          {
2016            $$= new (YYTHD->mem_root) List<Item>;
2017            if ($$ == NULL)
2018              MYSQL_YYABORT;
2019            $$->push_back($1);
2020          }
2021        | filter_table_list ',' filter_table_ident
2022          {
2023            $1->push_back($3);
2024            $$= $1;
2025          }
2026        ;
2027
2028filter_table_ident:
2029          ident '.' ident /* qualified table name */
2030          {
2031            THD *thd= YYTHD;
2032            Item_string *table_item= new (thd->mem_root) Item_string($1.str,
2033                                                              $1.length,
2034                                                              thd->charset());
2035            table_item->append(thd->strmake(".", 1), 1);
2036            table_item->append($3.str, $3.length);
2037            $$= table_item;
2038          }
2039        ;
2040
2041opt_filter_string_list:
2042          '(' ')'
2043          {
2044            $$= new (YYTHD->mem_root) List<Item>;
2045            if ($$ == NULL)
2046              MYSQL_YYABORT;
2047          }
2048        |'(' filter_string_list ')'
2049          {
2050            $$= $2;
2051          }
2052        ;
2053
2054filter_string_list:
2055          filter_string
2056          {
2057            $$= new (YYTHD->mem_root) List<Item>;
2058            if ($$ == NULL)
2059              MYSQL_YYABORT;
2060            $$->push_back($1);
2061          }
2062        | filter_string_list ',' filter_string
2063          {
2064            $1->push_back($3);
2065            $$= $1;
2066          }
2067        ;
2068
2069filter_string:
2070          filter_wild_db_table_string
2071          {
2072            THD *thd= YYTHD;
2073            Item *string_item= new (thd->mem_root) Item_string($1.str,
2074                                                               $1.length,
2075                                                               thd->charset());
2076            $$= string_item;
2077          }
2078        ;
2079
2080master_defs:
2081          master_def
2082        | master_defs ',' master_def
2083        ;
2084
2085master_def:
2086          MASTER_HOST_SYM EQ TEXT_STRING_sys_nonewline
2087          {
2088            Lex->mi.host = $3.str;
2089          }
2090        | MASTER_BIND_SYM EQ TEXT_STRING_sys_nonewline
2091          {
2092            Lex->mi.bind_addr = $3.str;
2093          }
2094        | MASTER_USER_SYM EQ TEXT_STRING_sys_nonewline
2095          {
2096            Lex->mi.user = $3.str;
2097          }
2098        | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys_nonewline
2099          {
2100            Lex->mi.password = $3.str;
2101            if (strlen($3.str) > 32)
2102            {
2103              my_error(ER_CHANGE_MASTER_PASSWORD_LENGTH, MYF(0));
2104              MYSQL_YYABORT;
2105            }
2106            Lex->contains_plaintext_password= true;
2107          }
2108        | MASTER_PORT_SYM EQ ulong_num
2109          {
2110            Lex->mi.port = $3;
2111          }
2112        | MASTER_CONNECT_RETRY_SYM EQ ulong_num
2113          {
2114            Lex->mi.connect_retry = $3;
2115          }
2116        | MASTER_RETRY_COUNT_SYM EQ ulong_num
2117          {
2118            Lex->mi.retry_count= $3;
2119            Lex->mi.retry_count_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
2120          }
2121        | MASTER_DELAY_SYM EQ ulong_num
2122          {
2123            if ($3 > MASTER_DELAY_MAX)
2124            {
2125              const char *msg= YYTHD->strmake(@3.cpp.start, @3.cpp.end - @3.cpp.start);
2126              my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0),
2127                       msg, MASTER_DELAY_MAX);
2128            }
2129            else
2130              Lex->mi.sql_delay = $3;
2131          }
2132        | MASTER_SSL_SYM EQ ulong_num
2133          {
2134            Lex->mi.ssl= $3 ?
2135              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
2136          }
2137        | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys_nonewline
2138          {
2139            Lex->mi.ssl_ca= $3.str;
2140          }
2141        | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys_nonewline
2142          {
2143            Lex->mi.ssl_capath= $3.str;
2144          }
2145        | MASTER_TLS_VERSION_SYM EQ TEXT_STRING_sys_nonewline
2146          {
2147            Lex->mi.tls_version= $3.str;
2148          }
2149        | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys_nonewline
2150          {
2151            Lex->mi.ssl_cert= $3.str;
2152          }
2153        | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys_nonewline
2154          {
2155            Lex->mi.ssl_cipher= $3.str;
2156          }
2157        | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys_nonewline
2158          {
2159            Lex->mi.ssl_key= $3.str;
2160          }
2161        | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num
2162          {
2163            Lex->mi.ssl_verify_server_cert= $3 ?
2164              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
2165          }
2166        | MASTER_SSL_CRL_SYM EQ TEXT_STRING_sys_nonewline
2167          {
2168            Lex->mi.ssl_crl= $3.str;
2169          }
2170        | MASTER_SSL_CRLPATH_SYM EQ TEXT_STRING_sys_nonewline
2171          {
2172            Lex->mi.ssl_crlpath= $3.str;
2173          }
2174
2175        | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal
2176          {
2177            ITEMIZE($3, &$3);
2178
2179            Lex->mi.heartbeat_period= (float) $3->val_real();
2180            if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD ||
2181                Lex->mi.heartbeat_period < 0.0)
2182            {
2183               const char format[]= "%d";
2184               char buf[4*sizeof(SLAVE_MAX_HEARTBEAT_PERIOD) + sizeof(format)];
2185               sprintf(buf, format, SLAVE_MAX_HEARTBEAT_PERIOD);
2186               my_error(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), buf);
2187               MYSQL_YYABORT;
2188            }
2189            if (Lex->mi.heartbeat_period > slave_net_timeout)
2190            {
2191              push_warning(YYTHD, Sql_condition::SL_WARNING,
2192                           ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX,
2193                           ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX));
2194            }
2195            if (Lex->mi.heartbeat_period < 0.001)
2196            {
2197              if (Lex->mi.heartbeat_period != 0.0)
2198              {
2199                push_warning(YYTHD, Sql_condition::SL_WARNING,
2200                             ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN,
2201                             ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN));
2202                Lex->mi.heartbeat_period= 0.0;
2203              }
2204              Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_DISABLE;
2205            }
2206            Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_ENABLE;
2207          }
2208        | IGNORE_SERVER_IDS_SYM EQ '(' ignore_server_id_list ')'
2209          {
2210            Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
2211           }
2212        |
2213        MASTER_AUTO_POSITION_SYM EQ ulong_num
2214          {
2215            Lex->mi.auto_position= $3 ?
2216              LEX_MASTER_INFO::LEX_MI_ENABLE :
2217              LEX_MASTER_INFO::LEX_MI_DISABLE;
2218          }
2219        |
2220        master_file_def
2221        ;
2222
2223ignore_server_id_list:
2224          /* Empty */
2225          | ignore_server_id
2226          | ignore_server_id_list ',' ignore_server_id
2227        ;
2228
2229ignore_server_id:
2230          ulong_num
2231          {
2232            Lex->mi.repl_ignore_server_ids.push_back($1);
2233          }
2234
2235master_file_def:
2236          MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys_nonewline
2237          {
2238            Lex->mi.log_file_name = $3.str;
2239          }
2240        | MASTER_LOG_POS_SYM EQ ulonglong_num
2241          {
2242            Lex->mi.pos = $3;
2243            /*
2244               If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
2245               instead of causing subsequent errors.
2246               We need to do it in this file, because only there we know that
2247               MASTER_LOG_POS has been explicitely specified. On the contrary
2248               in change_master() (sql_repl.cc) we cannot distinguish between 0
2249               (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
2250               whereas we want to distinguish (specified 0 means "read the binlog
2251               from 0" (4 in fact), unspecified means "don't change the position
2252               (keep the preceding value)").
2253            */
2254            Lex->mi.pos = max<ulonglong>(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
2255          }
2256        | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys_nonewline
2257          {
2258            Lex->mi.relay_log_name = $3.str;
2259          }
2260        | RELAY_LOG_POS_SYM EQ ulong_num
2261          {
2262            Lex->mi.relay_log_pos = $3;
2263            /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
2264            Lex->mi.relay_log_pos = max<ulong>(BIN_LOG_HEADER_SIZE,
2265                                               Lex->mi.relay_log_pos);
2266          }
2267        ;
2268
2269opt_channel:
2270         /*empty */
2271       {
2272         Lex->mi.channel= "";
2273         Lex->mi.for_channel= false;
2274       }
2275     | FOR_SYM CHANNEL_SYM TEXT_STRING_sys_nonewline
2276       {
2277         /*
2278           channel names are case insensitive. This means, even the results
2279           displayed to the user are converted to lower cases.
2280           system_charset_info is utf8_general_ci as required by channel name
2281           restrictions
2282         */
2283         my_casedn_str(system_charset_info, $3.str);
2284         Lex->mi.channel= $3.str;
2285         Lex->mi.for_channel= true;
2286       }
2287    ;
2288
2289/* create a table */
2290
2291create:
2292          CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
2293          {
2294            THD *thd= YYTHD;
2295            LEX *lex= thd->lex;
2296            lex->sql_command= SQLCOM_CREATE_TABLE;
2297            if (!lex->select_lex->add_table_to_list(thd, $5, NULL,
2298                                                    TL_OPTION_UPDATING,
2299                                                    TL_WRITE, MDL_SHARED))
2300              MYSQL_YYABORT;
2301            /*
2302              Instruct open_table() to acquire SHARED lock to check the
2303              existance of table. If the table does not exist then
2304              it will be upgraded EXCLUSIVE MDL lock. If table exist
2305              then open_table() will return with an error or warning.
2306            */
2307            lex->query_tables->open_strategy= TABLE_LIST::OPEN_FOR_CREATE;
2308            lex->alter_info.reset();
2309            lex->col_list.empty();
2310            lex->change=NullS;
2311	    new (&lex->create_info) HA_CREATE_INFO;
2312            lex->create_info.options=$2 | $4;
2313            lex->create_info.default_table_charset= NULL;
2314            lex->name.str= 0;
2315            lex->name.length= 0;
2316            lex->create_last_non_select_table= lex->last_table();
2317          }
2318          create2
2319          {
2320            THD *thd= YYTHD;
2321            LEX *lex= thd->lex;
2322            lex->set_current_select(lex->select_lex);
2323            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
2324                !lex->create_info.db_type)
2325            {
2326              lex->create_info.db_type=
2327                lex->create_info.options & HA_LEX_CREATE_TMP_TABLE ?
2328                ha_default_temp_handlerton(thd) : ha_default_handlerton(thd);
2329              push_warning_printf(YYTHD, Sql_condition::SL_WARNING,
2330                                  ER_WARN_USING_OTHER_HANDLER,
2331                                  ER(ER_WARN_USING_OTHER_HANDLER),
2332                                  ha_resolve_storage_engine_name(lex->create_info.db_type),
2333                                  $5->table.str);
2334            }
2335            create_table_set_open_action_and_adjust_tables(lex);
2336          }
2337        | CREATE opt_unique_combo_clustering INDEX_SYM ident key_alg ON table_ident
2338          {
2339            if (add_create_index_prepare(Lex, $7))
2340              MYSQL_YYABORT;
2341          }
2342          '(' key_list ')' normal_key_options
2343          {
2344            if (add_create_index(Lex, $2, $4))
2345              MYSQL_YYABORT;
2346          }
2347          opt_index_lock_algorithm { }
2348        | CREATE fulltext INDEX_SYM ident init_key_options ON
2349          table_ident
2350          {
2351            if (add_create_index_prepare(Lex, $7))
2352              MYSQL_YYABORT;
2353          }
2354          '(' key_list ')' fulltext_key_options
2355          {
2356            if (add_create_index(Lex, $2, $4))
2357              MYSQL_YYABORT;
2358          }
2359          opt_index_lock_algorithm { }
2360        | CREATE spatial INDEX_SYM ident init_key_options ON
2361          table_ident
2362          {
2363            if (add_create_index_prepare(Lex, $7))
2364              MYSQL_YYABORT;
2365          }
2366          '(' key_list ')' spatial_key_options
2367          {
2368            if (add_create_index(Lex, $2, $4))
2369              MYSQL_YYABORT;
2370          }
2371          opt_index_lock_algorithm { }
2372        | CREATE DATABASE opt_if_not_exists ident
2373          {
2374            Lex->create_info.default_table_charset= NULL;
2375            Lex->create_info.used_fields= 0;
2376          }
2377          opt_create_database_options
2378          {
2379            LEX *lex=Lex;
2380            lex->sql_command=SQLCOM_CREATE_DB;
2381            lex->name= $4;
2382            lex->create_info.options=$3;
2383          }
2384        | CREATE
2385          {
2386            Lex->create_view_mode= VIEW_CREATE_NEW;
2387            Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
2388            Lex->create_view_suid= TRUE;
2389          }
2390          view_or_trigger_or_sp_or_event
2391          {}
2392        | CREATE USER opt_if_not_exists clear_privileges grant_list require_clause
2393                      connect_options opt_account_lock_password_expire_options
2394          {
2395            LEX *lex=Lex;
2396            lex->sql_command = SQLCOM_CREATE_USER;
2397            lex->create_info.options=$3;
2398          }
2399        | CREATE LOGFILE_SYM GROUP_SYM logfile_group_info
2400          {
2401            Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
2402          }
2403        | CREATE TABLESPACE_SYM tablespace_info
2404          {
2405            Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
2406          }
2407        | CREATE SERVER_SYM ident_or_text FOREIGN DATA_SYM WRAPPER_SYM
2408          ident_or_text OPTIONS_SYM '(' server_options_list ')'
2409          {
2410            Lex->sql_command= SQLCOM_CREATE_SERVER;
2411            if ($3.length == 0)
2412            {
2413              my_error(ER_WRONG_VALUE, MYF(0), "server name", "");
2414              MYSQL_YYABORT;
2415            }
2416            Lex->server_options.m_server_name= $3;
2417            Lex->server_options.set_scheme($7);
2418            Lex->m_sql_cmd=
2419              new (YYTHD->mem_root) Sql_cmd_create_server(&Lex->server_options);
2420          }
2421        | CREATE COMPRESSION_DICTIONARY_SYM opt_if_not_exists ident
2422          '(' create_compression_dictionary_allowed_expr ')'
2423          {
2424            Lex->sql_command= SQLCOM_CREATE_COMPRESSION_DICTIONARY;
2425            Lex->create_info.options= $3;
2426            Lex->ident= $4;
2427            Lex->default_value= $6;
2428          }
2429        ;
2430/*
2431  Only a limited subset of <expr> are allowed in
2432  CREATE COMPRESSION_DICTIONARY.
2433*/
2434create_compression_dictionary_allowed_expr:
2435          text_literal
2436          { ITEMIZE($1, &$$); }
2437        | variable
2438          {
2439            ITEMIZE($1, &$1);
2440            if ($1->type() == Item::FUNC_ITEM)
2441            {
2442              Item_func *item= (Item_func*) $1;
2443              if (item->functype() == Item_func::SUSERVAR_FUNC)
2444              {
2445                /*
2446                  Don't allow the following syntax:
2447                    CREATE COMPRESSION_DICTIONARY <dict>(@foo := expr)
2448                */
2449                my_syntax_error(ER(ER_SYNTAX_ERROR));
2450                MYSQL_YYABORT;
2451              }
2452            }
2453            $$= $1;
2454          }
2455        ;
2456
2457server_options_list:
2458          server_option
2459        | server_options_list ',' server_option
2460        ;
2461
2462server_option:
2463          USER TEXT_STRING_sys
2464          {
2465            Lex->server_options.set_username($2);
2466          }
2467        | HOST_SYM TEXT_STRING_sys
2468          {
2469            Lex->server_options.set_host($2);
2470          }
2471        | DATABASE TEXT_STRING_sys
2472          {
2473            Lex->server_options.set_db($2);
2474          }
2475        | OWNER_SYM TEXT_STRING_sys
2476          {
2477            Lex->server_options.set_owner($2);
2478          }
2479        | PASSWORD TEXT_STRING_sys
2480          {
2481            Lex->server_options.set_password($2);
2482            Lex->contains_plaintext_password= true;
2483          }
2484        | SOCKET_SYM TEXT_STRING_sys
2485          {
2486            Lex->server_options.set_socket($2);
2487          }
2488        | PORT_SYM ulong_num
2489          {
2490            Lex->server_options.set_port($2);
2491          }
2492        ;
2493
2494event_tail:
2495          EVENT_SYM opt_if_not_exists sp_name
2496          {
2497            THD *thd= YYTHD;
2498            LEX *lex=Lex;
2499
2500            lex->stmt_definition_begin= @1.cpp.start;
2501            lex->create_info.options= $2;
2502            if (!(lex->event_parse_data= Event_parse_data::new_instance(thd)))
2503              MYSQL_YYABORT;
2504            lex->event_parse_data->identifier= $3;
2505            lex->event_parse_data->on_completion=
2506                                  Event_parse_data::ON_COMPLETION_DROP;
2507
2508            lex->sql_command= SQLCOM_CREATE_EVENT;
2509            /* We need that for disallowing subqueries */
2510          }
2511          ON SCHEDULE_SYM ev_schedule_time
2512          opt_ev_on_completion
2513          opt_ev_status
2514          opt_ev_comment
2515          DO_SYM ev_sql_stmt
2516          {
2517            /*
2518              sql_command is set here because some rules in ev_sql_stmt
2519              can overwrite it
2520            */
2521            Lex->sql_command= SQLCOM_CREATE_EVENT;
2522          }
2523        ;
2524
2525ev_schedule_time:
2526          EVERY_SYM expr interval
2527          {
2528            ITEMIZE($2, &$2);
2529
2530            Lex->event_parse_data->item_expression= $2;
2531            Lex->event_parse_data->interval= $3;
2532          }
2533          ev_starts
2534          ev_ends
2535        | AT_SYM expr
2536          {
2537            ITEMIZE($2, &$2);
2538
2539            Lex->event_parse_data->item_execute_at= $2;
2540          }
2541        ;
2542
2543opt_ev_status:
2544          /* empty */ { $$= 0; }
2545        | ENABLE_SYM
2546          {
2547            Lex->event_parse_data->status= Event_parse_data::ENABLED;
2548            Lex->event_parse_data->status_changed= true;
2549            $$= 1;
2550          }
2551        | DISABLE_SYM ON SLAVE
2552          {
2553            Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
2554            Lex->event_parse_data->status_changed= true;
2555            $$= 1;
2556          }
2557        | DISABLE_SYM
2558          {
2559            Lex->event_parse_data->status= Event_parse_data::DISABLED;
2560            Lex->event_parse_data->status_changed= true;
2561            $$= 1;
2562          }
2563        ;
2564
2565ev_starts:
2566          /* empty */
2567          {
2568            Item *item= new (YYTHD->mem_root) Item_func_now_local(0);
2569            if (item == NULL)
2570              MYSQL_YYABORT;
2571            Lex->event_parse_data->item_starts= item;
2572          }
2573        | STARTS_SYM expr
2574          {
2575            ITEMIZE($2, &$2);
2576
2577            Lex->event_parse_data->item_starts= $2;
2578          }
2579        ;
2580
2581ev_ends:
2582          /* empty */
2583        | ENDS_SYM expr
2584          {
2585            ITEMIZE($2, &$2);
2586
2587            Lex->event_parse_data->item_ends= $2;
2588          }
2589        ;
2590
2591opt_ev_on_completion:
2592          /* empty */ { $$= 0; }
2593        | ev_on_completion
2594        ;
2595
2596ev_on_completion:
2597          ON COMPLETION_SYM PRESERVE_SYM
2598          {
2599            Lex->event_parse_data->on_completion=
2600                                  Event_parse_data::ON_COMPLETION_PRESERVE;
2601            $$= 1;
2602          }
2603        | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
2604          {
2605            Lex->event_parse_data->on_completion=
2606                                  Event_parse_data::ON_COMPLETION_DROP;
2607            $$= 1;
2608          }
2609        ;
2610
2611opt_ev_comment:
2612          /* empty */ { $$= 0; }
2613        | COMMENT_SYM TEXT_STRING_sys
2614          {
2615            Lex->comment= Lex->event_parse_data->comment= $2;
2616            $$= 1;
2617          }
2618        ;
2619
2620ev_sql_stmt:
2621          {
2622            THD *thd= YYTHD;
2623            LEX *lex= thd->lex;
2624
2625            /*
2626              This stops the following :
2627              - CREATE EVENT ... DO CREATE EVENT ...;
2628              - ALTER  EVENT ... DO CREATE EVENT ...;
2629              - CREATE EVENT ... DO ALTER EVENT DO ....;
2630              - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END|
2631              This allows:
2632              - CREATE EVENT ... DO DROP EVENT yyy;
2633              - CREATE EVENT ... DO ALTER EVENT yyy;
2634                (the nested ALTER EVENT can have anything but DO clause)
2635              - ALTER  EVENT ... DO ALTER EVENT yyy;
2636                (the nested ALTER EVENT can have anything but DO clause)
2637              - ALTER  EVENT ... DO DROP EVENT yyy;
2638              - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END|
2639                (the nested ALTER EVENT can have anything but DO clause)
2640              - CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
2641            */
2642            if (lex->sphead)
2643            {
2644              my_error(ER_EVENT_RECURSION_FORBIDDEN, MYF(0));
2645              MYSQL_YYABORT;
2646            }
2647
2648            sp_head *sp= sp_start_parsing(thd,
2649                                          SP_TYPE_EVENT,
2650                                          lex->event_parse_data->identifier);
2651
2652            if (!sp)
2653              MYSQL_YYABORT;
2654
2655            lex->sphead= sp;
2656
2657            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
2658            sp->m_chistics= &lex->sp_chistics;
2659
2660            /*
2661              Set a body start to the end of the last preprocessed token
2662              before ev_sql_stmt:
2663            */
2664            sp->set_body_start(thd, @0.cpp.end);
2665          }
2666          ev_sql_stmt_inner
2667          {
2668            THD *thd= YYTHD;
2669            LEX *lex= thd->lex;
2670
2671            sp_finish_parsing(thd);
2672
2673            lex->sp_chistics.suid= SP_IS_SUID;  //always the definer!
2674            lex->event_parse_data->body_changed= TRUE;
2675          }
2676        ;
2677
2678ev_sql_stmt_inner:
2679          sp_proc_stmt_statement
2680        | sp_proc_stmt_return
2681        | sp_proc_stmt_if
2682        | case_stmt_specification
2683        | sp_labeled_block
2684        | sp_unlabeled_block
2685        | sp_labeled_control
2686        | sp_proc_stmt_unlabeled
2687        | sp_proc_stmt_leave
2688        | sp_proc_stmt_iterate
2689        | sp_proc_stmt_open
2690        | sp_proc_stmt_fetch
2691        | sp_proc_stmt_close
2692        ;
2693
2694clear_privileges:
2695          clear_password_expire_options
2696          {
2697           LEX *lex=Lex;
2698           lex->users_list.empty();
2699           lex->columns.empty();
2700           lex->grant= lex->grant_tot_col= 0;
2701           lex->all_privileges= 0;
2702           lex->select_lex->db= NULL;
2703           lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
2704           lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
2705           lex->alter_password.update_account_locked_column= false;
2706           lex->alter_password.account_locked= false;
2707           memset(&(lex->mqh), 0, sizeof(lex->mqh));
2708         }
2709        ;
2710
2711clear_password_expire_options:
2712         /* Nothing */
2713         {
2714           LEX *lex=Lex;
2715           lex->alter_password.update_password_expired_fields= false;
2716           lex->alter_password.update_password_expired_column= false;
2717           lex->alter_password.use_default_password_lifetime= true;
2718           lex->alter_password.expire_after_days= 0;
2719         }
2720        ;
2721
2722sp_name:
2723          ident '.' ident
2724          {
2725            if (!$1.str ||
2726                (check_and_convert_db_name(&$1, FALSE) != IDENT_NAME_OK))
2727              MYSQL_YYABORT;
2728            if (sp_check_name(&$3))
2729            {
2730              MYSQL_YYABORT;
2731            }
2732            $$= new sp_name(to_lex_cstring($1), $3, true);
2733            if ($$ == NULL)
2734              MYSQL_YYABORT;
2735            $$->init_qname(YYTHD);
2736          }
2737        | ident
2738          {
2739            THD *thd= YYTHD;
2740            LEX *lex= thd->lex;
2741            LEX_STRING db;
2742            if (sp_check_name(&$1))
2743            {
2744              MYSQL_YYABORT;
2745            }
2746            if (lex->copy_db_to(&db.str, &db.length))
2747              MYSQL_YYABORT;
2748            $$= new sp_name(to_lex_cstring(db), $1, false);
2749            if ($$ == NULL)
2750              MYSQL_YYABORT;
2751            $$->init_qname(thd);
2752          }
2753        ;
2754
2755sp_a_chistics:
2756          /* Empty */ {}
2757        | sp_a_chistics sp_chistic {}
2758        ;
2759
2760sp_c_chistics:
2761          /* Empty */ {}
2762        | sp_c_chistics sp_c_chistic {}
2763        ;
2764
2765/* Characteristics for both create and alter */
2766sp_chistic:
2767          COMMENT_SYM TEXT_STRING_sys
2768          { Lex->sp_chistics.comment= $2; }
2769        | LANGUAGE_SYM SQL_SYM
2770          { /* Just parse it, we only have one language for now. */ }
2771        | NO_SYM SQL_SYM
2772          { Lex->sp_chistics.daccess= SP_NO_SQL; }
2773        | CONTAINS_SYM SQL_SYM
2774          { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; }
2775        | READS_SYM SQL_SYM DATA_SYM
2776          { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; }
2777        | MODIFIES_SYM SQL_SYM DATA_SYM
2778          { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; }
2779        | sp_suid
2780          {}
2781        ;
2782
2783/* Create characteristics */
2784sp_c_chistic:
2785          sp_chistic            { }
2786        | DETERMINISTIC_SYM     { Lex->sp_chistics.detistic= TRUE; }
2787        | not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
2788        ;
2789
2790sp_suid:
2791          SQL_SYM SECURITY_SYM DEFINER_SYM
2792          {
2793            Lex->sp_chistics.suid= SP_IS_SUID;
2794          }
2795        | SQL_SYM SECURITY_SYM INVOKER_SYM
2796          {
2797            Lex->sp_chistics.suid= SP_IS_NOT_SUID;
2798          }
2799        ;
2800
2801call:
2802          CALL_SYM sp_name
2803          {
2804            LEX *lex = Lex;
2805
2806            lex->sql_command= SQLCOM_CALL;
2807            lex->spname= $2;
2808            lex->call_value_list.empty();
2809            sp_add_used_routine(lex, YYTHD, $2, SP_TYPE_PROCEDURE);
2810          }
2811          opt_sp_cparam_list {}
2812        ;
2813
2814/* CALL parameters */
2815opt_sp_cparam_list:
2816          /* Empty */
2817        | '(' opt_sp_cparams ')'
2818        ;
2819
2820opt_sp_cparams:
2821          /* Empty */
2822        | sp_cparams
2823        ;
2824
2825sp_cparams:
2826          sp_cparams ',' expr
2827          {
2828            ITEMIZE($3, &$3);
2829
2830           Lex->call_value_list.push_back($3);
2831          }
2832        | expr
2833          {
2834            ITEMIZE($1, &$1);
2835
2836            Lex->call_value_list.push_back($1);
2837          }
2838        ;
2839
2840/* Stored FUNCTION parameter declaration list */
2841sp_fdparam_list:
2842          /* Empty */
2843        | sp_fdparams
2844        ;
2845
2846sp_fdparams:
2847          sp_fdparams ',' sp_fdparam
2848        | sp_fdparam
2849        ;
2850
2851sp_init_param:
2852          /* Empty */
2853          {
2854            LEX *lex= Lex;
2855
2856            lex->length= 0;
2857            lex->dec= 0;
2858            lex->type= 0;
2859
2860            lex->default_value= 0;
2861            lex->on_update_value= 0;
2862
2863            lex->comment= null_lex_str;
2864            lex->charset= NULL;
2865
2866            lex->interval_list.empty();
2867            lex->uint_geom_type= 0;
2868          }
2869        ;
2870
2871sp_fdparam:
2872          ident sp_init_param type_with_opt_collate
2873          {
2874            THD *thd= YYTHD;
2875            LEX *lex= thd->lex;
2876            sp_head *sp= lex->sphead;
2877            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
2878
2879            if (pctx->find_variable($1, TRUE))
2880            {
2881              my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
2882              MYSQL_YYABORT;
2883            }
2884
2885            sp_variable *spvar= pctx->add_variable(thd,
2886                                                   $1,
2887                                                   (enum enum_field_types) $3,
2888                                                   sp_variable::MODE_IN);
2889
2890            if (fill_field_definition(thd, sp,
2891                                      (enum enum_field_types) $3,
2892                                      &spvar->field_def))
2893            {
2894              MYSQL_YYABORT;
2895            }
2896            spvar->field_def.field_name= spvar->name.str;
2897            spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
2898          }
2899        ;
2900
2901/* Stored PROCEDURE parameter declaration list */
2902sp_pdparam_list:
2903          /* Empty */
2904        | sp_pdparams
2905        ;
2906
2907sp_pdparams:
2908          sp_pdparams ',' sp_pdparam
2909        | sp_pdparam
2910        ;
2911
2912sp_pdparam:
2913          sp_opt_inout sp_init_param ident type_with_opt_collate
2914          {
2915            THD *thd= YYTHD;
2916            LEX *lex= thd->lex;
2917            sp_head *sp= lex->sphead;
2918            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
2919
2920            if (pctx->find_variable($3, TRUE))
2921            {
2922              my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
2923              MYSQL_YYABORT;
2924            }
2925            sp_variable *spvar= pctx->add_variable(thd,
2926                                                   $3,
2927                                                   (enum enum_field_types) $4,
2928                                                   (sp_variable::enum_mode) $1);
2929
2930            if (fill_field_definition(thd, sp,
2931                                      (enum enum_field_types) $4,
2932                                      &spvar->field_def))
2933            {
2934              MYSQL_YYABORT;
2935            }
2936            spvar->field_def.field_name= spvar->name.str;
2937            spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
2938          }
2939        ;
2940
2941sp_opt_inout:
2942          /* Empty */ { $$= sp_variable::MODE_IN; }
2943        | IN_SYM      { $$= sp_variable::MODE_IN; }
2944        | OUT_SYM     { $$= sp_variable::MODE_OUT; }
2945        | INOUT_SYM   { $$= sp_variable::MODE_INOUT; }
2946        ;
2947
2948sp_proc_stmts:
2949          /* Empty */ {}
2950        | sp_proc_stmts  sp_proc_stmt ';'
2951        ;
2952
2953sp_proc_stmts1:
2954          sp_proc_stmt ';' {}
2955        | sp_proc_stmts1  sp_proc_stmt ';'
2956        ;
2957
2958sp_decls:
2959          /* Empty */
2960          {
2961            $$.vars= $$.conds= $$.hndlrs= $$.curs= 0;
2962          }
2963        | sp_decls sp_decl ';'
2964          {
2965            /* We check for declarations out of (standard) order this way
2966              because letting the grammar rules reflect it caused tricky
2967               shift/reduce conflicts with the wrong result. (And we get
2968               better error handling this way.) */
2969            if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs))
2970            { /* Variable or condition following cursor or handler */
2971              my_message(ER_SP_VARCOND_AFTER_CURSHNDLR,
2972                         ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0));
2973              MYSQL_YYABORT;
2974            }
2975            if ($2.curs && $1.hndlrs)
2976            { /* Cursor following handler */
2977              my_message(ER_SP_CURSOR_AFTER_HANDLER,
2978                         ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0));
2979              MYSQL_YYABORT;
2980            }
2981            $$.vars= $1.vars + $2.vars;
2982            $$.conds= $1.conds + $2.conds;
2983            $$.hndlrs= $1.hndlrs + $2.hndlrs;
2984            $$.curs= $1.curs + $2.curs;
2985          }
2986        ;
2987
2988sp_decl:
2989          DECLARE_SYM           /*$1*/
2990          sp_decl_idents        /*$2*/
2991          {                     /*$3*/
2992            THD *thd= YYTHD;
2993            LEX *lex= thd->lex;
2994            sp_head *sp= lex->sphead;
2995            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
2996
2997            sp->reset_lex(thd);
2998            pctx->declare_var_boundary($2);
2999          }
3000          type_with_opt_collate /*$4*/
3001          sp_opt_default        /*$5*/
3002          {                     /*$6*/
3003            THD *thd= YYTHD;
3004            LEX *lex= thd->lex;
3005            sp_head *sp= lex->sphead;
3006            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3007            uint num_vars= pctx->context_var_count();
3008            enum enum_field_types var_type= (enum enum_field_types) $4;
3009            Item *dflt_value_item= $5;
3010            const bool has_default_clause = (dflt_value_item != NULL);
3011            bool is_const_item = false;
3012
3013            LEX_STRING dflt_value_query= EMPTY_STR;
3014
3015            if (has_default_clause) {
3016              // Handling a NEG_FUNC wrapping a constant.
3017              if (dflt_value_item->type() == Item::FUNC_ITEM) {
3018                Item_func *func_item = down_cast<Item_func *>(dflt_value_item);
3019                if (func_item->functype() == Item_func::NEG_FUNC) {
3020                  is_const_item = true;
3021                }
3022              } else if (dflt_value_item->const_item()) {
3023                is_const_item = true;
3024              }
3025
3026              // sp_opt_default only pushes start ptr for DEFAULT clause.
3027              const char *expr_start_ptr=
3028                sp->m_parser_data.pop_expr_start_ptr();
3029              if (lex->is_metadata_used())
3030              {
3031                dflt_value_query= make_string(thd, expr_start_ptr,
3032                                              @5.raw.end);
3033                if (!dflt_value_query.str)
3034                  MYSQL_YYABORT;
3035              }
3036            }
3037            else
3038            {
3039              dflt_value_item= new (thd->mem_root) Item_null();
3040
3041              if (dflt_value_item == NULL)
3042                MYSQL_YYABORT;
3043            }
3044
3045            sp_variable *first_spvar = NULL;
3046            const uint first_var_num = num_vars - $2;
3047
3048            // We can have several variables in DECLARE statement.
3049            // We need to create an sp_instr_set instruction for each variable.
3050
3051            for (uint i = first_var_num; i < num_vars; i++)
3052            {
3053              uint var_idx= pctx->var_context2runtime(i);
3054              sp_variable *spvar= pctx->find_variable(var_idx);
3055
3056              if (!spvar)
3057                MYSQL_YYABORT;
3058
3059              spvar->type= var_type;
3060
3061              // Transforming the following declare statements having non-const
3062              // expressions:
3063              // DECLARE a, b, c type DEFAULT expr;
3064              //              to
3065              // DECLARE a type DEFAULT expr, b type DEFAULT a,
3066              //         c type DEFAULT a;
3067
3068              if (i == first_var_num) {
3069                first_spvar = spvar;
3070              } else if (has_default_clause && !is_const_item) {
3071                Item_splocal *item =
3072                  NEW_PTN Item_splocal(first_spvar->name, first_spvar->offset,
3073                                       first_spvar->type, 0, 0);
3074                if (item == NULL)
3075                  MYSQL_YYABORT; // OOM
3076#ifndef NDEBUG
3077                item->m_sp = lex->sphead;
3078#endif
3079                dflt_value_item = item;
3080              }
3081              spvar->default_value= dflt_value_item;
3082
3083              if (has_default_clause && !is_const_item && (i > first_var_num)) {
3084                dflt_value_query = first_spvar->name;
3085              }
3086
3087              if (fill_field_definition(thd, sp, var_type, &spvar->field_def))
3088                MYSQL_YYABORT;
3089
3090              spvar->field_def.field_name= spvar->name.str;
3091              spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
3092
3093              /* The last instruction is responsible for freeing LEX. */
3094
3095              sp_instr_set *is=
3096                new (thd->mem_root)
3097                  sp_instr_set(sp->instructions(),
3098                               lex,
3099                               var_idx,
3100                               dflt_value_item,
3101                               dflt_value_query,
3102                               (i == num_vars - 1));
3103
3104              if (!is || sp->add_instr(thd, is))
3105                MYSQL_YYABORT;
3106            }
3107
3108            pctx->declare_var_boundary(0);
3109            if (sp->restore_lex(thd))
3110              MYSQL_YYABORT;
3111            $$.vars= $2;
3112            $$.conds= $$.hndlrs= $$.curs= 0;
3113          }
3114        | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
3115          {
3116            THD *thd= YYTHD;
3117            LEX *lex= thd->lex;
3118            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3119
3120            if (pctx->find_condition($2, TRUE))
3121            {
3122              my_error(ER_SP_DUP_COND, MYF(0), $2.str);
3123              MYSQL_YYABORT;
3124            }
3125            if(pctx->add_condition(thd, $2, $5))
3126              MYSQL_YYABORT;
3127            lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // DECLARE COND FOR
3128            $$.vars= $$.hndlrs= $$.curs= 0;
3129            $$.conds= 1;
3130          }
3131        | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM
3132          {
3133            THD *thd= YYTHD;
3134            LEX *lex= thd->lex;
3135            sp_head *sp= lex->sphead;
3136
3137            sp_pcontext *parent_pctx= lex->get_sp_current_parsing_ctx();
3138
3139            sp_pcontext *handler_pctx=
3140              parent_pctx->push_context(thd, sp_pcontext::HANDLER_SCOPE);
3141
3142            sp_handler *h=
3143              parent_pctx->add_handler(thd, (sp_handler::enum_type) $2);
3144
3145            lex->set_sp_current_parsing_ctx(handler_pctx);
3146
3147            sp_instr_hpush_jump *i=
3148              new (thd->mem_root)
3149                sp_instr_hpush_jump(sp->instructions(), handler_pctx, h);
3150
3151            if (!i || sp->add_instr(thd, i))
3152              MYSQL_YYABORT;
3153
3154            if ($2 == sp_handler::CONTINUE)
3155            {
3156              // Mark the end of CONTINUE handler scope.
3157
3158              if (sp->m_parser_data.add_backpatch_entry(
3159                    i, handler_pctx->last_label()))
3160              {
3161                MYSQL_YYABORT;
3162              }
3163            }
3164
3165            if (sp->m_parser_data.add_backpatch_entry(
3166                  i, handler_pctx->push_label(thd, EMPTY_STR, 0)))
3167            {
3168              MYSQL_YYABORT;
3169            }
3170
3171            lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // DECL HANDLER FOR
3172          }
3173          sp_hcond_list sp_proc_stmt
3174          {
3175            THD *thd= YYTHD;
3176            LEX *lex= Lex;
3177            sp_head *sp= lex->sphead;
3178            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3179            sp_label *hlab= pctx->pop_label(); /* After this hdlr */
3180
3181            if ($2 == sp_handler::CONTINUE)
3182            {
3183              sp_instr_hreturn *i=
3184                new (thd->mem_root) sp_instr_hreturn(sp->instructions(), pctx);
3185
3186              if (!i || sp->add_instr(thd, i))
3187                MYSQL_YYABORT;
3188            }
3189            else
3190            {  /* EXIT or UNDO handler, just jump to the end of the block */
3191              sp_instr_hreturn *i=
3192                new (thd->mem_root) sp_instr_hreturn(sp->instructions(), pctx);
3193
3194              if (i == NULL ||
3195                  sp->add_instr(thd, i) ||
3196                  sp->m_parser_data.add_backpatch_entry(i, pctx->last_label()))
3197                MYSQL_YYABORT;
3198            }
3199
3200            sp->m_parser_data.do_backpatch(hlab, sp->instructions());
3201
3202            lex->set_sp_current_parsing_ctx(pctx->pop_context());
3203
3204            $$.vars= $$.conds= $$.curs= 0;
3205            $$.hndlrs= 1;
3206          }
3207        | DECLARE_SYM   /*$1*/
3208          ident         /*$2*/
3209          CURSOR_SYM    /*$3*/
3210          FOR_SYM       /*$4*/
3211          {             /*$5*/
3212            THD *thd= YYTHD;
3213            LEX *lex= Lex;
3214            sp_head *sp= lex->sphead;
3215
3216            sp->reset_lex(thd);
3217            sp->m_parser_data.set_current_stmt_start_ptr(@4.raw.end);
3218          }
3219          select        /*$6*/
3220          {             /*$7*/
3221            CONTEXTUALIZE($6);
3222
3223            THD *thd= YYTHD;
3224            LEX *cursor_lex= Lex;
3225            sp_head *sp= cursor_lex->sphead;
3226
3227assert(cursor_lex->sql_command == SQLCOM_SELECT);
3228
3229            if (cursor_lex->result)
3230            {
3231              my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT),
3232                         MYF(0));
3233              MYSQL_YYABORT;
3234            }
3235
3236            cursor_lex->sp_lex_in_use= true;
3237
3238            if (sp->restore_lex(thd))
3239              MYSQL_YYABORT;
3240
3241            LEX *lex= Lex;
3242            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3243
3244            uint offp;
3245
3246            if (pctx->find_cursor($2, &offp, TRUE))
3247            {
3248              my_error(ER_SP_DUP_CURS, MYF(0), $2.str);
3249              delete cursor_lex;
3250              MYSQL_YYABORT;
3251            }
3252
3253            LEX_STRING cursor_query= EMPTY_STR;
3254
3255            if (cursor_lex->is_metadata_used())
3256            {
3257              cursor_query=
3258                make_string(thd,
3259                            sp->m_parser_data.get_current_stmt_start_ptr(),
3260                            @6.raw.end);
3261
3262              if (!cursor_query.str)
3263                MYSQL_YYABORT;
3264            }
3265
3266            sp_instr_cpush *i=
3267              new (thd->mem_root)
3268                sp_instr_cpush(sp->instructions(), pctx,
3269                               cursor_lex, cursor_query,
3270                               pctx->current_cursor_count());
3271
3272            if (i == NULL ||
3273                sp->add_instr(thd, i) ||
3274                pctx->add_cursor($2))
3275            {
3276              MYSQL_YYABORT;
3277            }
3278
3279            $$.vars= $$.conds= $$.hndlrs= 0;
3280            $$.curs= 1;
3281          }
3282        ;
3283
3284sp_handler_type:
3285          EXIT_SYM      { $$= sp_handler::EXIT; }
3286        | CONTINUE_SYM  { $$= sp_handler::CONTINUE; }
3287        /*| UNDO_SYM      { QQ No yet } */
3288        ;
3289
3290sp_hcond_list:
3291          sp_hcond_element
3292          { $$= 1; }
3293        | sp_hcond_list ',' sp_hcond_element
3294          { $$+= 1; }
3295        ;
3296
3297sp_hcond_element:
3298          sp_hcond
3299          {
3300            LEX *lex= Lex;
3301            sp_head *sp= lex->sphead;
3302            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3303            sp_pcontext *parent_pctx= pctx->parent_context();
3304
3305            if (parent_pctx->check_duplicate_handler($1))
3306            {
3307              my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
3308              MYSQL_YYABORT;
3309            }
3310            else
3311            {
3312              sp_instr_hpush_jump *i=
3313                (sp_instr_hpush_jump *)sp->last_instruction();
3314
3315              i->add_condition($1);
3316            }
3317          }
3318        ;
3319
3320sp_cond:
3321          ulong_num
3322          { /* mysql errno */
3323            if ($1 == 0)
3324            {
3325              my_error(ER_WRONG_VALUE, MYF(0), "CONDITION", "0");
3326              MYSQL_YYABORT;
3327            }
3328            $$= new (YYTHD->mem_root) sp_condition_value($1);
3329            if ($$ == NULL)
3330              MYSQL_YYABORT;
3331          }
3332        | sqlstate
3333        ;
3334
3335sqlstate:
3336          SQLSTATE_SYM opt_value TEXT_STRING_literal
3337          { /* SQLSTATE */
3338
3339            /*
3340              An error is triggered:
3341                - if the specified string is not a valid SQLSTATE,
3342                - or if it represents the completion condition -- it is not
3343                  allowed to SIGNAL, or declare a handler for the completion
3344                  condition.
3345            */
3346            if (!is_sqlstate_valid(&$3) || is_sqlstate_completion($3.str))
3347            {
3348              my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str);
3349              MYSQL_YYABORT;
3350            }
3351            $$= new (YYTHD->mem_root) sp_condition_value($3.str);
3352            if ($$ == NULL)
3353              MYSQL_YYABORT;
3354          }
3355        ;
3356
3357opt_value:
3358          /* Empty */  {}
3359        | VALUE_SYM    {}
3360        ;
3361
3362sp_hcond:
3363          sp_cond
3364          {
3365            $$= $1;
3366          }
3367        | ident /* CONDITION name */
3368          {
3369            LEX *lex= Lex;
3370            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3371
3372            $$= pctx->find_condition($1, false);
3373
3374            if ($$ == NULL)
3375            {
3376              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3377              MYSQL_YYABORT;
3378            }
3379          }
3380        | SQLWARNING_SYM /* SQLSTATEs 01??? */
3381          {
3382            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::WARNING);
3383            if ($$ == NULL)
3384              MYSQL_YYABORT;
3385          }
3386        | not FOUND_SYM /* SQLSTATEs 02??? */
3387          {
3388            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::NOT_FOUND);
3389            if ($$ == NULL)
3390              MYSQL_YYABORT;
3391          }
3392        | SQLEXCEPTION_SYM /* All other SQLSTATEs */
3393          {
3394            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::EXCEPTION);
3395            if ($$ == NULL)
3396              MYSQL_YYABORT;
3397          }
3398        ;
3399
3400signal_stmt:
3401          SIGNAL_SYM signal_value opt_set_signal_information
3402          {
3403            THD *thd= YYTHD;
3404            LEX *lex= thd->lex;
3405
3406            lex->sql_command= SQLCOM_SIGNAL;
3407            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_signal($2, $3);
3408            if (lex->m_sql_cmd == NULL)
3409              MYSQL_YYABORT;
3410          }
3411        ;
3412
3413signal_value:
3414          ident
3415          {
3416            LEX *lex= Lex;
3417            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3418
3419            if (!pctx)
3420            {
3421              /* SIGNAL foo cannot be used outside of stored programs */
3422              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3423              MYSQL_YYABORT;
3424            }
3425
3426            sp_condition_value *cond= pctx->find_condition($1, false);
3427
3428            if (!cond)
3429            {
3430              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3431              MYSQL_YYABORT;
3432            }
3433            if (cond->type != sp_condition_value::SQLSTATE)
3434            {
3435              my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0));
3436              MYSQL_YYABORT;
3437            }
3438            $$= cond;
3439          }
3440        | sqlstate
3441          { $$= $1; }
3442        ;
3443
3444opt_signal_value:
3445          /* empty */
3446          { $$= NULL; }
3447        | signal_value
3448          { $$= $1; }
3449        ;
3450
3451opt_set_signal_information:
3452          /* empty */
3453          { $$= new (YYTHD->mem_root) Set_signal_information(); }
3454        | SET signal_information_item_list
3455          { $$= $2; }
3456        ;
3457
3458signal_information_item_list:
3459          signal_condition_information_item_name EQ signal_allowed_expr
3460          {
3461            $$= new (YYTHD->mem_root) Set_signal_information();
3462            if ($$->set_item($1, $3))
3463              MYSQL_YYABORT;
3464          }
3465        | signal_information_item_list ','
3466          signal_condition_information_item_name EQ signal_allowed_expr
3467          {
3468            $$= $1;
3469            if ($$->set_item($3, $5))
3470              MYSQL_YYABORT;
3471          }
3472        ;
3473
3474/*
3475  Only a limited subset of <expr> are allowed in SIGNAL/RESIGNAL.
3476*/
3477signal_allowed_expr:
3478          literal
3479          { ITEMIZE($1, &$$); }
3480        | variable
3481          {
3482            ITEMIZE($1, &$1);
3483
3484            if ($1->type() == Item::FUNC_ITEM)
3485            {
3486              Item_func *item= (Item_func*) $1;
3487              if (item->functype() == Item_func::SUSERVAR_FUNC)
3488              {
3489                /*
3490                  Don't allow the following syntax:
3491                    SIGNAL/RESIGNAL ...
3492                    SET <signal condition item name> = @foo := expr
3493                */
3494                my_syntax_error(ER(ER_SYNTAX_ERROR));
3495                MYSQL_YYABORT;
3496              }
3497            }
3498            $$= $1;
3499          }
3500        | simple_ident
3501          { ITEMIZE($1, &$$); }
3502        ;
3503
3504/* conditions that can be set in signal / resignal */
3505signal_condition_information_item_name:
3506          CLASS_ORIGIN_SYM
3507          { $$= CIN_CLASS_ORIGIN; }
3508        | SUBCLASS_ORIGIN_SYM
3509          { $$= CIN_SUBCLASS_ORIGIN; }
3510        | CONSTRAINT_CATALOG_SYM
3511          { $$= CIN_CONSTRAINT_CATALOG; }
3512        | CONSTRAINT_SCHEMA_SYM
3513          { $$= CIN_CONSTRAINT_SCHEMA; }
3514        | CONSTRAINT_NAME_SYM
3515          { $$= CIN_CONSTRAINT_NAME; }
3516        | CATALOG_NAME_SYM
3517          { $$= CIN_CATALOG_NAME; }
3518        | SCHEMA_NAME_SYM
3519          { $$= CIN_SCHEMA_NAME; }
3520        | TABLE_NAME_SYM
3521          { $$= CIN_TABLE_NAME; }
3522        | COLUMN_NAME_SYM
3523          { $$= CIN_COLUMN_NAME; }
3524        | CURSOR_NAME_SYM
3525          { $$= CIN_CURSOR_NAME; }
3526        | MESSAGE_TEXT_SYM
3527          { $$= CIN_MESSAGE_TEXT; }
3528        | MYSQL_ERRNO_SYM
3529          { $$= CIN_MYSQL_ERRNO; }
3530        ;
3531
3532resignal_stmt:
3533          RESIGNAL_SYM opt_signal_value opt_set_signal_information
3534          {
3535            THD *thd= YYTHD;
3536            LEX *lex= thd->lex;
3537
3538            lex->sql_command= SQLCOM_RESIGNAL;
3539            lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // RESIGNAL doesn't clear diagnostics
3540            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_resignal($2, $3);
3541            if (lex->m_sql_cmd == NULL)
3542              MYSQL_YYABORT;
3543          }
3544        ;
3545
3546get_diagnostics:
3547          GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
3548          {
3549            Diagnostics_information *info= $4;
3550
3551            info->set_which_da($2);
3552
3553            Lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // GET DIAGS doesn't clear them.
3554            Lex->sql_command= SQLCOM_GET_DIAGNOSTICS;
3555            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_get_diagnostics(info);
3556
3557            if (Lex->m_sql_cmd == NULL)
3558              MYSQL_YYABORT;
3559          }
3560        ;
3561
3562which_area:
3563        /* If <which area> is not specified, then CURRENT is implicit. */
3564          { $$= Diagnostics_information::CURRENT_AREA; }
3565        | CURRENT_SYM
3566          { $$= Diagnostics_information::CURRENT_AREA; }
3567        | STACKED_SYM
3568          { $$= Diagnostics_information::STACKED_AREA; }
3569        ;
3570
3571diagnostics_information:
3572          statement_information
3573          {
3574            $$= new (YYTHD->mem_root) Statement_information($1);
3575            if ($$ == NULL)
3576              MYSQL_YYABORT;
3577          }
3578        | CONDITION_SYM condition_number condition_information
3579          {
3580            $$= new (YYTHD->mem_root) Condition_information($2, $3);
3581            if ($$ == NULL)
3582              MYSQL_YYABORT;
3583          }
3584        ;
3585
3586statement_information:
3587          statement_information_item
3588          {
3589            $$= new (YYTHD->mem_root) List<Statement_information_item>;
3590            if ($$ == NULL || $$->push_back($1))
3591              MYSQL_YYABORT;
3592          }
3593        | statement_information ',' statement_information_item
3594          {
3595            if ($1->push_back($3))
3596              MYSQL_YYABORT;
3597            $$= $1;
3598          }
3599        ;
3600
3601statement_information_item:
3602          simple_target_specification EQ statement_information_item_name
3603          {
3604            $$= new (YYTHD->mem_root) Statement_information_item($3, $1);
3605            if ($$ == NULL)
3606              MYSQL_YYABORT;
3607          }
3608
3609simple_target_specification:
3610          ident
3611          {
3612            THD *thd= YYTHD;
3613            LEX *lex= thd->lex;
3614            sp_head *sp= lex->sphead;
3615
3616            /*
3617              NOTE: lex->sphead is NULL if we're parsing something like
3618              'GET DIAGNOSTICS v' outside a stored program. We should throw
3619              ER_SP_UNDECLARED_VAR in such cases.
3620            */
3621
3622            if (!sp)
3623            {
3624              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
3625              MYSQL_YYABORT;
3626            }
3627
3628            $$=
3629              create_item_for_sp_var(
3630                thd, $1, NULL,
3631                sp->m_parser_data.get_current_stmt_start_ptr(),
3632                @1.raw.start,
3633                @1.raw.end);
3634
3635            if ($$ == NULL)
3636              MYSQL_YYABORT;
3637          }
3638        | '@' ident_or_text
3639          {
3640            $$= NEW_PTN Item_func_get_user_var(@$, $2);
3641            ITEMIZE($$, &$$);
3642          }
3643        ;
3644
3645statement_information_item_name:
3646          NUMBER_SYM
3647          { $$= Statement_information_item::NUMBER; }
3648        | ROW_COUNT_SYM
3649          { $$= Statement_information_item::ROW_COUNT; }
3650        ;
3651
3652/*
3653   Only a limited subset of <expr> are allowed in GET DIAGNOSTICS
3654   <condition number>, same subset as for SIGNAL/RESIGNAL.
3655*/
3656condition_number:
3657          signal_allowed_expr
3658          { $$= $1; }
3659        ;
3660
3661condition_information:
3662          condition_information_item
3663          {
3664            $$= new (YYTHD->mem_root) List<Condition_information_item>;
3665            if ($$ == NULL || $$->push_back($1))
3666              MYSQL_YYABORT;
3667          }
3668        | condition_information ',' condition_information_item
3669          {
3670            if ($1->push_back($3))
3671              MYSQL_YYABORT;
3672            $$= $1;
3673          }
3674        ;
3675
3676condition_information_item:
3677          simple_target_specification EQ condition_information_item_name
3678          {
3679            $$= new (YYTHD->mem_root) Condition_information_item($3, $1);
3680            if ($$ == NULL)
3681              MYSQL_YYABORT;
3682          }
3683
3684condition_information_item_name:
3685          CLASS_ORIGIN_SYM
3686          { $$= Condition_information_item::CLASS_ORIGIN; }
3687        | SUBCLASS_ORIGIN_SYM
3688          { $$= Condition_information_item::SUBCLASS_ORIGIN; }
3689        | CONSTRAINT_CATALOG_SYM
3690          { $$= Condition_information_item::CONSTRAINT_CATALOG; }
3691        | CONSTRAINT_SCHEMA_SYM
3692          { $$= Condition_information_item::CONSTRAINT_SCHEMA; }
3693        | CONSTRAINT_NAME_SYM
3694          { $$= Condition_information_item::CONSTRAINT_NAME; }
3695        | CATALOG_NAME_SYM
3696          { $$= Condition_information_item::CATALOG_NAME; }
3697        | SCHEMA_NAME_SYM
3698          { $$= Condition_information_item::SCHEMA_NAME; }
3699        | TABLE_NAME_SYM
3700          { $$= Condition_information_item::TABLE_NAME; }
3701        | COLUMN_NAME_SYM
3702          { $$= Condition_information_item::COLUMN_NAME; }
3703        | CURSOR_NAME_SYM
3704          { $$= Condition_information_item::CURSOR_NAME; }
3705        | MESSAGE_TEXT_SYM
3706          { $$= Condition_information_item::MESSAGE_TEXT; }
3707        | MYSQL_ERRNO_SYM
3708          { $$= Condition_information_item::MYSQL_ERRNO; }
3709        | RETURNED_SQLSTATE_SYM
3710          { $$= Condition_information_item::RETURNED_SQLSTATE; }
3711        ;
3712
3713sp_decl_idents:
3714          ident
3715          {
3716            /* NOTE: field definition is filled in sp_decl section. */
3717
3718            THD *thd= YYTHD;
3719            LEX *lex= thd->lex;
3720            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3721
3722            if (pctx->find_variable($1, TRUE))
3723            {
3724              my_error(ER_SP_DUP_VAR, MYF(0), $1.str);
3725              MYSQL_YYABORT;
3726            }
3727
3728            pctx->add_variable(thd,
3729                               $1,
3730                               MYSQL_TYPE_DECIMAL,
3731                               sp_variable::MODE_IN);
3732            $$= 1;
3733          }
3734        | sp_decl_idents ',' ident
3735          {
3736            /* NOTE: field definition is filled in sp_decl section. */
3737
3738            THD *thd= YYTHD;
3739            LEX *lex= thd->lex;
3740            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3741
3742            if (pctx->find_variable($3, TRUE))
3743            {
3744              my_error(ER_SP_DUP_VAR, MYF(0), $3.str);
3745              MYSQL_YYABORT;
3746            }
3747
3748            pctx->add_variable(thd,
3749                               $3,
3750                               MYSQL_TYPE_DECIMAL,
3751                               sp_variable::MODE_IN);
3752            $$= $1 + 1;
3753          }
3754        ;
3755
3756sp_opt_default:
3757        /* Empty */
3758          { $$ = NULL; }
3759        | DEFAULT
3760          { Lex->sphead->m_parser_data.push_expr_start_ptr(@1.raw.end); }
3761          expr
3762          {
3763            ITEMIZE($3, &$3);
3764
3765            $$ = $3;
3766          }
3767        ;
3768
3769sp_proc_stmt:
3770          sp_proc_stmt_statement
3771        | sp_proc_stmt_return
3772        | sp_proc_stmt_if
3773        | case_stmt_specification
3774        | sp_labeled_block
3775        | sp_unlabeled_block
3776        | sp_labeled_control
3777        | sp_proc_stmt_unlabeled
3778        | sp_proc_stmt_leave
3779        | sp_proc_stmt_iterate
3780        | sp_proc_stmt_open
3781        | sp_proc_stmt_fetch
3782        | sp_proc_stmt_close
3783        ;
3784
3785sp_proc_stmt_if:
3786          IF
3787          { Lex->sphead->m_parser_data.new_cont_backpatch(); }
3788          sp_if END IF
3789          {
3790            sp_head *sp= Lex->sphead;
3791
3792            sp->m_parser_data.do_cont_backpatch(sp->instructions());
3793          }
3794        ;
3795
3796sp_proc_stmt_statement:
3797          {
3798            THD *thd= YYTHD;
3799            LEX *lex= thd->lex;
3800            sp_head *sp= lex->sphead;
3801
3802            sp->reset_lex(thd);
3803            sp->m_parser_data.set_current_stmt_start_ptr(yylloc.raw.start);
3804          }
3805          statement
3806          {
3807            THD *thd= YYTHD;
3808            LEX *lex= thd->lex;
3809            sp_head *sp= lex->sphead;
3810
3811            sp->m_flags|= sp_get_flags_for_command(lex);
3812            if (lex->sql_command == SQLCOM_CHANGE_DB)
3813            { /* "USE db" doesn't work in a procedure */
3814              my_error(ER_SP_BADSTATEMENT, MYF(0), "USE");
3815              MYSQL_YYABORT;
3816            }
3817            /*
3818              Don't add an instruction for SET statements, since all
3819              instructions for them were already added during processing
3820              of "set" rule.
3821            */
3822            assert(lex->sql_command != SQLCOM_SET_OPTION ||
3823            lex->var_list.is_empty());
3824            if (lex->sql_command != SQLCOM_SET_OPTION)
3825            {
3826              /* Extract the query statement from the tokenizer. */
3827
3828              LEX_STRING query=
3829                make_string(thd,
3830                            sp->m_parser_data.get_current_stmt_start_ptr(),
3831                            @2.raw.end);
3832
3833              if (!query.str)
3834                MYSQL_YYABORT;
3835
3836              /* Add instruction. */
3837
3838              sp_instr_stmt *i=
3839                new (thd->mem_root)
3840                  sp_instr_stmt(sp->instructions(), lex, query);
3841
3842              if (!i || sp->add_instr(thd, i))
3843                MYSQL_YYABORT;
3844            }
3845
3846            if (sp->restore_lex(thd))
3847              MYSQL_YYABORT;
3848          }
3849        ;
3850
3851sp_proc_stmt_return:
3852          RETURN_SYM    /*$1*/
3853          {             /*$2*/
3854            THD *thd= YYTHD;
3855            LEX *lex= thd->lex;
3856            sp_head *sp= lex->sphead;
3857
3858            sp->reset_lex(thd);
3859
3860            sp->m_parser_data.push_expr_start_ptr(@1.raw.end);
3861          }
3862          expr          /*$3*/
3863          {             /*$4*/
3864            ITEMIZE($3, &$3);
3865
3866            THD *thd= YYTHD;
3867            LEX *lex= thd->lex;
3868            sp_head *sp= lex->sphead;
3869
3870            /* Extract expression string. */
3871
3872            LEX_STRING expr_query= EMPTY_STR;
3873            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
3874
3875            if (lex->is_metadata_used())
3876            {
3877              expr_query= make_string(thd, expr_start_ptr, @3.raw.end);
3878              if (!expr_query.str)
3879                MYSQL_YYABORT;
3880            }
3881
3882            /* Check that this is a stored function. */
3883
3884            if (sp->m_type != SP_TYPE_FUNCTION)
3885            {
3886              my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0));
3887              MYSQL_YYABORT;
3888            }
3889
3890            /* Indicate that we've reached RETURN statement. */
3891
3892            sp->m_flags|= sp_head::HAS_RETURN;
3893
3894            /* Add instruction. */
3895
3896            sp_instr_freturn *i=
3897              new (thd->mem_root)
3898                sp_instr_freturn(sp->instructions(), lex, $3, expr_query,
3899                                 sp->m_return_field_def.sql_type);
3900
3901            if (i == NULL ||
3902                sp->add_instr(thd, i) ||
3903                sp->restore_lex(thd))
3904            {
3905              MYSQL_YYABORT;
3906            }
3907          }
3908        ;
3909
3910sp_proc_stmt_unlabeled:
3911          { /* Unlabeled controls get a secret label. */
3912            THD *thd= YYTHD;
3913            LEX *lex= thd->lex;
3914            sp_head *sp= lex->sphead;
3915            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3916
3917            pctx->push_label(thd,
3918                             EMPTY_STR,
3919                             sp->instructions());
3920          }
3921          sp_unlabeled_control
3922          {
3923            LEX *lex= Lex;
3924            sp_head *sp= lex->sphead;
3925            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3926
3927            sp->m_parser_data.do_backpatch(pctx->pop_label(),
3928                                           sp->instructions());
3929          }
3930        ;
3931
3932sp_proc_stmt_leave:
3933          LEAVE_SYM label_ident
3934          {
3935            THD *thd= YYTHD;
3936            LEX *lex= Lex;
3937            sp_head *sp = lex->sphead;
3938            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3939            sp_label *lab= pctx->find_label($2);
3940
3941            if (! lab)
3942            {
3943              my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str);
3944              MYSQL_YYABORT;
3945            }
3946
3947            uint ip= sp->instructions();
3948
3949            /*
3950              When jumping to a BEGIN-END block end, the target jump
3951              points to the block hpop/cpop cleanup instructions,
3952              so we should exclude the block context here.
3953              When jumping to something else (i.e., sp_label::ITERATION),
3954              there are no hpop/cpop at the jump destination,
3955              so we should include the block context here for cleanup.
3956            */
3957            bool exclusive= (lab->type == sp_label::BEGIN);
3958
3959            size_t n= pctx->diff_handlers(lab->ctx, exclusive);
3960
3961            if (n)
3962            {
3963              sp_instr_hpop *hpop=
3964                new (thd->mem_root) sp_instr_hpop(ip++, pctx);
3965
3966              if (!hpop || sp->add_instr(thd, hpop))
3967                MYSQL_YYABORT;
3968            }
3969
3970            n= pctx->diff_cursors(lab->ctx, exclusive);
3971
3972            if (n)
3973            {
3974              sp_instr_cpop *cpop=
3975                new (thd->mem_root) sp_instr_cpop(ip++, pctx, n);
3976
3977              if (!cpop || sp->add_instr(thd, cpop))
3978                MYSQL_YYABORT;
3979            }
3980
3981            sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, pctx);
3982
3983            if (!i ||
3984                /* Jumping forward */
3985                sp->m_parser_data.add_backpatch_entry(i, lab) ||
3986                sp->add_instr(thd, i))
3987              MYSQL_YYABORT;
3988          }
3989        ;
3990
3991sp_proc_stmt_iterate:
3992          ITERATE_SYM label_ident
3993          {
3994            THD *thd= YYTHD;
3995            LEX *lex= Lex;
3996            sp_head *sp= lex->sphead;
3997            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3998            sp_label *lab= pctx->find_label($2);
3999
4000            if (! lab || lab->type != sp_label::ITERATION)
4001            {
4002              my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str);
4003              MYSQL_YYABORT;
4004            }
4005
4006            uint ip= sp->instructions();
4007
4008            /* Inclusive the dest. */
4009            size_t n= pctx->diff_handlers(lab->ctx, FALSE);
4010
4011            if (n)
4012            {
4013              sp_instr_hpop *hpop=
4014                new (thd->mem_root) sp_instr_hpop(ip++, pctx);
4015
4016              if (!hpop || sp->add_instr(thd, hpop))
4017                MYSQL_YYABORT;
4018            }
4019
4020            /* Inclusive the dest. */
4021            n= pctx->diff_cursors(lab->ctx, FALSE);
4022
4023            if (n)
4024            {
4025              sp_instr_cpop *cpop=
4026                new (thd->mem_root) sp_instr_cpop(ip++, pctx, n);
4027
4028              if (!cpop || sp->add_instr(thd, cpop))
4029                MYSQL_YYABORT;
4030            }
4031
4032            /* Jump back */
4033            sp_instr_jump *i=
4034              new (thd->mem_root) sp_instr_jump(ip, pctx, lab->ip);
4035
4036            if (!i || sp->add_instr(thd, i))
4037              MYSQL_YYABORT;
4038          }
4039        ;
4040
4041sp_proc_stmt_open:
4042          OPEN_SYM ident
4043          {
4044            THD *thd= YYTHD;
4045            LEX *lex= Lex;
4046            sp_head *sp= lex->sphead;
4047            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4048            uint offset;
4049
4050            if (! pctx->find_cursor($2, &offset, false))
4051            {
4052              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
4053              MYSQL_YYABORT;
4054            }
4055
4056            sp_instr_copen *i=
4057              new (thd->mem_root)
4058                sp_instr_copen(sp->instructions(), pctx, offset);
4059
4060            if (!i || sp->add_instr(thd, i))
4061              MYSQL_YYABORT;
4062          }
4063        ;
4064
4065sp_proc_stmt_fetch:
4066          FETCH_SYM sp_opt_fetch_noise ident INTO
4067          {
4068            THD *thd= YYTHD;
4069            LEX *lex= Lex;
4070            sp_head *sp= lex->sphead;
4071            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4072            uint offset;
4073
4074            if (! pctx->find_cursor($3, &offset, false))
4075            {
4076              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str);
4077              MYSQL_YYABORT;
4078            }
4079
4080            sp_instr_cfetch *i=
4081              new (thd->mem_root)
4082                sp_instr_cfetch(sp->instructions(), pctx, offset);
4083
4084            if (!i || sp->add_instr(thd, i))
4085              MYSQL_YYABORT;
4086          }
4087          sp_fetch_list
4088          {}
4089        ;
4090
4091sp_proc_stmt_close:
4092          CLOSE_SYM ident
4093          {
4094            THD *thd= YYTHD;
4095            LEX *lex= Lex;
4096            sp_head *sp= lex->sphead;
4097            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4098            uint offset;
4099
4100            if (! pctx->find_cursor($2, &offset, false))
4101            {
4102              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
4103              MYSQL_YYABORT;
4104            }
4105
4106            sp_instr_cclose *i=
4107              new (thd->mem_root)
4108                sp_instr_cclose(sp->instructions(), pctx, offset);
4109
4110            if (!i || sp->add_instr(thd, i))
4111              MYSQL_YYABORT;
4112          }
4113        ;
4114
4115sp_opt_fetch_noise:
4116          /* Empty */
4117        | NEXT_SYM FROM
4118        | FROM
4119        ;
4120
4121sp_fetch_list:
4122          ident
4123          {
4124            LEX *lex= Lex;
4125            sp_head *sp= lex->sphead;
4126            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4127            sp_variable *spv;
4128
4129            if (!pctx || !(spv= pctx->find_variable($1, false)))
4130            {
4131              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
4132              MYSQL_YYABORT;
4133            }
4134
4135            /* An SP local variable */
4136            sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
4137
4138            i->add_to_varlist(spv);
4139          }
4140        | sp_fetch_list ',' ident
4141          {
4142            LEX *lex= Lex;
4143            sp_head *sp= lex->sphead;
4144            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4145            sp_variable *spv;
4146
4147            if (!pctx || !(spv= pctx->find_variable($3, false)))
4148            {
4149              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str);
4150              MYSQL_YYABORT;
4151            }
4152
4153            /* An SP local variable */
4154            sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
4155
4156            i->add_to_varlist(spv);
4157          }
4158        ;
4159
4160sp_if:
4161          {                     /*$1*/
4162            THD *thd= YYTHD;
4163            LEX *lex= thd->lex;
4164            sp_head *sp= lex->sphead;
4165
4166            sp->reset_lex(thd);
4167            sp->m_parser_data.push_expr_start_ptr(@0.raw.end);
4168          }
4169          expr                  /*$2*/
4170          {                     /*$3*/
4171            ITEMIZE($2, &$2);
4172
4173            THD *thd= YYTHD;
4174            LEX *lex= Lex;
4175            sp_head *sp= lex->sphead;
4176            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4177
4178            /* Extract expression string. */
4179
4180            LEX_STRING expr_query= EMPTY_STR;
4181            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4182
4183            if (lex->is_metadata_used())
4184            {
4185              expr_query= make_string(thd, expr_start_ptr, @2.raw.end);
4186              if (!expr_query.str)
4187                MYSQL_YYABORT;
4188            }
4189
4190            sp_instr_jump_if_not *i =
4191              new (thd->mem_root)
4192                sp_instr_jump_if_not(sp->instructions(), lex,
4193                                     $2, expr_query);
4194
4195            /* Add jump instruction. */
4196
4197            if (i == NULL ||
4198                sp->m_parser_data.add_backpatch_entry(
4199                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4200                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4201                sp->add_instr(thd, i) ||
4202                sp->restore_lex(thd))
4203            {
4204              MYSQL_YYABORT;
4205            }
4206          }
4207          THEN_SYM              /*$4*/
4208          sp_proc_stmts1        /*$5*/
4209          {                     /*$6*/
4210            THD *thd= YYTHD;
4211            LEX *lex= thd->lex;
4212            sp_head *sp= lex->sphead;
4213            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4214
4215            sp_instr_jump *i =
4216              new (thd->mem_root) sp_instr_jump(sp->instructions(), pctx);
4217
4218            if (!i || sp->add_instr(thd, i))
4219              MYSQL_YYABORT;
4220
4221            sp->m_parser_data.do_backpatch(pctx->pop_label(),
4222                                           sp->instructions());
4223
4224            sp->m_parser_data.add_backpatch_entry(
4225              i, pctx->push_label(thd, EMPTY_STR, 0));
4226          }
4227          sp_elseifs            /*$7*/
4228          {                     /*$8*/
4229            LEX *lex= Lex;
4230            sp_head *sp= lex->sphead;
4231            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4232
4233            sp->m_parser_data.do_backpatch(pctx->pop_label(),
4234                                           sp->instructions());
4235          }
4236        ;
4237
4238sp_elseifs:
4239          /* Empty */
4240        | ELSEIF_SYM sp_if
4241        | ELSE sp_proc_stmts1
4242        ;
4243
4244case_stmt_specification:
4245          simple_case_stmt
4246        | searched_case_stmt
4247        ;
4248
4249simple_case_stmt:
4250          CASE_SYM                      /*$1*/
4251          {                             /*$2*/
4252            THD *thd= YYTHD;
4253            LEX *lex= thd->lex;
4254            sp_head *sp= lex->sphead;
4255
4256            case_stmt_action_case(thd);
4257
4258            sp->reset_lex(thd); /* For CASE-expr $3 */
4259            sp->m_parser_data.push_expr_start_ptr(@1.raw.end);
4260          }
4261          expr                          /*$3*/
4262          {                             /*$4*/
4263            ITEMIZE($3, &$3);
4264
4265            THD *thd= YYTHD;
4266            LEX *lex= Lex;
4267            sp_head *sp= lex->sphead;
4268
4269            /* Extract CASE-expression string. */
4270
4271            LEX_STRING case_expr_query= EMPTY_STR;
4272            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4273
4274            if (lex->is_metadata_used())
4275            {
4276              case_expr_query= make_string(thd, expr_start_ptr, @3.raw.end);
4277              if (!case_expr_query.str)
4278                MYSQL_YYABORT;
4279            }
4280
4281            /* Register new CASE-expression and get its id. */
4282
4283            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4284            int case_expr_id= pctx->push_case_expr_id();
4285
4286            if (case_expr_id < 0)
4287              MYSQL_YYABORT;
4288
4289            /* Add CASE-set instruction. */
4290
4291            sp_instr_set_case_expr *i=
4292              new (thd->mem_root)
4293                sp_instr_set_case_expr(sp->instructions(), lex,
4294                                       case_expr_id, $3, case_expr_query);
4295
4296            if (i == NULL ||
4297                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4298                sp->add_instr(thd, i) ||
4299                sp->restore_lex(thd))
4300            {
4301              MYSQL_YYABORT;
4302            }
4303          }
4304          simple_when_clause_list       /*$5*/
4305          else_clause_opt               /*$6*/
4306          END                           /*$7*/
4307          CASE_SYM                      /*$8*/
4308          {                             /*$9*/
4309            case_stmt_action_end_case(Lex, true);
4310          }
4311        ;
4312
4313searched_case_stmt:
4314          CASE_SYM
4315          {
4316            case_stmt_action_case(YYTHD);
4317          }
4318          searched_when_clause_list
4319          else_clause_opt
4320          END
4321          CASE_SYM
4322          {
4323            case_stmt_action_end_case(Lex, false);
4324          }
4325        ;
4326
4327simple_when_clause_list:
4328          simple_when_clause
4329        | simple_when_clause_list simple_when_clause
4330        ;
4331
4332searched_when_clause_list:
4333          searched_when_clause
4334        | searched_when_clause_list searched_when_clause
4335        ;
4336
4337simple_when_clause:
4338          WHEN_SYM                      /*$1*/
4339          {                             /*$2*/
4340            THD *thd= YYTHD;
4341            LEX *lex= thd->lex;
4342            sp_head *sp= lex->sphead;
4343
4344            sp->reset_lex(thd);
4345            sp->m_parser_data.push_expr_start_ptr(@1.raw.end);
4346          }
4347          expr                          /*$3*/
4348          {                             /*$4*/
4349            /* Simple case: <caseval> = <whenval> */
4350
4351            ITEMIZE($3, &$3);
4352
4353            THD *thd= YYTHD;
4354            LEX *lex= thd->lex;
4355            sp_head *sp= lex->sphead;
4356            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4357
4358            /* Extract expression string. */
4359
4360            LEX_STRING when_expr_query= EMPTY_STR;
4361            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4362
4363            if (lex->is_metadata_used())
4364            {
4365              when_expr_query= make_string(thd, expr_start_ptr, @3.raw.end);
4366              if (!when_expr_query.str)
4367                MYSQL_YYABORT;
4368            }
4369
4370            /* Add CASE-when-jump instruction. */
4371
4372            sp_instr_jump_case_when *i =
4373              new (thd->mem_root)
4374                sp_instr_jump_case_when(sp->instructions(), lex,
4375                                        pctx->get_current_case_expr_id(),
4376                                        $3, when_expr_query);
4377
4378            if (i == NULL ||
4379                i->on_after_expr_parsing(thd) ||
4380                sp->m_parser_data.add_backpatch_entry(
4381                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4382                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4383                sp->add_instr(thd, i) ||
4384                sp->restore_lex(thd))
4385            {
4386              MYSQL_YYABORT;
4387            }
4388          }
4389          THEN_SYM                      /*$5*/
4390          sp_proc_stmts1                /*$6*/
4391          {                             /*$7*/
4392            if (case_stmt_action_then(YYTHD, Lex))
4393              MYSQL_YYABORT;
4394          }
4395        ;
4396
4397searched_when_clause:
4398          WHEN_SYM                      /*$1*/
4399          {                             /*$2*/
4400            THD *thd= YYTHD;
4401            LEX *lex= thd->lex;
4402            sp_head *sp= lex->sphead;
4403
4404            sp->reset_lex(thd);
4405            sp->m_parser_data.push_expr_start_ptr(@1.raw.end);
4406          }
4407          expr                          /*$3*/
4408          {                             /*$4*/
4409            ITEMIZE($3, &$3);
4410
4411            THD *thd= YYTHD;
4412            LEX *lex= thd->lex;
4413            sp_head *sp= lex->sphead;
4414            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4415
4416            /* Extract expression string. */
4417
4418            LEX_STRING when_query= EMPTY_STR;
4419            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4420
4421            if (lex->is_metadata_used())
4422            {
4423              when_query= make_string(thd, expr_start_ptr, @3.raw.end);
4424              if (!when_query.str)
4425                MYSQL_YYABORT;
4426            }
4427
4428            /* Add jump instruction. */
4429
4430            sp_instr_jump_if_not *i=
4431              new (thd->mem_root)
4432                sp_instr_jump_if_not(sp->instructions(), lex, $3, when_query);
4433
4434            if (i == NULL ||
4435                sp->m_parser_data.add_backpatch_entry(
4436                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4437                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4438                sp->add_instr(thd, i) ||
4439                sp->restore_lex(thd))
4440            {
4441              MYSQL_YYABORT;
4442            }
4443          }
4444          THEN_SYM                      /*$6*/
4445          sp_proc_stmts1                /*$7*/
4446          {                             /*$8*/
4447            if (case_stmt_action_then(YYTHD, Lex))
4448              MYSQL_YYABORT;
4449          }
4450        ;
4451
4452else_clause_opt:
4453          /* empty */
4454          {
4455            THD *thd= YYTHD;
4456            LEX *lex= Lex;
4457            sp_head *sp= lex->sphead;
4458            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4459
4460            sp_instr_error *i=
4461              new (thd->mem_root)
4462                sp_instr_error(sp->instructions(), pctx, ER_SP_CASE_NOT_FOUND);
4463
4464            if (!i || sp->add_instr(thd, i))
4465              MYSQL_YYABORT;
4466          }
4467        | ELSE sp_proc_stmts1
4468        ;
4469
4470sp_labeled_control:
4471          label_ident ':'
4472          {
4473            LEX *lex= Lex;
4474            sp_head *sp= lex->sphead;
4475            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4476            sp_label *lab= pctx->find_label($1);
4477
4478            if (lab)
4479            {
4480              my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
4481              MYSQL_YYABORT;
4482            }
4483            else
4484            {
4485              lab= pctx->push_label(YYTHD, $1, sp->instructions());
4486              lab->type= sp_label::ITERATION;
4487            }
4488          }
4489          sp_unlabeled_control sp_opt_label
4490          {
4491            LEX *lex= Lex;
4492            sp_head *sp= lex->sphead;
4493            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4494            sp_label *lab= pctx->pop_label();
4495
4496            if ($5.str)
4497            {
4498              if (my_strcasecmp(system_charset_info, $5.str, lab->name.str) != 0)
4499              {
4500                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
4501                MYSQL_YYABORT;
4502              }
4503            }
4504            sp->m_parser_data.do_backpatch(lab, sp->instructions());
4505          }
4506        ;
4507
4508sp_opt_label:
4509          /* Empty  */  { $$= null_lex_str; }
4510        | label_ident   { $$= $1; }
4511        ;
4512
4513sp_labeled_block:
4514          label_ident ':'
4515          {
4516            LEX *lex= Lex;
4517            sp_head *sp= lex->sphead;
4518            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4519            sp_label *lab= pctx->find_label($1);
4520
4521            if (lab)
4522            {
4523              my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
4524              MYSQL_YYABORT;
4525            }
4526
4527            lab= pctx->push_label(YYTHD, $1, sp->instructions());
4528            lab->type= sp_label::BEGIN;
4529          }
4530          sp_block_content sp_opt_label
4531          {
4532            LEX *lex= Lex;
4533            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4534            sp_label *lab= pctx->pop_label();
4535
4536            if ($5.str)
4537            {
4538              if (my_strcasecmp(system_charset_info, $5.str, lab->name.str) != 0)
4539              {
4540                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
4541                MYSQL_YYABORT;
4542              }
4543            }
4544          }
4545        ;
4546
4547sp_unlabeled_block:
4548          { /* Unlabeled blocks get a secret label. */
4549            LEX *lex= Lex;
4550            sp_head *sp= lex->sphead;
4551            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4552
4553            sp_label *lab=
4554              pctx->push_label(YYTHD, EMPTY_STR, sp->instructions());
4555
4556            lab->type= sp_label::BEGIN;
4557          }
4558          sp_block_content
4559          {
4560            LEX *lex= Lex;
4561            lex->get_sp_current_parsing_ctx()->pop_label();
4562          }
4563        ;
4564
4565sp_block_content:
4566          BEGIN_SYM
4567          { /* QQ This is just a dummy for grouping declarations and statements
4568              together. No [[NOT] ATOMIC] yet, and we need to figure out how
4569              make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
4570            THD *thd= YYTHD;
4571            LEX *lex= thd->lex;
4572            sp_pcontext *parent_pctx= lex->get_sp_current_parsing_ctx();
4573
4574            sp_pcontext *child_pctx=
4575              parent_pctx->push_context(thd, sp_pcontext::REGULAR_SCOPE);
4576
4577            lex->set_sp_current_parsing_ctx(child_pctx);
4578          }
4579          sp_decls
4580          sp_proc_stmts
4581          END
4582          {
4583            THD *thd= YYTHD;
4584            LEX *lex= Lex;
4585            sp_head *sp= lex->sphead;
4586            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4587
4588            // We always have a label.
4589            sp->m_parser_data.do_backpatch(pctx->last_label(),
4590                                           sp->instructions());
4591
4592            if ($3.hndlrs)
4593            {
4594              sp_instr *i=
4595                new (thd->mem_root) sp_instr_hpop(sp->instructions(), pctx);
4596
4597              if (!i || sp->add_instr(thd, i))
4598                MYSQL_YYABORT;
4599            }
4600
4601            if ($3.curs)
4602            {
4603              sp_instr *i=
4604                new (thd->mem_root)
4605                  sp_instr_cpop(sp->instructions(), pctx, $3.curs);
4606
4607              if (!i || sp->add_instr(thd, i))
4608                MYSQL_YYABORT;
4609            }
4610
4611            lex->set_sp_current_parsing_ctx(pctx->pop_context());
4612          }
4613        ;
4614
4615sp_unlabeled_control:
4616          LOOP_SYM
4617          sp_proc_stmts1 END LOOP_SYM
4618          {
4619            THD *thd= YYTHD;
4620            LEX *lex= Lex;
4621            sp_head *sp= lex->sphead;
4622            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4623
4624            sp_instr_jump *i=
4625                new (thd->mem_root)
4626                  sp_instr_jump(sp->instructions(), pctx,
4627                                pctx->last_label()->ip);
4628
4629            if (!i || sp->add_instr(thd, i))
4630              MYSQL_YYABORT;
4631          }
4632        | WHILE_SYM                     /*$1*/
4633          {                             /*$2*/
4634            THD *thd= YYTHD;
4635            LEX *lex= thd->lex;
4636            sp_head *sp= lex->sphead;
4637
4638            sp->reset_lex(thd);
4639            sp->m_parser_data.push_expr_start_ptr(@1.raw.end);
4640          }
4641          expr                          /*$3*/
4642          {                             /*$4*/
4643            ITEMIZE($3, &$3);
4644
4645            THD *thd= YYTHD;
4646            LEX *lex= Lex;
4647            sp_head *sp= lex->sphead;
4648            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4649
4650            /* Extract expression string. */
4651
4652            LEX_STRING expr_query= EMPTY_STR;
4653            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4654
4655            if (lex->is_metadata_used())
4656            {
4657              expr_query= make_string(thd, expr_start_ptr, @3.raw.end);
4658              if (!expr_query.str)
4659                MYSQL_YYABORT;
4660            }
4661
4662            /* Add jump instruction. */
4663
4664            sp_instr_jump_if_not *i=
4665              new (thd->mem_root)
4666                sp_instr_jump_if_not(sp->instructions(), lex, $3, expr_query);
4667
4668            if (i == NULL ||
4669                /* Jumping forward */
4670                sp->m_parser_data.add_backpatch_entry(i, pctx->last_label()) ||
4671                sp->m_parser_data.new_cont_backpatch() ||
4672                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4673                sp->add_instr(thd, i) ||
4674                sp->restore_lex(thd))
4675            {
4676              MYSQL_YYABORT;
4677            }
4678          }
4679          DO_SYM                        /*$10*/
4680          sp_proc_stmts1                /*$11*/
4681          END                           /*$12*/
4682          WHILE_SYM                     /*$13*/
4683          {                             /*$14*/
4684            THD *thd= YYTHD;
4685            LEX *lex= Lex;
4686            sp_head *sp= lex->sphead;
4687            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4688
4689            sp_instr_jump *i=
4690              new (thd->mem_root)
4691                sp_instr_jump(sp->instructions(), pctx, pctx->last_label()->ip);
4692
4693            if (!i || sp->add_instr(thd, i))
4694              MYSQL_YYABORT;
4695
4696            sp->m_parser_data.do_cont_backpatch(sp->instructions());
4697          }
4698        | REPEAT_SYM                    /*$1*/
4699          sp_proc_stmts1                /*$2*/
4700          UNTIL_SYM                     /*$3*/
4701          {                             /*$4*/
4702            THD *thd= YYTHD;
4703            LEX *lex= thd->lex;
4704            sp_head *sp= lex->sphead;
4705
4706            sp->reset_lex(thd);
4707            sp->m_parser_data.push_expr_start_ptr(@3.raw.end);
4708          }
4709          expr                          /*$5*/
4710          {                             /*$6*/
4711            ITEMIZE($5, &$5);
4712
4713            THD *thd= YYTHD;
4714            LEX *lex= thd->lex;
4715            sp_head *sp= lex->sphead;
4716            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4717            uint ip= sp->instructions();
4718
4719            /* Extract expression string. */
4720
4721            LEX_STRING expr_query= EMPTY_STR;
4722            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4723
4724            if (lex->is_metadata_used())
4725            {
4726              expr_query= make_string(thd, expr_start_ptr, @5.raw.end);
4727              if (!expr_query.str)
4728                MYSQL_YYABORT;
4729            }
4730
4731            /* Add jump instruction. */
4732
4733            sp_instr_jump_if_not *i=
4734              new (thd->mem_root)
4735                sp_instr_jump_if_not(ip, lex, $5, expr_query,
4736                                     pctx->last_label()->ip);
4737
4738            if (i == NULL ||
4739                sp->add_instr(thd, i) ||
4740                sp->restore_lex(thd))
4741            {
4742              MYSQL_YYABORT;
4743            }
4744
4745            /* We can shortcut the cont_backpatch here */
4746            i->set_cont_dest(ip + 1);
4747          }
4748          END                           /*$7*/
4749          REPEAT_SYM                    /*$8*/
4750        ;
4751
4752trg_action_time:
4753            BEFORE_SYM
4754            { $$= TRG_ACTION_BEFORE; }
4755          | AFTER_SYM
4756            { $$= TRG_ACTION_AFTER; }
4757          ;
4758
4759trg_event:
4760            INSERT
4761            { $$= TRG_EVENT_INSERT; }
4762          | UPDATE_SYM
4763            { $$= TRG_EVENT_UPDATE; }
4764          | DELETE_SYM
4765            { $$= TRG_EVENT_DELETE; }
4766          ;
4767/*
4768  This part of the parser contains common code for all TABLESPACE
4769  commands.
4770  CREATE TABLESPACE_SYM name ...
4771  ALTER TABLESPACE_SYM name CHANGE DATAFILE ...
4772  ALTER TABLESPACE_SYM name ADD DATAFILE ...
4773  ALTER TABLESPACE_SYM name access_mode
4774  CREATE LOGFILE GROUP_SYM name ...
4775  ALTER LOGFILE GROUP_SYM name ADD UNDOFILE ..
4776  ALTER LOGFILE GROUP_SYM name ADD REDOFILE ..
4777  DROP TABLESPACE_SYM name
4778  DROP LOGFILE GROUP_SYM name
4779*/
4780change_tablespace_access:
4781          tablespace_name
4782          ts_access_mode
4783        ;
4784
4785change_tablespace_info:
4786          tablespace_name
4787          CHANGE ts_datafile
4788          change_ts_option_list
4789        ;
4790
4791tablespace_info:
4792          tablespace_name
4793          ADD ts_datafile
4794          opt_logfile_group_name
4795          tablespace_option_list
4796        ;
4797
4798opt_logfile_group_name:
4799          /* empty */ {}
4800        | USE_SYM LOGFILE_SYM GROUP_SYM ident
4801          {
4802            LEX *lex= Lex;
4803            lex->alter_tablespace_info->logfile_group_name= $4.str;
4804          }
4805        ;
4806
4807alter_tablespace_info:
4808          tablespace_name
4809          ADD ts_datafile
4810          alter_tablespace_option_list
4811          {
4812            Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_ADD_FILE;
4813          }
4814        | tablespace_name
4815          DROP ts_datafile
4816          alter_tablespace_option_list
4817          {
4818            Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_DROP_FILE;
4819          }
4820        ;
4821
4822logfile_group_info:
4823          logfile_group_name
4824          add_log_file
4825          logfile_group_option_list
4826        ;
4827
4828alter_logfile_group_info:
4829          logfile_group_name
4830          add_log_file
4831          alter_logfile_group_option_list
4832        ;
4833
4834add_log_file:
4835          ADD lg_undofile
4836        | ADD lg_redofile
4837        ;
4838
4839change_ts_option_list:
4840          /* empty */ {}
4841          change_ts_options
4842        ;
4843
4844change_ts_options:
4845          change_ts_option
4846        | change_ts_options change_ts_option
4847        | change_ts_options ',' change_ts_option
4848        ;
4849
4850change_ts_option:
4851          opt_ts_initial_size
4852        | opt_ts_autoextend_size
4853        | opt_ts_max_size
4854        ;
4855
4856tablespace_option_list:
4857          /* empty */
4858        | tablespace_options
4859        ;
4860
4861tablespace_options:
4862          tablespace_option
4863        | tablespace_options tablespace_option
4864        | tablespace_options ',' tablespace_option
4865        ;
4866
4867tablespace_option:
4868          opt_ts_initial_size
4869        | opt_ts_autoextend_size
4870        | opt_ts_max_size
4871        | opt_ts_extent_size
4872        | opt_ts_nodegroup
4873        | opt_ts_engine
4874        | ts_wait
4875        | opt_ts_comment
4876        | opt_ts_file_block_size
4877        | opt_ts_encryption
4878        ;
4879
4880alter_tablespace_option_list:
4881          /* empty */
4882        | alter_tablespace_options
4883        ;
4884
4885alter_tablespace_options:
4886          alter_tablespace_option
4887        | alter_tablespace_options alter_tablespace_option
4888        | alter_tablespace_options ',' alter_tablespace_option
4889        ;
4890
4891alter_tablespace_option:
4892          opt_ts_initial_size
4893        | opt_ts_autoextend_size
4894        | opt_ts_max_size
4895        | opt_ts_engine
4896        | ts_wait
4897        ;
4898
4899logfile_group_option_list:
4900          /* empty */
4901        | logfile_group_options
4902        ;
4903
4904logfile_group_options:
4905          logfile_group_option
4906        | logfile_group_options logfile_group_option
4907        | logfile_group_options ',' logfile_group_option
4908        ;
4909
4910logfile_group_option:
4911          opt_ts_initial_size
4912        | opt_ts_undo_buffer_size
4913        | opt_ts_redo_buffer_size
4914        | opt_ts_nodegroup
4915        | opt_ts_engine
4916        | ts_wait
4917        | opt_ts_comment
4918        ;
4919
4920alter_logfile_group_option_list:
4921          /* empty */
4922        | alter_logfile_group_options
4923        ;
4924
4925alter_logfile_group_options:
4926          alter_logfile_group_option
4927        | alter_logfile_group_options alter_logfile_group_option
4928        | alter_logfile_group_options ',' alter_logfile_group_option
4929        ;
4930
4931alter_logfile_group_option:
4932          opt_ts_initial_size
4933        | opt_ts_engine
4934        | ts_wait
4935        ;
4936
4937
4938ts_datafile:
4939          DATAFILE_SYM TEXT_STRING_sys
4940          {
4941            LEX *lex= Lex;
4942            lex->alter_tablespace_info->data_file_name= $2.str;
4943          }
4944        ;
4945
4946lg_undofile:
4947          UNDOFILE_SYM TEXT_STRING_sys
4948          {
4949            LEX *lex= Lex;
4950            lex->alter_tablespace_info->undo_file_name= $2.str;
4951          }
4952        ;
4953
4954lg_redofile:
4955          REDOFILE_SYM TEXT_STRING_sys
4956          {
4957            LEX *lex= Lex;
4958            lex->alter_tablespace_info->redo_file_name= $2.str;
4959          }
4960        ;
4961
4962tablespace_name:
4963          ident
4964          {
4965            LEX *lex= Lex;
4966            lex->alter_tablespace_info= new st_alter_tablespace();
4967            if (lex->alter_tablespace_info == NULL)
4968              MYSQL_YYABORT;
4969            lex->alter_tablespace_info->tablespace_name= $1.str;
4970            lex->sql_command= SQLCOM_ALTER_TABLESPACE;
4971          }
4972        ;
4973
4974logfile_group_name:
4975          ident
4976          {
4977            LEX *lex= Lex;
4978            lex->alter_tablespace_info= new st_alter_tablespace();
4979            if (lex->alter_tablespace_info == NULL)
4980              MYSQL_YYABORT;
4981            lex->alter_tablespace_info->logfile_group_name= $1.str;
4982            lex->sql_command= SQLCOM_ALTER_TABLESPACE;
4983          }
4984        ;
4985
4986ts_access_mode:
4987          READ_ONLY_SYM
4988          {
4989            LEX *lex= Lex;
4990            lex->alter_tablespace_info->ts_access_mode= TS_READ_ONLY;
4991          }
4992        | READ_WRITE_SYM
4993          {
4994            LEX *lex= Lex;
4995            lex->alter_tablespace_info->ts_access_mode= TS_READ_WRITE;
4996          }
4997        | NOT_SYM ACCESSIBLE_SYM
4998          {
4999            LEX *lex= Lex;
5000            lex->alter_tablespace_info->ts_access_mode= TS_NOT_ACCESSIBLE;
5001          }
5002        ;
5003
5004opt_ts_initial_size:
5005          INITIAL_SIZE_SYM opt_equal size_number
5006          {
5007            LEX *lex= Lex;
5008            lex->alter_tablespace_info->initial_size= $3;
5009          }
5010        ;
5011
5012opt_ts_autoextend_size:
5013          AUTOEXTEND_SIZE_SYM opt_equal size_number
5014          {
5015            LEX *lex= Lex;
5016            lex->alter_tablespace_info->autoextend_size= $3;
5017          }
5018        ;
5019
5020opt_ts_max_size:
5021          MAX_SIZE_SYM opt_equal size_number
5022          {
5023            LEX *lex= Lex;
5024            lex->alter_tablespace_info->max_size= $3;
5025          }
5026        ;
5027
5028opt_ts_extent_size:
5029          EXTENT_SIZE_SYM opt_equal size_number
5030          {
5031            LEX *lex= Lex;
5032            lex->alter_tablespace_info->extent_size= $3;
5033          }
5034        ;
5035
5036opt_ts_undo_buffer_size:
5037          UNDO_BUFFER_SIZE_SYM opt_equal size_number
5038          {
5039            LEX *lex= Lex;
5040            lex->alter_tablespace_info->undo_buffer_size= $3;
5041          }
5042        ;
5043
5044opt_ts_redo_buffer_size:
5045          REDO_BUFFER_SIZE_SYM opt_equal size_number
5046          {
5047            LEX *lex= Lex;
5048            lex->alter_tablespace_info->redo_buffer_size= $3;
5049          }
5050        ;
5051
5052opt_ts_nodegroup:
5053          NODEGROUP_SYM opt_equal real_ulong_num
5054          {
5055            LEX *lex= Lex;
5056            if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)
5057            {
5058              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
5059              MYSQL_YYABORT;
5060            }
5061            lex->alter_tablespace_info->nodegroup_id= $3;
5062          }
5063        ;
5064
5065opt_ts_comment:
5066          COMMENT_SYM opt_equal TEXT_STRING_sys
5067          {
5068            LEX *lex= Lex;
5069            if (lex->alter_tablespace_info->ts_comment != NULL)
5070            {
5071              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
5072              MYSQL_YYABORT;
5073            }
5074            lex->alter_tablespace_info->ts_comment= $3.str;
5075          }
5076        ;
5077
5078opt_ts_engine:
5079          opt_storage ENGINE_SYM opt_equal storage_engines
5080          {
5081            LEX *lex= Lex;
5082            if (lex->alter_tablespace_info->storage_engine != NULL)
5083            {
5084              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),
5085                       "STORAGE ENGINE");
5086              MYSQL_YYABORT;
5087            }
5088            lex->alter_tablespace_info->storage_engine= $4;
5089          }
5090        ;
5091
5092opt_ts_file_block_size:
5093          FILE_BLOCK_SIZE_SYM opt_equal size_number
5094          {
5095            LEX *lex= Lex;
5096            if (lex->alter_tablespace_info->file_block_size != 0)
5097            {
5098              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),
5099                       "FILE_BLOCK_SIZE");
5100              MYSQL_YYABORT;
5101            }
5102            lex->alter_tablespace_info->file_block_size= $3;
5103          }
5104        ;
5105
5106opt_ts_encryption:
5107          ENCRYPTION_SYM opt_equal TEXT_STRING_sys
5108          {
5109            Lex->alter_tablespace_info->encrypt= true;
5110            Lex->alter_tablespace_info->encrypt_type= $3;
5111          }
5112        ;
5113
5114ts_wait:
5115          WAIT_SYM
5116          {
5117            LEX *lex= Lex;
5118            lex->alter_tablespace_info->wait_until_completed= TRUE;
5119          }
5120        | NO_WAIT_SYM
5121          {
5122            LEX *lex= Lex;
5123            if (!(lex->alter_tablespace_info->wait_until_completed))
5124            {
5125              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
5126              MYSQL_YYABORT;
5127            }
5128            lex->alter_tablespace_info->wait_until_completed= FALSE;
5129          }
5130        ;
5131
5132size_number:
5133          real_ulonglong_num { $$= $1;}
5134        | IDENT_sys
5135          {
5136            ulonglong number;
5137            uint text_shift_number= 0;
5138            longlong prefix_number;
5139            char *start_ptr= $1.str;
5140            size_t str_len= $1.length;
5141            char *end_ptr= start_ptr + str_len;
5142            int error;
5143            prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
5144            if ((start_ptr + str_len - 1) == end_ptr)
5145            {
5146              switch (end_ptr[0])
5147              {
5148                case 'g':
5149                case 'G':
5150                  text_shift_number+=10;
5151                  // Fall through.
5152                case 'm':
5153                case 'M':
5154                  text_shift_number+=10;
5155                  // Fall through.
5156                case 'k':
5157                case 'K':
5158                  text_shift_number+=10;
5159                  break;
5160                default:
5161                {
5162                  my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
5163                  MYSQL_YYABORT;
5164                }
5165              }
5166              if (prefix_number >> 31)
5167              {
5168                my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0));
5169                MYSQL_YYABORT;
5170              }
5171              number= prefix_number << text_shift_number;
5172            }
5173            else
5174            {
5175              my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
5176              MYSQL_YYABORT;
5177            }
5178            $$= number;
5179          }
5180        ;
5181
5182/*
5183  End tablespace part
5184*/
5185
5186create2:
5187          '(' create2a {}
5188        | opt_create_table_options
5189          opt_create_partitioning
5190          create3 {}
5191        | LIKE table_ident
5192          {
5193            THD *thd= YYTHD;
5194            TABLE_LIST *src_table;
5195            LEX *lex= thd->lex;
5196
5197            lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
5198            src_table= lex->select_lex->add_table_to_list(thd, $2, NULL, 0,
5199                                                          TL_READ,
5200                                                          MDL_SHARED_READ);
5201            if (! src_table)
5202              MYSQL_YYABORT;
5203            /* CREATE TABLE ... LIKE is not allowed for views. */
5204            src_table->required_type= FRMTYPE_TABLE;
5205          }
5206        | '(' LIKE table_ident ')'
5207          {
5208            THD *thd= YYTHD;
5209            TABLE_LIST *src_table;
5210            LEX *lex= thd->lex;
5211
5212            lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
5213            src_table= lex->select_lex->add_table_to_list(thd, $3, NULL, 0,
5214                                                          TL_READ,
5215                                                          MDL_SHARED_READ);
5216            if (! src_table)
5217              MYSQL_YYABORT;
5218            /* CREATE TABLE ... LIKE is not allowed for views. */
5219            src_table->required_type= FRMTYPE_TABLE;
5220          }
5221        ;
5222
5223create2a:
5224          create_field_list ')' opt_create_table_options
5225          opt_create_partitioning
5226          create3 {}
5227        |  opt_create_partitioning
5228           create_select ')'
5229           {
5230             CONTEXTUALIZE($2);
5231             Select->set_braces(1);
5232           }
5233           union_opt
5234           {
5235             if ($5 != NULL)
5236               CONTEXTUALIZE($5);
5237           }
5238        ;
5239
5240create3:
5241          /* empty */ {}
5242        | opt_duplicate opt_as create_select
5243          {
5244            CONTEXTUALIZE($3);
5245            Select->set_braces(0);
5246          }
5247          opt_union_clause
5248          {
5249            if ($5 != NULL)
5250              CONTEXTUALIZE($5);
5251          }
5252        | opt_duplicate opt_as '(' create_select ')'
5253          {
5254            CONTEXTUALIZE($4);
5255            Select->set_braces(1);
5256          }
5257          union_opt
5258          {
5259             if ($7 != NULL)
5260               CONTEXTUALIZE($7);
5261          }
5262        ;
5263
5264opt_create_partitioning:
5265          opt_partitioning
5266          {
5267            /*
5268              Remove all tables used in PARTITION clause from the global table
5269              list. Partitioning with subqueries is not allowed anyway.
5270            */
5271            TABLE_LIST *last_non_sel_table= Lex->create_last_non_select_table;
5272            last_non_sel_table->next_global= 0;
5273            Lex->query_tables_last= &last_non_sel_table->next_global;
5274          }
5275        ;
5276
5277/*
5278 This part of the parser is about handling of the partition information.
5279
5280 It's first version was written by Mikael Ronström with lots of answers to
5281 questions provided by Antony Curtis.
5282
5283 The partition grammar can be called from three places.
5284 1) CREATE TABLE ... PARTITION ..
5285 2) ALTER TABLE table_name PARTITION ...
5286 3) PARTITION ...
5287
5288 The first place is called when a new table is created from a MySQL client.
5289 The second place is called when a table is altered with the ALTER TABLE
5290 command from a MySQL client.
5291 The third place is called when opening an frm file and finding partition
5292 info in the .frm file. It is necessary to avoid allowing PARTITION to be
5293 an allowed entry point for SQL client queries. This is arranged by setting
5294 some state variables before arriving here.
5295
5296 To be able to handle errors we will only set error code in this code
5297 and handle the error condition in the function calling the parser. This
5298 is necessary to ensure we can also handle errors when calling the parser
5299 from the openfrm function.
5300*/
5301opt_partitioning:
5302          /* empty */ {}
5303        | partitioning
5304        ;
5305
5306partitioning:
5307          PARTITION_SYM
5308          {
5309            LEX *lex= Lex;
5310            lex->part_info= new partition_info();
5311            if (!lex->part_info)
5312            {
5313              mem_alloc_error(sizeof(partition_info));
5314              MYSQL_YYABORT;
5315            }
5316            if (lex->sql_command == SQLCOM_ALTER_TABLE)
5317            {
5318              lex->alter_info.flags|= Alter_info::ALTER_PARTITION;
5319            }
5320          }
5321          partition
5322        ;
5323
5324partition_entry:
5325          PARTITION_SYM
5326          {
5327            LEX *lex= Lex;
5328            if (!lex->part_info)
5329            {
5330              my_syntax_error(ER(ER_PARTITION_ENTRY_ERROR));
5331              MYSQL_YYABORT;
5332            }
5333            /*
5334              We enter here when opening the frm file to translate
5335              partition info string into part_info data structure.
5336            */
5337          }
5338          partition {}
5339        ;
5340
5341partition:
5342          BY part_type_def opt_num_parts opt_sub_part part_defs
5343        ;
5344
5345part_type_def:
5346          opt_linear KEY_SYM opt_key_algo '(' part_field_list ')'
5347          {
5348            partition_info *part_info= Lex->part_info;
5349            part_info->list_of_part_fields= TRUE;
5350            part_info->column_list= FALSE;
5351            part_info->part_type= HASH_PARTITION;
5352          }
5353        | opt_linear HASH_SYM
5354          { Lex->part_info->part_type= HASH_PARTITION; }
5355          part_func {}
5356        | RANGE_SYM part_func
5357          { Lex->part_info->part_type= RANGE_PARTITION; }
5358        | RANGE_SYM part_column_list
5359          { Lex->part_info->part_type= RANGE_PARTITION; }
5360        | LIST_SYM part_func
5361          { Lex->part_info->part_type= LIST_PARTITION; }
5362        | LIST_SYM part_column_list
5363          { Lex->part_info->part_type= LIST_PARTITION; }
5364        ;
5365
5366opt_linear:
5367          /* empty */ {}
5368        | LINEAR_SYM
5369          { Lex->part_info->linear_hash_ind= TRUE;}
5370        ;
5371
5372opt_key_algo:
5373          /* empty */
5374          { Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_NONE;}
5375        | ALGORITHM_SYM EQ real_ulong_num
5376          {
5377            switch ($3) {
5378            case 1:
5379              Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_51;
5380              break;
5381            case 2:
5382              Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_55;
5383              break;
5384            default:
5385              my_syntax_error(ER(ER_SYNTAX_ERROR));
5386              MYSQL_YYABORT;
5387            }
5388          }
5389        ;
5390
5391part_field_list:
5392          /* empty */ {}
5393        | part_field_item_list {}
5394        ;
5395
5396part_field_item_list:
5397          part_field_item {}
5398        | part_field_item_list ',' part_field_item {}
5399        ;
5400
5401part_field_item:
5402          ident
5403          {
5404            partition_info *part_info= Lex->part_info;
5405            part_info->num_columns++;
5406            if (part_info->part_field_list.push_back($1.str))
5407            {
5408              mem_alloc_error(1);
5409              MYSQL_YYABORT;
5410            }
5411            if (part_info->num_columns > MAX_REF_PARTS)
5412            {
5413              my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
5414                       "list of partition fields");
5415              MYSQL_YYABORT;
5416            }
5417          }
5418        ;
5419
5420part_column_list:
5421          COLUMNS '(' part_field_list ')'
5422          {
5423            partition_info *part_info= Lex->part_info;
5424            part_info->column_list= TRUE;
5425            part_info->list_of_part_fields= TRUE;
5426          }
5427        ;
5428
5429
5430part_func:
5431          '(' part_func_expr ')'
5432          {
5433            partition_info *part_info= Lex->part_info;
5434            /*
5435              TODO: replace @1.cpp.end with @2.cpp.start: we don't need whitespaces at
5436              the beginning of the partition expression string:
5437            */
5438            if (part_info->set_part_expr(const_cast<char *>(@1.cpp.end), $2,
5439                                         const_cast<char *>(@2.cpp.end), FALSE))
5440            { MYSQL_YYABORT; }
5441            part_info->num_columns= 1;
5442            part_info->column_list= FALSE;
5443          }
5444        ;
5445
5446sub_part_func:
5447          '(' part_func_expr ')'
5448          {
5449            /*
5450              TODO: replace @1.cpp.end with @2.cpp.start: we don't need whitespaces at
5451              the beginning of the partition expression string:
5452            */
5453            if (Lex->part_info->set_part_expr(const_cast<char *>(@1.cpp.end), $2,
5454                                              const_cast<char *>(@2.cpp.end), TRUE))
5455            { MYSQL_YYABORT; }
5456          }
5457        ;
5458
5459
5460opt_num_parts:
5461          /* empty */ {}
5462        | PARTITIONS_SYM real_ulong_num
5463          {
5464            uint num_parts= $2;
5465            partition_info *part_info= Lex->part_info;
5466            if (num_parts == 0)
5467            {
5468              my_error(ER_NO_PARTS_ERROR, MYF(0), "partitions");
5469              MYSQL_YYABORT;
5470            }
5471
5472            part_info->num_parts= num_parts;
5473            part_info->use_default_num_partitions= FALSE;
5474          }
5475        ;
5476
5477opt_sub_part:
5478          /* empty */ {}
5479        | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func
5480          { Lex->part_info->subpart_type= HASH_PARTITION; }
5481          opt_num_subparts {}
5482        | SUBPARTITION_SYM BY opt_linear KEY_SYM opt_key_algo
5483          '(' sub_part_field_list ')'
5484          {
5485            partition_info *part_info= Lex->part_info;
5486            part_info->subpart_type= HASH_PARTITION;
5487            part_info->list_of_subpart_fields= TRUE;
5488          }
5489          opt_num_subparts {}
5490        ;
5491
5492sub_part_field_list:
5493          sub_part_field_item {}
5494        | sub_part_field_list ',' sub_part_field_item {}
5495        ;
5496
5497sub_part_field_item:
5498          ident
5499          {
5500            partition_info *part_info= Lex->part_info;
5501            if (part_info->subpart_field_list.push_back($1.str))
5502            {
5503              mem_alloc_error(1);
5504              MYSQL_YYABORT;
5505            }
5506            if (part_info->subpart_field_list.elements > MAX_REF_PARTS)
5507            {
5508              my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
5509                       "list of subpartition fields");
5510              MYSQL_YYABORT;
5511            }
5512          }
5513        ;
5514
5515part_func_expr:
5516          bit_expr
5517          {
5518            ITEMIZE($1, &$1);
5519
5520            LEX *lex= Lex;
5521            bool not_corr_func;
5522            not_corr_func= !lex->safe_to_cache_query;
5523            lex->safe_to_cache_query= 1;
5524            if (not_corr_func)
5525            {
5526              my_syntax_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
5527              MYSQL_YYABORT;
5528            }
5529            $$=$1;
5530          }
5531        ;
5532
5533opt_num_subparts:
5534          /* empty */ {}
5535        | SUBPARTITIONS_SYM real_ulong_num
5536          {
5537            uint num_parts= $2;
5538            LEX *lex= Lex;
5539            if (num_parts == 0)
5540            {
5541              my_error(ER_NO_PARTS_ERROR, MYF(0), "subpartitions");
5542              MYSQL_YYABORT;
5543            }
5544            lex->part_info->num_subparts= num_parts;
5545            lex->part_info->use_default_num_subpartitions= FALSE;
5546          }
5547        ;
5548
5549part_defs:
5550          /* empty */
5551          {
5552            partition_info *part_info= Lex->part_info;
5553            if (part_info->part_type == RANGE_PARTITION)
5554            {
5555              my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
5556                       "RANGE");
5557              MYSQL_YYABORT;
5558            }
5559            else if (part_info->part_type == LIST_PARTITION)
5560            {
5561              my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
5562                       "LIST");
5563              MYSQL_YYABORT;
5564            }
5565          }
5566        | '(' part_def_list ')'
5567          {
5568            partition_info *part_info= Lex->part_info;
5569            uint count_curr_parts= part_info->partitions.elements;
5570            if (part_info->num_parts != 0)
5571            {
5572              if (part_info->num_parts !=
5573                  count_curr_parts)
5574              {
5575                my_syntax_error(ER(ER_PARTITION_WRONG_NO_PART_ERROR));
5576                MYSQL_YYABORT;
5577              }
5578            }
5579            else if (count_curr_parts > 0)
5580            {
5581              part_info->num_parts= count_curr_parts;
5582            }
5583            part_info->count_curr_subparts= 0;
5584          }
5585        ;
5586
5587part_def_list:
5588          part_definition {}
5589        | part_def_list ',' part_definition {}
5590        ;
5591
5592part_definition:
5593          PARTITION_SYM
5594          {
5595            partition_info *part_info= Lex->part_info;
5596            partition_element *p_elem= new partition_element();
5597
5598            if (!p_elem || part_info->partitions.push_back(p_elem))
5599            {
5600              mem_alloc_error(sizeof(partition_element));
5601              MYSQL_YYABORT;
5602            }
5603            p_elem->part_state= PART_NORMAL;
5604            part_info->curr_part_elem= p_elem;
5605            part_info->current_partition= p_elem;
5606            part_info->use_default_partitions= FALSE;
5607            part_info->use_default_num_partitions= FALSE;
5608          }
5609          part_name
5610          opt_part_values
5611          opt_part_options
5612          opt_sub_partition
5613          {}
5614        ;
5615
5616part_name:
5617          ident
5618          {
5619            partition_info *part_info= Lex->part_info;
5620            partition_element *p_elem= part_info->curr_part_elem;
5621            if (check_string_char_length(to_lex_cstring($1), "", NAME_CHAR_LEN,
5622                                         system_charset_info, true))
5623            {
5624              my_error(ER_TOO_LONG_IDENT, MYF(0), $1.str);
5625              MYSQL_YYABORT;
5626            }
5627            p_elem->partition_name= $1.str;
5628          }
5629        ;
5630
5631opt_part_values:
5632          /* empty */
5633          {
5634            LEX *lex= Lex;
5635            partition_info *part_info= lex->part_info;
5636            if (part_info->part_type == NOT_A_PARTITION)
5637              part_info->part_type= HASH_PARTITION;
5638            else if (part_info->part_type == RANGE_PARTITION)
5639            {
5640              my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
5641                       "RANGE", "LESS THAN");
5642              MYSQL_YYABORT;
5643            }
5644            else if (part_info->part_type == LIST_PARTITION)
5645            {
5646              my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
5647                       "LIST", "IN");
5648              MYSQL_YYABORT;
5649            }
5650          }
5651        | VALUES LESS_SYM THAN_SYM
5652          {
5653            LEX *lex= Lex;
5654            partition_info *part_info= lex->part_info;
5655            if (part_info->part_type == NOT_A_PARTITION)
5656              part_info->part_type= RANGE_PARTITION;
5657            else if (part_info->part_type != RANGE_PARTITION)
5658            {
5659              my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
5660                       "RANGE", "LESS THAN");
5661              MYSQL_YYABORT;
5662            }
5663          }
5664          part_func_max {}
5665        | VALUES IN_SYM
5666          {
5667            LEX *lex= Lex;
5668            partition_info *part_info= lex->part_info;
5669            if (part_info->part_type == NOT_A_PARTITION)
5670              part_info->part_type= LIST_PARTITION;
5671            else if (part_info->part_type != LIST_PARTITION)
5672            {
5673              my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
5674                       "LIST", "IN");
5675              MYSQL_YYABORT;
5676            }
5677          }
5678          part_values_in {}
5679        ;
5680
5681part_func_max:
5682          MAX_VALUE_SYM
5683          {
5684            partition_info *part_info= Lex->part_info;
5685
5686            if (part_info->num_columns &&
5687                part_info->num_columns != 1U)
5688            {
5689              part_info->print_debug("Kilroy II", NULL);
5690              my_syntax_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5691              MYSQL_YYABORT;
5692            }
5693            else
5694              part_info->num_columns= 1U;
5695            if (part_info->init_column_part())
5696            {
5697              MYSQL_YYABORT;
5698            }
5699            if (part_info->add_max_value())
5700            {
5701              MYSQL_YYABORT;
5702            }
5703          }
5704        | part_value_item {}
5705        ;
5706
5707part_values_in:
5708          part_value_item
5709          {
5710            LEX *lex= Lex;
5711            partition_info *part_info= lex->part_info;
5712            part_info->print_debug("part_values_in: part_value_item", NULL);
5713
5714            if (part_info->num_columns != 1U)
5715            {
5716              if (!lex->is_partition_management() ||
5717                  part_info->num_columns == 0 ||
5718                  part_info->num_columns > MAX_REF_PARTS)
5719              {
5720                part_info->print_debug("Kilroy III", NULL);
5721                my_syntax_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5722                MYSQL_YYABORT;
5723              }
5724              /*
5725                Reorganize the current large array into a list of small
5726                arrays with one entry in each array. This can happen
5727                in the first partition of an ALTER TABLE statement where
5728                we ADD or REORGANIZE partitions. Also can only happen
5729                for LIST [COLUMNS] partitions.
5730              */
5731              if (part_info->reorganize_into_single_field_col_val())
5732              {
5733                MYSQL_YYABORT;
5734              }
5735            }
5736          }
5737        | '(' part_value_list ')'
5738          {
5739            partition_info *part_info= Lex->part_info;
5740            if (part_info->num_columns < 2U)
5741            {
5742              my_syntax_error(ER(ER_ROW_SINGLE_PARTITION_FIELD_ERROR));
5743              MYSQL_YYABORT;
5744            }
5745          }
5746        ;
5747
5748part_value_list:
5749          part_value_item {}
5750        | part_value_list ',' part_value_item {}
5751        ;
5752
5753part_value_item:
5754          '('
5755          {
5756            partition_info *part_info= Lex->part_info;
5757            part_info->print_debug("( part_value_item", NULL);
5758            /* Initialisation code needed for each list of value expressions */
5759            if (!(part_info->part_type == LIST_PARTITION &&
5760                  part_info->num_columns == 1U) &&
5761                 part_info->init_column_part())
5762            {
5763              MYSQL_YYABORT;
5764            }
5765          }
5766          part_value_item_list {}
5767          ')'
5768          {
5769            partition_info *part_info= Lex->part_info;
5770            part_info->print_debug(") part_value_item", NULL);
5771            if (part_info->num_columns == 0)
5772              part_info->num_columns= part_info->curr_list_object;
5773            if (part_info->num_columns != part_info->curr_list_object)
5774            {
5775              /*
5776                All value items lists must be of equal length, in some cases
5777                which is covered by the above if-statement we don't know yet
5778                how many columns is in the partition so the assignment above
5779                ensures that we only report errors when we know we have an
5780                error.
5781              */
5782              part_info->print_debug("Kilroy I", NULL);
5783              my_syntax_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5784              MYSQL_YYABORT;
5785            }
5786            part_info->curr_list_object= 0;
5787          }
5788        ;
5789
5790part_value_item_list:
5791          part_value_expr_item {}
5792        | part_value_item_list ',' part_value_expr_item {}
5793        ;
5794
5795part_value_expr_item:
5796          MAX_VALUE_SYM
5797          {
5798            partition_info *part_info= Lex->part_info;
5799            if (part_info->part_type == LIST_PARTITION)
5800            {
5801              my_syntax_error(ER(ER_MAXVALUE_IN_VALUES_IN));
5802              MYSQL_YYABORT;
5803            }
5804            if (part_info->add_max_value())
5805            {
5806              MYSQL_YYABORT;
5807            }
5808          }
5809        | bit_expr
5810          {
5811            ITEMIZE($1, &$1);
5812
5813            LEX *lex= Lex;
5814            partition_info *part_info= lex->part_info;
5815            Item *part_expr= $1;
5816
5817            if (!lex->safe_to_cache_query)
5818            {
5819              my_syntax_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
5820              MYSQL_YYABORT;
5821            }
5822            if (part_info->add_column_list_value(YYTHD, part_expr))
5823            {
5824              MYSQL_YYABORT;
5825            }
5826          }
5827        ;
5828
5829
5830opt_sub_partition:
5831          /* empty */
5832          {
5833            partition_info *part_info= Lex->part_info;
5834            if (part_info->num_subparts != 0 &&
5835                !part_info->use_default_subpartitions)
5836            {
5837              /*
5838                We come here when we have defined subpartitions on the first
5839                partition but not on all the subsequent partitions.
5840              */
5841              my_syntax_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5842              MYSQL_YYABORT;
5843            }
5844          }
5845        | '(' sub_part_list ')'
5846          {
5847            partition_info *part_info= Lex->part_info;
5848            if (part_info->num_subparts != 0)
5849            {
5850              if (part_info->num_subparts !=
5851                  part_info->count_curr_subparts)
5852              {
5853                my_syntax_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5854                MYSQL_YYABORT;
5855              }
5856            }
5857            else if (part_info->count_curr_subparts > 0)
5858            {
5859              if (part_info->partitions.elements > 1)
5860              {
5861                my_syntax_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5862                MYSQL_YYABORT;
5863              }
5864              part_info->num_subparts= part_info->count_curr_subparts;
5865            }
5866            part_info->count_curr_subparts= 0;
5867          }
5868        ;
5869
5870sub_part_list:
5871          sub_part_definition {}
5872        | sub_part_list ',' sub_part_definition {}
5873        ;
5874
5875sub_part_definition:
5876          SUBPARTITION_SYM
5877          {
5878            partition_info *part_info= Lex->part_info;
5879            partition_element *curr_part= part_info->current_partition;
5880            partition_element *sub_p_elem= new partition_element(curr_part);
5881            if (part_info->use_default_subpartitions &&
5882                part_info->partitions.elements >= 2)
5883            {
5884              /*
5885                create table t1 (a int)
5886                partition by list (a) subpartition by hash (a)
5887                (partition p0 values in (1),
5888                 partition p1 values in (2) subpartition sp11);
5889                causes use to arrive since we are on the second
5890                partition, but still use_default_subpartitions
5891                is set. When we come here we're processing at least
5892                the second partition (the current partition processed
5893                have already been put into the partitions list.
5894              */
5895              my_syntax_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5896              MYSQL_YYABORT;
5897            }
5898            if (!sub_p_elem ||
5899             curr_part->subpartitions.push_back(sub_p_elem))
5900            {
5901              mem_alloc_error(sizeof(partition_element));
5902              MYSQL_YYABORT;
5903            }
5904            part_info->curr_part_elem= sub_p_elem;
5905            part_info->use_default_subpartitions= FALSE;
5906            part_info->use_default_num_subpartitions= FALSE;
5907            part_info->count_curr_subparts++;
5908          }
5909          sub_name opt_part_options {}
5910        ;
5911
5912sub_name:
5913          ident_or_text
5914          {
5915            if (check_string_char_length(to_lex_cstring($1), "", NAME_CHAR_LEN,
5916                                         system_charset_info, true))
5917            {
5918              my_error(ER_TOO_LONG_IDENT, MYF(0), $1.str);
5919              MYSQL_YYABORT;
5920            }
5921            Lex->part_info->curr_part_elem->partition_name= $1.str;
5922          }
5923        ;
5924
5925opt_part_options:
5926         /* empty */ {}
5927       | opt_part_option_list {}
5928       ;
5929
5930opt_part_option_list:
5931         opt_part_option_list opt_part_option {}
5932       | opt_part_option {}
5933       ;
5934
5935opt_part_option:
5936          TABLESPACE_SYM opt_equal ident
5937          { Lex->part_info->curr_part_elem->tablespace_name= $3.str; }
5938        | opt_storage ENGINE_SYM opt_equal storage_engines
5939          {
5940            partition_info *part_info= Lex->part_info;
5941            part_info->curr_part_elem->engine_type= $4;
5942            part_info->default_engine_type= $4;
5943          }
5944        | NODEGROUP_SYM opt_equal real_ulong_num
5945          { Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; }
5946        | MAX_ROWS opt_equal real_ulonglong_num
5947          { Lex->part_info->curr_part_elem->part_max_rows= (ha_rows) $3; }
5948        | MIN_ROWS opt_equal real_ulonglong_num
5949          { Lex->part_info->curr_part_elem->part_min_rows= (ha_rows) $3; }
5950        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
5951          { Lex->part_info->curr_part_elem->data_file_name= $4.str; }
5952        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
5953          { Lex->part_info->curr_part_elem->index_file_name= $4.str; }
5954        | COMMENT_SYM opt_equal TEXT_STRING_sys
5955          { Lex->part_info->curr_part_elem->part_comment= $3.str; }
5956        ;
5957
5958/*
5959 End of partition parser part
5960*/
5961
5962create_select:
5963          SELECT_SYM select_options select_item_list table_expression
5964          {
5965            $$= NEW_PTN PT_create_select($1, $2, $3, $4);
5966          }
5967        ;
5968
5969opt_as:
5970          /* empty */ {}
5971        | AS {}
5972        ;
5973
5974opt_create_database_options:
5975          /* empty */ {}
5976        | create_database_options {}
5977        ;
5978
5979create_database_options:
5980          create_database_option {}
5981        | create_database_options create_database_option {}
5982        ;
5983
5984create_database_option:
5985          default_collation {}
5986        | default_charset {}
5987        ;
5988
5989opt_table_options:
5990          /* empty */ { $$= 0; }
5991        | table_options  { $$= $1;}
5992        ;
5993
5994table_options:
5995          table_option { $$=$1; }
5996        | table_option table_options { $$= $1 | $2; }
5997        ;
5998
5999table_option:
6000          TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }
6001        ;
6002
6003opt_if_not_exists:
6004          /* empty */ { $$= 0; }
6005        | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
6006        ;
6007
6008opt_create_table_options:
6009          /* empty */
6010        | create_table_options
6011        ;
6012
6013create_table_options_space_separated:
6014          create_table_option
6015        | create_table_option create_table_options_space_separated
6016        ;
6017
6018create_table_options:
6019          create_table_option
6020        | create_table_option     create_table_options
6021        | create_table_option ',' create_table_options
6022        ;
6023
6024create_table_option:
6025          ENGINE_SYM opt_equal storage_engines
6026          {
6027            Lex->create_info.db_type= $3;
6028            Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
6029          }
6030        | MAX_ROWS opt_equal ulonglong_num
6031          {
6032            Lex->create_info.max_rows= $3;
6033            Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;
6034          }
6035        | MIN_ROWS opt_equal ulonglong_num
6036          {
6037            Lex->create_info.min_rows= $3;
6038            Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;
6039          }
6040        | AVG_ROW_LENGTH opt_equal ulong_num
6041          {
6042            Lex->create_info.avg_row_length=$3;
6043            Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;
6044          }
6045        | PASSWORD opt_equal TEXT_STRING_sys
6046          {
6047            Lex->create_info.password=$3.str;
6048            Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD;
6049          }
6050        | COMMENT_SYM opt_equal TEXT_STRING_sys
6051          {
6052            Lex->create_info.comment=$3;
6053            Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
6054          }
6055        | COMPRESSION_SYM opt_equal TEXT_STRING_sys
6056	  {
6057            Lex->create_info.used_fields|= HA_CREATE_USED_COMPRESS;
6058            Lex->create_info.compress= $3;
6059	  }
6060        | ENCRYPTION_SYM opt_equal TEXT_STRING_sys
6061	  {
6062            Lex->create_info.used_fields|= HA_CREATE_USED_ENCRYPT;
6063            Lex->create_info.encrypt_type= $3;
6064	  }
6065        | ENCRYPTION_KEY_ID_SYM opt_equal real_ulong_num
6066          {
6067            Lex->create_info.used_fields|= HA_CREATE_USED_ENCRYPTION_KEY_ID;
6068            Lex->create_info.was_encryption_key_id_set= true;
6069            Lex->create_info.encryption_key_id= $3;
6070          }
6071        | AUTO_INC opt_equal ulonglong_num
6072          {
6073            Lex->create_info.auto_increment_value=$3;
6074            Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;
6075          }
6076        | PACK_KEYS_SYM opt_equal ulong_num
6077          {
6078            switch($3) {
6079            case 0:
6080                Lex->create_info.table_options|= HA_OPTION_NO_PACK_KEYS;
6081                break;
6082            case 1:
6083                Lex->create_info.table_options|= HA_OPTION_PACK_KEYS;
6084                break;
6085            default:
6086                my_syntax_error(ER(ER_SYNTAX_ERROR));
6087                MYSQL_YYABORT;
6088            }
6089            Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
6090          }
6091        | PACK_KEYS_SYM opt_equal DEFAULT
6092          {
6093            Lex->create_info.table_options&=
6094              ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
6095            Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
6096          }
6097        | STATS_AUTO_RECALC_SYM opt_equal ulong_num
6098          {
6099            switch($3) {
6100            case 0:
6101                Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_OFF;
6102                break;
6103            case 1:
6104                Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_ON;
6105                break;
6106            default:
6107                my_syntax_error(ER(ER_SYNTAX_ERROR));
6108                MYSQL_YYABORT;
6109            }
6110            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
6111          }
6112        | STATS_AUTO_RECALC_SYM opt_equal DEFAULT
6113          {
6114            Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_DEFAULT;
6115            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
6116          }
6117        | STATS_PERSISTENT_SYM opt_equal ulong_num
6118          {
6119            switch($3) {
6120            case 0:
6121                Lex->create_info.table_options|= HA_OPTION_NO_STATS_PERSISTENT;
6122                break;
6123            case 1:
6124                Lex->create_info.table_options|= HA_OPTION_STATS_PERSISTENT;
6125                break;
6126            default:
6127                my_syntax_error(ER(ER_SYNTAX_ERROR));
6128                MYSQL_YYABORT;
6129            }
6130            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
6131          }
6132        | STATS_PERSISTENT_SYM opt_equal DEFAULT
6133          {
6134            Lex->create_info.table_options&=
6135              ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
6136            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
6137          }
6138        | STATS_SAMPLE_PAGES_SYM opt_equal ulong_num
6139          {
6140            /* From user point of view STATS_SAMPLE_PAGES can be specified as
6141            STATS_SAMPLE_PAGES=N (where 0<N<=65535, it does not make sense to
6142            scan 0 pages) or STATS_SAMPLE_PAGES=default. Internally we record
6143            =default as 0. See create_frm() in sql/table.cc, we use only two
6144            bytes for stats_sample_pages and this is why we do not allow
6145            larger values. 65535 pages, 16kb each means to sample 1GB, which
6146            is impractical. If at some point this needs to be extended, then
6147            we can store the higher bits from stats_sample_pages in .frm too. */
6148            if ($3 == 0 || $3 > 0xffff)
6149            {
6150              my_syntax_error(ER(ER_SYNTAX_ERROR));
6151              MYSQL_YYABORT;
6152            }
6153            Lex->create_info.stats_sample_pages=$3;
6154            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
6155          }
6156        | STATS_SAMPLE_PAGES_SYM opt_equal DEFAULT
6157          {
6158            Lex->create_info.stats_sample_pages=0;
6159            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
6160          }
6161        | CHECKSUM_SYM opt_equal ulong_num
6162          {
6163            Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
6164            Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
6165          }
6166        | TABLE_CHECKSUM_SYM opt_equal ulong_num
6167          {
6168             Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
6169             Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
6170          }
6171        | DELAY_KEY_WRITE_SYM opt_equal ulong_num
6172          {
6173            Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE;
6174            Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE;
6175          }
6176        | ROW_FORMAT_SYM opt_equal row_types
6177          {
6178            Lex->create_info.row_type= $3;
6179            Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
6180          }
6181        | UNION_SYM opt_equal
6182          {
6183            Lex->select_lex->table_list.save_and_clear(&Lex->save_list);
6184          }
6185          '(' opt_table_list ')'
6186          {
6187            /*
6188              Move the union list to the merge_list and exclude its tables
6189              from the global list.
6190            */
6191            LEX *lex=Lex;
6192            lex->create_info.merge_list= lex->select_lex->table_list;
6193            lex->select_lex->table_list= lex->save_list;
6194            /*
6195              When excluding union list from the global list we assume that
6196              elements of the former immediately follow elements which represent
6197              table being created/altered and parent tables.
6198            */
6199            TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
6200            assert(last_non_sel_table->next_global ==
6201            lex->create_info.merge_list.first);
6202            last_non_sel_table->next_global= 0;
6203            Lex->query_tables_last= &last_non_sel_table->next_global;
6204
6205            lex->create_info.used_fields|= HA_CREATE_USED_UNION;
6206          }
6207        | default_charset
6208        | default_collation
6209        | INSERT_METHOD opt_equal merge_insert_types
6210          {
6211            Lex->create_info.merge_insert_method= $3;
6212            Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;
6213          }
6214        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
6215          {
6216            Lex->create_info.data_file_name= $4.str;
6217            Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR;
6218          }
6219        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
6220          {
6221            Lex->create_info.index_file_name= $4.str;
6222            Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR;
6223          }
6224        | TABLESPACE_SYM opt_equal ident
6225          {
6226            Lex->create_info.tablespace= $3.str;
6227            Lex->create_info.used_fields|= HA_CREATE_USED_TABLESPACE;
6228          }
6229        | STORAGE_SYM DISK_SYM
6230          {Lex->create_info.storage_media= HA_SM_DISK;}
6231        | STORAGE_SYM MEMORY_SYM
6232          {Lex->create_info.storage_media= HA_SM_MEMORY;}
6233        | CONNECTION_SYM opt_equal TEXT_STRING_sys
6234          {
6235            Lex->create_info.connect_string.str= $3.str;
6236            Lex->create_info.connect_string.length= $3.length;
6237            Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION;
6238          }
6239        | KEY_BLOCK_SIZE opt_equal ulong_num
6240          {
6241            Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
6242            Lex->create_info.key_block_size= $3;
6243          }
6244        ;
6245
6246default_charset:
6247          opt_default charset opt_equal charset_name_or_default
6248          {
6249            HA_CREATE_INFO *cinfo= &Lex->create_info;
6250            if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
6251                 cinfo->default_table_charset && $4 &&
6252                 !my_charset_same(cinfo->default_table_charset,$4))
6253            {
6254              my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
6255                       "CHARACTER SET ", cinfo->default_table_charset->csname,
6256                       "CHARACTER SET ", $4->csname);
6257              MYSQL_YYABORT;
6258            }
6259            Lex->create_info.default_table_charset= $4;
6260            Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
6261          }
6262        ;
6263
6264default_collation:
6265          opt_default COLLATE_SYM opt_equal collation_name_or_default
6266          {
6267            HA_CREATE_INFO *cinfo= &Lex->create_info;
6268            if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
6269                 cinfo->default_table_charset && $4 &&
6270                 !($4= merge_charset_and_collation(cinfo->default_table_charset,
6271                                                   $4)))
6272            {
6273              MYSQL_YYABORT;
6274            }
6275
6276            Lex->create_info.default_table_charset= $4;
6277            Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
6278          }
6279        ;
6280
6281storage_engines:
6282          ident_or_text
6283          {
6284            THD *thd= YYTHD;
6285            plugin_ref plugin=
6286              ha_resolve_by_name(thd, &$1,
6287                thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
6288
6289            if (plugin)
6290              $$= plugin_data<handlerton*>(plugin);
6291            else
6292            {
6293              if (!is_engine_substitution_allowed(thd))
6294              {
6295                my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
6296                MYSQL_YYABORT;
6297              }
6298              $$= 0;
6299              push_warning_printf(thd, Sql_condition::SL_WARNING,
6300                                  ER_UNKNOWN_STORAGE_ENGINE,
6301                                  ER(ER_UNKNOWN_STORAGE_ENGINE),
6302                                  $1.str);
6303            }
6304          }
6305        ;
6306
6307known_storage_engines:
6308          ident_or_text
6309          {
6310            THD *thd= YYTHD;
6311            LEX *lex= thd->lex;
6312            plugin_ref plugin=
6313              ha_resolve_by_name(thd, &$1,
6314                lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
6315            if (plugin)
6316              $$= plugin_data<handlerton*>(plugin);
6317            else
6318            {
6319              my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
6320              MYSQL_YYABORT;
6321            }
6322          }
6323        ;
6324
6325row_types:
6326          DEFAULT        { $$= ROW_TYPE_DEFAULT; }
6327        | FIXED_SYM      { $$= ROW_TYPE_FIXED; }
6328        | DYNAMIC_SYM    { $$= ROW_TYPE_DYNAMIC; }
6329        | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
6330        | REDUNDANT_SYM  { $$= ROW_TYPE_REDUNDANT; }
6331        | COMPACT_SYM    { $$= ROW_TYPE_COMPACT; }
6332        | TOKU_UNCOMPRESSED_SYM { $$= ROW_TYPE_TOKU_UNCOMPRESSED; }
6333        | TOKU_ZLIB_SYM         { $$= ROW_TYPE_TOKU_ZLIB; }
6334        | TOKU_SNAPPY_SYM       { $$= ROW_TYPE_TOKU_SNAPPY; }
6335        | TOKU_QUICKLZ_SYM      { $$= ROW_TYPE_TOKU_QUICKLZ; }
6336        | TOKU_LZMA_SYM         { $$= ROW_TYPE_TOKU_LZMA; }
6337        | TOKU_FAST_SYM         { $$= ROW_TYPE_TOKU_FAST; }
6338        | TOKU_SMALL_SYM        { $$= ROW_TYPE_TOKU_SMALL; }
6339        | TOKU_DEFAULT_SYM      { $$= ROW_TYPE_TOKU_DEFAULT; }
6340        ;
6341
6342merge_insert_types:
6343         NO_SYM          { $$= MERGE_INSERT_DISABLED; }
6344       | FIRST_SYM       { $$= MERGE_INSERT_TO_FIRST; }
6345       | LAST_SYM        { $$= MERGE_INSERT_TO_LAST; }
6346       ;
6347
6348udf_type:
6349          STRING_SYM {$$ = (int) STRING_RESULT; }
6350        | REAL {$$ = (int) REAL_RESULT; }
6351        | DECIMAL_SYM {$$ = (int) DECIMAL_RESULT; }
6352        | INT_SYM {$$ = (int) INT_RESULT; }
6353        ;
6354
6355
6356create_field_list:
6357        field_list
6358        {
6359          Lex->create_last_non_select_table= Lex->last_table();
6360        }
6361        ;
6362
6363field_list:
6364          field_list_item
6365        | field_list ',' field_list_item
6366        ;
6367
6368field_list_item:
6369          column_def
6370        | key_def
6371        ;
6372
6373column_def:
6374          field_spec opt_check_constraint
6375        | field_spec references
6376          {
6377            Lex->col_list.empty(); /* Alloced by sql_alloc */
6378          }
6379        ;
6380
6381key_def:
6382          normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
6383          {
6384            if (add_create_index (Lex, $1, $2))
6385              MYSQL_YYABORT;
6386          }
6387        | fulltext opt_key_or_index opt_ident init_key_options
6388            '(' key_list ')' fulltext_key_options
6389          {
6390            if (add_create_index (Lex, $1, $3))
6391              MYSQL_YYABORT;
6392          }
6393        | spatial opt_key_or_index opt_ident init_key_options
6394            '(' key_list ')' spatial_key_options
6395          {
6396            if (add_create_index (Lex, $1, $3))
6397              MYSQL_YYABORT;
6398          }
6399        | opt_constraint constraint_key_type opt_ident key_alg
6400          '(' key_list ')' normal_key_options
6401          {
6402            if (($1.length != 0)
6403                 && ($2 == (KEYTYPE_CLUSTERING | KEYTYPE_MULTIPLE)))
6404            {
6405              /* Forbid "CONSTRAINT c CLUSTERING" */
6406              my_syntax_error(ER(ER_SYNTAX_ERROR));
6407              MYSQL_YYABORT;
6408            }
6409            if (add_create_index (Lex, $2, $3.str ? $3 : $1))
6410              MYSQL_YYABORT;
6411          }
6412        | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
6413          {
6414            LEX *lex=Lex;
6415            Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list,
6416                                      $8->db,
6417                                      $8->table,
6418                                      lex->ref_list,
6419                                      lex->fk_delete_opt,
6420                                      lex->fk_update_opt,
6421                                      lex->fk_match_option);
6422            if (key == NULL)
6423              MYSQL_YYABORT;
6424            lex->alter_info.key_list.push_back(key);
6425            if (add_create_index (lex, KEYTYPE_MULTIPLE, $1.str ? $1 : $4,
6426                                  &default_key_create_info, 1))
6427              MYSQL_YYABORT;
6428            /* Only used for ALTER TABLE. Ignored otherwise. */
6429            lex->alter_info.flags|= Alter_info::ADD_FOREIGN_KEY;
6430          }
6431        | opt_constraint check_constraint
6432          {
6433            Lex->col_list.empty(); /* Alloced by sql_alloc */
6434          }
6435        ;
6436
6437opt_check_constraint:
6438          /* empty */
6439        | check_constraint
6440        ;
6441
6442check_constraint:
6443          CHECK_SYM '(' expr ')'
6444          {
6445            ITEMIZE($3, &$3);
6446          }
6447
6448        ;
6449
6450opt_constraint:
6451          /* empty */ { $$= null_lex_str; }
6452        | constraint { $$= $1; }
6453        ;
6454
6455constraint:
6456          CONSTRAINT opt_ident { $$=$2; }
6457        ;
6458
6459field_spec:
6460          field_ident
6461          {
6462            LEX *lex=Lex;
6463            lex->length=lex->dec=0;
6464            lex->type=0;
6465            lex->default_value= lex->on_update_value= 0;
6466            lex->comment=null_lex_str;
6467            lex->charset=NULL;
6468            lex->zip_dict_name=null_lex_cstr;
6469            lex->gcol_info= 0;
6470          }
6471          field_def
6472          {
6473            LEX *lex=Lex;
6474            if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3,
6475                                  lex->length,lex->dec,lex->type,
6476                                  lex->default_value, lex->on_update_value,
6477                                  &lex->comment,
6478                                  lex->change,&lex->interval_list,lex->charset,
6479                                  lex->uint_geom_type,
6480                                  &lex->zip_dict_name,
6481                                  lex->gcol_info))
6482              MYSQL_YYABORT;
6483          }
6484        ;
6485
6486field_def:
6487          type opt_attribute {}
6488        | type opt_collate_explicit opt_generated_always
6489          AS '(' generated_column_func ')' opt_stored_attribute
6490          opt_gcol_attribute_list
6491          {
6492            $$= $1;
6493            if (Lex->charset)
6494            {
6495              Lex->charset= merge_charset_and_collation(Lex->charset, $2);
6496              if (Lex->charset == NULL)
6497                MYSQL_YYABORT;
6498            }
6499            else
6500              Lex->charset= $2;
6501            Lex->gcol_info->set_field_type((enum enum_field_types) $$);
6502          }
6503        ;
6504
6505opt_generated_always:
6506          /* empty */
6507        | GENERATED ALWAYS_SYM
6508        ;
6509
6510opt_gcol_attribute_list:
6511          /* empty */
6512        | gcol_attribute_list
6513        ;
6514
6515gcol_attribute_list:
6516          gcol_attribute_list gcol_attribute
6517        | gcol_attribute
6518        ;
6519
6520gcol_attribute:
6521          UNIQUE_SYM
6522          {
6523            LEX *lex=Lex;
6524            lex->type|= UNIQUE_FLAG;
6525            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6526          }
6527        | UNIQUE_SYM KEY_SYM
6528          {
6529            LEX *lex=Lex;
6530            lex->type|= UNIQUE_KEY_FLAG;
6531            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6532          }
6533        | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
6534        | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
6535        | NULL_SYM
6536        | opt_primary KEY_SYM
6537          {
6538            LEX *lex=Lex;
6539            lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
6540            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6541          }
6542        | COLUMN_FORMAT_SYM DEFAULT
6543          {
6544            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6545            Lex->type|=
6546              (COLUMN_FORMAT_TYPE_DEFAULT << FIELD_FLAGS_COLUMN_FORMAT);
6547          }
6548        | COLUMN_FORMAT_SYM COMPRESSED_SYM opt_with_compression_dictionary
6549          {
6550            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6551            Lex->type|=
6552              (COLUMN_FORMAT_TYPE_COMPRESSED << FIELD_FLAGS_COLUMN_FORMAT);
6553            Lex->zip_dict_name= $3;
6554          }
6555        ;
6556
6557opt_stored_attribute:
6558          /* empty */
6559        | VIRTUAL_SYM
6560        | STORED_SYM
6561          {
6562            Lex->gcol_info->set_field_stored(TRUE);
6563          }
6564        ;
6565
6566parse_gcol_expr:
6567          PARSE_GCOL_EXPR_SYM '(' generated_column_func ')'
6568          {
6569            /*
6570              "PARSE_GCOL_EXPR" can only be used by the SQL server
6571              when reading a '*.frm' file.
6572              Prevent the end user from invoking this command.
6573            */
6574            if (!Lex->parse_gcol_expr)
6575            {
6576              YYTHD->parse_error_at(@1, ER_THD(YYTHD, ER_SYNTAX_ERROR));
6577              MYSQL_YYABORT;
6578            }
6579          }
6580        ;
6581
6582generated_column_func:
6583          expr
6584          {
6585            Lex->gcol_info= new Generated_column();
6586            if (!Lex->gcol_info)
6587            {
6588              mem_alloc_error(sizeof(Generated_column));
6589              MYSQL_YYABORT;
6590            }
6591            ITEMIZE($1, &$1);
6592            uint expr_len= (uint)@1.cpp.length();
6593            Lex->gcol_info->dup_expr_str(YYTHD->mem_root, @1.cpp.start, expr_len);
6594            Lex->gcol_info->expr_item= $1;
6595            /*
6596              @todo: problems:
6597              - here we have a call to the constructor of
6598              Generated_column, which takes no argument and builds a
6599              non-functional object
6600              - then we fill it member by member; either by assignment to
6601              public members (!) or by call to a public setter. Both these
6602              techniques allow changing, at any future point in time, vital
6603              properties of the object which should rather be constant.
6604              Class should rather have a constructor which takes arguments,
6605              sets members, and members should be constant after that.
6606              This would also get rid of some setters like set_field_stored();
6607            */
6608          }
6609        ;
6610
6611type:
6612          int_type opt_field_length field_options
6613          {
6614            Lex->length= const_cast<char *>($2);
6615            $$=$1;
6616          }
6617        | real_type opt_precision field_options
6618          {
6619            $$=$1;
6620            Lex->length= const_cast<char *>($2.length);
6621            Lex->dec= const_cast<char *>($2.dec);
6622          }
6623        | FLOAT_SYM float_options field_options
6624          {
6625            Lex->length= const_cast<char *>($2.length);
6626            Lex->dec= const_cast<char *>($2.dec);
6627            $$=MYSQL_TYPE_FLOAT;
6628          }
6629        | BIT_SYM
6630          {
6631            Lex->length= (char*) "1";
6632            $$=MYSQL_TYPE_BIT;
6633          }
6634        | BIT_SYM field_length
6635          {
6636            Lex->length= const_cast<char *>($2);
6637            $$=MYSQL_TYPE_BIT;
6638          }
6639        | BOOL_SYM
6640          {
6641            Lex->length= (char*) "1";
6642            $$=MYSQL_TYPE_TINY;
6643          }
6644        | BOOLEAN_SYM
6645          {
6646            Lex->length= (char*) "1";
6647            $$=MYSQL_TYPE_TINY;
6648          }
6649        | char field_length opt_binary
6650          {
6651            Lex->length= const_cast<char *>($2);
6652            Lex->charset= $3.charset;
6653            Lex->type|= $3.type_flags;
6654            $$=MYSQL_TYPE_STRING;
6655          }
6656        | char opt_binary
6657          {
6658            Lex->length= (char*) "1";
6659            Lex->charset= $2.charset;
6660            Lex->type|= $2.type_flags;
6661            $$=MYSQL_TYPE_STRING;
6662          }
6663        | nchar field_length opt_bin_mod
6664          {
6665            Lex->length= const_cast<char *>($2);
6666            Lex->type|= $3;
6667            $$=MYSQL_TYPE_STRING;
6668            Lex->charset=national_charset_info;
6669          }
6670        | nchar opt_bin_mod
6671          {
6672            Lex->length= (char*) "1";
6673            Lex->type|= $2;
6674            $$=MYSQL_TYPE_STRING;
6675            Lex->charset=national_charset_info;
6676          }
6677        | BINARY field_length
6678          {
6679            Lex->length= const_cast<char *>($2);
6680            Lex->charset=&my_charset_bin;
6681            $$=MYSQL_TYPE_STRING;
6682          }
6683        | BINARY
6684          {
6685            Lex->length= (char*) "1";
6686            Lex->charset=&my_charset_bin;
6687            $$=MYSQL_TYPE_STRING;
6688          }
6689        | varchar field_length opt_binary
6690          {
6691            Lex->length= const_cast<char *>($2);
6692            Lex->charset= $3.charset;
6693            Lex->type|= $3.type_flags;
6694            $$= MYSQL_TYPE_VARCHAR;
6695          }
6696        | nvarchar field_length opt_bin_mod
6697          {
6698            Lex->length= const_cast<char *>($2);
6699            Lex->type|= $3;
6700            $$= MYSQL_TYPE_VARCHAR;
6701            Lex->charset=national_charset_info;
6702          }
6703        | VARBINARY field_length
6704          {
6705            Lex->length= const_cast<char *>($2);
6706            Lex->charset=&my_charset_bin;
6707            $$= MYSQL_TYPE_VARCHAR;
6708          }
6709        | YEAR_SYM opt_field_length field_options
6710          {
6711            Lex->length= const_cast<char *>($2);
6712            if (Lex->length)
6713            {
6714              errno= 0;
6715              ulong length= strtoul(Lex->length, NULL, 10);
6716              if (errno != 0 || length != 4)
6717              {
6718                /* Only support length is 4 */
6719                my_error(ER_INVALID_YEAR_COLUMN_LENGTH, MYF(0), "YEAR");
6720                MYSQL_YYABORT;
6721              }
6722            }
6723            $$=MYSQL_TYPE_YEAR;
6724          }
6725        | DATE_SYM
6726          { $$=MYSQL_TYPE_DATE; }
6727        | TIME_SYM type_datetime_precision
6728          {
6729            Lex->dec= const_cast<char *>($2);
6730            $$= MYSQL_TYPE_TIME2;
6731          }
6732        | TIMESTAMP type_datetime_precision
6733          {
6734            Lex->dec= const_cast<char *>($2);
6735            if (YYTHD->variables.sql_mode & MODE_MAXDB)
6736            {
6737              push_warning(current_thd, Sql_condition::SL_WARNING,
6738                  WARN_DEPRECATED_MAXDB_SQL_MODE_FOR_TIMESTAMP,
6739                  ER_THD(YYTHD, WARN_DEPRECATED_MAXDB_SQL_MODE_FOR_TIMESTAMP));
6740              $$=MYSQL_TYPE_DATETIME2;
6741            }
6742            else
6743            {
6744              /*
6745                Unlike other types TIMESTAMP fields are NOT NULL by default.
6746                This behavior is deprecated now.
6747              */
6748              if (!YYTHD->variables.explicit_defaults_for_timestamp)
6749                Lex->type|= NOT_NULL_FLAG;
6750              /*
6751                To flag the current statement as dependent for binary
6752                logging on the session var. Extra copying to Lex is
6753                done in case prepared stmt.
6754              */
6755              Lex->binlog_need_explicit_defaults_ts=
6756                YYTHD->binlog_need_explicit_defaults_ts= true;
6757
6758              $$=MYSQL_TYPE_TIMESTAMP2;
6759            }
6760          }
6761        | DATETIME type_datetime_precision
6762          {
6763            Lex->dec= const_cast<char *>($2);
6764            $$= MYSQL_TYPE_DATETIME2;
6765          }
6766        | TINYBLOB
6767          {
6768            Lex->charset=&my_charset_bin;
6769            $$=MYSQL_TYPE_TINY_BLOB;
6770          }
6771        | BLOB_SYM opt_field_length
6772          {
6773            Lex->length= const_cast<char *>($2);
6774            Lex->charset=&my_charset_bin;
6775            $$=MYSQL_TYPE_BLOB;
6776          }
6777        | spatial_type
6778          {
6779            Lex->charset=&my_charset_bin;
6780            Lex->uint_geom_type= (uint)$1;
6781            $$=MYSQL_TYPE_GEOMETRY;
6782          }
6783        | MEDIUMBLOB
6784          {
6785            Lex->charset=&my_charset_bin;
6786            $$=MYSQL_TYPE_MEDIUM_BLOB;
6787          }
6788        | LONGBLOB
6789          {
6790            Lex->charset=&my_charset_bin;
6791            $$=MYSQL_TYPE_LONG_BLOB;
6792          }
6793        | LONG_SYM VARBINARY
6794          {
6795            Lex->charset=&my_charset_bin;
6796            $$=MYSQL_TYPE_MEDIUM_BLOB;
6797          }
6798        | LONG_SYM varchar opt_binary
6799          {
6800            Lex->charset= $3.charset;
6801            Lex->type|= $3.type_flags;
6802            $$=MYSQL_TYPE_MEDIUM_BLOB;
6803          }
6804        | TINYTEXT opt_binary
6805          {
6806            Lex->charset= $2.charset;
6807            Lex->type|= $2.type_flags;
6808            $$=MYSQL_TYPE_TINY_BLOB;
6809          }
6810        | TEXT_SYM opt_field_length opt_binary
6811          {
6812            Lex->length= const_cast<char *>($2);
6813            Lex->charset= $3.charset;
6814            Lex->type|= $3.type_flags;
6815            $$=MYSQL_TYPE_BLOB;
6816          }
6817        | MEDIUMTEXT opt_binary
6818          {
6819            Lex->charset= $2.charset;
6820            Lex->type|= $2.type_flags;
6821            $$=MYSQL_TYPE_MEDIUM_BLOB;
6822          }
6823        | LONGTEXT opt_binary
6824          {
6825            Lex->charset= $2.charset;
6826            Lex->type|= $2.type_flags;
6827            $$=MYSQL_TYPE_LONG_BLOB;
6828          }
6829        | DECIMAL_SYM float_options field_options
6830          {
6831            Lex->length= const_cast<char *>($2.length);
6832            Lex->dec= const_cast<char *>($2.dec);
6833            $$=MYSQL_TYPE_NEWDECIMAL;
6834          }
6835        | NUMERIC_SYM float_options field_options
6836          {
6837            Lex->length= const_cast<char *>($2.length);
6838            Lex->dec= const_cast<char *>($2.dec);
6839            $$=MYSQL_TYPE_NEWDECIMAL;
6840          }
6841        | FIXED_SYM float_options field_options
6842          {
6843            Lex->length= const_cast<char *>($2.length);
6844            Lex->dec= const_cast<char *>($2.dec);
6845            $$=MYSQL_TYPE_NEWDECIMAL;
6846          }
6847        | ENUM
6848          {Lex->interval_list.empty();}
6849          '(' string_list ')' opt_binary
6850          {
6851            Lex->charset= $6.charset;
6852            Lex->type|= $6.type_flags;
6853            $$=MYSQL_TYPE_ENUM;
6854          }
6855        | SET
6856          { Lex->interval_list.empty();}
6857          '(' string_list ')' opt_binary
6858          {
6859            Lex->charset= $6.charset;
6860            Lex->type|= $6.type_flags;
6861            $$=MYSQL_TYPE_SET;
6862          }
6863        | LONG_SYM opt_binary
6864          {
6865            Lex->charset= $2.charset;
6866            Lex->type|= $2.type_flags;
6867            $$=MYSQL_TYPE_MEDIUM_BLOB;
6868          }
6869        | SERIAL_SYM
6870          {
6871            $$=MYSQL_TYPE_LONGLONG;
6872            Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
6873              UNIQUE_FLAG);
6874          }
6875        | JSON_SYM
6876          {
6877            Lex->charset=&my_charset_bin;
6878            $$=MYSQL_TYPE_JSON;
6879          }
6880        ;
6881
6882spatial_type:
6883          GEOMETRY_SYM        { $$= Field::GEOM_GEOMETRY; }
6884        | GEOMETRYCOLLECTION  { $$= Field::GEOM_GEOMETRYCOLLECTION; }
6885        | POINT_SYM
6886          {
6887            Lex->length= const_cast<char*>(STRINGIFY_ARG
6888                                           (MAX_LEN_GEOM_POINT_FIELD));
6889            $$= Field::GEOM_POINT;
6890          }
6891        | MULTIPOINT          { $$= Field::GEOM_MULTIPOINT; }
6892        | LINESTRING          { $$= Field::GEOM_LINESTRING; }
6893        | MULTILINESTRING     { $$= Field::GEOM_MULTILINESTRING; }
6894        | POLYGON             { $$= Field::GEOM_POLYGON; }
6895        | MULTIPOLYGON        { $$= Field::GEOM_MULTIPOLYGON; }
6896        ;
6897
6898char:
6899          CHAR_SYM {}
6900        ;
6901
6902nchar:
6903          NCHAR_SYM {}
6904        | NATIONAL_SYM CHAR_SYM {}
6905        ;
6906
6907varchar:
6908          char VARYING {}
6909        | VARCHAR {}
6910        ;
6911
6912nvarchar:
6913          NATIONAL_SYM VARCHAR {}
6914        | NVARCHAR_SYM {}
6915        | NCHAR_SYM VARCHAR {}
6916        | NATIONAL_SYM CHAR_SYM VARYING {}
6917        | NCHAR_SYM VARYING {}
6918        ;
6919
6920int_type:
6921          INT_SYM   { $$=MYSQL_TYPE_LONG; }
6922        | TINYINT   { $$=MYSQL_TYPE_TINY; }
6923        | SMALLINT  { $$=MYSQL_TYPE_SHORT; }
6924        | MEDIUMINT { $$=MYSQL_TYPE_INT24; }
6925        | BIGINT    { $$=MYSQL_TYPE_LONGLONG; }
6926        ;
6927
6928real_type:
6929          REAL
6930          {
6931            $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ?
6932              MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
6933          }
6934        | DOUBLE_SYM
6935          { $$=MYSQL_TYPE_DOUBLE; }
6936        | DOUBLE_SYM PRECISION
6937          { $$=MYSQL_TYPE_DOUBLE; }
6938        ;
6939
6940float_options:
6941          /* empty */
6942          {
6943            $$.length= NULL;
6944            $$.dec= NULL;
6945          }
6946        | field_length
6947          {
6948            $$.length= $1;
6949            $$.dec= NULL;
6950          }
6951        | precision
6952        ;
6953
6954precision:
6955          '(' NUM ',' NUM ')'
6956          {
6957            $$.length= $2.str;
6958            $$.dec= $4.str;
6959          }
6960        ;
6961
6962
6963type_datetime_precision:
6964          /* empty */                { $$= NULL; }
6965        | '(' NUM ')'                { $$= $2.str; }
6966        ;
6967
6968func_datetime_precision:
6969          /* empty */                { $$= 0; }
6970        | '(' ')'                    { $$= 0; }
6971        | '(' NUM ')'
6972           {
6973             int error;
6974             $$= (ulong) my_strtoll10($2.str, NULL, &error);
6975           }
6976        ;
6977
6978field_options:
6979          /* empty */ {}
6980        | field_opt_list {}
6981        ;
6982
6983field_opt_list:
6984          field_opt_list field_option {}
6985        | field_option {}
6986        ;
6987
6988field_option:
6989          SIGNED_SYM {}
6990        | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
6991        | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
6992        ;
6993
6994field_length:
6995          '(' LONG_NUM ')'      { $$= $2.str; }
6996        | '(' ULONGLONG_NUM ')' { $$= $2.str; }
6997        | '(' DECIMAL_NUM ')'   { $$= $2.str; }
6998        | '(' NUM ')'           { $$= $2.str; };
6999
7000opt_field_length:
7001          /* empty */  { $$= NULL; /* use default length */ }
7002        | field_length
7003        ;
7004
7005opt_precision:
7006          /* empty */
7007          {
7008            $$.length= NULL;
7009            $$.dec = NULL;
7010          }
7011        | precision
7012        ;
7013
7014opt_attribute:
7015          /* empty */ {}
7016        | opt_attribute_list {}
7017        ;
7018
7019opt_attribute_list:
7020          opt_attribute_list attribute {}
7021        | attribute
7022        ;
7023
7024attribute:
7025          NULL_SYM
7026          {
7027            Lex->type&= ~ NOT_NULL_FLAG;
7028            Lex->type|= EXPLICIT_NULL_FLAG;
7029          }
7030        | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
7031        | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
7032        | ON UPDATE_SYM now
7033          {
7034            Item *item= new (YYTHD->mem_root)
7035              Item_func_now_local(static_cast<uint8>($3));
7036            if (item == NULL)
7037              MYSQL_YYABORT;
7038            Lex->on_update_value= item;
7039          }
7040        | AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
7041        | SERIAL_SYM DEFAULT VALUE_SYM
7042          {
7043            LEX *lex=Lex;
7044            lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
7045            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
7046          }
7047        | opt_primary KEY_SYM
7048          {
7049            LEX *lex=Lex;
7050            lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
7051            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
7052          }
7053        | unique_combo_clustering
7054          {
7055            LEX *lex=Lex;
7056            if ($1 & KEYTYPE_UNIQUE)
7057              lex->type|= UNIQUE_FLAG;
7058            if ($1 & KEYTYPE_CLUSTERING)
7059              lex->type|= CLUSTERING_FLAG;
7060            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
7061          }
7062        | unique_combo_clustering KEY_SYM
7063          {
7064            LEX *lex=Lex;
7065            if ($1 & KEYTYPE_UNIQUE)
7066              lex->type|= UNIQUE_KEY_FLAG;
7067            if ($1 & KEYTYPE_CLUSTERING)
7068              lex->type|= CLUSTERING_FLAG;
7069            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
7070          }
7071        | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
7072        | COLLATE_SYM collation_name
7073          {
7074            if (Lex->charset && !my_charset_same(Lex->charset,$2))
7075            {
7076              my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
7077                       $2->name,Lex->charset->csname);
7078              MYSQL_YYABORT;
7079            }
7080            else
7081            {
7082              Lex->charset=$2;
7083            }
7084          }
7085        | COLUMN_FORMAT_SYM DEFAULT
7086          {
7087            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
7088            Lex->type|=
7089              (COLUMN_FORMAT_TYPE_DEFAULT << FIELD_FLAGS_COLUMN_FORMAT);
7090          }
7091        | COLUMN_FORMAT_SYM FIXED_SYM
7092          {
7093            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
7094            Lex->type|=
7095              (COLUMN_FORMAT_TYPE_FIXED << FIELD_FLAGS_COLUMN_FORMAT);
7096          }
7097        | COLUMN_FORMAT_SYM DYNAMIC_SYM
7098          {
7099            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
7100            Lex->type|=
7101              (COLUMN_FORMAT_TYPE_DYNAMIC << FIELD_FLAGS_COLUMN_FORMAT);
7102          }
7103        | COLUMN_FORMAT_SYM COMPRESSED_SYM opt_with_compression_dictionary
7104          {
7105            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
7106            Lex->type|=
7107              (COLUMN_FORMAT_TYPE_COMPRESSED << FIELD_FLAGS_COLUMN_FORMAT);
7108            Lex->zip_dict_name= $3;
7109          }
7110        | STORAGE_SYM DEFAULT
7111          {
7112            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
7113            Lex->type|= (HA_SM_DEFAULT << FIELD_FLAGS_STORAGE_MEDIA);
7114          }
7115        | STORAGE_SYM DISK_SYM
7116          {
7117            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
7118            Lex->type|= (HA_SM_DISK << FIELD_FLAGS_STORAGE_MEDIA);
7119          }
7120        | STORAGE_SYM MEMORY_SYM
7121          {
7122            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
7123            Lex->type|= (HA_SM_MEMORY << FIELD_FLAGS_STORAGE_MEDIA);
7124          }
7125        ;
7126
7127opt_with_compression_dictionary:
7128          /* empty */ { $$= null_lex_cstr; }
7129        | WITH COMPRESSION_DICTIONARY_SYM ident
7130          {
7131            /*
7132              no single assignment because of
7133              LEX_STRING -> LEX_CSTRING conversion
7134            */
7135            $$.str= $3.str;
7136            $$.length= $3.length;
7137          }
7138        ;
7139
7140type_with_opt_collate:
7141        type opt_collate
7142        {
7143          $$= $1;
7144
7145          if (Lex->charset) /* Lex->charset is scanned in "type" */
7146          {
7147            if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
7148              MYSQL_YYABORT;
7149          }
7150          else if ($2)
7151          {
7152            my_error(ER_NOT_SUPPORTED_YET, MYF(0),
7153                     "COLLATE with no CHARACTER SET "
7154                     "in SP parameters, RETURNS, DECLARE");
7155            MYSQL_YYABORT;
7156          }
7157        }
7158        ;
7159
7160
7161now:
7162          NOW_SYM func_datetime_precision
7163          {
7164            $$= $2;
7165          };
7166
7167now_or_signed_literal:
7168          now
7169          {
7170            $$= new (YYTHD->mem_root)
7171              Item_func_now_local(static_cast<uint8>($1));
7172            if ($$ == NULL)
7173              MYSQL_YYABORT;
7174          }
7175        | signed_literal
7176          { $$=$1; }
7177        ;
7178
7179charset:
7180          CHAR_SYM SET {}
7181        | CHARSET {}
7182        ;
7183
7184charset_name:
7185          ident_or_text
7186          {
7187            if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))
7188            {
7189              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
7190              MYSQL_YYABORT;
7191            }
7192          }
7193        | BINARY { $$= &my_charset_bin; }
7194        ;
7195
7196charset_name_or_default:
7197          charset_name { $$=$1;   }
7198        | DEFAULT    { $$=NULL; }
7199        ;
7200
7201opt_load_data_charset:
7202          /* Empty */ { $$= NULL; }
7203        | charset charset_name_or_default { $$= $2; }
7204        ;
7205
7206old_or_new_charset_name:
7207          ident_or_text
7208          {
7209            if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) &&
7210                !($$=get_old_charset_by_name($1.str)))
7211            {
7212              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
7213              MYSQL_YYABORT;
7214            }
7215          }
7216        | BINARY { $$= &my_charset_bin; }
7217        ;
7218
7219old_or_new_charset_name_or_default:
7220          old_or_new_charset_name { $$=$1;   }
7221        | DEFAULT    { $$=NULL; }
7222        ;
7223
7224collation_name:
7225          ident_or_text
7226          {
7227            if (!($$= mysqld_collation_get_by_name($1.str)))
7228              MYSQL_YYABORT;
7229          }
7230        ;
7231
7232opt_collate:
7233          /* empty */ { $$=NULL; }
7234        | COLLATE_SYM collation_name_or_default { $$=$2; }
7235        ;
7236
7237opt_collate_explicit:
7238          /* empty */ { $$= NULL; }
7239        | COLLATE_SYM collation_name { $$= $2; }
7240        ;
7241
7242collation_name_or_default:
7243          collation_name { $$=$1; }
7244        | DEFAULT    { $$=NULL; }
7245        ;
7246
7247opt_default:
7248          /* empty */ {}
7249        | DEFAULT {}
7250        ;
7251
7252
7253ascii:
7254          ASCII_SYM        { $$= &my_charset_latin1; }
7255        | BINARY ASCII_SYM { $$= &my_charset_latin1_bin; }
7256        | ASCII_SYM BINARY { $$= &my_charset_latin1_bin; }
7257        ;
7258
7259unicode:
7260          UNICODE_SYM
7261          {
7262            if (!($$= get_charset_by_csname("ucs2", MY_CS_PRIMARY,MYF(0))))
7263            {
7264              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
7265              MYSQL_YYABORT;
7266            }
7267          }
7268        | UNICODE_SYM BINARY
7269          {
7270            if (!($$= mysqld_collation_get_by_name("ucs2_bin")))
7271              MYSQL_YYABORT;
7272          }
7273        | BINARY UNICODE_SYM
7274          {
7275            if (!($$= mysqld_collation_get_by_name("ucs2_bin")))
7276              my_error(ER_UNKNOWN_COLLATION, MYF(0), "ucs2_bin");
7277          }
7278        ;
7279
7280opt_binary:
7281          /* empty */
7282          {
7283            $$.charset= NULL;
7284            $$.type_flags= 0;
7285          }
7286        | ascii
7287          {
7288            $$.charset= $1;
7289            $$.type_flags= 0;
7290          }
7291        | unicode
7292          {
7293            $$.charset= $1;
7294            $$.type_flags= 0;
7295          }
7296        | BYTE_SYM
7297          {
7298            $$.charset= &my_charset_bin;
7299            $$.type_flags= 0;
7300          }
7301        | charset charset_name opt_bin_mod
7302          {
7303            $$.charset= $2;
7304            $$.type_flags= $3;
7305          }
7306        | BINARY
7307          {
7308            $$.charset= NULL;
7309            $$.type_flags= BINCMP_FLAG;
7310          }
7311        | BINARY charset charset_name
7312          {
7313            $$.charset= $3;
7314            $$.type_flags= BINCMP_FLAG;
7315          }
7316        ;
7317
7318opt_bin_mod:
7319          /* empty */ { $$= 0; }
7320        | BINARY      { $$= BINCMP_FLAG; }
7321        ;
7322
7323ws_nweights:
7324        '(' real_ulong_num
7325        {
7326          if ($2 == 0)
7327          {
7328            my_syntax_error(ER(ER_SYNTAX_ERROR));
7329            MYSQL_YYABORT;
7330          }
7331        }
7332        ')'
7333        { $$= $2; }
7334        ;
7335
7336ws_level_flag_desc:
7337        ASC { $$= 0; }
7338        | DESC { $$= 1 << MY_STRXFRM_DESC_SHIFT; }
7339        ;
7340
7341ws_level_flag_reverse:
7342        REVERSE_SYM { $$= 1 << MY_STRXFRM_REVERSE_SHIFT; } ;
7343
7344ws_level_flags:
7345        /* empty */ { $$= 0; }
7346        | ws_level_flag_desc { $$= $1; }
7347        | ws_level_flag_desc ws_level_flag_reverse { $$= $1 | $2; }
7348        | ws_level_flag_reverse { $$= $1 ; }
7349        ;
7350
7351ws_level_number:
7352        real_ulong_num
7353        {
7354          $$= $1 < 1 ? 1 : ($1 > MY_STRXFRM_NLEVELS ? MY_STRXFRM_NLEVELS : $1);
7355          $$--;
7356        }
7357        ;
7358
7359ws_level_list_item:
7360        ws_level_number ws_level_flags
7361        {
7362          $$= (1 | $2) << $1;
7363        }
7364        ;
7365
7366ws_level_list:
7367        ws_level_list_item { $$= $1; }
7368        | ws_level_list ',' ws_level_list_item { $$|= $3; }
7369        ;
7370
7371ws_level_range:
7372        ws_level_number '-' ws_level_number
7373        {
7374          uint start= $1;
7375          uint end= $3;
7376          for ($$= 0; start <= end; start++)
7377            $$|= (1 << start);
7378        }
7379        ;
7380
7381ws_level_list_or_range:
7382        ws_level_list { $$= $1; }
7383        | ws_level_range { $$= $1; }
7384        ;
7385
7386opt_ws_levels:
7387        /* empty*/ { $$= 0; }
7388        | LEVEL_SYM ws_level_list_or_range { $$= $2; }
7389        ;
7390
7391opt_primary:
7392          /* empty */
7393        | PRIMARY_SYM
7394        ;
7395
7396references:
7397          REFERENCES
7398          table_ident
7399          opt_ref_list
7400          opt_match_clause
7401          opt_on_update_delete
7402          {
7403            $$=$2;
7404          }
7405        ;
7406
7407opt_ref_list:
7408          /* empty */
7409          { Lex->ref_list.empty(); }
7410        | '(' ref_list ')'
7411        ;
7412
7413ref_list:
7414          ref_list ',' ident
7415          {
7416            Key_part_spec *key= new Key_part_spec($3, 0);
7417            if (key == NULL)
7418              MYSQL_YYABORT;
7419            Lex->ref_list.push_back(key);
7420          }
7421        | ident
7422          {
7423            Key_part_spec *key= new Key_part_spec($1, 0);
7424            if (key == NULL)
7425              MYSQL_YYABORT;
7426            LEX *lex= Lex;
7427            lex->ref_list.empty();
7428            lex->ref_list.push_back(key);
7429          }
7430        ;
7431
7432opt_match_clause:
7433          /* empty */
7434          { Lex->fk_match_option= FK_MATCH_UNDEF; }
7435        | MATCH FULL
7436          { Lex->fk_match_option= FK_MATCH_FULL; }
7437        | MATCH PARTIAL
7438          { Lex->fk_match_option= FK_MATCH_PARTIAL; }
7439        | MATCH SIMPLE_SYM
7440          { Lex->fk_match_option= FK_MATCH_SIMPLE; }
7441        ;
7442
7443opt_on_update_delete:
7444          /* empty */
7445          {
7446            LEX *lex= Lex;
7447            lex->fk_update_opt= FK_OPTION_UNDEF;
7448            lex->fk_delete_opt= FK_OPTION_UNDEF;
7449          }
7450        | ON UPDATE_SYM delete_option
7451          {
7452            LEX *lex= Lex;
7453            lex->fk_update_opt= $3;
7454            lex->fk_delete_opt= FK_OPTION_UNDEF;
7455          }
7456        | ON DELETE_SYM delete_option
7457          {
7458            LEX *lex= Lex;
7459            lex->fk_update_opt= FK_OPTION_UNDEF;
7460            lex->fk_delete_opt= $3;
7461          }
7462        | ON UPDATE_SYM delete_option
7463          ON DELETE_SYM delete_option
7464          {
7465            LEX *lex= Lex;
7466            lex->fk_update_opt= $3;
7467            lex->fk_delete_opt= $6;
7468          }
7469        | ON DELETE_SYM delete_option
7470          ON UPDATE_SYM delete_option
7471          {
7472            LEX *lex= Lex;
7473            lex->fk_update_opt= $6;
7474            lex->fk_delete_opt= $3;
7475          }
7476        ;
7477
7478delete_option:
7479          RESTRICT      { $$= FK_OPTION_RESTRICT; }
7480        | CASCADE       { $$= FK_OPTION_CASCADE; }
7481        | SET NULL_SYM  { $$= FK_OPTION_SET_NULL; }
7482        | NO_SYM ACTION { $$= FK_OPTION_NO_ACTION; }
7483        | SET DEFAULT   { $$= FK_OPTION_DEFAULT;  }
7484        ;
7485
7486normal_key_type:
7487          key_or_index { $$= KEYTYPE_MULTIPLE; }
7488        ;
7489
7490constraint_key_type:
7491          PRIMARY_SYM KEY_SYM { $$= KEYTYPE_PRIMARY; }
7492        | unique_combo_clustering opt_key_or_index { $$= $1; }
7493
7494        ;
7495
7496key_or_index:
7497          KEY_SYM {}
7498        | INDEX_SYM {}
7499        ;
7500
7501opt_key_or_index:
7502          /* empty */ {}
7503        | key_or_index
7504        ;
7505
7506keys_or_index:
7507          KEYS {}
7508        | INDEX_SYM {}
7509        | INDEXES {}
7510        ;
7511
7512opt_unique_combo_clustering:
7513          /* empty */          { $$= KEYTYPE_MULTIPLE; }
7514        | unique_combo_clustering
7515        ;
7516
7517unique_combo_clustering:
7518          clustering
7519          {
7520            $$= (enum keytype)($1 | KEYTYPE_MULTIPLE);
7521          }
7522        | unique_opt_clustering
7523          {
7524            $$= $1;
7525          }
7526        ;
7527
7528unique_opt_clustering:
7529          unique
7530          {
7531            $$= $1;
7532          }
7533        | unique clustering
7534          {
7535            $$= (enum keytype)($1 | $2);
7536          }
7537        | clustering unique
7538          {
7539            $$= (enum keytype)($1 | $2);
7540          }
7541        ;
7542
7543unique:
7544          UNIQUE_SYM     { $$= KEYTYPE_UNIQUE; }
7545        ;
7546
7547clustering:
7548          CLUSTERING_SYM { $$= KEYTYPE_CLUSTERING; }
7549        ;
7550
7551fulltext:
7552          FULLTEXT_SYM { $$= KEYTYPE_FULLTEXT;}
7553        ;
7554
7555spatial:
7556          SPATIAL_SYM
7557          {
7558            $$= KEYTYPE_SPATIAL;
7559          }
7560        ;
7561
7562init_key_options:
7563          {
7564            Lex->key_create_info= default_key_create_info;
7565          }
7566        ;
7567
7568/*
7569  For now, key_alg initializies lex->key_create_info.
7570  In the future, when all key options are after key definition,
7571  we can remove key_alg and move init_key_options to key_options
7572*/
7573
7574key_alg:
7575          init_key_options
7576        | init_key_options key_using_alg
7577        ;
7578
7579normal_key_options:
7580          /* empty */ {}
7581        | normal_key_opts
7582        ;
7583
7584fulltext_key_options:
7585          /* empty */ {}
7586        | fulltext_key_opts
7587        ;
7588
7589spatial_key_options:
7590          /* empty */ {}
7591        | spatial_key_opts
7592        ;
7593
7594normal_key_opts:
7595          normal_key_opt
7596        | normal_key_opts normal_key_opt
7597        ;
7598
7599spatial_key_opts:
7600          spatial_key_opt
7601        | spatial_key_opts spatial_key_opt
7602        ;
7603
7604fulltext_key_opts:
7605          fulltext_key_opt
7606        | fulltext_key_opts fulltext_key_opt
7607        ;
7608
7609key_using_alg:
7610          USING btree_or_rtree     { Lex->key_create_info.algorithm= $2; }
7611        | TYPE_SYM btree_or_rtree  { Lex->key_create_info.algorithm= $2; }
7612        ;
7613
7614all_key_opt:
7615          KEY_BLOCK_SIZE opt_equal ulong_num
7616          { Lex->key_create_info.block_size= $3; }
7617        | COMMENT_SYM TEXT_STRING_sys { Lex->key_create_info.comment= $2; }
7618        ;
7619
7620normal_key_opt:
7621          all_key_opt
7622        | key_using_alg
7623        ;
7624
7625spatial_key_opt:
7626          all_key_opt
7627        ;
7628
7629fulltext_key_opt:
7630          all_key_opt
7631        | WITH PARSER_SYM IDENT_sys
7632          {
7633            LEX_CSTRING plugin_name= {$3.str, $3.length};
7634            if (plugin_is_ready(plugin_name, MYSQL_FTPARSER_PLUGIN))
7635              Lex->key_create_info.parser_name= $3;
7636            else
7637            {
7638              my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
7639              MYSQL_YYABORT;
7640            }
7641          }
7642        ;
7643
7644btree_or_rtree:
7645          BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
7646        | RTREE_SYM { $$= HA_KEY_ALG_RTREE; }
7647        | HASH_SYM  { $$= HA_KEY_ALG_HASH; }
7648        ;
7649
7650key_list:
7651          key_list ',' key_part opt_ordering_direction
7652          {
7653            Lex->col_list.push_back($3);
7654          }
7655        | key_part opt_ordering_direction
7656          {
7657            Lex->col_list.push_back($1);
7658          }
7659        ;
7660
7661key_part:
7662          ident
7663          {
7664            $$= new Key_part_spec($1, 0);
7665            if ($$ == NULL)
7666              MYSQL_YYABORT;
7667          }
7668        | ident '(' NUM ')'
7669          {
7670            int key_part_len= atoi($3.str);
7671            if (!key_part_len)
7672            {
7673              my_error(ER_KEY_PART_0, MYF(0), $1.str);
7674            }
7675            $$= new Key_part_spec($1, (uint) key_part_len);
7676            if ($$ == NULL)
7677              MYSQL_YYABORT;
7678          }
7679        ;
7680
7681opt_ident:
7682          /* empty */ { $$= null_lex_str; }
7683        | field_ident { $$= $1; }
7684        ;
7685
7686opt_component:
7687          /* empty */    { $$= null_lex_str; }
7688        | '.' ident      { $$= $2; }
7689        ;
7690
7691string_list:
7692          text_string { Lex->interval_list.push_back($1); }
7693        | string_list ',' text_string { Lex->interval_list.push_back($3); };
7694
7695/*
7696** Alter table
7697*/
7698
7699alter:
7700          ALTER TABLE_SYM table_ident
7701          {
7702            THD *thd= YYTHD;
7703            LEX *lex= thd->lex;
7704            lex->name.str= 0;
7705            lex->name.length= 0;
7706            lex->sql_command= SQLCOM_ALTER_TABLE;
7707            lex->duplicates= DUP_ERROR;
7708            if (!lex->select_lex->add_table_to_list(thd, $3, NULL,
7709                                                    TL_OPTION_UPDATING,
7710                                                    TL_READ_NO_INSERT,
7711                                                    MDL_SHARED_UPGRADABLE))
7712              MYSQL_YYABORT;
7713            lex->col_list.empty();
7714            lex->select_lex->init_order();
7715            lex->select_lex->db=
7716                    const_cast<char*>((lex->select_lex->table_list.first)->db);
7717	    new (&lex->create_info) HA_CREATE_INFO;
7718            lex->create_info.db_type= 0;
7719            lex->create_info.default_table_charset= NULL;
7720            lex->create_info.row_type= ROW_TYPE_NOT_USED;
7721            lex->alter_info.reset();
7722            lex->no_write_to_binlog= 0;
7723            lex->create_info.storage_media= HA_SM_DEFAULT;
7724            lex->create_last_non_select_table= lex->last_table();
7725            assert(!lex->m_sql_cmd);
7726          }
7727          alter_commands
7728          {
7729            THD *thd= YYTHD;
7730            LEX *lex= thd->lex;
7731            if (!lex->m_sql_cmd)
7732            {
7733              /* Create a generic ALTER TABLE statment. */
7734              lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table();
7735              if (lex->m_sql_cmd == NULL)
7736                MYSQL_YYABORT;
7737            }
7738          }
7739        | ALTER DATABASE ident_or_empty
7740          {
7741            Lex->create_info.default_table_charset= NULL;
7742            Lex->create_info.used_fields= 0;
7743          }
7744          create_database_options
7745          {
7746            LEX *lex=Lex;
7747            lex->sql_command=SQLCOM_ALTER_DB;
7748            lex->name= $3;
7749            if (lex->name.str == NULL &&
7750                lex->copy_db_to(&lex->name.str, &lex->name.length))
7751              MYSQL_YYABORT;
7752          }
7753        | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
7754          {
7755            LEX *lex= Lex;
7756            push_deprecated_warn_no_replacement(YYTHD,
7757              "UPGRADE DATA DIRECTORY NAME");
7758            if (lex->sphead)
7759            {
7760              my_error(ER_SP_NO_DROP_SP, MYF(0), "DATABASE");
7761              MYSQL_YYABORT;
7762            }
7763            lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
7764            lex->name= $3;
7765          }
7766        | ALTER PROCEDURE_SYM sp_name
7767          {
7768            LEX *lex= Lex;
7769
7770            if (lex->sphead)
7771            {
7772              my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
7773              MYSQL_YYABORT;
7774            }
7775            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
7776          }
7777          sp_a_chistics
7778          {
7779            LEX *lex=Lex;
7780
7781            lex->sql_command= SQLCOM_ALTER_PROCEDURE;
7782            lex->spname= $3;
7783          }
7784        | ALTER FUNCTION_SYM sp_name
7785          {
7786            LEX *lex= Lex;
7787
7788            if (lex->sphead)
7789            {
7790              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
7791              MYSQL_YYABORT;
7792            }
7793            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
7794          }
7795          sp_a_chistics
7796          {
7797            LEX *lex=Lex;
7798
7799            lex->sql_command= SQLCOM_ALTER_FUNCTION;
7800            lex->spname= $3;
7801          }
7802        | ALTER view_algorithm definer_opt
7803          {
7804            LEX *lex= Lex;
7805
7806            if (lex->sphead)
7807            {
7808              my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
7809              MYSQL_YYABORT;
7810            }
7811            lex->create_view_mode= VIEW_ALTER;
7812          }
7813          view_tail
7814          {}
7815        | ALTER definer_opt
7816          /*
7817            We have two separate rules for ALTER VIEW rather that
7818            optional view_algorithm above, to resolve the ambiguity
7819            with the ALTER EVENT below.
7820          */
7821          {
7822            LEX *lex= Lex;
7823
7824            if (lex->sphead)
7825            {
7826              my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
7827              MYSQL_YYABORT;
7828            }
7829            lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
7830            lex->create_view_mode= VIEW_ALTER;
7831          }
7832          view_tail
7833          {}
7834        | ALTER definer_opt EVENT_SYM sp_name
7835          {
7836            /*
7837              It is safe to use Lex->spname because
7838              ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
7839              is not allowed. Lex->spname is used in the case of RENAME TO
7840              If it had to be supported spname had to be added to
7841              Event_parse_data.
7842            */
7843
7844            if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
7845              MYSQL_YYABORT;
7846            Lex->event_parse_data->identifier= $4;
7847
7848            Lex->sql_command= SQLCOM_ALTER_EVENT;
7849          }
7850          ev_alter_on_schedule_completion
7851          opt_ev_rename_to
7852          opt_ev_status
7853          opt_ev_comment
7854          opt_ev_sql_stmt
7855          {
7856            if (!($6 || $7 || $8 || $9 || $10))
7857            {
7858              my_syntax_error(ER(ER_SYNTAX_ERROR));
7859              MYSQL_YYABORT;
7860            }
7861            /*
7862              sql_command is set here because some rules in ev_sql_stmt
7863              can overwrite it
7864            */
7865            Lex->sql_command= SQLCOM_ALTER_EVENT;
7866          }
7867        | ALTER TABLESPACE_SYM alter_tablespace_info
7868          {
7869            LEX *lex= Lex;
7870            lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
7871          }
7872        | ALTER LOGFILE_SYM GROUP_SYM alter_logfile_group_info
7873          {
7874            LEX *lex= Lex;
7875            lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
7876          }
7877        | ALTER TABLESPACE_SYM change_tablespace_info
7878          {
7879            LEX *lex= Lex;
7880            lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE;
7881          }
7882        | ALTER TABLESPACE_SYM change_tablespace_access
7883          {
7884            LEX *lex= Lex;
7885            lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE;
7886          }
7887        | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
7888          {
7889            LEX *lex= Lex;
7890            lex->sql_command= SQLCOM_ALTER_SERVER;
7891            lex->server_options.m_server_name= $3;
7892            lex->m_sql_cmd=
7893              new (YYTHD->mem_root) Sql_cmd_alter_server(&Lex->server_options);
7894          }
7895        | alter_user_command grant_list require_clause
7896          connect_options opt_account_lock_password_expire_options
7897        | alter_user_command user_func IDENTIFIED_SYM BY TEXT_STRING
7898          {
7899            $2->auth.str= $5.str;
7900            $2->auth.length= $5.length;
7901            $2->uses_identified_by_clause= true;
7902            Lex->contains_plaintext_password= true;
7903          }
7904        | alter_instance_stmt { MAKE_CMD($1); }
7905        ;
7906
7907alter_user_command:
7908          ALTER USER if_exists clear_privileges
7909          {
7910            LEX *lex= Lex;
7911            lex->sql_command= SQLCOM_ALTER_USER;
7912            lex->drop_if_exists= $3;
7913          }
7914        ;
7915
7916opt_account_lock_password_expire_options:
7917          /* empty */ {}
7918        | opt_account_lock_password_expire_option_list
7919        ;
7920
7921opt_account_lock_password_expire_option_list:
7922          opt_account_lock_password_expire_option
7923        | opt_account_lock_password_expire_option_list opt_account_lock_password_expire_option
7924        ;
7925
7926opt_account_lock_password_expire_option:
7927          ACCOUNT_SYM UNLOCK_SYM
7928          {
7929            LEX *lex=Lex;
7930            lex->alter_password.update_account_locked_column= true;
7931            lex->alter_password.account_locked= false;
7932          }
7933        | ACCOUNT_SYM LOCK_SYM
7934          {
7935            LEX *lex=Lex;
7936            lex->alter_password.update_account_locked_column= true;
7937            lex->alter_password.account_locked= true;
7938          }
7939        | password_expire
7940          {
7941            LEX *lex=Lex;
7942            lex->alter_password.update_password_expired_fields= true;
7943            lex->alter_password.update_password_expired_column= true;
7944          }
7945        | password_expire INTERVAL_SYM real_ulong_num DAY_SYM
7946          {
7947            LEX *lex=Lex;
7948            if ($3 == 0 || $3 > UINT_MAX16)
7949            {
7950              char buf[MAX_BIGINT_WIDTH + 1];
7951              my_snprintf(buf, sizeof(buf), "%lu", $3);
7952              my_error(ER_WRONG_VALUE, MYF(0), "DAY", buf);
7953              MYSQL_YYABORT;
7954            }
7955            lex->alter_password.update_password_expired_fields= true;
7956            lex->alter_password.expire_after_days= $3;
7957            lex->alter_password.use_default_password_lifetime= false;
7958          }
7959        | password_expire NEVER_SYM
7960          {
7961            LEX *lex=Lex;
7962            lex->alter_password.update_password_expired_fields= true;
7963            lex->alter_password.use_default_password_lifetime= false;
7964          }
7965        | password_expire DEFAULT
7966          {
7967            Lex->alter_password.update_password_expired_fields= true;
7968          }
7969        ;
7970
7971password_expire:
7972          PASSWORD EXPIRE_SYM clear_password_expire_options {}
7973        ;
7974
7975connect_options:
7976          /* empty */ {}
7977        | WITH connect_option_list
7978        ;
7979
7980connect_option_list:
7981          connect_option_list connect_option {}
7982        | connect_option {}
7983        ;
7984
7985connect_option:
7986          MAX_QUERIES_PER_HOUR ulong_num
7987          {
7988            LEX *lex=Lex;
7989            lex->mqh.questions=$2;
7990            lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
7991          }
7992        | MAX_UPDATES_PER_HOUR ulong_num
7993          {
7994            LEX *lex=Lex;
7995            lex->mqh.updates=$2;
7996            lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
7997          }
7998        | MAX_CONNECTIONS_PER_HOUR ulong_num
7999          {
8000            LEX *lex=Lex;
8001            lex->mqh.conn_per_hour= $2;
8002            lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
8003          }
8004        | MAX_USER_CONNECTIONS_SYM ulong_num
8005          {
8006            LEX *lex=Lex;
8007            lex->mqh.user_conn= $2;
8008            lex->mqh.specified_limits|= USER_RESOURCES::USER_CONNECTIONS;
8009          }
8010        ;
8011
8012user_func:
8013          USER '(' ')'
8014          {
8015            /* empty LEX_USER means current_user */
8016            LEX_USER *curr_user;
8017            if (!(curr_user= (LEX_USER*) Lex->thd->alloc(sizeof(st_lex_user))))
8018              MYSQL_YYABORT;
8019
8020            memset(curr_user, 0, sizeof(st_lex_user));
8021            Lex->users_list.push_back(curr_user);
8022            $$= curr_user;
8023          }
8024        ;
8025
8026ev_alter_on_schedule_completion:
8027          /* empty */ { $$= 0;}
8028        | ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
8029        | ev_on_completion { $$= 1; }
8030        | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; }
8031        ;
8032
8033opt_ev_rename_to:
8034          /* empty */ { $$= 0;}
8035        | RENAME TO_SYM sp_name
8036          {
8037            /*
8038              Use lex's spname to hold the new name.
8039              The original name is in the Event_parse_data object
8040            */
8041            Lex->spname= $3;
8042            $$= 1;
8043          }
8044        ;
8045
8046opt_ev_sql_stmt:
8047          /* empty*/ { $$= 0;}
8048        | DO_SYM ev_sql_stmt { $$= 1; }
8049        ;
8050
8051ident_or_empty:
8052          /* empty */ { $$.str= 0; $$.length= 0; }
8053        | ident { $$= $1; }
8054        ;
8055
8056alter_commands:
8057          alter_command_list
8058        | alter_command_list partitioning
8059        | alter_command_list remove_partitioning
8060        | standalone_alter_commands
8061        | alter_commands_modifier_list ',' standalone_alter_commands
8062        ;
8063
8064alter_command_list:
8065	  /* empty */
8066        | alter_commands_modifier_list
8067        | alter_list
8068        | alter_commands_modifier_list ',' alter_list
8069        ;
8070
8071standalone_alter_commands:
8072          DISCARD TABLESPACE_SYM
8073          {
8074            Lex->m_sql_cmd= new (YYTHD->mem_root)
8075              Sql_cmd_discard_import_tablespace(
8076                Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE);
8077            if (Lex->m_sql_cmd == NULL)
8078              MYSQL_YYABORT;
8079          }
8080        | IMPORT TABLESPACE_SYM
8081          {
8082            Lex->m_sql_cmd= new (YYTHD->mem_root)
8083              Sql_cmd_discard_import_tablespace(
8084                Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE);
8085            if (Lex->m_sql_cmd == NULL)
8086              MYSQL_YYABORT;
8087          }
8088/*
8089  This part was added for release 5.1 by Mikael Ronström.
8090  From here we insert a number of commands to manage the partitions of a
8091  partitioned table such as adding partitions, dropping partitions,
8092  reorganising partitions in various manners. In future releases the list
8093  will be longer.
8094*/
8095        | add_partition_rule
8096        | DROP PARTITION_SYM alt_part_name_list
8097          {
8098            Lex->alter_info.flags|= Alter_info::ALTER_DROP_PARTITION;
8099          }
8100        | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog
8101          all_or_alt_part_name_list
8102          {
8103            LEX *lex= Lex;
8104            lex->alter_info.flags|= Alter_info::ALTER_REBUILD_PARTITION;
8105            lex->no_write_to_binlog= $3;
8106          }
8107        | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog
8108          all_or_alt_part_name_list
8109          {
8110            THD *thd= YYTHD;
8111            LEX *lex= thd->lex;
8112            lex->no_write_to_binlog= $3;
8113            lex->check_opt.init();
8114            assert(!lex->m_sql_cmd);
8115            lex->m_sql_cmd= new (thd->mem_root)
8116                              Sql_cmd_alter_table_optimize_partition();
8117            if (lex->m_sql_cmd == NULL)
8118              MYSQL_YYABORT;
8119          }
8120          opt_no_write_to_binlog
8121        | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog
8122          all_or_alt_part_name_list
8123          {
8124            THD *thd= YYTHD;
8125            LEX *lex= thd->lex;
8126            lex->no_write_to_binlog= $3;
8127            lex->check_opt.init();
8128            assert(!lex->m_sql_cmd);
8129            lex->m_sql_cmd= new (thd->mem_root)
8130                              Sql_cmd_alter_table_analyze_partition();
8131            if (lex->m_sql_cmd == NULL)
8132              MYSQL_YYABORT;
8133          }
8134        | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
8135          {
8136            THD *thd= YYTHD;
8137            LEX *lex= thd->lex;
8138            lex->check_opt.init();
8139            assert(!lex->m_sql_cmd);
8140            lex->m_sql_cmd= new (thd->mem_root)
8141                              Sql_cmd_alter_table_check_partition();
8142            if (lex->m_sql_cmd == NULL)
8143              MYSQL_YYABORT;
8144          }
8145          opt_mi_check_type
8146        | REPAIR PARTITION_SYM opt_no_write_to_binlog
8147          all_or_alt_part_name_list
8148          {
8149            THD *thd= YYTHD;
8150            LEX *lex= thd->lex;
8151            lex->no_write_to_binlog= $3;
8152            lex->check_opt.init();
8153            assert(!lex->m_sql_cmd);
8154            lex->m_sql_cmd= new (thd->mem_root)
8155                              Sql_cmd_alter_table_repair_partition();
8156            if (lex->m_sql_cmd == NULL)
8157              MYSQL_YYABORT;
8158          }
8159          opt_mi_repair_type
8160        | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num
8161          {
8162            LEX *lex= Lex;
8163            lex->alter_info.flags|= Alter_info::ALTER_COALESCE_PARTITION;
8164            lex->no_write_to_binlog= $3;
8165            lex->alter_info.num_parts= $4;
8166          }
8167        | TRUNCATE_SYM PARTITION_SYM all_or_alt_part_name_list
8168          {
8169            THD *thd= YYTHD;
8170            LEX *lex= thd->lex;
8171            lex->check_opt.init();
8172            assert(!lex->m_sql_cmd);
8173            lex->m_sql_cmd= new (thd->mem_root)
8174                              Sql_cmd_alter_table_truncate_partition();
8175            if (lex->m_sql_cmd == NULL)
8176              MYSQL_YYABORT;
8177          }
8178        | reorg_partition_rule
8179        | EXCHANGE_SYM PARTITION_SYM alt_part_name_item
8180          WITH TABLE_SYM table_ident opt_validation
8181          {
8182            THD *thd= YYTHD;
8183            LEX *lex= thd->lex;
8184            size_t dummy;
8185            lex->select_lex->db= const_cast<char*>($6->db.str);
8186            if (lex->select_lex->db == NULL &&
8187                lex->copy_db_to(&lex->select_lex->db, &dummy))
8188            {
8189              MYSQL_YYABORT;
8190            }
8191            lex->name.str= const_cast<char*>($6->table.str);
8192            lex->name.length= $6->table.length;
8193            lex->alter_info.flags|= Alter_info::ALTER_EXCHANGE_PARTITION;
8194            if (!lex->select_lex->add_table_to_list(thd, $6, NULL,
8195                                                    TL_OPTION_UPDATING,
8196                                                    TL_READ_NO_INSERT,
8197                                                    MDL_SHARED_NO_WRITE))
8198              MYSQL_YYABORT;
8199              assert(!lex->m_sql_cmd);
8200            lex->m_sql_cmd= new (thd->mem_root)
8201                               Sql_cmd_alter_table_exchange_partition();
8202            if (lex->m_sql_cmd == NULL)
8203              MYSQL_YYABORT;
8204          }
8205        | DISCARD PARTITION_SYM all_or_alt_part_name_list
8206          TABLESPACE_SYM
8207          {
8208            Lex->m_sql_cmd= new (YYTHD->mem_root)
8209              Sql_cmd_discard_import_tablespace(
8210                Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE);
8211            if (Lex->m_sql_cmd == NULL)
8212              MYSQL_YYABORT;
8213          }
8214        | IMPORT PARTITION_SYM all_or_alt_part_name_list
8215          TABLESPACE_SYM
8216          {
8217            Lex->m_sql_cmd= new (YYTHD->mem_root)
8218              Sql_cmd_discard_import_tablespace(
8219                Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE);
8220            if (Lex->m_sql_cmd == NULL)
8221              MYSQL_YYABORT;
8222          }
8223        ;
8224
8225opt_validation:
8226          /* empty */
8227        | alter_opt_validation
8228        ;
8229
8230alter_opt_validation:
8231        WITH VALIDATION_SYM
8232          {
8233            Lex->alter_info.with_validation= Alter_info::ALTER_WITH_VALIDATION;
8234          }
8235        | WITHOUT_SYM VALIDATION_SYM
8236          {
8237            Lex->alter_info.with_validation=
8238              Alter_info::ALTER_WITHOUT_VALIDATION;
8239          }
8240	    ;
8241
8242remove_partitioning:
8243          REMOVE_SYM PARTITIONING_SYM
8244          {
8245            Lex->alter_info.flags|= Alter_info::ALTER_REMOVE_PARTITIONING;
8246          }
8247        ;
8248
8249all_or_alt_part_name_list:
8250          ALL
8251          {
8252            Lex->alter_info.flags|= Alter_info::ALTER_ALL_PARTITION;
8253          }
8254        | alt_part_name_list
8255        ;
8256
8257add_partition_rule:
8258          ADD PARTITION_SYM opt_no_write_to_binlog
8259          {
8260            LEX *lex= Lex;
8261            lex->part_info= new partition_info();
8262            if (!lex->part_info)
8263            {
8264              mem_alloc_error(sizeof(partition_info));
8265              MYSQL_YYABORT;
8266            }
8267            lex->alter_info.flags|= Alter_info::ALTER_ADD_PARTITION;
8268            lex->no_write_to_binlog= $3;
8269          }
8270          add_part_extra
8271          {}
8272        ;
8273
8274add_part_extra:
8275          /* empty */
8276        | '(' part_def_list ')'
8277          {
8278            LEX *lex= Lex;
8279            lex->part_info->num_parts= lex->part_info->partitions.elements;
8280          }
8281        | PARTITIONS_SYM real_ulong_num
8282          {
8283            Lex->part_info->num_parts= $2;
8284          }
8285        ;
8286
8287reorg_partition_rule:
8288          REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog
8289          {
8290            LEX *lex= Lex;
8291            lex->part_info= new partition_info();
8292            if (!lex->part_info)
8293            {
8294              mem_alloc_error(sizeof(partition_info));
8295              MYSQL_YYABORT;
8296            }
8297            lex->no_write_to_binlog= $3;
8298          }
8299          reorg_parts_rule
8300        ;
8301
8302reorg_parts_rule:
8303          /* empty */
8304          {
8305            Lex->alter_info.flags|= Alter_info::ALTER_TABLE_REORG;
8306          }
8307        | alt_part_name_list
8308          {
8309            Lex->alter_info.flags|= Alter_info::ALTER_REORGANIZE_PARTITION;
8310          }
8311          INTO '(' part_def_list ')'
8312          {
8313            partition_info *part_info= Lex->part_info;
8314            part_info->num_parts= part_info->partitions.elements;
8315          }
8316        ;
8317
8318alt_part_name_list:
8319          alt_part_name_item {}
8320        | alt_part_name_list ',' alt_part_name_item {}
8321        ;
8322
8323alt_part_name_item:
8324          ident
8325          {
8326            String *s= new (YYTHD->mem_root) String((const char *) $1.str,
8327                                                    $1.length,
8328                                                    system_charset_info);
8329            if (s == NULL)
8330              MYSQL_YYABORT;
8331            if (Lex->alter_info.partition_names.push_back(s))
8332            {
8333              mem_alloc_error(1);
8334              MYSQL_YYABORT;
8335            }
8336          }
8337        ;
8338
8339/*
8340  End of management of partition commands
8341*/
8342
8343alter_list:
8344          alter_list_item
8345        | alter_list ',' alter_list_item
8346        | alter_list ',' alter_commands_modifier
8347        ;
8348
8349alter_commands_modifier_list:
8350          alter_commands_modifier
8351        | alter_commands_modifier_list ',' alter_commands_modifier
8352        ;
8353
8354add_column:
8355          ADD opt_column
8356          {
8357            LEX *lex=Lex;
8358            lex->change=0;
8359            lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN;
8360          }
8361        ;
8362
8363alter_list_item:
8364          add_column column_def opt_place
8365          {
8366            Lex->create_last_non_select_table= Lex->last_table();
8367          }
8368        | ADD key_def
8369          {
8370            Lex->create_last_non_select_table= Lex->last_table();
8371            Lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
8372          }
8373        | add_column '(' create_field_list ')'
8374        | CHANGE opt_column field_ident
8375          {
8376            LEX *lex=Lex;
8377            lex->change= $3.str;
8378            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
8379          }
8380          field_spec opt_place
8381          {
8382            Lex->create_last_non_select_table= Lex->last_table();
8383          }
8384        | MODIFY_SYM opt_column field_ident
8385          {
8386            LEX *lex=Lex;
8387            lex->length=lex->dec=0; lex->type=0;
8388            lex->default_value= lex->on_update_value= 0;
8389            lex->comment=null_lex_str;
8390            lex->charset= NULL;
8391            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
8392            lex->zip_dict_name= null_lex_cstr;
8393            lex->gcol_info= 0;
8394          }
8395          field_def
8396          {
8397            LEX *lex=Lex;
8398            if (add_field_to_list(lex->thd,&$3,
8399                                  (enum enum_field_types) $5,
8400                                  lex->length,lex->dec,lex->type,
8401                                  lex->default_value, lex->on_update_value,
8402                                  &lex->comment,
8403                                  $3.str, &lex->interval_list, lex->charset,
8404                                  lex->uint_geom_type, &lex->zip_dict_name,
8405                                  lex->gcol_info))
8406              MYSQL_YYABORT;
8407          }
8408          opt_place
8409          {
8410            Lex->create_last_non_select_table= Lex->last_table();
8411          }
8412        | DROP opt_column field_ident opt_restrict
8413          {
8414            LEX *lex=Lex;
8415            Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str);
8416            if (ad == NULL)
8417              MYSQL_YYABORT;
8418            lex->alter_info.drop_list.push_back(ad);
8419            lex->alter_info.flags|= Alter_info::ALTER_DROP_COLUMN;
8420          }
8421        | DROP FOREIGN KEY_SYM field_ident
8422          {
8423            LEX *lex=Lex;
8424            Alter_drop *ad= new Alter_drop(Alter_drop::FOREIGN_KEY, $4.str);
8425            if (ad == NULL)
8426              MYSQL_YYABORT;
8427            lex->alter_info.drop_list.push_back(ad);
8428            lex->alter_info.flags|= Alter_info::DROP_FOREIGN_KEY;
8429          }
8430        | DROP PRIMARY_SYM KEY_SYM
8431          {
8432            LEX *lex=Lex;
8433            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name);
8434            if (ad == NULL)
8435              MYSQL_YYABORT;
8436            lex->alter_info.drop_list.push_back(ad);
8437            lex->alter_info.flags|= Alter_info::ALTER_DROP_INDEX;
8438          }
8439        | DROP key_or_index field_ident
8440          {
8441            LEX *lex=Lex;
8442            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
8443            if (ad == NULL)
8444              MYSQL_YYABORT;
8445            lex->alter_info.drop_list.push_back(ad);
8446            lex->alter_info.flags|= Alter_info::ALTER_DROP_INDEX;
8447          }
8448        | DISABLE_SYM KEYS
8449          {
8450            LEX *lex=Lex;
8451            lex->alter_info.keys_onoff= Alter_info::DISABLE;
8452            lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
8453          }
8454        | ENABLE_SYM KEYS
8455          {
8456            LEX *lex=Lex;
8457            lex->alter_info.keys_onoff= Alter_info::ENABLE;
8458            lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
8459          }
8460        | ALTER opt_column field_ident SET DEFAULT signed_literal
8461          {
8462            LEX *lex=Lex;
8463            Alter_column *ac= new Alter_column($3.str,$6);
8464            if (ac == NULL)
8465              MYSQL_YYABORT;
8466            lex->alter_info.alter_list.push_back(ac);
8467            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
8468          }
8469        | ALTER opt_column field_ident DROP DEFAULT
8470          {
8471            LEX *lex=Lex;
8472            Alter_column *ac= new Alter_column($3.str, (Item*) 0);
8473            if (ac == NULL)
8474              MYSQL_YYABORT;
8475            lex->alter_info.alter_list.push_back(ac);
8476            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
8477          }
8478        | RENAME opt_to table_ident
8479          {
8480            LEX *lex=Lex;
8481            size_t dummy;
8482            lex->select_lex->db= const_cast<char*>($3->db.str);
8483            if (lex->select_lex->db == NULL &&
8484                lex->copy_db_to(&lex->select_lex->db, &dummy))
8485            {
8486              MYSQL_YYABORT;
8487            }
8488            enum_ident_name_check ident_check_status=
8489              check_table_name($3->table.str,$3->table.length, FALSE);
8490            if (ident_check_status == IDENT_NAME_WRONG)
8491            {
8492              my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
8493              MYSQL_YYABORT;
8494            }
8495            else if (ident_check_status == IDENT_NAME_TOO_LONG)
8496            {
8497              my_error(ER_TOO_LONG_IDENT, MYF(0), $3->table.str);
8498              MYSQL_YYABORT;
8499            }
8500            LEX_STRING db_str= to_lex_string($3->db);
8501            if (db_str.str &&
8502                (check_and_convert_db_name(&db_str, FALSE) != IDENT_NAME_OK))
8503              MYSQL_YYABORT;
8504            lex->name.str= const_cast<char*>($3->table.str);
8505            lex->name.length= $3->table.length;
8506            lex->alter_info.flags|= Alter_info::ALTER_RENAME;
8507          }
8508        | RENAME key_or_index field_ident TO_SYM field_ident
8509          {
8510            LEX *lex=Lex;
8511            Alter_rename_key *ak= new (YYTHD->mem_root)
8512                                    Alter_rename_key($3.str, $5.str);
8513            if (ak == NULL)
8514              MYSQL_YYABORT;
8515            lex->alter_info.alter_rename_key_list.push_back(ak);
8516            lex->alter_info.flags|= Alter_info::ALTER_RENAME_INDEX;
8517          }
8518        | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
8519          {
8520            if (!$4)
8521            {
8522              THD *thd= YYTHD;
8523              $4= thd->variables.collation_database;
8524            }
8525            $5= $5 ? $5 : $4;
8526            if (!my_charset_same($4,$5))
8527            {
8528              my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
8529                       $5->name, $4->csname);
8530              MYSQL_YYABORT;
8531            }
8532            LEX *lex= Lex;
8533            lex->create_info.table_charset=
8534            lex->create_info.default_table_charset= $5;
8535            lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET |
8536              HA_CREATE_USED_DEFAULT_CHARSET);
8537            lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
8538          }
8539        | create_table_options_space_separated
8540          {
8541            LEX *lex=Lex;
8542            lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
8543            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
8544                !lex->create_info.db_type)
8545            {
8546              lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
8547            }
8548          }
8549        | FORCE_SYM
8550          {
8551            Lex->alter_info.flags|= Alter_info::ALTER_RECREATE;
8552          }
8553        | alter_order_clause
8554          {
8555            LEX *lex=Lex;
8556            lex->alter_info.flags|= Alter_info::ALTER_ORDER;
8557          }
8558        | UPGRADE_SYM PARTITIONING_SYM
8559          {
8560            Lex->alter_info.flags|= Alter_info::ALTER_UPGRADE_PARTITIONING;
8561          }
8562        ;
8563
8564alter_commands_modifier:
8565          alter_algorithm_option
8566        | alter_lock_option
8567        | alter_opt_validation
8568        ;
8569
8570opt_index_lock_algorithm:
8571          /* empty */
8572        | alter_lock_option
8573        | alter_algorithm_option
8574        | alter_lock_option alter_algorithm_option
8575        | alter_algorithm_option alter_lock_option
8576
8577alter_algorithm_option:
8578          ALGORITHM_SYM opt_equal DEFAULT
8579          {
8580            Lex->alter_info.requested_algorithm=
8581              Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT;
8582          }
8583        | ALGORITHM_SYM opt_equal ident
8584          {
8585            if (Lex->alter_info.set_requested_algorithm(&$3))
8586            {
8587              my_error(ER_UNKNOWN_ALTER_ALGORITHM, MYF(0), $3.str);
8588              MYSQL_YYABORT;
8589            }
8590          }
8591        ;
8592
8593alter_lock_option:
8594          LOCK_SYM opt_equal DEFAULT
8595          {
8596            Lex->alter_info.requested_lock=
8597              Alter_info::ALTER_TABLE_LOCK_DEFAULT;
8598          }
8599        | LOCK_SYM opt_equal ident
8600          {
8601            if (Lex->alter_info.set_requested_lock(&$3))
8602            {
8603              my_error(ER_UNKNOWN_ALTER_LOCK, MYF(0), $3.str);
8604              MYSQL_YYABORT;
8605            }
8606          }
8607        ;
8608
8609opt_column:
8610          /* empty */ {}
8611        | COLUMN_SYM {}
8612        ;
8613
8614opt_ignore:
8615          /* empty */ { $$= false; }
8616        | IGNORE_SYM  { $$= true; }
8617        ;
8618
8619opt_restrict:
8620          /* empty */ { Lex->drop_mode= DROP_DEFAULT; }
8621        | RESTRICT    { Lex->drop_mode= DROP_RESTRICT; }
8622        | CASCADE     { Lex->drop_mode= DROP_CASCADE; }
8623        ;
8624
8625opt_place:
8626          /* empty */ {}
8627        | AFTER_SYM ident
8628          {
8629            store_position_for_column($2.str);
8630            Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
8631          }
8632        | FIRST_SYM
8633          {
8634            store_position_for_column(first_keyword);
8635            Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
8636          }
8637        ;
8638
8639opt_to:
8640          /* empty */ {}
8641        | TO_SYM {}
8642        | EQ {}
8643        | AS {}
8644        ;
8645
8646group_replication:
8647                 START_SYM GROUP_REPLICATION
8648                 {
8649                   LEX *lex=Lex;
8650                   lex->sql_command = SQLCOM_START_GROUP_REPLICATION;
8651                 }
8652               | STOP_SYM GROUP_REPLICATION
8653                 {
8654                   LEX *lex=Lex;
8655                   lex->sql_command = SQLCOM_STOP_GROUP_REPLICATION;
8656                 }
8657               ;
8658
8659slave:
8660        slave_start start_slave_opts{}
8661      | STOP_SYM SLAVE opt_slave_thread_option_list opt_channel
8662        {
8663          LEX *lex=Lex;
8664          lex->sql_command = SQLCOM_SLAVE_STOP;
8665          lex->type = 0;
8666          lex->slave_thd_opt= $3;
8667        }
8668      ;
8669
8670slave_start:
8671          START_SYM SLAVE opt_slave_thread_option_list
8672          {
8673            LEX *lex=Lex;
8674            /* Clean previous slave connection values */
8675            lex->slave_connection.reset();
8676            lex->sql_command = SQLCOM_SLAVE_START;
8677            lex->type = 0;
8678            /* We'll use mi structure for UNTIL options */
8679            lex->mi.set_unspecified();
8680            lex->slave_thd_opt= $3;
8681          }
8682         ;
8683
8684start_slave_opts:
8685          slave_until
8686          slave_connection_opts
8687          {
8688            /*
8689              It is not possible to set user's information when
8690              one is trying to start the SQL Thread.
8691            */
8692            if ((Lex->slave_thd_opt & SLAVE_SQL) == SLAVE_SQL &&
8693                (Lex->slave_thd_opt & SLAVE_IO) != SLAVE_IO &&
8694                (Lex->slave_connection.user ||
8695                 Lex->slave_connection.password ||
8696                 Lex->slave_connection.plugin_auth ||
8697                 Lex->slave_connection.plugin_dir))
8698            {
8699              my_error(ER_SQLTHREAD_WITH_SECURE_SLAVE, MYF(0));
8700              MYSQL_YYABORT;
8701            }
8702          }
8703          opt_channel
8704          ;
8705
8706start:
8707          START_SYM TRANSACTION_SYM opt_start_transaction_option_list
8708          {
8709            LEX *lex= Lex;
8710            lex->sql_command= SQLCOM_BEGIN;
8711            /* READ ONLY and READ WRITE are mutually exclusive. */
8712            if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) &&
8713                ($3 & MYSQL_START_TRANS_OPT_READ_ONLY))
8714            {
8715              my_syntax_error(ER(ER_SYNTAX_ERROR));
8716              MYSQL_YYABORT;
8717            }
8718            lex->start_transaction_opt= $3;
8719          }
8720        ;
8721
8722opt_start_transaction_option_list:
8723          /* empty */
8724          {
8725            $$= 0;
8726          }
8727        | start_transaction_option_list
8728          {
8729            $$= $1;
8730          }
8731        ;
8732
8733start_transaction_option_list:
8734          start_transaction_option
8735          {
8736            $$= $1;
8737          }
8738        | start_transaction_option_list ',' start_transaction_option
8739          {
8740            $$= $1 | $3;
8741          }
8742        ;
8743
8744start_transaction_option:
8745          WITH CONSISTENT_SYM SNAPSHOT_SYM
8746          {
8747            $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
8748          }
8749        | WITH CONSISTENT_SYM SNAPSHOT_SYM FROM SESSION_SYM expr
8750          {
8751            ITEMIZE($6, &$6);
8752
8753            $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
8754            Lex->donor_transaction_id= $6;
8755          }
8756        | READ_SYM ONLY_SYM
8757          {
8758            $$= MYSQL_START_TRANS_OPT_READ_ONLY;
8759          }
8760        | READ_SYM WRITE_SYM
8761          {
8762            $$= MYSQL_START_TRANS_OPT_READ_WRITE;
8763          }
8764        ;
8765
8766slave_connection_opts:
8767          slave_user_name_opt slave_user_pass_opt
8768          slave_plugin_auth_opt slave_plugin_dir_opt
8769        ;
8770
8771slave_user_name_opt:
8772          {
8773            /* empty */
8774          }
8775        | USER EQ TEXT_STRING_sys
8776          {
8777            Lex->slave_connection.user= $3.str;
8778          }
8779        ;
8780
8781slave_user_pass_opt:
8782          {
8783            /* empty */
8784          }
8785        | PASSWORD EQ TEXT_STRING_sys
8786          {
8787            Lex->slave_connection.password= $3.str;
8788            Lex->contains_plaintext_password= true;
8789          }
8790
8791slave_plugin_auth_opt:
8792          {
8793            /* empty */
8794          }
8795        | DEFAULT_AUTH_SYM EQ TEXT_STRING_sys
8796          {
8797            Lex->slave_connection.plugin_auth= $3.str;
8798          }
8799        ;
8800
8801slave_plugin_dir_opt:
8802          {
8803            /* empty */
8804          }
8805        | PLUGIN_DIR_SYM EQ TEXT_STRING_sys
8806          {
8807            Lex->slave_connection.plugin_dir= $3.str;
8808          }
8809        ;
8810
8811opt_slave_thread_option_list:
8812          /* empty */
8813          {
8814            $$= 0;
8815          }
8816        | slave_thread_option_list
8817          {
8818            $$= $1;
8819          }
8820        ;
8821
8822slave_thread_option_list:
8823          slave_thread_option
8824          {
8825            $$= $1;
8826          }
8827        | slave_thread_option_list ',' slave_thread_option
8828          {
8829            $$= $1 | $3;
8830          }
8831        ;
8832
8833slave_thread_option:
8834          SQL_THREAD
8835          {
8836            $$= SLAVE_SQL;
8837          }
8838        | RELAY_THREAD
8839          {
8840            $$= SLAVE_IO;
8841          }
8842        ;
8843
8844slave_until:
8845          /*empty*/
8846          {
8847            LEX *lex= Lex;
8848            lex->mi.slave_until= false;
8849          }
8850        | UNTIL_SYM slave_until_opts
8851          {
8852            LEX *lex=Lex;
8853            if (((lex->mi.log_file_name || lex->mi.pos) &&
8854                lex->mi.gtid) ||
8855               ((lex->mi.relay_log_name || lex->mi.relay_log_pos) &&
8856                lex->mi.gtid) ||
8857                !((lex->mi.log_file_name && lex->mi.pos) ||
8858                  (lex->mi.relay_log_name && lex->mi.relay_log_pos) ||
8859                  lex->mi.gtid ||
8860                  lex->mi.until_after_gaps) ||
8861                /* SQL_AFTER_MTS_GAPS is meaningless in combination */
8862                /* with any other coordinates related options       */
8863                ((lex->mi.log_file_name || lex->mi.pos || lex->mi.relay_log_name
8864                  || lex->mi.relay_log_pos || lex->mi.gtid)
8865                 && lex->mi.until_after_gaps))
8866            {
8867               my_message(ER_BAD_SLAVE_UNTIL_COND,
8868                          ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0));
8869               MYSQL_YYABORT;
8870            }
8871            lex->mi.slave_until= true;
8872          }
8873        ;
8874
8875slave_until_opts:
8876          master_file_def
8877        | slave_until_opts ',' master_file_def
8878        | SQL_BEFORE_GTIDS EQ TEXT_STRING_sys
8879          {
8880            Lex->mi.gtid= $3.str;
8881            Lex->mi.gtid_until_condition= LEX_MASTER_INFO::UNTIL_SQL_BEFORE_GTIDS;
8882          }
8883        | SQL_AFTER_GTIDS EQ TEXT_STRING_sys
8884          {
8885            Lex->mi.gtid= $3.str;
8886            Lex->mi.gtid_until_condition= LEX_MASTER_INFO::UNTIL_SQL_AFTER_GTIDS;
8887          }
8888        | SQL_AFTER_MTS_GAPS
8889          {
8890            Lex->mi.until_after_gaps= true;
8891          }
8892        ;
8893
8894checksum:
8895          CHECKSUM_SYM table_or_tables
8896          {
8897            LEX *lex=Lex;
8898            lex->sql_command = SQLCOM_CHECKSUM;
8899            /* Will be overriden during execution. */
8900            YYPS->m_lock_type= TL_UNLOCK;
8901          }
8902          table_list opt_checksum_type
8903          {}
8904        ;
8905
8906opt_checksum_type:
8907          /* nothing */ { Lex->check_opt.flags= 0; }
8908        | QUICK         { Lex->check_opt.flags= T_QUICK; }
8909        | EXTENDED_SYM  { Lex->check_opt.flags= T_EXTEND; }
8910        ;
8911
8912repair:
8913          REPAIR opt_no_write_to_binlog table_or_tables
8914          {
8915            LEX *lex=Lex;
8916            lex->sql_command = SQLCOM_REPAIR;
8917            lex->no_write_to_binlog= $2;
8918            lex->check_opt.init();
8919            lex->alter_info.reset();
8920            /* Will be overriden during execution. */
8921            YYPS->m_lock_type= TL_UNLOCK;
8922          }
8923          table_list opt_mi_repair_type
8924          {
8925            THD *thd= YYTHD;
8926            LEX* lex= thd->lex;
8927            assert(!lex->m_sql_cmd);
8928            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
8929            if (lex->m_sql_cmd == NULL)
8930              MYSQL_YYABORT;
8931          }
8932        ;
8933
8934opt_mi_repair_type:
8935          /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
8936        | mi_repair_types {}
8937        ;
8938
8939mi_repair_types:
8940          mi_repair_type {}
8941        | mi_repair_type mi_repair_types {}
8942        ;
8943
8944mi_repair_type:
8945          QUICK        { Lex->check_opt.flags|= T_QUICK; }
8946        | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
8947        | USE_FRM      { Lex->check_opt.sql_flags|= TT_USEFRM; }
8948        ;
8949
8950analyze:
8951          ANALYZE_SYM opt_no_write_to_binlog table_or_tables
8952          {
8953            LEX *lex=Lex;
8954            lex->sql_command = SQLCOM_ANALYZE;
8955            lex->no_write_to_binlog= $2;
8956            lex->check_opt.init();
8957            lex->alter_info.reset();
8958            /* Will be overriden during execution. */
8959            YYPS->m_lock_type= TL_UNLOCK;
8960          }
8961          table_list
8962          {
8963            THD *thd= YYTHD;
8964            LEX* lex= thd->lex;
8965            assert(!lex->m_sql_cmd);
8966            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
8967            if (lex->m_sql_cmd == NULL)
8968              MYSQL_YYABORT;
8969          }
8970        ;
8971
8972binlog_base64_event:
8973          BINLOG_SYM TEXT_STRING_sys
8974          {
8975            Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
8976            Lex->comment= $2;
8977          }
8978        ;
8979
8980check:
8981          CHECK_SYM table_or_tables
8982          {
8983            LEX *lex=Lex;
8984
8985            if (lex->sphead)
8986            {
8987              my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK");
8988              MYSQL_YYABORT;
8989            }
8990            lex->sql_command = SQLCOM_CHECK;
8991            lex->check_opt.init();
8992            lex->alter_info.reset();
8993            /* Will be overriden during execution. */
8994            YYPS->m_lock_type= TL_UNLOCK;
8995          }
8996          table_list opt_mi_check_type
8997          {
8998            THD *thd= YYTHD;
8999            LEX* lex= thd->lex;
9000            assert(!lex->m_sql_cmd);
9001            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
9002            if (lex->m_sql_cmd == NULL)
9003              MYSQL_YYABORT;
9004          }
9005        ;
9006
9007opt_mi_check_type:
9008          /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
9009        | mi_check_types {}
9010        ;
9011
9012mi_check_types:
9013          mi_check_type {}
9014        | mi_check_type mi_check_types {}
9015        ;
9016
9017mi_check_type:
9018          QUICK               { Lex->check_opt.flags|= T_QUICK; }
9019        | FAST_SYM            { Lex->check_opt.flags|= T_FAST; }
9020        | MEDIUM_SYM          { Lex->check_opt.flags|= T_MEDIUM; }
9021        | EXTENDED_SYM        { Lex->check_opt.flags|= T_EXTEND; }
9022        | CHANGED             { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
9023        | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
9024        ;
9025
9026optimize:
9027          OPTIMIZE opt_no_write_to_binlog table_or_tables
9028          {
9029            LEX *lex=Lex;
9030            lex->sql_command = SQLCOM_OPTIMIZE;
9031            lex->no_write_to_binlog= $2;
9032            lex->check_opt.init();
9033            lex->alter_info.reset();
9034            /* Will be overriden during execution. */
9035            YYPS->m_lock_type= TL_UNLOCK;
9036          }
9037          table_list
9038          {
9039            THD *thd= YYTHD;
9040            LEX* lex= thd->lex;
9041            assert(!lex->m_sql_cmd);
9042            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
9043            if (lex->m_sql_cmd == NULL)
9044              MYSQL_YYABORT;
9045          }
9046        ;
9047
9048opt_no_write_to_binlog:
9049          /* empty */ { $$= 0; }
9050        | NO_WRITE_TO_BINLOG { $$= 1; }
9051        | LOCAL_SYM { $$= 1; }
9052        ;
9053
9054rename:
9055          RENAME table_or_tables
9056          {
9057            Lex->sql_command= SQLCOM_RENAME_TABLE;
9058          }
9059          table_to_table_list
9060          {}
9061        | RENAME USER clear_privileges rename_list
9062          {
9063            Lex->sql_command = SQLCOM_RENAME_USER;
9064          }
9065        ;
9066
9067rename_list:
9068          user TO_SYM user
9069          {
9070            if (Lex->users_list.push_back($1) || Lex->users_list.push_back($3))
9071              MYSQL_YYABORT;
9072          }
9073        | rename_list ',' user TO_SYM user
9074          {
9075            if (Lex->users_list.push_back($3) || Lex->users_list.push_back($5))
9076              MYSQL_YYABORT;
9077          }
9078        ;
9079
9080table_to_table_list:
9081          table_to_table
9082        | table_to_table_list ',' table_to_table
9083        ;
9084
9085table_to_table:
9086          table_ident TO_SYM table_ident
9087          {
9088            LEX *lex=Lex;
9089            SELECT_LEX *sl= Select;
9090            if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
9091                                       TL_IGNORE, MDL_EXCLUSIVE) ||
9092                !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
9093                                       TL_IGNORE, MDL_EXCLUSIVE))
9094              MYSQL_YYABORT;
9095          }
9096        ;
9097
9098keycache:
9099          CACHE_SYM INDEX_SYM
9100          {
9101            Lex->alter_info.reset();
9102          }
9103          keycache_list_or_parts IN_SYM key_cache_name
9104          {
9105            LEX *lex=Lex;
9106            lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
9107            lex->ident= $6;
9108          }
9109        ;
9110
9111keycache_list_or_parts:
9112          keycache_list
9113        | assign_to_keycache_parts
9114        ;
9115
9116keycache_list:
9117          assign_to_keycache
9118        | keycache_list ',' assign_to_keycache
9119        ;
9120
9121assign_to_keycache:
9122          table_ident cache_keys_spec
9123          {
9124            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
9125                                           MDL_SHARED_READ,
9126                                           $2))
9127              MYSQL_YYABORT;
9128          }
9129        ;
9130
9131assign_to_keycache_parts:
9132          table_ident adm_partition cache_keys_spec
9133          {
9134            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
9135                                           MDL_SHARED_READ,
9136                                           $3))
9137              MYSQL_YYABORT;
9138          }
9139        ;
9140
9141key_cache_name:
9142          ident    { $$= $1; }
9143        | DEFAULT  { $$ = default_key_cache_base; }
9144        ;
9145
9146preload:
9147          LOAD INDEX_SYM INTO CACHE_SYM
9148          {
9149            LEX *lex=Lex;
9150            lex->sql_command=SQLCOM_PRELOAD_KEYS;
9151            lex->alter_info.reset();
9152          }
9153          preload_list_or_parts
9154          {}
9155        ;
9156
9157preload_list_or_parts:
9158          preload_keys_parts
9159        | preload_list
9160        ;
9161
9162preload_list:
9163          preload_keys
9164        | preload_list ',' preload_keys
9165        ;
9166
9167preload_keys:
9168          table_ident cache_keys_spec opt_ignore_leaves
9169          {
9170            if (!Select->add_table_to_list(YYTHD, $1, NULL, $3, TL_READ,
9171                                           MDL_SHARED_READ,
9172                                           $2))
9173              MYSQL_YYABORT;
9174          }
9175        ;
9176
9177preload_keys_parts:
9178          table_ident adm_partition cache_keys_spec opt_ignore_leaves
9179          {
9180            if (!Select->add_table_to_list(YYTHD, $1, NULL, $4, TL_READ,
9181                                           MDL_SHARED_READ,
9182                                           $3))
9183              MYSQL_YYABORT;
9184          }
9185        ;
9186
9187adm_partition:
9188          PARTITION_SYM
9189          {
9190            Lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
9191          }
9192          '(' all_or_alt_part_name_list ')'
9193        ;
9194
9195cache_keys_spec:
9196          cache_key_list_or_empty
9197        ;
9198
9199cache_key_list_or_empty:
9200          /* empty */ { $$= NULL; }
9201        | key_or_index '(' opt_key_usage_list ')'
9202          {
9203            init_index_hints($3, INDEX_HINT_USE,
9204                             old_mode ? INDEX_HINT_MASK_JOIN
9205                                      : INDEX_HINT_MASK_ALL);
9206            $$= $3;
9207          }
9208        ;
9209
9210opt_ignore_leaves:
9211          /* empty */
9212          { $$= 0; }
9213        | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
9214        ;
9215
9216/*
9217  Select : retrieve data from table
9218*/
9219
9220
9221select:
9222          select_init
9223          {
9224            $$= NEW_PTN PT_select($1, SQLCOM_SELECT);
9225          }
9226        ;
9227
9228/* Need first branch for subselects. */
9229select_init:
9230          SELECT_SYM select_part2 opt_union_clause
9231          {
9232            $$= NEW_PTN PT_select_init2($1, $2, $3);
9233          }
9234        | '(' select_paren ')' union_opt
9235          {
9236            $$= NEW_PTN PT_select_init_parenthesis($2, $4);
9237          }
9238        ;
9239
9240select_paren:
9241          SELECT_SYM select_part2
9242          {
9243            $$= NEW_PTN PT_select_paren($1, $2);
9244          }
9245        | '(' select_paren ')' { $$= $2; }
9246        ;
9247
9248/* The equivalent of select_paren for nested queries. */
9249select_paren_derived:
9250          SELECT_SYM select_part2_derived table_expression
9251          {
9252            $$= NEW_PTN PT_select_paren_derived($1, $2, $3);
9253          }
9254        | '(' select_paren_derived ')' { $$= $2; }
9255        ;
9256
9257/*
9258  Theoretically we can merge all 3 right hand sides of the select_part2
9259  rule into one, however such a transformation adds one shift/reduce
9260  conflict more.
9261*/
9262select_part2:
9263          select_options_and_item_list
9264          opt_order_clause
9265          opt_limit_clause
9266          opt_select_lock_type
9267          {
9268            $$= NEW_PTN PT_select_part2($1, NULL, NULL, NULL, NULL, NULL,
9269                                        $2, $3, NULL, NULL, $4);
9270          }
9271        | select_options_and_item_list into opt_select_lock_type
9272          {
9273            $$= NEW_PTN PT_select_part2($1, $2, NULL, NULL, NULL, NULL, NULL,
9274                                        NULL, NULL, NULL, $3);
9275          }
9276        | select_options_and_item_list  /* #1 */
9277          opt_into                      /* #2 */
9278          from_clause                   /* #3 */
9279          opt_where_clause              /* #4 */
9280          opt_group_clause              /* #5 */
9281          opt_having_clause             /* #6 */
9282          opt_order_clause              /* #7 */
9283          opt_limit_clause              /* #8 */
9284          opt_procedure_analyse_clause  /* #9 */
9285          opt_into                      /* #10 */
9286          opt_select_lock_type          /* #11 */
9287          {
9288            if ($2 && $10)
9289            {
9290              /* double "INTO" clause */
9291              YYTHD->parse_error_at(@10, ER(ER_SYNTAX_ERROR));
9292              MYSQL_YYABORT;
9293            }
9294            if ($9 && ($2 || $10))
9295            {
9296              /* "INTO" with "PROCEDURE ANALYSE" */
9297              my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "INTO");
9298              MYSQL_YYABORT;
9299            }
9300            $$= NEW_PTN PT_select_part2($1, $2, $3, $4, $5, $6, $7, $8, $9, $10,
9301                                        $11);
9302          }
9303        ;
9304
9305select_options_and_item_list:
9306          {
9307            /*
9308              TODO: remove this semantic action (currently this removal
9309              adds shift/reduce conflict)
9310            */
9311          }
9312          select_options select_item_list
9313          {
9314            $$= NEW_PTN PT_select_options_and_item_list($2, $3);
9315          }
9316        ;
9317
9318
9319table_expression:
9320          opt_from_clause               /* #1 */
9321          opt_where_clause              /* #2 */
9322          opt_group_clause              /* #3 */
9323          opt_having_clause             /* #4 */
9324          opt_order_clause              /* #5 */
9325          opt_limit_clause              /* #6 */
9326          opt_procedure_analyse_clause  /* #7 */
9327          opt_select_lock_type          /* #8 */
9328          {
9329            $$= NEW_PTN PT_table_expression($1, $2, $3, $4, $5, $6, $7, $8);
9330          }
9331        ;
9332
9333from_clause:
9334          FROM table_reference_list { $$= $2; }
9335        ;
9336
9337opt_from_clause:
9338          /* empty */ { $$= NULL; }
9339        | from_clause
9340        ;
9341
9342table_reference_list:
9343          join_table_list
9344          {
9345            $$= NEW_PTN PT_table_reference_list($1);
9346          }
9347        | DUAL_SYM { $$= NULL; }
9348          /* oracle compatibility: oracle always requires FROM clause,
9349             and DUAL is system table without fields.
9350             Is "SELECT 1 FROM DUAL" any better than "SELECT 1" ?
9351          Hmmm :) */
9352        ;
9353
9354select_options:
9355          /* empty*/
9356          {
9357            $$.query_spec_options= 0;
9358            $$.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
9359          }
9360        | select_option_list
9361        ;
9362
9363select_option_list:
9364          select_option_list select_option
9365          {
9366            if ($$.merge($1, $2))
9367              MYSQL_YYABORT;
9368          }
9369        | select_option
9370        ;
9371
9372select_option:
9373          query_spec_option
9374          {
9375            $$.query_spec_options= $1;
9376            $$.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
9377          }
9378        | SQL_NO_CACHE_SYM
9379          {
9380            push_deprecated_warn_no_replacement(YYTHD, "SQL_NO_CACHE");
9381            /*
9382              Allow this flag only on the first top-level SELECT statement, if
9383              SQL_CACHE wasn't specified, and only once per query.
9384             */
9385            $$.query_spec_options= 0;
9386            $$.sql_cache= SELECT_LEX::SQL_NO_CACHE;
9387          }
9388        | SQL_CACHE_SYM
9389          {
9390            push_deprecated_warn_no_replacement(YYTHD, "SQL_CACHE");
9391            /*
9392              Allow this flag only on the first top-level SELECT statement, if
9393              SQL_NO_CACHE wasn't specified, and only once per query.
9394             */
9395            $$.query_spec_options= 0;
9396            $$.sql_cache= SELECT_LEX::SQL_CACHE;
9397          }
9398        ;
9399
9400opt_select_lock_type:
9401          /* empty */ { $$.is_set= false; }
9402        | FOR_SYM UPDATE_SYM
9403          {
9404            $$.is_set= true;
9405            $$.lock_type= TL_WRITE;
9406            $$.is_safe_to_cache_query= false;
9407          }
9408        | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
9409          {
9410            $$.is_set= true;
9411            $$.lock_type= TL_READ_WITH_SHARED_LOCKS;
9412            $$.is_safe_to_cache_query= false;
9413          }
9414        ;
9415
9416select_item_list:
9417          select_item_list ',' select_item
9418          {
9419            if ($1 == NULL || $1->push_back($3))
9420              MYSQL_YYABORT;
9421            $$= $1;
9422          }
9423        | select_item
9424          {
9425            $$= NEW_PTN PT_select_item_list;
9426            if ($$ == NULL || $$->push_back($1))
9427              MYSQL_YYABORT;
9428          }
9429        | '*'
9430          {
9431            Item *item = NEW_PTN Item_asterisk(@$, NULL, NULL);
9432            $$= NEW_PTN PT_select_item_list;
9433            if ($$ == NULL || item == NULL || $$->push_back(item))
9434              MYSQL_YYABORT;
9435          }
9436        ;
9437
9438select_item:
9439          table_wild { $$= $1; }
9440        | expr select_alias
9441          {
9442            $$= NEW_PTN PTI_expr_with_alias(@$, $1, @1.cpp, $2);
9443          }
9444        ;
9445
9446
9447select_alias:
9448          /* empty */ { $$=null_lex_str;}
9449        | AS ident { $$=$2; }
9450        | AS TEXT_STRING_sys { $$=$2; }
9451        | ident { $$=$1; }
9452        | TEXT_STRING_sys { $$=$1; }
9453        ;
9454
9455optional_braces:
9456          /* empty */ {}
9457        | '(' ')' {}
9458        ;
9459
9460/* all possible expressions */
9461expr:
9462          expr or expr %prec OR_SYM
9463          {
9464            $$= flatten_associative_operator<Item_cond_or,
9465                                             Item_func::COND_OR_FUNC>(
9466                                                 YYTHD->mem_root, @$, $1, $3);
9467          }
9468        | expr XOR expr %prec XOR
9469          {
9470            /* XOR is a proprietary extension */
9471            $$ = NEW_PTN Item_func_xor(@$, $1, $3);
9472          }
9473        | expr and expr %prec AND_SYM
9474          {
9475            $$= flatten_associative_operator<Item_cond_and,
9476                                             Item_func::COND_AND_FUNC>(
9477                                                 YYTHD->mem_root, @$, $1, $3);
9478          }
9479        | NOT_SYM expr %prec NOT_SYM
9480          {
9481            $$= NEW_PTN PTI_negate_expression(@$, $2);
9482          }
9483        | bool_pri IS TRUE_SYM %prec IS
9484          {
9485            $$= NEW_PTN Item_func_istrue(@$, $1);
9486          }
9487        | bool_pri IS not TRUE_SYM %prec IS
9488          {
9489            $$= NEW_PTN Item_func_isnottrue(@$, $1);
9490          }
9491        | bool_pri IS FALSE_SYM %prec IS
9492          {
9493            $$= NEW_PTN Item_func_isfalse(@$, $1);
9494          }
9495        | bool_pri IS not FALSE_SYM %prec IS
9496          {
9497            $$= NEW_PTN Item_func_isnotfalse(@$, $1);
9498          }
9499        | bool_pri IS UNKNOWN_SYM %prec IS
9500          {
9501            $$= NEW_PTN Item_func_isnull(@$, $1);
9502          }
9503        | bool_pri IS not UNKNOWN_SYM %prec IS
9504          {
9505            $$= NEW_PTN Item_func_isnotnull(@$, $1);
9506          }
9507        | bool_pri
9508        ;
9509
9510bool_pri:
9511          bool_pri IS NULL_SYM %prec IS
9512          {
9513            $$= NEW_PTN Item_func_isnull(@$, $1);
9514          }
9515        | bool_pri IS not NULL_SYM %prec IS
9516          {
9517            $$= NEW_PTN Item_func_isnotnull(@$, $1);
9518          }
9519        | bool_pri comp_op predicate %prec EQ
9520          {
9521            $$= NEW_PTN PTI_comp_op(@$, $1, $2, $3);
9522          }
9523        | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
9524          {
9525            if ($2 == &comp_equal_creator)
9526              /*
9527                We throw this manual parse error rather than split the rule
9528                comp_op into a null-safe and a non null-safe rule, since doing
9529                so would add a shift/reduce conflict. It's actually this rule
9530                and the ones referencing it that cause all the conflicts, but
9531                we still don't want the count to go up.
9532              */
9533              YYTHD->parse_error_at(@2, ER_THD(YYTHD, ER_SYNTAX_ERROR));
9534            $$= NEW_PTN PTI_comp_op_all(@$, $1, $2, $3, $5);
9535          }
9536        | predicate
9537        ;
9538
9539predicate:
9540          bit_expr IN_SYM '(' subselect ')'
9541          {
9542            $$= NEW_PTN Item_in_subselect(@$, $1, $4);
9543          }
9544        | bit_expr not IN_SYM '(' subselect ')'
9545          {
9546            Item *item= NEW_PTN Item_in_subselect(@$, $1, $5);
9547            $$= NEW_PTN PTI_negate_expression(@$, item);
9548          }
9549        | bit_expr IN_SYM '(' expr ')'
9550          {
9551            $$= NEW_PTN PTI_handle_sql2003_note184_exception(@$, $1, true, $4);
9552          }
9553        | bit_expr IN_SYM '(' expr ',' expr_list ')'
9554          {
9555            if ($6 == NULL || $6->push_front($4) || $6->push_front($1))
9556              MYSQL_YYABORT;
9557
9558            $$= NEW_PTN Item_func_in(@$, $6, false);
9559          }
9560        | bit_expr not IN_SYM '(' expr ')'
9561          {
9562            $$= NEW_PTN PTI_handle_sql2003_note184_exception(@$, $1, false, $5);
9563          }
9564        | bit_expr not IN_SYM '(' expr ',' expr_list ')'
9565          {
9566            if ($7 == NULL || $7->push_front($5) || $7->value.push_front($1))
9567              MYSQL_YYABORT;
9568
9569            $$= NEW_PTN Item_func_in(@$, $7, true);
9570          }
9571        | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
9572          {
9573            $$= NEW_PTN Item_func_between(@$, $1, $3, $5, false);
9574          }
9575        | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
9576          {
9577            $$= NEW_PTN Item_func_between(@$, $1, $4, $6, true);
9578          }
9579        | bit_expr SOUNDS_SYM LIKE bit_expr
9580          {
9581            Item *item1= NEW_PTN Item_func_soundex(@$, $1);
9582            Item *item4= NEW_PTN Item_func_soundex(@$, $4);
9583            if ((item1 == NULL) || (item4 == NULL))
9584              MYSQL_YYABORT;
9585            $$= NEW_PTN Item_func_eq(@$, item1, item4);
9586          }
9587        | bit_expr LIKE simple_expr opt_escape
9588          {
9589            $$= NEW_PTN Item_func_like(@$, $1, $3, $4);
9590          }
9591        | bit_expr not LIKE simple_expr opt_escape
9592          {
9593            Item *item= NEW_PTN Item_func_like(@$, $1, $4, $5);
9594            if (item == NULL)
9595              MYSQL_YYABORT;
9596            $$= NEW_PTN Item_func_not(@$, item);
9597          }
9598        | bit_expr REGEXP bit_expr
9599          {
9600            $$= NEW_PTN Item_func_regex(@$, $1, $3);
9601          }
9602        | bit_expr not REGEXP bit_expr
9603          {
9604            Item *item= NEW_PTN Item_func_regex(@$, $1, $4);
9605            $$= NEW_PTN PTI_negate_expression(@$, item);
9606          }
9607        | bit_expr
9608        ;
9609
9610bit_expr:
9611          bit_expr '|' bit_expr %prec '|'
9612          {
9613            $$= NEW_PTN Item_func_bit_or(@$, $1, $3);
9614          }
9615        | bit_expr '&' bit_expr %prec '&'
9616          {
9617            $$= NEW_PTN Item_func_bit_and(@$, $1, $3);
9618          }
9619        | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
9620          {
9621            $$= NEW_PTN Item_func_shift_left(@$, $1, $3);
9622          }
9623        | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
9624          {
9625            $$= NEW_PTN Item_func_shift_right(@$, $1, $3);
9626          }
9627        | bit_expr '+' bit_expr %prec '+'
9628          {
9629            $$= NEW_PTN Item_func_plus(@$, $1, $3);
9630          }
9631        | bit_expr '-' bit_expr %prec '-'
9632          {
9633            $$= NEW_PTN Item_func_minus(@$, $1, $3);
9634          }
9635        | bit_expr '+' INTERVAL_SYM expr interval %prec '+'
9636          {
9637            $$= NEW_PTN Item_date_add_interval(@$, $1, $4, $5, 0);
9638          }
9639        | bit_expr '-' INTERVAL_SYM expr interval %prec '-'
9640          {
9641            $$= NEW_PTN Item_date_add_interval(@$, $1, $4, $5, 1);
9642          }
9643        | bit_expr '*' bit_expr %prec '*'
9644          {
9645            $$= NEW_PTN Item_func_mul(@$, $1, $3);
9646          }
9647        | bit_expr '/' bit_expr %prec '/'
9648          {
9649            $$= NEW_PTN Item_func_div(@$, $1,$3);
9650          }
9651        | bit_expr '%' bit_expr %prec '%'
9652          {
9653            $$= NEW_PTN Item_func_mod(@$, $1,$3);
9654          }
9655        | bit_expr DIV_SYM bit_expr %prec DIV_SYM
9656          {
9657            $$= NEW_PTN Item_func_int_div(@$, $1,$3);
9658          }
9659        | bit_expr MOD_SYM bit_expr %prec MOD_SYM
9660          {
9661            $$= NEW_PTN Item_func_mod(@$, $1, $3);
9662          }
9663        | bit_expr '^' bit_expr
9664          {
9665            $$= NEW_PTN Item_func_bit_xor(@$, $1, $3);
9666          }
9667        | simple_expr
9668        ;
9669
9670or:
9671          OR_SYM
9672       | OR2_SYM
9673       ;
9674
9675and:
9676          AND_SYM
9677       | AND_AND_SYM
9678       ;
9679
9680not:
9681          NOT_SYM
9682        | NOT2_SYM
9683        ;
9684
9685not2:
9686          '!'
9687        | NOT2_SYM
9688        ;
9689
9690comp_op:
9691          EQ     { $$ = &comp_eq_creator; }
9692        | EQUAL_SYM { $$ = &comp_equal_creator; }
9693        | GE     { $$ = &comp_ge_creator; }
9694        | GT_SYM { $$ = &comp_gt_creator; }
9695        | LE     { $$ = &comp_le_creator; }
9696        | LT     { $$ = &comp_lt_creator; }
9697        | NE     { $$ = &comp_ne_creator; }
9698        ;
9699
9700all_or_any:
9701          ALL     { $$ = 1; }
9702        | ANY_SYM { $$ = 0; }
9703        ;
9704
9705simple_expr:
9706          simple_ident
9707        | function_call_keyword
9708        | function_call_nonkeyword
9709        | function_call_generic
9710        | function_call_conflict
9711        | simple_expr COLLATE_SYM ident_or_text %prec NEG
9712          {
9713            $$= NEW_PTN Item_func_set_collation(@$, $1, $3);
9714          }
9715        | literal
9716        | param_marker { $$= $1; }
9717        | variable
9718        | sum_expr
9719        | simple_expr OR_OR_SYM simple_expr
9720          {
9721            $$= NEW_PTN Item_func_concat(@$, $1, $3);
9722          }
9723        | '+' simple_expr %prec NEG
9724          {
9725            $$= $2; // TODO: do we really want to ignore unary '+' before any kind of literals?
9726          }
9727        | '-' simple_expr %prec NEG
9728          {
9729            $$= NEW_PTN Item_func_neg(@$, $2);
9730          }
9731        | '~' simple_expr %prec NEG
9732          {
9733            $$= NEW_PTN Item_func_bit_neg(@$, $2);
9734          }
9735        | not2 simple_expr %prec NEG
9736          {
9737            $$= NEW_PTN PTI_negate_expression(@$, $2);
9738          }
9739        | '(' subselect ')'
9740          {
9741            $$= NEW_PTN PTI_singlerow_subselect(@$, $2);
9742          }
9743        | '(' expr ')'
9744          { $$= $2; }
9745        | '(' expr ',' expr_list ')'
9746          {
9747            $$= NEW_PTN Item_row(@$, $2, $4->value);
9748          }
9749        | ROW_SYM '(' expr ',' expr_list ')'
9750          {
9751            $$= NEW_PTN Item_row(@$, $3, $5->value);
9752          }
9753        | EXISTS '(' subselect ')'
9754          {
9755            $$= NEW_PTN PTI_exists_subselect(@$, $3);
9756          }
9757        | '{' ident expr '}'
9758          {
9759            $$= NEW_PTN PTI_odbc_date(@$, $2, $3);
9760          }
9761        | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
9762          {
9763            $$= NEW_PTN Item_func_match(@$, $2, $5, $6);
9764          }
9765        | BINARY simple_expr %prec NEG
9766          {
9767            $$= create_func_cast(YYTHD, @2, $2, ITEM_CAST_CHAR, &my_charset_bin);
9768          }
9769        | CAST_SYM '(' expr AS cast_type ')'
9770          {
9771            $$= create_func_cast(YYTHD, @3, $3, &$5);
9772          }
9773        | CASE_SYM opt_expr when_list opt_else END
9774          {
9775            $$= NEW_PTN Item_func_case(@$, *$3, $2, $4 );
9776          }
9777        | CONVERT_SYM '(' expr ',' cast_type ')'
9778          {
9779            $$= create_func_cast(YYTHD, @3, $3, &$5);
9780          }
9781        | CONVERT_SYM '(' expr USING charset_name ')'
9782          {
9783            $$= NEW_PTN Item_func_conv_charset(@$, $3,$5);
9784          }
9785        | DEFAULT '(' simple_ident ')'
9786          {
9787            $$= NEW_PTN Item_default_value(@$, $3);
9788          }
9789        | VALUES '(' simple_ident_nospvar ')'
9790          {
9791            $$= NEW_PTN Item_insert_value(@$, $3);
9792          }
9793        | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM
9794          /* we cannot put interval before - */
9795          {
9796            $$= NEW_PTN Item_date_add_interval(@$, $5, $2, $3, 0);
9797          }
9798        | simple_ident JSON_SEPARATOR_SYM TEXT_STRING_literal
9799          {
9800            Item_string *path=
9801              NEW_PTN Item_string(@$, $3.str, $3.length,
9802                                  YYTHD->variables.collation_connection);
9803            $$= NEW_PTN Item_func_json_extract(YYTHD, @$, $1, path);
9804          }
9805         | simple_ident JSON_UNQUOTED_SEPARATOR_SYM TEXT_STRING_literal
9806          {
9807            Item_string *path=
9808              NEW_PTN Item_string(@$, $3.str, $3.length,
9809                                  YYTHD->variables.collation_connection);
9810            Item *extr= NEW_PTN Item_func_json_extract(YYTHD, @$, $1, path);
9811            $$= NEW_PTN Item_func_json_unquote(@$, extr);
9812          }
9813        ;
9814
9815/*
9816  Function call syntax using official SQL 2003 keywords.
9817  Because the function name is an official token,
9818  a dedicated grammar rule is needed in the parser.
9819  There is no potential for conflicts
9820*/
9821function_call_keyword:
9822          CHAR_SYM '(' expr_list ')'
9823          {
9824            $$= NEW_PTN Item_func_char(@$, $3);
9825          }
9826        | CHAR_SYM '(' expr_list USING charset_name ')'
9827          {
9828            $$= NEW_PTN Item_func_char(@$, $3, $5);
9829          }
9830        | CURRENT_USER optional_braces
9831          {
9832            $$= NEW_PTN Item_func_current_user(@$);
9833          }
9834        | DATE_SYM '(' expr ')'
9835          {
9836            $$= NEW_PTN Item_date_typecast(@$, $3);
9837          }
9838        | DAY_SYM '(' expr ')'
9839          {
9840            $$= NEW_PTN Item_func_dayofmonth(@$, $3);
9841          }
9842        | HOUR_SYM '(' expr ')'
9843          {
9844            $$= NEW_PTN Item_func_hour(@$, $3);
9845          }
9846        | INSERT '(' expr ',' expr ',' expr ',' expr ')'
9847          {
9848            $$= NEW_PTN Item_func_insert(@$, $3, $5, $7, $9);
9849          }
9850        | INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM
9851          {
9852            $$= NEW_PTN Item_func_interval(@$, YYTHD->mem_root, $3, $5);
9853          }
9854        | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM
9855          {
9856            $$= NEW_PTN Item_func_interval(@$, YYTHD->mem_root, $3, $5, $7);
9857          }
9858        | LEFT '(' expr ',' expr ')'
9859          {
9860            $$= NEW_PTN Item_func_left(@$, $3, $5);
9861          }
9862        | MINUTE_SYM '(' expr ')'
9863          {
9864            $$= NEW_PTN Item_func_minute(@$, $3);
9865          }
9866        | MONTH_SYM '(' expr ')'
9867          {
9868            $$= NEW_PTN Item_func_month(@$, $3);
9869          }
9870        | RIGHT '(' expr ',' expr ')'
9871          {
9872            $$= NEW_PTN Item_func_right(@$, $3, $5);
9873          }
9874        | SECOND_SYM '(' expr ')'
9875          {
9876            $$= NEW_PTN Item_func_second(@$, $3);
9877          }
9878        | TIME_SYM '(' expr ')'
9879          {
9880            $$= NEW_PTN Item_time_typecast(@$, $3);
9881          }
9882        | TIMESTAMP '(' expr ')'
9883          {
9884            $$= NEW_PTN Item_datetime_typecast(@$, $3);
9885          }
9886        | TIMESTAMP '(' expr ',' expr ')'
9887          {
9888            $$= NEW_PTN Item_func_add_time(@$, $3, $5, 1, 0);
9889          }
9890        | TRIM '(' expr ')'
9891          {
9892            $$= NEW_PTN Item_func_trim(@$, $3,
9893                                       Item_func_trim::TRIM_BOTH_DEFAULT);
9894          }
9895        | TRIM '(' LEADING expr FROM expr ')'
9896          {
9897            $$= NEW_PTN Item_func_trim(@$, $6, $4,
9898                                       Item_func_trim::TRIM_LEADING);
9899          }
9900        | TRIM '(' TRAILING expr FROM expr ')'
9901          {
9902            $$= NEW_PTN Item_func_trim(@$, $6, $4,
9903                                       Item_func_trim::TRIM_TRAILING);
9904          }
9905        | TRIM '(' BOTH expr FROM expr ')'
9906          {
9907            $$= NEW_PTN Item_func_trim(@$, $6, $4, Item_func_trim::TRIM_BOTH);
9908          }
9909        | TRIM '(' LEADING FROM expr ')'
9910          {
9911            $$= NEW_PTN Item_func_trim(@$, $5, Item_func_trim::TRIM_LEADING);
9912          }
9913        | TRIM '(' TRAILING FROM expr ')'
9914          {
9915            $$= NEW_PTN Item_func_trim(@$, $5, Item_func_trim::TRIM_TRAILING);
9916          }
9917        | TRIM '(' BOTH FROM expr ')'
9918          {
9919            $$= NEW_PTN Item_func_trim(@$, $5, Item_func_trim::TRIM_BOTH);
9920          }
9921        | TRIM '(' expr FROM expr ')'
9922          {
9923            $$= NEW_PTN Item_func_trim(@$, $5, $3,
9924                                       Item_func_trim::TRIM_BOTH_DEFAULT);
9925          }
9926        | USER '(' ')'
9927          {
9928            $$= NEW_PTN Item_func_user(@$);
9929          }
9930        | YEAR_SYM '(' expr ')'
9931          {
9932            $$= NEW_PTN Item_func_year(@$, $3);
9933          }
9934        ;
9935
9936/*
9937  Function calls using non reserved keywords, with special syntaxic forms.
9938  Dedicated grammar rules are needed because of the syntax,
9939  but also have the potential to cause incompatibilities with other
9940  parts of the language.
9941  MAINTAINER:
9942  The only reasons a function should be added here are:
9943  - for compatibility reasons with another SQL syntax (CURDATE),
9944  - for typing reasons (GET_FORMAT)
9945  Any other 'Syntaxic sugar' enhancements should be *STRONGLY*
9946  discouraged.
9947*/
9948function_call_nonkeyword:
9949          ADDDATE_SYM '(' expr ',' expr ')'
9950          {
9951            $$= NEW_PTN Item_date_add_interval(@$, $3, $5, INTERVAL_DAY, 0);
9952          }
9953        | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
9954          {
9955            $$= NEW_PTN Item_date_add_interval(@$, $3, $6, $7, 0);
9956          }
9957        | CURDATE optional_braces
9958          {
9959            $$= NEW_PTN Item_func_curdate_local(@$);
9960          }
9961        | CURTIME func_datetime_precision
9962          {
9963            $$= NEW_PTN Item_func_curtime_local(@$, static_cast<uint8>($2));
9964          }
9965        | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
9966          %prec INTERVAL_SYM
9967          {
9968            $$= NEW_PTN Item_date_add_interval(@$, $3, $6, $7, 0);
9969          }
9970        | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
9971          %prec INTERVAL_SYM
9972          {
9973            $$= NEW_PTN Item_date_add_interval(@$, $3, $6, $7, 1);
9974          }
9975        | EXTRACT_SYM '(' interval FROM expr ')'
9976          {
9977            $$= NEW_PTN Item_extract(@$,  $3, $5);
9978          }
9979        | GET_FORMAT '(' date_time_type  ',' expr ')'
9980          {
9981            $$= NEW_PTN Item_func_get_format(@$, $3, $5);
9982          }
9983        | now
9984          {
9985            $$= NEW_PTN PTI_function_call_nonkeyword_now(@$,
9986              static_cast<uint8>($1));
9987          }
9988        | POSITION_SYM '(' bit_expr IN_SYM expr ')'
9989          {
9990            $$= NEW_PTN Item_func_locate(@$, $5,$3);
9991          }
9992        | SUBDATE_SYM '(' expr ',' expr ')'
9993          {
9994            $$= NEW_PTN Item_date_add_interval(@$, $3, $5, INTERVAL_DAY, 1);
9995          }
9996        | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
9997          {
9998            $$= NEW_PTN Item_date_add_interval(@$, $3, $6, $7, 1);
9999          }
10000        | SUBSTRING '(' expr ',' expr ',' expr ')'
10001          {
10002            $$= NEW_PTN Item_func_substr(@$, $3,$5,$7);
10003          }
10004        | SUBSTRING '(' expr ',' expr ')'
10005          {
10006            $$= NEW_PTN Item_func_substr(@$, $3,$5);
10007          }
10008        | SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
10009          {
10010            $$= NEW_PTN Item_func_substr(@$, $3,$5,$7);
10011          }
10012        | SUBSTRING '(' expr FROM expr ')'
10013          {
10014            $$= NEW_PTN Item_func_substr(@$, $3,$5);
10015          }
10016        | SYSDATE func_datetime_precision
10017          {
10018            $$= NEW_PTN PTI_function_call_nonkeyword_sysdate(@$,
10019              static_cast<uint8>($2));
10020          }
10021        | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
10022          {
10023            $$= NEW_PTN Item_date_add_interval(@$, $7, $5, $3, 0);
10024          }
10025        | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
10026          {
10027            $$= NEW_PTN Item_func_timestamp_diff(@$, $5,$7,$3);
10028          }
10029        | UTC_DATE_SYM optional_braces
10030          {
10031            $$= NEW_PTN Item_func_curdate_utc(@$);
10032          }
10033        | UTC_TIME_SYM func_datetime_precision
10034          {
10035            $$= NEW_PTN Item_func_curtime_utc(@$, static_cast<uint8>($2));
10036          }
10037        | UTC_TIMESTAMP_SYM func_datetime_precision
10038          {
10039            $$= NEW_PTN Item_func_now_utc(@$, static_cast<uint8>($2));
10040          }
10041        ;
10042
10043/*
10044  Functions calls using a non reserved keyword, and using a regular syntax.
10045  Because the non reserved keyword is used in another part of the grammar,
10046  a dedicated rule is needed here.
10047*/
10048function_call_conflict:
10049          ASCII_SYM '(' expr ')'
10050          {
10051            $$= NEW_PTN Item_func_ascii(@$, $3);
10052          }
10053        | CHARSET '(' expr ')'
10054          {
10055            $$= NEW_PTN Item_func_charset(@$, $3);
10056          }
10057        | COALESCE '(' expr_list ')'
10058          {
10059            $$= NEW_PTN Item_func_coalesce(@$, $3);
10060          }
10061        | COLLATION_SYM '(' expr ')'
10062          {
10063            $$= NEW_PTN Item_func_collation(@$, $3);
10064          }
10065        | DATABASE '(' ')'
10066          {
10067            $$= NEW_PTN Item_func_database(@$);
10068          }
10069        | IF '(' expr ',' expr ',' expr ')'
10070          {
10071            $$= NEW_PTN Item_func_if(@$, $3,$5,$7);
10072          }
10073        | FORMAT_SYM '(' expr ',' expr ')'
10074          {
10075            $$= NEW_PTN Item_func_format(@$, $3, $5);
10076          }
10077        | FORMAT_SYM '(' expr ',' expr ',' expr ')'
10078          {
10079            $$= NEW_PTN Item_func_format(@$, $3, $5, $7);
10080          }
10081        | MICROSECOND_SYM '(' expr ')'
10082          {
10083            $$= NEW_PTN Item_func_microsecond(@$, $3);
10084          }
10085        | MOD_SYM '(' expr ',' expr ')'
10086          {
10087            $$= NEW_PTN Item_func_mod(@$, $3, $5);
10088          }
10089        | PASSWORD '(' expr ')'
10090          {
10091            $$= NEW_PTN PTI_password(@$, $3);
10092          }
10093        | QUARTER_SYM '(' expr ')'
10094          {
10095            $$= NEW_PTN Item_func_quarter(@$, $3);
10096          }
10097        | REPEAT_SYM '(' expr ',' expr ')'
10098          {
10099            $$= NEW_PTN Item_func_repeat(@$, $3,$5);
10100          }
10101        | REPLACE '(' expr ',' expr ',' expr ')'
10102          {
10103            $$= NEW_PTN Item_func_replace(@$, $3,$5,$7);
10104          }
10105        | REVERSE_SYM '(' expr ')'
10106          {
10107            $$= NEW_PTN Item_func_reverse(@$, $3);
10108          }
10109        | ROW_COUNT_SYM '(' ')'
10110          {
10111            $$= NEW_PTN Item_func_row_count(@$);
10112          }
10113        | TRUNCATE_SYM '(' expr ',' expr ')'
10114          {
10115            $$= NEW_PTN Item_func_round(@$, $3,$5,1);
10116          }
10117        | WEEK_SYM '(' expr ')'
10118          {
10119            $$= NEW_PTN Item_func_week(@$, $3, NULL);
10120          }
10121        | WEEK_SYM '(' expr ',' expr ')'
10122          {
10123            $$= NEW_PTN Item_func_week(@$, $3, $5);
10124          }
10125        | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')'
10126          {
10127            $$= NEW_PTN Item_func_weight_string(@$, $3, 0, 0, $4);
10128          }
10129        | WEIGHT_STRING_SYM '(' expr AS CHAR_SYM ws_nweights opt_ws_levels ')'
10130          {
10131            $$= NEW_PTN Item_func_weight_string(@$, $3, 0, $6,
10132                        $7 | MY_STRXFRM_PAD_WITH_SPACE);
10133          }
10134        | WEIGHT_STRING_SYM '(' expr AS BINARY ws_nweights ')'
10135          {
10136            $$= NEW_PTN Item_func_weight_string(@$,
10137                        $3, 0, $6, MY_STRXFRM_PAD_WITH_SPACE, true);
10138          }
10139        | WEIGHT_STRING_SYM '(' expr ',' ulong_num ',' ulong_num ',' ulong_num ')'
10140          {
10141            $$= NEW_PTN Item_func_weight_string(@$, $3, $5, $7, $9);
10142          }
10143        | geometry_function
10144        ;
10145
10146geometry_function:
10147          CONTAINS_SYM '(' expr ',' expr ')'
10148          {
10149            push_deprecated_warn(YYTHD, "CONTAINS", "MBRCONTAINS");
10150            $$= NEW_PTN Item_func_spatial_mbr_rel(@$, $3, $5,
10151                        Item_func::SP_CONTAINS_FUNC);
10152          }
10153        | GEOMETRYCOLLECTION '(' opt_expr_list ')'
10154          {
10155            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10156                        Geometry::wkb_geometrycollection,
10157                        Geometry::wkb_point);
10158          }
10159        | LINESTRING '(' expr_list ')'
10160          {
10161            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10162                        Geometry::wkb_linestring,
10163                        Geometry::wkb_point);
10164          }
10165        | MULTILINESTRING '(' expr_list ')'
10166          {
10167            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10168                        Geometry::wkb_multilinestring,
10169                        Geometry::wkb_linestring);
10170          }
10171        | MULTIPOINT '(' expr_list ')'
10172          {
10173            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10174                        Geometry::wkb_multipoint,
10175                        Geometry::wkb_point);
10176          }
10177        | MULTIPOLYGON '(' expr_list ')'
10178          {
10179            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10180                        Geometry::wkb_multipolygon,
10181                        Geometry::wkb_polygon);
10182          }
10183        | POINT_SYM '(' expr ',' expr ')'
10184          {
10185            $$= NEW_PTN Item_func_point(@$, $3,$5);
10186          }
10187        | POLYGON '(' expr_list ')'
10188          {
10189            $$= NEW_PTN Item_func_spatial_collection(@$, $3,
10190                        Geometry::wkb_polygon,
10191                        Geometry::wkb_linestring);
10192          }
10193        ;
10194
10195/*
10196  Regular function calls.
10197  The function name is *not* a token, and therefore is guaranteed to not
10198  introduce side effects to the language in general.
10199  MAINTAINER:
10200  All the new functions implemented for new features should fit into
10201  this category. The place to implement the function itself is
10202  in sql/item_create.cc
10203*/
10204function_call_generic:
10205          IDENT_sys '(' opt_udf_expr_list ')'
10206          {
10207            $$= NEW_PTN PTI_function_call_generic_ident_sys(@1, $1, $3);
10208          }
10209        | ident '.' ident '(' opt_expr_list ')'
10210          {
10211            $$= NEW_PTN PTI_function_call_generic_2d(@$, $1, $3, $5);
10212          }
10213        ;
10214
10215fulltext_options:
10216          opt_natural_language_mode opt_query_expansion
10217          { $$= $1 | $2; }
10218        | IN_SYM BOOLEAN_SYM MODE_SYM
10219          {
10220            $$= FT_BOOL;
10221            DBUG_EXECUTE_IF("simulate_bug18831513",
10222                            {
10223                              THD *thd= YYTHD;
10224                              if (thd->sp_runtime_ctx)
10225                                MYSQLerror(NULL,thd,"syntax error");
10226                            });
10227          }
10228        ;
10229
10230opt_natural_language_mode:
10231          /* nothing */                         { $$= FT_NL; }
10232        | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM  { $$= FT_NL; }
10233        ;
10234
10235opt_query_expansion:
10236          /* nothing */                         { $$= 0;         }
10237        | WITH QUERY_SYM EXPANSION_SYM          { $$= FT_EXPAND; }
10238        ;
10239
10240opt_udf_expr_list:
10241        /* empty */     { $$= NULL; }
10242        | udf_expr_list { $$= $1; }
10243        ;
10244
10245udf_expr_list:
10246          udf_expr
10247          {
10248            $$= NEW_PTN PT_item_list;
10249            if ($$ == NULL || $$->push_back($1))
10250              MYSQL_YYABORT;
10251          }
10252        | udf_expr_list ',' udf_expr
10253          {
10254            if ($1 == NULL || $1->push_back($3))
10255              MYSQL_YYABORT;
10256            $$= $1;
10257          }
10258        ;
10259
10260udf_expr:
10261          expr select_alias
10262          {
10263            $$= NEW_PTN PTI_udf_expr(@$, $1, $2, @1.cpp);
10264          }
10265        ;
10266
10267sum_expr:
10268          AVG_SYM '(' in_sum_expr ')'
10269          {
10270            $$= NEW_PTN Item_sum_avg(@$, $3, FALSE);
10271          }
10272        | AVG_SYM '(' DISTINCT in_sum_expr ')'
10273          {
10274            $$= NEW_PTN Item_sum_avg(@$, $4, TRUE);
10275          }
10276        | BIT_AND  '(' in_sum_expr ')'
10277          {
10278            $$= NEW_PTN Item_sum_and(@$, $3);
10279          }
10280        | BIT_OR  '(' in_sum_expr ')'
10281          {
10282            $$= NEW_PTN Item_sum_or(@$, $3);
10283          }
10284        | JSON_ARRAYAGG '(' in_sum_expr ')'
10285          {
10286            $$= NEW_PTN Item_sum_json_array(@$, $3);
10287          }
10288        | JSON_OBJECTAGG '(' in_sum_expr ',' in_sum_expr ')'
10289          {
10290            $$= NEW_PTN Item_sum_json_object(@$, $3, $5);
10291          }
10292        | BIT_XOR  '(' in_sum_expr ')'
10293          {
10294            $$= NEW_PTN Item_sum_xor(@$, $3);
10295          }
10296        | COUNT_SYM '(' opt_all '*' ')'
10297          {
10298            $$= NEW_PTN PTI_count_sym(@$);
10299          }
10300        | COUNT_SYM '(' in_sum_expr ')'
10301          {
10302            $$= NEW_PTN Item_sum_count(@$, $3);
10303          }
10304        | COUNT_SYM '(' DISTINCT expr_list ')'
10305          {
10306            $$= new Item_sum_count(@$, $4);
10307          }
10308        | MIN_SYM '(' in_sum_expr ')'
10309          {
10310            $$= NEW_PTN Item_sum_min(@$, $3);
10311          }
10312        /*
10313          According to ANSI SQL, DISTINCT is allowed and has
10314          no sense inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...)
10315          is processed like an ordinary MIN | MAX()
10316        */
10317        | MIN_SYM '(' DISTINCT in_sum_expr ')'
10318          {
10319            $$= NEW_PTN Item_sum_min(@$, $4);
10320          }
10321        | MAX_SYM '(' in_sum_expr ')'
10322          {
10323            $$= NEW_PTN Item_sum_max(@$, $3);
10324          }
10325        | MAX_SYM '(' DISTINCT in_sum_expr ')'
10326          {
10327            $$= NEW_PTN Item_sum_max(@$, $4);
10328          }
10329        | STD_SYM '(' in_sum_expr ')'
10330          {
10331            $$= NEW_PTN Item_sum_std(@$, $3, 0);
10332          }
10333        | VARIANCE_SYM '(' in_sum_expr ')'
10334          {
10335            $$= NEW_PTN Item_sum_variance(@$, $3, 0);
10336          }
10337        | STDDEV_SAMP_SYM '(' in_sum_expr ')'
10338          {
10339            $$= NEW_PTN Item_sum_std(@$, $3, 1);
10340          }
10341        | VAR_SAMP_SYM '(' in_sum_expr ')'
10342          {
10343            $$= NEW_PTN Item_sum_variance(@$, $3, 1);
10344          }
10345        | SUM_SYM '(' in_sum_expr ')'
10346          {
10347            $$= NEW_PTN Item_sum_sum(@$, $3, FALSE);
10348          }
10349        | SUM_SYM '(' DISTINCT in_sum_expr ')'
10350          {
10351            $$= NEW_PTN Item_sum_sum(@$, $4, TRUE);
10352          }
10353        | GROUP_CONCAT_SYM '(' opt_distinct
10354          expr_list opt_gorder_clause
10355          opt_gconcat_separator
10356          ')'
10357          {
10358            $$= NEW_PTN Item_func_group_concat(@$, $3, $4, $5, $6);
10359          }
10360        ;
10361
10362variable:
10363          '@' variable_aux { $$= $2; }
10364        ;
10365
10366variable_aux:
10367          ident_or_text SET_VAR expr
10368          {
10369            $$= NEW_PTN PTI_variable_aux_set_var(@$, $1, $3);
10370          }
10371        | ident_or_text
10372          {
10373            $$= NEW_PTN PTI_variable_aux_ident_or_text(@$, $1);
10374          }
10375        | '@' opt_var_ident_type ident_or_text opt_component
10376          {
10377            $$= NEW_PTN PTI_variable_aux_3d(@$, $2, $3, @3, $4);
10378          }
10379        ;
10380
10381opt_distinct:
10382          /* empty */ { $$ = 0; }
10383        | DISTINCT    { $$ = 1; }
10384        ;
10385
10386opt_gconcat_separator:
10387          /* empty */
10388          {
10389            $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1);
10390            if ($$ == NULL)
10391              MYSQL_YYABORT;
10392          }
10393        | SEPARATOR_SYM text_string { $$ = $2; }
10394        ;
10395
10396opt_gorder_clause:
10397          /* empty */               { $$= NULL; }
10398        | ORDER_SYM BY gorder_list  { $$= $3; }
10399        ;
10400
10401gorder_list:
10402          gorder_list ',' order_expr
10403          {
10404            $1->push_back($3);
10405            $$= $1;
10406          }
10407        | order_expr
10408          {
10409            $$= NEW_PTN PT_gorder_list();
10410            if ($$ == NULL)
10411              MYSQL_YYABORT;
10412            $$->push_back($1);
10413          }
10414        ;
10415
10416in_sum_expr:
10417          opt_all expr
10418          {
10419            $$= NEW_PTN PTI_in_sum_expr(@1, $2);
10420          }
10421        ;
10422
10423cast_type:
10424          BINARY opt_field_length
10425          {
10426            $$.target= ITEM_CAST_CHAR;
10427            $$.charset= &my_charset_bin;
10428            $$.type_flags= 0;
10429            $$.length= $2;
10430            $$.dec= NULL;
10431          }
10432        | CHAR_SYM opt_field_length opt_binary
10433          {
10434            $$.target= ITEM_CAST_CHAR;
10435            $$.charset= $3.charset;
10436            $$.type_flags= $3.type_flags;
10437            $$.length= $2;
10438            $$.dec= NULL;
10439          }
10440        | NCHAR_SYM opt_field_length
10441          {
10442            $$.target= ITEM_CAST_CHAR;
10443            $$.charset= national_charset_info;
10444            $$.type_flags= 0;
10445            $$.length= $2;
10446            $$.dec= NULL;
10447          }
10448        | SIGNED_SYM
10449          {
10450            $$.target= ITEM_CAST_SIGNED_INT;
10451            $$.charset= NULL;
10452            $$.type_flags= 0;
10453            $$.length= NULL;
10454            $$.dec= NULL;
10455          }
10456        | SIGNED_SYM INT_SYM
10457          {
10458            $$.target= ITEM_CAST_SIGNED_INT;
10459            $$.charset= NULL;
10460            $$.type_flags= 0;
10461            $$.length= NULL;
10462            $$.dec= NULL;
10463          }
10464        | UNSIGNED
10465          {
10466            $$.target= ITEM_CAST_UNSIGNED_INT;
10467            $$.charset= NULL;
10468            $$.type_flags= 0;
10469            $$.length= NULL;
10470            $$.dec= NULL;
10471          }
10472        | UNSIGNED INT_SYM
10473          {
10474            $$.target= ITEM_CAST_UNSIGNED_INT;
10475            $$.charset= NULL;
10476            $$.type_flags= 0;
10477            $$.length= NULL;
10478            $$.dec= NULL;
10479          }
10480        | DATE_SYM
10481          {
10482            $$.target= ITEM_CAST_DATE;
10483            $$.charset= NULL;
10484            $$.type_flags= 0;
10485            $$.length= NULL;
10486            $$.dec= NULL;
10487          }
10488        | TIME_SYM type_datetime_precision
10489          {
10490            $$.target= ITEM_CAST_TIME;
10491            $$.charset= NULL;
10492            $$.type_flags= 0;
10493            $$.length= NULL;
10494            $$.dec= $2;
10495          }
10496        | DATETIME type_datetime_precision
10497          {
10498            $$.target= ITEM_CAST_DATETIME;
10499            $$.charset= NULL;
10500            $$.type_flags= 0;
10501            $$.length= NULL;
10502            $$.dec= $2;
10503          }
10504        | DECIMAL_SYM float_options
10505          {
10506            $$.target=ITEM_CAST_DECIMAL;
10507            $$.charset= NULL;
10508            $$.type_flags= 0;
10509            $$.length= $2.length;
10510            $$.dec= $2.dec;
10511          }
10512        | JSON_SYM
10513          {
10514            $$.target=ITEM_CAST_JSON;
10515            $$.charset= NULL;
10516            $$.type_flags= 0;
10517            $$.length= NULL;
10518            $$.dec= NULL;
10519          }
10520        ;
10521
10522opt_expr_list:
10523          /* empty */ { $$= NULL; }
10524        | expr_list
10525        ;
10526
10527expr_list:
10528          expr
10529          {
10530            $$= NEW_PTN PT_item_list;
10531            if ($$ == NULL || $$->push_back($1))
10532              MYSQL_YYABORT;
10533          }
10534        | expr_list ',' expr
10535          {
10536            if ($1 == NULL || $1->push_back($3))
10537              MYSQL_YYABORT;
10538            $$= $1;
10539          }
10540        ;
10541
10542ident_list_arg:
10543          ident_list          { $$= $1; }
10544        | '(' ident_list ')'  { $$= $2; }
10545        ;
10546
10547ident_list:
10548          simple_ident
10549          {
10550            $$= NEW_PTN PT_item_list;
10551            if ($$ == NULL || $$->push_back($1))
10552              MYSQL_YYABORT;
10553          }
10554        | ident_list ',' simple_ident
10555          {
10556            if ($1 == NULL || $1->push_back($3))
10557              MYSQL_YYABORT;
10558            $$= $1;
10559          }
10560        ;
10561
10562opt_expr:
10563          /* empty */    { $$= NULL; }
10564        | expr           { $$= $1; }
10565        ;
10566
10567opt_else:
10568          /* empty */  { $$= NULL; }
10569        | ELSE expr    { $$= $2; }
10570        ;
10571
10572when_list:
10573          WHEN_SYM expr THEN_SYM expr
10574          {
10575            $$= new List<Item>;
10576            if ($$ == NULL)
10577              MYSQL_YYABORT;
10578            $$->push_back($2);
10579            $$->push_back($4);
10580          }
10581        | when_list WHEN_SYM expr THEN_SYM expr
10582          {
10583            $1->push_back($3);
10584            $1->push_back($5);
10585            $$= $1;
10586          }
10587        ;
10588
10589/* Equivalent to <table reference> in the SQL:2003 standard. */
10590/* Warning - may return NULL in case of incomplete SELECT */
10591table_ref:
10592          table_factor
10593        | join_table
10594          {
10595            $$= NEW_PTN PT_table_ref_join_table($1);
10596          }
10597        ;
10598
10599join_table_list:
10600          derived_table_list
10601          {
10602            $$= NEW_PTN PT_join_table_list(@$, $1);
10603          }
10604        ;
10605
10606/*
10607  The ODBC escape syntax for Outer Join is: '{' OJ join_table '}'
10608  The parser does not define OJ as a token, any ident is accepted
10609  instead in $2 (ident). Also, all productions from table_ref can
10610  be escaped, not only join_table. Both syntax extensions are safe
10611  and are ignored.
10612*/
10613esc_table_ref:
10614        table_ref
10615      | '{' ident table_ref '}' { $$= $3; }
10616      ;
10617
10618/* Equivalent to <table reference list> in the SQL:2003 standard. */
10619/* Warning - may return NULL in case of incomplete SELECT */
10620derived_table_list:
10621          esc_table_ref
10622        | derived_table_list ',' esc_table_ref
10623          {
10624            $$= NEW_PTN PT_derived_table_list(@$, $1, $3);
10625          }
10626        ;
10627
10628/*
10629  Notice that JOIN is a left-associative operation, and it must be parsed
10630  as such, that is, the parser must process first the left join operand
10631  then the right one. Such order of processing ensures that the parser
10632  produces correct join trees which is essential for semantic analysis
10633  and subsequent optimization phases.
10634*/
10635join_table:
10636          /* INNER JOIN variants */
10637          /*
10638            Use %prec to evaluate production 'table_ref' before 'normal_join'
10639            so that [INNER | CROSS] JOIN is properly nested as other
10640            left-associative joins.
10641          */
10642          table_ref normal_join table_ref %prec TABLE_REF_PRIORITY
10643          {
10644            $$= NEW_PTN PT_join_table<JTT_NORMAL>($1, @2, $3);
10645          }
10646        | table_ref STRAIGHT_JOIN table_factor
10647          {
10648            $$= NEW_PTN PT_join_table<JTT_STRAIGHT>($1, @2, $3);
10649          }
10650        | table_ref normal_join table_ref
10651          ON
10652          expr
10653          {
10654            $$= NEW_PTN PT_join_table_on<JTT_NORMAL>($1, @2, $3, $5);
10655          }
10656        | table_ref STRAIGHT_JOIN table_factor
10657          ON
10658          expr
10659          {
10660            $$= NEW_PTN PT_join_table_on<JTT_STRAIGHT>($1, @2, $3, $5);
10661          }
10662        | table_ref normal_join table_ref
10663          USING
10664          '(' using_list ')'
10665          {
10666            $$= NEW_PTN PT_join_table_using<JTT_NORMAL>($1, @2, $3, $6);
10667          }
10668        | table_ref NATURAL JOIN_SYM table_factor
10669          {
10670            $$= NEW_PTN PT_join_table<JTT_NATURAL>($1, @2, $4);
10671          }
10672
10673          /* LEFT JOIN variants */
10674        | table_ref LEFT opt_outer JOIN_SYM table_ref
10675          ON
10676          expr
10677          {
10678            $$= NEW_PTN PT_join_table_on<JTT_LEFT>($1, @2, $5, $7);
10679          }
10680        | table_ref LEFT opt_outer JOIN_SYM table_factor
10681          USING '(' using_list ')'
10682          {
10683            $$= NEW_PTN PT_join_table_using<JTT_LEFT>($1, @2, $5, $8);
10684          }
10685        | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
10686          {
10687            $$= NEW_PTN PT_join_table<JTT_NATURAL_LEFT>($1, @2, $6);
10688          }
10689
10690          /* RIGHT JOIN variants */
10691        | table_ref RIGHT opt_outer JOIN_SYM table_ref
10692          ON
10693          expr
10694          {
10695            $$= NEW_PTN PT_join_table_on<JTT_RIGHT>($1, @2, $5, $7);
10696          }
10697        | table_ref RIGHT opt_outer JOIN_SYM table_factor
10698          USING '(' using_list ')'
10699          {
10700            $$= NEW_PTN PT_join_table_using<JTT_RIGHT>($1, @2, $5, $8);
10701          }
10702        | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
10703          {
10704            $$= NEW_PTN PT_join_table<JTT_NATURAL_RIGHT>($1, @2, $6);
10705          }
10706        ;
10707
10708normal_join:
10709          JOIN_SYM {}
10710        | INNER_SYM JOIN_SYM {}
10711        | CROSS JOIN_SYM {}
10712        ;
10713
10714/*
10715  table PARTITION (list of partitions), reusing using_list instead of creating
10716  a new rule for partition_list.
10717*/
10718opt_use_partition:
10719          /* empty */ { $$= NULL; }
10720        | use_partition
10721        ;
10722
10723use_partition:
10724          PARTITION_SYM '(' using_list ')'
10725          {
10726            $$= $3;
10727          }
10728        ;
10729
10730/*
10731   This is a flattening of the rules <table factor> and <table primary>
10732   in the SQL:2003 standard, since we don't have <sample clause>
10733
10734   I.e.
10735   <table factor> ::= <table primary> [ <sample clause> ]
10736*/
10737/* Warning - may return NULL in case of incomplete SELECT */
10738table_factor:
10739          table_ident opt_use_partition opt_table_alias opt_key_definition
10740          {
10741            $$= NEW_PTN PT_table_factor_table_ident($1, $2, $3, $4);
10742          }
10743        | SELECT_SYM select_options select_item_list table_expression
10744          {
10745            $$= NEW_PTN PT_table_factor_select_sym(@$, $1, $2, $3, $4);
10746          }
10747          /*
10748            Represents a flattening of the following rules from the SQL:2003
10749            standard. This sub-rule corresponds to the sub-rule
10750            <table primary> ::= ... | <derived table> [ AS ] <correlation name>
10751
10752            The following rules have been flattened into query_expression_body
10753            (since we have no <with clause>).
10754
10755            <derived table> ::= <table subquery>
10756            <table subquery> ::= <subquery>
10757            <subquery> ::= <left paren> <query expression> <right paren>
10758            <query expression> ::= [ <with clause> ] <query expression body>
10759
10760            For the time being we use the non-standard rule
10761            select_derived_union which is a compromise between the standard
10762            and our parser. Possibly this rule could be replaced by our
10763            query_expression_body.
10764          */
10765        | '(' select_derived_union ')' opt_table_alias
10766          {
10767            $$= NEW_PTN PT_table_factor_parenthesis($2, $4, @4);
10768          }
10769        ;
10770
10771/*
10772  This rule accepts just about anything. The reason is that we have
10773  empty-producing rules in the beginning of rules, in this case
10774  subselect_start. This forces bison to take a decision which rules to
10775  reduce by long before it has seen any tokens. This approach ties us
10776  to a very limited class of parseable languages, and unfortunately
10777  SQL is not one of them. The chosen 'solution' was this rule, which
10778  produces just about anything, even complete bogus statements, for
10779  instance ( table UNION SELECT 1 ).
10780
10781  Fortunately, we know that the semantic value returned by
10782  select_derived->value is NULL if it contained a derived table, and a pointer to
10783  the base table's TABLE_LIST if it was a base table. So in the rule
10784  regarding union's, we throw a parse error manually and pretend it
10785  was bison that did it.
10786
10787  Also worth noting is that this rule concerns query expressions in
10788  the from clause only. Top level select statements and other types of
10789  subqueries have their own union rules.
10790 */
10791select_derived_union:
10792          select_derived opt_union_order_or_limit
10793          {
10794            $$= NEW_PTN PT_select_derived_union_select($1, $2, @2);
10795          }
10796        | select_derived_union UNION_SYM union_option query_specification
10797          {
10798            $$= NEW_PTN PT_select_derived_union_union($1, @2, $3, $4);
10799          }
10800        ;
10801
10802/* The equivalent of select_part2 for nested queries. */
10803select_part2_derived:
10804          {
10805            /*
10806              TODO: remove this semantic action (currently this removal
10807              adds shift/reduce conflict)
10808            */
10809          }
10810          opt_query_spec_options select_item_list
10811          {
10812            $$= NEW_PTN PT_select_part2_derived($2, $3);
10813          }
10814        ;
10815
10816/* handle contents of parentheses in join expression */
10817select_derived:
10818          derived_table_list
10819          {
10820            $$= NEW_PTN PT_select_derived(@1, $1);
10821          }
10822        ;
10823
10824opt_outer:
10825          /* empty */ {}
10826        | OUTER {}
10827        ;
10828
10829index_hint_clause:
10830          /* empty */
10831          {
10832            $$= old_mode ?  INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
10833          }
10834        | FOR_SYM JOIN_SYM      { $$= INDEX_HINT_MASK_JOIN;  }
10835        | FOR_SYM ORDER_SYM BY  { $$= INDEX_HINT_MASK_ORDER; }
10836        | FOR_SYM GROUP_SYM BY  { $$= INDEX_HINT_MASK_GROUP; }
10837        ;
10838
10839index_hint_type:
10840          FORCE_SYM  { $$= INDEX_HINT_FORCE; }
10841        | IGNORE_SYM { $$= INDEX_HINT_IGNORE; }
10842        ;
10843
10844index_hint_definition:
10845          index_hint_type key_or_index index_hint_clause
10846          '(' key_usage_list ')'
10847          {
10848            init_index_hints($5, $1, $3);
10849            $$= $5;
10850          }
10851        | USE_SYM key_or_index index_hint_clause
10852          '(' opt_key_usage_list ')'
10853          {
10854            init_index_hints($5, INDEX_HINT_USE, $3);
10855            $$= $5;
10856          }
10857       ;
10858
10859index_hints_list:
10860          index_hint_definition
10861        | index_hints_list index_hint_definition
10862          {
10863            $2->concat($1);
10864            $$= $2;
10865          }
10866        ;
10867
10868opt_index_hints_list:
10869          /* empty */ { $$= NULL; }
10870        | index_hints_list
10871        ;
10872
10873opt_key_definition:
10874          opt_index_hints_list
10875        ;
10876
10877opt_key_usage_list:
10878          /* empty */
10879          {
10880            $$= new (YYTHD->mem_root) List<Index_hint>;
10881            Index_hint *hint= new (YYTHD->mem_root) Index_hint(NULL, 0);
10882            if ($$ == NULL || hint == NULL || $$->push_front(hint))
10883              MYSQL_YYABORT;
10884          }
10885        | key_usage_list
10886        ;
10887
10888key_usage_element:
10889          ident
10890          {
10891            $$= new (YYTHD->mem_root) Index_hint($1.str, $1.length);
10892            if ($$ == NULL)
10893              MYSQL_YYABORT;
10894          }
10895        | PRIMARY_SYM
10896          {
10897            $$= new (YYTHD->mem_root) Index_hint(STRING_WITH_LEN("PRIMARY"));
10898            if ($$ == NULL)
10899              MYSQL_YYABORT;
10900          }
10901        ;
10902
10903key_usage_list:
10904          key_usage_element
10905          {
10906            $$= new (YYTHD->mem_root) List<Index_hint>;
10907            if ($$ == NULL || $$->push_front($1))
10908              MYSQL_YYABORT;
10909          }
10910        | key_usage_list ',' key_usage_element
10911          {
10912            if ($$->push_front($3))
10913              MYSQL_YYABORT;
10914          }
10915        ;
10916
10917using_list:
10918          ident
10919          {
10920            if (!($$= new List<String>))
10921              MYSQL_YYABORT;
10922            String *s= new (YYTHD->mem_root) String((const char *) $1.str,
10923                                                    $1.length,
10924                                                    system_charset_info);
10925            if (s == NULL)
10926              MYSQL_YYABORT;
10927            $$->push_back(s);
10928          }
10929        | using_list ',' ident
10930          {
10931            String *s= new (YYTHD->mem_root) String((const char *) $3.str,
10932                                                    $3.length,
10933                                                    system_charset_info);
10934            if (s == NULL)
10935              MYSQL_YYABORT;
10936            $1->push_back(s);
10937            $$= $1;
10938          }
10939        ;
10940
10941interval:
10942          interval_time_stamp    {}
10943        | DAY_HOUR_SYM           { $$=INTERVAL_DAY_HOUR; }
10944        | DAY_MICROSECOND_SYM    { $$=INTERVAL_DAY_MICROSECOND; }
10945        | DAY_MINUTE_SYM         { $$=INTERVAL_DAY_MINUTE; }
10946        | DAY_SECOND_SYM         { $$=INTERVAL_DAY_SECOND; }
10947        | HOUR_MICROSECOND_SYM   { $$=INTERVAL_HOUR_MICROSECOND; }
10948        | HOUR_MINUTE_SYM        { $$=INTERVAL_HOUR_MINUTE; }
10949        | HOUR_SECOND_SYM        { $$=INTERVAL_HOUR_SECOND; }
10950        | MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; }
10951        | MINUTE_SECOND_SYM      { $$=INTERVAL_MINUTE_SECOND; }
10952        | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; }
10953        | YEAR_MONTH_SYM         { $$=INTERVAL_YEAR_MONTH; }
10954        ;
10955
10956interval_time_stamp:
10957          DAY_SYM         { $$=INTERVAL_DAY; }
10958        | WEEK_SYM        { $$=INTERVAL_WEEK; }
10959        | HOUR_SYM        { $$=INTERVAL_HOUR; }
10960        | MINUTE_SYM      { $$=INTERVAL_MINUTE; }
10961        | MONTH_SYM       { $$=INTERVAL_MONTH; }
10962        | QUARTER_SYM     { $$=INTERVAL_QUARTER; }
10963        | SECOND_SYM      { $$=INTERVAL_SECOND; }
10964        | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
10965        | YEAR_SYM        { $$=INTERVAL_YEAR; }
10966        ;
10967
10968date_time_type:
10969          DATE_SYM  {$$= MYSQL_TIMESTAMP_DATE; }
10970        | TIME_SYM  {$$= MYSQL_TIMESTAMP_TIME; }
10971        | TIMESTAMP {$$= MYSQL_TIMESTAMP_DATETIME; }
10972        | DATETIME  {$$= MYSQL_TIMESTAMP_DATETIME; }
10973        ;
10974
10975table_alias:
10976          /* empty */
10977        | AS
10978        | EQ
10979        ;
10980
10981opt_table_alias:
10982          /* empty */ { $$=0; }
10983        | table_alias ident
10984          {
10985            $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING));
10986            if ($$ == NULL)
10987              MYSQL_YYABORT;
10988          }
10989        ;
10990
10991opt_all:
10992          /* empty */
10993        | ALL
10994        ;
10995
10996opt_where_clause:
10997          /* empty */  { $$= NULL; }
10998        | WHERE expr
10999          {
11000            $$= new PTI_context<CTX_WHERE>(@$, $2);
11001          }
11002        ;
11003
11004opt_having_clause:
11005          /* empty */ { $$= NULL; }
11006        | HAVING expr
11007          {
11008            $$= new PTI_context<CTX_HAVING>(@$, $2);
11009          }
11010        ;
11011
11012opt_escape:
11013          ESCAPE_SYM simple_expr { $$= $2; }
11014        | /* empty */            { $$= NULL; }
11015        ;
11016
11017/*
11018   group by statement in select
11019*/
11020
11021opt_group_clause:
11022          /* empty */ { $$= NULL; }
11023        | GROUP_SYM BY group_list olap_opt
11024          {
11025            $$= NEW_PTN PT_group($3, $4);
11026          }
11027        ;
11028
11029group_list:
11030          group_list ',' grouping_expr
11031          {
11032            $1->push_back($3);
11033            $$= $1;
11034          }
11035        | grouping_expr
11036          {
11037            $$= NEW_PTN PT_order_list();
11038            if ($$ == NULL)
11039              MYSQL_YYABORT;
11040            $$->push_back($1);
11041          }
11042        ;
11043
11044olap_opt:
11045          /* empty */   { $$= UNSPECIFIED_OLAP_TYPE; }
11046        | WITH_CUBE_SYM { $$= CUBE_TYPE; }
11047            /*
11048              'WITH CUBE' is reserved in the MySQL syntax, but not implemented,
11049              and cause LALR(2) conflicts.
11050              This syntax is not standard.
11051              MySQL syntax: GROUP BY col1, col2, col3 WITH CUBE
11052              SQL-2003: GROUP BY ... CUBE(col1, col2, col3)
11053            */
11054        | WITH_ROLLUP_SYM { $$= ROLLUP_TYPE; }
11055            /*
11056              'WITH ROLLUP' is needed for backward compatibility,
11057              and cause LALR(2) conflicts.
11058              This syntax is not standard.
11059              MySQL syntax: GROUP BY col1, col2, col3 WITH ROLLUP
11060              SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3)
11061            */
11062        ;
11063
11064/*
11065  Order by statement in ALTER TABLE
11066*/
11067
11068alter_order_clause:
11069          ORDER_SYM BY alter_order_list
11070        ;
11071
11072alter_order_list:
11073          alter_order_list ',' alter_order_item
11074        | alter_order_item
11075        ;
11076
11077alter_order_item:
11078          simple_ident_nospvar opt_ordering_direction
11079          {
11080            ITEMIZE($1, &$1);
11081
11082            THD *thd= YYTHD;
11083            ORDER *order= (ORDER *) thd->alloc(sizeof(ORDER));
11084            if (order == NULL)
11085              MYSQL_YYABORT;
11086            order->item_ptr= $1;
11087            order->direction= ($2 == 1) ? ORDER::ORDER_ASC : ORDER::ORDER_DESC;
11088            order->is_position= false;
11089            add_order_to_list(thd, order);
11090          }
11091        ;
11092
11093/*
11094   Order by statement in select
11095*/
11096
11097opt_order_clause:
11098          /* empty */ { $$= NULL; }
11099        | order_clause
11100        ;
11101
11102order_clause:
11103          ORDER_SYM BY order_list
11104          {
11105            $$= NEW_PTN PT_order($3);
11106          }
11107        ;
11108
11109order_list:
11110          order_list ',' order_expr
11111          {
11112            $1->push_back($3);
11113            $$= $1;
11114          }
11115        | order_expr
11116          {
11117            $$= NEW_PTN PT_order_list();
11118            if ($$ == NULL)
11119              MYSQL_YYABORT;
11120            $$->push_back($1);
11121          }
11122        ;
11123
11124opt_ordering_direction:
11125          /* empty */ { $$ =  1; }
11126        | ordering_direction
11127        ;
11128
11129ordering_direction:
11130          ASC  { $$ =1; }
11131        | DESC { $$ =0; }
11132        ;
11133
11134opt_limit_clause:
11135          /* empty */ { $$= NULL; }
11136        | limit_clause
11137        ;
11138
11139limit_clause:
11140          LIMIT limit_options
11141          {
11142            $$= NEW_PTN PT_limit_clause($2);
11143          }
11144        ;
11145
11146limit_options:
11147          limit_option
11148          {
11149            $$.limit= $1;
11150            $$.opt_offset= NULL;
11151            $$.is_offset_first= false;
11152          }
11153        | limit_option ',' limit_option
11154          {
11155            $$.limit= $3;
11156            $$.opt_offset= $1;
11157            $$.is_offset_first= true;
11158          }
11159        | limit_option OFFSET_SYM limit_option
11160          {
11161            $$.limit= $1;
11162            $$.opt_offset= $3;
11163            $$.is_offset_first= false;
11164          }
11165        ;
11166
11167limit_option:
11168          ident
11169          {
11170            $$= NEW_PTN PTI_limit_option_ident(@$, $1, @1.raw);
11171          }
11172        | param_marker
11173          {
11174            $$= NEW_PTN PTI_limit_option_param_marker(@$, $1);
11175          }
11176        | ULONGLONG_NUM
11177          {
11178            $$= NEW_PTN Item_uint(@$, $1.str, $1.length);
11179          }
11180        | LONG_NUM
11181          {
11182            $$= NEW_PTN Item_uint(@$, $1.str, $1.length);
11183          }
11184        | NUM
11185          {
11186            $$= NEW_PTN Item_uint(@$, $1.str, $1.length);
11187          }
11188        ;
11189
11190opt_simple_limit:
11191          /* empty */        { $$= NULL; }
11192        | LIMIT limit_option { $$= $2; }
11193        ;
11194
11195ulong_num:
11196          NUM           { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11197        | HEX_NUM       { $$= (ulong) my_strtoll($1.str, (char**) 0, 16); }
11198        | LONG_NUM      { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11199        | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11200        | DECIMAL_NUM   { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11201        | FLOAT_NUM     { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11202        ;
11203
11204real_ulong_num:
11205          NUM           { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11206        | HEX_NUM       { $$= (ulong) my_strtoll($1.str, (char**) 0, 16); }
11207        | LONG_NUM      { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11208        | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11209        | dec_num_error { MYSQL_YYABORT; }
11210        ;
11211
11212ulonglong_num:
11213          NUM           { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11214        | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11215        | LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11216        | DECIMAL_NUM   { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11217        | FLOAT_NUM     { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11218        ;
11219
11220real_ulonglong_num:
11221          NUM           { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11222        | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11223        | LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11224        | dec_num_error { MYSQL_YYABORT; }
11225        ;
11226
11227dec_num_error:
11228          dec_num
11229          { my_syntax_error(ER(ER_ONLY_INTEGERS_ALLOWED)); }
11230        ;
11231
11232dec_num:
11233          DECIMAL_NUM
11234        | FLOAT_NUM
11235        ;
11236
11237opt_procedure_analyse_clause:
11238          /* empty */ { $$= NULL; }
11239        | PROCEDURE_SYM ANALYSE_SYM
11240          '(' opt_procedure_analyse_params ')'
11241          {
11242            push_deprecated_warn_no_replacement(YYTHD, "PROCEDURE ANALYSE");
11243            $$= NEW_PTN PT_procedure_analyse($4);
11244          }
11245        ;
11246
11247opt_procedure_analyse_params:
11248          /* empty */
11249          {
11250            $$.max_tree_elements= Proc_analyse_params::default_max_tree_elements;
11251            $$.max_treemem= Proc_analyse_params::default_max_treemem;
11252          }
11253        | procedure_analyse_param
11254          {
11255            $$.max_tree_elements= static_cast<uint>($1);
11256            $$.max_treemem= Proc_analyse_params::default_max_treemem;
11257          }
11258        | procedure_analyse_param ',' procedure_analyse_param
11259          {
11260            $$.max_tree_elements= static_cast<uint>($1);
11261            $$.max_treemem= static_cast<uint>($3);
11262          }
11263        ;
11264
11265procedure_analyse_param:
11266          NUM
11267          {
11268            int error;
11269            $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error);
11270            if (error != 0)
11271            {
11272              my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), "ANALYSE");
11273              MYSQL_YYABORT;
11274            }
11275          }
11276        ;
11277
11278select_var_list:
11279          select_var_list ',' select_var_ident
11280          {
11281            $$= $1;
11282            if ($$ == NULL || $$->push_back($3))
11283              MYSQL_YYABORT;
11284          }
11285        | select_var_ident
11286          {
11287            $$= NEW_PTN PT_select_var_list;
11288            if ($$ == NULL || $$->push_back($1))
11289              MYSQL_YYABORT;
11290          }
11291        ;
11292
11293select_var_ident:
11294          '@' ident_or_text
11295          {
11296            $$= NEW_PTN PT_select_var($2);
11297          }
11298        | ident_or_text
11299          {
11300            $$= NEW_PTN PT_select_sp_var($1);
11301          }
11302        ;
11303
11304opt_into:
11305          /* empty */ { $$= NULL; }
11306        | into
11307        ;
11308
11309into:
11310          INTO into_destination
11311          {
11312            $$= $2;
11313          }
11314        ;
11315
11316into_destination:
11317          OUTFILE TEXT_STRING_filesystem
11318          opt_load_data_charset
11319          opt_field_term opt_line_term
11320          {
11321            $$= NEW_PTN PT_into_destination_outfile($2, $3, $4, $5);
11322          }
11323        | DUMPFILE TEXT_STRING_filesystem
11324          {
11325            $$= NEW_PTN PT_into_destination_dumpfile($2);
11326          }
11327        | select_var_list { $$= $1; }
11328        ;
11329
11330/*
11331  DO statement
11332*/
11333
11334do_stmt:
11335          DO_SYM empty_select_options select_item_list
11336          {
11337            $$= NEW_PTN PT_select(
11338                  NEW_PTN PT_select_init2(NULL,
11339                    NEW_PTN PT_select_part2(
11340                      NEW_PTN PT_select_options_and_item_list($2, $3)), NULL),
11341                                                              SQLCOM_DO);
11342          }
11343        ;
11344
11345empty_select_options:
11346          /* empty */
11347          {
11348            $$.query_spec_options= 0;
11349            $$.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
11350          }
11351        ;
11352
11353/*
11354  Drop : delete tables or index or user
11355*/
11356
11357drop:
11358          DROP opt_temporary table_or_tables if_exists
11359          {
11360            LEX *lex=Lex;
11361            lex->sql_command = SQLCOM_DROP_TABLE;
11362            lex->drop_temporary= $2;
11363            lex->drop_if_exists= $4;
11364            YYPS->m_lock_type= TL_UNLOCK;
11365            YYPS->m_mdl_type= MDL_EXCLUSIVE;
11366          }
11367          table_list opt_restrict
11368          {}
11369        | DROP INDEX_SYM ident ON table_ident {}
11370          {
11371            LEX *lex=Lex;
11372            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
11373            if (ad == NULL)
11374              MYSQL_YYABORT;
11375            lex->sql_command= SQLCOM_DROP_INDEX;
11376            lex->alter_info.reset();
11377            lex->alter_info.flags= Alter_info::ALTER_DROP_INDEX;
11378            lex->alter_info.drop_list.push_back(ad);
11379            if (!lex->current_select()->add_table_to_list(lex->thd, $5, NULL,
11380                                                        TL_OPTION_UPDATING,
11381                                                        TL_READ_NO_INSERT,
11382                                                        MDL_SHARED_UPGRADABLE))
11383              MYSQL_YYABORT;
11384          }
11385          opt_index_lock_algorithm {}
11386        | DROP DATABASE if_exists ident
11387          {
11388            LEX *lex=Lex;
11389            lex->sql_command= SQLCOM_DROP_DB;
11390            lex->drop_if_exists=$3;
11391            lex->name= $4;
11392          }
11393        | DROP FUNCTION_SYM if_exists ident '.' ident
11394          {
11395            THD *thd= YYTHD;
11396            LEX *lex= thd->lex;
11397            sp_name *spname;
11398            if ($4.str &&
11399                (check_and_convert_db_name(&$4, FALSE) != IDENT_NAME_OK))
11400               MYSQL_YYABORT;
11401            if (sp_check_name(&$6))
11402               MYSQL_YYABORT;
11403            if (lex->sphead)
11404            {
11405              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
11406              MYSQL_YYABORT;
11407            }
11408            lex->sql_command = SQLCOM_DROP_FUNCTION;
11409            lex->drop_if_exists= $3;
11410            spname= new sp_name(to_lex_cstring($4), $6, true);
11411            if (spname == NULL)
11412              MYSQL_YYABORT;
11413            spname->init_qname(thd);
11414            lex->spname= spname;
11415          }
11416        | DROP FUNCTION_SYM if_exists ident
11417          {
11418            /*
11419              Unlike DROP PROCEDURE, "DROP FUNCTION ident" should work
11420              even if there is no current database. In this case it
11421              applies only to UDF.
11422              Hence we can't merge rules for "DROP FUNCTION ident.ident"
11423              and "DROP FUNCTION ident" into one "DROP FUNCTION sp_name"
11424              rule. sp_name assumes that database name should be always
11425              provided - either explicitly or implicitly.
11426            */
11427            THD *thd= YYTHD;
11428            LEX *lex= thd->lex;
11429            LEX_STRING db= NULL_STR;
11430            sp_name *spname;
11431            if (lex->sphead)
11432            {
11433              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
11434              MYSQL_YYABORT;
11435            }
11436            if (thd->db().str && lex->copy_db_to(&db.str, &db.length))
11437              MYSQL_YYABORT;
11438            if (sp_check_name(&$4))
11439               MYSQL_YYABORT;
11440            lex->sql_command = SQLCOM_DROP_FUNCTION;
11441            lex->drop_if_exists= $3;
11442            spname= new sp_name(to_lex_cstring(db), $4, false);
11443            if (spname == NULL)
11444              MYSQL_YYABORT;
11445            spname->init_qname(thd);
11446            lex->spname= spname;
11447          }
11448        | DROP PROCEDURE_SYM if_exists sp_name
11449          {
11450            LEX *lex=Lex;
11451            if (lex->sphead)
11452            {
11453              my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
11454              MYSQL_YYABORT;
11455            }
11456            lex->sql_command = SQLCOM_DROP_PROCEDURE;
11457            lex->drop_if_exists= $3;
11458            lex->spname= $4;
11459          }
11460        | DROP USER if_exists clear_privileges user_list
11461          {
11462             LEX *lex=Lex;
11463             lex->sql_command= SQLCOM_DROP_USER;
11464             lex->drop_if_exists= $3;
11465          }
11466        | DROP VIEW_SYM if_exists
11467          {
11468            LEX *lex= Lex;
11469            lex->sql_command= SQLCOM_DROP_VIEW;
11470            lex->drop_if_exists= $3;
11471            YYPS->m_lock_type= TL_UNLOCK;
11472            YYPS->m_mdl_type= MDL_EXCLUSIVE;
11473          }
11474          table_list opt_restrict
11475          {}
11476        | DROP EVENT_SYM if_exists sp_name
11477          {
11478            Lex->drop_if_exists= $3;
11479            Lex->spname= $4;
11480            Lex->sql_command = SQLCOM_DROP_EVENT;
11481          }
11482        | DROP TRIGGER_SYM if_exists sp_name
11483          {
11484            LEX *lex= Lex;
11485            lex->sql_command= SQLCOM_DROP_TRIGGER;
11486            lex->drop_if_exists= $3;
11487            lex->spname= $4;
11488          }
11489        | DROP TABLESPACE_SYM tablespace_name drop_ts_options_list
11490          {
11491            LEX *lex= Lex;
11492            lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE;
11493          }
11494        | DROP LOGFILE_SYM GROUP_SYM logfile_group_name drop_ts_options_list
11495          {
11496            LEX *lex= Lex;
11497            lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
11498          }
11499        | DROP SERVER_SYM if_exists ident_or_text
11500          {
11501            Lex->sql_command = SQLCOM_DROP_SERVER;
11502            Lex->m_sql_cmd=
11503              new (YYTHD->mem_root) Sql_cmd_drop_server($4, $3);
11504          }
11505        | DROP COMPRESSION_DICTIONARY_SYM if_exists ident
11506          {
11507            Lex->sql_command= SQLCOM_DROP_COMPRESSION_DICTIONARY;
11508            Lex->drop_if_exists= $3;
11509            Lex->ident= $4;
11510          }
11511        ;
11512
11513table_list:
11514          table_name
11515        | table_list ',' table_name
11516        ;
11517
11518table_name:
11519          table_ident
11520          {
11521            if (!Select->add_table_to_list(YYTHD, $1, NULL,
11522                                           TL_OPTION_UPDATING,
11523                                           YYPS->m_lock_type,
11524                                           YYPS->m_mdl_type))
11525              MYSQL_YYABORT;
11526          }
11527        ;
11528
11529table_alias_ref_list:
11530          table_ident_opt_wild
11531          {
11532            $$.init(YYTHD->mem_root);
11533            if ($$.push_back($1))
11534              MYSQL_YYABORT; // OOM
11535          }
11536        | table_alias_ref_list ',' table_ident_opt_wild
11537          {
11538            $$= $1;
11539            if ($$.push_back($3))
11540              MYSQL_YYABORT; // OOM
11541          }
11542        ;
11543
11544if_exists:
11545          /* empty */ { $$= 0; }
11546        | IF EXISTS { $$= 1; }
11547        ;
11548
11549opt_temporary:
11550          /* empty */ { $$= 0; }
11551        | TEMPORARY   { $$= 1; }
11552        ;
11553
11554drop_ts_options_list:
11555          /* empty */
11556        | drop_ts_options
11557
11558drop_ts_options:
11559          drop_ts_option
11560        | drop_ts_options drop_ts_option
11561        | drop_ts_options_list ',' drop_ts_option
11562        ;
11563
11564drop_ts_option:
11565          opt_ts_engine
11566        | ts_wait
11567
11568/*
11569** Insert : add new data to table
11570*/
11571
11572insert_stmt:
11573          INSERT                       /* #1 */
11574          insert_lock_option           /* #2 */
11575          opt_ignore                   /* #3 */
11576          opt_INTO                     /* #4 */
11577          table_ident                  /* #5 */
11578          opt_use_partition            /* #6 */
11579          insert_from_constructor      /* #7 */
11580          opt_insert_update_list       /* #8 */
11581          {
11582            $$= NEW_PTN PT_insert(false, $1, $2, $3, $5, $6,
11583                                  $7.column_list, $7.row_value_list,
11584                                  NULL,
11585                                  $8.column_list, $8.value_list);
11586          }
11587        | INSERT                       /* #1 */
11588          insert_lock_option           /* #2 */
11589          opt_ignore                   /* #3 */
11590          opt_INTO                     /* #4 */
11591          table_ident                  /* #5 */
11592          opt_use_partition            /* #6 */
11593          SET                          /* #7 */
11594          update_list                  /* #8 */
11595          opt_insert_update_list       /* #9 */
11596          {
11597            PT_insert_values_list *one_row= NEW_PTN PT_insert_values_list;
11598            if (one_row == NULL || one_row->push_back(&$8.value_list->value))
11599              MYSQL_YYABORT; // OOM
11600            $$= NEW_PTN PT_insert(false, $1, $2, $3, $5, $6,
11601                                  $8.column_list, one_row,
11602                                  NULL,
11603                                  $9.column_list, $9.value_list);
11604          }
11605        | INSERT                       /* #1 */
11606          insert_lock_option           /* #2 */
11607          opt_ignore                   /* #3 */
11608          opt_INTO                     /* #4 */
11609          table_ident                  /* #5 */
11610          opt_use_partition            /* #6 */
11611          insert_from_subquery         /* #7 */
11612          opt_insert_update_list       /* #8 */
11613          {
11614            $$= NEW_PTN PT_insert(false, $1, $2, $3, $5, $6,
11615                                  $7.column_list, NULL,
11616                                  $7.insert_query_expression,
11617                                  $8.column_list, $8.value_list);
11618          }
11619        ;
11620
11621replace_stmt:
11622          REPLACE                       /* #1 */
11623          replace_lock_option           /* #2 */
11624          opt_INTO                      /* #3 */
11625          table_ident                   /* #4 */
11626          opt_use_partition             /* #5 */
11627          insert_from_constructor       /* #6 */
11628          {
11629            $$= NEW_PTN PT_insert(true, $1, $2, false, $4, $5,
11630                                  $6.column_list, $6.row_value_list,
11631                                  NULL,
11632                                  NULL, NULL);
11633          }
11634        | REPLACE                       /* #1 */
11635          replace_lock_option           /* #2 */
11636          opt_INTO                      /* #3 */
11637          table_ident                   /* #4 */
11638          opt_use_partition             /* #5 */
11639          SET                           /* #6 */
11640          update_list                   /* #7 */
11641          {
11642            PT_insert_values_list *one_row= NEW_PTN PT_insert_values_list;
11643            if (one_row == NULL || one_row->push_back(&$7.value_list->value))
11644              MYSQL_YYABORT; // OOM
11645            $$= NEW_PTN PT_insert(true, $1, $2, false, $4, $5,
11646                                  $7.column_list, one_row,
11647                                  NULL,
11648                                  NULL, NULL);
11649          }
11650        | REPLACE                       /* #1 */
11651          replace_lock_option           /* #2 */
11652          opt_INTO                      /* #3 */
11653          table_ident                   /* #4 */
11654          opt_use_partition             /* #5 */
11655          insert_from_subquery          /* #6 */
11656          {
11657            $$= NEW_PTN PT_insert(true, $1, $2, false, $4, $5,
11658                                  $6.column_list, NULL,
11659                                  $6.insert_query_expression,
11660                                  NULL, NULL);
11661          }
11662        ;
11663
11664insert_lock_option:
11665          /* empty */   { $$= TL_WRITE_CONCURRENT_DEFAULT; }
11666        | LOW_PRIORITY  { $$= TL_WRITE_LOW_PRIORITY; }
11667        | DELAYED_SYM
11668        {
11669          $$= TL_WRITE_CONCURRENT_DEFAULT;
11670
11671          push_warning_printf(YYTHD, Sql_condition::SL_WARNING,
11672                              ER_WARN_LEGACY_SYNTAX_CONVERTED,
11673                              ER(ER_WARN_LEGACY_SYNTAX_CONVERTED),
11674                              "INSERT DELAYED", "INSERT");
11675        }
11676        | HIGH_PRIORITY { $$= TL_WRITE; }
11677        ;
11678
11679replace_lock_option:
11680          opt_low_priority { $$= $1; }
11681        | DELAYED_SYM
11682        {
11683          $$= TL_WRITE_DEFAULT;
11684
11685          push_warning_printf(YYTHD, Sql_condition::SL_WARNING,
11686                              ER_WARN_LEGACY_SYNTAX_CONVERTED,
11687                              ER(ER_WARN_LEGACY_SYNTAX_CONVERTED),
11688                              "REPLACE DELAYED", "REPLACE");
11689        }
11690        ;
11691
11692opt_INTO:
11693          /* empty */
11694        | INTO
11695        ;
11696
11697insert_from_constructor:
11698          insert_values
11699          {
11700            $$.column_list= NEW_PTN PT_item_list;
11701            $$.row_value_list= $1;
11702          }
11703        | '(' ')' insert_values
11704          {
11705            $$.column_list= NEW_PTN PT_item_list;
11706            $$.row_value_list= $3;
11707          }
11708        | '(' fields ')' insert_values
11709          {
11710            $$.column_list= $2;
11711            $$.row_value_list= $4;
11712          }
11713        ;
11714
11715insert_from_subquery:
11716          insert_query_expression
11717          {
11718            $$.column_list= NEW_PTN PT_item_list;
11719            $$.insert_query_expression= $1;
11720          }
11721        | '(' ')' insert_query_expression
11722          {
11723            $$.column_list= NEW_PTN PT_item_list;
11724            $$.insert_query_expression= $3;
11725          }
11726        | '(' fields ')' insert_query_expression
11727          {
11728            $$.column_list= $2;
11729            $$.insert_query_expression= $4;
11730          }
11731        ;
11732
11733fields:
11734          fields ',' insert_ident
11735          {
11736            if ($$->push_back($3))
11737              MYSQL_YYABORT;
11738            $$= $1;
11739          }
11740        | insert_ident
11741          {
11742            $$= NEW_PTN PT_item_list;
11743            if ($$ == NULL || $$->push_back($1))
11744              MYSQL_YYABORT;
11745          }
11746        ;
11747
11748insert_values:
11749          value_or_values values_list
11750          {
11751            $$= $2;
11752          }
11753        ;
11754
11755insert_query_expression:
11756          create_select opt_union_clause
11757          {
11758            $$= NEW_PTN PT_insert_query_expression(false, $1, $2);
11759          }
11760        | '(' create_select ')' union_opt
11761          {
11762            $$= NEW_PTN PT_insert_query_expression(true, $2, $4);
11763          }
11764        ;
11765
11766value_or_values:
11767          VALUE_SYM
11768        | VALUES
11769        ;
11770
11771values_list:
11772          values_list ','  row_value
11773          {
11774            if ($$->push_back(&$3->value))
11775              MYSQL_YYABORT;
11776          }
11777        | row_value
11778          {
11779            $$= NEW_PTN PT_insert_values_list;
11780            if ($$ == NULL || $$->push_back(&$1->value))
11781              MYSQL_YYABORT;
11782          }
11783        ;
11784
11785
11786equal:
11787          EQ {}
11788        | SET_VAR {}
11789        ;
11790
11791opt_equal:
11792          /* empty */ {}
11793        | equal {}
11794        ;
11795
11796row_value:
11797          '(' opt_values ')' { $$= $2; }
11798        ;
11799
11800opt_values:
11801          /* empty */
11802          {
11803            $$= NEW_PTN PT_item_list;
11804            if ($$ == NULL)
11805              MYSQL_YYABORT;
11806          }
11807        | values
11808        ;
11809
11810values:
11811          values ','  expr_or_default
11812          {
11813            if ($1->push_back($3))
11814              MYSQL_YYABORT;
11815            $$= $1;
11816          }
11817        | expr_or_default
11818          {
11819            $$= NEW_PTN PT_item_list;
11820            if ($$ == NULL || $$->push_back($1))
11821              MYSQL_YYABORT;
11822          }
11823        ;
11824
11825expr_or_default:
11826          expr
11827        | DEFAULT
11828          {
11829            $$= NEW_PTN Item_default_value(@$);
11830          }
11831        ;
11832
11833opt_insert_update_list:
11834          /* empty */
11835          {
11836            $$.value_list= NULL;
11837            $$.column_list= NULL;
11838          }
11839        | ON DUPLICATE_SYM KEY_SYM UPDATE_SYM update_list
11840          {
11841            $$= $5;
11842          }
11843        ;
11844
11845/* Update rows in a table */
11846
11847update_stmt:
11848          UPDATE_SYM            /* #1 */
11849          opt_low_priority      /* #2 */
11850          opt_ignore            /* #3 */
11851          join_table_list       /* #4 */
11852          SET                   /* #5 */
11853          update_list           /* #6 */
11854          opt_where_clause      /* #7 */
11855          opt_order_clause      /* #8 */
11856          opt_simple_limit      /* #9 */
11857          {
11858            $$= NEW_PTN PT_update($1, $2, $3, $4, $6.column_list, $6.value_list,
11859                                  $7, $8, $9);
11860          }
11861        ;
11862
11863update_list:
11864          update_list ',' update_elem
11865          {
11866            $$= $1;
11867            if ($$.column_list->push_back($3.column) ||
11868                $$.value_list->push_back($3.value))
11869              MYSQL_YYABORT; // OOM
11870          }
11871        | update_elem
11872          {
11873            $$.column_list= NEW_PTN PT_item_list;
11874            $$.value_list= NEW_PTN PT_item_list;
11875            if ($$.column_list == NULL || $$.value_list == NULL ||
11876                $$.column_list->push_back($1.column) ||
11877                $$.value_list->push_back($1.value))
11878              MYSQL_YYABORT; // OOM
11879          }
11880        ;
11881
11882update_elem:
11883          simple_ident_nospvar equal expr_or_default
11884          {
11885            $$.column= $1;
11886            $$.value= $3;
11887          }
11888        ;
11889
11890opt_low_priority:
11891          /* empty */ { $$= TL_WRITE_DEFAULT; }
11892        | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
11893        ;
11894
11895/* Delete rows from a table */
11896
11897delete_stmt:
11898          DELETE_SYM
11899          opt_delete_options
11900          FROM
11901          table_ident
11902          opt_use_partition
11903          opt_where_clause
11904          opt_order_clause
11905          opt_simple_limit
11906          {
11907            $$= NEW_PTN PT_delete(YYTHD->mem_root, $1, $2, $4, $5, $6, $7, $8);
11908          }
11909        | DELETE_SYM
11910          opt_delete_options
11911          table_alias_ref_list
11912          FROM
11913          join_table_list
11914          opt_where_clause
11915          {
11916            $$= NEW_PTN PT_delete($1, $2, $3, $5, $6);
11917          }
11918        | DELETE_SYM
11919          opt_delete_options
11920          FROM
11921          table_alias_ref_list
11922          USING
11923          join_table_list
11924          opt_where_clause
11925          {
11926            $$= NEW_PTN PT_delete($1, $2, $4, $6, $7);
11927          }
11928        ;
11929
11930opt_wild:
11931          /* empty */
11932        | '.' '*'
11933        ;
11934
11935opt_delete_options:
11936          /* empty */                          { $$= 0; }
11937        | opt_delete_option opt_delete_options { $$= $1 | $2; }
11938        ;
11939
11940opt_delete_option:
11941          QUICK        { $$= DELETE_QUICK; }
11942        | LOW_PRIORITY { $$= DELETE_LOW_PRIORITY; }
11943        | IGNORE_SYM   { $$= DELETE_IGNORE; }
11944        ;
11945
11946truncate:
11947          TRUNCATE_SYM opt_table_sym
11948          {
11949            LEX* lex= Lex;
11950            lex->sql_command= SQLCOM_TRUNCATE;
11951            lex->alter_info.reset();
11952            YYPS->m_lock_type= TL_WRITE;
11953            YYPS->m_mdl_type= MDL_EXCLUSIVE;
11954          }
11955          table_name
11956          {
11957            THD *thd= YYTHD;
11958            LEX* lex= thd->lex;
11959            assert(!lex->m_sql_cmd);
11960            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
11961            if (lex->m_sql_cmd == NULL)
11962              MYSQL_YYABORT;
11963          }
11964        ;
11965
11966opt_table_sym:
11967          /* empty */
11968        | TABLE_SYM
11969        ;
11970
11971opt_profile_defs:
11972  /* empty */
11973  | profile_defs;
11974
11975profile_defs:
11976  profile_def
11977  | profile_defs ',' profile_def;
11978
11979profile_def:
11980  CPU_SYM
11981    {
11982      Lex->profile_options|= PROFILE_CPU;
11983    }
11984  | MEMORY_SYM
11985    {
11986      Lex->profile_options|= PROFILE_MEMORY;
11987    }
11988  | BLOCK_SYM IO_SYM
11989    {
11990      Lex->profile_options|= PROFILE_BLOCK_IO;
11991    }
11992  | CONTEXT_SYM SWITCHES_SYM
11993    {
11994      Lex->profile_options|= PROFILE_CONTEXT;
11995    }
11996  | PAGE_SYM FAULTS_SYM
11997    {
11998      Lex->profile_options|= PROFILE_PAGE_FAULTS;
11999    }
12000  | IPC_SYM
12001    {
12002      Lex->profile_options|= PROFILE_IPC;
12003    }
12004  | SWAPS_SYM
12005    {
12006      Lex->profile_options|= PROFILE_SWAPS;
12007    }
12008  | SOURCE_SYM
12009    {
12010      Lex->profile_options|= PROFILE_SOURCE;
12011    }
12012  | ALL
12013    {
12014      Lex->profile_options|= PROFILE_ALL;
12015    }
12016  ;
12017
12018opt_profile_args:
12019  /* empty */
12020    {
12021      Lex->query_id= 0;
12022    }
12023  | FOR_SYM QUERY_SYM NUM
12024    {
12025      int error;
12026      Lex->query_id= static_cast<my_thread_id>(my_strtoll10($3.str, NULL, &error));
12027      if (error != 0)
12028        MYSQL_YYABORT;
12029    }
12030  ;
12031
12032/* Show things */
12033
12034show:
12035          SHOW
12036          {
12037            LEX *lex=Lex;
12038	    new (&lex->create_info) HA_CREATE_INFO;
12039          }
12040          show_param
12041        ;
12042
12043show_param:
12044           DATABASES opt_wild_or_where
12045           {
12046             LEX *lex= Lex;
12047             lex->sql_command= SQLCOM_SHOW_DATABASES;
12048             if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA))
12049               MYSQL_YYABORT;
12050           }
12051         | opt_full TABLES opt_db opt_wild_or_where
12052           {
12053             LEX *lex= Lex;
12054             lex->sql_command= SQLCOM_SHOW_TABLES;
12055             lex->select_lex->db= $3;
12056             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
12057               MYSQL_YYABORT;
12058           }
12059         | opt_full TRIGGERS_SYM opt_db opt_wild_or_where
12060           {
12061             LEX *lex= Lex;
12062             lex->sql_command= SQLCOM_SHOW_TRIGGERS;
12063             lex->select_lex->db= $3;
12064             if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS))
12065               MYSQL_YYABORT;
12066           }
12067         | EVENTS_SYM opt_db opt_wild_or_where
12068           {
12069             LEX *lex= Lex;
12070             lex->sql_command= SQLCOM_SHOW_EVENTS;
12071             lex->select_lex->db= $2;
12072             if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS))
12073               MYSQL_YYABORT;
12074           }
12075         | TABLE_SYM STATUS_SYM opt_db opt_wild_or_where
12076           {
12077             LEX *lex= Lex;
12078             lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
12079             lex->select_lex->db= $3;
12080             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
12081               MYSQL_YYABORT;
12082           }
12083        | OPEN_SYM TABLES opt_db opt_wild_or_where
12084          {
12085            LEX *lex= Lex;
12086            lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
12087            lex->select_lex->db= $3;
12088            if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
12089              MYSQL_YYABORT;
12090          }
12091        | PLUGINS_SYM
12092          {
12093            LEX *lex= Lex;
12094            lex->sql_command= SQLCOM_SHOW_PLUGINS;
12095            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
12096              MYSQL_YYABORT;
12097          }
12098        | ENGINE_SYM known_storage_engines show_engine_param
12099          { Lex->create_info.db_type= $2; }
12100        | ENGINE_SYM ALL show_engine_param
12101          { Lex->create_info.db_type= NULL; }
12102        | opt_full COLUMNS from_or_in table_ident opt_db opt_wild_or_where
12103          {
12104            LEX *lex= Lex;
12105            lex->sql_command= SQLCOM_SHOW_FIELDS;
12106            if ($5)
12107              $4->change_db($5);
12108            if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS))
12109              MYSQL_YYABORT;
12110          }
12111        | master_or_binary LOGS_SYM
12112          {
12113            Lex->sql_command = SQLCOM_SHOW_BINLOGS;
12114          }
12115        | SLAVE HOSTS_SYM
12116          {
12117            Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
12118          }
12119        | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
12120          {
12121            LEX *lex= Lex;
12122            lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
12123          }
12124          opt_limit_clause
12125          {
12126            if ($6 != NULL)
12127              CONTEXTUALIZE($6);
12128          }
12129        | RELAYLOG_SYM EVENTS_SYM binlog_in binlog_from
12130          {
12131            LEX *lex= Lex;
12132            lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS;
12133          }
12134          opt_limit_clause opt_channel
12135          {
12136            if ($6 != NULL)
12137              CONTEXTUALIZE($6);
12138          }
12139        | keys_or_index         /* #1 */
12140          from_or_in            /* #2 */
12141          table_ident           /* #3 */
12142          opt_db                /* #4 */
12143          opt_where_clause      /* #5 */
12144          {
12145            if ($5 != NULL)
12146              ITEMIZE($5, &$5);
12147            Select->set_where_cond($5);
12148
12149            LEX *lex= Lex;
12150            lex->sql_command= SQLCOM_SHOW_KEYS;
12151            if ($4)
12152              $3->change_db($4);
12153            if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS))
12154              MYSQL_YYABORT;
12155          }
12156        | opt_storage ENGINES_SYM
12157          {
12158            LEX *lex=Lex;
12159            lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
12160            if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
12161              MYSQL_YYABORT;
12162          }
12163        | PRIVILEGES
12164          {
12165            LEX *lex=Lex;
12166            lex->sql_command= SQLCOM_SHOW_PRIVILEGES;
12167          }
12168        | COUNT_SYM '(' '*' ')' WARNINGS
12169          {
12170            Lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // SHOW WARNINGS doesn't clear them.
12171            Parse_context pc(YYTHD, Select);
12172            create_select_for_variable(&pc, "warning_count");
12173          }
12174        | COUNT_SYM '(' '*' ')' ERRORS
12175          {
12176            Lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // SHOW ERRORS doesn't clear them.
12177            Parse_context pc(YYTHD, Select);
12178            create_select_for_variable(&pc, "error_count");
12179          }
12180        | WARNINGS opt_limit_clause
12181          {
12182            if ($2 != NULL)
12183              CONTEXTUALIZE($2);
12184
12185            Lex->sql_command = SQLCOM_SHOW_WARNS;
12186            Lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // SHOW WARNINGS doesn't clear them.
12187          }
12188        | ERRORS opt_limit_clause
12189          {
12190            if ($2 != NULL)
12191              CONTEXTUALIZE($2);
12192
12193            Lex->sql_command = SQLCOM_SHOW_ERRORS;
12194            Lex->keep_diagnostics= DA_KEEP_DIAGNOSTICS; // SHOW ERRORS doesn't clear them.
12195          }
12196        | PROFILES_SYM
12197          {
12198            push_warning_printf(YYTHD, Sql_condition::SL_WARNING,
12199                                ER_WARN_DEPRECATED_SYNTAX,
12200                                ER(ER_WARN_DEPRECATED_SYNTAX),
12201                                "SHOW PROFILES", "Performance Schema");
12202            Lex->sql_command = SQLCOM_SHOW_PROFILES;
12203          }
12204        | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause
12205          {
12206            if ($4 != NULL)
12207              CONTEXTUALIZE($4);
12208
12209            LEX *lex= Lex;
12210            lex->sql_command= SQLCOM_SHOW_PROFILE;
12211            if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
12212              YYABORT;
12213          }
12214        | opt_var_type STATUS_SYM opt_wild_or_where_for_show
12215          {
12216            THD *thd= YYTHD;
12217            LEX *lex= thd->lex;
12218            if (show_compatibility_56)
12219            {
12220              /* 5.6, DEPRECATED */
12221              lex->sql_command= SQLCOM_SHOW_STATUS;
12222              lex->option_type= $1;
12223              if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
12224                MYSQL_YYABORT;
12225            }
12226            else
12227            {
12228              Item *where_cond= Select->where_cond();
12229              Select->set_where_cond(NULL);
12230
12231              if ($1 == OPT_SESSION)
12232              {
12233                /* 5.7, SUPPORTED */
12234                if (build_show_session_status(@$, thd, lex->wild, where_cond) == NULL)
12235                  MYSQL_YYABORT;
12236              }
12237              else
12238              {
12239                /* 5.7, SUPPORTED */
12240                if (build_show_global_status(@$, thd, lex->wild, where_cond) == NULL)
12241                  MYSQL_YYABORT;
12242              }
12243            }
12244          }
12245        | opt_full PROCESSLIST_SYM
12246          { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
12247        | opt_var_type VARIABLES opt_wild_or_where_for_show
12248          {
12249            THD *thd= YYTHD;
12250            LEX *lex= thd->lex;
12251            if (show_compatibility_56)
12252            {
12253              /* 5.6, DEPRECATED */
12254              lex->sql_command= SQLCOM_SHOW_VARIABLES;
12255              lex->option_type= $1;
12256              if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
12257                MYSQL_YYABORT;
12258            }
12259            else
12260            {
12261              Item *where_cond= Select->where_cond();
12262              Select->set_where_cond(NULL);
12263
12264              if ($1 == OPT_SESSION)
12265              {
12266                /* 5.7, SUPPORTED */
12267                if (build_show_session_variables(@$, thd, lex->wild, where_cond) == NULL)
12268                  MYSQL_YYABORT;
12269              }
12270              else
12271              {
12272                /* 5.7, SUPPORTED */
12273                if (build_show_global_variables(@$, thd, lex->wild, where_cond) == NULL)
12274                  MYSQL_YYABORT;
12275              }
12276            }
12277          }
12278        | charset opt_wild_or_where
12279          {
12280            LEX *lex= Lex;
12281            lex->sql_command= SQLCOM_SHOW_CHARSETS;
12282            if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS))
12283              MYSQL_YYABORT;
12284          }
12285        | COLLATION_SYM opt_wild_or_where
12286          {
12287            LEX *lex= Lex;
12288            lex->sql_command= SQLCOM_SHOW_COLLATIONS;
12289            if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS))
12290              MYSQL_YYABORT;
12291          }
12292        | GRANTS
12293          {
12294            LEX *lex=Lex;
12295            lex->sql_command= SQLCOM_SHOW_GRANTS;
12296            LEX_USER *curr_user;
12297            if (!(curr_user= (LEX_USER*) lex->thd->alloc(sizeof(st_lex_user))))
12298              MYSQL_YYABORT;
12299            memset(curr_user, 0, sizeof(st_lex_user));
12300            lex->grant_user= curr_user;
12301          }
12302        | GRANTS FOR_SYM user
12303          {
12304            LEX *lex=Lex;
12305            lex->sql_command= SQLCOM_SHOW_GRANTS;
12306            lex->grant_user=$3;
12307            lex->grant_user->auth= NULL_CSTR;
12308          }
12309        | CREATE DATABASE opt_if_not_exists ident
12310          {
12311            Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
12312            Lex->create_info.options=$3;
12313            Lex->name= $4;
12314          }
12315        | CREATE TABLE_SYM table_ident
12316          {
12317            LEX *lex= Lex;
12318            lex->sql_command = SQLCOM_SHOW_CREATE;
12319            if (!lex->select_lex->add_table_to_list(YYTHD, $3, NULL,0))
12320              MYSQL_YYABORT;
12321            lex->only_view= 0;
12322            lex->create_info.storage_media= HA_SM_DEFAULT;
12323          }
12324        | CREATE VIEW_SYM table_ident
12325          {
12326            LEX *lex= Lex;
12327            lex->sql_command = SQLCOM_SHOW_CREATE;
12328            if (!lex->select_lex->add_table_to_list(YYTHD, $3, NULL, 0))
12329              MYSQL_YYABORT;
12330            lex->only_view= 1;
12331          }
12332        | MASTER_SYM STATUS_SYM
12333          {
12334            Lex->sql_command = SQLCOM_SHOW_MASTER_STAT;
12335          }
12336        | SLAVE STATUS_SYM opt_channel
12337          {
12338            Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
12339          }
12340        | CLIENT_STATS_SYM opt_wild_or_where
12341          {
12342           LEX *lex= Lex;
12343           Lex->sql_command= SQLCOM_SHOW_CLIENT_STATS;
12344           if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
12345             MYSQL_YYABORT;
12346          }
12347        | USER_STATS_SYM opt_wild_or_where
12348          {
12349           LEX *lex= Lex;
12350           lex->sql_command= SQLCOM_SHOW_USER_STATS;
12351           if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
12352             MYSQL_YYABORT;
12353          }
12354        | THREAD_STATS_SYM opt_wild_or_where
12355          {
12356           LEX *lex= Lex;
12357           Lex->sql_command= SQLCOM_SHOW_THREAD_STATS;
12358           if (prepare_schema_table(YYTHD, lex, 0, SCH_THREAD_STATS))
12359             MYSQL_YYABORT;
12360          }
12361        | TABLE_STATS_SYM opt_wild_or_where
12362          {
12363           LEX *lex= Lex;
12364           lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
12365           if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
12366             MYSQL_YYABORT;
12367          }
12368        | INDEX_STATS_SYM opt_wild_or_where
12369          {
12370           LEX *lex= Lex;
12371           lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
12372           if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
12373             MYSQL_YYABORT;
12374          }
12375        | CREATE PROCEDURE_SYM sp_name
12376          {
12377            LEX *lex= Lex;
12378
12379            lex->sql_command = SQLCOM_SHOW_CREATE_PROC;
12380            lex->spname= $3;
12381          }
12382        | CREATE FUNCTION_SYM sp_name
12383          {
12384            LEX *lex= Lex;
12385
12386            lex->sql_command = SQLCOM_SHOW_CREATE_FUNC;
12387            lex->spname= $3;
12388          }
12389        | CREATE TRIGGER_SYM sp_name
12390          {
12391            LEX *lex= Lex;
12392            lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER;
12393            lex->spname= $3;
12394          }
12395        | PROCEDURE_SYM STATUS_SYM opt_wild_or_where
12396          {
12397            LEX *lex= Lex;
12398            lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
12399            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
12400              MYSQL_YYABORT;
12401          }
12402        | FUNCTION_SYM STATUS_SYM opt_wild_or_where
12403          {
12404            LEX *lex= Lex;
12405            lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
12406            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
12407              MYSQL_YYABORT;
12408          }
12409        | PROCEDURE_SYM CODE_SYM sp_name
12410          {
12411            Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
12412            Lex->spname= $3;
12413          }
12414        | FUNCTION_SYM CODE_SYM sp_name
12415          {
12416            Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
12417            Lex->spname= $3;
12418          }
12419        | CREATE EVENT_SYM sp_name
12420          {
12421            Lex->spname= $3;
12422            Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
12423          }
12424        | CREATE USER clear_privileges user
12425          {
12426            LEX *lex=Lex;
12427            lex->sql_command= SQLCOM_SHOW_CREATE_USER;
12428            lex->grant_user=$4;
12429          }
12430        ;
12431
12432show_engine_param:
12433          STATUS_SYM
12434          { Lex->sql_command= SQLCOM_SHOW_ENGINE_STATUS; }
12435        | MUTEX_SYM
12436          { Lex->sql_command= SQLCOM_SHOW_ENGINE_MUTEX; }
12437        | LOGS_SYM
12438          { Lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS; }
12439        ;
12440
12441master_or_binary:
12442          MASTER_SYM
12443        | BINARY
12444        ;
12445
12446opt_storage:
12447          /* empty */
12448        | STORAGE_SYM
12449        ;
12450
12451opt_db:
12452          /* empty */  { $$= 0; }
12453        | from_or_in ident { $$= $2.str; }
12454        ;
12455
12456opt_full:
12457          /* empty */ { Lex->verbose=0; }
12458        | FULL        { Lex->verbose=1; }
12459        ;
12460
12461from_or_in:
12462          FROM
12463        | IN_SYM
12464        ;
12465
12466binlog_in:
12467          /* empty */            { Lex->mi.log_file_name = 0; }
12468        | IN_SYM TEXT_STRING_sys { Lex->mi.log_file_name = $2.str; }
12469        ;
12470
12471binlog_from:
12472          /* empty */        { Lex->mi.pos = 4; /* skip magic number */ }
12473        | FROM ulonglong_num { Lex->mi.pos = $2; }
12474        ;
12475
12476opt_wild_or_where:
12477          /* empty */
12478        | LIKE TEXT_STRING_sys
12479          {
12480            Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
12481                                                    system_charset_info);
12482            if (Lex->wild == NULL)
12483              MYSQL_YYABORT;
12484          }
12485        | WHERE expr
12486          {
12487            ITEMIZE($2, &$2);
12488
12489            Select->set_where_cond($2);
12490            if ($2)
12491              $2->top_level_item();
12492          }
12493        ;
12494
12495opt_wild_or_where_for_show:
12496          /* empty */
12497        | LIKE TEXT_STRING_sys
12498          {
12499            Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
12500                                                    system_charset_info);
12501            if (Lex->wild == NULL)
12502              MYSQL_YYABORT;
12503          }
12504        | WHERE expr
12505          {
12506            if (show_compatibility_56)
12507            {
12508              /*
12509                This parsed tree fragment is added as part of a
12510                SQLCOM_SHOW_STATUS or SQLCOM_SHOW_VARIABLES command.
12511              */
12512              ITEMIZE($2, &$2);
12513
12514              Select->set_where_cond($2);
12515              if ($2)
12516                $2->top_level_item();
12517            }
12518            else
12519            {
12520              /*
12521                This parsed tree fragment is used to build a
12522                SQLCOM_SELECT statement, see sql/sql_show_status.cc
12523              */
12524              Select->set_where_cond($2);
12525            }
12526          }
12527        ;
12528
12529/* A Oracle compatible synonym for show */
12530describe:
12531          describe_command table_ident
12532          {
12533            LEX *lex= Lex;
12534            lex->current_select()->parsing_place= CTX_SELECT_LIST;
12535            lex->sql_command= SQLCOM_SHOW_FIELDS;
12536            lex->select_lex->db= NULL;
12537            lex->verbose= 0;
12538            if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
12539              MYSQL_YYABORT;
12540          }
12541          opt_describe_column
12542          {
12543            // Ensure we're resetting parsing context of the right select
12544            assert(Select->parsing_place == CTX_SELECT_LIST);
12545            Select->parsing_place= CTX_NONE;
12546          }
12547        | describe_command opt_extended_describe
12548          {
12549            Lex->describe|= DESCRIBE_NORMAL;
12550          }
12551          explainable_command
12552        ;
12553
12554explainable_command:
12555          select  { CONTEXTUALIZE($1); }
12556        | insert_stmt                           { MAKE_CMD($1); }
12557        | replace_stmt                          { MAKE_CMD($1); }
12558        | update_stmt                           { MAKE_CMD($1); }
12559        | delete_stmt                           { MAKE_CMD($1); }
12560        | FOR_SYM CONNECTION_SYM real_ulong_num
12561          {
12562            Lex->sql_command= SQLCOM_EXPLAIN_OTHER;
12563            if (Lex->sphead)
12564            {
12565              my_error(ER_NOT_SUPPORTED_YET, MYF(0),
12566                       "non-standalone EXPLAIN FOR CONNECTION");
12567              MYSQL_YYABORT;
12568            }
12569            Lex->query_id= (my_thread_id)($3);
12570          }
12571        ;
12572
12573describe_command:
12574          DESC
12575        | DESCRIBE
12576        ;
12577
12578opt_extended_describe:
12579          /* empty */
12580          {
12581            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
12582              MYSQL_YYABORT;
12583          }
12584        | EXTENDED_SYM
12585          {
12586            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
12587              MYSQL_YYABORT;
12588            push_deprecated_warn_no_replacement(YYTHD, "EXTENDED");
12589          }
12590        | PARTITIONS_SYM
12591          {
12592            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
12593              MYSQL_YYABORT;
12594            push_deprecated_warn_no_replacement(YYTHD, "PARTITIONS");
12595          }
12596        | FORMAT_SYM EQ ident_or_text
12597          {
12598            if (!my_strcasecmp(system_charset_info, $3.str, "JSON"))
12599            {
12600              if ((Lex->explain_format= new Explain_format_JSON) == NULL)
12601                MYSQL_YYABORT;
12602            }
12603            else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL"))
12604            {
12605              if ((Lex->explain_format= new Explain_format_traditional) == NULL)
12606                MYSQL_YYABORT;
12607            }
12608            else
12609            {
12610              my_error(ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), $3.str);
12611              MYSQL_YYABORT;
12612            }
12613          }
12614        ;
12615
12616opt_describe_column:
12617          /* empty */ {}
12618        | text_string { Lex->wild= $1; }
12619        | ident
12620          {
12621            Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,
12622                                                    $1.length,
12623                                                    system_charset_info);
12624            if (Lex->wild == NULL)
12625              MYSQL_YYABORT;
12626          }
12627        ;
12628
12629
12630/* flush things */
12631
12632flush:
12633          FLUSH_SYM opt_no_write_to_binlog
12634          {
12635            LEX *lex=Lex;
12636            lex->sql_command= SQLCOM_FLUSH;
12637            lex->type= 0;
12638            lex->no_write_to_binlog= $2;
12639          }
12640          flush_options
12641          {}
12642        ;
12643
12644flush_options:
12645          table_or_tables
12646          {
12647            Lex->type|= REFRESH_TABLES;
12648            /*
12649              Set type of metadata and table locks for
12650              FLUSH TABLES table_list [WITH READ LOCK].
12651            */
12652            YYPS->m_lock_type= TL_READ_NO_INSERT;
12653            YYPS->m_mdl_type= MDL_SHARED_HIGH_PRIO;
12654          }
12655          opt_table_list {}
12656          opt_flush_lock {}
12657        | flush_options_list
12658        ;
12659
12660opt_flush_lock:
12661          /* empty */ {}
12662        | WITH READ_SYM LOCK_SYM
12663          {
12664            TABLE_LIST *tables= Lex->query_tables;
12665            Lex->type|= REFRESH_READ_LOCK;
12666            for (; tables; tables= tables->next_global)
12667            {
12668              tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
12669              tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
12670              tables->open_type= OT_BASE_ONLY;      /* Ignore temporary tables. */
12671            }
12672          }
12673        | FOR_SYM
12674          {
12675            if (Lex->query_tables == NULL) // Table list can't be empty
12676            {
12677              my_syntax_error(ER(ER_NO_TABLES_USED));
12678              MYSQL_YYABORT;
12679            }
12680          }
12681          EXPORT_SYM
12682          {
12683            TABLE_LIST *tables= Lex->query_tables;
12684            Lex->type|= REFRESH_FOR_EXPORT;
12685            for (; tables; tables= tables->next_global)
12686            {
12687              tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
12688              tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
12689              tables->open_type= OT_BASE_ONLY;      /* Ignore temporary tables. */
12690            }
12691          }
12692        ;
12693
12694flush_options_list:
12695          flush_options_list ',' flush_option
12696        | flush_option
12697          {}
12698        ;
12699
12700flush_option:
12701          ERROR_SYM LOGS_SYM
12702          { Lex->type|= REFRESH_ERROR_LOG; }
12703        | ENGINE_SYM LOGS_SYM
12704          { Lex->type|= REFRESH_ENGINE_LOG; }
12705        | GENERAL LOGS_SYM
12706          { Lex->type|= REFRESH_GENERAL_LOG; }
12707        | SLOW LOGS_SYM
12708          { Lex->type|= REFRESH_SLOW_LOG; }
12709        | BINARY LOGS_SYM
12710          { Lex->type|= REFRESH_BINARY_LOG; }
12711        | RELAY LOGS_SYM opt_channel
12712          { Lex->type|= REFRESH_RELAY_LOG; }
12713        | QUERY_SYM CACHE_SYM
12714          {
12715            push_deprecated_warn_no_replacement(YYTHD, "FLUSH QUERY CACHE");
12716            Lex->type|= REFRESH_QUERY_CACHE_FREE;
12717          }
12718        | HOSTS_SYM
12719          { Lex->type|= REFRESH_HOSTS; }
12720        | PRIVILEGES
12721          { Lex->type|= REFRESH_GRANT; }
12722        | LOGS_SYM
12723          { Lex->type|= REFRESH_LOG; }
12724        | STATUS_SYM
12725          { Lex->type|= REFRESH_STATUS; }
12726        | CLIENT_STATS_SYM
12727          { Lex->type|= REFRESH_CLIENT_STATS; }
12728        | USER_STATS_SYM
12729          { Lex->type|= REFRESH_USER_STATS; }
12730        | THREAD_STATS_SYM
12731          { Lex->type|= REFRESH_THREAD_STATS; }
12732        | TABLE_STATS_SYM
12733          { Lex->type|= REFRESH_TABLE_STATS; }
12734        | INDEX_STATS_SYM
12735          { Lex->type|= REFRESH_INDEX_STATS; }
12736        | DES_KEY_FILE
12737          { Lex->type|= REFRESH_DES_KEY_FILE; }
12738        | RESOURCES
12739          { Lex->type|= REFRESH_USER_RESOURCES; }
12740        | OPTIMIZER_COSTS_SYM
12741          { Lex->type|= REFRESH_OPTIMIZER_COSTS; }
12742        | CHANGED_PAGE_BITMAPS_SYM
12743          { Lex->type|= REFRESH_FLUSH_PAGE_BITMAPS; }
12744        ;
12745
12746opt_table_list:
12747          /* empty */  {}
12748        | table_list {}
12749        ;
12750
12751reset:
12752          RESET_SYM
12753          {
12754            LEX *lex=Lex;
12755            lex->sql_command= SQLCOM_RESET; lex->type=0;
12756          }
12757          reset_options
12758          {}
12759        ;
12760
12761reset_options:
12762          reset_options ',' reset_option
12763        | reset_option
12764        ;
12765
12766reset_option:
12767          SLAVE               { Lex->type|= REFRESH_SLAVE; }
12768          slave_reset_options opt_channel
12769        | MASTER_SYM          { Lex->type|= REFRESH_MASTER; }
12770        | QUERY_SYM CACHE_SYM
12771          {
12772            push_deprecated_warn_no_replacement(YYTHD, "RESET QUERY CACHE");
12773            Lex->type|= REFRESH_QUERY_CACHE;
12774          }
12775        | CHANGED_PAGE_BITMAPS_SYM
12776          { Lex->type |= REFRESH_RESET_PAGE_BITMAPS; }
12777        ;
12778
12779slave_reset_options:
12780          /* empty */ { Lex->reset_slave_info.all= false; }
12781        | ALL         { Lex->reset_slave_info.all= true; }
12782        ;
12783
12784purge:
12785          PURGE
12786          {
12787            LEX *lex=Lex;
12788            lex->type=0;
12789            lex->sql_command = SQLCOM_PURGE;
12790          }
12791          purge_options
12792          {}
12793        ;
12794
12795purge_options:
12796          master_or_binary LOGS_SYM purge_option
12797        | CHANGED_PAGE_BITMAPS_SYM BEFORE_SYM real_ulonglong_num
12798          {
12799            LEX *lex= Lex;
12800            lex->purge_value_list.empty();
12801            lex->purge_value_list.push_front(new Item_uint($3));
12802            lex->type= PURGE_BITMAPS_TO_LSN;
12803          }
12804        ;
12805
12806purge_option:
12807          TO_SYM TEXT_STRING_sys
12808          {
12809            Lex->to_log = $2.str;
12810          }
12811        | BEFORE_SYM expr
12812          {
12813            ITEMIZE($2, &$2);
12814
12815            LEX *lex= Lex;
12816            lex->purge_value_list.empty();
12817            lex->purge_value_list.push_front($2);
12818            lex->sql_command= SQLCOM_PURGE_BEFORE;
12819          }
12820        ;
12821
12822/* kill threads */
12823
12824kill:
12825          KILL_SYM kill_option expr
12826          {
12827            ITEMIZE($3, &$3);
12828
12829            LEX *lex=Lex;
12830            lex->kill_value_list.empty();
12831            lex->kill_value_list.push_front($3);
12832            lex->sql_command= SQLCOM_KILL;
12833          }
12834        ;
12835
12836kill_option:
12837          /* empty */ { Lex->type= 0; }
12838        | CONNECTION_SYM { Lex->type= 0; }
12839        | QUERY_SYM      { Lex->type= ONLY_KILL_QUERY; }
12840        ;
12841
12842/* change database */
12843
12844use:
12845          USE_SYM ident
12846          {
12847            LEX *lex=Lex;
12848            lex->sql_command=SQLCOM_CHANGE_DB;
12849            lex->select_lex->db= $2.str;
12850          }
12851        ;
12852
12853/* import, export of files */
12854
12855load:
12856          LOAD data_or_xml
12857          {
12858            THD *thd= YYTHD;
12859            LEX *lex= thd->lex;
12860
12861            if (lex->sphead)
12862            {
12863              my_error(ER_SP_BADSTATEMENT, MYF(0),
12864                       $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
12865              MYSQL_YYABORT;
12866            }
12867          }
12868          load_data_lock opt_local INFILE TEXT_STRING_filesystem
12869          {
12870            LEX *lex=Lex;
12871            lex->sql_command= SQLCOM_LOAD;
12872            lex->local_file=  $5;
12873            lex->duplicates= DUP_ERROR;
12874            lex->set_ignore(false);
12875            if (!(lex->exchange= new sql_exchange($7.str, 0, $2)))
12876              MYSQL_YYABORT;
12877          }
12878          opt_duplicate INTO TABLE_SYM table_ident opt_use_partition
12879          {
12880            LEX *lex=Lex;
12881            /* Fix lock for LOAD DATA CONCURRENT REPLACE */
12882            if (lex->duplicates == DUP_REPLACE && $4 == TL_WRITE_CONCURRENT_INSERT)
12883              $4= TL_WRITE_DEFAULT;
12884            if (!Select->add_table_to_list(YYTHD, $12, NULL, TL_OPTION_UPDATING,
12885                                           $4, $4 == TL_WRITE_LOW_PRIORITY ?
12886                                               MDL_SHARED_WRITE_LOW_PRIO :
12887                                               MDL_SHARED_WRITE, NULL, $13))
12888              MYSQL_YYABORT;
12889            lex->load_field_list.empty();
12890            lex->load_update_list.empty();
12891            lex->load_value_list.empty();
12892            /* We can't give an error in the middle when using LOCAL files */
12893            if (lex->local_file && lex->duplicates == DUP_ERROR)
12894              lex->set_ignore(true);
12895          }
12896          opt_load_data_charset
12897          { Lex->exchange->cs= $15; }
12898          opt_xml_rows_identified_by
12899          opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
12900          opt_load_data_set_spec
12901          {
12902            Lex->exchange->field.merge_field_separators($18);
12903            Lex->exchange->line.merge_line_separators($19);
12904          }
12905          ;
12906
12907data_or_xml:
12908        DATA_SYM  { $$= FILETYPE_CSV; }
12909        | XML_SYM { $$= FILETYPE_XML; }
12910        ;
12911
12912opt_local:
12913          /* empty */ { $$=0;}
12914        | LOCAL_SYM { $$=1;}
12915        ;
12916
12917load_data_lock:
12918          /* empty */ { $$= TL_WRITE_DEFAULT; }
12919        | CONCURRENT  { $$= TL_WRITE_CONCURRENT_INSERT; }
12920        | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
12921        ;
12922
12923opt_duplicate:
12924          /* empty */ { Lex->duplicates=DUP_ERROR; }
12925        | REPLACE { Lex->duplicates=DUP_REPLACE; }
12926        | IGNORE_SYM { Lex->set_ignore(true); }
12927        ;
12928
12929opt_field_term:
12930          /* empty */             { $$.cleanup(); }
12931        | COLUMNS field_term_list { $$= $2; }
12932        ;
12933
12934field_term_list:
12935          field_term_list field_term
12936          {
12937            $$= $1;
12938            $$.merge_field_separators($2);
12939          }
12940        | field_term
12941        ;
12942
12943field_term:
12944          TERMINATED BY text_string
12945          {
12946            $$.cleanup();
12947            $$.field_term= $3;
12948          }
12949        | OPTIONALLY ENCLOSED BY text_string
12950          {
12951            $$.cleanup();
12952            $$.enclosed= $4;
12953            $$.opt_enclosed= 1;
12954          }
12955        | ENCLOSED BY text_string
12956          {
12957            $$.cleanup();
12958            $$.enclosed= $3;
12959          }
12960        | ESCAPED BY text_string
12961          {
12962            $$.cleanup();
12963            $$.escaped= $3;
12964          }
12965        ;
12966
12967opt_line_term:
12968          /* empty */          { $$.cleanup(); }
12969        | LINES line_term_list { $$= $2; }
12970        ;
12971
12972line_term_list:
12973          line_term_list line_term
12974          {
12975            $$= $1;
12976            $$.merge_line_separators($2);
12977          }
12978        | line_term
12979        ;
12980
12981line_term:
12982          TERMINATED BY text_string
12983          {
12984            $$.cleanup();
12985            $$.line_term= $3;
12986          }
12987        | STARTING BY text_string
12988          {
12989            $$.cleanup();
12990            $$.line_start= $3;
12991          }
12992        ;
12993
12994opt_xml_rows_identified_by:
12995        /* empty */ { }
12996        | ROWS_SYM IDENTIFIED_SYM BY text_string
12997          { Lex->exchange->line.line_term = $4; };
12998
12999opt_ignore_lines:
13000          /* empty */
13001        | IGNORE_SYM NUM lines_or_rows
13002          {
13003          assert(Lex->exchange != 0);
13004            Lex->exchange->skip_lines= atol($2.str);
13005          }
13006        ;
13007
13008lines_or_rows:
13009        LINES { }
13010
13011        | ROWS_SYM { }
13012        ;
13013
13014opt_field_or_var_spec:
13015          /* empty */ {}
13016        | '(' fields_or_vars ')' {}
13017        | '(' ')' {}
13018        ;
13019
13020fields_or_vars:
13021          fields_or_vars ',' field_or_var
13022          { Lex->load_field_list.push_back($3); }
13023        | field_or_var
13024          { Lex->load_field_list.push_back($1); }
13025        ;
13026
13027field_or_var:
13028          simple_ident_nospvar { ITEMIZE($1, &$$); }
13029        | '@' ident_or_text
13030          {
13031            $$= new (YYTHD->mem_root) Item_user_var_as_out_param($2);
13032            if ($$ == NULL)
13033              MYSQL_YYABORT;
13034          }
13035        ;
13036
13037opt_load_data_set_spec:
13038          /* empty */ {}
13039        | SET load_data_set_list {}
13040        ;
13041
13042load_data_set_list:
13043          load_data_set_list ',' load_data_set_elem
13044        | load_data_set_elem
13045        ;
13046
13047load_data_set_elem:
13048          simple_ident_nospvar equal expr_or_default
13049          {
13050            ITEMIZE($1, &$1);
13051            ITEMIZE($3, &$3);
13052
13053            LEX *lex= Lex;
13054            uint length= (uint) (@3.cpp.end - @2.cpp.start);
13055            String *val= new (YYTHD->mem_root) String(@2.cpp.start,
13056                                                      length,
13057                                                      YYTHD->charset());
13058            if (val == NULL)
13059              MYSQL_YYABORT;
13060            if (lex->load_update_list.push_back($1) ||
13061                lex->load_value_list.push_back($3) ||
13062                lex->load_set_str_list.push_back(val))
13063                MYSQL_YYABORT;
13064            $3->item_name.copy(@2.cpp.start, length, YYTHD->charset());
13065          }
13066        ;
13067
13068/* Common definitions */
13069
13070text_literal:
13071          TEXT_STRING
13072          {
13073            $$= NEW_PTN PTI_text_literal_text_string(@$,
13074                YYTHD->m_parser_state->m_lip.text_string_is_7bit(), $1);
13075          }
13076        | NCHAR_STRING
13077          {
13078            $$= NEW_PTN PTI_text_literal_nchar_string(@$,
13079                YYTHD->m_parser_state->m_lip.text_string_is_7bit(), $1);
13080          }
13081        | UNDERSCORE_CHARSET TEXT_STRING
13082          {
13083            $$= NEW_PTN PTI_text_literal_underscore_charset(@$,
13084                YYTHD->m_parser_state->m_lip.text_string_is_7bit(), $1, $2);
13085          }
13086        | text_literal TEXT_STRING_literal
13087          {
13088            $$= NEW_PTN PTI_text_literal_concat(@$,
13089                YYTHD->m_parser_state->m_lip.text_string_is_7bit(), $1, $2);
13090          }
13091        ;
13092
13093text_string:
13094          TEXT_STRING_literal
13095          {
13096            $$= new (YYTHD->mem_root) String($1.str,
13097                                             $1.length,
13098                                             YYTHD->variables.collation_connection);
13099            if ($$ == NULL)
13100              MYSQL_YYABORT;
13101          }
13102        | HEX_NUM
13103          {
13104            LEX_STRING s= Item_hex_string::make_hex_str($1.str, $1.length);
13105            $$= new (YYTHD->mem_root) String(s.str, s.length, &my_charset_bin);
13106            if ($$ == NULL)
13107              MYSQL_YYABORT;
13108          }
13109        | BIN_NUM
13110          {
13111            LEX_STRING s= Item_bin_string::make_bin_str($1.str, $1.length);
13112            $$= new (YYTHD->mem_root) String(s.str, s.length, &my_charset_bin);
13113            if ($$ == NULL)
13114              MYSQL_YYABORT;
13115          }
13116        ;
13117
13118param_marker:
13119          PARAM_MARKER
13120          {
13121            $$= NEW_PTN Item_param(@$,
13122                                   (uint) (@1.raw.start - YYLIP->get_buf()));
13123            Lex->param_list.push_back($$);
13124          }
13125        ;
13126
13127signed_literal:
13128          literal { ITEMIZE($1, &$$); }
13129        | '+' NUM_literal { ITEMIZE($2, &$$); }
13130        | '-' NUM_literal
13131          {
13132            ITEMIZE($2, &$2);
13133
13134            $2->max_length++;
13135            $$= ((Item_int *)$2)->neg();
13136          }
13137        ;
13138
13139
13140literal:
13141          text_literal { $$= $1; }
13142        | NUM_literal
13143        | temporal_literal
13144        | NULL_SYM
13145          {
13146            Lex_input_stream *lip= YYLIP;
13147            /*
13148              For the digest computation, in this context only,
13149              NULL is considered a literal, hence reduced to '?'
13150              REDUCE:
13151                TOK_GENERIC_VALUE := NULL_SYM
13152            */
13153            lip->reduce_digest_token(TOK_GENERIC_VALUE, NULL_SYM);
13154            $$= NEW_PTN Item_null(@$);
13155            lip->next_state= MY_LEX_OPERATOR_OR_IDENT;
13156          }
13157        | FALSE_SYM
13158          {
13159            $$= NEW_PTN Item_int(@$, NAME_STRING("FALSE"), 0, 1);
13160          }
13161        | TRUE_SYM
13162          {
13163            $$= NEW_PTN Item_int(@$, NAME_STRING("TRUE"), 1, 1);
13164          }
13165        | HEX_NUM
13166          {
13167            $$= NEW_PTN Item_hex_string(@$, $1);
13168          }
13169        | BIN_NUM
13170          {
13171            $$= NEW_PTN Item_bin_string(@$, $1);
13172          }
13173        | UNDERSCORE_CHARSET HEX_NUM
13174          {
13175            $$= NEW_PTN PTI_literal_underscore_charset_hex_num(@$, $1, $2);
13176          }
13177        | UNDERSCORE_CHARSET BIN_NUM
13178          {
13179            $$= NEW_PTN PTI_literal_underscore_charset_bin_num(@$, $1, $2);
13180          }
13181        ;
13182
13183NUM_literal:
13184          NUM
13185          {
13186            $$= NEW_PTN PTI_num_literal_num(@$, $1);
13187          }
13188        | LONG_NUM
13189          {
13190            $$= NEW_PTN PTI_num_literal_num(@$, $1);
13191          }
13192        | ULONGLONG_NUM
13193          {
13194            $$= NEW_PTN Item_uint(@$, $1.str, $1.length);
13195          }
13196        | DECIMAL_NUM
13197          {
13198            $$= NEW_PTN Item_decimal(@$, $1.str, $1.length, YYCSCL);
13199          }
13200        | FLOAT_NUM
13201          {
13202            $$= NEW_PTN Item_float(@$, $1.str, $1.length);
13203          }
13204        ;
13205
13206
13207temporal_literal:
13208        DATE_SYM TEXT_STRING
13209          {
13210            $$= NEW_PTN PTI_temporal_literal(@$, $2, MYSQL_TYPE_DATE, YYCSCL);
13211          }
13212        | TIME_SYM TEXT_STRING
13213          {
13214            $$= NEW_PTN PTI_temporal_literal(@$, $2, MYSQL_TYPE_TIME, YYCSCL);
13215          }
13216        | TIMESTAMP TEXT_STRING
13217          {
13218            $$= NEW_PTN PTI_temporal_literal(@$, $2, MYSQL_TYPE_DATETIME, YYCSCL);
13219          }
13220        ;
13221
13222
13223
13224
13225/**********************************************************************
13226** Creating different items.
13227**********************************************************************/
13228
13229insert_ident:
13230          simple_ident_nospvar
13231        | table_wild
13232        ;
13233
13234table_wild:
13235          ident '.' '*'
13236          {
13237            $$= NEW_PTN Item_asterisk(@$, NULL, $1.str);
13238          }
13239        | ident '.' ident '.' '*'
13240          {
13241            const char *schema_name = YYCLIENT_NO_SCHEMA ? NULL : $1.str;
13242            $$= NEW_PTN Item_asterisk(@$, schema_name, $3.str);
13243          }
13244        ;
13245
13246order_expr:
13247          expr opt_ordering_direction
13248          {
13249            $$= NEW_PTN PT_order_expr($1, $2);
13250          }
13251        ;
13252
13253grouping_expr:
13254          expr
13255          {
13256            $$= NEW_PTN PT_order_expr($1, 1);
13257          }
13258        | expr ordering_direction
13259          {
13260            push_deprecated_warn(YYTHD, "GROUP BY with ASC/DESC",
13261                                 "GROUP BY ... ORDER BY ... ASC/DESC");
13262            $$= NEW_PTN PT_order_expr($1, $2);
13263          }
13264        ;
13265
13266simple_ident:
13267          ident
13268          {
13269            $$= NEW_PTN PTI_simple_ident_ident(@$, $1);
13270          }
13271        | simple_ident_q
13272        ;
13273
13274simple_ident_nospvar:
13275          ident
13276          {
13277            $$= NEW_PTN PTI_simple_ident_nospvar_ident(@$, $1);
13278          }
13279        | simple_ident_q
13280        ;
13281
13282simple_ident_q:
13283          ident '.' ident
13284          {
13285            $$= NEW_PTN PTI_simple_ident_q_2d(@$, $1.str, $3.str);
13286          }
13287        | '.' ident '.' ident
13288          {
13289            push_deprecated_warn(YYTHD, ".<table>.<column>",
13290                                 "the table.column name without a dot prefix");
13291            $$= NEW_PTN PTI_simple_ident_q_3d(@$, NULL, $2.str, $4.str);
13292          }
13293        | ident '.' ident '.' ident
13294          {
13295            $$= NEW_PTN PTI_simple_ident_q_3d(@$, $1.str, $3.str, $5.str);
13296          }
13297        ;
13298
13299field_ident:
13300          ident { $$=$1;}
13301        | ident '.' ident '.' ident
13302          {
13303            TABLE_LIST *table= Select->table_list.first;
13304            if (my_strcasecmp(table_alias_charset, $1.str, table->db))
13305            {
13306              my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
13307              MYSQL_YYABORT;
13308            }
13309            if (my_strcasecmp(table_alias_charset, $3.str,
13310                              table->table_name))
13311            {
13312              my_error(ER_WRONG_TABLE_NAME, MYF(0), $3.str);
13313              MYSQL_YYABORT;
13314            }
13315            $$=$5;
13316          }
13317        | ident '.' ident
13318          {
13319            TABLE_LIST *table= Select->table_list.first;
13320            if (my_strcasecmp(table_alias_charset, $1.str, table->alias))
13321            {
13322              my_error(ER_WRONG_TABLE_NAME, MYF(0), $1.str);
13323              MYSQL_YYABORT;
13324            }
13325            $$=$3;
13326          }
13327        | '.' ident /* For Delphi */
13328          {
13329            push_deprecated_warn(YYTHD, ".<column>", "the column name without a dot prefix");
13330            $$=$2;
13331          }
13332        ;
13333
13334table_ident:
13335          ident
13336          {
13337            $$= NEW_PTN Table_ident(to_lex_cstring($1));
13338            if ($$ == NULL)
13339              MYSQL_YYABORT;
13340          }
13341        | ident '.' ident
13342          {
13343            LEX_CSTRING schema_name= YYCLIENT_NO_SCHEMA ? LEX_CSTRING()
13344                                                        : to_lex_cstring($1);
13345            $$= NEW_PTN Table_ident(schema_name, to_lex_cstring($3));
13346            if ($$ == NULL)
13347              MYSQL_YYABORT;
13348          }
13349        | '.' ident
13350          {
13351            /* For Delphi */
13352            push_deprecated_warn(YYTHD, ".<table>", "the table name without a dot prefix");
13353            $$= NEW_PTN Table_ident(to_lex_cstring($2));
13354            if ($$ == NULL)
13355              MYSQL_YYABORT;
13356          }
13357        ;
13358
13359table_ident_opt_wild:
13360          ident opt_wild
13361          {
13362            $$= NEW_PTN Table_ident(to_lex_cstring($1));
13363            if ($$ == NULL)
13364              MYSQL_YYABORT;
13365          }
13366        | ident '.' ident opt_wild
13367          {
13368            $$= NEW_PTN Table_ident(YYTHD, to_lex_cstring($1),
13369                                    to_lex_cstring($3), 0);
13370            if ($$ == NULL)
13371              MYSQL_YYABORT;
13372          }
13373        ;
13374
13375table_ident_nodb:
13376          ident
13377          {
13378            LEX_CSTRING db= { any_db, strlen(any_db) };
13379            $$= new Table_ident(YYTHD, db, to_lex_cstring($1), 0);
13380            if ($$ == NULL)
13381              MYSQL_YYABORT;
13382          }
13383        ;
13384
13385IDENT_sys:
13386          IDENT { $$= $1; }
13387        | IDENT_QUOTED
13388          {
13389            THD *thd= YYTHD;
13390
13391            if (thd->charset_is_system_charset)
13392            {
13393              const CHARSET_INFO *cs= system_charset_info;
13394              int dummy_error;
13395              size_t wlen= cs->cset->well_formed_len(cs, $1.str,
13396                                                     $1.str+$1.length,
13397                                                     $1.length, &dummy_error);
13398              if (wlen < $1.length)
13399              {
13400                ErrConvString err($1.str, $1.length, &my_charset_bin);
13401                my_error(ER_INVALID_CHARACTER_STRING, MYF(0),
13402                         cs->csname, err.ptr());
13403                MYSQL_YYABORT;
13404              }
13405              $$= $1;
13406            }
13407            else
13408            {
13409              if (thd->convert_string(&$$, system_charset_info,
13410                                  $1.str, $1.length, thd->charset()))
13411                MYSQL_YYABORT;
13412            }
13413          }
13414        ;
13415
13416TEXT_STRING_sys_nonewline:
13417          TEXT_STRING_sys
13418          {
13419            if (!strcont($1.str, "\n"))
13420              $$= $1;
13421            else
13422            {
13423              my_error(ER_WRONG_VALUE, MYF(0), "argument contains not-allowed LF", $1.str);
13424              MYSQL_YYABORT;
13425            }
13426          }
13427        ;
13428
13429filter_wild_db_table_string:
13430          TEXT_STRING_sys_nonewline
13431          {
13432            if (strcont($1.str, "."))
13433              $$= $1;
13434            else
13435            {
13436              my_error(ER_INVALID_RPL_WILD_TABLE_FILTER_PATTERN, MYF(0));
13437              MYSQL_YYABORT;
13438            }
13439          }
13440        ;
13441
13442TEXT_STRING_sys:
13443          TEXT_STRING
13444          {
13445            THD *thd= YYTHD;
13446
13447            if (thd->charset_is_system_charset)
13448              $$= $1;
13449            else
13450            {
13451              if (thd->convert_string(&$$, system_charset_info,
13452                                  $1.str, $1.length, thd->charset()))
13453                MYSQL_YYABORT;
13454            }
13455          }
13456        ;
13457
13458TEXT_STRING_literal:
13459          TEXT_STRING
13460          {
13461            THD *thd= YYTHD;
13462
13463            if (thd->charset_is_collation_connection)
13464              $$= $1;
13465            else
13466            {
13467              if (thd->convert_string(&$$, thd->variables.collation_connection,
13468                                  $1.str, $1.length, thd->charset()))
13469                MYSQL_YYABORT;
13470            }
13471          }
13472        ;
13473
13474TEXT_STRING_filesystem:
13475          TEXT_STRING
13476          {
13477            THD *thd= YYTHD;
13478
13479            if (thd->charset_is_character_set_filesystem)
13480              $$= $1;
13481            else
13482            {
13483              if (thd->convert_string(&$$,
13484                                      thd->variables.character_set_filesystem,
13485                                      $1.str, $1.length, thd->charset()))
13486                MYSQL_YYABORT;
13487            }
13488          }
13489        ;
13490
13491ident:
13492          IDENT_sys    { $$=$1; }
13493        | keyword
13494          {
13495            THD *thd= YYTHD;
13496            $$.str= thd->strmake($1.str, $1.length);
13497            if ($$.str == NULL)
13498              MYSQL_YYABORT;
13499            $$.length= $1.length;
13500          }
13501        ;
13502
13503label_ident:
13504          IDENT_sys    { $$=$1; }
13505        | keyword_sp
13506          {
13507            THD *thd= YYTHD;
13508            $$.str= thd->strmake($1.str, $1.length);
13509            if ($$.str == NULL)
13510              MYSQL_YYABORT;
13511            $$.length= $1.length;
13512          }
13513        ;
13514
13515ident_or_text:
13516          ident           { $$=$1;}
13517        | TEXT_STRING_sys { $$=$1;}
13518        | LEX_HOSTNAME { $$=$1;}
13519        ;
13520
13521user:
13522          ident_or_text
13523          {
13524            THD *thd= YYTHD;
13525            if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
13526              MYSQL_YYABORT;
13527
13528            /*
13529              Trim whitespace as the values will go to a CHAR field
13530              when stored.
13531            */
13532            trim_whitespace(system_charset_info, &$1);
13533
13534            $$->user.str= $1.str;
13535            $$->user.length= $1.length;
13536            $$->host.str= "%";
13537            $$->host.length= 1;
13538            $$->plugin= EMPTY_CSTR;
13539            $$->auth= NULL_CSTR;
13540            $$->uses_identified_by_clause= false;
13541            $$->uses_identified_with_clause= false;
13542            $$->uses_identified_by_password_clause= false;
13543            $$->uses_authentication_string_clause= false;
13544
13545            if (check_string_char_length($$->user, ER(ER_USERNAME),
13546                                         USERNAME_CHAR_LENGTH,
13547                                         system_charset_info, 0))
13548              MYSQL_YYABORT;
13549          }
13550        | ident_or_text '@' ident_or_text
13551          {
13552            THD *thd= YYTHD;
13553            if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
13554              MYSQL_YYABORT;
13555
13556            /*
13557              Trim whitespace as the values will go to a CHAR field
13558              when stored.
13559            */
13560            trim_whitespace(system_charset_info, &$1);
13561            trim_whitespace(system_charset_info, &$3);
13562
13563            $$->user.str= $1.str;
13564            $$->user.length= $1.length;
13565            $$->host.str= $3.str;
13566            $$->host.length= $3.length;
13567            $$->plugin= EMPTY_CSTR;
13568            $$->auth= NULL_CSTR;
13569            $$->uses_identified_by_clause= false;
13570            $$->uses_identified_with_clause= false;
13571            $$->uses_identified_by_password_clause= false;
13572            $$->uses_authentication_string_clause= false;
13573
13574            if (check_string_char_length($$->user, ER(ER_USERNAME),
13575                                         USERNAME_CHAR_LENGTH,
13576                                         system_charset_info, 0) ||
13577                check_host_name($$->host))
13578              MYSQL_YYABORT;
13579            /*
13580              Convert hostname part of username to lowercase.
13581              It's OK to use in-place lowercase as long as
13582              the character set is utf8.
13583            */
13584            my_casedn_str(system_charset_info, $3.str);
13585            $$->host.str= $3.str;
13586          }
13587        | CURRENT_USER optional_braces
13588          {
13589            if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
13590              MYSQL_YYABORT;
13591            /*
13592              empty LEX_USER means current_user and
13593              will be handled in the  get_current_user() function
13594              later
13595            */
13596            memset($$, 0, sizeof(LEX_USER));
13597          }
13598        ;
13599
13600/* Keyword that we allow for identifiers (except SP labels) */
13601keyword:
13602          keyword_sp            {}
13603        | ACCOUNT_SYM           {}
13604        | ASCII_SYM             {}
13605        | ALWAYS_SYM            {}
13606        | BACKUP_SYM            {}
13607        | BEGIN_SYM             {}
13608        | BYTE_SYM              {}
13609        | CACHE_SYM             {}
13610        | CHARSET               {}
13611        | CHECKSUM_SYM          {}
13612        | CLOSE_SYM             {}
13613        | COMMENT_SYM           {}
13614        | COMMIT_SYM            {}
13615        | CONTAINS_SYM          {}
13616        | DEALLOCATE_SYM        {}
13617        | DO_SYM                {}
13618        | END                   {}
13619        | EXECUTE_SYM           {}
13620        | FLUSH_SYM             {}
13621        | FOLLOWS_SYM           {}
13622        | FORMAT_SYM            {}
13623        | GROUP_REPLICATION     {}
13624        | HANDLER_SYM           {}
13625        | HELP_SYM              {}
13626        | HOST_SYM              {}
13627        | INSTALL_SYM           {}
13628        | LANGUAGE_SYM          {}
13629        | NO_SYM                {}
13630        | OPEN_SYM              {}
13631        | OPTIONS_SYM           {}
13632        | OWNER_SYM             {}
13633        | PARSER_SYM            {}
13634        | PARSE_GCOL_EXPR_SYM   {}
13635        | PORT_SYM              {}
13636        | PRECEDES_SYM          {}
13637        | PREPARE_SYM           {}
13638        | REMOVE_SYM            {}
13639        | REPAIR                {}
13640        | RESET_SYM             {}
13641        | RESTORE_SYM           {}
13642        | ROLLBACK_SYM          {}
13643        | SAVEPOINT_SYM         {}
13644        | SECURITY_SYM          {}
13645        | SERVER_SYM            {}
13646        | SHUTDOWN              {}
13647        | SIGNED_SYM            {}
13648        | SOCKET_SYM            {}
13649        | SLAVE                 {}
13650        | SONAME_SYM            {}
13651        | START_SYM             {}
13652        | STOP_SYM              {}
13653        | TRUNCATE_SYM          {}
13654        | UNICODE_SYM           {}
13655        | UNINSTALL_SYM         {}
13656        | WRAPPER_SYM           {}
13657        | XA_SYM                {}
13658        | UPGRADE_SYM           {}
13659        ;
13660
13661/*
13662 * Keywords that we allow for labels in SPs.
13663 * Anything that's the beginning of a statement or characteristics
13664 * must be in keyword above, otherwise we get (harmful) shift/reduce
13665 * conflicts.
13666 */
13667keyword_sp:
13668          ACTION                   {}
13669        | ADDDATE_SYM              {}
13670        | AFTER_SYM                {}
13671        | AGAINST                  {}
13672        | AGGREGATE_SYM            {}
13673        | ALGORITHM_SYM            {}
13674        | ANALYSE_SYM              {}
13675        | ANY_SYM                  {}
13676        | AT_SYM                   {}
13677        | AUTO_INC                 {}
13678        | AUTOEXTEND_SIZE_SYM      {}
13679        | AVG_ROW_LENGTH           {}
13680        | AVG_SYM                  {}
13681        | BINLOG_SYM               {}
13682        | BIT_SYM                  {}
13683        | BLOCK_SYM                {}
13684        | BOOL_SYM                 {}
13685        | BOOLEAN_SYM              {}
13686        | BTREE_SYM                {}
13687        | CASCADED                 {}
13688        | CATALOG_NAME_SYM         {}
13689        | CHAIN_SYM                {}
13690        | CHANGED                  {}
13691        | CHANGED_PAGE_BITMAPS_SYM {}
13692        | CHANNEL_SYM              {}
13693        | CIPHER_SYM               {}
13694        | CLIENT_STATS_SYM         {}
13695        | CLIENT_SYM               {}
13696        | CLASS_ORIGIN_SYM         {}
13697        | COALESCE                 {}
13698        | CODE_SYM                 {}
13699        | COLLATION_SYM            {}
13700        | COLUMN_NAME_SYM          {}
13701        | COLUMN_FORMAT_SYM        {}
13702        | COLUMNS                  {}
13703        | COMMITTED_SYM            {}
13704        | COMPACT_SYM              {}
13705        | COMPLETION_SYM           {}
13706        | COMPRESSED_SYM           {}
13707        | COMPRESSION_DICTIONARY_SYM {}
13708        | COMPRESSION_SYM          {}
13709        | ENCRYPTION_SYM           {}
13710        | ENCRYPTION_KEY_ID_SYM    {}
13711        | CONCURRENT               {}
13712        | CONNECTION_SYM           {}
13713        | CONSISTENT_SYM           {}
13714        | CONSTRAINT_CATALOG_SYM   {}
13715        | CONSTRAINT_SCHEMA_SYM    {}
13716        | CONSTRAINT_NAME_SYM      {}
13717        | CONTEXT_SYM              {}
13718        | CPU_SYM                  {}
13719        | CUBE_SYM                 {}
13720        /*
13721          Although a reserved keyword in SQL:2003 (and :2008),
13722          not reserved in MySQL per WL#2111 specification.
13723        */
13724        | CURRENT_SYM              {}
13725        | CURSOR_NAME_SYM          {}
13726        | DATA_SYM                 {}
13727        | DATAFILE_SYM             {}
13728        | DATETIME                 {}
13729        | DATE_SYM                 {}
13730        | DAY_SYM                  {}
13731        | DEFAULT_AUTH_SYM         {}
13732        | DEFINER_SYM              {}
13733        | DELAY_KEY_WRITE_SYM      {}
13734        | DES_KEY_FILE             {}
13735        | DIAGNOSTICS_SYM          {}
13736        | DIRECTORY_SYM            {}
13737        | DISABLE_SYM              {}
13738        | DISCARD                  {}
13739        | DISK_SYM                 {}
13740        | DUMPFILE                 {}
13741        | DUPLICATE_SYM            {}
13742        | DYNAMIC_SYM              {}
13743        | ENDS_SYM                 {}
13744        | ENUM                     {}
13745        | ENGINE_SYM               {}
13746        | ENGINES_SYM              {}
13747        | ERROR_SYM                {}
13748        | ERRORS                   {}
13749        | ESCAPE_SYM               {}
13750        | EVENT_SYM                {}
13751        | EVENTS_SYM               {}
13752        | EVERY_SYM                {}
13753        | EXCHANGE_SYM             {}
13754        | EXPANSION_SYM            {}
13755        | EXPIRE_SYM               {}
13756        | EXPORT_SYM               {}
13757        | EXTENDED_SYM             {}
13758        | EXTENT_SIZE_SYM          {}
13759        | FAULTS_SYM               {}
13760        | FAST_SYM                 {}
13761        | FOUND_SYM                {}
13762        | ENABLE_SYM               {}
13763        | FULL                     {}
13764        | FILE_SYM                 {}
13765        | FILE_BLOCK_SIZE_SYM      {}
13766        | FILTER_SYM               {}
13767        | FIRST_SYM                {}
13768        | FIXED_SYM                {}
13769        | GENERAL                  {}
13770        | GEOMETRY_SYM             {}
13771        | GEOMETRYCOLLECTION       {}
13772        | GET_FORMAT               {}
13773        | GRANTS                   {}
13774        | GLOBAL_SYM               {}
13775        | HASH_SYM                 {}
13776        | HOSTS_SYM                {}
13777        | HOUR_SYM                 {}
13778        | IDENTIFIED_SYM           {}
13779        | INDEX_STATS_SYM          {}
13780        | IGNORE_SERVER_IDS_SYM    {}
13781        | INVOKER_SYM              {}
13782        | IMPORT                   {}
13783        | INDEXES                  {}
13784        | INITIAL_SIZE_SYM         {}
13785        | INSTANCE_SYM             {}
13786        | IO_SYM                   {}
13787        | IPC_SYM                  {}
13788        | ISOLATION                {}
13789        | ISSUER_SYM               {}
13790        | INSERT_METHOD            {}
13791        | JSON_SYM                 {}
13792        | KEY_BLOCK_SIZE           {}
13793        | LAST_SYM                 {}
13794        | LEAVES                   {}
13795        | LESS_SYM                 {}
13796        | LEVEL_SYM                {}
13797        | LINESTRING               {}
13798        | LIST_SYM                 {}
13799        | LOCAL_SYM                {}
13800        | LOCKS_SYM                {}
13801        | LOGFILE_SYM              {}
13802        | LOGS_SYM                 {}
13803        | MAX_ROWS                 {}
13804        | MASTER_SYM               {}
13805        | MASTER_HEARTBEAT_PERIOD_SYM {}
13806        | MASTER_HOST_SYM          {}
13807        | MASTER_PORT_SYM          {}
13808        | MASTER_LOG_FILE_SYM      {}
13809        | MASTER_LOG_POS_SYM       {}
13810        | MASTER_USER_SYM          {}
13811        | MASTER_PASSWORD_SYM      {}
13812        | MASTER_SERVER_ID_SYM     {}
13813        | MASTER_CONNECT_RETRY_SYM {}
13814        | MASTER_RETRY_COUNT_SYM   {}
13815        | MASTER_DELAY_SYM         {}
13816        | MASTER_SSL_SYM           {}
13817        | MASTER_SSL_CA_SYM        {}
13818        | MASTER_SSL_CAPATH_SYM    {}
13819        | MASTER_TLS_VERSION_SYM   {}
13820        | MASTER_SSL_CERT_SYM      {}
13821        | MASTER_SSL_CIPHER_SYM    {}
13822        | MASTER_SSL_CRL_SYM       {}
13823        | MASTER_SSL_CRLPATH_SYM   {}
13824        | MASTER_SSL_KEY_SYM       {}
13825        | MASTER_AUTO_POSITION_SYM {}
13826        | MAX_CONNECTIONS_PER_HOUR {}
13827        | MAX_QUERIES_PER_HOUR     {}
13828        | MAX_SIZE_SYM             {}
13829        | MAX_UPDATES_PER_HOUR     {}
13830        | MAX_USER_CONNECTIONS_SYM {}
13831        | MEDIUM_SYM               {}
13832        | MEMORY_SYM               {}
13833        | MERGE_SYM                {}
13834        | MESSAGE_TEXT_SYM         {}
13835        | MICROSECOND_SYM          {}
13836        | MIGRATE_SYM              {}
13837        | MINUTE_SYM               {}
13838        | MIN_ROWS                 {}
13839        | MODIFY_SYM               {}
13840        | MODE_SYM                 {}
13841        | MONTH_SYM                {}
13842        | MULTILINESTRING          {}
13843        | MULTIPOINT               {}
13844        | MULTIPOLYGON             {}
13845        | MUTEX_SYM                {}
13846        | MYSQL_ERRNO_SYM          {}
13847        | NAME_SYM                 {}
13848        | NAMES_SYM                {}
13849        | NATIONAL_SYM             {}
13850        | NCHAR_SYM                {}
13851        | NDBCLUSTER_SYM           {}
13852        | NEVER_SYM                {}
13853        | NEXT_SYM                 {}
13854        | NEW_SYM                  {}
13855        | NO_WAIT_SYM              {}
13856        | NODEGROUP_SYM            {}
13857        | NONE_SYM                 {}
13858        | NUMBER_SYM               {}
13859        | NVARCHAR_SYM             {}
13860        | OFFSET_SYM               {}
13861        | ONE_SYM                  {}
13862        | ONLY_SYM                 {}
13863        | PACK_KEYS_SYM            {}
13864        | PAGE_SYM                 {}
13865        | PARTIAL                  {}
13866        | PARTITIONING_SYM         {}
13867        | PARTITIONS_SYM           {}
13868        | PASSWORD                 {}
13869        | PHASE_SYM                {}
13870        | PLUGIN_DIR_SYM           {}
13871        | PLUGIN_SYM               {}
13872        | PLUGINS_SYM              {}
13873        | POINT_SYM                {}
13874        | POLYGON                  {}
13875        | PRESERVE_SYM             {}
13876        | PREV_SYM                 {}
13877        | PRIVILEGES               {}
13878        | PROCESS                  {}
13879        | PROCESSLIST_SYM          {}
13880        | PROFILE_SYM              {}
13881        | PROFILES_SYM             {}
13882        | PROXY_SYM                {}
13883        | QUARTER_SYM              {}
13884        | QUERY_SYM                {}
13885        | QUICK                    {}
13886        | READ_ONLY_SYM            {}
13887        | REBUILD_SYM              {}
13888        | RECOVER_SYM              {}
13889        | REDO_BUFFER_SIZE_SYM     {}
13890        | REDOFILE_SYM             {}
13891        | REDUNDANT_SYM            {}
13892        | RELAY                    {}
13893        | RELAYLOG_SYM             {}
13894        | RELAY_LOG_FILE_SYM       {}
13895        | RELAY_LOG_POS_SYM        {}
13896        | RELAY_THREAD             {}
13897        | RELOAD                   {}
13898        | REORGANIZE_SYM           {}
13899        | REPEATABLE_SYM           {}
13900        | REPLICATION              {}
13901        | REPLICATE_DO_DB          {}
13902        | REPLICATE_IGNORE_DB      {}
13903        | REPLICATE_DO_TABLE       {}
13904        | REPLICATE_IGNORE_TABLE   {}
13905        | REPLICATE_WILD_DO_TABLE  {}
13906        | REPLICATE_WILD_IGNORE_TABLE {}
13907        | REPLICATE_REWRITE_DB     {}
13908        | RESOURCES                {}
13909        | RESUME_SYM               {}
13910        | RETURNED_SQLSTATE_SYM    {}
13911        | RETURNS_SYM              {}
13912        | REVERSE_SYM              {}
13913        | ROLLUP_SYM               {}
13914        | ROTATE_SYM               {}
13915        | ROUTINE_SYM              {}
13916        | ROWS_SYM                 {}
13917        | ROW_COUNT_SYM            {}
13918        | ROW_FORMAT_SYM           {}
13919        | ROW_SYM                  {}
13920        | RTREE_SYM                {}
13921        | SCHEDULE_SYM             {}
13922        | SCHEMA_NAME_SYM          {}
13923        | SECOND_SYM               {}
13924        | SERIAL_SYM               {}
13925        | SERIALIZABLE_SYM         {}
13926        | SESSION_SYM              {}
13927        | SIMPLE_SYM               {}
13928        | SHARE_SYM                {}
13929        | SLOW                     {}
13930        | SNAPSHOT_SYM             {}
13931        | SOUNDS_SYM               {}
13932        | SOURCE_SYM               {}
13933        | SQL_AFTER_GTIDS          {}
13934        | SQL_AFTER_MTS_GAPS       {}
13935        | SQL_BEFORE_GTIDS         {}
13936        | SQL_CACHE_SYM            {}
13937        | SQL_BUFFER_RESULT        {}
13938        | SQL_NO_CACHE_SYM         {}
13939        | SQL_THREAD               {}
13940        | STACKED_SYM              {}
13941        | STARTS_SYM               {}
13942        | STATS_AUTO_RECALC_SYM    {}
13943        | STATS_PERSISTENT_SYM     {}
13944        | STATS_SAMPLE_PAGES_SYM   {}
13945        | STATEMENT_SYM            {}
13946        | STATUS_SYM               {}
13947        | STORAGE_SYM              {}
13948        | STRING_SYM               {}
13949        | SUBCLASS_ORIGIN_SYM      {}
13950        | SUBDATE_SYM              {}
13951        | SUBJECT_SYM              {}
13952        | SUBPARTITION_SYM         {}
13953        | SUBPARTITIONS_SYM        {}
13954        | SUPER_SYM                {}
13955        | SUSPEND_SYM              {}
13956        | SWAPS_SYM                {}
13957        | SWITCHES_SYM             {}
13958        | TABLE_STATS_SYM          {}
13959        | TABLE_NAME_SYM           {}
13960        | TABLES                   {}
13961        | TABLE_CHECKSUM_SYM       {}
13962        | TABLESPACE_SYM           {}
13963        | TEMPORARY                {}
13964        | TEMPTABLE_SYM            {}
13965        | TEXT_SYM                 {}
13966        | THAN_SYM                 {}
13967        | THREAD_STATS_SYM         {}
13968        | TRANSACTION_SYM          {}
13969        | TRIGGERS_SYM             {}
13970        | TIMESTAMP                {}
13971        | TIMESTAMP_ADD            {}
13972        | TIMESTAMP_DIFF           {}
13973        | TIME_SYM                 {}
13974        | TOKU_UNCOMPRESSED_SYM    {}
13975        | TOKU_ZLIB_SYM            {}
13976        | TOKU_SNAPPY_SYM          {}
13977        | TOKU_QUICKLZ_SYM         {}
13978        | TOKU_LZMA_SYM            {}
13979        | TOKU_SMALL_SYM           {}
13980        | TOKU_FAST_SYM            {}
13981        | TOKU_DEFAULT_SYM         {}
13982        | TYPES_SYM                {}
13983        | TYPE_SYM                 {}
13984        | UDF_RETURNS_SYM          {}
13985        | FUNCTION_SYM             {}
13986        | UNCOMMITTED_SYM          {}
13987        | UNDEFINED_SYM            {}
13988        | UNDO_BUFFER_SIZE_SYM     {}
13989        | UNDOFILE_SYM             {}
13990        | UNKNOWN_SYM              {}
13991        | UNTIL_SYM                {}
13992        | USER                     {}
13993        | USER_STATS_SYM           {}
13994        | USE_FRM                  {}
13995        | VALIDATION_SYM           {}
13996        | VARIABLES                {}
13997        | VIEW_SYM                 {}
13998        | VALUE_SYM                {}
13999        | WARNINGS                 {}
14000        | WAIT_SYM                 {}
14001        | WEEK_SYM                 {}
14002        | WITHOUT_SYM              {}
14003        | WORK_SYM                 {}
14004        | WEIGHT_STRING_SYM        {}
14005        | X509_SYM                 {}
14006        | XID_SYM                  {}
14007        | XML_SYM                  {}
14008        | YEAR_SYM                 {}
14009        ;
14010
14011/*
14012  SQLCOM_SET_OPTION statement.
14013
14014  Note that to avoid shift/reduce conflicts, we have separate rules for the
14015  first option listed in the statement.
14016*/
14017
14018set:
14019          SET start_option_value_list
14020          {
14021            $$= NEW_PTN PT_set(@1, @1, $2, false);
14022          }
14023        | SET STATEMENT_SYM option_value_following_option_type
14024          set_stmt_option_value_list_continued
14025          FOR_SYM statement
14026          {
14027            $$= NEW_PTN PT_set(@1, @2,
14028              NEW_PTN PT_start_option_value_list_type(OPT_SESSION,
14029                NEW_PTN PT_start_option_value_list_following_option_type_eq($3,
14030                                                                            @3,
14031                                                                            $4)), true);
14032          }
14033        ;
14034
14035// Start of option value list
14036start_option_value_list:
14037          option_value_no_option_type option_value_list_continued
14038          {
14039            $$= NEW_PTN PT_start_option_value_list_no_type($1, @1, $2);
14040          }
14041        | TRANSACTION_SYM transaction_characteristics
14042          {
14043            $$= NEW_PTN PT_start_option_value_list_transaction($2, @2);
14044          }
14045        | option_type start_option_value_list_following_option_type
14046          {
14047            $$= NEW_PTN PT_start_option_value_list_type($1, $2);
14048          }
14049        | PASSWORD equal password
14050          {
14051            $$= NEW_PTN PT_option_value_no_option_type_password($3, @3);
14052          }
14053        | PASSWORD equal PASSWORD '(' password ')'
14054          {
14055            push_deprecated_warn(YYTHD, "SET PASSWORD = "
14056                                 "PASSWORD('<plaintext_password>')",
14057                                 "SET PASSWORD = '<plaintext_password>'");
14058            $$= NEW_PTN PT_option_value_no_option_type_password($5, @5);
14059          }
14060        | PASSWORD FOR_SYM user equal password
14061          {
14062            $$= NEW_PTN PT_option_value_no_option_type_password_for($3, $5, @5);
14063          }
14064        | PASSWORD FOR_SYM user equal PASSWORD '(' password ')'
14065          {
14066            push_deprecated_warn(YYTHD, "SET PASSWORD FOR <user> = "
14067                                 "PASSWORD('<plaintext_password>')",
14068                                 "SET PASSWORD FOR <user> = "
14069                                 "'<plaintext_password>'");
14070            $$= NEW_PTN PT_option_value_no_option_type_password_for($3, $7, @7);
14071          }
14072        ;
14073
14074
14075// Start of option value list, option_type was given
14076start_option_value_list_following_option_type:
14077          option_value_following_option_type option_value_list_continued
14078          {
14079            $$=
14080              NEW_PTN PT_start_option_value_list_following_option_type_eq($1,
14081                                                                          @1,
14082                                                                          $2);
14083          }
14084        | TRANSACTION_SYM transaction_characteristics
14085          {
14086            $$= NEW_PTN
14087              PT_start_option_value_list_following_option_type_transaction($2,
14088                                                                           @2);
14089          }
14090        ;
14091
14092set_stmt_option_value_list_continued:
14093          /* empty */                    { $$= NULL; }
14094        | ',' set_stmt_option_value_list { $$= $2;   }
14095
14096set_stmt_option_value_list:
14097          option_value_no_option_type
14098          {
14099            $$= NEW_PTN PT_option_value_list_head(@0, $1, @1);
14100          }
14101        | option_value_list ',' option_value_no_option_type
14102          {
14103            $$= NEW_PTN PT_option_value_list($1, @2, $3, @3);
14104          }
14105        ;
14106
14107// Remainder of the option value list after first option value.
14108option_value_list_continued:
14109          /* empty */           { $$= NULL; }
14110        | ',' option_value_list { $$= $2; }
14111        ;
14112
14113// Repeating list of option values after first option value.
14114option_value_list:
14115          option_value
14116          {
14117            $$= NEW_PTN PT_option_value_list_head(@0, $1, @1);
14118          }
14119        | option_value_list ',' option_value
14120          {
14121            $$= NEW_PTN PT_option_value_list($1, @2, $3, @3);
14122          }
14123        ;
14124
14125// Wrapper around option values following the first option value in the stmt.
14126option_value:
14127          option_type option_value_following_option_type
14128          {
14129            $$= NEW_PTN PT_option_value_type($1, $2);
14130          }
14131        | option_value_no_option_type { $$= $1; }
14132        ;
14133
14134option_type:
14135          GLOBAL_SYM  { $$=OPT_GLOBAL; }
14136        | LOCAL_SYM   { $$=OPT_SESSION; }
14137        | SESSION_SYM { $$=OPT_SESSION; }
14138        ;
14139
14140opt_var_type:
14141          /* empty */ { $$=OPT_SESSION; }
14142        | GLOBAL_SYM  { $$=OPT_GLOBAL; }
14143        | LOCAL_SYM   { $$=OPT_SESSION; }
14144        | SESSION_SYM { $$=OPT_SESSION; }
14145        ;
14146
14147opt_var_ident_type:
14148          /* empty */     { $$=OPT_DEFAULT; }
14149        | GLOBAL_SYM '.'  { $$=OPT_GLOBAL; }
14150        | LOCAL_SYM '.'   { $$=OPT_SESSION; }
14151        | SESSION_SYM '.' { $$=OPT_SESSION; }
14152        ;
14153
14154// Option values with preceding option_type.
14155option_value_following_option_type:
14156          internal_variable_name equal set_expr_or_default
14157          {
14158            $$= NEW_PTN PT_option_value_following_option_type(@$, $1, $3);
14159          }
14160        ;
14161
14162// Option values without preceding option_type.
14163option_value_no_option_type:
14164          internal_variable_name        /*$1*/
14165          equal                         /*$2*/
14166          set_expr_or_default           /*$3*/
14167          {
14168            $$= NEW_PTN PT_option_value_no_option_type_internal($1, $3, @3);
14169          }
14170        | '@' ident_or_text equal expr
14171          {
14172            $$= NEW_PTN PT_option_value_no_option_type_user_var($2, $4);
14173          }
14174        | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
14175          {
14176            $$= NEW_PTN PT_option_value_no_option_type_sys_var($3, $4, $6);
14177          }
14178        | charset old_or_new_charset_name_or_default
14179          {
14180            $$= NEW_PTN PT_option_value_no_option_type_charset($2);
14181          }
14182        | NAMES_SYM equal expr
14183          {
14184            /*
14185              Bad syntax, always fails with an error
14186            */
14187            $$= NEW_PTN PT_option_value_no_option_type_names(@2);
14188          }
14189        | NAMES_SYM charset_name_or_default opt_collate
14190          {
14191            $$= NEW_PTN PT_option_value_no_option_type_names_charset($2, $3);
14192          }
14193        ;
14194
14195internal_variable_name:
14196          ident
14197          {
14198            $$= NEW_PTN PT_internal_variable_name_1d($1);
14199          }
14200        | ident '.' ident
14201          {
14202            $$= NEW_PTN PT_internal_variable_name_2d(@$, $1, $3);
14203          }
14204        | DEFAULT '.' ident
14205          {
14206            $$= NEW_PTN PT_internal_variable_name_default($3);
14207          }
14208        ;
14209
14210transaction_characteristics:
14211          transaction_access_mode opt_isolation_level
14212          {
14213            $$= NEW_PTN PT_transaction_characteristics($1, $2);
14214          }
14215        | isolation_level opt_transaction_access_mode
14216          {
14217            $$= NEW_PTN PT_transaction_characteristics($1, $2);
14218          }
14219        ;
14220
14221transaction_access_mode:
14222          transaction_access_mode_types
14223          {
14224            $$= NEW_PTN PT_transaction_access_mode($1);
14225          }
14226        ;
14227
14228opt_transaction_access_mode:
14229          /* empty */                 { $$= NULL; }
14230        | ',' transaction_access_mode { $$= $2; }
14231        ;
14232
14233isolation_level:
14234          ISOLATION LEVEL_SYM isolation_types
14235          {
14236            $$= NEW_PTN PT_isolation_level($3);
14237          }
14238        ;
14239
14240opt_isolation_level:
14241          /* empty */         { $$= NULL; }
14242        | ',' isolation_level { $$= $2; }
14243        ;
14244
14245transaction_access_mode_types:
14246          READ_SYM ONLY_SYM { $$= true; }
14247        | READ_SYM WRITE_SYM { $$= false; }
14248        ;
14249
14250isolation_types:
14251          READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
14252        | READ_SYM COMMITTED_SYM   { $$= ISO_READ_COMMITTED; }
14253        | REPEATABLE_SYM READ_SYM  { $$= ISO_REPEATABLE_READ; }
14254        | SERIALIZABLE_SYM         { $$= ISO_SERIALIZABLE; }
14255        ;
14256
14257password:
14258          TEXT_STRING
14259          {
14260            $$=$1.str;
14261            Lex->contains_plaintext_password= true;
14262          }
14263        ;
14264
14265
14266set_expr_or_default:
14267          expr
14268        | DEFAULT { $$= NULL; }
14269        | ON
14270          {
14271            $$= NEW_PTN Item_string(@$, "ON",  2, system_charset_info);
14272          }
14273        | ALL
14274          {
14275            $$= NEW_PTN Item_string(@$, "ALL", 3, system_charset_info);
14276          }
14277        | BINARY
14278          {
14279            $$= NEW_PTN Item_string(@$, "binary", 6, system_charset_info);
14280          }
14281        | FORCE_SYM
14282          {
14283            $$= NEW_PTN Item_string(@$, "FORCE", 5, system_charset_info);
14284          }
14285        ;
14286
14287/* Lock function */
14288
14289lock:
14290          LOCK_SYM lock_variant
14291          {
14292            if (Lex->sphead)
14293            {
14294              my_error(ER_SP_BADSTATEMENT, MYF(0), "LOCK");
14295              MYSQL_YYABORT;
14296            }
14297          }
14298        ;
14299
14300lock_variant:
14301          BINLOG_SYM FOR_SYM BACKUP_SYM
14302          {
14303            Lex->sql_command= SQLCOM_LOCK_BINLOG_FOR_BACKUP;
14304          }
14305        | TABLES FOR_SYM BACKUP_SYM
14306          {
14307            Lex->sql_command= SQLCOM_LOCK_TABLES_FOR_BACKUP;
14308          }
14309        | table_or_tables
14310          {
14311            Lex->sql_command= SQLCOM_LOCK_TABLES;
14312          }
14313          table_lock_list
14314          {}
14315        ;
14316
14317table_or_tables:
14318          TABLE_SYM
14319        | TABLES
14320        ;
14321
14322table_lock_list:
14323          table_lock
14324        | table_lock_list ',' table_lock
14325        ;
14326
14327table_lock:
14328          table_ident opt_table_alias lock_option
14329          {
14330            thr_lock_type lock_type= (thr_lock_type) $3;
14331            enum_mdl_type mdl_lock_type;
14332
14333            if (lock_type >= TL_WRITE_ALLOW_WRITE)
14334            {
14335              /* LOCK TABLE ... WRITE/LOW_PRIORITY WRITE */
14336              mdl_lock_type= MDL_SHARED_NO_READ_WRITE;
14337            }
14338            else if (lock_type == TL_READ)
14339            {
14340              /* LOCK TABLE ... READ LOCAL */
14341              mdl_lock_type= MDL_SHARED_READ;
14342            }
14343            else
14344            {
14345              /* LOCK TABLE ... READ */
14346              mdl_lock_type= MDL_SHARED_READ_ONLY;
14347            }
14348
14349            if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type,
14350                                           mdl_lock_type))
14351              MYSQL_YYABORT;
14352          }
14353        ;
14354
14355lock_option:
14356          READ_SYM               { $$= TL_READ_NO_INSERT; }
14357        | WRITE_SYM              { $$= TL_WRITE_DEFAULT; }
14358        | LOW_PRIORITY WRITE_SYM
14359          {
14360            $$= TL_WRITE_LOW_PRIORITY;
14361            push_deprecated_warn(YYTHD, "LOW_PRIORITY WRITE", "WRITE");
14362          }
14363        | READ_SYM LOCAL_SYM     { $$= TL_READ; }
14364        ;
14365
14366unlock:
14367          UNLOCK_SYM unlock_variant
14368          {
14369            if (Lex->sphead)
14370            {
14371              my_error(ER_SP_BADSTATEMENT, MYF(0), "UNLOCK");
14372              MYSQL_YYABORT;
14373            }
14374          }
14375	;
14376
14377unlock_variant:
14378          BINLOG_SYM
14379          {
14380            Lex->sql_command= SQLCOM_UNLOCK_BINLOG;
14381          }
14382        | table_or_tables
14383          {
14384            Lex->sql_command= SQLCOM_UNLOCK_TABLES;
14385          }
14386        ;
14387
14388
14389shutdown_stmt:
14390          SHUTDOWN
14391          {
14392            Lex->sql_command= SQLCOM_SHUTDOWN;
14393            $$= NEW_PTN PT_shutdown();
14394          }
14395        ;
14396
14397alter_instance_stmt:
14398          ALTER INSTANCE_SYM alter_instance_action
14399          {
14400            Lex->sql_command= SQLCOM_ALTER_INSTANCE;
14401            $$= NEW_PTN PT_alter_instance($3);
14402          }
14403
14404alter_instance_action:
14405          ROTATE_SYM ident_or_text MASTER_SYM KEY_SYM
14406          {
14407            if (!my_strcasecmp(system_charset_info, $2.str, "INNODB"))
14408            {
14409              $$= ROTATE_INNODB_MASTER_KEY;
14410            }
14411            else
14412            {
14413              YYTHD->parse_error_at(@2, ER(ER_SYNTAX_ERROR));
14414              MYSQL_YYABORT;
14415            }
14416          }
14417        ;
14418
14419/*
14420** Handler: direct access to ISAM functions
14421*/
14422
14423handler:
14424          HANDLER_SYM table_ident OPEN_SYM opt_table_alias
14425          {
14426            THD *thd= YYTHD;
14427            LEX *lex= Lex;
14428            if (lex->sphead)
14429            {
14430              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
14431              MYSQL_YYABORT;
14432            }
14433            lex->sql_command = SQLCOM_HA_OPEN;
14434            if (!lex->current_select()->add_table_to_list(thd, $2, $4, 0))
14435              MYSQL_YYABORT;
14436            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_open();
14437            if (lex->m_sql_cmd == NULL)
14438              MYSQL_YYABORT;
14439          }
14440        | HANDLER_SYM table_ident_nodb CLOSE_SYM
14441          {
14442            THD *thd= YYTHD;
14443            LEX *lex= Lex;
14444            if (lex->sphead)
14445            {
14446              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
14447              MYSQL_YYABORT;
14448            }
14449            lex->sql_command = SQLCOM_HA_CLOSE;
14450            if (!lex->current_select()->add_table_to_list(thd, $2, 0, 0))
14451              MYSQL_YYABORT;
14452            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_close();
14453            if (lex->m_sql_cmd == NULL)
14454              MYSQL_YYABORT;
14455          }
14456        | HANDLER_SYM           /* #1 */
14457          table_ident_nodb      /* #2 */
14458          READ_SYM              /* #3 */
14459          {                     /* #4 */
14460            LEX *lex=Lex;
14461            if (lex->sphead)
14462            {
14463              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
14464              MYSQL_YYABORT;
14465            }
14466            lex->expr_allows_subselect= FALSE;
14467            lex->sql_command = SQLCOM_HA_READ;
14468            Item *one= new (YYTHD->mem_root) Item_int((int32) 1);
14469            if (one == NULL)
14470              MYSQL_YYABORT;
14471            lex->current_select()->select_limit= one;
14472            lex->current_select()->offset_limit= 0;
14473            if (!lex->current_select()->add_table_to_list(lex->thd, $2, 0, 0))
14474              MYSQL_YYABORT;
14475          }
14476          handler_read_or_scan  /* #5 */
14477          opt_where_clause      /* #6 */
14478          opt_limit_clause      /* #7 */
14479          {
14480            if ($6 != NULL)
14481              ITEMIZE($6, &$6);
14482            Select->set_where_cond($6);
14483
14484            if ($7 != NULL)
14485              CONTEXTUALIZE($7);
14486
14487            THD *thd= YYTHD;
14488            LEX *lex= Lex;
14489            Lex->expr_allows_subselect= TRUE;
14490            /* Stored functions are not supported for HANDLER READ. */
14491            if (lex->uses_stored_routines())
14492            {
14493              my_error(ER_NOT_SUPPORTED_YET, MYF(0),
14494                       "stored functions in HANDLER ... READ");
14495              MYSQL_YYABORT;
14496            }
14497            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_read($5,
14498                                  lex->ident.str, lex->handler_insert_list,
14499                                  thd->m_parser_state->m_yacc.m_ha_rkey_mode);
14500            if (lex->m_sql_cmd == NULL)
14501              MYSQL_YYABORT;
14502          }
14503        ;
14504
14505handler_read_or_scan:
14506          handler_scan_function       { Lex->ident= null_lex_str; $$=$1; }
14507        | ident handler_rkey_function { Lex->ident= $1; $$=$2; }
14508        ;
14509
14510handler_scan_function:
14511          FIRST_SYM { $$= RFIRST; }
14512        | NEXT_SYM  { $$= RNEXT;  }
14513        ;
14514
14515handler_rkey_function:
14516          FIRST_SYM { $$= RFIRST; }
14517        | NEXT_SYM  { $$= RNEXT;  }
14518        | PREV_SYM  { $$= RPREV;  }
14519        | LAST_SYM  { $$= RLAST;  }
14520        | handler_rkey_mode
14521          {
14522            YYTHD->m_parser_state->m_yacc.m_ha_rkey_mode= $1;
14523          }
14524          '(' values ')'
14525          {
14526            CONTEXTUALIZE($4);
14527            Lex->handler_insert_list= &$4->value;
14528            $$= RKEY;
14529          }
14530        ;
14531
14532handler_rkey_mode:
14533          EQ     { $$=HA_READ_KEY_EXACT;   }
14534        | GE     { $$=HA_READ_KEY_OR_NEXT; }
14535        | LE     { $$=HA_READ_KEY_OR_PREV; }
14536        | GT_SYM { $$=HA_READ_AFTER_KEY;   }
14537        | LT     { $$=HA_READ_BEFORE_KEY;  }
14538        ;
14539
14540/* GRANT / REVOKE */
14541
14542revoke:
14543          REVOKE clear_privileges { Lex->sql_command= SQLCOM_REVOKE; } revoke_command
14544          {}
14545        ;
14546
14547revoke_command:
14548          grant_privileges ON opt_table grant_ident FROM user_list
14549          {
14550            LEX *lex= Lex;
14551            lex->type= 0;
14552          }
14553        | grant_privileges ON FUNCTION_SYM grant_ident FROM user_list
14554          {
14555            LEX *lex= Lex;
14556            if (lex->columns.elements)
14557            {
14558              my_syntax_error(ER(ER_SYNTAX_ERROR));
14559              MYSQL_YYABORT;
14560            }
14561            lex->type= TYPE_ENUM_FUNCTION;
14562          }
14563        | grant_privileges ON PROCEDURE_SYM grant_ident FROM user_list
14564          {
14565            LEX *lex= Lex;
14566            if (lex->columns.elements)
14567            {
14568              my_syntax_error(ER(ER_SYNTAX_ERROR));
14569              MYSQL_YYABORT;
14570            }
14571            lex->type= TYPE_ENUM_PROCEDURE;
14572          }
14573        | ALL opt_privileges ',' GRANT OPTION FROM user_list
14574          {
14575            Lex->sql_command = SQLCOM_REVOKE_ALL;
14576          }
14577        | PROXY_SYM ON user FROM user_list
14578          {
14579            LEX *lex= Lex;
14580            lex->users_list.push_front ($3);
14581            lex->type= TYPE_ENUM_PROXY;
14582          }
14583        ;
14584
14585grant:
14586          GRANT clear_privileges { Lex->sql_command= SQLCOM_GRANT; } grant_command
14587          {}
14588        ;
14589
14590grant_command:
14591          grant_privileges ON opt_table grant_ident TO_SYM grant_list
14592          require_clause grant_options
14593          {
14594            LEX *lex= Lex;
14595            lex->type= 0;
14596          }
14597        | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
14598          require_clause grant_options
14599          {
14600            LEX *lex= Lex;
14601            if (lex->columns.elements)
14602            {
14603              my_syntax_error(ER(ER_SYNTAX_ERROR));
14604              MYSQL_YYABORT;
14605            }
14606            lex->type= TYPE_ENUM_FUNCTION;
14607          }
14608        | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list
14609          require_clause grant_options
14610          {
14611            LEX *lex= Lex;
14612            if (lex->columns.elements)
14613            {
14614              my_syntax_error(ER(ER_SYNTAX_ERROR));
14615              MYSQL_YYABORT;
14616            }
14617            lex->type= TYPE_ENUM_PROCEDURE;
14618          }
14619        | PROXY_SYM ON user TO_SYM grant_list opt_grant_option
14620          {
14621            LEX *lex= Lex;
14622            lex->users_list.push_front ($3);
14623            lex->type= TYPE_ENUM_PROXY;
14624          }
14625        ;
14626
14627opt_table:
14628          /* Empty */
14629        | TABLE_SYM
14630        ;
14631
14632grant_privileges:
14633          object_privilege_list
14634          {
14635            LEX *lex= Lex;
14636            if (lex->grant == GLOBAL_ACLS &&
14637                lex->sql_command == SQLCOM_REVOKE)
14638              lex->sql_command= SQLCOM_REVOKE_ALL;
14639          }
14640        | ALL opt_privileges
14641          {
14642            Lex->all_privileges= 1;
14643            Lex->grant= GLOBAL_ACLS;
14644          }
14645        ;
14646
14647opt_privileges:
14648          /* empty */
14649        | PRIVILEGES
14650        ;
14651
14652object_privilege_list:
14653          object_privilege
14654        | object_privilege_list ',' object_privilege
14655        ;
14656
14657object_privilege:
14658          SELECT_SYM
14659          { Lex->which_columns = SELECT_ACL;}
14660          opt_column_list {}
14661        | INSERT
14662          { Lex->which_columns = INSERT_ACL;}
14663          opt_column_list {}
14664        | UPDATE_SYM
14665          { Lex->which_columns = UPDATE_ACL; }
14666          opt_column_list {}
14667        | REFERENCES
14668          { Lex->which_columns = REFERENCES_ACL;}
14669          opt_column_list {}
14670        | DELETE_SYM              { Lex->grant |= DELETE_ACL;}
14671        | USAGE                   {}
14672        | INDEX_SYM               { Lex->grant |= INDEX_ACL;}
14673        | ALTER                   { Lex->grant |= ALTER_ACL;}
14674        | CREATE                  { Lex->grant |= CREATE_ACL;}
14675        | DROP                    { Lex->grant |= DROP_ACL;}
14676        | EXECUTE_SYM             { Lex->grant |= EXECUTE_ACL;}
14677        | RELOAD                  { Lex->grant |= RELOAD_ACL;}
14678        | SHUTDOWN                { Lex->grant |= SHUTDOWN_ACL;}
14679        | PROCESS                 { Lex->grant |= PROCESS_ACL;}
14680        | FILE_SYM                { Lex->grant |= FILE_ACL;}
14681        | GRANT OPTION            { Lex->grant |= GRANT_ACL;}
14682        | SHOW DATABASES          { Lex->grant |= SHOW_DB_ACL;}
14683        | SUPER_SYM               { Lex->grant |= SUPER_ACL;}
14684        | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
14685        | LOCK_SYM TABLES         { Lex->grant |= LOCK_TABLES_ACL; }
14686        | REPLICATION SLAVE       { Lex->grant |= REPL_SLAVE_ACL; }
14687        | REPLICATION CLIENT_SYM  { Lex->grant |= REPL_CLIENT_ACL; }
14688        | CREATE VIEW_SYM         { Lex->grant |= CREATE_VIEW_ACL; }
14689        | SHOW VIEW_SYM           { Lex->grant |= SHOW_VIEW_ACL; }
14690        | CREATE ROUTINE_SYM      { Lex->grant |= CREATE_PROC_ACL; }
14691        | ALTER ROUTINE_SYM       { Lex->grant |= ALTER_PROC_ACL; }
14692        | CREATE USER             { Lex->grant |= CREATE_USER_ACL; }
14693        | EVENT_SYM               { Lex->grant |= EVENT_ACL;}
14694        | TRIGGER_SYM             { Lex->grant |= TRIGGER_ACL; }
14695        | CREATE TABLESPACE_SYM   { Lex->grant |= CREATE_TABLESPACE_ACL; }
14696        ;
14697
14698opt_and:
14699          /* empty */ {}
14700        | AND_SYM {}
14701        ;
14702
14703require_list:
14704          require_list_element opt_and require_list
14705        | require_list_element
14706        ;
14707
14708require_list_element:
14709          SUBJECT_SYM TEXT_STRING
14710          {
14711            LEX *lex=Lex;
14712            if (lex->x509_subject)
14713            {
14714              my_error(ER_DUP_ARGUMENT, MYF(0), "SUBJECT");
14715              MYSQL_YYABORT;
14716            }
14717            lex->x509_subject=$2.str;
14718          }
14719        | ISSUER_SYM TEXT_STRING
14720          {
14721            LEX *lex=Lex;
14722            if (lex->x509_issuer)
14723            {
14724              my_error(ER_DUP_ARGUMENT, MYF(0), "ISSUER");
14725              MYSQL_YYABORT;
14726            }
14727            lex->x509_issuer=$2.str;
14728          }
14729        | CIPHER_SYM TEXT_STRING
14730          {
14731            LEX *lex=Lex;
14732            if (lex->ssl_cipher)
14733            {
14734              my_error(ER_DUP_ARGUMENT, MYF(0), "CIPHER");
14735              MYSQL_YYABORT;
14736            }
14737            lex->ssl_cipher=$2.str;
14738          }
14739        ;
14740
14741grant_ident:
14742          '*'
14743          {
14744            LEX *lex= Lex;
14745            size_t dummy;
14746            if (lex->copy_db_to(&lex->current_select()->db, &dummy))
14747              MYSQL_YYABORT;
14748            if (lex->grant == GLOBAL_ACLS)
14749              lex->grant = DB_ACLS & ~GRANT_ACL;
14750            else if (lex->columns.elements)
14751            {
14752              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
14753                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
14754              MYSQL_YYABORT;
14755            }
14756          }
14757        | ident '.' '*'
14758          {
14759            LEX *lex= Lex;
14760            lex->current_select()->db = $1.str;
14761            if (lex->grant == GLOBAL_ACLS)
14762              lex->grant = DB_ACLS & ~GRANT_ACL;
14763            else if (lex->columns.elements)
14764            {
14765              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
14766                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
14767              MYSQL_YYABORT;
14768            }
14769          }
14770        | '*' '.' '*'
14771          {
14772            LEX *lex= Lex;
14773            lex->current_select()->db = NULL;
14774            if (lex->grant == GLOBAL_ACLS)
14775              lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
14776            else if (lex->columns.elements)
14777            {
14778              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
14779                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
14780              MYSQL_YYABORT;
14781            }
14782          }
14783        | table_ident
14784          {
14785            LEX *lex=Lex;
14786            if (!lex->current_select()->add_table_to_list(lex->thd, $1,NULL,
14787                                                        TL_OPTION_UPDATING))
14788              MYSQL_YYABORT;
14789            if (lex->grant == GLOBAL_ACLS)
14790              lex->grant =  TABLE_ACLS & ~GRANT_ACL;
14791          }
14792        ;
14793
14794user_list:
14795          user
14796          {
14797            if (Lex->users_list.push_back($1))
14798              MYSQL_YYABORT;
14799          }
14800        | user_list ',' user
14801          {
14802            if (Lex->users_list.push_back($3))
14803              MYSQL_YYABORT;
14804          }
14805        ;
14806
14807grant_list:
14808          grant_user
14809          {
14810            if (Lex->users_list.push_back($1))
14811              MYSQL_YYABORT;
14812          }
14813        | grant_list ',' grant_user
14814          {
14815            if (Lex->users_list.push_back($3))
14816              MYSQL_YYABORT;
14817          }
14818        ;
14819
14820grant_user:
14821          user IDENTIFIED_SYM BY TEXT_STRING
14822          {
14823            $$=$1;
14824            $1->auth.str= $4.str;
14825            $1->auth.length= $4.length;
14826            $1->uses_identified_by_clause= true;
14827            Lex->contains_plaintext_password= true;
14828          }
14829        | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
14830          {
14831            $$= $1;
14832            $1->auth.str= $5.str;
14833            $1->auth.length= $5.length;
14834            $1->uses_identified_by_password_clause= true;
14835            if (Lex->sql_command == SQLCOM_ALTER_USER)
14836            {
14837              my_syntax_error(ER_THD(YYTHD, ER_SYNTAX_ERROR));
14838              MYSQL_YYABORT;
14839            }
14840            else
14841              push_deprecated_warn(YYTHD, "IDENTIFIED BY PASSWORD",
14842                                   "IDENTIFIED WITH <plugin> AS <hash>");
14843          }
14844        | user IDENTIFIED_SYM WITH ident_or_text
14845          {
14846            $$= $1;
14847            $1->plugin.str= $4.str;
14848            $1->plugin.length= $4.length;
14849            $1->auth= EMPTY_CSTR;
14850            $1->uses_identified_with_clause= true;
14851          }
14852        | user IDENTIFIED_SYM WITH ident_or_text AS TEXT_STRING_sys
14853          {
14854            $$= $1;
14855            $1->plugin.str= $4.str;
14856            $1->plugin.length= $4.length;
14857            $1->auth.str= $6.str;
14858            $1->auth.length= $6.length;
14859            $1->uses_identified_with_clause= true;
14860            $1->uses_authentication_string_clause= true;
14861          }
14862        | user IDENTIFIED_SYM WITH ident_or_text BY TEXT_STRING_sys
14863          {
14864            $$= $1;
14865            $1->plugin.str= $4.str;
14866            $1->plugin.length= $4.length;
14867            $1->auth.str= $6.str;
14868            $1->auth.length= $6.length;
14869            $1->uses_identified_with_clause= true;
14870            $1->uses_identified_by_clause= true;
14871            Lex->contains_plaintext_password= true;
14872          }
14873        | user
14874          {
14875            $$= $1;
14876            $1->auth= NULL_CSTR;
14877          }
14878        ;
14879
14880opt_column_list:
14881          /* empty */
14882          {
14883            LEX *lex=Lex;
14884            lex->grant |= lex->which_columns;
14885          }
14886        | '(' column_list ')'
14887        ;
14888
14889column_list:
14890          column_list ',' column_list_id
14891        | column_list_id
14892        ;
14893
14894column_list_id:
14895          ident
14896          {
14897            String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
14898            if (new_str == NULL)
14899              MYSQL_YYABORT;
14900            List_iterator <LEX_COLUMN> iter(Lex->columns);
14901            class LEX_COLUMN *point;
14902            LEX *lex=Lex;
14903            while ((point=iter++))
14904            {
14905              if (!my_strcasecmp(system_charset_info,
14906                                 point->column.ptr(), new_str->ptr()))
14907                break;
14908            }
14909            lex->grant_tot_col|= lex->which_columns;
14910            if (point)
14911              point->rights |= lex->which_columns;
14912            else
14913            {
14914              LEX_COLUMN *col= new LEX_COLUMN (*new_str,lex->which_columns);
14915              if (col == NULL)
14916                MYSQL_YYABORT;
14917              lex->columns.push_back(col);
14918            }
14919          }
14920        ;
14921
14922require_clause:
14923          /* empty */
14924        | REQUIRE_SYM require_list
14925          {
14926            Lex->ssl_type=SSL_TYPE_SPECIFIED;
14927          }
14928        | REQUIRE_SYM SSL_SYM
14929          {
14930            Lex->ssl_type=SSL_TYPE_ANY;
14931          }
14932        | REQUIRE_SYM X509_SYM
14933          {
14934            Lex->ssl_type=SSL_TYPE_X509;
14935          }
14936        | REQUIRE_SYM NONE_SYM
14937          {
14938            Lex->ssl_type=SSL_TYPE_NONE;
14939          }
14940        ;
14941
14942grant_options:
14943          /* empty */ {}
14944        | WITH grant_option_list
14945        ;
14946
14947opt_grant_option:
14948          /* empty */ {}
14949        | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
14950        ;
14951
14952grant_option_list:
14953          grant_option_list grant_option {}
14954        | grant_option {}
14955        ;
14956
14957grant_option:
14958          GRANT OPTION { Lex->grant |= GRANT_ACL;}
14959        | MAX_QUERIES_PER_HOUR ulong_num
14960          {
14961            LEX *lex=Lex;
14962            lex->mqh.questions=$2;
14963            lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
14964          }
14965        | MAX_UPDATES_PER_HOUR ulong_num
14966          {
14967            LEX *lex=Lex;
14968            lex->mqh.updates=$2;
14969            lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
14970          }
14971        | MAX_CONNECTIONS_PER_HOUR ulong_num
14972          {
14973            LEX *lex=Lex;
14974            lex->mqh.conn_per_hour= $2;
14975            lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
14976          }
14977        | MAX_USER_CONNECTIONS_SYM ulong_num
14978          {
14979            LEX *lex=Lex;
14980            lex->mqh.user_conn= $2;
14981            lex->mqh.specified_limits|= USER_RESOURCES::USER_CONNECTIONS;
14982          }
14983        ;
14984
14985begin:
14986          BEGIN_SYM
14987          {
14988            LEX *lex=Lex;
14989            lex->sql_command = SQLCOM_BEGIN;
14990            lex->start_transaction_opt= 0;
14991          }
14992          opt_work {}
14993        ;
14994
14995opt_work:
14996          /* empty */ {}
14997        | WORK_SYM  {}
14998        ;
14999
15000opt_chain:
15001          /* empty */
15002          { $$= TVL_UNKNOWN; }
15003        | AND_SYM NO_SYM CHAIN_SYM { $$= TVL_NO; }
15004        | AND_SYM CHAIN_SYM        { $$= TVL_YES; }
15005        ;
15006
15007opt_release:
15008          /* empty */
15009          { $$= TVL_UNKNOWN; }
15010        | RELEASE_SYM        { $$= TVL_YES; }
15011        | NO_SYM RELEASE_SYM { $$= TVL_NO; }
15012;
15013
15014opt_savepoint:
15015          /* empty */ {}
15016        | SAVEPOINT_SYM {}
15017        ;
15018
15019commit:
15020          COMMIT_SYM opt_work opt_chain opt_release
15021          {
15022            LEX *lex=Lex;
15023            lex->sql_command= SQLCOM_COMMIT;
15024            /* Don't allow AND CHAIN RELEASE. */
15025            MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
15026            lex->tx_chain= $3;
15027            lex->tx_release= $4;
15028          }
15029        ;
15030
15031rollback:
15032          ROLLBACK_SYM opt_work opt_chain opt_release
15033          {
15034            LEX *lex=Lex;
15035            lex->sql_command= SQLCOM_ROLLBACK;
15036            /* Don't allow AND CHAIN RELEASE. */
15037            MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
15038            lex->tx_chain= $3;
15039            lex->tx_release= $4;
15040          }
15041        | ROLLBACK_SYM opt_work
15042          TO_SYM opt_savepoint ident
15043          {
15044            LEX *lex=Lex;
15045            lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT;
15046            lex->ident= $5;
15047          }
15048        ;
15049
15050savepoint:
15051          SAVEPOINT_SYM ident
15052          {
15053            LEX *lex=Lex;
15054            lex->sql_command= SQLCOM_SAVEPOINT;
15055            lex->ident= $2;
15056          }
15057        ;
15058
15059release:
15060          RELEASE_SYM SAVEPOINT_SYM ident
15061          {
15062            LEX *lex=Lex;
15063            lex->sql_command= SQLCOM_RELEASE_SAVEPOINT;
15064            lex->ident= $3;
15065          }
15066        ;
15067
15068/*
15069   UNIONS : glue selects together
15070*/
15071
15072
15073opt_union_clause:
15074          /* empty */ { $$= NULL; }
15075        | union_list
15076        ;
15077
15078union_list:
15079          UNION_SYM union_option select_init
15080          {
15081            $$= NEW_PTN PT_union_list($2, $3);
15082          }
15083        ;
15084
15085union_opt:
15086          /* Empty */          { $$= NULL; }
15087        | union_list           { $$= $1; }
15088        | union_order_or_limit { $$= $1; }
15089        ;
15090
15091opt_union_order_or_limit:
15092          /* Empty */          { $$= NULL; }
15093        | union_order_or_limit { $$= $1; }
15094        ;
15095
15096union_order_or_limit:
15097          order_or_limit
15098          {
15099            $$= NEW_PTN PT_union_order_or_limit($1);
15100          }
15101        ;
15102
15103order_or_limit:
15104          order_clause opt_limit_clause
15105          {
15106            $$= NEW_PTN PT_order_or_limit_order($1, $2);
15107          }
15108        | limit_clause { $$= $1; }
15109        ;
15110
15111union_option:
15112          /* empty */ { $$=1; }
15113        | DISTINCT  { $$=1; }
15114        | ALL       { $$=0; }
15115        ;
15116
15117query_specification:
15118          SELECT_SYM select_part2_derived table_expression
15119          {
15120            $$= NEW_PTN PT_query_specification_select($1, $2, $3);
15121          }
15122        | '(' select_paren_derived ')'
15123          opt_union_order_or_limit
15124          {
15125            $$= NEW_PTN PT_query_specification_parenthesis($2, $4);
15126          }
15127        ;
15128
15129query_expression_body:
15130          query_specification
15131        | query_expression_body UNION_SYM union_option query_specification
15132          {
15133            $$= NEW_PTN PT_query_expression_body_union(@$, $1, $3, $4);
15134          }
15135        ;
15136
15137/* Corresponds to <query expression> in the SQL:2003 standard. */
15138subselect:
15139          {
15140            /*
15141              TODO: remove this semantic action (currently this removal
15142              adds reduce/reduce conflict)
15143            */
15144          }
15145          query_expression_body
15146          {
15147            $$= NEW_PTN PT_subselect(@$, $2);
15148          }
15149        ;
15150
15151opt_query_spec_options:
15152          /* empty */ { $$= 0; }
15153        | query_spec_option_list
15154        ;
15155
15156query_spec_option_list:
15157          query_spec_option_list query_spec_option
15158          {
15159            $$= $1 | $2;
15160          }
15161        | query_spec_option
15162        ;
15163
15164query_spec_option:
15165          STRAIGHT_JOIN       { $$= SELECT_STRAIGHT_JOIN; }
15166        | HIGH_PRIORITY       { $$= SELECT_HIGH_PRIORITY; }
15167        | DISTINCT            { $$= SELECT_DISTINCT; }
15168        | SQL_SMALL_RESULT    { $$= SELECT_SMALL_RESULT; }
15169        | SQL_BIG_RESULT      { $$= SELECT_BIG_RESULT; }
15170        | SQL_BUFFER_RESULT   { $$= OPTION_BUFFER_RESULT; }
15171        | SQL_CALC_FOUND_ROWS { $$= OPTION_FOUND_ROWS; }
15172        | ALL                 { $$= SELECT_ALL; }
15173        ;
15174
15175/**************************************************************************
15176
15177 CREATE VIEW | TRIGGER | PROCEDURE statements.
15178
15179**************************************************************************/
15180
15181view_or_trigger_or_sp_or_event:
15182          definer definer_tail
15183          {}
15184        | no_definer no_definer_tail
15185          {}
15186        | view_replace_or_algorithm definer_opt view_tail
15187          {}
15188        ;
15189
15190definer_tail:
15191          view_tail
15192        | trigger_tail
15193        | sp_tail
15194        | sf_tail
15195        | event_tail
15196        ;
15197
15198no_definer_tail:
15199          view_tail
15200        | trigger_tail
15201        | sp_tail
15202        | sf_tail
15203        | udf_tail
15204        | event_tail
15205        ;
15206
15207/**************************************************************************
15208
15209 DEFINER clause support.
15210
15211**************************************************************************/
15212
15213definer_opt:
15214          no_definer
15215        | definer
15216        ;
15217
15218no_definer:
15219          /* empty */
15220          {
15221            /*
15222              We have to distinguish missing DEFINER-clause from case when
15223              CURRENT_USER specified as definer explicitly in order to properly
15224              handle CREATE TRIGGER statements which come to replication thread
15225              from older master servers (i.e. to create non-suid trigger in this
15226              case).
15227            */
15228            YYTHD->lex->definer= 0;
15229          }
15230        ;
15231
15232definer:
15233          DEFINER_SYM EQ user
15234          {
15235            YYTHD->lex->definer= get_current_user(YYTHD, $3);
15236          }
15237        ;
15238
15239/**************************************************************************
15240
15241 CREATE VIEW statement parts.
15242
15243**************************************************************************/
15244
15245view_replace_or_algorithm:
15246          view_replace
15247          {}
15248        | view_replace view_algorithm
15249          {}
15250        | view_algorithm
15251          {}
15252        ;
15253
15254view_replace:
15255          OR_SYM REPLACE
15256          { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
15257        ;
15258
15259view_algorithm:
15260          ALGORITHM_SYM EQ UNDEFINED_SYM
15261          { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
15262        | ALGORITHM_SYM EQ MERGE_SYM
15263          { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
15264        | ALGORITHM_SYM EQ TEMPTABLE_SYM
15265          { Lex->create_view_algorithm= VIEW_ALGORITHM_TEMPTABLE; }
15266        ;
15267
15268view_suid:
15269          /* empty */
15270          { Lex->create_view_suid= VIEW_SUID_DEFAULT; }
15271        | SQL_SYM SECURITY_SYM DEFINER_SYM
15272          { Lex->create_view_suid= VIEW_SUID_DEFINER; }
15273        | SQL_SYM SECURITY_SYM INVOKER_SYM
15274          { Lex->create_view_suid= VIEW_SUID_INVOKER; }
15275        ;
15276
15277view_tail:
15278          view_suid VIEW_SYM table_ident
15279          {
15280            THD *thd= YYTHD;
15281            LEX *lex= thd->lex;
15282            lex->sql_command= SQLCOM_CREATE_VIEW;
15283            /* first table in list is target VIEW name */
15284            if (!lex->select_lex->add_table_to_list(thd, $3, NULL,
15285                                                    TL_OPTION_UPDATING,
15286                                                    TL_IGNORE,
15287                                                    MDL_EXCLUSIVE))
15288              MYSQL_YYABORT;
15289            lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
15290          }
15291          view_list_opt AS view_select
15292        ;
15293
15294view_list_opt:
15295          /* empty */
15296          {}
15297        | '(' view_list ')'
15298        ;
15299
15300view_list:
15301          ident
15302            {
15303              Lex->view_list.push_back((LEX_STRING*)
15304              sql_memdup(&$1, sizeof(LEX_STRING)));
15305            }
15306        | view_list ',' ident
15307            {
15308              Lex->view_list.push_back((LEX_STRING*)
15309              sql_memdup(&$3, sizeof(LEX_STRING)));
15310            }
15311        ;
15312
15313view_select:
15314          {
15315            LEX *lex= Lex;
15316            lex->parsing_options.allows_variable= FALSE;
15317            lex->parsing_options.allows_select_into= FALSE;
15318            lex->parsing_options.allows_select_procedure= FALSE;
15319          }
15320          view_select_aux view_check_option
15321          {
15322            THD *thd= YYTHD;
15323            LEX *lex= Lex;
15324
15325            lex->create_view_select.str= const_cast<char *>(@2.cpp.start);
15326            size_t len= @3.cpp.end - lex->create_view_select.str;
15327            void *create_view_select= thd->memdup(lex->create_view_select.str, len);
15328            lex->create_view_select.length= len;
15329            lex->create_view_select.str= (char *) create_view_select;
15330            trim_whitespace(thd->charset(), &lex->create_view_select);
15331            lex->parsing_options.allows_variable= TRUE;
15332            lex->parsing_options.allows_select_into= TRUE;
15333            lex->parsing_options.allows_select_procedure= TRUE;
15334          }
15335        ;
15336
15337view_select_aux:
15338          create_view_select
15339          {
15340            if (Lex->current_select()->set_braces(0))
15341            {
15342              my_syntax_error(ER(ER_SYNTAX_ERROR));
15343              MYSQL_YYABORT;
15344            }
15345            /*
15346              For statment as "CREATE VIEW v1 AS SELECT1 UNION SELECT2",
15347              parsing of Select query (SELECT1) is completed and UNION_CLAUSE
15348              is not yet parsed. So check for
15349              Lex->current_select()->master_unit()->first_select()->braces
15350              (as its done in "PT_select_init2::contextualize()) is not
15351              done here.
15352            */
15353          }
15354          opt_union_clause
15355          {
15356            if ($3 != NULL)
15357              CONTEXTUALIZE($3);
15358          }
15359        | '(' create_view_select_paren ')' union_opt
15360          {
15361            if ($4 != NULL)
15362              CONTEXTUALIZE($4);
15363          }
15364        ;
15365
15366create_view_select_paren:
15367          {
15368            Lex->current_select()->set_braces(true);
15369          }
15370          create_view_select
15371          {
15372            if (setup_select_in_parentheses(Select))
15373              MYSQL_YYABORT;
15374          }
15375        | '(' create_view_select_paren ')'
15376        ;
15377
15378create_view_select:
15379          SELECT_SYM
15380          {
15381            Lex->current_select()->table_list.save_and_clear(&Lex->save_list);
15382          }
15383          select_part2
15384          {
15385            CONTEXTUALIZE($3);
15386
15387            Lex->current_select()->table_list.push_front(&Lex->save_list);
15388          }
15389        ;
15390
15391view_check_option:
15392          /* empty */
15393          { Lex->create_view_check= VIEW_CHECK_NONE; }
15394        | WITH CHECK_SYM OPTION
15395          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
15396        | WITH CASCADED CHECK_SYM OPTION
15397          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
15398        | WITH LOCAL_SYM CHECK_SYM OPTION
15399          { Lex->create_view_check= VIEW_CHECK_LOCAL; }
15400        ;
15401
15402/**************************************************************************
15403
15404 CREATE TRIGGER statement parts.
15405
15406**************************************************************************/
15407
15408trigger_action_order:
15409            FOLLOWS_SYM
15410            { $$= TRG_ORDER_FOLLOWS; }
15411          | PRECEDES_SYM
15412            { $$= TRG_ORDER_PRECEDES; }
15413          ;
15414
15415trigger_follows_precedes_clause:
15416            /* empty */
15417            {
15418              $$.ordering_clause= TRG_ORDER_NONE;
15419              $$.anchor_trigger_name.str= NULL;
15420              $$.anchor_trigger_name.length= 0;
15421            }
15422          |
15423            trigger_action_order ident_or_text
15424            {
15425              $$.ordering_clause= $1;
15426              $$.anchor_trigger_name= $2;
15427            }
15428          ;
15429
15430trigger_tail:
15431          TRIGGER_SYM       /* $1 */
15432          sp_name           /* $2 */
15433          trg_action_time   /* $3 */
15434          trg_event         /* $4 */
15435          ON                /* $5 */
15436          table_ident       /* $6 */
15437          FOR_SYM           /* $7 */
15438          EACH_SYM          /* $8 */
15439          ROW_SYM           /* $9 */
15440          trigger_follows_precedes_clause /* $10 */
15441          {                 /* $11 */
15442            THD *thd= YYTHD;
15443            LEX *lex= thd->lex;
15444
15445            if (lex->sphead)
15446            {
15447              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
15448              MYSQL_YYABORT;
15449            }
15450
15451            lex->raw_trg_on_table_name_begin= @5.raw.start;
15452            lex->raw_trg_on_table_name_end= @7.raw.start;
15453
15454            if (@10.is_empty())
15455            {
15456              /*
15457                @10.is_empty() is true when a clause PRECEDES/FOLLOWS is absent.
15458              */
15459              lex->trg_ordering_clause_begin= NULL;
15460              lex->trg_ordering_clause_end= NULL;
15461            }
15462            else
15463            {
15464              lex->trg_ordering_clause_begin= @10.cpp.start;
15465              lex->trg_ordering_clause_end= @10.cpp.end;
15466            }
15467
15468            sp_head *sp= sp_start_parsing(thd, SP_TYPE_TRIGGER, $2);
15469
15470            if (!sp)
15471              MYSQL_YYABORT;
15472
15473            sp->m_trg_chistics.action_time= (enum enum_trigger_action_time_type) $3;
15474            sp->m_trg_chistics.event= (enum enum_trigger_event_type) $4;
15475            sp->m_trg_chistics.ordering_clause= $10.ordering_clause;
15476            sp->m_trg_chistics.anchor_trigger_name= $10.anchor_trigger_name;
15477
15478            lex->stmt_definition_begin= @1.cpp.start;
15479            lex->ident.str= const_cast<char *>(@6.cpp.start);
15480            lex->ident.length= @8.cpp.start - @6.cpp.start;
15481
15482            lex->sphead= sp;
15483            lex->spname= $2;
15484
15485            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
15486            sp->m_chistics= &lex->sp_chistics;
15487
15488            sp->set_body_start(thd, @9.cpp.end);
15489          }
15490          sp_proc_stmt /* $12 */
15491          { /* $13 */
15492            THD *thd= YYTHD;
15493            LEX *lex= Lex;
15494            sp_head *sp= lex->sphead;
15495
15496            sp_finish_parsing(thd);
15497
15498            lex->sql_command= SQLCOM_CREATE_TRIGGER;
15499
15500            if (sp->is_not_allowed_in_function("trigger"))
15501              MYSQL_YYABORT;
15502
15503            /*
15504              We have to do it after parsing trigger body, because some of
15505              sp_proc_stmt alternatives are not saving/restoring LEX, so
15506              lex->query_tables can be wiped out.
15507            */
15508            if (!lex->select_lex->add_table_to_list(thd, $6,
15509                                                    (LEX_STRING*) 0,
15510                                                    TL_OPTION_UPDATING,
15511                                                    TL_READ_NO_INSERT,
15512                                                    MDL_SHARED_NO_WRITE))
15513              MYSQL_YYABORT;
15514          }
15515        ;
15516
15517/**************************************************************************
15518
15519 CREATE FUNCTION | PROCEDURE statements parts.
15520
15521**************************************************************************/
15522
15523udf_tail:
15524          AGGREGATE_SYM FUNCTION_SYM ident
15525          RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
15526          {
15527            THD *thd= YYTHD;
15528            LEX *lex= thd->lex;
15529            if (is_native_function(thd, & $3))
15530            {
15531              my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
15532                       $3.str);
15533              MYSQL_YYABORT;
15534            }
15535            lex->sql_command = SQLCOM_CREATE_FUNCTION;
15536            lex->udf.type= UDFTYPE_AGGREGATE;
15537            lex->stmt_definition_begin= @2.cpp.start;
15538            lex->udf.name = $3;
15539            lex->udf.returns=(Item_result) $5;
15540            lex->udf.dl=$7.str;
15541          }
15542        | FUNCTION_SYM ident
15543          RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
15544          {
15545            THD *thd= YYTHD;
15546            LEX *lex= thd->lex;
15547            if (is_native_function(thd, & $2))
15548            {
15549              my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
15550                       $2.str);
15551              MYSQL_YYABORT;
15552            }
15553            lex->sql_command = SQLCOM_CREATE_FUNCTION;
15554            lex->udf.type= UDFTYPE_FUNCTION;
15555            lex->stmt_definition_begin= @1.cpp.start;
15556            lex->udf.name = $2;
15557            lex->udf.returns=(Item_result) $4;
15558            lex->udf.dl=$6.str;
15559          }
15560        ;
15561
15562sf_tail:
15563          FUNCTION_SYM /* $1 */
15564          sp_name /* $2 */
15565          '(' /* $3 */
15566          { /* $4 */
15567            THD *thd= YYTHD;
15568            LEX *lex= thd->lex;
15569
15570            lex->stmt_definition_begin= @1.cpp.start;
15571            lex->spname= $2;
15572
15573            if (lex->sphead)
15574            {
15575              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
15576              MYSQL_YYABORT;
15577            }
15578
15579            sp_head *sp= sp_start_parsing(thd, SP_TYPE_FUNCTION, lex->spname);
15580
15581            if (!sp)
15582              MYSQL_YYABORT;
15583
15584            lex->sphead= sp;
15585
15586            sp->m_parser_data.set_parameter_start_ptr(@3.cpp.end);
15587          }
15588          sp_fdparam_list /* $5 */
15589          ')' /* $6 */
15590          { /* $7 */
15591            Lex->sphead->m_parser_data.set_parameter_end_ptr(@6.cpp.start);
15592          }
15593          RETURNS_SYM /* $8 */
15594          { /* $9 */
15595            LEX *lex= Lex;
15596            lex->charset= NULL;
15597            lex->length= lex->dec= NULL;
15598            lex->interval_list.empty();
15599            lex->type= 0;
15600            lex->gcol_info= 0;
15601          }
15602          type_with_opt_collate /* $10 */
15603          { /* $11 */
15604            LEX *lex= Lex;
15605            sp_head *sp= lex->sphead;
15606            /*
15607              This was disabled in 5.1.12. See bug #20701
15608              When collation support in SP is implemented, then this test
15609              should be removed.
15610            */
15611            if (($10 == MYSQL_TYPE_STRING || $10 == MYSQL_TYPE_VARCHAR)
15612                && (lex->type & BINCMP_FLAG))
15613            {
15614              my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
15615              MYSQL_YYABORT;
15616            }
15617
15618            if (fill_field_definition(YYTHD, sp,
15619                                      (enum enum_field_types) $10,
15620                                      &sp->m_return_field_def))
15621              MYSQL_YYABORT;
15622
15623            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
15624          }
15625          sp_c_chistics /* $12 */
15626          { /* $13 */
15627            THD *thd= YYTHD;
15628            LEX *lex= thd->lex;
15629
15630            lex->sphead->m_chistics= &lex->sp_chistics;
15631            lex->sphead->set_body_start(thd, yylloc.cpp.start);
15632          }
15633          sp_proc_stmt /* $14 */
15634          {
15635            THD *thd= YYTHD;
15636            LEX *lex= thd->lex;
15637            sp_head *sp= lex->sphead;
15638
15639            if (sp->is_not_allowed_in_function("function"))
15640              MYSQL_YYABORT;
15641
15642            sp_finish_parsing(thd);
15643
15644            lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
15645
15646            if (!(sp->m_flags & sp_head::HAS_RETURN))
15647            {
15648              my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
15649              MYSQL_YYABORT;
15650            }
15651
15652            if (is_native_function(thd, & sp->m_name))
15653            {
15654              /*
15655                This warning will be printed when
15656                [1] A client query is parsed,
15657                [2] A stored function is loaded by db_load_routine.
15658                Printing the warning for [2] is intentional, to cover the
15659                following scenario:
15660                - A user define a SF 'foo' using MySQL 5.N
15661                - An application uses select foo(), and works.
15662                - MySQL 5.{N+1} defines a new native function 'foo', as
15663                part of a new feature.
15664                - MySQL 5.{N+1} documentation is updated, and should mention
15665                that there is a potential incompatible change in case of
15666                existing stored function named 'foo'.
15667                - The user deploys 5.{N+1}. At this point, 'select foo()'
15668                means something different, and the user code is most likely
15669                broken (it's only safe if the code is 'select db.foo()').
15670                With a warning printed when the SF is loaded (which has to occur
15671                before the call), the warning will provide a hint explaining
15672                the root cause of a later failure of 'select foo()'.
15673                With no warning printed, the user code will fail with no
15674                apparent reason.
15675                Printing a warning each time db_load_routine is executed for
15676                an ambiguous function is annoying, since that can happen a lot,
15677                but in practice should not happen unless there *are* name
15678                collisions.
15679                If a collision exists, it should not be silenced but fixed.
15680              */
15681              push_warning_printf(thd,
15682                                  Sql_condition::SL_NOTE,
15683                                  ER_NATIVE_FCT_NAME_COLLISION,
15684                                  ER(ER_NATIVE_FCT_NAME_COLLISION),
15685                                  sp->m_name.str);
15686            }
15687          }
15688        ;
15689
15690sp_tail:
15691          PROCEDURE_SYM         /*$1*/
15692          sp_name               /*$2*/
15693          {                     /*$3*/
15694            THD *thd= YYTHD;
15695            LEX *lex= Lex;
15696
15697            if (lex->sphead)
15698            {
15699              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
15700              MYSQL_YYABORT;
15701            }
15702
15703            lex->stmt_definition_begin= @2.cpp.start;
15704
15705            sp_head *sp= sp_start_parsing(thd, SP_TYPE_PROCEDURE, $2);
15706
15707            if (!sp)
15708              MYSQL_YYABORT;
15709
15710            lex->sphead= sp;
15711          }
15712          '('                   /*$4*/
15713          {                     /*$5*/
15714            Lex->sphead->m_parser_data.set_parameter_start_ptr(@4.cpp.end);
15715          }
15716          sp_pdparam_list       /*$6*/
15717          ')'                   /*$7*/
15718          {                     /*$8*/
15719            THD *thd= YYTHD;
15720            LEX *lex= thd->lex;
15721
15722            lex->sphead->m_parser_data.set_parameter_end_ptr(@7.cpp.start);
15723            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
15724          }
15725          sp_c_chistics         /*$9*/
15726          {                     /*$10*/
15727            THD *thd= YYTHD;
15728            LEX *lex= thd->lex;
15729
15730            lex->sphead->m_chistics= &lex->sp_chistics;
15731            lex->sphead->set_body_start(thd, yylloc.cpp.start);
15732          }
15733          sp_proc_stmt          /*$11*/
15734          {                     /*$12*/
15735            THD *thd= YYTHD;
15736            LEX *lex= Lex;
15737
15738            sp_finish_parsing(thd);
15739
15740            lex->sql_command= SQLCOM_CREATE_PROCEDURE;
15741          }
15742        ;
15743
15744/*************************************************************************/
15745
15746xa:
15747          XA_SYM begin_or_start xid opt_join_or_resume
15748          {
15749            Lex->sql_command = SQLCOM_XA_START;
15750            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_start($3, $4);
15751          }
15752        | XA_SYM END xid opt_suspend
15753          {
15754            Lex->sql_command = SQLCOM_XA_END;
15755            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_end($3, $4);
15756          }
15757        | XA_SYM PREPARE_SYM xid
15758          {
15759            Lex->sql_command = SQLCOM_XA_PREPARE;
15760            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_prepare($3);
15761          }
15762        | XA_SYM COMMIT_SYM xid opt_one_phase
15763          {
15764            Lex->sql_command = SQLCOM_XA_COMMIT;
15765            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_commit($3, $4);
15766          }
15767        | XA_SYM ROLLBACK_SYM xid
15768          {
15769            Lex->sql_command = SQLCOM_XA_ROLLBACK;
15770            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_rollback($3);
15771          }
15772        | XA_SYM RECOVER_SYM opt_convert_xid
15773          {
15774            Lex->sql_command = SQLCOM_XA_RECOVER;
15775            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_xa_recover($3);
15776          }
15777        ;
15778
15779opt_convert_xid:
15780          /* empty */ { $$= false; }
15781         | CONVERT_SYM XID_SYM { $$= true; }
15782
15783xid:
15784          text_string
15785          {
15786            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
15787            XID *xid;
15788            if (!(xid= (XID *)YYTHD->alloc(sizeof(XID))))
15789              MYSQL_YYABORT;
15790            xid->set(1L, $1->ptr(), $1->length(), 0, 0);
15791            $$= xid;
15792          }
15793          | text_string ',' text_string
15794          {
15795            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE &&
15796                                 $3->length() <= MAXBQUALSIZE);
15797            XID *xid;
15798            if (!(xid= (XID *)YYTHD->alloc(sizeof(XID))))
15799              MYSQL_YYABORT;
15800            xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
15801            $$= xid;
15802          }
15803          | text_string ',' text_string ',' ulong_num
15804          {
15805            // check for overwflow of xid format id
15806            bool format_id_overflow_detected= ($5 > LONG_MAX);
15807
15808            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE &&
15809                                 $3->length() <= MAXBQUALSIZE
15810                                 && !format_id_overflow_detected);
15811
15812            XID *xid;
15813            if (!(xid= (XID *)YYTHD->alloc(sizeof(XID))))
15814              MYSQL_YYABORT;
15815            xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
15816            $$= xid;
15817          }
15818        ;
15819
15820begin_or_start:
15821          BEGIN_SYM {}
15822        | START_SYM {}
15823        ;
15824
15825opt_join_or_resume:
15826          /* nothing */ { $$= XA_NONE;        }
15827        | JOIN_SYM      { $$= XA_JOIN;        }
15828        | RESUME_SYM    { $$= XA_RESUME;      }
15829        ;
15830
15831opt_one_phase:
15832          /* nothing */     { $$= XA_NONE;        }
15833        | ONE_SYM PHASE_SYM { $$= XA_ONE_PHASE;   }
15834        ;
15835
15836opt_suspend:
15837          /* nothing */
15838          { $$= XA_NONE;        }
15839        | SUSPEND_SYM
15840          { $$= XA_SUSPEND;     }
15841        | SUSPEND_SYM FOR_SYM MIGRATE_SYM
15842          { $$= XA_FOR_MIGRATE; }
15843        ;
15844
15845install:
15846          INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys
15847          {
15848            LEX *lex= Lex;
15849            lex->sql_command= SQLCOM_INSTALL_PLUGIN;
15850            lex->m_sql_cmd= new Sql_cmd_install_plugin($3, $5);
15851          }
15852        ;
15853
15854uninstall:
15855          UNINSTALL_SYM PLUGIN_SYM ident
15856          {
15857            LEX *lex= Lex;
15858            lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
15859            lex->m_sql_cmd= new Sql_cmd_uninstall_plugin($3);
15860          }
15861        ;
15862
15863/**
15864  @} (end of group Parser)
15865*/
15866