1/*
2   Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
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  YYTHD->variables.character_set_client
38
39#define MYSQL_YACC
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_priv.h"
45#include "unireg.h"                    // REQUIRED: for other includes
46#include "sql_parse.h"                        /* comp_*_creator */
47#include "sql_table.h"                        /* primary_key_name */
48#include "sql_partition.h"  /* mem_alloc_error, partition_info, HASH_PARTITION */
49#include "sql_acl.h"                          /* *_ACL */
50#include "password.h"       /* my_make_scrambled_password_323, my_make_scrambled_password */
51#include "sql_class.h"      /* Key_part_spec, enum_filetype, Diag_condition_item_name */
52#include "rpl_slave.h"
53#include "lex_symbol.h"
54#include "item_create.h"
55#include "sp_head.h"
56#include "sp_instr.h"
57#include "sp_pcontext.h"
58#include "sp_rcontext.h"
59#include "sp.h"
60#include "sql_alter.h"                         // Sql_cmd_alter_table*
61#include "sql_truncate.h"                      // Sql_cmd_truncate_table
62#include "sql_admin.h"                         // Sql_cmd_analyze/Check..._table
63#include "sql_partition_admin.h"               // Sql_cmd_alter_table_*_part.
64#include "sql_handler.h"                       // Sql_cmd_handler_*
65#include "sql_signal.h"
66#include "sql_get_diagnostics.h"               // Sql_cmd_get_diagnostics
67#include "event_parse_data.h"
68#include <myisam.h>
69#include <myisammrg.h>
70#include "keycaches.h"
71#include "set_var.h"
72#include "opt_explain_traditional.h"
73#include "opt_explain_json.h"
74#include "lex_token.h"
75
76/* this is to get the bison compilation windows warnings out */
77#ifdef _MSC_VER
78/* warning C4065: switch statement contains 'default' but no 'case' labels */
79#pragma warning (disable : 4065)
80#endif
81
82using std::min;
83using std::max;
84
85int yylex(void *yylval, void *yythd);
86
87#define yyoverflow(A,B,C,D,E,F)               \
88  {                                           \
89    ulong val= *(F);                          \
90    if (my_yyoverflow((B), (D), &val))        \
91    {                                         \
92      yyerror(YYTHD, (char*) (A));            \
93      return 2;                               \
94    }                                         \
95    else                                      \
96    {                                         \
97      *(F)= (YYSIZE_T)val;                    \
98    }                                         \
99  }
100
101#define MYSQL_YYABORT                         \
102  do                                          \
103  {                                           \
104    LEX::cleanup_lex_after_parse_error(YYTHD);\
105    YYABORT;                                  \
106  } while (0)
107
108#define MYSQL_YYABORT_UNLESS(A)         \
109  if (!(A))                             \
110  {                                     \
111    my_parse_error(ER(ER_SYNTAX_ERROR));\
112    MYSQL_YYABORT;                      \
113  }
114
115/*
116  Work around for broken code generated by bison 1.875.
117
118  The code generated by bison 1.875a and later, bison 2.1 and bison 2.2 is ok.
119  With bison 1.875 however, the generated code contains:
120<pre>
121  yyerrlab1:
122  #if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__)
123    MY_ATTRIBUTE ((__unused__))
124  #endif
125</pre>
126  This usage of MY_ATTRIBUTE is illegal, so we remove it.
127  See the following references for details:
128  http://lists.gnu.org/archive/html/bug-bison/2004-02/msg00014.html
129  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14273
130*/
131
132#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__)
133#undef MY_ATTRIBUTE
134#define MY_ATTRIBUTE(X)
135#endif
136
137
138#ifndef DBUG_OFF
139#define YYDEBUG 1
140#else
141#define YYDEBUG 0
142#endif
143
144/**
145  @brief Push an error message into MySQL error stack with line
146  and position information.
147
148  This function provides semantic action implementers with a way
149  to push the famous "You have a syntax error near..." error
150  message into the error stack, which is normally produced only if
151  a parse error is discovered internally by the Bison generated
152  parser.
153*/
154
155void my_parse_error(const char *s)
156{
157  THD *thd= current_thd;
158  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
159
160  const char *yytext= lip->get_tok_start();
161  if (!yytext)
162    yytext= "";
163
164  /* Push an error into the error stack */
165  ErrConvString err(yytext, thd->variables.character_set_client);
166  my_printf_error(ER_PARSE_ERROR,  ER(ER_PARSE_ERROR), MYF(0), s,
167                  err.ptr(), lip->yylineno);
168}
169
170/**
171  @brief Bison callback to report a syntax/OOM error
172
173  This function is invoked by the bison-generated parser
174  when a syntax error, a parse error or an out-of-memory
175  condition occurs. This function is not invoked when the
176  parser is requested to abort by semantic action code
177  by means of YYABORT or YYACCEPT macros. This is why these
178  macros should not be used (use MYSQL_YYABORT/MYSQL_YYACCEPT
179  instead).
180
181  The parser will abort immediately after invoking this callback.
182
183  This function is not for use in semantic actions and is internal to
184  the parser, as it performs some pre-return cleanup.
185  In semantic actions, please use my_parse_error or my_error to
186  push an error into the error stack and MYSQL_YYABORT
187  to abort from the parser.
188*/
189
190void MYSQLerror(THD *thd, const char *s)
191{
192  /*
193    Restore the original LEX if it was replaced when parsing
194    a stored procedure. We must ensure that a parsing error
195    does not leave any side effects in the THD.
196  */
197  LEX::cleanup_lex_after_parse_error(thd);
198
199  /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */
200  if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0)
201    s= ER(ER_SYNTAX_ERROR);
202  my_parse_error(s);
203}
204
205
206#ifndef DBUG_OFF
207void turn_parser_debug_on()
208{
209  /*
210     MYSQLdebug is in sql/sql_yacc.cc, in bison generated code.
211     Turning this option on is **VERY** verbose, and should be
212     used when investigating a syntax error problem only.
213
214     The syntax to run with bison traces is as follows :
215     - Starting a server manually :
216       mysqld --debug="d,parser_debug" ...
217     - Running a test :
218       mysql-test-run.pl --mysqld="--debug=d,parser_debug" ...
219
220     The result will be in the process stderr (var/log/master.err)
221   */
222
223  extern int yydebug;
224  yydebug= 1;
225}
226#endif
227
228static bool is_native_function(THD *thd, const LEX_STRING *name)
229{
230  if (find_native_function_builder(thd, *name))
231    return true;
232
233  if (is_lex_native_function(name))
234    return true;
235
236  return false;
237}
238
239
240/**
241  Helper action for a case statement (entering the CASE).
242  This helper is used for both 'simple' and 'searched' cases.
243  This helper, with the other case_stmt_action_..., is executed when
244  the following SQL code is parsed:
245<pre>
246CREATE PROCEDURE proc_19194_simple(i int)
247BEGIN
248  DECLARE str CHAR(10);
249
250  CASE i
251    WHEN 1 THEN SET str="1";
252    WHEN 2 THEN SET str="2";
253    WHEN 3 THEN SET str="3";
254    ELSE SET str="unknown";
255  END CASE;
256
257  SELECT str;
258END
259</pre>
260  The actions are used to generate the following code:
261<pre>
262SHOW PROCEDURE CODE proc_19194_simple;
263Pos     Instruction
2640       set str@1 NULL
2651       set_case_expr (12) 0 i@0
2662       jump_if_not 5(12) (case_expr@0 = 1)
2673       set str@1 _latin1'1'
2684       jump 12
2695       jump_if_not 8(12) (case_expr@0 = 2)
2706       set str@1 _latin1'2'
2717       jump 12
2728       jump_if_not 11(12) (case_expr@0 = 3)
2739       set str@1 _latin1'3'
27410      jump 12
27511      set str@1 _latin1'unknown'
27612      stmt 0 "SELECT str"
277</pre>
278
279  @param thd thread handler
280*/
281
282void case_stmt_action_case(THD *thd)
283{
284  LEX *lex= thd->lex;
285  sp_head *sp= lex->sphead;
286  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
287
288  sp->m_parser_data.new_cont_backpatch();
289
290  /*
291    BACKPATCH: Creating target label for the jump to
292    "case_stmt_action_end_case"
293    (Instruction 12 in the example)
294  */
295
296  pctx->push_label(thd, EMPTY_STR, sp->instructions());
297}
298
299/**
300  Helper action for a case then statements.
301  This helper is used for both 'simple' and 'searched' cases.
302  @param lex the parser lex context
303*/
304
305bool case_stmt_action_then(THD *thd, LEX *lex)
306{
307  sp_head *sp= lex->sphead;
308  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
309
310  sp_instr_jump *i =
311    new (thd->mem_root) sp_instr_jump(sp->instructions(), pctx);
312
313  if (!i || sp->add_instr(thd, i))
314    return true;
315
316  /*
317    BACKPATCH: Resolving forward jump from
318    "case_stmt_action_when" to "case_stmt_action_then"
319    (jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
320  */
321
322  sp->m_parser_data.do_backpatch(pctx->pop_label(), sp->instructions());
323
324  /*
325    BACKPATCH: Registering forward jump from
326    "case_stmt_action_then" to "case_stmt_action_end_case"
327    (jump from instruction 4 to 12, 7 to 12 ... in the example)
328  */
329
330  return sp->m_parser_data.add_backpatch_entry(i, pctx->last_label());
331}
332
333/**
334  Helper action for an end case.
335  This helper is used for both 'simple' and 'searched' cases.
336  @param lex the parser lex context
337  @param simple true for simple cases, false for searched cases
338*/
339
340void case_stmt_action_end_case(LEX *lex, bool simple)
341{
342  sp_head *sp= lex->sphead;
343  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
344
345  /*
346    BACKPATCH: Resolving forward jump from
347    "case_stmt_action_then" to "case_stmt_action_end_case"
348    (jump from instruction 4 to 12, 7 to 12 ... in the example)
349  */
350  sp->m_parser_data.do_backpatch(pctx->pop_label(), sp->instructions());
351
352  if (simple)
353    pctx->pop_case_expr_id();
354
355  sp->m_parser_data.do_cont_backpatch(sp->instructions());
356}
357
358
359static bool
360find_sys_var_null_base(THD *thd, struct sys_var_with_base *tmp)
361{
362  tmp->var= find_sys_var(thd, tmp->base_name.str, tmp->base_name.length);
363
364  if (tmp->var == NULL)
365    my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), tmp->base_name.str);
366  else
367    tmp->base_name= null_lex_str;
368
369  return thd->is_error();
370}
371
372
373/**
374  Helper action for a SET statement.
375  Used to push a system variable into the assignment list.
376
377  @param thd      the current thread
378  @param tmp      the system variable with base name
379  @param var_type the scope of the variable
380  @param val      the value being assigned to the variable
381
382  @return TRUE if error, FALSE otherwise.
383*/
384
385static bool
386set_system_variable(THD *thd, struct sys_var_with_base *tmp,
387                    enum enum_var_type var_type, Item *val)
388{
389  set_var *var;
390  LEX *lex= thd->lex;
391  sp_head *sp= lex->sphead;
392  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
393
394  /* No AUTOCOMMIT from a stored function or trigger. */
395  if (pctx && tmp->var == Sys_autocommit_ptr)
396    sp->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
397
398#ifdef HAVE_REPLICATION
399  if (lex->uses_stored_routines() &&
400      ((tmp->var == Sys_gtid_next_ptr
401#ifdef HAVE_GTID_NEXT_LIST
402       || tmp->var == Sys_gtid_next_list_ptr
403#endif
404       ) ||
405       Sys_gtid_purged_ptr == tmp->var))
406  {
407    my_error(ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION, MYF(0),
408             tmp->var->name.str);
409    return TRUE;
410  }
411#endif
412
413  if (val && val->type() == Item::FIELD_ITEM &&
414      ((Item_field*)val)->table_name)
415  {
416    my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), tmp->var->name.str);
417    return TRUE;
418  }
419
420  if (! (var= new set_var(var_type, tmp->var, &tmp->base_name, val)))
421    return TRUE;
422
423  return lex->var_list.push_back(var);
424}
425
426
427/**
428  Helper action for a SET statement.
429  Used to SET a field of NEW row.
430
431  @param thd                thread handler
432  @param trigger_field_name the NEW-row field name
433  @param expr_item          the value expression being assigned
434  @param expr_query         the value expression query
435
436  @return error status (true if error, false otherwise).
437*/
438
439static bool set_trigger_new_row(THD *thd,
440                                LEX_STRING trigger_field_name,
441                                Item *expr_item,
442                                LEX_STRING expr_query)
443{
444  LEX *lex= thd->lex;
445  sp_head *sp= lex->sphead;
446
447  DBUG_ASSERT(expr_item);
448  DBUG_ASSERT(sp->m_trg_chistics.action_time == TRG_ACTION_BEFORE &&
449              (sp->m_trg_chistics.event == TRG_EVENT_INSERT ||
450               sp->m_trg_chistics.event == TRG_EVENT_UPDATE));
451
452  Item_trigger_field *trg_fld=
453    new (thd->mem_root) Item_trigger_field(lex->current_context(),
454                                           Item_trigger_field::NEW_ROW,
455                                           trigger_field_name.str,
456                                           UPDATE_ACL, false);
457
458  if (!trg_fld)
459    return true;
460
461  sp_instr_set_trigger_field *i=
462    new (thd->mem_root)
463      sp_instr_set_trigger_field(sp->instructions(),
464                                 lex,
465                                 trigger_field_name,
466                                 trg_fld, expr_item,
467                                 expr_query);
468
469  if (!i)
470    return true;
471
472  /*
473    Let us add this item to list of all Item_trigger_field
474    objects in trigger.
475  */
476  sp->m_cur_instr_trig_field_items.link_in_list(trg_fld,
477                                                &trg_fld->next_trg_field);
478
479  return sp->add_instr(thd, i);
480}
481
482
483/**
484  Create an object to represent a SP variable in the Item-hierarchy.
485
486  @param thd              The current thread.
487  @param name             The SP variable name.
488  @param spv              The SP variable (optional).
489  @param query_start_ptr  Start of the SQL-statement query string (optional).
490  @param start_in_q       Start position of the SP variable name in the query.
491  @param end_in_q         End position of the SP variable name in the query.
492
493  @remark If spv is not specified, the name is used to search for the
494          variable in the parse-time context. If the variable does not
495          exist, a error is set and NULL is returned to the caller.
496
497  @return An Item_splocal object representing the SP variable, or NULL on error.
498*/
499static Item_splocal* create_item_for_sp_var(THD *thd,
500                                            LEX_STRING name,
501                                            sp_variable *spv,
502                                            const char *query_start_ptr,
503                                            const char *start_in_q,
504                                            const char *end_in_q)
505{
506  LEX *lex= thd->lex;
507  uint spv_pos_in_query= 0;
508  uint spv_len_in_query= 0;
509  sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
510
511  /* If necessary, look for the variable. */
512  if (pctx && !spv)
513    spv= pctx->find_variable(name, false);
514
515  if (!spv)
516  {
517    my_error(ER_SP_UNDECLARED_VAR, MYF(0), name.str);
518    return NULL;
519  }
520
521  DBUG_ASSERT(pctx && spv);
522
523  if (query_start_ptr)
524  {
525    /* Position and length of the SP variable name in the query. */
526    spv_pos_in_query= start_in_q - query_start_ptr;
527    spv_len_in_query= end_in_q - start_in_q;
528  }
529
530  Item_splocal *item=
531    new (thd->mem_root) Item_splocal(
532      name, spv->offset, spv->type, spv_pos_in_query, spv_len_in_query);
533
534#ifndef DBUG_OFF
535  if (item)
536    item->m_sp= lex->sphead;
537#endif
538
539  return item;
540}
541
542
543/**
544  Helper to resolve the SQL:2003 Syntax exception 1) in <in predicate>.
545  See SQL:2003, Part 2, section 8.4 <in predicate>, Note 184, page 383.
546  This function returns the proper item for the SQL expression
547  <code>left [NOT] IN ( expr )</code>
548  @param thd the current thread
549  @param left the in predicand
550  @param equal true for IN predicates, false for NOT IN predicates
551  @param expr first and only expression of the in value list
552  @return an expression representing the IN predicate.
553*/
554Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal,
555                                       Item *expr)
556{
557  /*
558    Relevant references for this issue:
559    - SQL:2003, Part 2, section 8.4 <in predicate>, page 383,
560    - SQL:2003, Part 2, section 7.2 <row value expression>, page 296,
561    - SQL:2003, Part 2, section 6.3 <value expression primary>, page 174,
562    - SQL:2003, Part 2, section 7.15 <subquery>, page 370,
563    - SQL:2003 Feature F561, "Full value expressions".
564
565    The exception in SQL:2003 Note 184 means:
566    Item_singlerow_subselect, which corresponds to a <scalar subquery>,
567    should be re-interpreted as an Item_in_subselect, which corresponds
568    to a <table subquery> when used inside an <in predicate>.
569
570    Our reading of Note 184 is reccursive, so that all:
571    - IN (( <subquery> ))
572    - IN ((( <subquery> )))
573    - IN '('^N <subquery> ')'^N
574    - etc
575    should be interpreted as a <table subquery>, no matter how deep in the
576    expression the <subquery> is.
577  */
578
579  Item *result;
580
581  DBUG_ENTER("handle_sql2003_note184_exception");
582
583  if (expr->type() == Item::SUBSELECT_ITEM)
584  {
585    Item_subselect *expr2 = (Item_subselect*) expr;
586
587    if (expr2->substype() == Item_subselect::SINGLEROW_SUBS)
588    {
589      Item_singlerow_subselect *expr3 = (Item_singlerow_subselect*) expr2;
590      st_select_lex *subselect;
591
592      /*
593        Implement the mandated change, by altering the semantic tree:
594          left IN Item_singlerow_subselect(subselect)
595        is modified to
596          left IN (subselect)
597        which is represented as
598          Item_in_subselect(left, subselect)
599      */
600      subselect= expr3->invalidate_and_restore_select_lex();
601      result= new (thd->mem_root) Item_in_subselect(left, subselect);
602
603      if (! equal)
604        result = negate_expression(thd, result);
605
606      DBUG_RETURN(result);
607    }
608  }
609
610  if (equal)
611    result= new (thd->mem_root) Item_func_eq(left, expr);
612  else
613    result= new (thd->mem_root) Item_func_ne(left, expr);
614
615  DBUG_RETURN(result);
616}
617
618/**
619   @brief Creates a new SELECT_LEX for a UNION branch.
620
621   Sets up and initializes a SELECT_LEX structure for a query once the parser
622   discovers a UNION token. The current SELECT_LEX is pushed on the stack and
623   the new SELECT_LEX becomes the current one.
624
625   @param lex The parser state.
626
627   @param is_union_distinct True if the union preceding the new select statement
628   uses UNION DISTINCT.
629
630   @param is_top_level This should be @c TRUE if the newly created SELECT_LEX
631   is a non-nested statement.
632
633   @return <code>false</code> if successful, <code>true</code> if an error was
634   reported. In the latter case parsing should stop.
635 */
636bool add_select_to_union_list(LEX *lex, bool is_union_distinct,
637                              bool is_top_level)
638{
639  /*
640     Only the last SELECT can have INTO. Since the grammar won't allow INTO in
641     a nested SELECT, we make this check only when creating a top-level SELECT.
642  */
643  if (is_top_level && lex->result)
644  {
645    my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
646    return TRUE;
647  }
648  if (lex->proc_analyse)
649  {
650    my_error(ER_WRONG_USAGE, MYF(0), "UNION", "SELECT ... PROCEDURE ANALYSE()");
651    return TRUE;
652  }
653  if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
654  {
655    my_parse_error(ER(ER_SYNTAX_ERROR));
656    return TRUE;
657  }
658  /* This counter shouldn't be incremented for UNION parts */
659  lex->nest_level--;
660  if (mysql_new_select(lex, 0))
661    return TRUE;
662  mysql_init_select(lex);
663  lex->current_select->linkage=UNION_TYPE;
664  if (is_union_distinct) /* UNION DISTINCT - remember position */
665    lex->current_select->master_unit()->union_distinct=
666      lex->current_select;
667  return FALSE;
668}
669
670/**
671   @brief Initializes a SELECT_LEX for a query within parentheses (aka
672   braces).
673
674   @return false if successful, true if an error was reported. In the latter
675   case parsing should stop.
676 */
677bool setup_select_in_parentheses(LEX *lex)
678{
679  SELECT_LEX * sel= lex->current_select;
680  if (sel->set_braces(1))
681  {
682    my_parse_error(ER(ER_SYNTAX_ERROR));
683    return TRUE;
684  }
685  if (sel->linkage == UNION_TYPE &&
686      !sel->master_unit()->first_select()->braces &&
687      sel->master_unit()->first_select()->linkage ==
688      UNION_TYPE)
689  {
690    my_parse_error(ER(ER_SYNTAX_ERROR));
691    return TRUE;
692  }
693  if (sel->linkage == UNION_TYPE &&
694      sel->olap != UNSPECIFIED_OLAP_TYPE &&
695      sel->master_unit()->fake_select_lex)
696  {
697    my_error(ER_WRONG_USAGE, MYF(0), "CUBE/ROLLUP", "ORDER BY");
698    return TRUE;
699  }
700  /* select in braces, can't contain global parameters */
701  if (sel->master_unit()->fake_select_lex)
702    sel->master_unit()->global_parameters=
703      sel->master_unit()->fake_select_lex;
704  return FALSE;
705}
706
707static bool add_create_index_prepare (LEX *lex, Table_ident *table)
708{
709  lex->sql_command= SQLCOM_CREATE_INDEX;
710  if (!lex->current_select->add_table_to_list(lex->thd, table, NULL,
711                                              TL_OPTION_UPDATING,
712                                              TL_READ_NO_INSERT,
713                                              MDL_SHARED_UPGRADABLE))
714    return TRUE;
715  lex->alter_info.reset();
716  lex->alter_info.flags= Alter_info::ALTER_ADD_INDEX;
717  lex->col_list.empty();
718  lex->change= NullS;
719  return FALSE;
720}
721
722static bool add_create_index (LEX *lex, Key::Keytype type,
723                              const LEX_STRING &name,
724                              KEY_CREATE_INFO *info= NULL, bool generated= 0)
725{
726  Key *key;
727  key= new Key(type, name, info ? info : &lex->key_create_info, generated,
728               lex->col_list);
729  if (key == NULL)
730    return TRUE;
731
732  lex->alter_info.key_list.push_back(key);
733  lex->col_list.empty();
734  return FALSE;
735}
736
737/**
738  Make a new string allocated on THD's mem-root.
739
740  @param thd        thread handler.
741  @param start_ptr  start of the new string.
742  @param end_ptr    end of the new string.
743
744  @return LEX_STRING object, containing a pointer to a newly
745  constructed/allocated string, and its length. The pointer is NULL
746  in case of out-of-memory error.
747*/
748static LEX_STRING make_string(THD *thd,
749                              const char *start_ptr,
750                              const char *end_ptr)
751{
752  LEX_STRING s;
753
754  s.length= end_ptr - start_ptr;
755  s.str= (char *) thd->alloc(s.length + 1);
756
757  if (s.str)
758    strmake(s.str, start_ptr, s.length);
759
760  return s;
761}
762
763/*
764  The start is either lip->ptr, if there was no lookahead, lip->tok_start
765  otherwise.
766*/
767#define YY_TOKEN_START \
768  ((yychar == YYEMPTY) ?  YYLIP->get_ptr() : YYLIP->get_tok_start())
769
770/*
771   The end is either lip->ptr, if there was no lookahead,
772   or lip->tok_end otherwise.
773*/
774
775#define YY_TOKEN_END \
776  ((yychar == YYEMPTY) ?  YYLIP->get_ptr() : YYLIP->get_tok_end())
777
778/**
779  Create a separate LEX for each assignment if in SP.
780
781  If we are in SP we want have own LEX for each assignment.
782  This is mostly because it is hard for several sp_instr_set
783  and sp_instr_set_trigger instructions share one LEX.
784  (Well, it is theoretically possible but adds some extra
785  overhead on preparation for execution stage and IMO less
786  robust).
787
788  @see sp_create_assignment_instr
789
790  @param thd        Thread context
791  @param option_ptr Option-value-expression start pointer
792*/
793
794static void sp_create_assignment_lex(THD *thd, const char *option_ptr)
795{
796  LEX *lex= thd->lex;
797  sp_head *sp= lex->sphead;
798
799  /*
800    We can come here in the following cases:
801
802      1. it's a regular SET statement outside stored programs
803        (lex->sphead is NULL);
804
805      2. we're parsing a stored program normally (loading from mysql.proc, ...);
806
807      3. we're re-parsing SET-statement with a user variable after meta-data
808        change. It's guaranteed, that:
809        - this SET-statement deals with a user/system variable (otherwise, it
810          would be a different SP-instruction, and we would parse an expression);
811        - this SET-statement has a single user/system variable assignment
812          (that's how we generate sp_instr_stmt-instructions for SET-statements).
813        So, in this case, even if lex->sphead is set, we should not process
814        further.
815  */
816
817  if (!sp ||            // case #1
818      sp->is_invoked()) // case #3
819  {
820    return;
821  }
822
823  LEX *old_lex= lex;
824  sp->reset_lex(thd);
825  lex= thd->lex;
826
827  /* Set new LEX as if we at start of set rule. */
828  mysql_init_select(lex);
829  lex->sql_command= SQLCOM_SET_OPTION;
830  lex->var_list.empty();
831  lex->one_shot_set= 0;
832  lex->autocommit= 0;
833
834  /*
835    It's a SET statement within SP. It will be either translated
836    into one or more sp_instr_stmt instructions, or it will be
837    sp_instr_set / sp_instr_set_trigger_field instructions.
838    In any case, position of SP-variable can not be determined
839    reliably. So, we set the start pointer of the current statement
840    to NULL.
841  */
842  sp->m_parser_data.set_current_stmt_start_ptr(NULL);
843  sp->m_parser_data.set_option_start_ptr(option_ptr);
844
845  /* Inherit from outer lex. */
846  lex->option_type= old_lex->option_type;
847}
848
849
850/**
851  Create a SP instruction for a SET assignment.
852
853  @see sp_create_assignment_lex
854
855  @param thd           Thread context
856  @param expr_end_ptr  Option-value-expression end pointer
857
858  @return false if success, true otherwise.
859*/
860
861static bool sp_create_assignment_instr(THD *thd, const char *expr_end_ptr)
862{
863  LEX *lex= thd->lex;
864  sp_head *sp= lex->sphead;
865
866  /*
867    We can come here in the following cases:
868
869      1. it's a regular SET statement outside stored programs
870        (lex->sphead is NULL);
871
872      2. we're parsing a stored program normally (loading from mysql.proc, ...);
873
874      3. we're re-parsing SET-statement with a user variable after meta-data
875        change. It's guaranteed, that:
876        - this SET-statement deals with a user/system variable (otherwise, it
877          would be a different SP-instruction, and we would parse an expression);
878        - this SET-statement has a single user/system variable assignment
879          (that's how we generate sp_instr_stmt-instructions for SET-statements).
880        So, in this case, even if lex->sphead is set, we should not process
881        further.
882  */
883
884  if (!sp ||            // case #1
885      sp->is_invoked()) // case #3
886  {
887    return false;
888  }
889
890  if (!lex->var_list.is_empty())
891  {
892    /* Extract expression string. */
893
894    const char *expr_start_ptr= sp->m_parser_data.get_option_start_ptr();
895
896    LEX_STRING expr;
897    expr.str= (char *) expr_start_ptr;
898    expr.length= expr_end_ptr - expr_start_ptr;
899
900    /* Construct SET-statement query. */
901
902    LEX_STRING set_stmt_query;
903
904    set_stmt_query.length= expr.length + 3;
905    set_stmt_query.str= (char *) thd->alloc(set_stmt_query.length + 1);
906
907    if (!set_stmt_query.str)
908      return true;
909
910    strmake(strmake(set_stmt_query.str, "SET", 3),
911            expr.str, expr.length);
912
913    /*
914      We have assignment to user or system variable or option setting, so we
915      should construct sp_instr_stmt for it.
916    */
917
918    sp_instr_stmt *i=
919      new (thd->mem_root)
920        sp_instr_stmt(sp->instructions(), lex, set_stmt_query);
921
922    if (!i || sp->add_instr(thd, i))
923      return true;
924  }
925
926  /* Remember option_type of the currently parsed LEX. */
927  enum_var_type inner_option_type= lex->option_type;
928
929  if (sp->restore_lex(thd))
930    return true;
931
932  /* Copy option_type to outer lex in case it has changed. */
933  thd->lex->option_type= inner_option_type;
934
935  return false;
936}
937
938/**
939  Compare a LEX_USER against the current user as defined by the exact user and
940  host used during authentication.
941
942  @param user A pointer to a user which needs to be matched against the
943              current.
944
945  @see SET PASSWORD rules
946
947  @retval true The specified user is the authorized user
948  @retval false The user doesn't match
949*/
950
951bool match_authorized_user(Security_context *ctx, LEX_USER *user)
952{
953  if(user->user.str && my_strcasecmp(system_charset_info,
954                                     ctx->priv_user,
955                                     user->user.str) == 0)
956  {
957    /*
958      users match; let's compare hosts.
959      1. first compare with the host we actually authorized,
960      2. then see if we match the host mask of the priv_host
961    */
962    if (user->host.str && my_strcasecmp(system_charset_info,
963                                        user->host.str,
964                                        ctx->priv_host) == 0)
965    {
966      /* specified user exactly match the authorized user */
967      return true;
968    }
969  }
970  return false;
971}
972
973
974%}
975%union {
976  int  num;
977  ulong ulong_num;
978  ulonglong ulonglong_number;
979  longlong longlong_number;
980  LEX_STRING lex_str;
981  LEX_CSTRING lex_cstr;
982  LEX_STRING *lex_str_ptr;
983  LEX_SYMBOL symbol;
984  Table_ident *table;
985  char *simple_string;
986  Item *item;
987  Item_num *item_num;
988  List<Item> *item_list;
989  List<String> *string_list;
990  String *string;
991  Key_part_spec *key_part;
992  TABLE_LIST *table_list;
993  udf_func *udf;
994  LEX_USER *lex_user;
995  struct sys_var_with_base variable;
996  enum enum_var_type var_type;
997  Key::Keytype key_type;
998  enum ha_key_alg key_alg;
999  handlerton *db_type;
1000  enum row_type row_type;
1001  enum ha_rkey_function ha_rkey_mode;
1002  enum enum_ha_read_modes ha_read_mode;
1003  enum enum_tx_isolation tx_isolation;
1004  enum Cast_target cast_type;
1005  enum Item_udftype udf_type;
1006  const CHARSET_INFO *charset;
1007  thr_lock_type lock_type;
1008  interval_type interval, interval_time_st;
1009  timestamp_type date_time_type;
1010  st_select_lex *select_lex;
1011  chooser_compare_func_creator boolfunc2creator;
1012  class sp_condition_value *spcondvalue;
1013  struct { int vars, conds, hndlrs, curs; } spblock;
1014  sp_name *spname;
1015  LEX *lex;
1016  sp_head *sphead;
1017  struct p_elem_val *p_elem_value;
1018  enum index_hint_type index_hint;
1019  enum enum_filetype filetype;
1020  enum Foreign_key::fk_option m_fk_option;
1021  enum enum_yes_no_unknown m_yes_no_unk;
1022  Diag_condition_item_name diag_condition_item_name;
1023  Diagnostics_information::Which_area diag_area;
1024  Diagnostics_information *diag_info;
1025  Statement_information_item *stmt_info_item;
1026  Statement_information_item::Name stmt_info_item_name;
1027  List<Statement_information_item> *stmt_info_list;
1028  Condition_information_item *cond_info_item;
1029  Condition_information_item::Name cond_info_item_name;
1030  List<Condition_information_item> *cond_info_list;
1031  bool is_not_empty;
1032}
1033
1034%{
1035bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
1036%}
1037
1038%parse-param { class THD *YYTHD }
1039%lex-param { class THD *YYTHD }
1040%pure-parser                                    /* We have threads */
1041/*
1042  Currently there are 161 shift/reduce conflicts.
1043  We should not introduce new conflicts any more.
1044*/
1045%expect 164
1046
1047/*
1048   Comments for TOKENS.
1049   For each token, please include in the same line a comment that contains
1050   the following tags:
1051   SQL-2003-R : Reserved keyword as per SQL-2003
1052   SQL-2003-N : Non Reserved keyword as per SQL-2003
1053   SQL-1999-R : Reserved keyword as per SQL-1999
1054   SQL-1999-N : Non Reserved keyword as per SQL-1999
1055   MYSQL      : MySQL extention (unspecified)
1056   MYSQL-FUNC : MySQL extention, function
1057   INTERNAL   : Not a real token, lex optimization
1058   OPERATOR   : SQL operator
1059   FUTURE-USE : Reserved for futur use
1060
1061   This makes the code grep-able, and helps maintenance.
1062*/
1063
1064%token  ABORT_SYM                     /* INTERNAL (used in lex) */
1065%token  ACCESSIBLE_SYM
1066%token  ACTION                        /* SQL-2003-N */
1067%token  ADD                           /* SQL-2003-R */
1068%token  ADDDATE_SYM                   /* MYSQL-FUNC */
1069%token  AFTER_SYM                     /* SQL-2003-N */
1070%token  AGAINST
1071%token  AGGREGATE_SYM
1072%token  ALGORITHM_SYM
1073%token  ALL                           /* SQL-2003-R */
1074%token  ALTER                         /* SQL-2003-R */
1075%token  ANALYSE_SYM
1076%token  ANALYZE_SYM
1077%token  AND_AND_SYM                   /* OPERATOR */
1078%token  AND_SYM                       /* SQL-2003-R */
1079%token  ANY_SYM                       /* SQL-2003-R */
1080%token  ARCHIVED_SYM                  /* MYSQL      */
1081%token  AS                            /* SQL-2003-R */
1082%token  ASC                           /* SQL-2003-N */
1083%token  ASCII_SYM                     /* MYSQL-FUNC */
1084%token  ASENSITIVE_SYM                /* FUTURE-USE */
1085%token  AT_SYM                        /* SQL-2003-R */
1086%token  AUTOEXTEND_SIZE_SYM
1087%token  AUTO_INC
1088%token  AVG_ROW_LENGTH
1089%token  AVG_SYM                       /* SQL-2003-N */
1090%token  BACKUP_SYM
1091%token  BEFORE_SYM                    /* SQL-2003-N */
1092%token  BEGIN_SYM                     /* SQL-2003-R */
1093%token  BETWEEN_SYM                   /* SQL-2003-R */
1094%token  BIGINT                        /* SQL-2003-R */
1095%token  BINARY                        /* SQL-2003-R */
1096%token  BINLOG_SYM
1097%token  BIN_NUM
1098%token  BIT_AND                       /* MYSQL-FUNC */
1099%token  BIT_OR                        /* MYSQL-FUNC */
1100%token  BIT_SYM                       /* MYSQL-FUNC */
1101%token  BIT_XOR                       /* MYSQL-FUNC */
1102%token  BLOB_SYM                      /* SQL-2003-R */
1103%token  BLOCK_SYM
1104%token  BOOLEAN_SYM                   /* SQL-2003-R */
1105%token  BOOL_SYM
1106%token  BOTH                          /* SQL-2003-R */
1107%token  BTREE_SYM
1108%token  BY                            /* SQL-2003-R */
1109%token  BYTE_SYM
1110%token  CACHE_SYM
1111%token  CALL_SYM                      /* SQL-2003-R */
1112%token  CASCADE                       /* SQL-2003-N */
1113%token  CASCADED                      /* SQL-2003-R */
1114%token  CASE_SYM                      /* SQL-2003-R */
1115%token  CAST_SYM                      /* SQL-2003-R */
1116%token  CATALOG_NAME_SYM              /* SQL-2003-N */
1117%token  CHAIN_SYM                     /* SQL-2003-N */
1118%token  CHANGE
1119%token  CHANGED
1120%token  CHANGED_PAGE_BITMAPS_SYM      /* MYSQL      */
1121%token  CHARSET
1122%token  CHAR_SYM                      /* SQL-2003-R */
1123%token  CHECKSUM_SYM
1124%token  CHECK_SYM                     /* SQL-2003-R */
1125%token  CIPHER_SYM
1126%token  CLASS_ORIGIN_SYM              /* SQL-2003-N */
1127%token  CLIENT_SYM
1128%token  CLIENT_STATS_SYM
1129%token  CLOSE_SYM                     /* SQL-2003-R */
1130%token  CLUSTERING_SYM
1131%token  COALESCE                      /* SQL-2003-N */
1132%token  CODE_SYM
1133%token  COLLATE_SYM                   /* SQL-2003-R */
1134%token  COLLATION_SYM                 /* SQL-2003-N */
1135%token  COLUMNS
1136%token  COLUMN_SYM                    /* SQL-2003-R */
1137%token  COLUMN_FORMAT_SYM
1138%token  COLUMN_NAME_SYM               /* SQL-2003-N */
1139%token  COMMENT_SYM
1140%token  COMMITTED_SYM                 /* SQL-2003-N */
1141%token  COMMIT_SYM                    /* SQL-2003-R */
1142%token  COMPACT_SYM
1143%token  COMPLETION_SYM
1144%token  COMPRESSED_SYM
1145%token  COMPRESSION_DICTIONARY_SYM
1146%token  CONCURRENT
1147%token  CONDITION_SYM                 /* SQL-2003-R, SQL-2008-R */
1148%token  CONNECTION_SYM
1149%token  CONSISTENT_SYM
1150%token  CONSTRAINT                    /* SQL-2003-R */
1151%token  CONSTRAINT_CATALOG_SYM        /* SQL-2003-N */
1152%token  CONSTRAINT_NAME_SYM           /* SQL-2003-N */
1153%token  CONSTRAINT_SCHEMA_SYM         /* SQL-2003-N */
1154%token  CONTAINS_SYM                  /* SQL-2003-N */
1155%token  CONTEXT_SYM
1156%token  CONTINUE_SYM                  /* SQL-2003-R */
1157%token  CONVERT_SYM                   /* SQL-2003-N */
1158%token  COUNT_SYM                     /* SQL-2003-N */
1159%token  CPU_SYM
1160%token  CREATE                        /* SQL-2003-R */
1161%token  CROSS                         /* SQL-2003-R */
1162%token  CUBE_SYM                      /* SQL-2003-R */
1163%token  CURDATE                       /* MYSQL-FUNC */
1164%token  CURRENT_SYM                   /* SQL-2003-R */
1165%token  CURRENT_USER                  /* SQL-2003-R */
1166%token  CURSOR_SYM                    /* SQL-2003-R */
1167%token  CURSOR_NAME_SYM               /* SQL-2003-N */
1168%token  CURTIME                       /* MYSQL-FUNC */
1169%token  DATABASE
1170%token  DATABASES
1171%token  DATAFILE_SYM
1172%token  DATA_SYM                      /* SQL-2003-N */
1173%token  DATETIME
1174%token  DATE_ADD_INTERVAL             /* MYSQL-FUNC */
1175%token  DATE_SUB_INTERVAL             /* MYSQL-FUNC */
1176%token  DATE_SYM                      /* SQL-2003-R */
1177%token  DAY_HOUR_SYM
1178%token  DAY_MICROSECOND_SYM
1179%token  DAY_MINUTE_SYM
1180%token  DAY_SECOND_SYM
1181%token  DAY_SYM                       /* SQL-2003-R */
1182%token  DEALLOCATE_SYM                /* SQL-2003-R */
1183%token  DECIMAL_NUM
1184%token  DECIMAL_SYM                   /* SQL-2003-R */
1185%token  DECLARE_SYM                   /* SQL-2003-R */
1186%token  DEFAULT                       /* SQL-2003-R */
1187%token  DEFAULT_AUTH_SYM              /* INTERNAL */
1188%token  DEFINER_SYM
1189%token  DELAYED_SYM
1190%token  DELAY_KEY_WRITE_SYM
1191%token  DELETE_SYM                    /* SQL-2003-R */
1192%token  DESC                          /* SQL-2003-N */
1193%token  DESCRIBE                      /* SQL-2003-R */
1194%token  DES_KEY_FILE
1195%token  DETERMINISTIC_SYM             /* SQL-2003-R */
1196%token  DIAGNOSTICS_SYM               /* SQL-2003-N */
1197%token  DIRECTORY_SYM
1198%token  DISABLE_SYM
1199%token  DISCARD
1200%token  DISK_SYM
1201%token  DISTINCT                      /* SQL-2003-R */
1202%token  DIV_SYM
1203%token  DOUBLE_SYM                    /* SQL-2003-R */
1204%token  DO_SYM
1205%token  DROP                          /* SQL-2003-R */
1206%token  DUAL_SYM
1207%token  DUMPFILE
1208%token  DUPLICATE_SYM
1209%token  DYNAMIC_SYM                   /* SQL-2003-R */
1210%token  EACH_SYM                      /* SQL-2003-R */
1211%token  ELSE                          /* SQL-2003-R */
1212%token  ELSEIF_SYM
1213%token  ENABLE_SYM
1214%token  ENCLOSED
1215%token  END                           /* SQL-2003-R */
1216%token  ENDS_SYM
1217%token  END_OF_INPUT                  /* INTERNAL */
1218%token  ENGINES_SYM
1219%token  ENGINE_SYM
1220%token  ENUM
1221%token  EQ                            /* OPERATOR */
1222%token  EQUAL_SYM                     /* OPERATOR */
1223%token  ERROR_SYM
1224%token  ERRORS
1225%token  ESCAPED
1226%token  ESCAPE_SYM                    /* SQL-2003-R */
1227%token  EVENTS_SYM
1228%token  EVENT_SYM
1229%token  EVERY_SYM                     /* SQL-2003-N */
1230%token  EXCHANGE_SYM
1231%token  EXECUTE_SYM                   /* SQL-2003-R */
1232%token  EXISTS                        /* SQL-2003-R */
1233%token  EXIT_SYM
1234%token  EXPANSION_SYM
1235%token  EXPIRE_SYM
1236%token  EXPORT_SYM
1237%token  EXTENDED_SYM
1238%token  EXTENT_SIZE_SYM
1239%token  EXTRACT_SYM                   /* SQL-2003-N */
1240%token  FALSE_SYM                     /* SQL-2003-R */
1241%token  FAST_SYM
1242%token  FAULTS_SYM
1243%token  FETCH_SYM                     /* SQL-2003-R */
1244%token  FILE_SYM
1245%token  FIRST_SYM                     /* SQL-2003-N */
1246%token  FIXED_SYM
1247%token  FLOAT_NUM
1248%token  FLOAT_SYM                     /* SQL-2003-R */
1249%token  FLUSH_SYM
1250%token  FORCE_SYM
1251%token  FOREIGN                       /* SQL-2003-R */
1252%token  FOR_SYM                       /* SQL-2003-R */
1253%token  FORMAT_SYM
1254%token  FOUND_SYM                     /* SQL-2003-R */
1255%token  FROM
1256%token  FULL                          /* SQL-2003-R */
1257%token  FULLTEXT_SYM
1258%token  FUNCTION_SYM                  /* SQL-2003-R */
1259%token  GE
1260%token  GENERAL
1261%token  GEOMETRYCOLLECTION
1262%token  GEOMETRY_SYM
1263%token  GET_FORMAT                    /* MYSQL-FUNC */
1264%token  GET_SYM                       /* SQL-2003-R */
1265%token  GLOBAL_SYM                    /* SQL-2003-R */
1266%token  GRANT                         /* SQL-2003-R */
1267%token  GRANTS
1268%token  GROUP_SYM                     /* SQL-2003-R */
1269%token  GROUP_CONCAT_SYM
1270%token  GT_SYM                        /* OPERATOR */
1271%token  HANDLER_SYM
1272%token  HASH_SYM
1273%token  HAVING                        /* SQL-2003-R */
1274%token  HELP_SYM
1275%token  HEX_NUM
1276%token  HIGH_PRIORITY
1277%token  HOST_SYM
1278%token  HOSTS_SYM
1279%token  HOUR_MICROSECOND_SYM
1280%token  HOUR_MINUTE_SYM
1281%token  HOUR_SECOND_SYM
1282%token  HOUR_SYM                      /* SQL-2003-R */
1283%token  IDENT
1284%token  IDENTIFIED_SYM
1285%token  IDENT_QUOTED
1286%token  IF
1287%token  IGNORE_SYM
1288%token  IGNORE_SERVER_IDS_SYM
1289%token  IMPORT
1290%token  INDEXES
1291%token  INDEX_SYM
1292%token  INDEX_STATS_SYM
1293%token  INFILE
1294%token  INITIAL_SIZE_SYM
1295%token  INNER_SYM                     /* SQL-2003-R */
1296%token  INOUT_SYM                     /* SQL-2003-R */
1297%token  INSENSITIVE_SYM               /* SQL-2003-R */
1298%token  INSERT                        /* SQL-2003-R */
1299%token  INSERT_METHOD
1300%token  INSTALL_SYM
1301%token  INTERVAL_SYM                  /* SQL-2003-R */
1302%token  INTO                          /* SQL-2003-R */
1303%token  INT_SYM                       /* SQL-2003-R */
1304%token  INVOKER_SYM
1305%token  IN_SYM                        /* SQL-2003-R */
1306%token  IO_AFTER_GTIDS                /* MYSQL, FUTURE-USE */
1307%token  IO_BEFORE_GTIDS               /* MYSQL, FUTURE-USE */
1308%token  IO_SYM
1309%token  IPC_SYM
1310%token  IS                            /* SQL-2003-R */
1311%token  ISOLATION                     /* SQL-2003-R */
1312%token  ISSUER_SYM
1313%token  ITERATE_SYM
1314%token  JOIN_SYM                      /* SQL-2003-R */
1315%token  KEYS
1316%token  KEY_BLOCK_SIZE
1317%token  KEY_SYM                       /* SQL-2003-N */
1318%token  KILL_SYM
1319%token  LANGUAGE_SYM                  /* SQL-2003-R */
1320%token  LAST_SYM                      /* SQL-2003-N */
1321%token  LE                            /* OPERATOR */
1322%token  LEADING                       /* SQL-2003-R */
1323%token  LEAVES
1324%token  LEAVE_SYM
1325%token  LEFT                          /* SQL-2003-R */
1326%token  LESS_SYM
1327%token  LEVEL_SYM
1328%token  LEX_HOSTNAME
1329%token  LIKE                          /* SQL-2003-R */
1330%token  LIMIT
1331%token  LINEAR_SYM
1332%token  LINES
1333%token  LINESTRING
1334%token  LIST_SYM
1335%token  LOAD
1336%token  LOCAL_SYM                     /* SQL-2003-R */
1337%token  LOCATOR_SYM                   /* SQL-2003-N */
1338%token  LOCKS_SYM
1339%token  LOCK_SYM
1340%token  LOGFILE_SYM
1341%token  LOGS_SYM
1342%token  LONGBLOB
1343%token  LONGTEXT
1344%token  LONG_NUM
1345%token  LONG_SYM
1346%token  LOOP_SYM
1347%token  LOW_PRIORITY
1348%token  LT                            /* OPERATOR */
1349%token  MASTER_AUTO_POSITION_SYM
1350%token  MASTER_BIND_SYM
1351%token  MASTER_CONNECT_RETRY_SYM
1352%token  MASTER_DELAY_SYM
1353%token  MASTER_HOST_SYM
1354%token  MASTER_LOG_FILE_SYM
1355%token  MASTER_LOG_POS_SYM
1356%token  MASTER_PASSWORD_SYM
1357%token  MASTER_PORT_SYM
1358%token  MASTER_RETRY_COUNT_SYM
1359%token  MASTER_SERVER_ID_SYM
1360%token  MASTER_SSL_CAPATH_SYM
1361%token  MASTER_SSL_CA_SYM
1362%token  MASTER_SSL_CERT_SYM
1363%token  MASTER_SSL_CIPHER_SYM
1364%token  MASTER_SSL_CRL_SYM
1365%token  MASTER_SSL_CRLPATH_SYM
1366%token  MASTER_SSL_KEY_SYM
1367%token  MASTER_SSL_SYM
1368%token  MASTER_SSL_VERIFY_SERVER_CERT_SYM
1369%token  MASTER_SYM
1370%token  MASTER_USER_SYM
1371%token  MASTER_HEARTBEAT_PERIOD_SYM
1372%token  MATCH                         /* SQL-2003-R */
1373%token  MAX_CONNECTIONS_PER_HOUR
1374%token  MAX_QUERIES_PER_HOUR
1375%token  MAX_ROWS
1376%token  MAX_SIZE_SYM
1377%token  MAX_SYM                       /* SQL-2003-N */
1378%token  MAX_UPDATES_PER_HOUR
1379%token  MAX_USER_CONNECTIONS_SYM
1380%token  MAX_VALUE_SYM                 /* SQL-2003-N */
1381%token  MEDIUMBLOB
1382%token  MEDIUMINT
1383%token  MEDIUMTEXT
1384%token  MEDIUM_SYM
1385%token  MEMORY_SYM
1386%token  MERGE_SYM                     /* SQL-2003-R */
1387%token  MESSAGE_TEXT_SYM              /* SQL-2003-N */
1388%token  MICROSECOND_SYM               /* MYSQL-FUNC */
1389%token  MIGRATE_SYM
1390%token  MINUTE_MICROSECOND_SYM
1391%token  MINUTE_SECOND_SYM
1392%token  MINUTE_SYM                    /* SQL-2003-R */
1393%token  MIN_ROWS
1394%token  MIN_SYM                       /* SQL-2003-N */
1395%token  MODE_SYM
1396%token  MODIFIES_SYM                  /* SQL-2003-R */
1397%token  MODIFY_SYM
1398%token  MOD_SYM                       /* SQL-2003-N */
1399%token  MONTH_SYM                     /* SQL-2003-R */
1400%token  MULTILINESTRING
1401%token  MULTIPOINT
1402%token  MULTIPOLYGON
1403%token  MUTEX_SYM
1404%token  MYSQL_ERRNO_SYM
1405%token  NAMES_SYM                     /* SQL-2003-N */
1406%token  NAME_SYM                      /* SQL-2003-N */
1407%token  NATIONAL_SYM                  /* SQL-2003-R */
1408%token  NATURAL                       /* SQL-2003-R */
1409%token  NCHAR_STRING
1410%token  NCHAR_SYM                     /* SQL-2003-R */
1411%token  NDBCLUSTER_SYM
1412%token  NE                            /* OPERATOR */
1413%token  NEG
1414%token  NEW_SYM                       /* SQL-2003-R */
1415%token  NEXT_SYM                      /* SQL-2003-N */
1416%token  NODEGROUP_SYM
1417%token  NONE_SYM                      /* SQL-2003-R */
1418%token  NOT2_SYM
1419%token  NOT_SYM                       /* SQL-2003-R */
1420%token  NOW_SYM
1421%token  NO_SYM                        /* SQL-2003-R */
1422%token  NO_WAIT_SYM
1423%token  NO_WRITE_TO_BINLOG
1424%token  NULL_SYM                      /* SQL-2003-R */
1425%token  NUM
1426%token  NUMBER_SYM                    /* SQL-2003-N */
1427%token  NUMERIC_SYM                   /* SQL-2003-R */
1428%token  NVARCHAR_SYM
1429%token  OFFSET_SYM
1430%token  OLD_PASSWORD
1431%token  ON                            /* SQL-2003-R */
1432%token  ONE_SYM
1433%token  ONLY_SYM                      /* SQL-2003-R */
1434%token  OPEN_SYM                      /* SQL-2003-R */
1435%token  OPTIMIZE
1436%token  OPTIONS_SYM
1437%token  OPTION                        /* SQL-2003-N */
1438%token  OPTIONALLY
1439%token  OR2_SYM
1440%token  ORDER_SYM                     /* SQL-2003-R */
1441%token  OR_OR_SYM                     /* OPERATOR */
1442%token  OR_SYM                        /* SQL-2003-R */
1443%token  OUTER
1444%token  OUTFILE
1445%token  OUT_SYM                       /* SQL-2003-R */
1446%token  OWNER_SYM
1447%token  PACK_KEYS_SYM
1448%token  PAGE_SYM
1449%token  PARAM_MARKER
1450%token  PARSER_SYM
1451%token  PARTIAL                       /* SQL-2003-N */
1452%token  PARTITION_SYM                 /* SQL-2003-R */
1453%token  PARTITIONS_SYM
1454%token  PARTITIONING_SYM
1455%token  PASSWORD
1456%token  PHASE_SYM
1457%token  PLUGIN_DIR_SYM                /* INTERNAL */
1458%token  PLUGIN_SYM
1459%token  PLUGINS_SYM
1460%token  POINT_SYM
1461%token  POLYGON
1462%token  PORT_SYM
1463%token  POSITION_SYM                  /* SQL-2003-N */
1464%token  PRECISION                     /* SQL-2003-R */
1465%token  PREPARE_SYM                   /* SQL-2003-R */
1466%token  PRESERVE_SYM
1467%token  PREV_SYM
1468%token  PRIMARY_SYM                   /* SQL-2003-R */
1469%token  PRIVILEGES                    /* SQL-2003-N */
1470%token  PROCEDURE_SYM                 /* SQL-2003-R */
1471%token  PROCESS
1472%token  PROCESSLIST_SYM
1473%token  PROFILE_SYM
1474%token  PROFILES_SYM
1475%token  PROXY_SYM
1476%token  PURGE
1477%token  QUARTER_SYM
1478%token  QUERY_SYM
1479%token  QUICK
1480%token  RANGE_SYM                     /* SQL-2003-R */
1481%token  READS_SYM                     /* SQL-2003-R */
1482%token  READ_ONLY_SYM
1483%token  READ_SYM                      /* SQL-2003-N */
1484%token  READ_WRITE_SYM
1485%token  REAL                          /* SQL-2003-R */
1486%token  REBUILD_SYM
1487%token  RECOVER_SYM
1488%token  REDOFILE_SYM
1489%token  REDO_BUFFER_SIZE_SYM
1490%token  REDUNDANT_SYM
1491%token  REFERENCES                    /* SQL-2003-R */
1492%token  REGEXP
1493%token  RELAY
1494%token  RELAYLOG_SYM
1495%token  RELAY_LOG_FILE_SYM
1496%token  RELAY_LOG_POS_SYM
1497%token  RELAY_THREAD
1498%token  RELEASE_SYM                   /* SQL-2003-R */
1499%token  RELOAD
1500%token  REMOVE_SYM
1501%token  RENAME
1502%token  REORGANIZE_SYM
1503%token  REPAIR
1504%token  REPEATABLE_SYM                /* SQL-2003-N */
1505%token  REPEAT_SYM                    /* MYSQL-FUNC */
1506%token  REPLACE                       /* MYSQL-FUNC */
1507%token  REPLICATION
1508%token  REQUIRE_SYM
1509%token  RESET_SYM
1510%token  RESIGNAL_SYM                  /* SQL-2003-R */
1511%token  RESOURCES
1512%token  RESTORE_SYM
1513%token  RESTRICT
1514%token  RESUME_SYM
1515%token  RETURNED_SQLSTATE_SYM         /* SQL-2003-N */
1516%token  RETURNS_SYM                   /* SQL-2003-R */
1517%token  RETURN_SYM                    /* SQL-2003-R */
1518%token  REVERSE_SYM
1519%token  REVOKE                        /* SQL-2003-R */
1520%token  RIGHT                         /* SQL-2003-R */
1521%token  ROLLBACK_SYM                  /* SQL-2003-R */
1522%token  ROLLUP_SYM                    /* SQL-2003-R */
1523%token  ROUTINE_SYM                   /* SQL-2003-N */
1524%token  ROWS_SYM                      /* SQL-2003-R */
1525%token  ROW_FORMAT_SYM
1526%token  ROW_SYM                       /* SQL-2003-R */
1527%token  ROW_COUNT_SYM                 /* SQL-2003-N */
1528%token  RTREE_SYM
1529%token  SAVEPOINT_SYM                 /* SQL-2003-R */
1530%token  SCHEDULE_SYM
1531%token  SCHEMA_NAME_SYM               /* SQL-2003-N */
1532%token  SECOND_MICROSECOND_SYM
1533%token  SECOND_SYM                    /* SQL-2003-R */
1534%token  SECURITY_SYM                  /* SQL-2003-N */
1535%token  SELECT_SYM                    /* SQL-2003-R */
1536%token  SENSITIVE_SYM                 /* FUTURE-USE */
1537%token  SEPARATOR_SYM
1538%token  SERIALIZABLE_SYM              /* SQL-2003-N */
1539%token  SERIAL_SYM
1540%token  SESSION_SYM                   /* SQL-2003-N */
1541%token  SERVER_SYM
1542%token  SERVER_OPTIONS
1543%token  SET                           /* SQL-2003-R */
1544%token  SET_VAR
1545%token  SHARE_SYM
1546%token  SHIFT_LEFT                    /* OPERATOR */
1547%token  SHIFT_RIGHT                   /* OPERATOR */
1548%token  SHOW
1549%token  SHUTDOWN
1550%token  SIGNAL_SYM                    /* SQL-2003-R */
1551%token  SIGNED_SYM
1552%token  SIMPLE_SYM                    /* SQL-2003-N */
1553%token  SLAVE
1554%token  SLOW
1555%token  SMALLINT                      /* SQL-2003-R */
1556%token  SNAPSHOT_SYM
1557%token  SOCKET_SYM
1558%token  SONAME_SYM
1559%token  SOUNDS_SYM
1560%token  SOURCE_SYM
1561%token  SPATIAL_SYM
1562%token  SPECIFIC_SYM                  /* SQL-2003-R */
1563%token  SQLEXCEPTION_SYM              /* SQL-2003-R */
1564%token  SQLSTATE_SYM                  /* SQL-2003-R */
1565%token  SQLWARNING_SYM                /* SQL-2003-R */
1566%token  SQL_AFTER_GTIDS               /* MYSQL */
1567%token  SQL_AFTER_MTS_GAPS            /* MYSQL */
1568%token  SQL_BEFORE_GTIDS              /* MYSQL */
1569%token  SQL_BIG_RESULT
1570%token  SQL_BUFFER_RESULT
1571%token  SQL_CACHE_SYM
1572%token  SQL_CALC_FOUND_ROWS
1573%token  SQL_NO_CACHE_SYM
1574%token  SQL_SMALL_RESULT
1575%token  SQL_SYM                       /* SQL-2003-R */
1576%token  SQL_THREAD
1577%token  SSL_SYM
1578%token  STARTING
1579%token  STARTS_SYM
1580%token  START_SYM                     /* SQL-2003-R */
1581%token  STATEMENT_SYM
1582%token  STATS_AUTO_RECALC_SYM
1583%token  STATS_PERSISTENT_SYM
1584%token  STATS_SAMPLE_PAGES_SYM
1585%token  STATUS_SYM
1586%token  NOLOCK_SYM                    /* SHOW SLAVE STATUS NOLOCK */
1587%token  NONBLOCKING_SYM
1588%token  STDDEV_SAMP_SYM               /* SQL-2003-N */
1589%token  STD_SYM
1590%token  STOP_SYM
1591%token  STORAGE_SYM
1592%token  STRAIGHT_JOIN
1593%token  STRING_SYM
1594%token  SUBCLASS_ORIGIN_SYM           /* SQL-2003-N */
1595%token  SUBDATE_SYM
1596%token  SUBJECT_SYM
1597%token  SUBPARTITIONS_SYM
1598%token  SUBPARTITION_SYM
1599%token  SUBSTRING                     /* SQL-2003-N */
1600%token  SUM_SYM                       /* SQL-2003-N */
1601%token  SUPER_SYM
1602%token  SUSPEND_SYM
1603%token  SWAPS_SYM
1604%token  SWITCHES_SYM
1605%token  SYSDATE
1606%token  TABLES
1607%token  TABLESPACE
1608%token  TABLE_REF_PRIORITY
1609%token  TABLE_SYM                     /* SQL-2003-R */
1610%token  TABLE_STATS_SYM
1611%token  TABLE_CHECKSUM_SYM
1612%token  TABLE_NAME_SYM                /* SQL-2003-N */
1613%token  TEMPORARY                     /* SQL-2003-N */
1614%token  TEMPTABLE_SYM
1615%token  TERMINATED
1616%token  TEXT_STRING
1617%token  TEXT_SYM
1618%token  THAN_SYM
1619%token  THEN_SYM                      /* SQL-2003-R */
1620%token  THREAD_STATS_SYM
1621%token  TIMESTAMP                     /* SQL-2003-R */
1622%token  TIMESTAMP_ADD
1623%token  TIMESTAMP_DIFF
1624%token  TIME_SYM                      /* SQL-2003-R */
1625%token  TINYBLOB
1626%token  TINYINT
1627%token  TINYTEXT
1628%token  TO_SYM                        /* SQL-2003-R */
1629%token  TOKU_UNCOMPRESSED_SYM
1630%token  TOKU_ZLIB_SYM
1631%token  TOKU_SNAPPY_SYM
1632%token  TOKU_QUICKLZ_SYM
1633%token  TOKU_LZMA_SYM
1634%token  TOKU_FAST_SYM
1635%token  TOKU_SMALL_SYM
1636%token  TOKU_DEFAULT_SYM
1637%token  TRAILING                      /* SQL-2003-R */
1638%token  TRANSACTION_SYM
1639%token  TRIGGERS_SYM
1640%token  TRIGGER_SYM                   /* SQL-2003-R */
1641%token  TRIM                          /* SQL-2003-N */
1642%token  TRUE_SYM                      /* SQL-2003-R */
1643%token  TRUNCATE_SYM
1644%token  TYPES_SYM
1645%token  TYPE_SYM                      /* SQL-2003-N */
1646%token  UDF_RETURNS_SYM
1647%token  ULONGLONG_NUM
1648%token  UNCOMMITTED_SYM               /* SQL-2003-N */
1649%token  UNDEFINED_SYM
1650%token  UNDERSCORE_CHARSET
1651%token  UNDOFILE_SYM
1652%token  UNDO_BUFFER_SIZE_SYM
1653%token  UNDO_SYM                      /* FUTURE-USE */
1654%token  UNICODE_SYM
1655%token  UNINSTALL_SYM
1656%token  UNION_SYM                     /* SQL-2003-R */
1657%token  UNIQUE_SYM
1658%token  UNKNOWN_SYM                   /* SQL-2003-R */
1659%token  UNLOCK_SYM
1660%token  UNSIGNED
1661%token  UNTIL_SYM
1662%token  UPDATE_SYM                    /* SQL-2003-R */
1663%token  UPGRADE_SYM
1664%token  USAGE                         /* SQL-2003-N */
1665%token  USER                          /* SQL-2003-R */
1666%token  USER_STATS_SYM
1667%token  USE_FRM
1668%token  USE_SYM
1669%token  USING                         /* SQL-2003-R */
1670%token  UTC_DATE_SYM
1671%token  UTC_TIMESTAMP_SYM
1672%token  UTC_TIME_SYM
1673%token  VALUES                        /* SQL-2003-R */
1674%token  VALUE_SYM                     /* SQL-2003-R */
1675%token  VARBINARY
1676%token  VARCHAR                       /* SQL-2003-R */
1677%token  VARIABLES
1678%token  VARIANCE_SYM
1679%token  VARYING                       /* SQL-2003-R */
1680%token  VAR_SAMP_SYM
1681%token  VIEW_SYM                      /* SQL-2003-N */
1682%token  WAIT_SYM
1683%token  WARNINGS
1684%token  WEEK_SYM
1685%token  WEIGHT_STRING_SYM
1686%token  WHEN_SYM                      /* SQL-2003-R */
1687%token  WHERE                         /* SQL-2003-R */
1688%token  WHILE_SYM
1689%token  WITH                          /* SQL-2003-R */
1690%token  WITH_CUBE_SYM                 /* INTERNAL */
1691%token  WITH_ROLLUP_SYM               /* INTERNAL */
1692%token  WORK_SYM                      /* SQL-2003-N */
1693%token  WRAPPER_SYM
1694%token  WRITE_SYM                     /* SQL-2003-N */
1695%token  X509_SYM
1696%token  XA_SYM
1697%token  XML_SYM
1698%token  XOR
1699%token  YEAR_MONTH_SYM
1700%token  YEAR_SYM                      /* SQL-2003-R */
1701%token  ZEROFILL
1702
1703%left   JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
1704/* A dummy token to force the priority of table_ref production in a join. */
1705%left   TABLE_REF_PRIORITY
1706%left   SET_VAR
1707%left   OR_OR_SYM OR_SYM OR2_SYM
1708%left   XOR
1709%left   AND_SYM AND_AND_SYM
1710%left   BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
1711%left   EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
1712%left   '|'
1713%left   '&'
1714%left   SHIFT_LEFT SHIFT_RIGHT
1715%left   '-' '+'
1716%left   '*' '/' '%' DIV_SYM MOD_SYM
1717%left   '^'
1718%left   NEG '~'
1719%right  NOT_SYM NOT2_SYM
1720%right  BINARY COLLATE_SYM
1721%left  INTERVAL_SYM
1722
1723%type <lex_str>
1724        IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM
1725        LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
1726        IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
1727        NCHAR_STRING opt_component key_cache_name
1728        sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
1729        opt_constraint constraint opt_ident TEXT_STRING_sys_nonewline
1730
1731%type <lex_cstr>
1732        opt_with_compression_dictionary
1733
1734%type <lex_str_ptr>
1735        opt_table_alias
1736
1737%type <table>
1738        table_ident table_ident_nodb references xid
1739        table_ident_opt_wild
1740
1741%type <simple_string>
1742        remember_name remember_end opt_db text_or_password
1743
1744%type <string>
1745        text_string opt_gconcat_separator
1746
1747%type <num>
1748        type type_with_opt_collate int_type real_type order_dir lock_option
1749        udf_type if_exists opt_local opt_table_options table_options
1750        table_option opt_if_not_exists opt_no_write_to_binlog
1751        opt_temporary all_or_any opt_distinct
1752        opt_ignore_leaves fulltext_options spatial_type union_option
1753        union_opt select_derived_init transaction_access_mode_types
1754        opt_natural_language_mode opt_query_expansion
1755        opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
1756        ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
1757        trg_action_time trg_event
1758
1759/*
1760  Bit field of MYSQL_START_TRANS_OPT_* flags.
1761*/
1762%type <num> opt_start_transaction_option_list
1763%type <num> start_transaction_option_list
1764%type <num> start_transaction_option
1765
1766%type <m_yes_no_unk>
1767        opt_chain opt_release
1768
1769%type <m_fk_option>
1770        delete_option
1771
1772%type <ulong_num>
1773        ulong_num real_ulong_num merge_insert_types
1774        ws_nweights func_datetime_precision
1775        ws_level_flag_desc ws_level_flag_reverse ws_level_flags
1776        opt_ws_levels ws_level_list ws_level_list_item ws_level_number
1777        ws_level_range ws_level_list_or_range
1778
1779%type <ulonglong_number>
1780        ulonglong_num real_ulonglong_num size_number
1781        procedure_analyse_param
1782
1783%type <lock_type>
1784        replace_lock_option opt_low_priority insert_lock_option load_data_lock
1785
1786%type <item>
1787        literal text_literal insert_ident order_ident temporal_literal
1788        simple_ident expr opt_expr opt_else sum_expr in_sum_expr
1789        variable variable_aux bool_pri
1790        predicate bit_expr
1791        table_wild simple_expr udf_expr
1792        expr_or_default set_expr_or_default
1793        param_marker geometry_function
1794        signed_literal now now_or_signed_literal opt_escape
1795        sp_opt_default
1796        simple_ident_nospvar simple_ident_q
1797        field_or_var limit_option
1798        part_func_expr
1799        function_call_keyword
1800        function_call_nonkeyword
1801        function_call_generic
1802        function_call_conflict
1803        signal_allowed_expr
1804        simple_target_specification
1805        condition_number
1806        create_compression_dictionary_allowed_expr
1807
1808%type <item_num>
1809        NUM_literal
1810
1811%type <item_list>
1812        expr_list opt_udf_expr_list udf_expr_list when_list
1813        ident_list ident_list_arg opt_expr_list
1814
1815%type <var_type>
1816        option_type opt_var_type opt_var_ident_type
1817
1818%type <key_type>
1819        normal_key_type opt_unique_combo_clustering constraint_key_type
1820        fulltext spatial unique_opt_clustering unique_combo_clustering unique clustering
1821
1822%type <key_alg>
1823        btree_or_rtree
1824
1825%type <string_list>
1826        using_list opt_use_partition use_partition
1827
1828%type <key_part>
1829        key_part
1830
1831%type <table_list>
1832        join_table_list  join_table
1833        table_factor table_ref esc_table_ref
1834        select_derived derived_table_list
1835        select_derived_union
1836
1837%type <date_time_type> date_time_type;
1838%type <interval> interval
1839
1840%type <interval_time_st> interval_time_stamp
1841
1842%type <db_type> storage_engines known_storage_engines
1843
1844%type <row_type> row_types
1845
1846%type <tx_isolation> isolation_types
1847
1848%type <ha_rkey_mode> handler_rkey_mode
1849
1850%type <ha_read_mode> handler_read_or_scan handler_scan_function
1851        handler_rkey_function
1852
1853%type <cast_type> cast_type
1854
1855%type <symbol> keyword keyword_sp
1856
1857%type <lex_user> user grant_user
1858
1859%type <charset>
1860        opt_collate
1861        charset_name
1862        charset_name_or_default
1863        old_or_new_charset_name
1864        old_or_new_charset_name_or_default
1865        collation_name
1866        collation_name_or_default
1867        opt_load_data_charset
1868        UNDERSCORE_CHARSET
1869
1870%type <variable> internal_variable_name
1871
1872%type <select_lex> subselect
1873        get_select_lex query_specification
1874        query_expression_body
1875
1876%type <boolfunc2creator> comp_op
1877
1878%type <NONE>
1879        query verb_clause create change select do drop insert replace insert2
1880        insert_values update delete truncate rename
1881        show describe load alter optimize keycache preload flush
1882        reset purge begin commit rollback savepoint release
1883        slave master_def master_defs master_file_def slave_until_opts
1884        repair analyze check start checksum
1885        field_list field_list_item field_spec kill column_def key_def
1886        keycache_list keycache_list_or_parts assign_to_keycache
1887        assign_to_keycache_parts
1888        preload_list preload_list_or_parts preload_keys preload_keys_parts
1889        select_item_list select_item values_list no_braces
1890        opt_limit_clause delete_limit_clause fields opt_values values
1891        opt_procedure_analyse_params
1892        handler
1893        opt_precision opt_ignore opt_column opt_restrict
1894        grant revoke set lock unlock string_list field_options field_option
1895        field_opt_list opt_binary ascii unicode table_lock_list table_lock
1896        ref_list opt_match_clause opt_on_update_delete use
1897        opt_delete_options opt_delete_option varchar nchar nvarchar
1898        opt_outer table_list table_name table_alias_ref_list table_alias_ref
1899        opt_place
1900        opt_attribute opt_attribute_list attribute column_list column_list_id
1901        opt_column_list grant_privileges grant_ident grant_list grant_option
1902        object_privilege object_privilege_list user_list rename_list
1903        clear_privileges flush_options flush_option
1904        opt_flush_lock flush_options_list
1905        equal optional_braces
1906        opt_mi_check_type opt_to mi_check_types normal_join
1907        table_to_table_list table_to_table opt_table_list opt_as
1908        single_multi table_wild_list table_wild_one opt_wild
1909        union_clause union_list
1910        precision subselect_start opt_and charset
1911        subselect_end select_var_list select_var_list_init help
1912        field_length opt_field_length
1913        opt_extended_describe
1914        prepare prepare_src execute deallocate
1915        statement sp_suid
1916        sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
1917        opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
1918        view_replace_or_algorithm view_replace
1919        view_algorithm view_or_trigger_or_sp_or_event
1920        definer_tail no_definer_tail
1921        view_suid view_tail view_list_opt view_list view_select
1922        view_check_option trigger_tail sp_tail sf_tail udf_tail event_tail
1923        install uninstall partition_entry binlog_base64_event
1924        init_key_options normal_key_options normal_key_opts all_key_opt
1925        spatial_key_options fulltext_key_options normal_key_opt
1926        fulltext_key_opt spatial_key_opt fulltext_key_opts spatial_key_opts
1927        key_using_alg
1928        part_column_list
1929        server_def server_options_list server_option
1930        definer_opt no_definer definer get_diagnostics
1931        alter_user_list
1932END_OF_INPUT
1933
1934%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
1935%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return
1936%type <NONE> sp_proc_stmt_if
1937%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled
1938%type <NONE> sp_labeled_block sp_unlabeled_block
1939%type <NONE> sp_proc_stmt_leave
1940%type <NONE> sp_proc_stmt_iterate
1941%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
1942%type <NONE> case_stmt_specification simple_case_stmt searched_case_stmt
1943
1944%type <num>  sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
1945%type <spcondvalue> sp_cond sp_hcond sqlstate signal_value opt_signal_value
1946%type <spblock> sp_decls sp_decl
1947%type <spname> sp_name
1948%type <index_hint> index_hint_type
1949%type <num> index_hint_clause
1950%type <filetype> data_or_xml
1951
1952%type <NONE> signal_stmt resignal_stmt
1953%type <diag_condition_item_name> signal_condition_information_item_name
1954
1955%type <diag_area> which_area;
1956%type <diag_info> diagnostics_information;
1957%type <stmt_info_item> statement_information_item;
1958%type <stmt_info_item_name> statement_information_item_name;
1959%type <stmt_info_list> statement_information;
1960%type <cond_info_item> condition_information_item;
1961%type <cond_info_item_name> condition_information_item_name;
1962%type <cond_info_list> condition_information;
1963
1964%type <NONE>
1965        '-' '+' '*' '/' '%' '(' ')'
1966        ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
1967        THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM DELETE_SYM
1968
1969/*
1970  A bit field of SLAVE_IO, SLAVE_SQL flags.
1971*/
1972%type <num> opt_slave_thread_option_list
1973%type <num> slave_thread_option_list
1974%type <num> slave_thread_option
1975
1976%type <is_not_empty> opt_union_order_or_limit
1977
1978%%
1979
1980/*
1981  Indentation of grammar rules:
1982
1983rule: <-- starts at col 1
1984          rule1a rule1b rule1c <-- starts at col 11
1985          { <-- starts at col 11
1986            code <-- starts at col 13, indentation is 2 spaces
1987          }
1988        | rule2a rule2b
1989          {
1990            code
1991          }
1992        ; <-- on a line by itself, starts at col 9
1993
1994  Also, please do not use any <TAB>, but spaces.
1995  Having a uniform indentation in this file helps
1996  code reviews, patches, merges, and make maintenance easier.
1997  Tip: grep [[:cntrl:]] sql_yacc.yy
1998  Thanks.
1999*/
2000
2001query:
2002          END_OF_INPUT
2003          {
2004            THD *thd= YYTHD;
2005            if (!thd->bootstrap &&
2006              (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
2007            {
2008              my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
2009              MYSQL_YYABORT;
2010            }
2011            thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
2012            YYLIP->found_semicolon= NULL;
2013          }
2014        | verb_clause
2015          {
2016            Lex_input_stream *lip = YYLIP;
2017
2018            if ((YYTHD->client_capabilities & CLIENT_MULTI_QUERIES) &&
2019                lip->multi_statements &&
2020                ! lip->eof())
2021            {
2022              /*
2023                We found a well formed query, and multi queries are allowed:
2024                - force the parser to stop after the ';'
2025                - mark the start of the next query for the next invocation
2026                  of the parser.
2027              */
2028              lip->next_state= MY_LEX_END;
2029              lip->found_semicolon= lip->get_ptr();
2030            }
2031            else
2032            {
2033              /* Single query, terminated. */
2034              lip->found_semicolon= NULL;
2035            }
2036          }
2037          ';'
2038          opt_end_of_input
2039        | verb_clause END_OF_INPUT
2040          {
2041            /* Single query, not terminated. */
2042            YYLIP->found_semicolon= NULL;
2043          }
2044        ;
2045
2046opt_end_of_input:
2047          /* empty */
2048        | END_OF_INPUT
2049        ;
2050
2051verb_clause:
2052          statement
2053        | begin
2054        ;
2055
2056/* Verb clauses, except begin */
2057statement:
2058          alter
2059        | analyze
2060        | binlog_base64_event
2061        | call
2062        | change
2063        | check
2064        | checksum
2065        | commit
2066        | create
2067        | deallocate
2068        | delete
2069        | describe
2070        | do
2071        | drop
2072        | execute
2073        | flush
2074        | get_diagnostics
2075        | grant
2076        | handler
2077        | help
2078        | insert
2079        | install
2080        | kill
2081        | load
2082        | lock
2083        | optimize
2084        | keycache
2085        | partition_entry
2086        | preload
2087        | prepare
2088        | purge
2089        | release
2090        | rename
2091        | repair
2092        | replace
2093        | reset
2094        | resignal_stmt
2095        | revoke
2096        | rollback
2097        | savepoint
2098        | select
2099        | set
2100        | signal_stmt
2101        | show
2102        | slave
2103        | start
2104        | truncate
2105        | uninstall
2106        | unlock
2107        | update
2108        | use
2109        | xa
2110        ;
2111
2112deallocate:
2113          deallocate_or_drop PREPARE_SYM ident
2114          {
2115            THD *thd= YYTHD;
2116            LEX *lex= thd->lex;
2117            lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
2118            lex->prepared_stmt_name= $3;
2119          }
2120        ;
2121
2122deallocate_or_drop:
2123          DEALLOCATE_SYM
2124        | DROP
2125        ;
2126
2127prepare:
2128          PREPARE_SYM ident FROM prepare_src
2129          {
2130            THD *thd= YYTHD;
2131            LEX *lex= thd->lex;
2132            lex->sql_command= SQLCOM_PREPARE;
2133            lex->prepared_stmt_name= $2;
2134            /*
2135              We don't know know at this time whether there's a password
2136              in prepare_src, so we err on the side of caution.  Setting
2137              the flag will force a rewrite which will obscure all of
2138              prepare_src in the "Query" log line.  We'll see the actual
2139              query (with just the passwords obscured, if any) immediately
2140              afterwards in the "Prepare" log lines anyway, and then again
2141              in the "Execute" log line if and when prepare_src is executed.
2142            */
2143            lex->contains_plaintext_password= true;
2144          }
2145        ;
2146
2147prepare_src:
2148          TEXT_STRING_sys
2149          {
2150            THD *thd= YYTHD;
2151            LEX *lex= thd->lex;
2152            lex->prepared_stmt_code= $1;
2153            lex->prepared_stmt_code_is_varref= FALSE;
2154          }
2155        | '@' ident_or_text
2156          {
2157            THD *thd= YYTHD;
2158            LEX *lex= thd->lex;
2159            lex->prepared_stmt_code= $2;
2160            lex->prepared_stmt_code_is_varref= TRUE;
2161          }
2162        ;
2163
2164execute:
2165          EXECUTE_SYM ident
2166          {
2167            THD *thd= YYTHD;
2168            LEX *lex= thd->lex;
2169            lex->sql_command= SQLCOM_EXECUTE;
2170            lex->prepared_stmt_name= $2;
2171          }
2172          execute_using
2173          {}
2174        ;
2175
2176execute_using:
2177          /* nothing */
2178        | USING execute_var_list
2179        ;
2180
2181execute_var_list:
2182          execute_var_list ',' execute_var_ident
2183        | execute_var_ident
2184        ;
2185
2186execute_var_ident:
2187          '@' ident_or_text
2188          {
2189            LEX *lex=Lex;
2190            LEX_STRING *lexstr= (LEX_STRING*)sql_memdup(&$2, sizeof(LEX_STRING));
2191            if (!lexstr || lex->prepared_stmt_params.push_back(lexstr))
2192              MYSQL_YYABORT;
2193          }
2194        ;
2195
2196/* help */
2197
2198help:
2199          HELP_SYM
2200          {
2201            if (Lex->sphead)
2202            {
2203              my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP");
2204              MYSQL_YYABORT;
2205            }
2206          }
2207          ident_or_text
2208          {
2209            LEX *lex= Lex;
2210            lex->sql_command= SQLCOM_HELP;
2211            lex->help_arg= $3.str;
2212          }
2213        ;
2214
2215/* change master */
2216
2217change:
2218          CHANGE MASTER_SYM TO_SYM
2219          {
2220            LEX *lex = Lex;
2221            lex->sql_command = SQLCOM_CHANGE_MASTER;
2222            /*
2223              Clear LEX_MASTER_INFO struct. repl_ignore_server_ids is freed
2224              in THD::cleanup_after_query. So it is guaranteed to be
2225              uninitialized before here.
2226	      Its allocation is deferred till the option is parsed below.
2227            */
2228            lex->mi.set_unspecified();
2229            DBUG_ASSERT(Lex->mi.repl_ignore_server_ids.elements == 0);
2230          }
2231          master_defs
2232          {}
2233        ;
2234
2235master_defs:
2236          master_def
2237        | master_defs ',' master_def
2238        ;
2239
2240master_def:
2241          MASTER_HOST_SYM EQ TEXT_STRING_sys_nonewline
2242          {
2243            Lex->mi.host = $3.str;
2244          }
2245        | MASTER_BIND_SYM EQ TEXT_STRING_sys_nonewline
2246          {
2247            Lex->mi.bind_addr = $3.str;
2248          }
2249        | MASTER_USER_SYM EQ TEXT_STRING_sys_nonewline
2250          {
2251            Lex->mi.user = $3.str;
2252          }
2253        | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys_nonewline
2254          {
2255            Lex->mi.password = $3.str;
2256            Lex->contains_plaintext_password= true;
2257          }
2258        | MASTER_PORT_SYM EQ ulong_num
2259          {
2260            Lex->mi.port = $3;
2261          }
2262        | MASTER_CONNECT_RETRY_SYM EQ ulong_num
2263          {
2264            Lex->mi.connect_retry = $3;
2265          }
2266        | MASTER_RETRY_COUNT_SYM EQ ulong_num
2267          {
2268            Lex->mi.retry_count= $3;
2269            Lex->mi.retry_count_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
2270          }
2271        | MASTER_DELAY_SYM EQ ulong_num
2272          {
2273            if ($3 > MASTER_DELAY_MAX)
2274            {
2275              Lex_input_stream *lip= YYLIP;
2276              const char *start= lip->get_tok_start();
2277              const char *msg= YYTHD->strmake(start, lip->get_ptr() - start);
2278              my_error(ER_MASTER_DELAY_VALUE_OUT_OF_RANGE, MYF(0),
2279                       msg, MASTER_DELAY_MAX);
2280            }
2281            else
2282              Lex->mi.sql_delay = $3;
2283          }
2284        | MASTER_SSL_SYM EQ ulong_num
2285          {
2286            Lex->mi.ssl= $3 ?
2287              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
2288          }
2289        | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys_nonewline
2290          {
2291            Lex->mi.ssl_ca= $3.str;
2292          }
2293        | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys_nonewline
2294          {
2295            Lex->mi.ssl_capath= $3.str;
2296          }
2297        | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys_nonewline
2298          {
2299            Lex->mi.ssl_cert= $3.str;
2300          }
2301        | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys_nonewline
2302          {
2303            Lex->mi.ssl_cipher= $3.str;
2304          }
2305        | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys_nonewline
2306          {
2307            Lex->mi.ssl_key= $3.str;
2308          }
2309        | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num
2310          {
2311            Lex->mi.ssl_verify_server_cert= $3 ?
2312              LEX_MASTER_INFO::LEX_MI_ENABLE : LEX_MASTER_INFO::LEX_MI_DISABLE;
2313          }
2314        | MASTER_SSL_CRL_SYM EQ TEXT_STRING_sys_nonewline
2315          {
2316            Lex->mi.ssl_crl= $3.str;
2317          }
2318        | MASTER_SSL_CRLPATH_SYM EQ TEXT_STRING_sys_nonewline
2319          {
2320            Lex->mi.ssl_crlpath= $3.str;
2321          }
2322
2323        | MASTER_HEARTBEAT_PERIOD_SYM EQ NUM_literal
2324          {
2325            Lex->mi.heartbeat_period= (float) $3->val_real();
2326            if (Lex->mi.heartbeat_period > SLAVE_MAX_HEARTBEAT_PERIOD ||
2327                Lex->mi.heartbeat_period < 0.0)
2328            {
2329               const char format[]= "%d";
2330               char buf[4*sizeof(SLAVE_MAX_HEARTBEAT_PERIOD) + sizeof(format)];
2331               sprintf(buf, format, SLAVE_MAX_HEARTBEAT_PERIOD);
2332               my_error(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE, MYF(0), buf);
2333               MYSQL_YYABORT;
2334            }
2335            if (Lex->mi.heartbeat_period > slave_net_timeout)
2336            {
2337              push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
2338                                  ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX,
2339                                  ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX));
2340            }
2341            if (Lex->mi.heartbeat_period < 0.001)
2342            {
2343              if (Lex->mi.heartbeat_period != 0.0)
2344              {
2345                push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
2346                                    ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN,
2347                                    ER(ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN));
2348                Lex->mi.heartbeat_period= 0.0;
2349              }
2350              Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_DISABLE;
2351            }
2352            Lex->mi.heartbeat_opt=  LEX_MASTER_INFO::LEX_MI_ENABLE;
2353          }
2354        | IGNORE_SERVER_IDS_SYM EQ '(' ignore_server_id_list ')'
2355          {
2356            Lex->mi.repl_ignore_server_ids_opt= LEX_MASTER_INFO::LEX_MI_ENABLE;
2357           }
2358        |
2359        MASTER_AUTO_POSITION_SYM EQ ulong_num
2360          {
2361            Lex->mi.auto_position= $3 ?
2362              LEX_MASTER_INFO::LEX_MI_ENABLE :
2363              LEX_MASTER_INFO::LEX_MI_DISABLE;
2364          }
2365        |
2366        master_file_def
2367        ;
2368
2369ignore_server_id_list:
2370          /* Empty */
2371          | ignore_server_id
2372          | ignore_server_id_list ',' ignore_server_id
2373        ;
2374
2375ignore_server_id:
2376          ulong_num
2377          {
2378            if (Lex->mi.repl_ignore_server_ids.elements == 0)
2379            {
2380              my_init_dynamic_array2(&Lex->mi.repl_ignore_server_ids,
2381                                     sizeof(::server_id),
2382                                     Lex->mi.server_ids_buffer,
2383                                     array_elements(Lex->mi.server_ids_buffer),
2384                                     16);
2385            }
2386            insert_dynamic(&Lex->mi.repl_ignore_server_ids, (uchar*) &($1));
2387          }
2388
2389master_file_def:
2390          MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys_nonewline
2391          {
2392            Lex->mi.log_file_name = $3.str;
2393          }
2394        | MASTER_LOG_POS_SYM EQ ulonglong_num
2395          {
2396            Lex->mi.pos = $3;
2397            /*
2398               If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
2399               instead of causing subsequent errors.
2400               We need to do it in this file, because only there we know that
2401               MASTER_LOG_POS has been explicitely specified. On the contrary
2402               in change_master() (sql_repl.cc) we cannot distinguish between 0
2403               (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
2404               whereas we want to distinguish (specified 0 means "read the binlog
2405               from 0" (4 in fact), unspecified means "don't change the position
2406               (keep the preceding value)").
2407            */
2408            Lex->mi.pos = max<ulonglong>(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
2409          }
2410        | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys_nonewline
2411          {
2412            Lex->mi.relay_log_name = $3.str;
2413          }
2414        | RELAY_LOG_POS_SYM EQ ulong_num
2415          {
2416            Lex->mi.relay_log_pos = $3;
2417            /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
2418            Lex->mi.relay_log_pos = max<ulong>(BIN_LOG_HEADER_SIZE,
2419                                               Lex->mi.relay_log_pos);
2420          }
2421        ;
2422
2423/* create a table */
2424
2425create:
2426          CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
2427          {
2428            THD *thd= YYTHD;
2429            LEX *lex= thd->lex;
2430            lex->sql_command= SQLCOM_CREATE_TABLE;
2431            if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
2432                                                   TL_OPTION_UPDATING,
2433                                                   TL_WRITE, MDL_SHARED))
2434              MYSQL_YYABORT;
2435            /*
2436              Instruct open_table() to acquire SHARED lock to check the
2437              existance of table. If the table does not exist then
2438              it will be upgraded EXCLUSIVE MDL lock. If table exist
2439              then open_table() will return with an error or warning.
2440            */
2441            lex->query_tables->open_strategy= TABLE_LIST::OPEN_FOR_CREATE;
2442            lex->alter_info.reset();
2443            lex->col_list.empty();
2444            lex->change=NullS;
2445            memset(static_cast<void*>(&lex->create_info), 0,
2446                   sizeof(lex->create_info));
2447            lex->create_info.options=$2 | $4;
2448            lex->create_info.default_table_charset= NULL;
2449            lex->name.str= 0;
2450            lex->name.length= 0;
2451            lex->create_last_non_select_table= lex->last_table();
2452          }
2453          create2
2454          {
2455            THD *thd= YYTHD;
2456            LEX *lex= thd->lex;
2457            lex->current_select= &lex->select_lex;
2458            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
2459                !lex->create_info.db_type)
2460            {
2461              lex->create_info.db_type=
2462                lex->create_info.options & HA_LEX_CREATE_TMP_TABLE ?
2463                ha_default_temp_handlerton(thd) : ha_default_handlerton(thd);
2464              push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
2465                                  ER_WARN_USING_OTHER_HANDLER,
2466                                  ER(ER_WARN_USING_OTHER_HANDLER),
2467                                  ha_resolve_storage_engine_name(lex->create_info.db_type),
2468                                  $5->table.str);
2469            }
2470            create_table_set_open_action_and_adjust_tables(lex);
2471          }
2472        | CREATE opt_unique_combo_clustering INDEX_SYM ident key_alg ON table_ident
2473          {
2474            if (add_create_index_prepare(Lex, $7))
2475              MYSQL_YYABORT;
2476          }
2477          '(' key_list ')' normal_key_options
2478          {
2479            if (add_create_index(Lex, $2, $4))
2480              MYSQL_YYABORT;
2481          }
2482          opt_index_lock_algorithm { }
2483        | CREATE fulltext INDEX_SYM ident init_key_options ON
2484          table_ident
2485          {
2486            if (add_create_index_prepare(Lex, $7))
2487              MYSQL_YYABORT;
2488          }
2489          '(' key_list ')' fulltext_key_options
2490          {
2491            if (add_create_index(Lex, $2, $4))
2492              MYSQL_YYABORT;
2493          }
2494          opt_index_lock_algorithm { }
2495        | CREATE spatial INDEX_SYM ident init_key_options ON
2496          table_ident
2497          {
2498            if (add_create_index_prepare(Lex, $7))
2499              MYSQL_YYABORT;
2500          }
2501          '(' key_list ')' spatial_key_options
2502          {
2503            if (add_create_index(Lex, $2, $4))
2504              MYSQL_YYABORT;
2505          }
2506          opt_index_lock_algorithm { }
2507        | CREATE DATABASE opt_if_not_exists ident
2508          {
2509            Lex->create_info.default_table_charset= NULL;
2510            Lex->create_info.used_fields= 0;
2511          }
2512          opt_create_database_options
2513          {
2514            LEX *lex=Lex;
2515            lex->sql_command=SQLCOM_CREATE_DB;
2516            lex->name= $4;
2517            lex->create_info.options=$3;
2518          }
2519        | CREATE
2520          {
2521            Lex->create_view_mode= VIEW_CREATE_NEW;
2522            Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
2523            Lex->create_view_suid= TRUE;
2524          }
2525          view_or_trigger_or_sp_or_event
2526          {}
2527        | CREATE USER clear_privileges grant_list
2528          {
2529            Lex->sql_command = SQLCOM_CREATE_USER;
2530          }
2531        | CREATE LOGFILE_SYM GROUP_SYM logfile_group_info
2532          {
2533            Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
2534          }
2535        | CREATE TABLESPACE tablespace_info
2536          {
2537            Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
2538          }
2539        | CREATE server_def
2540          {
2541            Lex->sql_command= SQLCOM_CREATE_SERVER;
2542          }
2543        | CREATE COMPRESSION_DICTIONARY_SYM opt_if_not_exists ident
2544          '(' create_compression_dictionary_allowed_expr ')'
2545          {
2546            Lex->sql_command= SQLCOM_CREATE_COMPRESSION_DICTIONARY;
2547            Lex->create_info.options= $3;
2548            Lex->ident= $4;
2549            Lex->default_value= $6;
2550          }
2551        ;
2552/*
2553  Only a limited subset of <expr> are allowed in
2554  CREATE COMPRESSION_DICTIONARY.
2555*/
2556create_compression_dictionary_allowed_expr:
2557          text_literal
2558          { $$= $1; }
2559        | variable
2560          {
2561            if ($1->type() == Item::FUNC_ITEM)
2562            {
2563              Item_func *item= (Item_func*) $1;
2564              if (item->functype() == Item_func::SUSERVAR_FUNC)
2565              {
2566                /*
2567                  Don't allow the following syntax:
2568                    CREATE COMPRESSION_DICTIONARY <dict>(@foo := expr)
2569                */
2570                my_parse_error(ER(ER_SYNTAX_ERROR));
2571                MYSQL_YYABORT;
2572              }
2573            }
2574            $$= $1;
2575          }
2576        ;
2577
2578server_def:
2579          SERVER_SYM
2580          ident_or_text
2581          FOREIGN DATA_SYM WRAPPER_SYM
2582          ident_or_text
2583          OPTIONS_SYM '(' server_options_list ')'
2584          {
2585            if ($2.length == 0)
2586            {
2587              my_error(ER_WRONG_VALUE, MYF(0), "server name", "");
2588              MYSQL_YYABORT;
2589            }
2590            Lex->server_options.server_name= $2.str;
2591            Lex->server_options.server_name_length= $2.length;
2592            Lex->server_options.scheme= $6.str;
2593          }
2594        ;
2595
2596server_options_list:
2597          server_option
2598        | server_options_list ',' server_option
2599        ;
2600
2601server_option:
2602          USER TEXT_STRING_sys
2603          {
2604            Lex->server_options.username= $2.str;
2605          }
2606        | HOST_SYM TEXT_STRING_sys
2607          {
2608            Lex->server_options.host= $2.str;
2609          }
2610        | DATABASE TEXT_STRING_sys
2611          {
2612            Lex->server_options.db= $2.str;
2613          }
2614        | OWNER_SYM TEXT_STRING_sys
2615          {
2616            Lex->server_options.owner= $2.str;
2617          }
2618        | PASSWORD TEXT_STRING_sys
2619          {
2620            Lex->server_options.password= $2.str;
2621            Lex->contains_plaintext_password= true;
2622          }
2623        | SOCKET_SYM TEXT_STRING_sys
2624          {
2625            Lex->server_options.socket= $2.str;
2626          }
2627        | PORT_SYM ulong_num
2628          {
2629            Lex->server_options.port= $2;
2630          }
2631        ;
2632
2633event_tail:
2634          remember_name EVENT_SYM opt_if_not_exists sp_name
2635          {
2636            THD *thd= YYTHD;
2637            LEX *lex=Lex;
2638
2639            lex->stmt_definition_begin= $1;
2640            lex->create_info.options= $3;
2641            if (!(lex->event_parse_data= Event_parse_data::new_instance(thd)))
2642              MYSQL_YYABORT;
2643            lex->event_parse_data->identifier= $4;
2644            lex->event_parse_data->on_completion=
2645                                  Event_parse_data::ON_COMPLETION_DROP;
2646
2647            lex->sql_command= SQLCOM_CREATE_EVENT;
2648            /* We need that for disallowing subqueries */
2649          }
2650          ON SCHEDULE_SYM ev_schedule_time
2651          opt_ev_on_completion
2652          opt_ev_status
2653          opt_ev_comment
2654          DO_SYM ev_sql_stmt
2655          {
2656            /*
2657              sql_command is set here because some rules in ev_sql_stmt
2658              can overwrite it
2659            */
2660            Lex->sql_command= SQLCOM_CREATE_EVENT;
2661          }
2662        ;
2663
2664ev_schedule_time:
2665          EVERY_SYM expr interval
2666          {
2667            Lex->event_parse_data->item_expression= $2;
2668            Lex->event_parse_data->interval= $3;
2669          }
2670          ev_starts
2671          ev_ends
2672        | AT_SYM expr
2673          {
2674            Lex->event_parse_data->item_execute_at= $2;
2675          }
2676        ;
2677
2678opt_ev_status:
2679          /* empty */ { $$= 0; }
2680        | ENABLE_SYM
2681          {
2682            Lex->event_parse_data->status= Event_parse_data::ENABLED;
2683            Lex->event_parse_data->status_changed= true;
2684            $$= 1;
2685          }
2686        | DISABLE_SYM ON SLAVE
2687          {
2688            Lex->event_parse_data->status= Event_parse_data::SLAVESIDE_DISABLED;
2689            Lex->event_parse_data->status_changed= true;
2690            $$= 1;
2691          }
2692        | DISABLE_SYM
2693          {
2694            Lex->event_parse_data->status= Event_parse_data::DISABLED;
2695            Lex->event_parse_data->status_changed= true;
2696            $$= 1;
2697          }
2698        ;
2699
2700ev_starts:
2701          /* empty */
2702          {
2703            Item *item= new (YYTHD->mem_root) Item_func_now_local(0);
2704            if (item == NULL)
2705              MYSQL_YYABORT;
2706            Lex->event_parse_data->item_starts= item;
2707          }
2708        | STARTS_SYM expr
2709          {
2710            Lex->event_parse_data->item_starts= $2;
2711          }
2712        ;
2713
2714ev_ends:
2715          /* empty */
2716        | ENDS_SYM expr
2717          {
2718            Lex->event_parse_data->item_ends= $2;
2719          }
2720        ;
2721
2722opt_ev_on_completion:
2723          /* empty */ { $$= 0; }
2724        | ev_on_completion
2725        ;
2726
2727ev_on_completion:
2728          ON COMPLETION_SYM PRESERVE_SYM
2729          {
2730            Lex->event_parse_data->on_completion=
2731                                  Event_parse_data::ON_COMPLETION_PRESERVE;
2732            $$= 1;
2733          }
2734        | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
2735          {
2736            Lex->event_parse_data->on_completion=
2737                                  Event_parse_data::ON_COMPLETION_DROP;
2738            $$= 1;
2739          }
2740        ;
2741
2742opt_ev_comment:
2743          /* empty */ { $$= 0; }
2744        | COMMENT_SYM TEXT_STRING_sys
2745          {
2746            Lex->comment= Lex->event_parse_data->comment= $2;
2747            $$= 1;
2748          }
2749        ;
2750
2751ev_sql_stmt:
2752          {
2753            THD *thd= YYTHD;
2754            LEX *lex= thd->lex;
2755            Lex_input_stream *lip= YYLIP;
2756
2757            /*
2758              This stops the following :
2759              - CREATE EVENT ... DO CREATE EVENT ...;
2760              - ALTER  EVENT ... DO CREATE EVENT ...;
2761              - CREATE EVENT ... DO ALTER EVENT DO ....;
2762              - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END|
2763              This allows:
2764              - CREATE EVENT ... DO DROP EVENT yyy;
2765              - CREATE EVENT ... DO ALTER EVENT yyy;
2766                (the nested ALTER EVENT can have anything but DO clause)
2767              - ALTER  EVENT ... DO ALTER EVENT yyy;
2768                (the nested ALTER EVENT can have anything but DO clause)
2769              - ALTER  EVENT ... DO DROP EVENT yyy;
2770              - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END|
2771                (the nested ALTER EVENT can have anything but DO clause)
2772              - CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
2773            */
2774            if (lex->sphead)
2775            {
2776              my_error(ER_EVENT_RECURSION_FORBIDDEN, MYF(0));
2777              MYSQL_YYABORT;
2778            }
2779
2780            sp_head *sp= sp_start_parsing(thd,
2781                                          SP_TYPE_PROCEDURE,
2782                                          lex->event_parse_data->identifier);
2783
2784            if (!sp)
2785              MYSQL_YYABORT;
2786
2787            lex->sphead= sp;
2788
2789            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
2790            sp->m_chistics= &lex->sp_chistics;
2791
2792            sp->set_body_start(thd, lip->get_cpp_ptr());
2793          }
2794          ev_sql_stmt_inner
2795          {
2796            THD *thd= YYTHD;
2797            LEX *lex= thd->lex;
2798
2799            sp_finish_parsing(thd);
2800
2801            lex->sp_chistics.suid= SP_IS_SUID;  //always the definer!
2802            lex->event_parse_data->body_changed= TRUE;
2803          }
2804        ;
2805
2806ev_sql_stmt_inner:
2807          sp_proc_stmt_statement
2808        | sp_proc_stmt_return
2809        | sp_proc_stmt_if
2810        | case_stmt_specification
2811        | sp_labeled_block
2812        | sp_unlabeled_block
2813        | sp_labeled_control
2814        | sp_proc_stmt_unlabeled
2815        | sp_proc_stmt_leave
2816        | sp_proc_stmt_iterate
2817        | sp_proc_stmt_open
2818        | sp_proc_stmt_fetch
2819        | sp_proc_stmt_close
2820        ;
2821
2822clear_privileges:
2823          /* Nothing */
2824          {
2825           LEX *lex=Lex;
2826           lex->users_list.empty();
2827           lex->columns.empty();
2828           lex->grant= lex->grant_tot_col= 0;
2829           lex->all_privileges= 0;
2830           lex->select_lex.db= 0;
2831           lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
2832           lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
2833           memset(&(lex->mqh), 0, sizeof(lex->mqh));
2834         }
2835        ;
2836
2837sp_name:
2838          ident '.' ident
2839          {
2840            if (!$1.str ||
2841                (check_and_convert_db_name(&$1, FALSE) != IDENT_NAME_OK))
2842              MYSQL_YYABORT;
2843            if (sp_check_name(&$3))
2844            {
2845              MYSQL_YYABORT;
2846            }
2847            $$= new sp_name($1, $3, true);
2848            if ($$ == NULL)
2849              MYSQL_YYABORT;
2850            $$->init_qname(YYTHD);
2851          }
2852        | ident
2853          {
2854            THD *thd= YYTHD;
2855            LEX *lex= thd->lex;
2856            LEX_STRING db;
2857            if (sp_check_name(&$1))
2858            {
2859              MYSQL_YYABORT;
2860            }
2861            if (lex->copy_db_to(&db.str, &db.length))
2862              MYSQL_YYABORT;
2863            $$= new sp_name(db, $1, false);
2864            if ($$ == NULL)
2865              MYSQL_YYABORT;
2866            $$->init_qname(thd);
2867          }
2868        ;
2869
2870sp_a_chistics:
2871          /* Empty */ {}
2872        | sp_a_chistics sp_chistic {}
2873        ;
2874
2875sp_c_chistics:
2876          /* Empty */ {}
2877        | sp_c_chistics sp_c_chistic {}
2878        ;
2879
2880/* Characteristics for both create and alter */
2881sp_chistic:
2882          COMMENT_SYM TEXT_STRING_sys
2883          { Lex->sp_chistics.comment= $2; }
2884        | LANGUAGE_SYM SQL_SYM
2885          { /* Just parse it, we only have one language for now. */ }
2886        | NO_SYM SQL_SYM
2887          { Lex->sp_chistics.daccess= SP_NO_SQL; }
2888        | CONTAINS_SYM SQL_SYM
2889          { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; }
2890        | READS_SYM SQL_SYM DATA_SYM
2891          { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; }
2892        | MODIFIES_SYM SQL_SYM DATA_SYM
2893          { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; }
2894        | sp_suid
2895          {}
2896        ;
2897
2898/* Create characteristics */
2899sp_c_chistic:
2900          sp_chistic            { }
2901        | DETERMINISTIC_SYM     { Lex->sp_chistics.detistic= TRUE; }
2902        | not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
2903        ;
2904
2905sp_suid:
2906          SQL_SYM SECURITY_SYM DEFINER_SYM
2907          {
2908            Lex->sp_chistics.suid= SP_IS_SUID;
2909          }
2910        | SQL_SYM SECURITY_SYM INVOKER_SYM
2911          {
2912            Lex->sp_chistics.suid= SP_IS_NOT_SUID;
2913          }
2914        ;
2915
2916call:
2917          CALL_SYM sp_name
2918          {
2919            LEX *lex = Lex;
2920
2921            lex->sql_command= SQLCOM_CALL;
2922            lex->spname= $2;
2923            lex->value_list.empty();
2924            sp_add_used_routine(lex, YYTHD, $2, SP_TYPE_PROCEDURE);
2925          }
2926          opt_sp_cparam_list {}
2927        ;
2928
2929/* CALL parameters */
2930opt_sp_cparam_list:
2931          /* Empty */
2932        | '(' opt_sp_cparams ')'
2933        ;
2934
2935opt_sp_cparams:
2936          /* Empty */
2937        | sp_cparams
2938        ;
2939
2940sp_cparams:
2941          sp_cparams ',' expr
2942          {
2943           Lex->value_list.push_back($3);
2944          }
2945        | expr
2946          {
2947            Lex->value_list.push_back($1);
2948          }
2949        ;
2950
2951/* Stored FUNCTION parameter declaration list */
2952sp_fdparam_list:
2953          /* Empty */
2954        | sp_fdparams
2955        ;
2956
2957sp_fdparams:
2958          sp_fdparams ',' sp_fdparam
2959        | sp_fdparam
2960        ;
2961
2962sp_init_param:
2963          /* Empty */
2964          {
2965            LEX *lex= Lex;
2966
2967            lex->length= 0;
2968            lex->dec= 0;
2969            lex->type= 0;
2970
2971            lex->default_value= 0;
2972            lex->on_update_value= 0;
2973
2974            lex->comment= null_lex_str;
2975            lex->charset= NULL;
2976
2977            lex->interval_list.empty();
2978            lex->uint_geom_type= 0;
2979          }
2980        ;
2981
2982sp_fdparam:
2983          ident sp_init_param type_with_opt_collate
2984          {
2985            THD *thd= YYTHD;
2986            LEX *lex= thd->lex;
2987            sp_head *sp= lex->sphead;
2988            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
2989
2990            if (pctx->find_variable($1, TRUE))
2991            {
2992              my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
2993              MYSQL_YYABORT;
2994            }
2995
2996            sp_variable *spvar= pctx->add_variable(thd,
2997                                                   $1,
2998                                                   (enum enum_field_types) $3,
2999                                                   sp_variable::MODE_IN);
3000
3001            if (fill_field_definition(thd, sp,
3002                                      (enum enum_field_types) $3,
3003                                      &spvar->field_def))
3004            {
3005              MYSQL_YYABORT;
3006            }
3007            spvar->field_def.field_name= spvar->name.str;
3008            spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
3009          }
3010        ;
3011
3012/* Stored PROCEDURE parameter declaration list */
3013sp_pdparam_list:
3014          /* Empty */
3015        | sp_pdparams
3016        ;
3017
3018sp_pdparams:
3019          sp_pdparams ',' sp_pdparam
3020        | sp_pdparam
3021        ;
3022
3023sp_pdparam:
3024          sp_opt_inout sp_init_param ident type_with_opt_collate
3025          {
3026            THD *thd= YYTHD;
3027            LEX *lex= thd->lex;
3028            sp_head *sp= lex->sphead;
3029            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3030
3031            if (pctx->find_variable($3, TRUE))
3032            {
3033              my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
3034              MYSQL_YYABORT;
3035            }
3036            sp_variable *spvar= pctx->add_variable(thd,
3037                                                   $3,
3038                                                   (enum enum_field_types) $4,
3039                                                   (sp_variable::enum_mode) $1);
3040
3041            if (fill_field_definition(thd, sp,
3042                                      (enum enum_field_types) $4,
3043                                      &spvar->field_def))
3044            {
3045              MYSQL_YYABORT;
3046            }
3047            spvar->field_def.field_name= spvar->name.str;
3048            spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
3049          }
3050        ;
3051
3052sp_opt_inout:
3053          /* Empty */ { $$= sp_variable::MODE_IN; }
3054        | IN_SYM      { $$= sp_variable::MODE_IN; }
3055        | OUT_SYM     { $$= sp_variable::MODE_OUT; }
3056        | INOUT_SYM   { $$= sp_variable::MODE_INOUT; }
3057        ;
3058
3059sp_proc_stmts:
3060          /* Empty */ {}
3061        | sp_proc_stmts  sp_proc_stmt ';'
3062        ;
3063
3064sp_proc_stmts1:
3065          sp_proc_stmt ';' {}
3066        | sp_proc_stmts1  sp_proc_stmt ';'
3067        ;
3068
3069sp_decls:
3070          /* Empty */
3071          {
3072            $$.vars= $$.conds= $$.hndlrs= $$.curs= 0;
3073          }
3074        | sp_decls sp_decl ';'
3075          {
3076            /* We check for declarations out of (standard) order this way
3077              because letting the grammar rules reflect it caused tricky
3078               shift/reduce conflicts with the wrong result. (And we get
3079               better error handling this way.) */
3080            if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs))
3081            { /* Variable or condition following cursor or handler */
3082              my_message(ER_SP_VARCOND_AFTER_CURSHNDLR,
3083                         ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0));
3084              MYSQL_YYABORT;
3085            }
3086            if ($2.curs && $1.hndlrs)
3087            { /* Cursor following handler */
3088              my_message(ER_SP_CURSOR_AFTER_HANDLER,
3089                         ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0));
3090              MYSQL_YYABORT;
3091            }
3092            $$.vars= $1.vars + $2.vars;
3093            $$.conds= $1.conds + $2.conds;
3094            $$.hndlrs= $1.hndlrs + $2.hndlrs;
3095            $$.curs= $1.curs + $2.curs;
3096          }
3097        ;
3098
3099sp_decl:
3100          DECLARE_SYM sp_decl_idents
3101          {
3102            THD *thd= YYTHD;
3103            LEX *lex= thd->lex;
3104            sp_head *sp= lex->sphead;
3105            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3106
3107            sp->reset_lex(thd);
3108            pctx->declare_var_boundary($2);
3109          }
3110          type_with_opt_collate
3111          sp_opt_default
3112          {
3113            THD *thd= YYTHD;
3114            LEX *lex= thd->lex;
3115            sp_head *sp= lex->sphead;
3116            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3117            uint num_vars= pctx->context_var_count();
3118            enum enum_field_types var_type= (enum enum_field_types) $4;
3119            Item *dflt_value_item= $5;
3120            LEX_STRING dflt_value_query= EMPTY_STR;
3121
3122            if (dflt_value_item)
3123            {
3124              // sp_opt_default only pushes start ptr for DEFAULT clause.
3125              const char *expr_start_ptr=
3126                sp->m_parser_data.pop_expr_start_ptr();
3127              if (lex->is_metadata_used())
3128              {
3129                dflt_value_query= make_string(thd, expr_start_ptr,
3130                                              YY_TOKEN_END);
3131                if (!dflt_value_query.str)
3132                  MYSQL_YYABORT;
3133              }
3134            }
3135            else
3136            {
3137              dflt_value_item= new (thd->mem_root) Item_null();
3138
3139              if (dflt_value_item == NULL)
3140                MYSQL_YYABORT;
3141            }
3142
3143            // We can have several variables in DECLARE statement.
3144            // We need to create an sp_instr_set instruction for each variable.
3145
3146            for (uint i = num_vars-$2 ; i < num_vars ; i++)
3147            {
3148              uint var_idx= pctx->var_context2runtime(i);
3149              sp_variable *spvar= pctx->find_variable(var_idx);
3150
3151              if (!spvar)
3152                MYSQL_YYABORT;
3153
3154              spvar->type= var_type;
3155              spvar->default_value= dflt_value_item;
3156
3157              if (fill_field_definition(thd, sp, var_type, &spvar->field_def))
3158                MYSQL_YYABORT;
3159
3160              spvar->field_def.field_name= spvar->name.str;
3161              spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
3162
3163              /* The last instruction is responsible for freeing LEX. */
3164
3165              sp_instr_set *is=
3166                new (thd->mem_root)
3167                  sp_instr_set(sp->instructions(),
3168                               lex,
3169                               var_idx,
3170                               dflt_value_item,
3171                               dflt_value_query,
3172                               (i == num_vars - 1));
3173
3174              if (!is || sp->add_instr(thd, is))
3175                MYSQL_YYABORT;
3176            }
3177
3178            pctx->declare_var_boundary(0);
3179            if (sp->restore_lex(thd))
3180              MYSQL_YYABORT;
3181            $$.vars= $2;
3182            $$.conds= $$.hndlrs= $$.curs= 0;
3183          }
3184        | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
3185          {
3186            THD *thd= YYTHD;
3187            LEX *lex= thd->lex;
3188            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3189
3190            if (pctx->find_condition($2, TRUE))
3191            {
3192              my_error(ER_SP_DUP_COND, MYF(0), $2.str);
3193              MYSQL_YYABORT;
3194            }
3195            if(pctx->add_condition(thd, $2, $5))
3196              MYSQL_YYABORT;
3197            $$.vars= $$.hndlrs= $$.curs= 0;
3198            $$.conds= 1;
3199          }
3200        | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM
3201          {
3202            THD *thd= YYTHD;
3203            LEX *lex= thd->lex;
3204            sp_head *sp= lex->sphead;
3205
3206            sp_pcontext *parent_pctx= lex->get_sp_current_parsing_ctx();
3207
3208            sp_pcontext *handler_pctx=
3209              parent_pctx->push_context(thd, sp_pcontext::HANDLER_SCOPE);
3210
3211            sp_handler *h=
3212              parent_pctx->add_handler(thd, (sp_handler::enum_type) $2);
3213
3214            lex->set_sp_current_parsing_ctx(handler_pctx);
3215
3216            sp_instr_hpush_jump *i=
3217              new (thd->mem_root)
3218                sp_instr_hpush_jump(sp->instructions(), handler_pctx, h);
3219
3220            if (!i || sp->add_instr(thd, i))
3221              MYSQL_YYABORT;
3222
3223            if ($2 == sp_handler::CONTINUE)
3224            {
3225              // Mark the end of CONTINUE handler scope.
3226
3227              if (sp->m_parser_data.add_backpatch_entry(
3228                    i, handler_pctx->last_label()))
3229              {
3230                MYSQL_YYABORT;
3231              }
3232            }
3233
3234            if (sp->m_parser_data.add_backpatch_entry(
3235                  i, handler_pctx->push_label(thd, EMPTY_STR, 0)))
3236            {
3237              MYSQL_YYABORT;
3238            }
3239          }
3240          sp_hcond_list sp_proc_stmt
3241          {
3242            THD *thd= YYTHD;
3243            LEX *lex= Lex;
3244            sp_head *sp= lex->sphead;
3245            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3246            sp_label *hlab= pctx->pop_label(); /* After this hdlr */
3247
3248            if ($2 == sp_handler::CONTINUE)
3249            {
3250              sp_instr_hreturn *i=
3251                new (thd->mem_root) sp_instr_hreturn(sp->instructions(), pctx);
3252
3253              if (!i || sp->add_instr(thd, i))
3254                MYSQL_YYABORT;
3255            }
3256            else
3257            {  /* EXIT or UNDO handler, just jump to the end of the block */
3258              sp_instr_hreturn *i=
3259                new (thd->mem_root) sp_instr_hreturn(sp->instructions(), pctx);
3260
3261              if (i == NULL ||
3262                  sp->add_instr(thd, i) ||
3263                  sp->m_parser_data.add_backpatch_entry(i, pctx->last_label()))
3264                MYSQL_YYABORT;
3265            }
3266
3267            sp->m_parser_data.do_backpatch(hlab, sp->instructions());
3268
3269            lex->set_sp_current_parsing_ctx(pctx->pop_context());
3270
3271            $$.vars= $$.conds= $$.curs= 0;
3272            $$.hndlrs= 1;
3273          }
3274        | DECLARE_SYM ident CURSOR_SYM FOR_SYM
3275          {
3276            THD *thd= YYTHD;
3277            LEX *lex= Lex;
3278            sp_head *sp= lex->sphead;
3279
3280            sp->reset_lex(thd);
3281            sp->m_parser_data.set_current_stmt_start_ptr(YY_TOKEN_END);
3282          }
3283          select
3284          {
3285            THD *thd= YYTHD;
3286            LEX *cursor_lex= Lex;
3287            sp_head *sp= cursor_lex->sphead;
3288
3289            DBUG_ASSERT(cursor_lex->sql_command == SQLCOM_SELECT);
3290
3291            if (cursor_lex->result)
3292            {
3293              my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT),
3294                         MYF(0));
3295              MYSQL_YYABORT;
3296            }
3297
3298            cursor_lex->sp_lex_in_use= true;
3299
3300            if (sp->restore_lex(thd))
3301              MYSQL_YYABORT;
3302
3303            LEX *lex= Lex;
3304            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3305
3306            uint offp;
3307
3308            if (pctx->find_cursor($2, &offp, TRUE))
3309            {
3310              my_error(ER_SP_DUP_CURS, MYF(0), $2.str);
3311              delete cursor_lex;
3312              MYSQL_YYABORT;
3313            }
3314
3315            LEX_STRING cursor_query= EMPTY_STR;
3316
3317            if (cursor_lex->is_metadata_used())
3318            {
3319              cursor_query=
3320                make_string(thd,
3321                            sp->m_parser_data.get_current_stmt_start_ptr(),
3322                            YY_TOKEN_END);
3323
3324              if (!cursor_query.str)
3325                MYSQL_YYABORT;
3326            }
3327
3328            sp_instr_cpush *i=
3329              new (thd->mem_root)
3330                sp_instr_cpush(sp->instructions(), pctx,
3331                               cursor_lex, cursor_query,
3332                               pctx->current_cursor_count());
3333
3334            if (i == NULL ||
3335                sp->add_instr(thd, i) ||
3336                pctx->add_cursor($2))
3337            {
3338              MYSQL_YYABORT;
3339            }
3340
3341            $$.vars= $$.conds= $$.hndlrs= 0;
3342            $$.curs= 1;
3343          }
3344        ;
3345
3346sp_handler_type:
3347          EXIT_SYM      { $$= sp_handler::EXIT; }
3348        | CONTINUE_SYM  { $$= sp_handler::CONTINUE; }
3349        /*| UNDO_SYM      { QQ No yet } */
3350        ;
3351
3352sp_hcond_list:
3353          sp_hcond_element
3354          { $$= 1; }
3355        | sp_hcond_list ',' sp_hcond_element
3356          { $$+= 1; }
3357        ;
3358
3359sp_hcond_element:
3360          sp_hcond
3361          {
3362            LEX *lex= Lex;
3363            sp_head *sp= lex->sphead;
3364            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3365            sp_pcontext *parent_pctx= pctx->parent_context();
3366
3367            if (parent_pctx->check_duplicate_handler($1))
3368            {
3369              my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
3370              MYSQL_YYABORT;
3371            }
3372            else
3373            {
3374              sp_instr_hpush_jump *i=
3375                (sp_instr_hpush_jump *)sp->last_instruction();
3376
3377              i->add_condition($1);
3378            }
3379          }
3380        ;
3381
3382sp_cond:
3383          ulong_num
3384          { /* mysql errno */
3385            if ($1 == 0)
3386            {
3387              my_error(ER_WRONG_VALUE, MYF(0), "CONDITION", "0");
3388              MYSQL_YYABORT;
3389            }
3390            $$= new (YYTHD->mem_root) sp_condition_value($1);
3391            if ($$ == NULL)
3392              MYSQL_YYABORT;
3393          }
3394        | sqlstate
3395        ;
3396
3397sqlstate:
3398          SQLSTATE_SYM opt_value TEXT_STRING_literal
3399          { /* SQLSTATE */
3400
3401            /*
3402              An error is triggered:
3403                - if the specified string is not a valid SQLSTATE,
3404                - or if it represents the completion condition -- it is not
3405                  allowed to SIGNAL, or declare a handler for the completion
3406                  condition.
3407            */
3408            if (!is_sqlstate_valid(&$3) || is_sqlstate_completion($3.str))
3409            {
3410              my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str);
3411              MYSQL_YYABORT;
3412            }
3413            $$= new (YYTHD->mem_root) sp_condition_value($3.str);
3414            if ($$ == NULL)
3415              MYSQL_YYABORT;
3416          }
3417        ;
3418
3419opt_value:
3420          /* Empty */  {}
3421        | VALUE_SYM    {}
3422        ;
3423
3424sp_hcond:
3425          sp_cond
3426          {
3427            $$= $1;
3428          }
3429        | ident /* CONDITION name */
3430          {
3431            LEX *lex= Lex;
3432            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3433
3434            $$= pctx->find_condition($1, false);
3435
3436            if ($$ == NULL)
3437            {
3438              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3439              MYSQL_YYABORT;
3440            }
3441          }
3442        | SQLWARNING_SYM /* SQLSTATEs 01??? */
3443          {
3444            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::WARNING);
3445            if ($$ == NULL)
3446              MYSQL_YYABORT;
3447          }
3448        | not FOUND_SYM /* SQLSTATEs 02??? */
3449          {
3450            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::NOT_FOUND);
3451            if ($$ == NULL)
3452              MYSQL_YYABORT;
3453          }
3454        | SQLEXCEPTION_SYM /* All other SQLSTATEs */
3455          {
3456            $$= new (YYTHD->mem_root) sp_condition_value(sp_condition_value::EXCEPTION);
3457            if ($$ == NULL)
3458              MYSQL_YYABORT;
3459          }
3460        ;
3461
3462signal_stmt:
3463          SIGNAL_SYM signal_value opt_set_signal_information
3464          {
3465            THD *thd= YYTHD;
3466            LEX *lex= thd->lex;
3467            Yacc_state *state= & thd->m_parser_state->m_yacc;
3468
3469            lex->sql_command= SQLCOM_SIGNAL;
3470            lex->m_sql_cmd=
3471              new (thd->mem_root) Sql_cmd_signal($2, state->m_set_signal_info);
3472            if (lex->m_sql_cmd == NULL)
3473              MYSQL_YYABORT;
3474          }
3475        ;
3476
3477signal_value:
3478          ident
3479          {
3480            LEX *lex= Lex;
3481            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3482
3483            if (!pctx)
3484            {
3485              /* SIGNAL foo cannot be used outside of stored programs */
3486              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3487              MYSQL_YYABORT;
3488            }
3489
3490            sp_condition_value *cond= pctx->find_condition($1, false);
3491
3492            if (!cond)
3493            {
3494              my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
3495              MYSQL_YYABORT;
3496            }
3497            if (cond->type != sp_condition_value::SQLSTATE)
3498            {
3499              my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0));
3500              MYSQL_YYABORT;
3501            }
3502            $$= cond;
3503          }
3504        | sqlstate
3505          { $$= $1; }
3506        ;
3507
3508opt_signal_value:
3509          /* empty */
3510          { $$= NULL; }
3511        | signal_value
3512          { $$= $1; }
3513        ;
3514
3515opt_set_signal_information:
3516          /* empty */
3517          {
3518            YYTHD->m_parser_state->m_yacc.m_set_signal_info.clear();
3519          }
3520        | SET signal_information_item_list
3521        ;
3522
3523signal_information_item_list:
3524          signal_condition_information_item_name EQ signal_allowed_expr
3525          {
3526            Set_signal_information *info;
3527            info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info;
3528            int index= (int) $1;
3529            info->clear();
3530            info->m_item[index]= $3;
3531          }
3532        | signal_information_item_list ','
3533          signal_condition_information_item_name EQ signal_allowed_expr
3534          {
3535            Set_signal_information *info;
3536            info= & YYTHD->m_parser_state->m_yacc.m_set_signal_info;
3537            int index= (int) $3;
3538            if (info->m_item[index] != NULL)
3539            {
3540              my_error(ER_DUP_SIGNAL_SET, MYF(0),
3541                       Diag_condition_item_names[index].str);
3542              MYSQL_YYABORT;
3543            }
3544            info->m_item[index]= $5;
3545          }
3546        ;
3547
3548/*
3549  Only a limited subset of <expr> are allowed in SIGNAL/RESIGNAL.
3550*/
3551signal_allowed_expr:
3552          literal
3553          { $$= $1; }
3554        | variable
3555          {
3556            if ($1->type() == Item::FUNC_ITEM)
3557            {
3558              Item_func *item= (Item_func*) $1;
3559              if (item->functype() == Item_func::SUSERVAR_FUNC)
3560              {
3561                /*
3562                  Don't allow the following syntax:
3563                    SIGNAL/RESIGNAL ...
3564                    SET <signal condition item name> = @foo := expr
3565                */
3566                my_parse_error(ER(ER_SYNTAX_ERROR));
3567                MYSQL_YYABORT;
3568              }
3569            }
3570            $$= $1;
3571          }
3572        | simple_ident
3573          { $$= $1; }
3574        ;
3575
3576/* conditions that can be set in signal / resignal */
3577signal_condition_information_item_name:
3578          CLASS_ORIGIN_SYM
3579          { $$= DIAG_CLASS_ORIGIN; }
3580        | SUBCLASS_ORIGIN_SYM
3581          { $$= DIAG_SUBCLASS_ORIGIN; }
3582        | CONSTRAINT_CATALOG_SYM
3583          { $$= DIAG_CONSTRAINT_CATALOG; }
3584        | CONSTRAINT_SCHEMA_SYM
3585          { $$= DIAG_CONSTRAINT_SCHEMA; }
3586        | CONSTRAINT_NAME_SYM
3587          { $$= DIAG_CONSTRAINT_NAME; }
3588        | CATALOG_NAME_SYM
3589          { $$= DIAG_CATALOG_NAME; }
3590        | SCHEMA_NAME_SYM
3591          { $$= DIAG_SCHEMA_NAME; }
3592        | TABLE_NAME_SYM
3593          { $$= DIAG_TABLE_NAME; }
3594        | COLUMN_NAME_SYM
3595          { $$= DIAG_COLUMN_NAME; }
3596        | CURSOR_NAME_SYM
3597          { $$= DIAG_CURSOR_NAME; }
3598        | MESSAGE_TEXT_SYM
3599          { $$= DIAG_MESSAGE_TEXT; }
3600        | MYSQL_ERRNO_SYM
3601          { $$= DIAG_MYSQL_ERRNO; }
3602        ;
3603
3604resignal_stmt:
3605          RESIGNAL_SYM opt_signal_value opt_set_signal_information
3606          {
3607            THD *thd= YYTHD;
3608            LEX *lex= thd->lex;
3609            Yacc_state *state= & thd->m_parser_state->m_yacc;
3610
3611            lex->sql_command= SQLCOM_RESIGNAL;
3612            lex->m_sql_cmd=
3613              new (thd->mem_root) Sql_cmd_resignal($2,
3614                                                   state->m_set_signal_info);
3615            if (lex->m_sql_cmd == NULL)
3616              MYSQL_YYABORT;
3617          }
3618        ;
3619
3620get_diagnostics:
3621          GET_SYM which_area DIAGNOSTICS_SYM diagnostics_information
3622          {
3623            Diagnostics_information *info= $4;
3624
3625            info->set_which_da($2);
3626
3627            Lex->sql_command= SQLCOM_GET_DIAGNOSTICS;
3628            Lex->m_sql_cmd= new (YYTHD->mem_root) Sql_cmd_get_diagnostics(info);
3629
3630            if (Lex->m_sql_cmd == NULL)
3631              MYSQL_YYABORT;
3632          }
3633        ;
3634
3635which_area:
3636        /* If <which area> is not specified, then CURRENT is implicit. */
3637          { $$= Diagnostics_information::CURRENT_AREA; }
3638        | CURRENT_SYM
3639          { $$= Diagnostics_information::CURRENT_AREA; }
3640        ;
3641
3642diagnostics_information:
3643          statement_information
3644          {
3645            $$= new (YYTHD->mem_root) Statement_information($1);
3646            if ($$ == NULL)
3647              MYSQL_YYABORT;
3648          }
3649        | CONDITION_SYM condition_number condition_information
3650          {
3651            $$= new (YYTHD->mem_root) Condition_information($2, $3);
3652            if ($$ == NULL)
3653              MYSQL_YYABORT;
3654          }
3655        ;
3656
3657statement_information:
3658          statement_information_item
3659          {
3660            $$= new (YYTHD->mem_root) List<Statement_information_item>;
3661            if ($$ == NULL || $$->push_back($1))
3662              MYSQL_YYABORT;
3663          }
3664        | statement_information ',' statement_information_item
3665          {
3666            if ($1->push_back($3))
3667              MYSQL_YYABORT;
3668            $$= $1;
3669          }
3670        ;
3671
3672statement_information_item:
3673          simple_target_specification EQ statement_information_item_name
3674          {
3675            $$= new (YYTHD->mem_root) Statement_information_item($3, $1);
3676            if ($$ == NULL)
3677              MYSQL_YYABORT;
3678          }
3679
3680simple_target_specification:
3681          ident
3682          {
3683            THD *thd= YYTHD;
3684            LEX *lex= thd->lex;
3685            Lex_input_stream *lip= YYLIP;
3686            sp_head *sp= lex->sphead;
3687
3688            /*
3689              NOTE: lex->sphead is NULL if we're parsing something like
3690              'GET DIAGNOSTICS v' outside a stored program. We should throw
3691              ER_SP_UNDECLARED_VAR in such cases.
3692            */
3693
3694            if (!sp)
3695            {
3696              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
3697              MYSQL_YYABORT;
3698            }
3699
3700            $$=
3701              create_item_for_sp_var(
3702                thd, $1, NULL,
3703                sp->m_parser_data.get_current_stmt_start_ptr(),
3704                lip->get_tok_start(),
3705                lip->get_ptr());
3706
3707            if ($$ == NULL)
3708              MYSQL_YYABORT;
3709          }
3710        | '@' ident_or_text
3711          {
3712            $$= new (YYTHD->mem_root) Item_func_get_user_var($2);
3713            if ($$ == NULL)
3714              MYSQL_YYABORT;
3715          }
3716        ;
3717
3718statement_information_item_name:
3719          NUMBER_SYM
3720          { $$= Statement_information_item::NUMBER; }
3721        | ROW_COUNT_SYM
3722          { $$= Statement_information_item::ROW_COUNT; }
3723        ;
3724
3725/*
3726   Only a limited subset of <expr> are allowed in GET DIAGNOSTICS
3727   <condition number>, same subset as for SIGNAL/RESIGNAL.
3728*/
3729condition_number:
3730          signal_allowed_expr
3731          { $$= $1; }
3732        ;
3733
3734condition_information:
3735          condition_information_item
3736          {
3737            $$= new (YYTHD->mem_root) List<Condition_information_item>;
3738            if ($$ == NULL || $$->push_back($1))
3739              MYSQL_YYABORT;
3740          }
3741        | condition_information ',' condition_information_item
3742          {
3743            if ($1->push_back($3))
3744              MYSQL_YYABORT;
3745            $$= $1;
3746          }
3747        ;
3748
3749condition_information_item:
3750          simple_target_specification EQ condition_information_item_name
3751          {
3752            $$= new (YYTHD->mem_root) Condition_information_item($3, $1);
3753            if ($$ == NULL)
3754              MYSQL_YYABORT;
3755          }
3756
3757condition_information_item_name:
3758          CLASS_ORIGIN_SYM
3759          { $$= Condition_information_item::CLASS_ORIGIN; }
3760        | SUBCLASS_ORIGIN_SYM
3761          { $$= Condition_information_item::SUBCLASS_ORIGIN; }
3762        | CONSTRAINT_CATALOG_SYM
3763          { $$= Condition_information_item::CONSTRAINT_CATALOG; }
3764        | CONSTRAINT_SCHEMA_SYM
3765          { $$= Condition_information_item::CONSTRAINT_SCHEMA; }
3766        | CONSTRAINT_NAME_SYM
3767          { $$= Condition_information_item::CONSTRAINT_NAME; }
3768        | CATALOG_NAME_SYM
3769          { $$= Condition_information_item::CATALOG_NAME; }
3770        | SCHEMA_NAME_SYM
3771          { $$= Condition_information_item::SCHEMA_NAME; }
3772        | TABLE_NAME_SYM
3773          { $$= Condition_information_item::TABLE_NAME; }
3774        | COLUMN_NAME_SYM
3775          { $$= Condition_information_item::COLUMN_NAME; }
3776        | CURSOR_NAME_SYM
3777          { $$= Condition_information_item::CURSOR_NAME; }
3778        | MESSAGE_TEXT_SYM
3779          { $$= Condition_information_item::MESSAGE_TEXT; }
3780        | MYSQL_ERRNO_SYM
3781          { $$= Condition_information_item::MYSQL_ERRNO; }
3782        | RETURNED_SQLSTATE_SYM
3783          { $$= Condition_information_item::RETURNED_SQLSTATE; }
3784        ;
3785
3786sp_decl_idents:
3787          ident
3788          {
3789            /* NOTE: field definition is filled in sp_decl section. */
3790
3791            THD *thd= YYTHD;
3792            LEX *lex= thd->lex;
3793            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3794
3795            if (pctx->find_variable($1, TRUE))
3796            {
3797              my_error(ER_SP_DUP_VAR, MYF(0), $1.str);
3798              MYSQL_YYABORT;
3799            }
3800
3801            pctx->add_variable(thd,
3802                               $1,
3803                               MYSQL_TYPE_DECIMAL,
3804                               sp_variable::MODE_IN);
3805            $$= 1;
3806          }
3807        | sp_decl_idents ',' ident
3808          {
3809            /* NOTE: field definition is filled in sp_decl section. */
3810
3811            THD *thd= YYTHD;
3812            LEX *lex= thd->lex;
3813            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3814
3815            if (pctx->find_variable($3, TRUE))
3816            {
3817              my_error(ER_SP_DUP_VAR, MYF(0), $3.str);
3818              MYSQL_YYABORT;
3819            }
3820
3821            pctx->add_variable(thd,
3822                               $3,
3823                               MYSQL_TYPE_DECIMAL,
3824                               sp_variable::MODE_IN);
3825            $$= $1 + 1;
3826          }
3827        ;
3828
3829sp_opt_default:
3830        /* Empty */
3831          { $$ = NULL; }
3832        | DEFAULT
3833          { Lex->sphead->m_parser_data.push_expr_start_ptr(YY_TOKEN_END); }
3834          expr
3835          { $$ = $3; }
3836        ;
3837
3838sp_proc_stmt:
3839          sp_proc_stmt_statement
3840        | sp_proc_stmt_return
3841        | sp_proc_stmt_if
3842        | case_stmt_specification
3843        | sp_labeled_block
3844        | sp_unlabeled_block
3845        | sp_labeled_control
3846        | sp_proc_stmt_unlabeled
3847        | sp_proc_stmt_leave
3848        | sp_proc_stmt_iterate
3849        | sp_proc_stmt_open
3850        | sp_proc_stmt_fetch
3851        | sp_proc_stmt_close
3852        ;
3853
3854sp_proc_stmt_if:
3855          IF
3856          { Lex->sphead->m_parser_data.new_cont_backpatch(); }
3857          sp_if END IF
3858          {
3859            sp_head *sp= Lex->sphead;
3860
3861            sp->m_parser_data.do_cont_backpatch(sp->instructions());
3862          }
3863        ;
3864
3865sp_proc_stmt_statement:
3866          {
3867            THD *thd= YYTHD;
3868            LEX *lex= thd->lex;
3869            Lex_input_stream *lip= YYLIP;
3870            sp_head *sp= lex->sphead;
3871
3872            sp->reset_lex(thd);
3873            sp->m_parser_data.set_current_stmt_start_ptr(lip->get_tok_start());
3874          }
3875          statement
3876          {
3877            THD *thd= YYTHD;
3878            LEX *lex= thd->lex;
3879            sp_head *sp= lex->sphead;
3880
3881            sp->m_flags|= sp_get_flags_for_command(lex);
3882            if (lex->sql_command == SQLCOM_CHANGE_DB)
3883            { /* "USE db" doesn't work in a procedure */
3884              my_error(ER_SP_BADSTATEMENT, MYF(0), "USE");
3885              MYSQL_YYABORT;
3886            }
3887            /*
3888              Don't add an instruction for SET statements, since all
3889              instructions for them were already added during processing
3890              of "set" rule.
3891            */
3892            DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION ||
3893                        lex->var_list.is_empty());
3894            if (lex->sql_command != SQLCOM_SET_OPTION)
3895            {
3896              /* Extract the query statement from the tokenizer. */
3897
3898              LEX_STRING query=
3899                make_string(thd,
3900                            sp->m_parser_data.get_current_stmt_start_ptr(),
3901                            YY_TOKEN_END);
3902
3903              if (!query.str)
3904                MYSQL_YYABORT;
3905
3906              /* Add instruction. */
3907
3908              sp_instr_stmt *i=
3909                new (thd->mem_root)
3910                  sp_instr_stmt(sp->instructions(), lex, query);
3911
3912              if (!i || sp->add_instr(thd, i))
3913                MYSQL_YYABORT;
3914            }
3915
3916            if (sp->restore_lex(thd))
3917              MYSQL_YYABORT;
3918          }
3919        ;
3920
3921sp_proc_stmt_return:
3922          RETURN_SYM
3923          {
3924            THD *thd= YYTHD;
3925            LEX *lex= thd->lex;
3926            sp_head *sp= lex->sphead;
3927
3928            sp->reset_lex(thd);
3929
3930            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
3931          }
3932          expr
3933          {
3934            THD *thd= YYTHD;
3935            LEX *lex= thd->lex;
3936            sp_head *sp= lex->sphead;
3937
3938            /* Extract expression string. */
3939
3940            LEX_STRING expr_query= EMPTY_STR;
3941            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
3942
3943            if (lex->is_metadata_used())
3944            {
3945              expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
3946              if (!expr_query.str)
3947                MYSQL_YYABORT;
3948            }
3949
3950            /* Check that this is a stored function. */
3951
3952            if (sp->m_type != SP_TYPE_FUNCTION)
3953            {
3954              my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0));
3955              MYSQL_YYABORT;
3956            }
3957
3958            /* Indicate that we've reached RETURN statement. */
3959
3960            sp->m_flags|= sp_head::HAS_RETURN;
3961
3962            /* Add instruction. */
3963
3964            sp_instr_freturn *i=
3965              new (thd->mem_root)
3966                sp_instr_freturn(sp->instructions(), lex, $3, expr_query,
3967                                 sp->m_return_field_def.sql_type);
3968
3969            if (i == NULL ||
3970                sp->add_instr(thd, i) ||
3971                sp->restore_lex(thd))
3972            {
3973              MYSQL_YYABORT;
3974            }
3975          }
3976        ;
3977
3978sp_proc_stmt_unlabeled:
3979          { /* Unlabeled controls get a secret label. */
3980            THD *thd= YYTHD;
3981            LEX *lex= thd->lex;
3982            sp_head *sp= lex->sphead;
3983            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3984
3985            pctx->push_label(thd,
3986                             EMPTY_STR,
3987                             sp->instructions());
3988          }
3989          sp_unlabeled_control
3990          {
3991            LEX *lex= Lex;
3992            sp_head *sp= lex->sphead;
3993            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
3994
3995            sp->m_parser_data.do_backpatch(pctx->pop_label(),
3996                                           sp->instructions());
3997          }
3998        ;
3999
4000sp_proc_stmt_leave:
4001          LEAVE_SYM label_ident
4002          {
4003            THD *thd= YYTHD;
4004            LEX *lex= Lex;
4005            sp_head *sp = lex->sphead;
4006            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4007            sp_label *lab= pctx->find_label($2);
4008
4009            if (! lab)
4010            {
4011              my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str);
4012              MYSQL_YYABORT;
4013            }
4014
4015            uint ip= sp->instructions();
4016
4017            /*
4018              When jumping to a BEGIN-END block end, the target jump
4019              points to the block hpop/cpop cleanup instructions,
4020              so we should exclude the block context here.
4021              When jumping to something else (i.e., sp_label::ITERATION),
4022              there are no hpop/cpop at the jump destination,
4023              so we should include the block context here for cleanup.
4024            */
4025            bool exclusive= (lab->type == sp_label::BEGIN);
4026
4027            uint n= pctx->diff_handlers(lab->ctx, exclusive);
4028
4029            if (n)
4030            {
4031              sp_instr_hpop *hpop=
4032                new (thd->mem_root) sp_instr_hpop(ip++, pctx);
4033
4034              if (!hpop || sp->add_instr(thd, hpop))
4035                MYSQL_YYABORT;
4036            }
4037
4038            n= pctx->diff_cursors(lab->ctx, exclusive);
4039
4040            if (n)
4041            {
4042              sp_instr_cpop *cpop=
4043                new (thd->mem_root) sp_instr_cpop(ip++, pctx, n);
4044
4045              if (!cpop || sp->add_instr(thd, cpop))
4046                MYSQL_YYABORT;
4047            }
4048
4049            sp_instr_jump *i= new (thd->mem_root) sp_instr_jump(ip, pctx);
4050
4051            if (!i ||
4052                /* Jumping forward */
4053                sp->m_parser_data.add_backpatch_entry(i, lab) ||
4054                sp->add_instr(thd, i))
4055              MYSQL_YYABORT;
4056          }
4057        ;
4058
4059sp_proc_stmt_iterate:
4060          ITERATE_SYM label_ident
4061          {
4062            THD *thd= YYTHD;
4063            LEX *lex= Lex;
4064            sp_head *sp= lex->sphead;
4065            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4066            sp_label *lab= pctx->find_label($2);
4067
4068            if (! lab || lab->type != sp_label::ITERATION)
4069            {
4070              my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str);
4071              MYSQL_YYABORT;
4072            }
4073
4074            uint ip= sp->instructions();
4075
4076            /* Inclusive the dest. */
4077            uint n= pctx->diff_handlers(lab->ctx, FALSE);
4078
4079            if (n)
4080            {
4081              sp_instr_hpop *hpop=
4082                new (thd->mem_root) sp_instr_hpop(ip++, pctx);
4083
4084              if (!hpop || sp->add_instr(thd, hpop))
4085                MYSQL_YYABORT;
4086            }
4087
4088            /* Inclusive the dest. */
4089            n= pctx->diff_cursors(lab->ctx, FALSE);
4090
4091            if (n)
4092            {
4093              sp_instr_cpop *cpop=
4094                new (thd->mem_root) sp_instr_cpop(ip++, pctx, n);
4095
4096              if (!cpop || sp->add_instr(thd, cpop))
4097                MYSQL_YYABORT;
4098            }
4099
4100            /* Jump back */
4101            sp_instr_jump *i=
4102              new (thd->mem_root) sp_instr_jump(ip, pctx, lab->ip);
4103
4104            if (!i || sp->add_instr(thd, i))
4105              MYSQL_YYABORT;
4106          }
4107        ;
4108
4109sp_proc_stmt_open:
4110          OPEN_SYM ident
4111          {
4112            THD *thd= YYTHD;
4113            LEX *lex= Lex;
4114            sp_head *sp= lex->sphead;
4115            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4116            uint offset;
4117
4118            if (! pctx->find_cursor($2, &offset, false))
4119            {
4120              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
4121              MYSQL_YYABORT;
4122            }
4123
4124            sp_instr_copen *i=
4125              new (thd->mem_root)
4126                sp_instr_copen(sp->instructions(), pctx, offset);
4127
4128            if (!i || sp->add_instr(thd, i))
4129              MYSQL_YYABORT;
4130          }
4131        ;
4132
4133sp_proc_stmt_fetch:
4134          FETCH_SYM sp_opt_fetch_noise ident INTO
4135          {
4136            THD *thd= YYTHD;
4137            LEX *lex= Lex;
4138            sp_head *sp= lex->sphead;
4139            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4140            uint offset;
4141
4142            if (! pctx->find_cursor($3, &offset, false))
4143            {
4144              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str);
4145              MYSQL_YYABORT;
4146            }
4147
4148            sp_instr_cfetch *i=
4149              new (thd->mem_root)
4150                sp_instr_cfetch(sp->instructions(), pctx, offset);
4151
4152            if (!i || sp->add_instr(thd, i))
4153              MYSQL_YYABORT;
4154          }
4155          sp_fetch_list
4156          {}
4157        ;
4158
4159sp_proc_stmt_close:
4160          CLOSE_SYM ident
4161          {
4162            THD *thd= YYTHD;
4163            LEX *lex= Lex;
4164            sp_head *sp= lex->sphead;
4165            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4166            uint offset;
4167
4168            if (! pctx->find_cursor($2, &offset, false))
4169            {
4170              my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
4171              MYSQL_YYABORT;
4172            }
4173
4174            sp_instr_cclose *i=
4175              new (thd->mem_root)
4176                sp_instr_cclose(sp->instructions(), pctx, offset);
4177
4178            if (!i || sp->add_instr(thd, i))
4179              MYSQL_YYABORT;
4180          }
4181        ;
4182
4183sp_opt_fetch_noise:
4184          /* Empty */
4185        | NEXT_SYM FROM
4186        | FROM
4187        ;
4188
4189sp_fetch_list:
4190          ident
4191          {
4192            LEX *lex= Lex;
4193            sp_head *sp= lex->sphead;
4194            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4195            sp_variable *spv;
4196
4197            if (!pctx || !(spv= pctx->find_variable($1, false)))
4198            {
4199              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
4200              MYSQL_YYABORT;
4201            }
4202
4203            /* An SP local variable */
4204            sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
4205
4206            i->add_to_varlist(spv);
4207          }
4208        | sp_fetch_list ',' ident
4209          {
4210            LEX *lex= Lex;
4211            sp_head *sp= lex->sphead;
4212            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4213            sp_variable *spv;
4214
4215            if (!pctx || !(spv= pctx->find_variable($3, false)))
4216            {
4217              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str);
4218              MYSQL_YYABORT;
4219            }
4220
4221            /* An SP local variable */
4222            sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
4223
4224            i->add_to_varlist(spv);
4225          }
4226        ;
4227
4228sp_if:
4229          {
4230            THD *thd= YYTHD;
4231            LEX *lex= thd->lex;
4232            sp_head *sp= lex->sphead;
4233
4234            sp->reset_lex(thd);
4235            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4236          }
4237          expr
4238          {
4239            THD *thd= YYTHD;
4240            LEX *lex= Lex;
4241            sp_head *sp= lex->sphead;
4242            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4243
4244            /* Extract expression string. */
4245
4246            LEX_STRING expr_query= EMPTY_STR;
4247            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4248
4249            if (lex->is_metadata_used())
4250            {
4251              expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4252              if (!expr_query.str)
4253                MYSQL_YYABORT;
4254            }
4255
4256            sp_instr_jump_if_not *i =
4257              new (thd->mem_root)
4258                sp_instr_jump_if_not(sp->instructions(), lex,
4259                                     $2, expr_query);
4260
4261            /* Add jump instruction. */
4262
4263            if (i == NULL ||
4264                sp->m_parser_data.add_backpatch_entry(
4265                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4266                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4267                sp->add_instr(thd, i) ||
4268                sp->restore_lex(thd))
4269            {
4270              MYSQL_YYABORT;
4271            }
4272          }
4273          THEN_SYM sp_proc_stmts1
4274          {
4275            THD *thd= YYTHD;
4276            LEX *lex= thd->lex;
4277            sp_head *sp= lex->sphead;
4278            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4279
4280            sp_instr_jump *i =
4281              new (thd->mem_root) sp_instr_jump(sp->instructions(), pctx);
4282
4283            if (!i || sp->add_instr(thd, i))
4284              MYSQL_YYABORT;
4285
4286            sp->m_parser_data.do_backpatch(pctx->pop_label(),
4287                                           sp->instructions());
4288
4289            sp->m_parser_data.add_backpatch_entry(
4290              i, pctx->push_label(thd, EMPTY_STR, 0));
4291          }
4292          sp_elseifs
4293          {
4294            LEX *lex= Lex;
4295            sp_head *sp= lex->sphead;
4296            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4297
4298            sp->m_parser_data.do_backpatch(pctx->pop_label(),
4299                                           sp->instructions());
4300          }
4301        ;
4302
4303sp_elseifs:
4304          /* Empty */
4305        | ELSEIF_SYM sp_if
4306        | ELSE sp_proc_stmts1
4307        ;
4308
4309case_stmt_specification:
4310          simple_case_stmt
4311        | searched_case_stmt
4312        ;
4313
4314simple_case_stmt:
4315          CASE_SYM
4316          {
4317            THD *thd= YYTHD;
4318            LEX *lex= thd->lex;
4319            sp_head *sp= lex->sphead;
4320
4321            case_stmt_action_case(thd);
4322
4323            sp->reset_lex(thd); /* For CASE-expr $3 */
4324            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4325          }
4326          expr
4327          {
4328            THD *thd= YYTHD;
4329            LEX *lex= Lex;
4330            sp_head *sp= lex->sphead;
4331
4332            /* Extract CASE-expression string. */
4333
4334            LEX_STRING case_expr_query= EMPTY_STR;
4335            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4336
4337            if (lex->is_metadata_used())
4338            {
4339              case_expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4340              if (!case_expr_query.str)
4341                MYSQL_YYABORT;
4342            }
4343
4344            /* Register new CASE-expression and get its id. */
4345
4346            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4347            int case_expr_id= pctx->push_case_expr_id();
4348
4349            if (case_expr_id < 0)
4350              MYSQL_YYABORT;
4351
4352            /* Add CASE-set instruction. */
4353
4354            sp_instr_set_case_expr *i=
4355              new (thd->mem_root)
4356                sp_instr_set_case_expr(sp->instructions(), lex,
4357                                       case_expr_id, $3, case_expr_query);
4358
4359            if (i == NULL ||
4360                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4361                sp->add_instr(thd, i) ||
4362                sp->restore_lex(thd))
4363            {
4364              MYSQL_YYABORT;
4365            }
4366          }
4367          simple_when_clause_list
4368          else_clause_opt
4369          END
4370          CASE_SYM
4371          {
4372            case_stmt_action_end_case(Lex, true);
4373          }
4374        ;
4375
4376searched_case_stmt:
4377          CASE_SYM
4378          {
4379            case_stmt_action_case(YYTHD);
4380          }
4381          searched_when_clause_list
4382          else_clause_opt
4383          END
4384          CASE_SYM
4385          {
4386            case_stmt_action_end_case(Lex, false);
4387          }
4388        ;
4389
4390simple_when_clause_list:
4391          simple_when_clause
4392        | simple_when_clause_list simple_when_clause
4393        ;
4394
4395searched_when_clause_list:
4396          searched_when_clause
4397        | searched_when_clause_list searched_when_clause
4398        ;
4399
4400simple_when_clause:
4401          WHEN_SYM
4402          {
4403            THD *thd= YYTHD;
4404            LEX *lex= thd->lex;
4405            sp_head *sp= lex->sphead;
4406
4407            sp->reset_lex(thd);
4408            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4409          }
4410          expr
4411          {
4412            /* Simple case: <caseval> = <whenval> */
4413
4414            THD *thd= YYTHD;
4415            LEX *lex= thd->lex;
4416            sp_head *sp= lex->sphead;
4417            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4418
4419            /* Extract expression string. */
4420
4421            LEX_STRING when_expr_query= EMPTY_STR;
4422            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4423
4424            if (lex->is_metadata_used())
4425            {
4426              when_expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4427              if (!when_expr_query.str)
4428                MYSQL_YYABORT;
4429            }
4430
4431            /* Add CASE-when-jump instruction. */
4432
4433            sp_instr_jump_case_when *i =
4434              new (thd->mem_root)
4435                sp_instr_jump_case_when(sp->instructions(), lex,
4436                                        pctx->get_current_case_expr_id(),
4437                                        $3, when_expr_query);
4438
4439            if (i == NULL ||
4440                i->on_after_expr_parsing(thd) ||
4441                sp->m_parser_data.add_backpatch_entry(
4442                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4443                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4444                sp->add_instr(thd, i) ||
4445                sp->restore_lex(thd))
4446            {
4447              MYSQL_YYABORT;
4448            }
4449          }
4450          THEN_SYM
4451          sp_proc_stmts1
4452          {
4453            if (case_stmt_action_then(YYTHD, Lex))
4454              MYSQL_YYABORT;
4455          }
4456        ;
4457
4458searched_when_clause:
4459          WHEN_SYM
4460          {
4461            THD *thd= YYTHD;
4462            LEX *lex= thd->lex;
4463            sp_head *sp= lex->sphead;
4464
4465            sp->reset_lex(thd);
4466            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4467          }
4468          expr
4469          {
4470            THD *thd= YYTHD;
4471            LEX *lex= thd->lex;
4472            sp_head *sp= lex->sphead;
4473            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4474
4475            /* Extract expression string. */
4476
4477            LEX_STRING when_query= EMPTY_STR;
4478            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4479
4480            if (lex->is_metadata_used())
4481            {
4482              when_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4483              if (!when_query.str)
4484                MYSQL_YYABORT;
4485            }
4486
4487            /* Add jump instruction. */
4488
4489            sp_instr_jump_if_not *i=
4490              new (thd->mem_root)
4491                sp_instr_jump_if_not(sp->instructions(), lex, $3, when_query);
4492
4493            if (i == NULL ||
4494                sp->m_parser_data.add_backpatch_entry(
4495                  i, pctx->push_label(thd, EMPTY_STR, 0)) ||
4496                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4497                sp->add_instr(thd, i) ||
4498                sp->restore_lex(thd))
4499            {
4500              MYSQL_YYABORT;
4501            }
4502          }
4503          THEN_SYM
4504          sp_proc_stmts1
4505          {
4506            if (case_stmt_action_then(YYTHD, Lex))
4507              MYSQL_YYABORT;
4508          }
4509        ;
4510
4511else_clause_opt:
4512          /* empty */
4513          {
4514            THD *thd= YYTHD;
4515            LEX *lex= Lex;
4516            sp_head *sp= lex->sphead;
4517            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4518
4519            sp_instr_error *i=
4520              new (thd->mem_root)
4521                sp_instr_error(sp->instructions(), pctx, ER_SP_CASE_NOT_FOUND);
4522
4523            if (!i || sp->add_instr(thd, i))
4524              MYSQL_YYABORT;
4525          }
4526        | ELSE sp_proc_stmts1
4527        ;
4528
4529sp_labeled_control:
4530          label_ident ':'
4531          {
4532            LEX *lex= Lex;
4533            sp_head *sp= lex->sphead;
4534            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4535            sp_label *lab= pctx->find_label($1);
4536
4537            if (lab)
4538            {
4539              my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
4540              MYSQL_YYABORT;
4541            }
4542            else
4543            {
4544              lab= pctx->push_label(YYTHD, $1, sp->instructions());
4545              lab->type= sp_label::ITERATION;
4546            }
4547          }
4548          sp_unlabeled_control sp_opt_label
4549          {
4550            LEX *lex= Lex;
4551            sp_head *sp= lex->sphead;
4552            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4553            sp_label *lab= pctx->pop_label();
4554
4555            if ($5.str)
4556            {
4557              if (my_strcasecmp(system_charset_info, $5.str, lab->name.str) != 0)
4558              {
4559                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
4560                MYSQL_YYABORT;
4561              }
4562            }
4563            sp->m_parser_data.do_backpatch(lab, sp->instructions());
4564          }
4565        ;
4566
4567sp_opt_label:
4568          /* Empty  */  { $$= null_lex_str; }
4569        | label_ident   { $$= $1; }
4570        ;
4571
4572sp_labeled_block:
4573          label_ident ':'
4574          {
4575            LEX *lex= Lex;
4576            sp_head *sp= lex->sphead;
4577            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4578            sp_label *lab= pctx->find_label($1);
4579
4580            if (lab)
4581            {
4582              my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
4583              MYSQL_YYABORT;
4584            }
4585
4586            lab= pctx->push_label(YYTHD, $1, sp->instructions());
4587            lab->type= sp_label::BEGIN;
4588          }
4589          sp_block_content sp_opt_label
4590          {
4591            LEX *lex= Lex;
4592            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4593            sp_label *lab= pctx->pop_label();
4594
4595            if ($5.str)
4596            {
4597              if (my_strcasecmp(system_charset_info, $5.str, lab->name.str) != 0)
4598              {
4599                my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
4600                MYSQL_YYABORT;
4601              }
4602            }
4603          }
4604        ;
4605
4606sp_unlabeled_block:
4607          { /* Unlabeled blocks get a secret label. */
4608            LEX *lex= Lex;
4609            sp_head *sp= lex->sphead;
4610            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4611
4612            sp_label *lab=
4613              pctx->push_label(YYTHD, EMPTY_STR, sp->instructions());
4614
4615            lab->type= sp_label::BEGIN;
4616          }
4617          sp_block_content
4618          {
4619            LEX *lex= Lex;
4620            lex->get_sp_current_parsing_ctx()->pop_label();
4621          }
4622        ;
4623
4624sp_block_content:
4625          BEGIN_SYM
4626          { /* QQ This is just a dummy for grouping declarations and statements
4627              together. No [[NOT] ATOMIC] yet, and we need to figure out how
4628              make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
4629            THD *thd= YYTHD;
4630            LEX *lex= thd->lex;
4631            sp_pcontext *parent_pctx= lex->get_sp_current_parsing_ctx();
4632
4633            sp_pcontext *child_pctx=
4634              parent_pctx->push_context(thd, sp_pcontext::REGULAR_SCOPE);
4635
4636            lex->set_sp_current_parsing_ctx(child_pctx);
4637          }
4638          sp_decls
4639          sp_proc_stmts
4640          END
4641          {
4642            THD *thd= YYTHD;
4643            LEX *lex= Lex;
4644            sp_head *sp= lex->sphead;
4645            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4646
4647            // We always have a label.
4648            sp->m_parser_data.do_backpatch(pctx->last_label(),
4649                                           sp->instructions());
4650
4651            if ($3.hndlrs)
4652            {
4653              sp_instr *i=
4654                new (thd->mem_root) sp_instr_hpop(sp->instructions(), pctx);
4655
4656              if (!i || sp->add_instr(thd, i))
4657                MYSQL_YYABORT;
4658            }
4659
4660            if ($3.curs)
4661            {
4662              sp_instr *i=
4663                new (thd->mem_root)
4664                  sp_instr_cpop(sp->instructions(), pctx, $3.curs);
4665
4666              if (!i || sp->add_instr(thd, i))
4667                MYSQL_YYABORT;
4668            }
4669
4670            lex->set_sp_current_parsing_ctx(pctx->pop_context());
4671          }
4672        ;
4673
4674sp_unlabeled_control:
4675          LOOP_SYM
4676          sp_proc_stmts1 END LOOP_SYM
4677          {
4678            THD *thd= YYTHD;
4679            LEX *lex= Lex;
4680            sp_head *sp= lex->sphead;
4681            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4682
4683            sp_instr_jump *i=
4684                new (thd->mem_root)
4685                  sp_instr_jump(sp->instructions(), pctx,
4686                                pctx->last_label()->ip);
4687
4688            if (!i || sp->add_instr(thd, i))
4689              MYSQL_YYABORT;
4690          }
4691        | WHILE_SYM
4692          {
4693            THD *thd= YYTHD;
4694            LEX *lex= thd->lex;
4695            sp_head *sp= lex->sphead;
4696
4697            sp->reset_lex(thd);
4698            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4699          }
4700          expr
4701          {
4702            THD *thd= YYTHD;
4703            LEX *lex= Lex;
4704            sp_head *sp= lex->sphead;
4705            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4706
4707            /* Extract expression string. */
4708
4709            LEX_STRING expr_query= EMPTY_STR;
4710            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4711
4712            if (lex->is_metadata_used())
4713            {
4714              expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4715              if (!expr_query.str)
4716                MYSQL_YYABORT;
4717            }
4718
4719            /* Add jump instruction. */
4720
4721            sp_instr_jump_if_not *i=
4722              new (thd->mem_root)
4723                sp_instr_jump_if_not(sp->instructions(), lex, $3, expr_query);
4724
4725            if (i == NULL ||
4726                /* Jumping forward */
4727                sp->m_parser_data.add_backpatch_entry(i, pctx->last_label()) ||
4728                sp->m_parser_data.new_cont_backpatch() ||
4729                sp->m_parser_data.add_cont_backpatch_entry(i) ||
4730                sp->add_instr(thd, i) ||
4731                sp->restore_lex(thd))
4732            {
4733              MYSQL_YYABORT;
4734            }
4735          }
4736          DO_SYM
4737          sp_proc_stmts1
4738          END WHILE_SYM
4739          {
4740            THD *thd= YYTHD;
4741            LEX *lex= Lex;
4742            sp_head *sp= lex->sphead;
4743            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4744
4745            sp_instr_jump *i=
4746              new (thd->mem_root)
4747                sp_instr_jump(sp->instructions(), pctx, pctx->last_label()->ip);
4748
4749            if (!i || sp->add_instr(thd, i))
4750              MYSQL_YYABORT;
4751
4752            sp->m_parser_data.do_cont_backpatch(sp->instructions());
4753          }
4754        | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM
4755          {
4756            THD *thd= YYTHD;
4757            LEX *lex= thd->lex;
4758            sp_head *sp= lex->sphead;
4759
4760            sp->reset_lex(thd);
4761            sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_END);
4762          }
4763          expr
4764          {
4765            THD *thd= YYTHD;
4766            LEX *lex= thd->lex;
4767            sp_head *sp= lex->sphead;
4768            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
4769            uint ip= sp->instructions();
4770
4771            /* Extract expression string. */
4772
4773            LEX_STRING expr_query= EMPTY_STR;
4774            const char *expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
4775
4776            if (lex->is_metadata_used())
4777            {
4778              expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
4779              if (!expr_query.str)
4780                MYSQL_YYABORT;
4781            }
4782
4783            /* Add jump instruction. */
4784
4785            sp_instr_jump_if_not *i=
4786              new (thd->mem_root)
4787                sp_instr_jump_if_not(ip, lex, $5, expr_query,
4788                                     pctx->last_label()->ip);
4789
4790            if (i == NULL ||
4791                sp->add_instr(thd, i) ||
4792                sp->restore_lex(thd))
4793            {
4794              MYSQL_YYABORT;
4795            }
4796
4797            /* We can shortcut the cont_backpatch here */
4798            i->set_cont_dest(ip + 1);
4799          }
4800          END REPEAT_SYM
4801        ;
4802
4803trg_action_time:
4804            BEFORE_SYM
4805            { $$= TRG_ACTION_BEFORE; }
4806          | AFTER_SYM
4807            { $$= TRG_ACTION_AFTER; }
4808          ;
4809
4810trg_event:
4811            INSERT
4812            { $$= TRG_EVENT_INSERT; }
4813          | UPDATE_SYM
4814            { $$= TRG_EVENT_UPDATE; }
4815          | DELETE_SYM
4816            { $$= TRG_EVENT_DELETE; }
4817          ;
4818/*
4819  This part of the parser contains common code for all TABLESPACE
4820  commands.
4821  CREATE TABLESPACE name ...
4822  ALTER TABLESPACE name CHANGE DATAFILE ...
4823  ALTER TABLESPACE name ADD DATAFILE ...
4824  ALTER TABLESPACE name access_mode
4825  CREATE LOGFILE GROUP_SYM name ...
4826  ALTER LOGFILE GROUP_SYM name ADD UNDOFILE ..
4827  ALTER LOGFILE GROUP_SYM name ADD REDOFILE ..
4828  DROP TABLESPACE name
4829  DROP LOGFILE GROUP_SYM name
4830*/
4831change_tablespace_access:
4832          tablespace_name
4833          ts_access_mode
4834        ;
4835
4836change_tablespace_info:
4837          tablespace_name
4838          CHANGE ts_datafile
4839          change_ts_option_list
4840        ;
4841
4842tablespace_info:
4843          tablespace_name
4844          ADD ts_datafile
4845          opt_logfile_group_name
4846          tablespace_option_list
4847        ;
4848
4849opt_logfile_group_name:
4850          /* empty */ {}
4851        | USE_SYM LOGFILE_SYM GROUP_SYM ident
4852          {
4853            LEX *lex= Lex;
4854            lex->alter_tablespace_info->logfile_group_name= $4.str;
4855          }
4856        ;
4857
4858alter_tablespace_info:
4859          tablespace_name
4860          ADD ts_datafile
4861          alter_tablespace_option_list
4862          {
4863            Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_ADD_FILE;
4864          }
4865        | tablespace_name
4866          DROP ts_datafile
4867          alter_tablespace_option_list
4868          {
4869            Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_DROP_FILE;
4870          }
4871        ;
4872
4873logfile_group_info:
4874          logfile_group_name
4875          add_log_file
4876          logfile_group_option_list
4877        ;
4878
4879alter_logfile_group_info:
4880          logfile_group_name
4881          add_log_file
4882          alter_logfile_group_option_list
4883        ;
4884
4885add_log_file:
4886          ADD lg_undofile
4887        | ADD lg_redofile
4888        ;
4889
4890change_ts_option_list:
4891          /* empty */ {}
4892          change_ts_options
4893        ;
4894
4895change_ts_options:
4896          change_ts_option
4897        | change_ts_options change_ts_option
4898        | change_ts_options ',' change_ts_option
4899        ;
4900
4901change_ts_option:
4902          opt_ts_initial_size
4903        | opt_ts_autoextend_size
4904        | opt_ts_max_size
4905        ;
4906
4907tablespace_option_list:
4908          /* empty */
4909        | tablespace_options
4910        ;
4911
4912tablespace_options:
4913          tablespace_option
4914        | tablespace_options tablespace_option
4915        | tablespace_options ',' tablespace_option
4916        ;
4917
4918tablespace_option:
4919          opt_ts_initial_size
4920        | opt_ts_autoextend_size
4921        | opt_ts_max_size
4922        | opt_ts_extent_size
4923        | opt_ts_nodegroup
4924        | opt_ts_engine
4925        | ts_wait
4926        | opt_ts_comment
4927        ;
4928
4929alter_tablespace_option_list:
4930          /* empty */
4931        | alter_tablespace_options
4932        ;
4933
4934alter_tablespace_options:
4935          alter_tablespace_option
4936        | alter_tablespace_options alter_tablespace_option
4937        | alter_tablespace_options ',' alter_tablespace_option
4938        ;
4939
4940alter_tablespace_option:
4941          opt_ts_initial_size
4942        | opt_ts_autoextend_size
4943        | opt_ts_max_size
4944        | opt_ts_engine
4945        | ts_wait
4946        ;
4947
4948logfile_group_option_list:
4949          /* empty */
4950        | logfile_group_options
4951        ;
4952
4953logfile_group_options:
4954          logfile_group_option
4955        | logfile_group_options logfile_group_option
4956        | logfile_group_options ',' logfile_group_option
4957        ;
4958
4959logfile_group_option:
4960          opt_ts_initial_size
4961        | opt_ts_undo_buffer_size
4962        | opt_ts_redo_buffer_size
4963        | opt_ts_nodegroup
4964        | opt_ts_engine
4965        | ts_wait
4966        | opt_ts_comment
4967        ;
4968
4969alter_logfile_group_option_list:
4970          /* empty */
4971        | alter_logfile_group_options
4972        ;
4973
4974alter_logfile_group_options:
4975          alter_logfile_group_option
4976        | alter_logfile_group_options alter_logfile_group_option
4977        | alter_logfile_group_options ',' alter_logfile_group_option
4978        ;
4979
4980alter_logfile_group_option:
4981          opt_ts_initial_size
4982        | opt_ts_engine
4983        | ts_wait
4984        ;
4985
4986
4987ts_datafile:
4988          DATAFILE_SYM TEXT_STRING_sys
4989          {
4990            LEX *lex= Lex;
4991            lex->alter_tablespace_info->data_file_name= $2.str;
4992          }
4993        ;
4994
4995lg_undofile:
4996          UNDOFILE_SYM TEXT_STRING_sys
4997          {
4998            LEX *lex= Lex;
4999            lex->alter_tablespace_info->undo_file_name= $2.str;
5000          }
5001        ;
5002
5003lg_redofile:
5004          REDOFILE_SYM TEXT_STRING_sys
5005          {
5006            LEX *lex= Lex;
5007            lex->alter_tablespace_info->redo_file_name= $2.str;
5008          }
5009        ;
5010
5011tablespace_name:
5012          ident
5013          {
5014            LEX *lex= Lex;
5015            lex->alter_tablespace_info= new st_alter_tablespace();
5016            if (lex->alter_tablespace_info == NULL)
5017              MYSQL_YYABORT;
5018            lex->alter_tablespace_info->tablespace_name= $1.str;
5019            lex->sql_command= SQLCOM_ALTER_TABLESPACE;
5020          }
5021        ;
5022
5023logfile_group_name:
5024          ident
5025          {
5026            LEX *lex= Lex;
5027            lex->alter_tablespace_info= new st_alter_tablespace();
5028            if (lex->alter_tablespace_info == NULL)
5029              MYSQL_YYABORT;
5030            lex->alter_tablespace_info->logfile_group_name= $1.str;
5031            lex->sql_command= SQLCOM_ALTER_TABLESPACE;
5032          }
5033        ;
5034
5035ts_access_mode:
5036          READ_ONLY_SYM
5037          {
5038            LEX *lex= Lex;
5039            lex->alter_tablespace_info->ts_access_mode= TS_READ_ONLY;
5040          }
5041        | READ_WRITE_SYM
5042          {
5043            LEX *lex= Lex;
5044            lex->alter_tablespace_info->ts_access_mode= TS_READ_WRITE;
5045          }
5046        | NOT_SYM ACCESSIBLE_SYM
5047          {
5048            LEX *lex= Lex;
5049            lex->alter_tablespace_info->ts_access_mode= TS_NOT_ACCESSIBLE;
5050          }
5051        ;
5052
5053opt_ts_initial_size:
5054          INITIAL_SIZE_SYM opt_equal size_number
5055          {
5056            LEX *lex= Lex;
5057            lex->alter_tablespace_info->initial_size= $3;
5058          }
5059        ;
5060
5061opt_ts_autoextend_size:
5062          AUTOEXTEND_SIZE_SYM opt_equal size_number
5063          {
5064            LEX *lex= Lex;
5065            lex->alter_tablespace_info->autoextend_size= $3;
5066          }
5067        ;
5068
5069opt_ts_max_size:
5070          MAX_SIZE_SYM opt_equal size_number
5071          {
5072            LEX *lex= Lex;
5073            lex->alter_tablespace_info->max_size= $3;
5074          }
5075        ;
5076
5077opt_ts_extent_size:
5078          EXTENT_SIZE_SYM opt_equal size_number
5079          {
5080            LEX *lex= Lex;
5081            lex->alter_tablespace_info->extent_size= $3;
5082          }
5083        ;
5084
5085opt_ts_undo_buffer_size:
5086          UNDO_BUFFER_SIZE_SYM opt_equal size_number
5087          {
5088            LEX *lex= Lex;
5089            lex->alter_tablespace_info->undo_buffer_size= $3;
5090          }
5091        ;
5092
5093opt_ts_redo_buffer_size:
5094          REDO_BUFFER_SIZE_SYM opt_equal size_number
5095          {
5096            LEX *lex= Lex;
5097            lex->alter_tablespace_info->redo_buffer_size= $3;
5098          }
5099        ;
5100
5101opt_ts_nodegroup:
5102          NODEGROUP_SYM opt_equal real_ulong_num
5103          {
5104            LEX *lex= Lex;
5105            if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)
5106            {
5107              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
5108              MYSQL_YYABORT;
5109            }
5110            lex->alter_tablespace_info->nodegroup_id= $3;
5111          }
5112        ;
5113
5114opt_ts_comment:
5115          COMMENT_SYM opt_equal TEXT_STRING_sys
5116          {
5117            LEX *lex= Lex;
5118            if (lex->alter_tablespace_info->ts_comment != NULL)
5119            {
5120              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
5121              MYSQL_YYABORT;
5122            }
5123            lex->alter_tablespace_info->ts_comment= $3.str;
5124          }
5125        ;
5126
5127opt_ts_engine:
5128          opt_storage ENGINE_SYM opt_equal storage_engines
5129          {
5130            LEX *lex= Lex;
5131            if (lex->alter_tablespace_info->storage_engine != NULL)
5132            {
5133              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),
5134                       "STORAGE ENGINE");
5135              MYSQL_YYABORT;
5136            }
5137            lex->alter_tablespace_info->storage_engine= $4;
5138          }
5139        ;
5140
5141ts_wait:
5142          WAIT_SYM
5143          {
5144            LEX *lex= Lex;
5145            lex->alter_tablespace_info->wait_until_completed= TRUE;
5146          }
5147        | NO_WAIT_SYM
5148          {
5149            LEX *lex= Lex;
5150            if (!(lex->alter_tablespace_info->wait_until_completed))
5151            {
5152              my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
5153              MYSQL_YYABORT;
5154            }
5155            lex->alter_tablespace_info->wait_until_completed= FALSE;
5156          }
5157        ;
5158
5159size_number:
5160          real_ulonglong_num { $$= $1;}
5161        | IDENT_sys
5162          {
5163            ulonglong number;
5164            uint text_shift_number= 0;
5165            longlong prefix_number;
5166            char *start_ptr= $1.str;
5167            uint str_len= $1.length;
5168            char *end_ptr= start_ptr + str_len;
5169            int error;
5170            prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
5171            if ((start_ptr + str_len - 1) == end_ptr)
5172            {
5173              switch (end_ptr[0])
5174              {
5175                case 'g':
5176                case 'G':
5177                  text_shift_number+=10;
5178                  // fallthrough
5179                case 'm':
5180                case 'M':
5181                  text_shift_number+=10;
5182                  // fallthrough
5183                case 'k':
5184                case 'K':
5185                  text_shift_number+=10;
5186                  break;
5187                default:
5188                {
5189                  my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
5190                  MYSQL_YYABORT;
5191                }
5192              }
5193              if (prefix_number >> 31)
5194              {
5195                my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0));
5196                MYSQL_YYABORT;
5197              }
5198              number= prefix_number << text_shift_number;
5199            }
5200            else
5201            {
5202              my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
5203              MYSQL_YYABORT;
5204            }
5205            $$= number;
5206          }
5207        ;
5208
5209/*
5210  End tablespace part
5211*/
5212
5213create2:
5214          '(' create2a {}
5215        | opt_create_table_options
5216          opt_create_partitioning
5217          create3 {}
5218        | LIKE table_ident
5219          {
5220            THD *thd= YYTHD;
5221            TABLE_LIST *src_table;
5222            LEX *lex= thd->lex;
5223
5224            lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
5225            src_table= lex->select_lex.add_table_to_list(thd, $2, NULL, 0,
5226                                                         TL_READ,
5227                                                         MDL_SHARED_READ);
5228            if (! src_table)
5229              MYSQL_YYABORT;
5230            /* CREATE TABLE ... LIKE is not allowed for views. */
5231            src_table->required_type= FRMTYPE_TABLE;
5232          }
5233        | '(' LIKE table_ident ')'
5234          {
5235            THD *thd= YYTHD;
5236            TABLE_LIST *src_table;
5237            LEX *lex= thd->lex;
5238
5239            lex->create_info.options|= HA_LEX_CREATE_TABLE_LIKE;
5240            src_table= lex->select_lex.add_table_to_list(thd, $3, NULL, 0,
5241                                                         TL_READ,
5242                                                         MDL_SHARED_READ);
5243            if (! src_table)
5244              MYSQL_YYABORT;
5245            /* CREATE TABLE ... LIKE is not allowed for views. */
5246            src_table->required_type= FRMTYPE_TABLE;
5247          }
5248        ;
5249
5250create2a:
5251          create_field_list ')' opt_create_table_options
5252          opt_create_partitioning
5253          create3 {}
5254        |  opt_create_partitioning
5255           create_select ')'
5256           { Select->set_braces(1);}
5257           union_opt {}
5258        ;
5259
5260create3:
5261          /* empty */ {}
5262        | opt_duplicate opt_as create_select
5263          { Select->set_braces(0);}
5264          union_clause {}
5265        | opt_duplicate opt_as '(' create_select ')'
5266          { Select->set_braces(1);}
5267          union_opt {}
5268        ;
5269
5270opt_create_partitioning:
5271          opt_partitioning
5272          {
5273            /*
5274              Remove all tables used in PARTITION clause from the global table
5275              list. Partitioning with subqueries is not allowed anyway.
5276            */
5277            TABLE_LIST *last_non_sel_table= Lex->create_last_non_select_table;
5278            last_non_sel_table->next_global= 0;
5279            Lex->query_tables_last= &last_non_sel_table->next_global;
5280          }
5281        ;
5282
5283/*
5284 This part of the parser is about handling of the partition information.
5285
5286 It's first version was written by Mikael Ronström with lots of answers to
5287 questions provided by Antony Curtis.
5288
5289 The partition grammar can be called from three places.
5290 1) CREATE TABLE ... PARTITION ..
5291 2) ALTER TABLE table_name PARTITION ...
5292 3) PARTITION ...
5293
5294 The first place is called when a new table is created from a MySQL client.
5295 The second place is called when a table is altered with the ALTER TABLE
5296 command from a MySQL client.
5297 The third place is called when opening an frm file and finding partition
5298 info in the .frm file. It is necessary to avoid allowing PARTITION to be
5299 an allowed entry point for SQL client queries. This is arranged by setting
5300 some state variables before arriving here.
5301
5302 To be able to handle errors we will only set error code in this code
5303 and handle the error condition in the function calling the parser. This
5304 is necessary to ensure we can also handle errors when calling the parser
5305 from the openfrm function.
5306*/
5307opt_partitioning:
5308          /* empty */ {}
5309        | partitioning
5310        ;
5311
5312partitioning:
5313          PARTITION_SYM have_partitioning
5314          {
5315            LEX *lex= Lex;
5316            lex->part_info= new partition_info();
5317            if (!lex->part_info)
5318            {
5319              mem_alloc_error(sizeof(partition_info));
5320              MYSQL_YYABORT;
5321            }
5322            if (lex->sql_command == SQLCOM_ALTER_TABLE)
5323            {
5324              lex->alter_info.flags|= Alter_info::ALTER_PARTITION;
5325            }
5326          }
5327          partition
5328        ;
5329
5330have_partitioning:
5331          /* empty */
5332          {
5333#ifdef WITH_PARTITION_STORAGE_ENGINE
5334            LEX_STRING partition_name={C_STRING_WITH_LEN("partition")};
5335            if (!plugin_is_ready(&partition_name, MYSQL_STORAGE_ENGINE_PLUGIN))
5336            {
5337              my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
5338                      "--skip-partition");
5339              MYSQL_YYABORT;
5340            }
5341#else
5342            my_error(ER_FEATURE_DISABLED, MYF(0), "partitioning",
5343                    "--with-plugin-partition");
5344            MYSQL_YYABORT;
5345#endif
5346          }
5347        ;
5348
5349partition_entry:
5350          PARTITION_SYM
5351          {
5352            LEX *lex= Lex;
5353            if (!lex->part_info)
5354            {
5355              my_parse_error(ER(ER_PARTITION_ENTRY_ERROR));
5356              MYSQL_YYABORT;
5357            }
5358            /*
5359              We enter here when opening the frm file to translate
5360              partition info string into part_info data structure.
5361            */
5362          }
5363          partition {}
5364        ;
5365
5366partition:
5367          BY part_type_def opt_num_parts opt_sub_part part_defs
5368        ;
5369
5370part_type_def:
5371          opt_linear KEY_SYM opt_key_algo '(' part_field_list ')'
5372          {
5373            partition_info *part_info= Lex->part_info;
5374            part_info->list_of_part_fields= TRUE;
5375            part_info->column_list= FALSE;
5376            part_info->part_type= HASH_PARTITION;
5377          }
5378        | opt_linear HASH_SYM
5379          { Lex->part_info->part_type= HASH_PARTITION; }
5380          part_func {}
5381        | RANGE_SYM part_func
5382          { Lex->part_info->part_type= RANGE_PARTITION; }
5383        | RANGE_SYM part_column_list
5384          { Lex->part_info->part_type= RANGE_PARTITION; }
5385        | LIST_SYM part_func
5386          { Lex->part_info->part_type= LIST_PARTITION; }
5387        | LIST_SYM part_column_list
5388          { Lex->part_info->part_type= LIST_PARTITION; }
5389        ;
5390
5391opt_linear:
5392          /* empty */ {}
5393        | LINEAR_SYM
5394          { Lex->part_info->linear_hash_ind= TRUE;}
5395        ;
5396
5397opt_key_algo:
5398          /* empty */
5399          { Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_NONE;}
5400        | ALGORITHM_SYM EQ real_ulong_num
5401          {
5402            switch ($3) {
5403            case 1:
5404              Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_51;
5405              break;
5406            case 2:
5407              Lex->part_info->key_algorithm= partition_info::KEY_ALGORITHM_55;
5408              break;
5409            default:
5410              my_parse_error(ER(ER_SYNTAX_ERROR));
5411              MYSQL_YYABORT;
5412            }
5413          }
5414        ;
5415
5416part_field_list:
5417          /* empty */ {}
5418        | part_field_item_list {}
5419        ;
5420
5421part_field_item_list:
5422          part_field_item {}
5423        | part_field_item_list ',' part_field_item {}
5424        ;
5425
5426part_field_item:
5427          ident
5428          {
5429            partition_info *part_info= Lex->part_info;
5430            part_info->num_columns++;
5431            if (part_info->part_field_list.push_back($1.str))
5432            {
5433              mem_alloc_error(1);
5434              MYSQL_YYABORT;
5435            }
5436            if (part_info->num_columns > MAX_REF_PARTS)
5437            {
5438              my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
5439                       "list of partition fields");
5440              MYSQL_YYABORT;
5441            }
5442          }
5443        ;
5444
5445part_column_list:
5446          COLUMNS '(' part_field_list ')'
5447          {
5448            partition_info *part_info= Lex->part_info;
5449            part_info->column_list= TRUE;
5450            part_info->list_of_part_fields= TRUE;
5451          }
5452        ;
5453
5454
5455part_func:
5456          '(' remember_name part_func_expr remember_end ')'
5457          {
5458            partition_info *part_info= Lex->part_info;
5459            if (part_info->set_part_expr($2+1, $3, $4, FALSE))
5460            { MYSQL_YYABORT; }
5461            part_info->num_columns= 1;
5462            part_info->column_list= FALSE;
5463          }
5464        ;
5465
5466sub_part_func:
5467          '(' remember_name part_func_expr remember_end ')'
5468          {
5469            if (Lex->part_info->set_part_expr($2+1, $3, $4, TRUE))
5470            { MYSQL_YYABORT; }
5471          }
5472        ;
5473
5474
5475opt_num_parts:
5476          /* empty */ {}
5477        | PARTITIONS_SYM real_ulong_num
5478          {
5479            uint num_parts= $2;
5480            partition_info *part_info= Lex->part_info;
5481            if (num_parts == 0)
5482            {
5483              my_error(ER_NO_PARTS_ERROR, MYF(0), "partitions");
5484              MYSQL_YYABORT;
5485            }
5486
5487            part_info->num_parts= num_parts;
5488            part_info->use_default_num_partitions= FALSE;
5489          }
5490        ;
5491
5492opt_sub_part:
5493          /* empty */ {}
5494        | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func
5495          { Lex->part_info->subpart_type= HASH_PARTITION; }
5496          opt_num_subparts {}
5497        | SUBPARTITION_SYM BY opt_linear KEY_SYM opt_key_algo
5498          '(' sub_part_field_list ')'
5499          {
5500            partition_info *part_info= Lex->part_info;
5501            part_info->subpart_type= HASH_PARTITION;
5502            part_info->list_of_subpart_fields= TRUE;
5503          }
5504          opt_num_subparts {}
5505        ;
5506
5507sub_part_field_list:
5508          sub_part_field_item {}
5509        | sub_part_field_list ',' sub_part_field_item {}
5510        ;
5511
5512sub_part_field_item:
5513          ident
5514          {
5515            partition_info *part_info= Lex->part_info;
5516            if (part_info->subpart_field_list.push_back($1.str))
5517            {
5518              mem_alloc_error(1);
5519              MYSQL_YYABORT;
5520            }
5521            if (part_info->subpart_field_list.elements > MAX_REF_PARTS)
5522            {
5523              my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0),
5524                       "list of subpartition fields");
5525              MYSQL_YYABORT;
5526            }
5527          }
5528        ;
5529
5530part_func_expr:
5531          bit_expr
5532          {
5533            LEX *lex= Lex;
5534            bool not_corr_func;
5535            not_corr_func= !lex->safe_to_cache_query;
5536            lex->safe_to_cache_query= 1;
5537            if (not_corr_func)
5538            {
5539              my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
5540              MYSQL_YYABORT;
5541            }
5542            $$=$1;
5543          }
5544        ;
5545
5546opt_num_subparts:
5547          /* empty */ {}
5548        | SUBPARTITIONS_SYM real_ulong_num
5549          {
5550            uint num_parts= $2;
5551            LEX *lex= Lex;
5552            if (num_parts == 0)
5553            {
5554              my_error(ER_NO_PARTS_ERROR, MYF(0), "subpartitions");
5555              MYSQL_YYABORT;
5556            }
5557            lex->part_info->num_subparts= num_parts;
5558            lex->part_info->use_default_num_subpartitions= FALSE;
5559          }
5560        ;
5561
5562part_defs:
5563          /* empty */
5564          {
5565            partition_info *part_info= Lex->part_info;
5566            if (part_info->part_type == RANGE_PARTITION)
5567            {
5568              my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
5569                       "RANGE");
5570              MYSQL_YYABORT;
5571            }
5572            else if (part_info->part_type == LIST_PARTITION)
5573            {
5574              my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0),
5575                       "LIST");
5576              MYSQL_YYABORT;
5577            }
5578          }
5579        | '(' part_def_list ')'
5580          {
5581            partition_info *part_info= Lex->part_info;
5582            uint count_curr_parts= part_info->partitions.elements;
5583            if (part_info->num_parts != 0)
5584            {
5585              if (part_info->num_parts !=
5586                  count_curr_parts)
5587              {
5588                my_parse_error(ER(ER_PARTITION_WRONG_NO_PART_ERROR));
5589                MYSQL_YYABORT;
5590              }
5591            }
5592            else if (count_curr_parts > 0)
5593            {
5594              part_info->num_parts= count_curr_parts;
5595            }
5596            part_info->count_curr_subparts= 0;
5597          }
5598        ;
5599
5600part_def_list:
5601          part_definition {}
5602        | part_def_list ',' part_definition {}
5603        ;
5604
5605part_definition:
5606          PARTITION_SYM
5607          {
5608            partition_info *part_info= Lex->part_info;
5609            partition_element *p_elem= new partition_element();
5610
5611            if (!p_elem || part_info->partitions.push_back(p_elem))
5612            {
5613              mem_alloc_error(sizeof(partition_element));
5614              MYSQL_YYABORT;
5615            }
5616            p_elem->part_state= PART_NORMAL;
5617            part_info->curr_part_elem= p_elem;
5618            part_info->current_partition= p_elem;
5619            part_info->use_default_partitions= FALSE;
5620            part_info->use_default_num_partitions= FALSE;
5621          }
5622          part_name
5623          opt_part_values
5624          opt_part_options
5625          opt_sub_partition
5626          {}
5627        ;
5628
5629part_name:
5630          ident
5631          {
5632            partition_info *part_info= Lex->part_info;
5633            partition_element *p_elem= part_info->curr_part_elem;
5634            if (check_string_char_length(&$1, "", NAME_CHAR_LEN,
5635                                         system_charset_info, true))
5636            {
5637              my_error(ER_TOO_LONG_IDENT, MYF(0), $1.str);
5638              MYSQL_YYABORT;
5639            }
5640            p_elem->partition_name= $1.str;
5641          }
5642        ;
5643
5644opt_part_values:
5645          /* empty */
5646          {
5647            LEX *lex= Lex;
5648            partition_info *part_info= lex->part_info;
5649            if (part_info->part_type == NOT_A_PARTITION)
5650              part_info->part_type= HASH_PARTITION;
5651            else if (part_info->part_type == RANGE_PARTITION)
5652            {
5653              my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
5654                       "RANGE", "LESS THAN");
5655              MYSQL_YYABORT;
5656            }
5657            else if (part_info->part_type == LIST_PARTITION)
5658            {
5659              my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
5660                       "LIST", "IN");
5661              MYSQL_YYABORT;
5662            }
5663          }
5664        | VALUES LESS_SYM THAN_SYM
5665          {
5666            LEX *lex= Lex;
5667            partition_info *part_info= lex->part_info;
5668            if (part_info->part_type == NOT_A_PARTITION)
5669              part_info->part_type= RANGE_PARTITION;
5670            else if (part_info->part_type != RANGE_PARTITION)
5671            {
5672              my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
5673                       "RANGE", "LESS THAN");
5674              MYSQL_YYABORT;
5675            }
5676          }
5677          part_func_max {}
5678        | VALUES IN_SYM
5679          {
5680            LEX *lex= Lex;
5681            partition_info *part_info= lex->part_info;
5682            if (part_info->part_type == NOT_A_PARTITION)
5683              part_info->part_type= LIST_PARTITION;
5684            else if (part_info->part_type != LIST_PARTITION)
5685            {
5686              my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
5687                       "LIST", "IN");
5688              MYSQL_YYABORT;
5689            }
5690          }
5691          part_values_in {}
5692        ;
5693
5694part_func_max:
5695          MAX_VALUE_SYM
5696          {
5697            partition_info *part_info= Lex->part_info;
5698
5699            if (part_info->num_columns &&
5700                part_info->num_columns != 1U)
5701            {
5702              part_info->print_debug("Kilroy II", NULL);
5703              my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5704              MYSQL_YYABORT;
5705            }
5706            else
5707              part_info->num_columns= 1U;
5708            if (part_info->init_column_part())
5709            {
5710              MYSQL_YYABORT;
5711            }
5712            if (part_info->add_max_value())
5713            {
5714              MYSQL_YYABORT;
5715            }
5716          }
5717        | part_value_item {}
5718        ;
5719
5720part_values_in:
5721          part_value_item
5722          {
5723            LEX *lex= Lex;
5724            partition_info *part_info= lex->part_info;
5725            part_info->print_debug("part_values_in: part_value_item", NULL);
5726
5727            if (part_info->num_columns != 1U)
5728            {
5729              if (!lex->is_partition_management() ||
5730                  part_info->num_columns == 0 ||
5731                  part_info->num_columns > MAX_REF_PARTS)
5732              {
5733                part_info->print_debug("Kilroy III", NULL);
5734                my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5735                MYSQL_YYABORT;
5736              }
5737              /*
5738                Reorganize the current large array into a list of small
5739                arrays with one entry in each array. This can happen
5740                in the first partition of an ALTER TABLE statement where
5741                we ADD or REORGANIZE partitions. Also can only happen
5742                for LIST [COLUMNS] partitions.
5743              */
5744              if (part_info->reorganize_into_single_field_col_val())
5745              {
5746                MYSQL_YYABORT;
5747              }
5748            }
5749          }
5750        | '(' part_value_list ')'
5751          {
5752            partition_info *part_info= Lex->part_info;
5753            if (part_info->num_columns < 2U)
5754            {
5755              my_parse_error(ER(ER_ROW_SINGLE_PARTITION_FIELD_ERROR));
5756              MYSQL_YYABORT;
5757            }
5758          }
5759        ;
5760
5761part_value_list:
5762          part_value_item {}
5763        | part_value_list ',' part_value_item {}
5764        ;
5765
5766part_value_item:
5767          '('
5768          {
5769            partition_info *part_info= Lex->part_info;
5770            part_info->print_debug("( part_value_item", NULL);
5771            /* Initialisation code needed for each list of value expressions */
5772            if (!(part_info->part_type == LIST_PARTITION &&
5773                  part_info->num_columns == 1U) &&
5774                 part_info->init_column_part())
5775            {
5776              MYSQL_YYABORT;
5777            }
5778          }
5779          part_value_item_list {}
5780          ')'
5781          {
5782            partition_info *part_info= Lex->part_info;
5783            part_info->print_debug(") part_value_item", NULL);
5784            if (part_info->num_columns == 0)
5785              part_info->num_columns= part_info->curr_list_object;
5786            if (part_info->num_columns != part_info->curr_list_object)
5787            {
5788              /*
5789                All value items lists must be of equal length, in some cases
5790                which is covered by the above if-statement we don't know yet
5791                how many columns is in the partition so the assignment above
5792                ensures that we only report errors when we know we have an
5793                error.
5794              */
5795              part_info->print_debug("Kilroy I", NULL);
5796              my_parse_error(ER(ER_PARTITION_COLUMN_LIST_ERROR));
5797              MYSQL_YYABORT;
5798            }
5799            part_info->curr_list_object= 0;
5800          }
5801        ;
5802
5803part_value_item_list:
5804          part_value_expr_item {}
5805        | part_value_item_list ',' part_value_expr_item {}
5806        ;
5807
5808part_value_expr_item:
5809          MAX_VALUE_SYM
5810          {
5811            partition_info *part_info= Lex->part_info;
5812            if (part_info->part_type == LIST_PARTITION)
5813            {
5814              my_parse_error(ER(ER_MAXVALUE_IN_VALUES_IN));
5815              MYSQL_YYABORT;
5816            }
5817            if (part_info->add_max_value())
5818            {
5819              MYSQL_YYABORT;
5820            }
5821          }
5822        | bit_expr
5823          {
5824            LEX *lex= Lex;
5825            partition_info *part_info= lex->part_info;
5826            Item *part_expr= $1;
5827
5828            if (!lex->safe_to_cache_query)
5829            {
5830              my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
5831              MYSQL_YYABORT;
5832            }
5833            if (part_info->add_column_list_value(YYTHD, part_expr))
5834            {
5835              MYSQL_YYABORT;
5836            }
5837          }
5838        ;
5839
5840
5841opt_sub_partition:
5842          /* empty */
5843          {
5844            partition_info *part_info= Lex->part_info;
5845            if (part_info->num_subparts != 0 &&
5846                !part_info->use_default_subpartitions)
5847            {
5848              /*
5849                We come here when we have defined subpartitions on the first
5850                partition but not on all the subsequent partitions.
5851              */
5852              my_parse_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5853              MYSQL_YYABORT;
5854            }
5855          }
5856        | '(' sub_part_list ')'
5857          {
5858            partition_info *part_info= Lex->part_info;
5859            if (part_info->num_subparts != 0)
5860            {
5861              if (part_info->num_subparts !=
5862                  part_info->count_curr_subparts)
5863              {
5864                my_parse_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5865                MYSQL_YYABORT;
5866              }
5867            }
5868            else if (part_info->count_curr_subparts > 0)
5869            {
5870              if (part_info->partitions.elements > 1)
5871              {
5872                my_parse_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5873                MYSQL_YYABORT;
5874              }
5875              part_info->num_subparts= part_info->count_curr_subparts;
5876            }
5877            part_info->count_curr_subparts= 0;
5878          }
5879        ;
5880
5881sub_part_list:
5882          sub_part_definition {}
5883        | sub_part_list ',' sub_part_definition {}
5884        ;
5885
5886sub_part_definition:
5887          SUBPARTITION_SYM
5888          {
5889            partition_info *part_info= Lex->part_info;
5890            partition_element *curr_part= part_info->current_partition;
5891            partition_element *sub_p_elem= new partition_element(curr_part);
5892            if (part_info->use_default_subpartitions &&
5893                part_info->partitions.elements >= 2)
5894            {
5895              /*
5896                create table t1 (a int)
5897                partition by list (a) subpartition by hash (a)
5898                (partition p0 values in (1),
5899                 partition p1 values in (2) subpartition sp11);
5900                causes use to arrive since we are on the second
5901                partition, but still use_default_subpartitions
5902                is set. When we come here we're processing at least
5903                the second partition (the current partition processed
5904                have already been put into the partitions list.
5905              */
5906              my_parse_error(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
5907              MYSQL_YYABORT;
5908            }
5909            if (!sub_p_elem ||
5910             curr_part->subpartitions.push_back(sub_p_elem))
5911            {
5912              mem_alloc_error(sizeof(partition_element));
5913              MYSQL_YYABORT;
5914            }
5915            part_info->curr_part_elem= sub_p_elem;
5916            part_info->use_default_subpartitions= FALSE;
5917            part_info->use_default_num_subpartitions= FALSE;
5918            part_info->count_curr_subparts++;
5919          }
5920          sub_name opt_part_options {}
5921        ;
5922
5923sub_name:
5924          ident_or_text
5925          {
5926            if (check_string_char_length(&$1, "", NAME_CHAR_LEN,
5927                                         system_charset_info, true))
5928            {
5929              my_error(ER_TOO_LONG_IDENT, MYF(0), $1.str);
5930              MYSQL_YYABORT;
5931            }
5932            Lex->part_info->curr_part_elem->partition_name= $1.str;
5933          }
5934        ;
5935
5936opt_part_options:
5937         /* empty */ {}
5938       | opt_part_option_list {}
5939       ;
5940
5941opt_part_option_list:
5942         opt_part_option_list opt_part_option {}
5943       | opt_part_option {}
5944       ;
5945
5946opt_part_option:
5947          TABLESPACE opt_equal ident_or_text
5948          { Lex->part_info->curr_part_elem->tablespace_name= $3.str; }
5949        | opt_storage ENGINE_SYM opt_equal storage_engines
5950          {
5951            partition_info *part_info= Lex->part_info;
5952            part_info->curr_part_elem->engine_type= $4;
5953            part_info->default_engine_type= $4;
5954          }
5955        | NODEGROUP_SYM opt_equal real_ulong_num
5956          { Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; }
5957        | MAX_ROWS opt_equal real_ulonglong_num
5958          { Lex->part_info->curr_part_elem->part_max_rows= (ha_rows) $3; }
5959        | MIN_ROWS opt_equal real_ulonglong_num
5960          { Lex->part_info->curr_part_elem->part_min_rows= (ha_rows) $3; }
5961        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
5962          { Lex->part_info->curr_part_elem->data_file_name= $4.str; }
5963        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
5964          { Lex->part_info->curr_part_elem->index_file_name= $4.str; }
5965        | COMMENT_SYM opt_equal TEXT_STRING_sys
5966          { Lex->part_info->curr_part_elem->part_comment= $3.str; }
5967        ;
5968
5969/*
5970 End of partition parser part
5971*/
5972
5973create_select:
5974          SELECT_SYM
5975          {
5976            LEX *lex=Lex;
5977            if (lex->sql_command == SQLCOM_INSERT)
5978              lex->sql_command= SQLCOM_INSERT_SELECT;
5979            else if (lex->sql_command == SQLCOM_REPLACE)
5980              lex->sql_command= SQLCOM_REPLACE_SELECT;
5981            /*
5982              The following work only with the local list, the global list
5983              is created correctly in this case
5984            */
5985            lex->current_select->table_list.save_and_clear(&lex->save_list);
5986            mysql_init_select(lex);
5987            lex->current_select->parsing_place= SELECT_LIST;
5988          }
5989          select_options select_item_list
5990          {
5991            Select->parsing_place= NO_MATTER;
5992          }
5993          opt_select_from
5994          {
5995            /*
5996              The following work only with the local list, the global list
5997              is created correctly in this case
5998            */
5999            Lex->current_select->table_list.push_front(&Lex->save_list);
6000          }
6001        ;
6002
6003opt_as:
6004          /* empty */ {}
6005        | AS {}
6006        ;
6007
6008opt_create_database_options:
6009          /* empty */ {}
6010        | create_database_options {}
6011        ;
6012
6013create_database_options:
6014          create_database_option {}
6015        | create_database_options create_database_option {}
6016        ;
6017
6018create_database_option:
6019          default_collation {}
6020        | default_charset {}
6021        ;
6022
6023opt_table_options:
6024          /* empty */ { $$= 0; }
6025        | table_options  { $$= $1;}
6026        ;
6027
6028table_options:
6029          table_option { $$=$1; }
6030        | table_option table_options { $$= $1 | $2; }
6031        ;
6032
6033table_option:
6034          TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }
6035        ;
6036
6037opt_if_not_exists:
6038          /* empty */ { $$= 0; }
6039        | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }
6040        ;
6041
6042opt_create_table_options:
6043          /* empty */
6044        | create_table_options
6045        ;
6046
6047create_table_options_space_separated:
6048          create_table_option
6049        | create_table_option create_table_options_space_separated
6050        ;
6051
6052create_table_options:
6053          create_table_option
6054        | create_table_option     create_table_options
6055        | create_table_option ',' create_table_options
6056        ;
6057
6058create_table_option:
6059          ENGINE_SYM opt_equal storage_engines
6060          {
6061            Lex->create_info.db_type= $3;
6062            Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
6063          }
6064        | MAX_ROWS opt_equal ulonglong_num
6065          {
6066            Lex->create_info.max_rows= $3;
6067            Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;
6068          }
6069        | MIN_ROWS opt_equal ulonglong_num
6070          {
6071            Lex->create_info.min_rows= $3;
6072            Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;
6073          }
6074        | AVG_ROW_LENGTH opt_equal ulong_num
6075          {
6076            Lex->create_info.avg_row_length=$3;
6077            Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;
6078          }
6079        | PASSWORD opt_equal TEXT_STRING_sys
6080          {
6081            Lex->create_info.password=$3.str;
6082            Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD;
6083          }
6084        | COMMENT_SYM opt_equal TEXT_STRING_sys
6085          {
6086            Lex->create_info.comment=$3;
6087            Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT;
6088          }
6089        | AUTO_INC opt_equal ulonglong_num
6090          {
6091            Lex->create_info.auto_increment_value=$3;
6092            Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;
6093          }
6094        | PACK_KEYS_SYM opt_equal ulong_num
6095          {
6096            switch($3) {
6097            case 0:
6098                Lex->create_info.table_options|= HA_OPTION_NO_PACK_KEYS;
6099                break;
6100            case 1:
6101                Lex->create_info.table_options|= HA_OPTION_PACK_KEYS;
6102                break;
6103            default:
6104                my_parse_error(ER(ER_SYNTAX_ERROR));
6105                MYSQL_YYABORT;
6106            }
6107            Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
6108          }
6109        | PACK_KEYS_SYM opt_equal DEFAULT
6110          {
6111            Lex->create_info.table_options&=
6112              ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
6113            Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
6114          }
6115        | STATS_AUTO_RECALC_SYM opt_equal ulong_num
6116          {
6117            switch($3) {
6118            case 0:
6119                Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_OFF;
6120                break;
6121            case 1:
6122                Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_ON;
6123                break;
6124            default:
6125                my_parse_error(ER(ER_SYNTAX_ERROR));
6126                MYSQL_YYABORT;
6127            }
6128            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
6129          }
6130        | STATS_AUTO_RECALC_SYM opt_equal DEFAULT
6131          {
6132            Lex->create_info.stats_auto_recalc= HA_STATS_AUTO_RECALC_DEFAULT;
6133            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_AUTO_RECALC;
6134          }
6135        | STATS_PERSISTENT_SYM opt_equal ulong_num
6136          {
6137            switch($3) {
6138            case 0:
6139                Lex->create_info.table_options|= HA_OPTION_NO_STATS_PERSISTENT;
6140                break;
6141            case 1:
6142                Lex->create_info.table_options|= HA_OPTION_STATS_PERSISTENT;
6143                break;
6144            default:
6145                my_parse_error(ER(ER_SYNTAX_ERROR));
6146                MYSQL_YYABORT;
6147            }
6148            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
6149          }
6150        | STATS_PERSISTENT_SYM opt_equal DEFAULT
6151          {
6152            Lex->create_info.table_options&=
6153              ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
6154            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_PERSISTENT;
6155          }
6156        | STATS_SAMPLE_PAGES_SYM opt_equal ulong_num
6157          {
6158            /* From user point of view STATS_SAMPLE_PAGES can be specified as
6159            STATS_SAMPLE_PAGES=N (where 0<N<=65535, it does not make sense to
6160            scan 0 pages) or STATS_SAMPLE_PAGES=default. Internally we record
6161            =default as 0. See create_frm() in sql/table.cc, we use only two
6162            bytes for stats_sample_pages and this is why we do not allow
6163            larger values. 65535 pages, 16kb each means to sample 1GB, which
6164            is impractical. If at some point this needs to be extended, then
6165            we can store the higher bits from stats_sample_pages in .frm too. */
6166            if ($3 == 0 || $3 > 0xffff)
6167            {
6168              my_parse_error(ER(ER_SYNTAX_ERROR));
6169              MYSQL_YYABORT;
6170            }
6171            Lex->create_info.stats_sample_pages=$3;
6172            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
6173          }
6174        | STATS_SAMPLE_PAGES_SYM opt_equal DEFAULT
6175          {
6176            Lex->create_info.stats_sample_pages=0;
6177            Lex->create_info.used_fields|= HA_CREATE_USED_STATS_SAMPLE_PAGES;
6178          }
6179        | CHECKSUM_SYM opt_equal ulong_num
6180          {
6181            Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
6182            Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
6183          }
6184        | TABLE_CHECKSUM_SYM opt_equal ulong_num
6185          {
6186             Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM;
6187             Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM;
6188          }
6189        | DELAY_KEY_WRITE_SYM opt_equal ulong_num
6190          {
6191            Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE;
6192            Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE;
6193          }
6194        | ROW_FORMAT_SYM opt_equal row_types
6195          {
6196            Lex->create_info.row_type= $3;
6197            Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT;
6198          }
6199        | UNION_SYM opt_equal
6200          {
6201            Lex->select_lex.table_list.save_and_clear(&Lex->save_list);
6202          }
6203          '(' opt_table_list ')'
6204          {
6205            /*
6206              Move the union list to the merge_list and exclude its tables
6207              from the global list.
6208            */
6209            LEX *lex=Lex;
6210            lex->create_info.merge_list= lex->select_lex.table_list;
6211            lex->select_lex.table_list= lex->save_list;
6212            /*
6213              When excluding union list from the global list we assume that
6214              elements of the former immediately follow elements which represent
6215              table being created/altered and parent tables.
6216            */
6217            TABLE_LIST *last_non_sel_table= lex->create_last_non_select_table;
6218            DBUG_ASSERT(last_non_sel_table->next_global ==
6219                        lex->create_info.merge_list.first);
6220            last_non_sel_table->next_global= 0;
6221            Lex->query_tables_last= &last_non_sel_table->next_global;
6222
6223            lex->create_info.used_fields|= HA_CREATE_USED_UNION;
6224          }
6225        | default_charset
6226        | default_collation
6227        | INSERT_METHOD opt_equal merge_insert_types
6228          {
6229            Lex->create_info.merge_insert_method= $3;
6230            Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;
6231          }
6232        | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
6233          {
6234            Lex->create_info.data_file_name= $4.str;
6235            Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR;
6236          }
6237        | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
6238          {
6239            Lex->create_info.index_file_name= $4.str;
6240            Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR;
6241          }
6242        | TABLESPACE ident
6243          {Lex->create_info.tablespace= $2.str;}
6244        | STORAGE_SYM DISK_SYM
6245          {Lex->create_info.storage_media= HA_SM_DISK;}
6246        | STORAGE_SYM MEMORY_SYM
6247          {Lex->create_info.storage_media= HA_SM_MEMORY;}
6248        | CONNECTION_SYM opt_equal TEXT_STRING_sys
6249          {
6250            Lex->create_info.connect_string.str= $3.str;
6251            Lex->create_info.connect_string.length= $3.length;
6252            Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION;
6253          }
6254        | KEY_BLOCK_SIZE opt_equal ulong_num
6255          {
6256            Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
6257            Lex->create_info.key_block_size= $3;
6258          }
6259        ;
6260
6261default_charset:
6262          opt_default charset opt_equal charset_name_or_default
6263          {
6264            HA_CREATE_INFO *cinfo= &Lex->create_info;
6265            if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
6266                 cinfo->default_table_charset && $4 &&
6267                 !my_charset_same(cinfo->default_table_charset,$4))
6268            {
6269              my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
6270                       "CHARACTER SET ", cinfo->default_table_charset->csname,
6271                       "CHARACTER SET ", $4->csname);
6272              MYSQL_YYABORT;
6273            }
6274            Lex->create_info.default_table_charset= $4;
6275            Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
6276          }
6277        ;
6278
6279default_collation:
6280          opt_default COLLATE_SYM opt_equal collation_name_or_default
6281          {
6282            HA_CREATE_INFO *cinfo= &Lex->create_info;
6283            if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
6284                 cinfo->default_table_charset && $4 &&
6285                 !($4= merge_charset_and_collation(cinfo->default_table_charset,
6286                                                   $4)))
6287            {
6288              MYSQL_YYABORT;
6289            }
6290
6291            Lex->create_info.default_table_charset= $4;
6292            Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
6293          }
6294        ;
6295
6296storage_engines:
6297          ident_or_text
6298          {
6299            THD *thd= YYTHD;
6300            plugin_ref plugin=
6301              ha_resolve_by_name(thd, &$1,
6302                thd->lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
6303
6304            if (plugin)
6305              $$= plugin_data(plugin, handlerton*);
6306            else
6307            {
6308              if (thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
6309              {
6310                my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
6311                MYSQL_YYABORT;
6312              }
6313              $$= 0;
6314              push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
6315                                  ER_UNKNOWN_STORAGE_ENGINE,
6316                                  ER(ER_UNKNOWN_STORAGE_ENGINE),
6317                                  $1.str);
6318            }
6319          }
6320        ;
6321
6322known_storage_engines:
6323          ident_or_text
6324          {
6325            THD *thd= YYTHD;
6326            LEX *lex= thd->lex;
6327            plugin_ref plugin=
6328              ha_resolve_by_name(thd, &$1,
6329                lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
6330            if (plugin)
6331              $$= plugin_data(plugin, handlerton*);
6332            else
6333            {
6334              my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
6335              MYSQL_YYABORT;
6336            }
6337          }
6338        ;
6339
6340row_types:
6341          DEFAULT        { $$= ROW_TYPE_DEFAULT; }
6342        | FIXED_SYM      { $$= ROW_TYPE_FIXED; }
6343        | DYNAMIC_SYM    { $$= ROW_TYPE_DYNAMIC; }
6344        | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
6345        | REDUNDANT_SYM  { $$= ROW_TYPE_REDUNDANT; }
6346        | COMPACT_SYM    { $$= ROW_TYPE_COMPACT; }
6347        | TOKU_UNCOMPRESSED_SYM { $$= ROW_TYPE_TOKU_UNCOMPRESSED; }
6348        | TOKU_ZLIB_SYM         { $$= ROW_TYPE_TOKU_ZLIB; }
6349        | TOKU_SNAPPY_SYM       { $$= ROW_TYPE_TOKU_SNAPPY; }
6350        | TOKU_QUICKLZ_SYM      { $$= ROW_TYPE_TOKU_QUICKLZ; }
6351        | TOKU_LZMA_SYM         { $$= ROW_TYPE_TOKU_LZMA; }
6352        | TOKU_FAST_SYM         { $$= ROW_TYPE_TOKU_FAST; }
6353        | TOKU_SMALL_SYM        { $$= ROW_TYPE_TOKU_SMALL; }
6354        | TOKU_DEFAULT_SYM      { $$= ROW_TYPE_TOKU_DEFAULT; }
6355        ;
6356
6357merge_insert_types:
6358         NO_SYM          { $$= MERGE_INSERT_DISABLED; }
6359       | FIRST_SYM       { $$= MERGE_INSERT_TO_FIRST; }
6360       | LAST_SYM        { $$= MERGE_INSERT_TO_LAST; }
6361       ;
6362
6363opt_select_from:
6364          opt_limit_clause {}
6365        | select_from select_lock_type
6366        ;
6367
6368udf_type:
6369          STRING_SYM {$$ = (int) STRING_RESULT; }
6370        | REAL {$$ = (int) REAL_RESULT; }
6371        | DECIMAL_SYM {$$ = (int) DECIMAL_RESULT; }
6372        | INT_SYM {$$ = (int) INT_RESULT; }
6373        ;
6374
6375
6376create_field_list:
6377        field_list
6378        {
6379          Lex->create_last_non_select_table= Lex->last_table();
6380        }
6381        ;
6382
6383field_list:
6384          field_list_item
6385        | field_list ',' field_list_item
6386        ;
6387
6388field_list_item:
6389          column_def
6390        | key_def
6391        ;
6392
6393column_def:
6394          field_spec opt_check_constraint
6395        | field_spec references
6396          {
6397            Lex->col_list.empty(); /* Alloced by sql_alloc */
6398          }
6399        ;
6400
6401key_def:
6402          normal_key_type opt_ident key_alg '(' key_list ')' normal_key_options
6403          {
6404            if (add_create_index (Lex, $1, $2))
6405              MYSQL_YYABORT;
6406          }
6407        | fulltext opt_key_or_index opt_ident init_key_options
6408            '(' key_list ')' fulltext_key_options
6409          {
6410            if (add_create_index (Lex, $1, $3))
6411              MYSQL_YYABORT;
6412          }
6413        | spatial opt_key_or_index opt_ident init_key_options
6414            '(' key_list ')' spatial_key_options
6415          {
6416            if (add_create_index (Lex, $1, $3))
6417              MYSQL_YYABORT;
6418          }
6419        | opt_constraint constraint_key_type opt_ident key_alg
6420          '(' key_list ')' normal_key_options
6421          {
6422            if (($1.length != 0)
6423                 && ((enum Key::Keytype)$2 == (Key::CLUSTERING | Key::MULTIPLE)))
6424            {
6425              /* Forbid "CONSTRAINT c CLUSTERING" */
6426              my_parse_error(ER(ER_SYNTAX_ERROR));
6427              MYSQL_YYABORT;
6428            }
6429            if (add_create_index (Lex, $2, $3.str ? $3 : $1))
6430              MYSQL_YYABORT;
6431          }
6432        | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
6433          {
6434            LEX *lex=Lex;
6435            Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list,
6436                                      $8->db,
6437                                      $8->table,
6438                                      lex->ref_list,
6439                                      lex->fk_delete_opt,
6440                                      lex->fk_update_opt,
6441                                      lex->fk_match_option);
6442            if (key == NULL)
6443              MYSQL_YYABORT;
6444            lex->alter_info.key_list.push_back(key);
6445            if (add_create_index (lex, Key::MULTIPLE, $1.str ? $1 : $4,
6446                                  &default_key_create_info, 1))
6447              MYSQL_YYABORT;
6448            /* Only used for ALTER TABLE. Ignored otherwise. */
6449            lex->alter_info.flags|= Alter_info::ADD_FOREIGN_KEY;
6450          }
6451        | opt_constraint check_constraint
6452          {
6453            Lex->col_list.empty(); /* Alloced by sql_alloc */
6454          }
6455        ;
6456
6457opt_check_constraint:
6458          /* empty */
6459        | check_constraint
6460        ;
6461
6462check_constraint:
6463          CHECK_SYM '(' expr ')'
6464        ;
6465
6466opt_constraint:
6467          /* empty */ { $$= null_lex_str; }
6468        | constraint { $$= $1; }
6469        ;
6470
6471constraint:
6472          CONSTRAINT opt_ident { $$=$2; }
6473        ;
6474
6475field_spec:
6476          field_ident
6477          {
6478            LEX *lex=Lex;
6479            lex->length=lex->dec=0;
6480            lex->type=0;
6481            lex->default_value= lex->on_update_value= 0;
6482            lex->comment=null_lex_str;
6483            lex->charset=NULL;
6484            lex->zip_dict_name=null_lex_cstr;
6485          }
6486          type opt_attribute
6487          {
6488            LEX *lex=Lex;
6489            if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3,
6490                                  lex->length,lex->dec,lex->type,
6491                                  lex->default_value, lex->on_update_value,
6492                                  &lex->comment,
6493                                  lex->change,&lex->interval_list,lex->charset,
6494                                  lex->uint_geom_type, &lex->zip_dict_name))
6495              MYSQL_YYABORT;
6496          }
6497        ;
6498
6499type:
6500          int_type opt_field_length field_options { $$=$1; }
6501        | real_type opt_precision field_options { $$=$1; }
6502        | FLOAT_SYM float_options field_options { $$=MYSQL_TYPE_FLOAT; }
6503        | BIT_SYM
6504          {
6505            Lex->length= (char*) "1";
6506            $$=MYSQL_TYPE_BIT;
6507          }
6508        | BIT_SYM field_length
6509          {
6510            $$=MYSQL_TYPE_BIT;
6511          }
6512        | BOOL_SYM
6513          {
6514            Lex->length= (char*) "1";
6515            $$=MYSQL_TYPE_TINY;
6516          }
6517        | BOOLEAN_SYM
6518          {
6519            Lex->length= (char*) "1";
6520            $$=MYSQL_TYPE_TINY;
6521          }
6522        | char field_length opt_binary
6523          {
6524            $$=MYSQL_TYPE_STRING;
6525          }
6526        | char opt_binary
6527          {
6528            Lex->length= (char*) "1";
6529            $$=MYSQL_TYPE_STRING;
6530          }
6531        | nchar field_length opt_bin_mod
6532          {
6533            $$=MYSQL_TYPE_STRING;
6534            Lex->charset=national_charset_info;
6535          }
6536        | nchar opt_bin_mod
6537          {
6538            Lex->length= (char*) "1";
6539            $$=MYSQL_TYPE_STRING;
6540            Lex->charset=national_charset_info;
6541          }
6542        | BINARY field_length
6543          {
6544            Lex->charset=&my_charset_bin;
6545            $$=MYSQL_TYPE_STRING;
6546          }
6547        | BINARY
6548          {
6549            Lex->length= (char*) "1";
6550            Lex->charset=&my_charset_bin;
6551            $$=MYSQL_TYPE_STRING;
6552          }
6553        | varchar field_length opt_binary
6554          {
6555            $$= MYSQL_TYPE_VARCHAR;
6556          }
6557        | nvarchar field_length opt_bin_mod
6558          {
6559            $$= MYSQL_TYPE_VARCHAR;
6560            Lex->charset=national_charset_info;
6561          }
6562        | VARBINARY field_length
6563          {
6564            Lex->charset=&my_charset_bin;
6565            $$= MYSQL_TYPE_VARCHAR;
6566          }
6567        | YEAR_SYM opt_field_length field_options
6568          {
6569            if (Lex->length)
6570            {
6571              errno= 0;
6572              ulong length= strtoul(Lex->length, NULL, 10);
6573              if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4)
6574              {
6575                /* Reset unsupported positive column width to default value */
6576                Lex->length= NULL;
6577                push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
6578                                    ER_INVALID_YEAR_COLUMN_LENGTH,
6579                                    ER(ER_INVALID_YEAR_COLUMN_LENGTH),
6580                                    length);
6581              }
6582            }
6583            $$=MYSQL_TYPE_YEAR;
6584          }
6585        | DATE_SYM
6586          { $$=MYSQL_TYPE_DATE; }
6587        | TIME_SYM type_datetime_precision
6588          { $$= MYSQL_TYPE_TIME2; }
6589        | TIMESTAMP type_datetime_precision
6590          {
6591            if (YYTHD->variables.sql_mode & MODE_MAXDB)
6592              $$=MYSQL_TYPE_DATETIME2;
6593            else
6594            {
6595              /*
6596                Unlike other types TIMESTAMP fields are NOT NULL by default.
6597                This behavior is deprecated now.
6598              */
6599              if (!YYTHD->variables.explicit_defaults_for_timestamp)
6600                Lex->type|= NOT_NULL_FLAG;
6601
6602              $$=MYSQL_TYPE_TIMESTAMP2;
6603            }
6604          }
6605        | DATETIME type_datetime_precision
6606          { $$= MYSQL_TYPE_DATETIME2; }
6607        | TINYBLOB
6608          {
6609            Lex->charset=&my_charset_bin;
6610            $$=MYSQL_TYPE_TINY_BLOB;
6611          }
6612        | BLOB_SYM opt_field_length
6613          {
6614            Lex->charset=&my_charset_bin;
6615            $$=MYSQL_TYPE_BLOB;
6616          }
6617        | spatial_type
6618          {
6619#ifdef HAVE_SPATIAL
6620            Lex->charset=&my_charset_bin;
6621            Lex->uint_geom_type= (uint)$1;
6622            $$=MYSQL_TYPE_GEOMETRY;
6623#else
6624            my_error(ER_FEATURE_DISABLED, MYF(0),
6625                     sym_group_geom.name, sym_group_geom.needed_define);
6626            MYSQL_YYABORT;
6627#endif
6628          }
6629        | MEDIUMBLOB
6630          {
6631            Lex->charset=&my_charset_bin;
6632            $$=MYSQL_TYPE_MEDIUM_BLOB;
6633          }
6634        | LONGBLOB
6635          {
6636            Lex->charset=&my_charset_bin;
6637            $$=MYSQL_TYPE_LONG_BLOB;
6638          }
6639        | LONG_SYM VARBINARY
6640          {
6641            Lex->charset=&my_charset_bin;
6642            $$=MYSQL_TYPE_MEDIUM_BLOB;
6643          }
6644        | LONG_SYM varchar opt_binary
6645          { $$=MYSQL_TYPE_MEDIUM_BLOB; }
6646        | TINYTEXT opt_binary
6647          { $$=MYSQL_TYPE_TINY_BLOB; }
6648        | TEXT_SYM opt_field_length opt_binary
6649          { $$=MYSQL_TYPE_BLOB; }
6650        | MEDIUMTEXT opt_binary
6651          { $$=MYSQL_TYPE_MEDIUM_BLOB; }
6652        | LONGTEXT opt_binary
6653          { $$=MYSQL_TYPE_LONG_BLOB; }
6654        | DECIMAL_SYM float_options field_options
6655          { $$=MYSQL_TYPE_NEWDECIMAL;}
6656        | NUMERIC_SYM float_options field_options
6657          { $$=MYSQL_TYPE_NEWDECIMAL;}
6658        | FIXED_SYM float_options field_options
6659          { $$=MYSQL_TYPE_NEWDECIMAL;}
6660        | ENUM
6661          {Lex->interval_list.empty();}
6662          '(' string_list ')' opt_binary
6663          { $$=MYSQL_TYPE_ENUM; }
6664        | SET
6665          { Lex->interval_list.empty();}
6666          '(' string_list ')' opt_binary
6667          { $$=MYSQL_TYPE_SET; }
6668        | LONG_SYM opt_binary
6669          { $$=MYSQL_TYPE_MEDIUM_BLOB; }
6670        | SERIAL_SYM
6671          {
6672            $$=MYSQL_TYPE_LONGLONG;
6673            Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
6674              UNIQUE_FLAG);
6675          }
6676        ;
6677
6678spatial_type:
6679          GEOMETRY_SYM        { $$= Field::GEOM_GEOMETRY; }
6680        | GEOMETRYCOLLECTION  { $$= Field::GEOM_GEOMETRYCOLLECTION; }
6681        | POINT_SYM
6682          {
6683            Lex->length= const_cast<char*>(STRINGIFY_ARG
6684                                           (MAX_LEN_GEOM_POINT_FIELD));
6685            $$= Field::GEOM_POINT;
6686          }
6687        | MULTIPOINT          { $$= Field::GEOM_MULTIPOINT; }
6688        | LINESTRING          { $$= Field::GEOM_LINESTRING; }
6689        | MULTILINESTRING     { $$= Field::GEOM_MULTILINESTRING; }
6690        | POLYGON             { $$= Field::GEOM_POLYGON; }
6691        | MULTIPOLYGON        { $$= Field::GEOM_MULTIPOLYGON; }
6692        ;
6693
6694char:
6695          CHAR_SYM {}
6696        ;
6697
6698nchar:
6699          NCHAR_SYM {}
6700        | NATIONAL_SYM CHAR_SYM {}
6701        ;
6702
6703varchar:
6704          char VARYING {}
6705        | VARCHAR {}
6706        ;
6707
6708nvarchar:
6709          NATIONAL_SYM VARCHAR {}
6710        | NVARCHAR_SYM {}
6711        | NCHAR_SYM VARCHAR {}
6712        | NATIONAL_SYM CHAR_SYM VARYING {}
6713        | NCHAR_SYM VARYING {}
6714        ;
6715
6716int_type:
6717          INT_SYM   { $$=MYSQL_TYPE_LONG; }
6718        | TINYINT   { $$=MYSQL_TYPE_TINY; }
6719        | SMALLINT  { $$=MYSQL_TYPE_SHORT; }
6720        | MEDIUMINT { $$=MYSQL_TYPE_INT24; }
6721        | BIGINT    { $$=MYSQL_TYPE_LONGLONG; }
6722        ;
6723
6724real_type:
6725          REAL
6726          {
6727            $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ?
6728              MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
6729          }
6730        | DOUBLE_SYM
6731          { $$=MYSQL_TYPE_DOUBLE; }
6732        | DOUBLE_SYM PRECISION
6733          { $$=MYSQL_TYPE_DOUBLE; }
6734        ;
6735
6736float_options:
6737          /* empty */
6738          { Lex->dec=Lex->length= (char*)0; }
6739        | field_length
6740          { Lex->dec= (char*)0; }
6741        | precision
6742          {}
6743        ;
6744
6745precision:
6746          '(' NUM ',' NUM ')'
6747          {
6748            LEX *lex=Lex;
6749            lex->length=$2.str;
6750            lex->dec=$4.str;
6751          }
6752        ;
6753
6754
6755type_datetime_precision:
6756          /* empty */                { Lex->dec= (char *) 0; }
6757        | '(' NUM ')'                { Lex->dec= $2.str; }
6758        ;
6759
6760func_datetime_precision:
6761          /* empty */                { $$= 0; }
6762        | '(' ')'                    { $$= 0; }
6763        | '(' NUM ')'
6764           {
6765             int error;
6766             $$= (ulong) my_strtoll10($2.str, NULL, &error);
6767           }
6768        ;
6769
6770field_options:
6771          /* empty */ {}
6772        | field_opt_list {}
6773        ;
6774
6775field_opt_list:
6776          field_opt_list field_option {}
6777        | field_option {}
6778        ;
6779
6780field_option:
6781          SIGNED_SYM {}
6782        | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
6783        | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }
6784        ;
6785
6786field_length:
6787          '(' LONG_NUM ')'      { Lex->length= $2.str; }
6788        | '(' ULONGLONG_NUM ')' { Lex->length= $2.str; }
6789        | '(' DECIMAL_NUM ')'   { Lex->length= $2.str; }
6790        | '(' NUM ')'           { Lex->length= $2.str; };
6791
6792opt_field_length:
6793          /* empty */  { Lex->length=(char*) 0; /* use default length */ }
6794        | field_length { }
6795        ;
6796
6797opt_precision:
6798          /* empty */ {}
6799        | precision {}
6800        ;
6801
6802opt_attribute:
6803          /* empty */ {}
6804        | opt_attribute_list {}
6805        ;
6806
6807opt_attribute_list:
6808          opt_attribute_list attribute {}
6809        | attribute
6810        ;
6811
6812attribute:
6813          NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
6814        | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
6815        | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
6816        | ON UPDATE_SYM now { Lex->on_update_value= $3; }
6817        | AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
6818        | SERIAL_SYM DEFAULT VALUE_SYM
6819          {
6820            LEX *lex=Lex;
6821            lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
6822            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6823          }
6824        | opt_primary KEY_SYM
6825          {
6826            LEX *lex=Lex;
6827            lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
6828            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6829          }
6830        | unique_combo_clustering
6831          {
6832            LEX *lex=Lex;
6833            if ($1 & Key::UNIQUE)
6834              lex->type|= UNIQUE_FLAG;
6835            if ($1 & Key::CLUSTERING)
6836              lex->type|= CLUSTERING_FLAG;
6837            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6838          }
6839        | unique_combo_clustering KEY_SYM
6840          {
6841            LEX *lex=Lex;
6842            if ($1 & Key::UNIQUE)
6843              lex->type|= UNIQUE_KEY_FLAG;
6844            if ($1 & Key::CLUSTERING)
6845              lex->type|= CLUSTERING_FLAG;
6846            lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
6847          }
6848        | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
6849        | COLLATE_SYM collation_name
6850          {
6851            if (Lex->charset && !my_charset_same(Lex->charset,$2))
6852            {
6853              my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
6854                       $2->name,Lex->charset->csname);
6855              MYSQL_YYABORT;
6856            }
6857            else
6858            {
6859              Lex->charset=$2;
6860            }
6861          }
6862        | COLUMN_FORMAT_SYM DEFAULT
6863          {
6864            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6865            Lex->type|=
6866              (COLUMN_FORMAT_TYPE_DEFAULT << FIELD_FLAGS_COLUMN_FORMAT);
6867          }
6868        | COLUMN_FORMAT_SYM FIXED_SYM
6869          {
6870            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6871            Lex->type|=
6872              (COLUMN_FORMAT_TYPE_FIXED << FIELD_FLAGS_COLUMN_FORMAT);
6873          }
6874        | COLUMN_FORMAT_SYM DYNAMIC_SYM
6875          {
6876            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6877            Lex->type|=
6878              (COLUMN_FORMAT_TYPE_DYNAMIC << FIELD_FLAGS_COLUMN_FORMAT);
6879          }
6880        | COLUMN_FORMAT_SYM COMPRESSED_SYM opt_with_compression_dictionary
6881          {
6882            Lex->type&= ~(FIELD_FLAGS_COLUMN_FORMAT_MASK);
6883            Lex->type|=
6884              (COLUMN_FORMAT_TYPE_COMPRESSED << FIELD_FLAGS_COLUMN_FORMAT);
6885            Lex->zip_dict_name= $3;
6886          }
6887        | STORAGE_SYM DEFAULT
6888          {
6889            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
6890            Lex->type|= (HA_SM_DEFAULT << FIELD_FLAGS_STORAGE_MEDIA);
6891          }
6892        | STORAGE_SYM DISK_SYM
6893          {
6894            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
6895            Lex->type|= (HA_SM_DISK << FIELD_FLAGS_STORAGE_MEDIA);
6896          }
6897        | STORAGE_SYM MEMORY_SYM
6898          {
6899            Lex->type&= ~(FIELD_FLAGS_STORAGE_MEDIA_MASK);
6900            Lex->type|= (HA_SM_MEMORY << FIELD_FLAGS_STORAGE_MEDIA);
6901          }
6902        ;
6903
6904opt_with_compression_dictionary:
6905          /* empty */ { $$= null_lex_cstr; }
6906        | WITH COMPRESSION_DICTIONARY_SYM ident
6907          {
6908            /*
6909              no single assignment because of
6910              LEX_STRING -> LEX_CSTRING conversion
6911            */
6912            $$.str= $3.str;
6913            $$.length= $3.length;
6914          }
6915        ;
6916
6917type_with_opt_collate:
6918        type opt_collate
6919        {
6920          $$= $1;
6921
6922          if (Lex->charset) /* Lex->charset is scanned in "type" */
6923          {
6924            if (!(Lex->charset= merge_charset_and_collation(Lex->charset, $2)))
6925              MYSQL_YYABORT;
6926          }
6927          else if ($2)
6928          {
6929            my_error(ER_NOT_SUPPORTED_YET, MYF(0),
6930                     "COLLATE with no CHARACTER SET "
6931                     "in SP parameters, RETURNS, DECLARE");
6932            MYSQL_YYABORT;
6933          }
6934        }
6935        ;
6936
6937
6938now:
6939          NOW_SYM func_datetime_precision
6940          {
6941            $$= new (YYTHD->mem_root) Item_func_now_local($2);
6942            if ($$ == NULL)
6943              MYSQL_YYABORT;
6944          };
6945
6946now_or_signed_literal:
6947        now
6948        | signed_literal
6949          { $$=$1; }
6950        ;
6951
6952charset:
6953          CHAR_SYM SET {}
6954        | CHARSET {}
6955        ;
6956
6957charset_name:
6958          ident_or_text
6959          {
6960            if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))
6961            {
6962              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
6963              MYSQL_YYABORT;
6964            }
6965          }
6966        | BINARY { $$= &my_charset_bin; }
6967        ;
6968
6969charset_name_or_default:
6970          charset_name { $$=$1;   }
6971        | DEFAULT    { $$=NULL; }
6972        ;
6973
6974opt_load_data_charset:
6975          /* Empty */ { $$= NULL; }
6976        | charset charset_name_or_default { $$= $2; }
6977        ;
6978
6979old_or_new_charset_name:
6980          ident_or_text
6981          {
6982            if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) &&
6983                !($$=get_old_charset_by_name($1.str)))
6984            {
6985              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
6986              MYSQL_YYABORT;
6987            }
6988          }
6989        | BINARY { $$= &my_charset_bin; }
6990        ;
6991
6992old_or_new_charset_name_or_default:
6993          old_or_new_charset_name { $$=$1;   }
6994        | DEFAULT    { $$=NULL; }
6995        ;
6996
6997collation_name:
6998          ident_or_text
6999          {
7000            if (!($$= mysqld_collation_get_by_name($1.str)))
7001              MYSQL_YYABORT;
7002          }
7003        ;
7004
7005opt_collate:
7006          /* empty */ { $$=NULL; }
7007        | COLLATE_SYM collation_name_or_default { $$=$2; }
7008        ;
7009
7010collation_name_or_default:
7011          collation_name { $$=$1; }
7012        | DEFAULT    { $$=NULL; }
7013        ;
7014
7015opt_default:
7016          /* empty */ {}
7017        | DEFAULT {}
7018        ;
7019
7020
7021ascii:
7022          ASCII_SYM { Lex->charset= &my_charset_latin1; }
7023        | BINARY ASCII_SYM
7024          {
7025            Lex->charset= &my_charset_latin1_bin;
7026          }
7027        | ASCII_SYM BINARY
7028          {
7029            Lex->charset= &my_charset_latin1_bin;
7030          }
7031        ;
7032
7033unicode:
7034          UNICODE_SYM
7035          {
7036            if (!(Lex->charset=get_charset_by_csname("ucs2",
7037                                                     MY_CS_PRIMARY,MYF(0))))
7038            {
7039              my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
7040              MYSQL_YYABORT;
7041            }
7042          }
7043        | UNICODE_SYM BINARY
7044          {
7045            if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
7046              MYSQL_YYABORT;
7047          }
7048        | BINARY UNICODE_SYM
7049          {
7050            if (!(Lex->charset= mysqld_collation_get_by_name("ucs2_bin")))
7051              my_error(ER_UNKNOWN_COLLATION, MYF(0), "ucs2_bin");
7052          }
7053        ;
7054
7055opt_binary:
7056          /* empty */ { Lex->charset=NULL; }
7057        | ascii
7058        | unicode
7059        | BYTE_SYM { Lex->charset=&my_charset_bin; }
7060        | charset charset_name opt_bin_mod { Lex->charset=$2; }
7061        | BINARY
7062          {
7063            Lex->charset= NULL;
7064            Lex->type|= BINCMP_FLAG;
7065          }
7066        | BINARY charset charset_name
7067          {
7068            Lex->charset= $3;
7069            Lex->type|= BINCMP_FLAG;
7070          }
7071        ;
7072
7073opt_bin_mod:
7074          /* empty */ { }
7075        | BINARY { Lex->type|= BINCMP_FLAG; }
7076        ;
7077
7078ws_nweights:
7079        '(' real_ulong_num
7080        {
7081          if ($2 == 0)
7082          {
7083            my_parse_error(ER(ER_SYNTAX_ERROR));
7084            MYSQL_YYABORT;
7085          }
7086        }
7087        ')'
7088        { $$= $2; }
7089        ;
7090
7091ws_level_flag_desc:
7092        ASC { $$= 0; }
7093        | DESC { $$= 1 << MY_STRXFRM_DESC_SHIFT; }
7094        ;
7095
7096ws_level_flag_reverse:
7097        REVERSE_SYM { $$= 1 << MY_STRXFRM_REVERSE_SHIFT; } ;
7098
7099ws_level_flags:
7100        /* empty */ { $$= 0; }
7101        | ws_level_flag_desc { $$= $1; }
7102        | ws_level_flag_desc ws_level_flag_reverse { $$= $1 | $2; }
7103        | ws_level_flag_reverse { $$= $1 ; }
7104        ;
7105
7106ws_level_number:
7107        real_ulong_num
7108        {
7109          $$= $1 < 1 ? 1 : ($1 > MY_STRXFRM_NLEVELS ? MY_STRXFRM_NLEVELS : $1);
7110          $$--;
7111        }
7112        ;
7113
7114ws_level_list_item:
7115        ws_level_number ws_level_flags
7116        {
7117          $$= (1 | $2) << $1;
7118        }
7119        ;
7120
7121ws_level_list:
7122        ws_level_list_item { $$= $1; }
7123        | ws_level_list ',' ws_level_list_item { $$|= $3; }
7124        ;
7125
7126ws_level_range:
7127        ws_level_number '-' ws_level_number
7128        {
7129          uint start= $1;
7130          uint end= $3;
7131          for ($$= 0; start <= end; start++)
7132            $$|= (1 << start);
7133        }
7134        ;
7135
7136ws_level_list_or_range:
7137        ws_level_list { $$= $1; }
7138        | ws_level_range { $$= $1; }
7139        ;
7140
7141opt_ws_levels:
7142        /* empty*/ { $$= 0; }
7143        | LEVEL_SYM ws_level_list_or_range { $$= $2; }
7144        ;
7145
7146opt_primary:
7147          /* empty */
7148        | PRIMARY_SYM
7149        ;
7150
7151references:
7152          REFERENCES
7153          table_ident
7154          opt_ref_list
7155          opt_match_clause
7156          opt_on_update_delete
7157          {
7158            $$=$2;
7159          }
7160        ;
7161
7162opt_ref_list:
7163          /* empty */
7164          { Lex->ref_list.empty(); }
7165        | '(' ref_list ')'
7166        ;
7167
7168ref_list:
7169          ref_list ',' ident
7170          {
7171            Key_part_spec *key= new Key_part_spec($3, 0);
7172            if (key == NULL)
7173              MYSQL_YYABORT;
7174            Lex->ref_list.push_back(key);
7175          }
7176        | ident
7177          {
7178            Key_part_spec *key= new Key_part_spec($1, 0);
7179            if (key == NULL)
7180              MYSQL_YYABORT;
7181            LEX *lex= Lex;
7182            lex->ref_list.empty();
7183            lex->ref_list.push_back(key);
7184          }
7185        ;
7186
7187opt_match_clause:
7188          /* empty */
7189          { Lex->fk_match_option= Foreign_key::FK_MATCH_UNDEF; }
7190        | MATCH FULL
7191          { Lex->fk_match_option= Foreign_key::FK_MATCH_FULL; }
7192        | MATCH PARTIAL
7193          { Lex->fk_match_option= Foreign_key::FK_MATCH_PARTIAL; }
7194        | MATCH SIMPLE_SYM
7195          { Lex->fk_match_option= Foreign_key::FK_MATCH_SIMPLE; }
7196        ;
7197
7198opt_on_update_delete:
7199          /* empty */
7200          {
7201            LEX *lex= Lex;
7202            lex->fk_update_opt= Foreign_key::FK_OPTION_UNDEF;
7203            lex->fk_delete_opt= Foreign_key::FK_OPTION_UNDEF;
7204          }
7205        | ON UPDATE_SYM delete_option
7206          {
7207            LEX *lex= Lex;
7208            lex->fk_update_opt= $3;
7209            lex->fk_delete_opt= Foreign_key::FK_OPTION_UNDEF;
7210          }
7211        | ON DELETE_SYM delete_option
7212          {
7213            LEX *lex= Lex;
7214            lex->fk_update_opt= Foreign_key::FK_OPTION_UNDEF;
7215            lex->fk_delete_opt= $3;
7216          }
7217        | ON UPDATE_SYM delete_option
7218          ON DELETE_SYM delete_option
7219          {
7220            LEX *lex= Lex;
7221            lex->fk_update_opt= $3;
7222            lex->fk_delete_opt= $6;
7223          }
7224        | ON DELETE_SYM delete_option
7225          ON UPDATE_SYM delete_option
7226          {
7227            LEX *lex= Lex;
7228            lex->fk_update_opt= $6;
7229            lex->fk_delete_opt= $3;
7230          }
7231        ;
7232
7233delete_option:
7234          RESTRICT      { $$= Foreign_key::FK_OPTION_RESTRICT; }
7235        | CASCADE       { $$= Foreign_key::FK_OPTION_CASCADE; }
7236        | SET NULL_SYM  { $$= Foreign_key::FK_OPTION_SET_NULL; }
7237        | NO_SYM ACTION { $$= Foreign_key::FK_OPTION_NO_ACTION; }
7238        | SET DEFAULT   { $$= Foreign_key::FK_OPTION_DEFAULT;  }
7239        ;
7240
7241normal_key_type:
7242          key_or_index { $$= Key::MULTIPLE; }
7243        ;
7244
7245constraint_key_type:
7246          PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
7247        | unique_combo_clustering opt_key_or_index { $$= $1; }
7248
7249        ;
7250
7251key_or_index:
7252          KEY_SYM {}
7253        | INDEX_SYM {}
7254        ;
7255
7256opt_key_or_index:
7257          /* empty */ {}
7258        | key_or_index
7259        ;
7260
7261keys_or_index:
7262          KEYS {}
7263        | INDEX_SYM {}
7264        | INDEXES {}
7265        ;
7266
7267opt_unique_combo_clustering:
7268          /* empty */          { $$= Key::MULTIPLE; }
7269        | unique_combo_clustering
7270        ;
7271
7272unique_combo_clustering:
7273          clustering
7274          {
7275            $$= (enum Key::Keytype)($1 | Key::MULTIPLE);
7276          }
7277        | unique_opt_clustering
7278          {
7279            $$= $1;
7280          }
7281        ;
7282
7283unique_opt_clustering:
7284          unique
7285          {
7286            $$= $1;
7287          }
7288        | unique clustering
7289          {
7290            $$= (enum Key::Keytype)($1 | $2);
7291          }
7292        | clustering unique
7293          {
7294            $$= (enum Key::Keytype)($1 | $2);
7295          }
7296        ;
7297
7298unique:
7299          UNIQUE_SYM     { $$= Key::UNIQUE; }
7300        ;
7301
7302clustering:
7303          CLUSTERING_SYM { $$= Key::CLUSTERING; }
7304        ;
7305
7306fulltext:
7307          FULLTEXT_SYM { $$= Key::FULLTEXT;}
7308        ;
7309
7310spatial:
7311          SPATIAL_SYM
7312          {
7313#ifdef HAVE_SPATIAL
7314            $$= Key::SPATIAL;
7315#else
7316            my_error(ER_FEATURE_DISABLED, MYF(0),
7317                     sym_group_geom.name, sym_group_geom.needed_define);
7318            MYSQL_YYABORT;
7319#endif
7320          }
7321        ;
7322
7323init_key_options:
7324          {
7325            Lex->key_create_info= default_key_create_info;
7326          }
7327        ;
7328
7329/*
7330  For now, key_alg initializies lex->key_create_info.
7331  In the future, when all key options are after key definition,
7332  we can remove key_alg and move init_key_options to key_options
7333*/
7334
7335key_alg:
7336          init_key_options
7337        | init_key_options key_using_alg
7338        ;
7339
7340normal_key_options:
7341          /* empty */ {}
7342        | normal_key_opts
7343        ;
7344
7345fulltext_key_options:
7346          /* empty */ {}
7347        | fulltext_key_opts
7348        ;
7349
7350spatial_key_options:
7351          /* empty */ {}
7352        | spatial_key_opts
7353        ;
7354
7355normal_key_opts:
7356          normal_key_opt
7357        | normal_key_opts normal_key_opt
7358        ;
7359
7360spatial_key_opts:
7361          spatial_key_opt
7362        | spatial_key_opts spatial_key_opt
7363        ;
7364
7365fulltext_key_opts:
7366          fulltext_key_opt
7367        | fulltext_key_opts fulltext_key_opt
7368        ;
7369
7370key_using_alg:
7371          USING btree_or_rtree     { Lex->key_create_info.algorithm= $2; }
7372        | TYPE_SYM btree_or_rtree  { Lex->key_create_info.algorithm= $2; }
7373        ;
7374
7375all_key_opt:
7376          KEY_BLOCK_SIZE opt_equal ulong_num
7377          { Lex->key_create_info.block_size= $3; }
7378	| COMMENT_SYM TEXT_STRING_sys { Lex->key_create_info.comment= $2; }
7379        ;
7380
7381normal_key_opt:
7382          all_key_opt
7383        | key_using_alg
7384        ;
7385
7386spatial_key_opt:
7387          all_key_opt
7388        ;
7389
7390fulltext_key_opt:
7391          all_key_opt
7392        | WITH PARSER_SYM IDENT_sys
7393          {
7394            if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
7395              Lex->key_create_info.parser_name= $3;
7396            else
7397            {
7398              my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
7399              MYSQL_YYABORT;
7400            }
7401          }
7402        ;
7403
7404btree_or_rtree:
7405          BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
7406        | RTREE_SYM { $$= HA_KEY_ALG_RTREE; }
7407        | HASH_SYM  { $$= HA_KEY_ALG_HASH; }
7408        ;
7409
7410key_list:
7411          key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
7412        | key_part order_dir { Lex->col_list.push_back($1); }
7413        ;
7414
7415key_part:
7416          ident
7417          {
7418            $$= new Key_part_spec($1, 0);
7419            if ($$ == NULL)
7420              MYSQL_YYABORT;
7421          }
7422        | ident '(' NUM ')'
7423          {
7424            int key_part_len= atoi($3.str);
7425            if (!key_part_len)
7426            {
7427              my_error(ER_KEY_PART_0, MYF(0), $1.str);
7428            }
7429            $$= new Key_part_spec($1, (uint) key_part_len);
7430            if ($$ == NULL)
7431              MYSQL_YYABORT;
7432          }
7433        ;
7434
7435opt_ident:
7436          /* empty */ { $$= null_lex_str; }
7437        | field_ident { $$= $1; }
7438        ;
7439
7440opt_component:
7441          /* empty */    { $$= null_lex_str; }
7442        | '.' ident      { $$= $2; }
7443        ;
7444
7445string_list:
7446          text_string { Lex->interval_list.push_back($1); }
7447        | string_list ',' text_string { Lex->interval_list.push_back($3); };
7448
7449/*
7450** Alter table
7451*/
7452
7453alter:
7454          ALTER opt_ignore TABLE_SYM table_ident
7455          {
7456            THD *thd= YYTHD;
7457            LEX *lex= thd->lex;
7458            lex->name.str= 0;
7459            lex->name.length= 0;
7460            lex->sql_command= SQLCOM_ALTER_TABLE;
7461            lex->duplicates= DUP_ERROR;
7462            if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
7463                                                   TL_OPTION_UPDATING,
7464                                                   TL_READ_NO_INSERT,
7465                                                   MDL_SHARED_UPGRADABLE))
7466              MYSQL_YYABORT;
7467            lex->col_list.empty();
7468            lex->select_lex.init_order();
7469            lex->select_lex.db= (lex->select_lex.table_list.first)->db;
7470            memset(static_cast<void*>(&lex->create_info), 0,
7471                   sizeof(lex->create_info));
7472            lex->create_info.db_type= 0;
7473            lex->create_info.default_table_charset= NULL;
7474            lex->create_info.row_type= ROW_TYPE_NOT_USED;
7475            lex->alter_info.reset();
7476            lex->no_write_to_binlog= 0;
7477            lex->create_info.storage_media= HA_SM_DEFAULT;
7478            lex->create_last_non_select_table= lex->last_table();
7479            DBUG_ASSERT(!lex->m_sql_cmd);
7480            if (lex->ignore)
7481            {
7482              push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
7483                                  ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT,
7484                                  ER(ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT),
7485                                  "IGNORE");
7486            }
7487          }
7488          alter_commands
7489          {
7490            THD *thd= YYTHD;
7491            LEX *lex= thd->lex;
7492            if (!lex->m_sql_cmd)
7493            {
7494              /* Create a generic ALTER TABLE statment. */
7495              lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_table();
7496              if (lex->m_sql_cmd == NULL)
7497                MYSQL_YYABORT;
7498            }
7499          }
7500        | ALTER DATABASE ident_or_empty
7501          {
7502            Lex->create_info.default_table_charset= NULL;
7503            Lex->create_info.used_fields= 0;
7504          }
7505          create_database_options
7506          {
7507            LEX *lex=Lex;
7508            lex->sql_command=SQLCOM_ALTER_DB;
7509            lex->name= $3;
7510            if (lex->name.str == NULL &&
7511                lex->copy_db_to(&lex->name.str, &lex->name.length))
7512              MYSQL_YYABORT;
7513          }
7514        | ALTER DATABASE ident UPGRADE_SYM DATA_SYM DIRECTORY_SYM NAME_SYM
7515          {
7516            LEX *lex= Lex;
7517            if (lex->sphead)
7518            {
7519              my_error(ER_SP_NO_DROP_SP, MYF(0), "DATABASE");
7520              MYSQL_YYABORT;
7521            }
7522            lex->sql_command= SQLCOM_ALTER_DB_UPGRADE;
7523            lex->name= $3;
7524          }
7525        | ALTER PROCEDURE_SYM sp_name
7526          {
7527            LEX *lex= Lex;
7528
7529            if (lex->sphead)
7530            {
7531              my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
7532              MYSQL_YYABORT;
7533            }
7534            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
7535          }
7536          sp_a_chistics
7537          {
7538            LEX *lex=Lex;
7539
7540            lex->sql_command= SQLCOM_ALTER_PROCEDURE;
7541            lex->spname= $3;
7542          }
7543        | ALTER FUNCTION_SYM sp_name
7544          {
7545            LEX *lex= Lex;
7546
7547            if (lex->sphead)
7548            {
7549              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
7550              MYSQL_YYABORT;
7551            }
7552            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
7553          }
7554          sp_a_chistics
7555          {
7556            LEX *lex=Lex;
7557
7558            lex->sql_command= SQLCOM_ALTER_FUNCTION;
7559            lex->spname= $3;
7560          }
7561        | ALTER view_algorithm definer_opt
7562          {
7563            LEX *lex= Lex;
7564
7565            if (lex->sphead)
7566            {
7567              my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
7568              MYSQL_YYABORT;
7569            }
7570            lex->create_view_mode= VIEW_ALTER;
7571          }
7572          view_tail
7573          {}
7574        | ALTER definer_opt
7575          /*
7576            We have two separate rules for ALTER VIEW rather that
7577            optional view_algorithm above, to resolve the ambiguity
7578            with the ALTER EVENT below.
7579          */
7580          {
7581            LEX *lex= Lex;
7582
7583            if (lex->sphead)
7584            {
7585              my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
7586              MYSQL_YYABORT;
7587            }
7588            lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
7589            lex->create_view_mode= VIEW_ALTER;
7590          }
7591          view_tail
7592          {}
7593        | ALTER definer_opt EVENT_SYM sp_name
7594          {
7595            /*
7596              It is safe to use Lex->spname because
7597              ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
7598              is not allowed. Lex->spname is used in the case of RENAME TO
7599              If it had to be supported spname had to be added to
7600              Event_parse_data.
7601            */
7602
7603            if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
7604              MYSQL_YYABORT;
7605            Lex->event_parse_data->identifier= $4;
7606
7607            Lex->sql_command= SQLCOM_ALTER_EVENT;
7608          }
7609          ev_alter_on_schedule_completion
7610          opt_ev_rename_to
7611          opt_ev_status
7612          opt_ev_comment
7613          opt_ev_sql_stmt
7614          {
7615            if (!($6 || $7 || $8 || $9 || $10))
7616            {
7617              my_parse_error(ER(ER_SYNTAX_ERROR));
7618              MYSQL_YYABORT;
7619            }
7620            /*
7621              sql_command is set here because some rules in ev_sql_stmt
7622              can overwrite it
7623            */
7624            Lex->sql_command= SQLCOM_ALTER_EVENT;
7625          }
7626        | ALTER TABLESPACE alter_tablespace_info
7627          {
7628            LEX *lex= Lex;
7629            lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
7630          }
7631        | ALTER LOGFILE_SYM GROUP_SYM alter_logfile_group_info
7632          {
7633            LEX *lex= Lex;
7634            lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
7635          }
7636        | ALTER TABLESPACE change_tablespace_info
7637          {
7638            LEX *lex= Lex;
7639            lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE;
7640          }
7641        | ALTER TABLESPACE change_tablespace_access
7642          {
7643            LEX *lex= Lex;
7644            lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE;
7645          }
7646        | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
7647          {
7648            LEX *lex= Lex;
7649            lex->sql_command= SQLCOM_ALTER_SERVER;
7650            lex->server_options.server_name= $3.str;
7651            lex->server_options.server_name_length= $3.length;
7652          }
7653        | ALTER USER clear_privileges alter_user_list
7654          {
7655            Lex->sql_command= SQLCOM_ALTER_USER;
7656          }
7657        ;
7658
7659alter_user_list:
7660        user PASSWORD EXPIRE_SYM
7661        {
7662            if (Lex->users_list.push_back($1))
7663              MYSQL_YYABORT;
7664        }
7665        | alter_user_list ',' user PASSWORD EXPIRE_SYM
7666          {
7667            if (Lex->users_list.push_back($3))
7668              MYSQL_YYABORT;
7669          }
7670        ;
7671
7672ev_alter_on_schedule_completion:
7673          /* empty */ { $$= 0;}
7674        | ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
7675        | ev_on_completion { $$= 1; }
7676        | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; }
7677        ;
7678
7679opt_ev_rename_to:
7680          /* empty */ { $$= 0;}
7681        | RENAME TO_SYM sp_name
7682          {
7683            /*
7684              Use lex's spname to hold the new name.
7685              The original name is in the Event_parse_data object
7686            */
7687            Lex->spname= $3;
7688            $$= 1;
7689          }
7690        ;
7691
7692opt_ev_sql_stmt:
7693          /* empty*/ { $$= 0;}
7694        | DO_SYM ev_sql_stmt { $$= 1; }
7695        ;
7696
7697ident_or_empty:
7698          /* empty */ { $$.str= 0; $$.length= 0; }
7699        | ident { $$= $1; }
7700        ;
7701
7702alter_commands:
7703          /* empty */
7704        | DISCARD TABLESPACE
7705          {
7706            Lex->m_sql_cmd= new (YYTHD->mem_root)
7707              Sql_cmd_discard_import_tablespace(
7708                Sql_cmd_discard_import_tablespace::DISCARD_TABLESPACE);
7709            if (Lex->m_sql_cmd == NULL)
7710              MYSQL_YYABORT;
7711          }
7712        | IMPORT TABLESPACE
7713          {
7714            Lex->m_sql_cmd= new (YYTHD->mem_root)
7715              Sql_cmd_discard_import_tablespace(
7716                Sql_cmd_discard_import_tablespace::IMPORT_TABLESPACE);
7717            if (Lex->m_sql_cmd == NULL)
7718              MYSQL_YYABORT;
7719          }
7720        | alter_list
7721          opt_partitioning
7722        | alter_list
7723          remove_partitioning
7724        | remove_partitioning
7725        | partitioning
7726/*
7727  This part was added for release 5.1 by Mikael Ronström.
7728  From here we insert a number of commands to manage the partitions of a
7729  partitioned table such as adding partitions, dropping partitions,
7730  reorganising partitions in various manners. In future releases the list
7731  will be longer.
7732*/
7733        | add_partition_rule
7734        | DROP PARTITION_SYM alt_part_name_list
7735          {
7736            Lex->alter_info.flags|= Alter_info::ALTER_DROP_PARTITION;
7737          }
7738        | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog
7739          all_or_alt_part_name_list
7740          {
7741            LEX *lex= Lex;
7742            lex->alter_info.flags|= Alter_info::ALTER_REBUILD_PARTITION;
7743            lex->no_write_to_binlog= $3;
7744          }
7745        | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog
7746          all_or_alt_part_name_list
7747          {
7748            THD *thd= YYTHD;
7749            LEX *lex= thd->lex;
7750            lex->no_write_to_binlog= $3;
7751            lex->check_opt.init();
7752            DBUG_ASSERT(!lex->m_sql_cmd);
7753            lex->m_sql_cmd= new (thd->mem_root)
7754                              Sql_cmd_alter_table_optimize_partition();
7755            if (lex->m_sql_cmd == NULL)
7756              MYSQL_YYABORT;
7757          }
7758          opt_no_write_to_binlog
7759        | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog
7760          all_or_alt_part_name_list
7761          {
7762            THD *thd= YYTHD;
7763            LEX *lex= thd->lex;
7764            lex->no_write_to_binlog= $3;
7765            lex->check_opt.init();
7766            DBUG_ASSERT(!lex->m_sql_cmd);
7767            lex->m_sql_cmd= new (thd->mem_root)
7768                              Sql_cmd_alter_table_analyze_partition();
7769            if (lex->m_sql_cmd == NULL)
7770              MYSQL_YYABORT;
7771          }
7772        | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
7773          {
7774            THD *thd= YYTHD;
7775            LEX *lex= thd->lex;
7776            lex->check_opt.init();
7777            DBUG_ASSERT(!lex->m_sql_cmd);
7778            lex->m_sql_cmd= new (thd->mem_root)
7779                              Sql_cmd_alter_table_check_partition();
7780            if (lex->m_sql_cmd == NULL)
7781              MYSQL_YYABORT;
7782          }
7783          opt_mi_check_type
7784        | REPAIR PARTITION_SYM opt_no_write_to_binlog
7785          all_or_alt_part_name_list
7786          {
7787            THD *thd= YYTHD;
7788            LEX *lex= thd->lex;
7789            lex->no_write_to_binlog= $3;
7790            lex->check_opt.init();
7791            DBUG_ASSERT(!lex->m_sql_cmd);
7792            lex->m_sql_cmd= new (thd->mem_root)
7793                              Sql_cmd_alter_table_repair_partition();
7794            if (lex->m_sql_cmd == NULL)
7795              MYSQL_YYABORT;
7796          }
7797          opt_mi_repair_type
7798        | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num
7799          {
7800            LEX *lex= Lex;
7801            lex->alter_info.flags|= Alter_info::ALTER_COALESCE_PARTITION;
7802            lex->no_write_to_binlog= $3;
7803            lex->alter_info.num_parts= $4;
7804          }
7805        | TRUNCATE_SYM PARTITION_SYM all_or_alt_part_name_list
7806          {
7807            THD *thd= YYTHD;
7808            LEX *lex= thd->lex;
7809            lex->check_opt.init();
7810            DBUG_ASSERT(!lex->m_sql_cmd);
7811            lex->m_sql_cmd= new (thd->mem_root)
7812                              Sql_cmd_alter_table_truncate_partition();
7813            if (lex->m_sql_cmd == NULL)
7814              MYSQL_YYABORT;
7815          }
7816        | reorg_partition_rule
7817        | EXCHANGE_SYM PARTITION_SYM alt_part_name_item
7818          WITH TABLE_SYM table_ident have_partitioning
7819          {
7820            THD *thd= YYTHD;
7821            LEX *lex= thd->lex;
7822            size_t dummy;
7823            lex->select_lex.db=$6->db.str;
7824            if (lex->select_lex.db == NULL &&
7825                lex->copy_db_to(&lex->select_lex.db, &dummy))
7826            {
7827              MYSQL_YYABORT;
7828            }
7829            lex->name= $6->table;
7830            lex->alter_info.flags|= Alter_info::ALTER_EXCHANGE_PARTITION;
7831            if (!lex->select_lex.add_table_to_list(thd, $6, NULL,
7832                                                   TL_OPTION_UPDATING,
7833                                                   TL_READ_NO_INSERT,
7834                                                   MDL_SHARED_NO_WRITE))
7835              MYSQL_YYABORT;
7836            DBUG_ASSERT(!lex->m_sql_cmd);
7837            lex->m_sql_cmd= new (thd->mem_root)
7838                               Sql_cmd_alter_table_exchange_partition();
7839            if (lex->m_sql_cmd == NULL)
7840              MYSQL_YYABORT;
7841          }
7842        ;
7843
7844remove_partitioning:
7845          REMOVE_SYM PARTITIONING_SYM have_partitioning
7846          {
7847            Lex->alter_info.flags|= Alter_info::ALTER_REMOVE_PARTITIONING;
7848          }
7849        ;
7850
7851all_or_alt_part_name_list:
7852          ALL
7853          {
7854            Lex->alter_info.flags|= Alter_info::ALTER_ALL_PARTITION;
7855          }
7856        | alt_part_name_list
7857        ;
7858
7859add_partition_rule:
7860          ADD PARTITION_SYM opt_no_write_to_binlog
7861          {
7862            LEX *lex= Lex;
7863            lex->part_info= new partition_info();
7864            if (!lex->part_info)
7865            {
7866              mem_alloc_error(sizeof(partition_info));
7867              MYSQL_YYABORT;
7868            }
7869            lex->alter_info.flags|= Alter_info::ALTER_ADD_PARTITION;
7870            lex->no_write_to_binlog= $3;
7871          }
7872          add_part_extra
7873          {}
7874        ;
7875
7876add_part_extra:
7877          /* empty */
7878        | '(' part_def_list ')'
7879          {
7880            LEX *lex= Lex;
7881            lex->part_info->num_parts= lex->part_info->partitions.elements;
7882          }
7883        | PARTITIONS_SYM real_ulong_num
7884          {
7885            Lex->part_info->num_parts= $2;
7886          }
7887        ;
7888
7889reorg_partition_rule:
7890          REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog
7891          {
7892            LEX *lex= Lex;
7893            lex->part_info= new partition_info();
7894            if (!lex->part_info)
7895            {
7896              mem_alloc_error(sizeof(partition_info));
7897              MYSQL_YYABORT;
7898            }
7899            lex->no_write_to_binlog= $3;
7900          }
7901          reorg_parts_rule
7902        ;
7903
7904reorg_parts_rule:
7905          /* empty */
7906          {
7907            Lex->alter_info.flags|= Alter_info::ALTER_TABLE_REORG;
7908          }
7909        | alt_part_name_list
7910          {
7911            Lex->alter_info.flags|= Alter_info::ALTER_REORGANIZE_PARTITION;
7912          }
7913          INTO '(' part_def_list ')'
7914          {
7915            partition_info *part_info= Lex->part_info;
7916            part_info->num_parts= part_info->partitions.elements;
7917          }
7918        ;
7919
7920alt_part_name_list:
7921          alt_part_name_item {}
7922        | alt_part_name_list ',' alt_part_name_item {}
7923        ;
7924
7925alt_part_name_item:
7926          ident
7927          {
7928            if (Lex->alter_info.partition_names.push_back($1.str))
7929            {
7930              mem_alloc_error(1);
7931              MYSQL_YYABORT;
7932            }
7933          }
7934        ;
7935
7936/*
7937  End of management of partition commands
7938*/
7939
7940alter_list:
7941          alter_list_item
7942        | alter_list ',' alter_list_item
7943        ;
7944
7945add_column:
7946          ADD opt_column
7947          {
7948            LEX *lex=Lex;
7949            lex->change=0;
7950            lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN;
7951          }
7952        ;
7953
7954alter_list_item:
7955          add_column column_def opt_place
7956          {
7957            Lex->create_last_non_select_table= Lex->last_table();
7958          }
7959        | ADD key_def
7960          {
7961            Lex->create_last_non_select_table= Lex->last_table();
7962            Lex->alter_info.flags|= Alter_info::ALTER_ADD_INDEX;
7963          }
7964        | add_column '(' create_field_list ')'
7965          {
7966            Lex->alter_info.flags|= Alter_info::ALTER_ADD_COLUMN |
7967                                    Alter_info::ALTER_ADD_INDEX;
7968          }
7969        | CHANGE opt_column field_ident
7970          {
7971            LEX *lex=Lex;
7972            lex->change= $3.str;
7973            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
7974          }
7975          field_spec opt_place
7976          {
7977            Lex->create_last_non_select_table= Lex->last_table();
7978          }
7979        | MODIFY_SYM opt_column field_ident
7980          {
7981            LEX *lex=Lex;
7982            lex->length=lex->dec=0; lex->type=0;
7983            lex->default_value= lex->on_update_value= 0;
7984            lex->comment=null_lex_str;
7985            lex->charset= NULL;
7986            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN;
7987            lex->zip_dict_name= null_lex_cstr;
7988          }
7989          type opt_attribute
7990          {
7991            LEX *lex=Lex;
7992            if (add_field_to_list(lex->thd,&$3,
7993                                  (enum enum_field_types) $5,
7994                                  lex->length,lex->dec,lex->type,
7995                                  lex->default_value, lex->on_update_value,
7996                                  &lex->comment,
7997                                  $3.str, &lex->interval_list, lex->charset,
7998                                  lex->uint_geom_type, &lex->zip_dict_name))
7999              MYSQL_YYABORT;
8000          }
8001          opt_place
8002          {
8003            Lex->create_last_non_select_table= Lex->last_table();
8004          }
8005        | DROP opt_column field_ident opt_restrict
8006          {
8007            LEX *lex=Lex;
8008            Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str);
8009            if (ad == NULL)
8010              MYSQL_YYABORT;
8011            lex->alter_info.drop_list.push_back(ad);
8012            lex->alter_info.flags|= Alter_info::ALTER_DROP_COLUMN;
8013          }
8014        | DROP FOREIGN KEY_SYM field_ident
8015          {
8016            LEX *lex=Lex;
8017            Alter_drop *ad= new Alter_drop(Alter_drop::FOREIGN_KEY, $4.str);
8018            if (ad == NULL)
8019              MYSQL_YYABORT;
8020            lex->alter_info.drop_list.push_back(ad);
8021            lex->alter_info.flags|= Alter_info::DROP_FOREIGN_KEY;
8022          }
8023        | DROP PRIMARY_SYM KEY_SYM
8024          {
8025            LEX *lex=Lex;
8026            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name);
8027            if (ad == NULL)
8028              MYSQL_YYABORT;
8029            lex->alter_info.drop_list.push_back(ad);
8030            lex->alter_info.flags|= Alter_info::ALTER_DROP_INDEX;
8031          }
8032        | DROP key_or_index field_ident
8033          {
8034            LEX *lex=Lex;
8035            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
8036            if (ad == NULL)
8037              MYSQL_YYABORT;
8038            lex->alter_info.drop_list.push_back(ad);
8039            lex->alter_info.flags|= Alter_info::ALTER_DROP_INDEX;
8040          }
8041        | DISABLE_SYM KEYS
8042          {
8043            LEX *lex=Lex;
8044            lex->alter_info.keys_onoff= Alter_info::DISABLE;
8045            lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
8046          }
8047        | ENABLE_SYM KEYS
8048          {
8049            LEX *lex=Lex;
8050            lex->alter_info.keys_onoff= Alter_info::ENABLE;
8051            lex->alter_info.flags|= Alter_info::ALTER_KEYS_ONOFF;
8052          }
8053        | ALTER opt_column field_ident SET DEFAULT signed_literal
8054          {
8055            LEX *lex=Lex;
8056            Alter_column *ac= new Alter_column($3.str,$6);
8057            if (ac == NULL)
8058              MYSQL_YYABORT;
8059            lex->alter_info.alter_list.push_back(ac);
8060            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
8061          }
8062        | ALTER opt_column field_ident DROP DEFAULT
8063          {
8064            LEX *lex=Lex;
8065            Alter_column *ac= new Alter_column($3.str, (Item*) 0);
8066            if (ac == NULL)
8067              MYSQL_YYABORT;
8068            lex->alter_info.alter_list.push_back(ac);
8069            lex->alter_info.flags|= Alter_info::ALTER_CHANGE_COLUMN_DEFAULT;
8070          }
8071        | RENAME opt_to table_ident
8072          {
8073            LEX *lex=Lex;
8074            size_t dummy;
8075            lex->select_lex.db=$3->db.str;
8076            if (lex->select_lex.db == NULL &&
8077                lex->copy_db_to(&lex->select_lex.db, &dummy))
8078            {
8079              MYSQL_YYABORT;
8080            }
8081            enum_ident_name_check ident_check_status=
8082              check_table_name($3->table.str,$3->table.length, FALSE);
8083            if (ident_check_status == IDENT_NAME_WRONG)
8084            {
8085              my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
8086              MYSQL_YYABORT;
8087            }
8088            else if (ident_check_status == IDENT_NAME_TOO_LONG)
8089            {
8090              my_error(ER_TOO_LONG_IDENT, MYF(0), $3->table.str);
8091              MYSQL_YYABORT;
8092            }
8093            if ($3->db.str &&
8094                (check_and_convert_db_name(&$3->db, FALSE) != IDENT_NAME_OK))
8095              MYSQL_YYABORT;
8096            lex->name= $3->table;
8097            lex->alter_info.flags|= Alter_info::ALTER_RENAME;
8098          }
8099        | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
8100          {
8101            if (!$4)
8102            {
8103              THD *thd= YYTHD;
8104              $4= thd->variables.collation_database;
8105            }
8106            $5= $5 ? $5 : $4;
8107            if (!my_charset_same($4,$5))
8108            {
8109              my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
8110                       $5->name, $4->csname);
8111              MYSQL_YYABORT;
8112            }
8113            LEX *lex= Lex;
8114            lex->create_info.table_charset=
8115            lex->create_info.default_table_charset= $5;
8116            lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET |
8117              HA_CREATE_USED_DEFAULT_CHARSET);
8118            lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
8119          }
8120        | create_table_options_space_separated
8121          {
8122            LEX *lex=Lex;
8123            lex->alter_info.flags|= Alter_info::ALTER_OPTIONS;
8124            if ((lex->create_info.used_fields & HA_CREATE_USED_ENGINE) &&
8125                !lex->create_info.db_type)
8126            {
8127              lex->create_info.used_fields&= ~HA_CREATE_USED_ENGINE;
8128            }
8129          }
8130        | FORCE_SYM
8131          {
8132            Lex->alter_info.flags|= Alter_info::ALTER_RECREATE;
8133          }
8134        | alter_order_clause
8135          {
8136            LEX *lex=Lex;
8137            lex->alter_info.flags|= Alter_info::ALTER_ORDER;
8138          }
8139        | alter_algorithm_option
8140        | alter_lock_option
8141        ;
8142
8143opt_index_lock_algorithm:
8144          /* empty */
8145        | alter_lock_option
8146        | alter_algorithm_option
8147        | alter_lock_option alter_algorithm_option
8148        | alter_algorithm_option alter_lock_option
8149
8150alter_algorithm_option:
8151          ALGORITHM_SYM opt_equal DEFAULT
8152          {
8153            Lex->alter_info.requested_algorithm=
8154              Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT;
8155          }
8156        | ALGORITHM_SYM opt_equal ident
8157          {
8158            if (Lex->alter_info.set_requested_algorithm(&$3))
8159            {
8160              my_error(ER_UNKNOWN_ALTER_ALGORITHM, MYF(0), $3.str);
8161              MYSQL_YYABORT;
8162            }
8163          }
8164        ;
8165
8166alter_lock_option:
8167          LOCK_SYM opt_equal DEFAULT
8168          {
8169            Lex->alter_info.requested_lock=
8170              Alter_info::ALTER_TABLE_LOCK_DEFAULT;
8171          }
8172        | LOCK_SYM opt_equal ident
8173          {
8174            if (Lex->alter_info.set_requested_lock(&$3))
8175            {
8176              my_error(ER_UNKNOWN_ALTER_LOCK, MYF(0), $3.str);
8177              MYSQL_YYABORT;
8178            }
8179          }
8180        ;
8181
8182opt_column:
8183          /* empty */ {}
8184        | COLUMN_SYM {}
8185        ;
8186
8187opt_ignore:
8188          /* empty */ { Lex->ignore= 0;}
8189        | IGNORE_SYM { Lex->ignore= 1;}
8190        ;
8191
8192opt_restrict:
8193          /* empty */ { Lex->drop_mode= DROP_DEFAULT; }
8194        | RESTRICT    { Lex->drop_mode= DROP_RESTRICT; }
8195        | CASCADE     { Lex->drop_mode= DROP_CASCADE; }
8196        ;
8197
8198opt_place:
8199          /* empty */ {}
8200        | AFTER_SYM ident
8201          {
8202            store_position_for_column($2.str);
8203            Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
8204          }
8205        | FIRST_SYM
8206          {
8207            store_position_for_column(first_keyword);
8208            Lex->alter_info.flags |= Alter_info::ALTER_COLUMN_ORDER;
8209          }
8210        ;
8211
8212opt_to:
8213          /* empty */ {}
8214        | TO_SYM {}
8215        | EQ {}
8216        | AS {}
8217        ;
8218
8219slave:
8220          START_SYM SLAVE opt_slave_thread_option_list
8221          {
8222            LEX *lex=Lex;
8223            /* Clean previous slave connection values */
8224            lex->slave_connection.reset();
8225            lex->sql_command = SQLCOM_SLAVE_START;
8226            lex->type = 0;
8227            /* We'll use mi structure for UNTIL options */
8228            lex->mi.set_unspecified();
8229            lex->slave_thd_opt= $3;
8230          }
8231          slave_until
8232          slave_connection_opts
8233          {
8234            /*
8235              It is not possible to set user's information when
8236              one is trying to start the SQL Thread.
8237            */
8238            if ((Lex->slave_thd_opt & SLAVE_SQL) == SLAVE_SQL &&
8239                (Lex->slave_thd_opt & SLAVE_IO) != SLAVE_IO &&
8240                (Lex->slave_connection.user ||
8241                 Lex->slave_connection.password ||
8242                 Lex->slave_connection.plugin_auth ||
8243                 Lex->slave_connection.plugin_dir))
8244            {
8245              my_error(ER_SQLTHREAD_WITH_SECURE_SLAVE, MYF(0));
8246              MYSQL_YYABORT;
8247            }
8248          }
8249        | STOP_SYM SLAVE opt_slave_thread_option_list
8250          {
8251            LEX *lex=Lex;
8252            lex->sql_command = SQLCOM_SLAVE_STOP;
8253            lex->type = 0;
8254            lex->slave_thd_opt= $3;
8255          }
8256        ;
8257
8258start:
8259          START_SYM TRANSACTION_SYM opt_start_transaction_option_list
8260          {
8261            LEX *lex= Lex;
8262            lex->sql_command= SQLCOM_BEGIN;
8263            /* READ ONLY and READ WRITE are mutually exclusive. */
8264            if (($3 & MYSQL_START_TRANS_OPT_READ_WRITE) &&
8265                ($3 & MYSQL_START_TRANS_OPT_READ_ONLY))
8266            {
8267              my_parse_error(ER(ER_SYNTAX_ERROR));
8268              MYSQL_YYABORT;
8269            }
8270            lex->start_transaction_opt= $3;
8271          }
8272        ;
8273
8274opt_start_transaction_option_list:
8275          /* empty */
8276          {
8277            $$= 0;
8278          }
8279        | start_transaction_option_list
8280          {
8281            $$= $1;
8282          }
8283        ;
8284
8285start_transaction_option_list:
8286          start_transaction_option
8287          {
8288            $$= $1;
8289          }
8290        | start_transaction_option_list ',' start_transaction_option
8291          {
8292            $$= $1 | $3;
8293          }
8294        ;
8295
8296start_transaction_option:
8297          WITH CONSISTENT_SYM SNAPSHOT_SYM
8298          {
8299            $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
8300          }
8301        | WITH CONSISTENT_SYM SNAPSHOT_SYM FROM SESSION_SYM expr
8302          {
8303            $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
8304            Lex->value_list.empty();
8305            Lex->value_list.push_front($6);
8306          }
8307        | READ_SYM ONLY_SYM
8308          {
8309            $$= MYSQL_START_TRANS_OPT_READ_ONLY;
8310          }
8311        | READ_SYM WRITE_SYM
8312          {
8313            $$= MYSQL_START_TRANS_OPT_READ_WRITE;
8314          }
8315        ;
8316
8317slave_connection_opts:
8318          slave_user_name_opt slave_user_pass_opt
8319          slave_plugin_auth_opt slave_plugin_dir_opt
8320        ;
8321
8322slave_user_name_opt:
8323          {
8324            /* empty */
8325          }
8326        | USER EQ TEXT_STRING_sys
8327          {
8328            Lex->slave_connection.user= $3.str;
8329          }
8330        ;
8331
8332slave_user_pass_opt:
8333          {
8334            /* empty */
8335          }
8336        | PASSWORD EQ TEXT_STRING_sys
8337          {
8338            Lex->slave_connection.password= $3.str;
8339            Lex->contains_plaintext_password= true;
8340          }
8341
8342slave_plugin_auth_opt:
8343          {
8344            /* empty */
8345          }
8346        | DEFAULT_AUTH_SYM EQ TEXT_STRING_sys
8347          {
8348            Lex->slave_connection.plugin_auth= $3.str;
8349          }
8350        ;
8351
8352slave_plugin_dir_opt:
8353          {
8354            /* empty */
8355          }
8356        | PLUGIN_DIR_SYM EQ TEXT_STRING_sys
8357          {
8358            Lex->slave_connection.plugin_dir= $3.str;
8359          }
8360        ;
8361
8362opt_slave_thread_option_list:
8363          /* empty */
8364          {
8365            $$= 0;
8366          }
8367        | slave_thread_option_list
8368          {
8369            $$= $1;
8370          }
8371        ;
8372
8373slave_thread_option_list:
8374          slave_thread_option
8375          {
8376            $$= $1;
8377          }
8378        | slave_thread_option_list ',' slave_thread_option
8379          {
8380            $$= $1 | $3;
8381          }
8382        ;
8383
8384slave_thread_option:
8385          SQL_THREAD
8386          {
8387            $$= SLAVE_SQL;
8388          }
8389        | RELAY_THREAD
8390          {
8391            $$= SLAVE_IO;
8392          }
8393        ;
8394
8395slave_until:
8396          /*empty*/ {}
8397        | UNTIL_SYM slave_until_opts
8398          {
8399            LEX *lex=Lex;
8400            if (((lex->mi.log_file_name || lex->mi.pos) &&
8401                lex->mi.gtid) ||
8402               ((lex->mi.relay_log_name || lex->mi.relay_log_pos) &&
8403                lex->mi.gtid) ||
8404                !((lex->mi.log_file_name && lex->mi.pos) ||
8405                  (lex->mi.relay_log_name && lex->mi.relay_log_pos) ||
8406                  lex->mi.gtid ||
8407                  lex->mi.until_after_gaps) ||
8408                /* SQL_AFTER_MTS_GAPS is meaningless in combination */
8409                /* with any other coordinates related options       */
8410                ((lex->mi.log_file_name || lex->mi.pos || lex->mi.relay_log_name
8411                  || lex->mi.relay_log_pos || lex->mi.gtid)
8412                 && lex->mi.until_after_gaps))
8413            {
8414               my_message(ER_BAD_SLAVE_UNTIL_COND,
8415                          ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0));
8416               MYSQL_YYABORT;
8417            }
8418          }
8419        ;
8420
8421slave_until_opts:
8422          master_file_def
8423        | slave_until_opts ',' master_file_def
8424        | SQL_BEFORE_GTIDS EQ TEXT_STRING_sys
8425          {
8426            Lex->mi.gtid= $3.str;
8427            Lex->mi.gtid_until_condition= LEX_MASTER_INFO::UNTIL_SQL_BEFORE_GTIDS;
8428          }
8429        | SQL_AFTER_GTIDS EQ TEXT_STRING_sys
8430          {
8431            Lex->mi.gtid= $3.str;
8432            Lex->mi.gtid_until_condition= LEX_MASTER_INFO::UNTIL_SQL_AFTER_GTIDS;
8433          }
8434        | SQL_AFTER_MTS_GAPS
8435          {
8436            Lex->mi.until_after_gaps= true;
8437          }
8438        ;
8439
8440checksum:
8441          CHECKSUM_SYM table_or_tables
8442          {
8443            LEX *lex=Lex;
8444            lex->sql_command = SQLCOM_CHECKSUM;
8445            /* Will be overriden during execution. */
8446            YYPS->m_lock_type= TL_UNLOCK;
8447          }
8448          table_list opt_checksum_type
8449          {}
8450        ;
8451
8452opt_checksum_type:
8453          /* nothing */ { Lex->check_opt.flags= 0; }
8454        | QUICK         { Lex->check_opt.flags= T_QUICK; }
8455        | EXTENDED_SYM  { Lex->check_opt.flags= T_EXTEND; }
8456        ;
8457
8458repair:
8459          REPAIR opt_no_write_to_binlog table_or_tables
8460          {
8461            LEX *lex=Lex;
8462            lex->sql_command = SQLCOM_REPAIR;
8463            lex->no_write_to_binlog= $2;
8464            lex->check_opt.init();
8465            lex->alter_info.reset();
8466            /* Will be overriden during execution. */
8467            YYPS->m_lock_type= TL_UNLOCK;
8468          }
8469          table_list opt_mi_repair_type
8470          {
8471            THD *thd= YYTHD;
8472            LEX* lex= thd->lex;
8473            DBUG_ASSERT(!lex->m_sql_cmd);
8474            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_repair_table();
8475            if (lex->m_sql_cmd == NULL)
8476              MYSQL_YYABORT;
8477          }
8478        ;
8479
8480opt_mi_repair_type:
8481          /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
8482        | mi_repair_types {}
8483        ;
8484
8485mi_repair_types:
8486          mi_repair_type {}
8487        | mi_repair_type mi_repair_types {}
8488        ;
8489
8490mi_repair_type:
8491          QUICK        { Lex->check_opt.flags|= T_QUICK; }
8492        | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
8493        | USE_FRM      { Lex->check_opt.sql_flags|= TT_USEFRM; }
8494        ;
8495
8496analyze:
8497          ANALYZE_SYM opt_no_write_to_binlog table_or_tables
8498          {
8499            LEX *lex=Lex;
8500            lex->sql_command = SQLCOM_ANALYZE;
8501            lex->no_write_to_binlog= $2;
8502            lex->check_opt.init();
8503            lex->alter_info.reset();
8504            /* Will be overriden during execution. */
8505            YYPS->m_lock_type= TL_UNLOCK;
8506          }
8507          table_list
8508          {
8509            THD *thd= YYTHD;
8510            LEX* lex= thd->lex;
8511            DBUG_ASSERT(!lex->m_sql_cmd);
8512            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_analyze_table();
8513            if (lex->m_sql_cmd == NULL)
8514              MYSQL_YYABORT;
8515          }
8516        ;
8517
8518binlog_base64_event:
8519          BINLOG_SYM TEXT_STRING_sys
8520          {
8521            Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
8522            Lex->comment= $2;
8523          }
8524        ;
8525
8526check:
8527          CHECK_SYM table_or_tables
8528          {
8529            LEX *lex=Lex;
8530
8531            if (lex->sphead)
8532            {
8533              my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK");
8534              MYSQL_YYABORT;
8535            }
8536            lex->sql_command = SQLCOM_CHECK;
8537            lex->check_opt.init();
8538            lex->alter_info.reset();
8539            /* Will be overriden during execution. */
8540            YYPS->m_lock_type= TL_UNLOCK;
8541          }
8542          table_list opt_mi_check_type
8543          {
8544            THD *thd= YYTHD;
8545            LEX* lex= thd->lex;
8546            DBUG_ASSERT(!lex->m_sql_cmd);
8547            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_check_table();
8548            if (lex->m_sql_cmd == NULL)
8549              MYSQL_YYABORT;
8550          }
8551        ;
8552
8553opt_mi_check_type:
8554          /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
8555        | mi_check_types {}
8556        ;
8557
8558mi_check_types:
8559          mi_check_type {}
8560        | mi_check_type mi_check_types {}
8561        ;
8562
8563mi_check_type:
8564          QUICK               { Lex->check_opt.flags|= T_QUICK; }
8565        | FAST_SYM            { Lex->check_opt.flags|= T_FAST; }
8566        | MEDIUM_SYM          { Lex->check_opt.flags|= T_MEDIUM; }
8567        | EXTENDED_SYM        { Lex->check_opt.flags|= T_EXTEND; }
8568        | CHANGED             { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
8569        | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
8570        ;
8571
8572optimize:
8573          OPTIMIZE opt_no_write_to_binlog table_or_tables
8574          {
8575            LEX *lex=Lex;
8576            lex->sql_command = SQLCOM_OPTIMIZE;
8577            lex->no_write_to_binlog= $2;
8578            lex->check_opt.init();
8579            lex->alter_info.reset();
8580            /* Will be overriden during execution. */
8581            YYPS->m_lock_type= TL_UNLOCK;
8582          }
8583          table_list
8584          {
8585            THD *thd= YYTHD;
8586            LEX* lex= thd->lex;
8587            DBUG_ASSERT(!lex->m_sql_cmd);
8588            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_optimize_table();
8589            if (lex->m_sql_cmd == NULL)
8590              MYSQL_YYABORT;
8591          }
8592        ;
8593
8594opt_no_write_to_binlog:
8595          /* empty */ { $$= 0; }
8596        | NO_WRITE_TO_BINLOG { $$= 1; }
8597        | LOCAL_SYM { $$= 1; }
8598        ;
8599
8600rename:
8601          RENAME table_or_tables
8602          {
8603            Lex->sql_command= SQLCOM_RENAME_TABLE;
8604          }
8605          table_to_table_list
8606          {}
8607        | RENAME USER clear_privileges rename_list
8608          {
8609            Lex->sql_command = SQLCOM_RENAME_USER;
8610          }
8611        ;
8612
8613rename_list:
8614          user TO_SYM user
8615          {
8616            if (Lex->users_list.push_back($1) || Lex->users_list.push_back($3))
8617              MYSQL_YYABORT;
8618          }
8619        | rename_list ',' user TO_SYM user
8620          {
8621            if (Lex->users_list.push_back($3) || Lex->users_list.push_back($5))
8622              MYSQL_YYABORT;
8623          }
8624        ;
8625
8626table_to_table_list:
8627          table_to_table
8628        | table_to_table_list ',' table_to_table
8629        ;
8630
8631table_to_table:
8632          table_ident TO_SYM table_ident
8633          {
8634            LEX *lex=Lex;
8635            SELECT_LEX *sl= lex->current_select;
8636            if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
8637                                       TL_IGNORE, MDL_EXCLUSIVE) ||
8638                !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
8639                                       TL_IGNORE, MDL_EXCLUSIVE))
8640              MYSQL_YYABORT;
8641          }
8642        ;
8643
8644keycache:
8645          CACHE_SYM INDEX_SYM
8646          {
8647            Lex->alter_info.reset();
8648          }
8649          keycache_list_or_parts IN_SYM key_cache_name
8650          {
8651            LEX *lex=Lex;
8652            lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
8653            lex->ident= $6;
8654          }
8655        ;
8656
8657keycache_list_or_parts:
8658          keycache_list
8659        | assign_to_keycache_parts
8660        ;
8661
8662keycache_list:
8663          assign_to_keycache
8664        | keycache_list ',' assign_to_keycache
8665        ;
8666
8667assign_to_keycache:
8668          table_ident cache_keys_spec
8669          {
8670            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
8671                                           MDL_SHARED_READ,
8672                                           Select->pop_index_hints()))
8673              MYSQL_YYABORT;
8674          }
8675        ;
8676
8677assign_to_keycache_parts:
8678          table_ident adm_partition cache_keys_spec
8679          {
8680            if (!Select->add_table_to_list(YYTHD, $1, NULL, 0, TL_READ,
8681                                           MDL_SHARED_READ,
8682                                           Select->pop_index_hints()))
8683              MYSQL_YYABORT;
8684          }
8685        ;
8686
8687key_cache_name:
8688          ident    { $$= $1; }
8689        | DEFAULT  { $$ = default_key_cache_base; }
8690        ;
8691
8692preload:
8693          LOAD INDEX_SYM INTO CACHE_SYM
8694          {
8695            LEX *lex=Lex;
8696            lex->sql_command=SQLCOM_PRELOAD_KEYS;
8697            lex->alter_info.reset();
8698          }
8699          preload_list_or_parts
8700          {}
8701        ;
8702
8703preload_list_or_parts:
8704          preload_keys_parts
8705        | preload_list
8706        ;
8707
8708preload_list:
8709          preload_keys
8710        | preload_list ',' preload_keys
8711        ;
8712
8713preload_keys:
8714          table_ident cache_keys_spec opt_ignore_leaves
8715          {
8716            if (!Select->add_table_to_list(YYTHD, $1, NULL, $3, TL_READ,
8717                                           MDL_SHARED_READ,
8718                                           Select->pop_index_hints()))
8719              MYSQL_YYABORT;
8720          }
8721        ;
8722
8723preload_keys_parts:
8724          table_ident adm_partition cache_keys_spec opt_ignore_leaves
8725          {
8726            if (!Select->add_table_to_list(YYTHD, $1, NULL, $4, TL_READ,
8727                                           MDL_SHARED_READ,
8728                                           Select->pop_index_hints()))
8729              MYSQL_YYABORT;
8730          }
8731        ;
8732
8733adm_partition:
8734          PARTITION_SYM have_partitioning
8735          {
8736            Lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
8737          }
8738          '(' all_or_alt_part_name_list ')'
8739        ;
8740
8741cache_keys_spec:
8742          {
8743            Lex->select_lex.alloc_index_hints(YYTHD);
8744            Select->set_index_hint_type(INDEX_HINT_USE,
8745                                        old_mode ?
8746                                        INDEX_HINT_MASK_JOIN :
8747                                        INDEX_HINT_MASK_ALL);
8748          }
8749          cache_key_list_or_empty
8750        ;
8751
8752cache_key_list_or_empty:
8753          /* empty */ { }
8754        | key_or_index '(' opt_key_usage_list ')'
8755        ;
8756
8757opt_ignore_leaves:
8758          /* empty */
8759          { $$= 0; }
8760        | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
8761        ;
8762
8763/*
8764  Select : retrieve data from table
8765*/
8766
8767
8768select:
8769          select_init
8770          {
8771            LEX *lex= Lex;
8772            lex->sql_command= SQLCOM_SELECT;
8773          }
8774        ;
8775
8776/* Need select_init2 for subselects. */
8777select_init:
8778          SELECT_SYM select_init2
8779        | '(' select_paren ')' union_opt
8780        ;
8781
8782select_paren:
8783          SELECT_SYM select_part2
8784          {
8785            if (setup_select_in_parentheses(Lex))
8786              MYSQL_YYABORT;
8787          }
8788        | '(' select_paren ')'
8789        ;
8790
8791/* The equivalent of select_paren for nested queries. */
8792select_paren_derived:
8793          SELECT_SYM select_part2_derived
8794          {
8795            if (setup_select_in_parentheses(Lex))
8796              MYSQL_YYABORT;
8797          }
8798        | '(' select_paren_derived ')'
8799        ;
8800
8801select_init2:
8802          select_part2
8803          {
8804            LEX *lex= Lex;
8805            SELECT_LEX * sel= lex->current_select;
8806            if (lex->current_select->set_braces(0))
8807            {
8808              my_parse_error(ER(ER_SYNTAX_ERROR));
8809              MYSQL_YYABORT;
8810            }
8811            if (sel->linkage == UNION_TYPE &&
8812                sel->master_unit()->first_select()->braces)
8813            {
8814              my_parse_error(ER(ER_SYNTAX_ERROR));
8815              MYSQL_YYABORT;
8816            }
8817          }
8818          union_clause
8819        ;
8820
8821select_part2:
8822          {
8823            LEX *lex= Lex;
8824            SELECT_LEX *sel= lex->current_select;
8825            if (sel->linkage != UNION_TYPE)
8826              mysql_init_select(lex);
8827            lex->current_select->parsing_place= SELECT_LIST;
8828          }
8829          select_options select_item_list
8830          {
8831            Select->parsing_place= NO_MATTER;
8832          }
8833          select_into select_lock_type
8834        ;
8835
8836select_into:
8837          opt_order_clause opt_limit_clause {}
8838        | into
8839        | select_from
8840        | into select_from
8841        | select_from into
8842        ;
8843
8844select_from:
8845          FROM join_table_list where_clause group_clause having_clause
8846          opt_order_clause opt_limit_clause procedure_analyse_clause
8847          {
8848            Select->context.table_list=
8849              Select->context.first_name_resolution_table=
8850                Select->table_list.first;
8851          }
8852        | FROM DUAL_SYM where_clause opt_limit_clause
8853          /* oracle compatibility: oracle always requires FROM clause,
8854             and DUAL is system table without fields.
8855             Is "SELECT 1 FROM DUAL" any better than "SELECT 1" ?
8856          Hmmm :) */
8857        ;
8858
8859select_options:
8860          /* empty*/
8861        | select_option_list
8862          {
8863            if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL)
8864            {
8865              my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT");
8866              MYSQL_YYABORT;
8867            }
8868          }
8869        ;
8870
8871select_option_list:
8872          select_option_list select_option
8873        | select_option
8874        ;
8875
8876select_option:
8877          query_expression_option
8878        | SQL_NO_CACHE_SYM
8879          {
8880            /*
8881              Allow this flag only on the first top-level SELECT statement, if
8882              SQL_CACHE wasn't specified, and only once per query.
8883             */
8884            if (Lex->current_select != &Lex->select_lex)
8885            {
8886              my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_NO_CACHE");
8887              MYSQL_YYABORT;
8888            }
8889            else if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
8890            {
8891              my_error(ER_WRONG_USAGE, MYF(0), "SQL_CACHE", "SQL_NO_CACHE");
8892              MYSQL_YYABORT;
8893            }
8894            else if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
8895            {
8896              my_error(ER_DUP_ARGUMENT, MYF(0), "SQL_NO_CACHE");
8897              MYSQL_YYABORT;
8898            }
8899            else
8900            {
8901              Lex->safe_to_cache_query=0;
8902              Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
8903              Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
8904            }
8905          }
8906        | SQL_CACHE_SYM
8907          {
8908            /*
8909              Allow this flag only on the first top-level SELECT statement, if
8910              SQL_NO_CACHE wasn't specified, and only once per query.
8911             */
8912            if (Lex->current_select != &Lex->select_lex)
8913            {
8914              my_error(ER_CANT_USE_OPTION_HERE, MYF(0), "SQL_CACHE");
8915              MYSQL_YYABORT;
8916            }
8917            else if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_NO_CACHE)
8918            {
8919              my_error(ER_WRONG_USAGE, MYF(0), "SQL_NO_CACHE", "SQL_CACHE");
8920              MYSQL_YYABORT;
8921            }
8922            else if (Lex->select_lex.sql_cache == SELECT_LEX::SQL_CACHE)
8923            {
8924              my_error(ER_DUP_ARGUMENT, MYF(0), "SQL_CACHE");
8925              MYSQL_YYABORT;
8926            }
8927            else
8928            {
8929              Lex->safe_to_cache_query=1;
8930              Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
8931              Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE;
8932            }
8933          }
8934        ;
8935
8936select_lock_type:
8937          /* empty */
8938        | FOR_SYM UPDATE_SYM
8939          {
8940            LEX *lex=Lex;
8941            if (!lex->describe)
8942            {
8943              lex->current_select->set_lock_for_tables(TL_WRITE);
8944              lex->safe_to_cache_query=0;
8945            }
8946          }
8947        | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
8948          {
8949            LEX *lex=Lex;
8950            if (!lex->describe)
8951            {
8952              lex->current_select->
8953                set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
8954              lex->safe_to_cache_query=0;
8955            }
8956          }
8957        ;
8958
8959select_item_list:
8960          select_item_list ',' select_item
8961        | select_item
8962        | '*'
8963          {
8964            THD *thd= YYTHD;
8965            Item *item= new (thd->mem_root)
8966                          Item_field(&thd->lex->current_select->context,
8967                                     NULL, NULL, "*");
8968            if (item == NULL)
8969              MYSQL_YYABORT;
8970            if (add_item_to_list(thd, item))
8971              MYSQL_YYABORT;
8972            (thd->lex->current_select->with_wild)++;
8973          }
8974        ;
8975
8976select_item:
8977          remember_name table_wild remember_end
8978          {
8979            THD *thd= YYTHD;
8980
8981            if (add_item_to_list(thd, $2))
8982              MYSQL_YYABORT;
8983          }
8984        | remember_name expr remember_end select_alias
8985          {
8986            THD *thd= YYTHD;
8987            DBUG_ASSERT($1 < $3);
8988
8989            if (add_item_to_list(thd, $2))
8990              MYSQL_YYABORT;
8991            if ($4.str)
8992            {
8993              if (Lex->sql_command == SQLCOM_CREATE_VIEW &&
8994                  check_column_name($4.str))
8995              {
8996                my_error(ER_WRONG_COLUMN_NAME, MYF(0), $4.str);
8997                MYSQL_YYABORT;
8998              }
8999              $2->item_name.copy($4.str, $4.length, system_charset_info, false);
9000            }
9001            else if (!$2->item_name.is_set())
9002            {
9003              $2->item_name.copy($1, (uint) ($3 - $1), thd->charset());
9004            }
9005          }
9006        ;
9007
9008remember_name:
9009          {
9010            $$= (char*) YYLIP->get_cpp_tok_start();
9011          }
9012        ;
9013
9014remember_end:
9015          {
9016            $$= (char*) YYLIP->get_cpp_tok_end();
9017          }
9018        ;
9019
9020select_alias:
9021          /* empty */ { $$=null_lex_str;}
9022        | AS ident { $$=$2; }
9023        | AS TEXT_STRING_sys { $$=$2; }
9024        | ident { $$=$1; }
9025        | TEXT_STRING_sys { $$=$1; }
9026        ;
9027
9028optional_braces:
9029          /* empty */ {}
9030        | '(' ')' {}
9031        ;
9032
9033/* all possible expressions */
9034expr:
9035          expr or expr %prec OR_SYM
9036          {
9037            /*
9038              Design notes:
9039              Do not use a manually maintained stack like thd->lex->xxx_list,
9040              but use the internal bison stack ($$, $1 and $3) instead.
9041              Using the bison stack is:
9042              - more robust to changes in the grammar,
9043              - guaranteed to be in sync with the parser state,
9044              - better for performances (no memory allocation).
9045            */
9046            Item_cond_or *item1;
9047            Item_cond_or *item3;
9048            if (is_cond_or($1))
9049            {
9050              item1= (Item_cond_or*) $1;
9051              if (is_cond_or($3))
9052              {
9053                item3= (Item_cond_or*) $3;
9054                /*
9055                  (X1 OR X2) OR (Y1 OR Y2) ==> OR (X1, X2, Y1, Y2)
9056                */
9057                item3->add_at_head(item1->argument_list());
9058                $$ = $3;
9059              }
9060              else
9061              {
9062                /*
9063                  (X1 OR X2) OR Y ==> OR (X1, X2, Y)
9064                */
9065                item1->add($3);
9066                $$ = $1;
9067              }
9068            }
9069            else if (is_cond_or($3))
9070            {
9071              item3= (Item_cond_or*) $3;
9072              /*
9073                X OR (Y1 OR Y2) ==> OR (X, Y1, Y2)
9074              */
9075              item3->add_at_head($1);
9076              $$ = $3;
9077            }
9078            else
9079            {
9080              /* X OR Y */
9081              $$ = new (YYTHD->mem_root) Item_cond_or($1, $3);
9082              if ($$ == NULL)
9083                MYSQL_YYABORT;
9084            }
9085          }
9086        | expr XOR expr %prec XOR
9087          {
9088            /* XOR is a proprietary extension */
9089            $$ = new (YYTHD->mem_root) Item_func_xor($1, $3);
9090            if ($$ == NULL)
9091              MYSQL_YYABORT;
9092          }
9093        | expr and expr %prec AND_SYM
9094          {
9095            /* See comments in rule expr: expr or expr */
9096            Item_cond_and *item1;
9097            Item_cond_and *item3;
9098            if (is_cond_and($1))
9099            {
9100              item1= (Item_cond_and*) $1;
9101              if (is_cond_and($3))
9102              {
9103                item3= (Item_cond_and*) $3;
9104                /*
9105                  (X1 AND X2) AND (Y1 AND Y2) ==> AND (X1, X2, Y1, Y2)
9106                */
9107                item3->add_at_head(item1->argument_list());
9108                $$ = $3;
9109              }
9110              else
9111              {
9112                /*
9113                  (X1 AND X2) AND Y ==> AND (X1, X2, Y)
9114                */
9115                item1->add($3);
9116                $$ = $1;
9117              }
9118            }
9119            else if (is_cond_and($3))
9120            {
9121              item3= (Item_cond_and*) $3;
9122              /*
9123                X AND (Y1 AND Y2) ==> AND (X, Y1, Y2)
9124              */
9125              item3->add_at_head($1);
9126              $$ = $3;
9127            }
9128            else
9129            {
9130              /* X AND Y */
9131              $$ = new (YYTHD->mem_root) Item_cond_and($1, $3);
9132              if ($$ == NULL)
9133                MYSQL_YYABORT;
9134            }
9135          }
9136        | NOT_SYM expr %prec NOT_SYM
9137          {
9138            $$= negate_expression(YYTHD, $2);
9139            if ($$ == NULL)
9140              MYSQL_YYABORT;
9141          }
9142        | bool_pri IS TRUE_SYM %prec IS
9143          {
9144            $$= new (YYTHD->mem_root) Item_func_istrue($1);
9145            if ($$ == NULL)
9146              MYSQL_YYABORT;
9147          }
9148        | bool_pri IS not TRUE_SYM %prec IS
9149          {
9150            $$= new (YYTHD->mem_root) Item_func_isnottrue($1);
9151            if ($$ == NULL)
9152              MYSQL_YYABORT;
9153          }
9154        | bool_pri IS FALSE_SYM %prec IS
9155          {
9156            $$= new (YYTHD->mem_root) Item_func_isfalse($1);
9157            if ($$ == NULL)
9158              MYSQL_YYABORT;
9159          }
9160        | bool_pri IS not FALSE_SYM %prec IS
9161          {
9162            $$= new (YYTHD->mem_root) Item_func_isnotfalse($1);
9163            if ($$ == NULL)
9164              MYSQL_YYABORT;
9165          }
9166        | bool_pri IS UNKNOWN_SYM %prec IS
9167          {
9168            $$= new (YYTHD->mem_root) Item_func_isnull($1);
9169            if ($$ == NULL)
9170              MYSQL_YYABORT;
9171          }
9172        | bool_pri IS not UNKNOWN_SYM %prec IS
9173          {
9174            $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
9175            if ($$ == NULL)
9176              MYSQL_YYABORT;
9177          }
9178        | bool_pri
9179        ;
9180
9181bool_pri:
9182          bool_pri IS NULL_SYM %prec IS
9183          {
9184            $$= new (YYTHD->mem_root) Item_func_isnull($1);
9185            if ($$ == NULL)
9186              MYSQL_YYABORT;
9187          }
9188        | bool_pri IS not NULL_SYM %prec IS
9189          {
9190            $$= new (YYTHD->mem_root) Item_func_isnotnull($1);
9191            if ($$ == NULL)
9192              MYSQL_YYABORT;
9193          }
9194        | bool_pri EQUAL_SYM predicate %prec EQUAL_SYM
9195          {
9196            $$= new (YYTHD->mem_root) Item_func_equal($1,$3);
9197            if ($$ == NULL)
9198              MYSQL_YYABORT;
9199          }
9200        | bool_pri comp_op predicate %prec EQ
9201          {
9202            $$= (*$2)(0)->create($1,$3);
9203            if ($$ == NULL)
9204              MYSQL_YYABORT;
9205          }
9206        | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
9207          {
9208            $$= all_any_subquery_creator($1, $2, $3, $5);
9209            if ($$ == NULL)
9210              MYSQL_YYABORT;
9211          }
9212        | predicate
9213        ;
9214
9215predicate:
9216          bit_expr IN_SYM '(' subselect ')'
9217          {
9218            $$= new (YYTHD->mem_root) Item_in_subselect($1, $4);
9219            if ($$ == NULL)
9220              MYSQL_YYABORT;
9221          }
9222        | bit_expr not IN_SYM '(' subselect ')'
9223          {
9224            THD *thd= YYTHD;
9225            Item *item= new (thd->mem_root) Item_in_subselect($1, $5);
9226            if (item == NULL)
9227              MYSQL_YYABORT;
9228            $$= negate_expression(thd, item);
9229            if ($$ == NULL)
9230              MYSQL_YYABORT;
9231          }
9232        | bit_expr IN_SYM '(' expr ')'
9233          {
9234            $$= handle_sql2003_note184_exception(YYTHD, $1, true, $4);
9235            if ($$ == NULL)
9236              MYSQL_YYABORT;
9237          }
9238        | bit_expr IN_SYM '(' expr ',' expr_list ')'
9239          {
9240            $6->push_front($4);
9241            $6->push_front($1);
9242            $$= new (YYTHD->mem_root) Item_func_in(*$6);
9243            if ($$ == NULL)
9244              MYSQL_YYABORT;
9245          }
9246        | bit_expr not IN_SYM '(' expr ')'
9247          {
9248            $$= handle_sql2003_note184_exception(YYTHD, $1, false, $5);
9249            if ($$ == NULL)
9250              MYSQL_YYABORT;
9251          }
9252        | bit_expr not IN_SYM '(' expr ',' expr_list ')'
9253          {
9254            $7->push_front($5);
9255            $7->push_front($1);
9256            Item_func_in *item = new (YYTHD->mem_root) Item_func_in(*$7);
9257            if (item == NULL)
9258              MYSQL_YYABORT;
9259            item->negate();
9260            $$= item;
9261          }
9262        | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
9263          {
9264            $$= new (YYTHD->mem_root) Item_func_between($1,$3,$5);
9265            if ($$ == NULL)
9266              MYSQL_YYABORT;
9267          }
9268        | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
9269          {
9270            Item_func_between *item;
9271            item= new (YYTHD->mem_root) Item_func_between($1,$4,$6);
9272            if (item == NULL)
9273              MYSQL_YYABORT;
9274            item->negate();
9275            $$= item;
9276          }
9277        | bit_expr SOUNDS_SYM LIKE bit_expr
9278          {
9279            Item *item1= new (YYTHD->mem_root) Item_func_soundex($1);
9280            Item *item4= new (YYTHD->mem_root) Item_func_soundex($4);
9281            if ((item1 == NULL) || (item4 == NULL))
9282              MYSQL_YYABORT;
9283            $$= new (YYTHD->mem_root) Item_func_eq(item1, item4);
9284            if ($$ == NULL)
9285              MYSQL_YYABORT;
9286          }
9287        | bit_expr LIKE simple_expr opt_escape
9288          {
9289            $$= new (YYTHD->mem_root) Item_func_like($1,$3,$4,Lex->escape_used);
9290            if ($$ == NULL)
9291              MYSQL_YYABORT;
9292          }
9293        | bit_expr not LIKE simple_expr opt_escape
9294          {
9295            Item *item= new (YYTHD->mem_root) Item_func_like($1,$4,$5,
9296                                                             Lex->escape_used);
9297            if (item == NULL)
9298              MYSQL_YYABORT;
9299            $$= new (YYTHD->mem_root) Item_func_not(item);
9300            if ($$ == NULL)
9301              MYSQL_YYABORT;
9302          }
9303        | bit_expr REGEXP bit_expr
9304          {
9305            $$= new (YYTHD->mem_root) Item_func_regex($1,$3);
9306            if ($$ == NULL)
9307              MYSQL_YYABORT;
9308          }
9309        | bit_expr not REGEXP bit_expr
9310          {
9311            Item *item= new (YYTHD->mem_root) Item_func_regex($1,$4);
9312            if (item == NULL)
9313              MYSQL_YYABORT;
9314            $$= negate_expression(YYTHD, item);
9315            if ($$ == NULL)
9316              MYSQL_YYABORT;
9317          }
9318        | bit_expr
9319        ;
9320
9321bit_expr:
9322          bit_expr '|' bit_expr %prec '|'
9323          {
9324            $$= new (YYTHD->mem_root) Item_func_bit_or($1,$3);
9325            if ($$ == NULL)
9326              MYSQL_YYABORT;
9327          }
9328        | bit_expr '&' bit_expr %prec '&'
9329          {
9330            $$= new (YYTHD->mem_root) Item_func_bit_and($1,$3);
9331            if ($$ == NULL)
9332              MYSQL_YYABORT;
9333          }
9334        | bit_expr SHIFT_LEFT bit_expr %prec SHIFT_LEFT
9335          {
9336            $$= new (YYTHD->mem_root) Item_func_shift_left($1,$3);
9337            if ($$ == NULL)
9338              MYSQL_YYABORT;
9339          }
9340        | bit_expr SHIFT_RIGHT bit_expr %prec SHIFT_RIGHT
9341          {
9342            $$= new (YYTHD->mem_root) Item_func_shift_right($1,$3);
9343            if ($$ == NULL)
9344              MYSQL_YYABORT;
9345          }
9346        | bit_expr '+' bit_expr %prec '+'
9347          {
9348            $$= new (YYTHD->mem_root) Item_func_plus($1,$3);
9349            if ($$ == NULL)
9350              MYSQL_YYABORT;
9351          }
9352        | bit_expr '-' bit_expr %prec '-'
9353          {
9354            $$= new (YYTHD->mem_root) Item_func_minus($1,$3);
9355            if ($$ == NULL)
9356              MYSQL_YYABORT;
9357          }
9358        | bit_expr '+' INTERVAL_SYM expr interval %prec '+'
9359          {
9360            $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,0);
9361            if ($$ == NULL)
9362              MYSQL_YYABORT;
9363          }
9364        | bit_expr '-' INTERVAL_SYM expr interval %prec '-'
9365          {
9366            $$= new (YYTHD->mem_root) Item_date_add_interval($1,$4,$5,1);
9367            if ($$ == NULL)
9368              MYSQL_YYABORT;
9369          }
9370        | bit_expr '*' bit_expr %prec '*'
9371          {
9372            $$= new (YYTHD->mem_root) Item_func_mul($1,$3);
9373            if ($$ == NULL)
9374              MYSQL_YYABORT;
9375          }
9376        | bit_expr '/' bit_expr %prec '/'
9377          {
9378            $$= new (YYTHD->mem_root) Item_func_div($1,$3);
9379            if ($$ == NULL)
9380              MYSQL_YYABORT;
9381          }
9382        | bit_expr '%' bit_expr %prec '%'
9383          {
9384            $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
9385            if ($$ == NULL)
9386              MYSQL_YYABORT;
9387          }
9388        | bit_expr DIV_SYM bit_expr %prec DIV_SYM
9389          {
9390            $$= new (YYTHD->mem_root) Item_func_int_div($1,$3);
9391            if ($$ == NULL)
9392              MYSQL_YYABORT;
9393          }
9394        | bit_expr MOD_SYM bit_expr %prec MOD_SYM
9395          {
9396            $$= new (YYTHD->mem_root) Item_func_mod($1,$3);
9397            if ($$ == NULL)
9398              MYSQL_YYABORT;
9399          }
9400        | bit_expr '^' bit_expr
9401          {
9402            $$= new (YYTHD->mem_root) Item_func_bit_xor($1,$3);
9403            if ($$ == NULL)
9404              MYSQL_YYABORT;
9405          }
9406        | simple_expr
9407        ;
9408
9409or:
9410          OR_SYM
9411       | OR2_SYM
9412       ;
9413
9414and:
9415          AND_SYM
9416       | AND_AND_SYM
9417       ;
9418
9419not:
9420          NOT_SYM
9421        | NOT2_SYM
9422        ;
9423
9424not2:
9425          '!'
9426        | NOT2_SYM
9427        ;
9428
9429comp_op:
9430          EQ     { $$ = &comp_eq_creator; }
9431        | GE     { $$ = &comp_ge_creator; }
9432        | GT_SYM { $$ = &comp_gt_creator; }
9433        | LE     { $$ = &comp_le_creator; }
9434        | LT     { $$ = &comp_lt_creator; }
9435        | NE     { $$ = &comp_ne_creator; }
9436        ;
9437
9438all_or_any:
9439          ALL     { $$ = 1; }
9440        | ANY_SYM { $$ = 0; }
9441        ;
9442
9443simple_expr:
9444          simple_ident
9445        | function_call_keyword
9446        | function_call_nonkeyword
9447        | function_call_generic
9448        | function_call_conflict
9449        | simple_expr COLLATE_SYM ident_or_text %prec NEG
9450          {
9451            THD *thd= YYTHD;
9452            Item *i1= new (thd->mem_root) Item_string($3.str,
9453                                                      $3.length,
9454                                                      thd->charset());
9455            if (i1 == NULL)
9456              MYSQL_YYABORT;
9457            $$= new (thd->mem_root) Item_func_set_collation($1, i1);
9458            if ($$ == NULL)
9459              MYSQL_YYABORT;
9460          }
9461        | literal
9462        | param_marker
9463        | variable
9464        | sum_expr
9465        | simple_expr OR_OR_SYM simple_expr
9466          {
9467            $$= new (YYTHD->mem_root) Item_func_concat($1, $3);
9468            if ($$ == NULL)
9469              MYSQL_YYABORT;
9470          }
9471        | '+' simple_expr %prec NEG
9472          {
9473            $$= $2;
9474          }
9475        | '-' simple_expr %prec NEG
9476          {
9477            $$= new (YYTHD->mem_root) Item_func_neg($2);
9478            if ($$ == NULL)
9479              MYSQL_YYABORT;
9480          }
9481        | '~' simple_expr %prec NEG
9482          {
9483            $$= new (YYTHD->mem_root) Item_func_bit_neg($2);
9484            if ($$ == NULL)
9485              MYSQL_YYABORT;
9486          }
9487        | not2 simple_expr %prec NEG
9488          {
9489            $$= negate_expression(YYTHD, $2);
9490            if ($$ == NULL)
9491              MYSQL_YYABORT;
9492          }
9493        | '(' subselect ')'
9494          {
9495            $$= new (YYTHD->mem_root) Item_singlerow_subselect($2);
9496            if ($$ == NULL)
9497              MYSQL_YYABORT;
9498          }
9499        | '(' expr ')'
9500          { $$= $2; }
9501        | '(' expr ',' expr_list ')'
9502          {
9503            $4->push_front($2);
9504            $$= new (YYTHD->mem_root) Item_row(*$4);
9505            if ($$ == NULL)
9506              MYSQL_YYABORT;
9507          }
9508        | ROW_SYM '(' expr ',' expr_list ')'
9509          {
9510            $5->push_front($3);
9511            $$= new (YYTHD->mem_root) Item_row(*$5);
9512            if ($$ == NULL)
9513              MYSQL_YYABORT;
9514          }
9515        | EXISTS '(' subselect ')'
9516          {
9517            $$= new (YYTHD->mem_root) Item_exists_subselect($3);
9518            if ($$ == NULL)
9519              MYSQL_YYABORT;
9520          }
9521        | '{' ident expr '}'
9522          {
9523            Item_string *item;
9524            $$= NULL;
9525            /*
9526              If "expr" is reasonably short pure ASCII string literal,
9527              try to parse known ODBC style date, time or timestamp literals,
9528              e.g:
9529              SELECT {d'2001-01-01'};
9530              SELECT {t'10:20:30'};
9531              SELECT {ts'2001-01-01 10:20:30'};
9532            */
9533            if ($3->type() == Item::STRING_ITEM &&
9534               (item= (Item_string *) $3) &&
9535                item->collation.repertoire == MY_REPERTOIRE_ASCII &&
9536                item->str_value.length() < MAX_DATE_STRING_REP_LENGTH * 4)
9537            {
9538              enum_field_types type= MYSQL_TYPE_STRING;
9539              ErrConvString str(&item->str_value);
9540              LEX_STRING *ls= &$2;
9541              if (ls->length == 1)
9542              {
9543                if (ls->str[0] == 'd')  /* {d'2001-01-01'} */
9544                  type= MYSQL_TYPE_DATE;
9545                else if (ls->str[0] == 't') /* {t'10:20:30'} */
9546                  type= MYSQL_TYPE_TIME;
9547              }
9548              else if (ls->length == 2) /* {ts'2001-01-01 10:20:30'} */
9549              {
9550                if (ls->str[0] == 't' && ls->str[1] == 's')
9551                  type= MYSQL_TYPE_DATETIME;
9552              }
9553              if (type != MYSQL_TYPE_STRING)
9554                $$= create_temporal_literal(YYTHD,
9555                                            str.ptr(), str.length(),
9556                                            system_charset_info,
9557                                            type, false);
9558            }
9559            if ($$ == NULL)
9560              $$= $3;
9561          }
9562        | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
9563          {
9564            $2->push_front($5);
9565            Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6);
9566            if (i1 == NULL)
9567              MYSQL_YYABORT;
9568            Select->add_ftfunc_to_list(i1);
9569            $$= i1;
9570          }
9571        | BINARY simple_expr %prec NEG
9572          {
9573            $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, NULL, NULL,
9574                                 &my_charset_bin);
9575            if ($$ == NULL)
9576              MYSQL_YYABORT;
9577          }
9578        | CAST_SYM '(' expr AS cast_type ')'
9579          {
9580            LEX *lex= Lex;
9581            $$= create_func_cast(YYTHD, $3, $5, lex->length, lex->dec,
9582                                 lex->charset);
9583            if ($$ == NULL)
9584              MYSQL_YYABORT;
9585          }
9586        | CASE_SYM opt_expr when_list opt_else END
9587          {
9588            $$= new (YYTHD->mem_root) Item_func_case(* $3, $2, $4 );
9589            if ($$ == NULL)
9590              MYSQL_YYABORT;
9591          }
9592        | CONVERT_SYM '(' expr ',' cast_type ')'
9593          {
9594            $$= create_func_cast(YYTHD, $3, $5, Lex->length, Lex->dec,
9595                                 Lex->charset);
9596            if ($$ == NULL)
9597              MYSQL_YYABORT;
9598          }
9599        | CONVERT_SYM '(' expr USING charset_name ')'
9600          {
9601            $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5);
9602            if ($$ == NULL)
9603              MYSQL_YYABORT;
9604          }
9605        | DEFAULT '(' simple_ident ')'
9606          {
9607            if ($3->is_splocal())
9608            {
9609              Item_splocal *il= static_cast<Item_splocal *>($3);
9610
9611              my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->m_name.ptr());
9612              MYSQL_YYABORT;
9613            }
9614            $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
9615                                                         $3);
9616            if ($$ == NULL)
9617              MYSQL_YYABORT;
9618          }
9619        | VALUES '(' simple_ident_nospvar ')'
9620          {
9621            $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(),
9622                                                        $3);
9623            if ($$ == NULL)
9624              MYSQL_YYABORT;
9625          }
9626        | INTERVAL_SYM expr interval '+' expr %prec INTERVAL_SYM
9627          /* we cannot put interval before - */
9628          {
9629            $$= new (YYTHD->mem_root) Item_date_add_interval($5,$2,$3,0);
9630            if ($$ == NULL)
9631              MYSQL_YYABORT;
9632          }
9633        ;
9634
9635/*
9636  Function call syntax using official SQL 2003 keywords.
9637  Because the function name is an official token,
9638  a dedicated grammar rule is needed in the parser.
9639  There is no potential for conflicts
9640*/
9641function_call_keyword:
9642          CHAR_SYM '(' expr_list ')'
9643          {
9644            $$= new (YYTHD->mem_root) Item_func_char(*$3);
9645            if ($$ == NULL)
9646              MYSQL_YYABORT;
9647          }
9648        | CHAR_SYM '(' expr_list USING charset_name ')'
9649          {
9650            $$= new (YYTHD->mem_root) Item_func_char(*$3, $5);
9651            if ($$ == NULL)
9652              MYSQL_YYABORT;
9653          }
9654        | CURRENT_USER optional_braces
9655          {
9656            $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
9657            if ($$ == NULL)
9658              MYSQL_YYABORT;
9659            Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
9660            Lex->safe_to_cache_query= 0;
9661          }
9662        | DATE_SYM '(' expr ')'
9663          {
9664            $$= new (YYTHD->mem_root) Item_date_typecast($3);
9665            if ($$ == NULL)
9666              MYSQL_YYABORT;
9667          }
9668        | DAY_SYM '(' expr ')'
9669          {
9670            $$= new (YYTHD->mem_root) Item_func_dayofmonth($3);
9671            if ($$ == NULL)
9672              MYSQL_YYABORT;
9673          }
9674        | HOUR_SYM '(' expr ')'
9675          {
9676            $$= new (YYTHD->mem_root) Item_func_hour($3);
9677            if ($$ == NULL)
9678              MYSQL_YYABORT;
9679          }
9680        | INSERT '(' expr ',' expr ',' expr ',' expr ')'
9681          {
9682            $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9);
9683            if ($$ == NULL)
9684              MYSQL_YYABORT;
9685          }
9686        | INTERVAL_SYM '(' expr ',' expr ')' %prec INTERVAL_SYM
9687          {
9688            THD *thd= YYTHD;
9689            List<Item> *list= new (thd->mem_root) List<Item>;
9690            if (list == NULL)
9691              MYSQL_YYABORT;
9692            list->push_front($5);
9693            list->push_front($3);
9694            Item_row *item= new (thd->mem_root) Item_row(*list);
9695            if (item == NULL)
9696              MYSQL_YYABORT;
9697            $$= new (thd->mem_root) Item_func_interval(item);
9698            if ($$ == NULL)
9699              MYSQL_YYABORT;
9700          }
9701        | INTERVAL_SYM '(' expr ',' expr ',' expr_list ')' %prec INTERVAL_SYM
9702          {
9703            THD *thd= YYTHD;
9704            $7->push_front($5);
9705            $7->push_front($3);
9706            Item_row *item= new (thd->mem_root) Item_row(*$7);
9707            if (item == NULL)
9708              MYSQL_YYABORT;
9709            $$= new (thd->mem_root) Item_func_interval(item);
9710            if ($$ == NULL)
9711              MYSQL_YYABORT;
9712          }
9713        | LEFT '(' expr ',' expr ')'
9714          {
9715            $$= new (YYTHD->mem_root) Item_func_left($3,$5);
9716            if ($$ == NULL)
9717              MYSQL_YYABORT;
9718          }
9719        | MINUTE_SYM '(' expr ')'
9720          {
9721            $$= new (YYTHD->mem_root) Item_func_minute($3);
9722            if ($$ == NULL)
9723              MYSQL_YYABORT;
9724          }
9725        | MONTH_SYM '(' expr ')'
9726          {
9727            $$= new (YYTHD->mem_root) Item_func_month($3);
9728            if ($$ == NULL)
9729              MYSQL_YYABORT;
9730          }
9731        | RIGHT '(' expr ',' expr ')'
9732          {
9733            $$= new (YYTHD->mem_root) Item_func_right($3,$5);
9734            if ($$ == NULL)
9735              MYSQL_YYABORT;
9736          }
9737        | SECOND_SYM '(' expr ')'
9738          {
9739            $$= new (YYTHD->mem_root) Item_func_second($3);
9740            if ($$ == NULL)
9741              MYSQL_YYABORT;
9742          }
9743        | TIME_SYM '(' expr ')'
9744          {
9745            $$= new (YYTHD->mem_root) Item_time_typecast($3);
9746            if ($$ == NULL)
9747              MYSQL_YYABORT;
9748          }
9749        | TIMESTAMP '(' expr ')'
9750          {
9751            $$= new (YYTHD->mem_root) Item_datetime_typecast($3);
9752            if ($$ == NULL)
9753              MYSQL_YYABORT;
9754          }
9755        | TIMESTAMP '(' expr ',' expr ')'
9756          {
9757            $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0);
9758            if ($$ == NULL)
9759              MYSQL_YYABORT;
9760          }
9761        | TRIM '(' expr ')'
9762          {
9763            $$= new (YYTHD->mem_root) Item_func_trim($3);
9764            if ($$ == NULL)
9765              MYSQL_YYABORT;
9766          }
9767        | TRIM '(' LEADING expr FROM expr ')'
9768          {
9769            $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4);
9770            if ($$ == NULL)
9771              MYSQL_YYABORT;
9772          }
9773        | TRIM '(' TRAILING expr FROM expr ')'
9774          {
9775            $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4);
9776            if ($$ == NULL)
9777              MYSQL_YYABORT;
9778          }
9779        | TRIM '(' BOTH expr FROM expr ')'
9780          {
9781            $$= new (YYTHD->mem_root) Item_func_trim($6,$4);
9782            if ($$ == NULL)
9783              MYSQL_YYABORT;
9784          }
9785        | TRIM '(' LEADING FROM expr ')'
9786          {
9787            $$= new (YYTHD->mem_root) Item_func_ltrim($5);
9788            if ($$ == NULL)
9789              MYSQL_YYABORT;
9790          }
9791        | TRIM '(' TRAILING FROM expr ')'
9792          {
9793            $$= new (YYTHD->mem_root) Item_func_rtrim($5);
9794            if ($$ == NULL)
9795              MYSQL_YYABORT;
9796          }
9797        | TRIM '(' BOTH FROM expr ')'
9798          {
9799            $$= new (YYTHD->mem_root) Item_func_trim($5);
9800            if ($$ == NULL)
9801              MYSQL_YYABORT;
9802          }
9803        | TRIM '(' expr FROM expr ')'
9804          {
9805            $$= new (YYTHD->mem_root) Item_func_trim($5,$3);
9806            if ($$ == NULL)
9807              MYSQL_YYABORT;
9808          }
9809        | USER '(' ')'
9810          {
9811            $$= new (YYTHD->mem_root) Item_func_user();
9812            if ($$ == NULL)
9813              MYSQL_YYABORT;
9814            Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
9815            Lex->safe_to_cache_query=0;
9816          }
9817        | YEAR_SYM '(' expr ')'
9818          {
9819            $$= new (YYTHD->mem_root) Item_func_year($3);
9820            if ($$ == NULL)
9821              MYSQL_YYABORT;
9822          }
9823        ;
9824
9825/*
9826  Function calls using non reserved keywords, with special syntaxic forms.
9827  Dedicated grammar rules are needed because of the syntax,
9828  but also have the potential to cause incompatibilities with other
9829  parts of the language.
9830  MAINTAINER:
9831  The only reasons a function should be added here are:
9832  - for compatibility reasons with another SQL syntax (CURDATE),
9833  - for typing reasons (GET_FORMAT)
9834  Any other 'Syntaxic sugar' enhancements should be *STRONGLY*
9835  discouraged.
9836*/
9837function_call_nonkeyword:
9838          ADDDATE_SYM '(' expr ',' expr ')'
9839          {
9840            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
9841                                                             INTERVAL_DAY, 0);
9842            if ($$ == NULL)
9843              MYSQL_YYABORT;
9844          }
9845        | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
9846          {
9847            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0);
9848            if ($$ == NULL)
9849              MYSQL_YYABORT;
9850          }
9851        | CURDATE optional_braces
9852          {
9853            $$= new (YYTHD->mem_root) Item_func_curdate_local();
9854            if ($$ == NULL)
9855              MYSQL_YYABORT;
9856            Lex->safe_to_cache_query=0;
9857          }
9858        | CURTIME func_datetime_precision
9859          {
9860            $$= new (YYTHD->mem_root) Item_func_curtime_local($2);
9861            if ($$ == NULL)
9862              MYSQL_YYABORT;
9863            Lex->safe_to_cache_query=0;
9864          }
9865        | DATE_ADD_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
9866          %prec INTERVAL_SYM
9867          {
9868            $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,0);
9869            if ($$ == NULL)
9870              MYSQL_YYABORT;
9871          }
9872        | DATE_SUB_INTERVAL '(' expr ',' INTERVAL_SYM expr interval ')'
9873          %prec INTERVAL_SYM
9874          {
9875            $$= new (YYTHD->mem_root) Item_date_add_interval($3,$6,$7,1);
9876            if ($$ == NULL)
9877              MYSQL_YYABORT;
9878          }
9879        | EXTRACT_SYM '(' interval FROM expr ')'
9880          {
9881            $$=new (YYTHD->mem_root) Item_extract( $3, $5);
9882            if ($$ == NULL)
9883              MYSQL_YYABORT;
9884          }
9885        | GET_FORMAT '(' date_time_type  ',' expr ')'
9886          {
9887            $$= new (YYTHD->mem_root) Item_func_get_format($3, $5);
9888            if ($$ == NULL)
9889              MYSQL_YYABORT;
9890          }
9891        | now
9892          {
9893            $$= $1;
9894            Lex->safe_to_cache_query= 0;
9895          }
9896        | POSITION_SYM '(' bit_expr IN_SYM expr ')'
9897          {
9898            $$ = new (YYTHD->mem_root) Item_func_locate($5,$3);
9899            if ($$ == NULL)
9900              MYSQL_YYABORT;
9901          }
9902        | SUBDATE_SYM '(' expr ',' expr ')'
9903          {
9904            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
9905                                                             INTERVAL_DAY, 1);
9906            if ($$ == NULL)
9907              MYSQL_YYABORT;
9908          }
9909        | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
9910          {
9911            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1);
9912            if ($$ == NULL)
9913              MYSQL_YYABORT;
9914          }
9915        | SUBSTRING '(' expr ',' expr ',' expr ')'
9916          {
9917            $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
9918            if ($$ == NULL)
9919              MYSQL_YYABORT;
9920          }
9921        | SUBSTRING '(' expr ',' expr ')'
9922          {
9923            $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
9924            if ($$ == NULL)
9925              MYSQL_YYABORT;
9926          }
9927        | SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
9928          {
9929            $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7);
9930            if ($$ == NULL)
9931              MYSQL_YYABORT;
9932          }
9933        | SUBSTRING '(' expr FROM expr ')'
9934          {
9935            $$= new (YYTHD->mem_root) Item_func_substr($3,$5);
9936            if ($$ == NULL)
9937              MYSQL_YYABORT;
9938          }
9939        | SYSDATE func_datetime_precision
9940          {
9941            /*
9942              Unlike other time-related functions, SYSDATE() is
9943              replication-unsafe because it is not affected by the
9944              TIMESTAMP variable.  It is unsafe even if
9945              sysdate_is_now=1, because the slave may have
9946              sysdate_is_now=0.
9947            */
9948            Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
9949            if (global_system_variables.sysdate_is_now == 0)
9950              $$= new (YYTHD->mem_root) Item_func_sysdate_local($2);
9951            else
9952              $$= new (YYTHD->mem_root) Item_func_now_local($2);
9953            if ($$ == NULL)
9954              MYSQL_YYABORT;
9955            Lex->safe_to_cache_query=0;
9956          }
9957        | TIMESTAMP_ADD '(' interval_time_stamp ',' expr ',' expr ')'
9958          {
9959            $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0);
9960            if ($$ == NULL)
9961              MYSQL_YYABORT;
9962          }
9963        | TIMESTAMP_DIFF '(' interval_time_stamp ',' expr ',' expr ')'
9964          {
9965            $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3);
9966            if ($$ == NULL)
9967              MYSQL_YYABORT;
9968          }
9969        | UTC_DATE_SYM optional_braces
9970          {
9971            $$= new (YYTHD->mem_root) Item_func_curdate_utc();
9972            if ($$ == NULL)
9973              MYSQL_YYABORT;
9974            Lex->safe_to_cache_query=0;
9975          }
9976        | UTC_TIME_SYM func_datetime_precision
9977          {
9978            $$= new (YYTHD->mem_root) Item_func_curtime_utc($2);
9979            if ($$ == NULL)
9980              MYSQL_YYABORT;
9981            Lex->safe_to_cache_query=0;
9982          }
9983        | UTC_TIMESTAMP_SYM func_datetime_precision
9984          {
9985            $$= new (YYTHD->mem_root) Item_func_now_utc($2);
9986            if ($$ == NULL)
9987              MYSQL_YYABORT;
9988            Lex->safe_to_cache_query=0;
9989          }
9990        ;
9991
9992/*
9993  Functions calls using a non reserved keyword, and using a regular syntax.
9994  Because the non reserved keyword is used in another part of the grammar,
9995  a dedicated rule is needed here.
9996*/
9997function_call_conflict:
9998          ASCII_SYM '(' expr ')'
9999          {
10000            $$= new (YYTHD->mem_root) Item_func_ascii($3);
10001            if ($$ == NULL)
10002              MYSQL_YYABORT;
10003          }
10004        | CHARSET '(' expr ')'
10005          {
10006            $$= new (YYTHD->mem_root) Item_func_charset($3);
10007            if ($$ == NULL)
10008              MYSQL_YYABORT;
10009          }
10010        | COALESCE '(' expr_list ')'
10011          {
10012            $$= new (YYTHD->mem_root) Item_func_coalesce(* $3);
10013            if ($$ == NULL)
10014              MYSQL_YYABORT;
10015          }
10016        | COLLATION_SYM '(' expr ')'
10017          {
10018            $$= new (YYTHD->mem_root) Item_func_collation($3);
10019            if ($$ == NULL)
10020              MYSQL_YYABORT;
10021          }
10022        | DATABASE '(' ')'
10023          {
10024            $$= new (YYTHD->mem_root) Item_func_database();
10025            if ($$ == NULL)
10026              MYSQL_YYABORT;
10027            Lex->safe_to_cache_query=0;
10028          }
10029        | IF '(' expr ',' expr ',' expr ')'
10030          {
10031            $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7);
10032            if ($$ == NULL)
10033              MYSQL_YYABORT;
10034          }
10035        | FORMAT_SYM '(' expr ',' expr ')'
10036          {
10037            $$= new (YYTHD->mem_root) Item_func_format($3, $5);
10038            if ($$ == NULL)
10039              MYSQL_YYABORT;
10040          }
10041        | FORMAT_SYM '(' expr ',' expr ',' expr ')'
10042          {
10043            $$= new (YYTHD->mem_root) Item_func_format($3, $5, $7);
10044            if ($$ == NULL)
10045              MYSQL_YYABORT;
10046          }
10047        | MICROSECOND_SYM '(' expr ')'
10048          {
10049            $$= new (YYTHD->mem_root) Item_func_microsecond($3);
10050            if ($$ == NULL)
10051              MYSQL_YYABORT;
10052          }
10053        | MOD_SYM '(' expr ',' expr ')'
10054          {
10055            $$ = new (YYTHD->mem_root) Item_func_mod($3, $5);
10056            if ($$ == NULL)
10057              MYSQL_YYABORT;
10058          }
10059        | OLD_PASSWORD '(' expr ')'
10060          {
10061            WARN_DEPRECATED(YYTHD, "OLD_PASSWORD", "PASSWORD");
10062            $$=  new (YYTHD->mem_root) Item_func_old_password($3);
10063            Lex->contains_plaintext_password= true;
10064            if ($$ == NULL)
10065              MYSQL_YYABORT;
10066          }
10067        | PASSWORD '(' expr ')'
10068          {
10069            THD *thd= YYTHD;
10070            Item* i1;
10071            Lex->contains_plaintext_password= true;
10072            if (thd->variables.old_passwords == 1)
10073              i1= new (thd->mem_root) Item_func_old_password($3);
10074            else
10075              i1= new (thd->mem_root) Item_func_password($3);
10076            if (i1 == NULL)
10077              MYSQL_YYABORT;
10078            $$= i1;
10079          }
10080        | QUARTER_SYM '(' expr ')'
10081          {
10082            $$ = new (YYTHD->mem_root) Item_func_quarter($3);
10083            if ($$ == NULL)
10084              MYSQL_YYABORT;
10085          }
10086        | REPEAT_SYM '(' expr ',' expr ')'
10087          {
10088            $$= new (YYTHD->mem_root) Item_func_repeat($3,$5);
10089            if ($$ == NULL)
10090              MYSQL_YYABORT;
10091          }
10092        | REPLACE '(' expr ',' expr ',' expr ')'
10093          {
10094            $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7);
10095            if ($$ == NULL)
10096              MYSQL_YYABORT;
10097          }
10098        | REVERSE_SYM '(' expr ')'
10099          {
10100            $$= new (YYTHD->mem_root) Item_func_reverse($3);
10101            if ($$ == NULL)
10102              MYSQL_YYABORT;
10103          }
10104        | ROW_COUNT_SYM '(' ')'
10105          {
10106            $$= new (YYTHD->mem_root) Item_func_row_count();
10107            if ($$ == NULL)
10108              MYSQL_YYABORT;
10109            Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
10110            Lex->safe_to_cache_query= 0;
10111          }
10112        | TRUNCATE_SYM '(' expr ',' expr ')'
10113          {
10114            $$= new (YYTHD->mem_root) Item_func_round($3,$5,1);
10115            if ($$ == NULL)
10116              MYSQL_YYABORT;
10117          }
10118        | WEEK_SYM '(' expr ')'
10119          {
10120            THD *thd= YYTHD;
10121            Item *i1= new (thd->mem_root) Item_int(NAME_STRING("0"),
10122                                           thd->variables.default_week_format,
10123                                                   1);
10124            if (i1 == NULL)
10125              MYSQL_YYABORT;
10126            $$= new (thd->mem_root) Item_func_week($3, i1);
10127            if ($$ == NULL)
10128              MYSQL_YYABORT;
10129          }
10130        | WEEK_SYM '(' expr ',' expr ')'
10131          {
10132            $$= new (YYTHD->mem_root) Item_func_week($3,$5);
10133            if ($$ == NULL)
10134              MYSQL_YYABORT;
10135          }
10136        | WEIGHT_STRING_SYM '(' expr opt_ws_levels ')'
10137          {
10138            $$= new (YYTHD->mem_root) Item_func_weight_string($3, 0, 0, $4);
10139            if ($$ == NULL)
10140              MYSQL_YYABORT;
10141          }
10142        | WEIGHT_STRING_SYM '(' expr AS CHAR_SYM ws_nweights opt_ws_levels ')'
10143          {
10144            $$= new (YYTHD->mem_root)
10145                Item_func_weight_string($3, 0, $6,
10146                                        $7 | MY_STRXFRM_PAD_WITH_SPACE);
10147            if ($$ == NULL)
10148              MYSQL_YYABORT;
10149          }
10150        | WEIGHT_STRING_SYM '(' expr AS BINARY ws_nweights ')'
10151          {
10152            Item *item= new (YYTHD->mem_root) Item_char_typecast($3, $6, &my_charset_bin);
10153            if (item == NULL)
10154              MYSQL_YYABORT;
10155            $$= new (YYTHD->mem_root)
10156                Item_func_weight_string(item, 0, $6, MY_STRXFRM_PAD_WITH_SPACE);
10157            if ($$ == NULL)
10158              MYSQL_YYABORT;
10159          }
10160        | WEIGHT_STRING_SYM '(' expr ',' ulong_num ',' ulong_num ',' ulong_num ')'
10161          {
10162            $$= new (YYTHD->mem_root) Item_func_weight_string($3, $5, $7, $9);
10163            if ($$ == NULL)
10164              MYSQL_YYABORT;
10165          }
10166        | geometry_function
10167          {
10168#ifdef HAVE_SPATIAL
10169            $$= $1;
10170            /* $1 may be NULL, GEOM_NEW not tested for out of memory */
10171            if ($$ == NULL)
10172              MYSQL_YYABORT;
10173#else
10174            my_error(ER_FEATURE_DISABLED, MYF(0),
10175                     sym_group_geom.name, sym_group_geom.needed_define);
10176            MYSQL_YYABORT;
10177#endif
10178          }
10179        ;
10180
10181geometry_function:
10182          CONTAINS_SYM '(' expr ',' expr ')'
10183          {
10184            $$= GEOM_NEW(YYTHD,
10185                         Item_func_spatial_mbr_rel($3, $5,
10186                                               Item_func::SP_CONTAINS_FUNC));
10187          }
10188        | GEOMETRYCOLLECTION '(' expr_list ')'
10189          {
10190            $$= GEOM_NEW(YYTHD,
10191                         Item_func_spatial_collection(* $3,
10192                           Geometry::wkb_geometrycollection,
10193                           Geometry::wkb_point));
10194          }
10195        | LINESTRING '(' expr_list ')'
10196          {
10197            $$= GEOM_NEW(YYTHD,
10198                         Item_func_spatial_collection(* $3,
10199                           Geometry::wkb_linestring,
10200                           Geometry::wkb_point));
10201          }
10202        | MULTILINESTRING '(' expr_list ')'
10203          {
10204            $$= GEOM_NEW(YYTHD,
10205                         Item_func_spatial_collection(* $3,
10206                           Geometry::wkb_multilinestring,
10207                           Geometry::wkb_linestring));
10208          }
10209        | MULTIPOINT '(' expr_list ')'
10210          {
10211            $$= GEOM_NEW(YYTHD,
10212                         Item_func_spatial_collection(* $3,
10213                           Geometry::wkb_multipoint,
10214                           Geometry::wkb_point));
10215          }
10216        | MULTIPOLYGON '(' expr_list ')'
10217          {
10218            $$= GEOM_NEW(YYTHD,
10219                         Item_func_spatial_collection(* $3,
10220                           Geometry::wkb_multipolygon,
10221                           Geometry::wkb_polygon));
10222          }
10223        | POINT_SYM '(' expr ',' expr ')'
10224          {
10225            $$= GEOM_NEW(YYTHD, Item_func_point($3,$5));
10226          }
10227        | POLYGON '(' expr_list ')'
10228          {
10229            $$= GEOM_NEW(YYTHD,
10230                         Item_func_spatial_collection(* $3,
10231                           Geometry::wkb_polygon,
10232                           Geometry::wkb_linestring));
10233          }
10234        ;
10235
10236/*
10237  Regular function calls.
10238  The function name is *not* a token, and therefore is guaranteed to not
10239  introduce side effects to the language in general.
10240  MAINTAINER:
10241  All the new functions implemented for new features should fit into
10242  this category. The place to implement the function itself is
10243  in sql/item_create.cc
10244*/
10245function_call_generic:
10246          IDENT_sys '('
10247          {
10248#ifdef HAVE_DLOPEN
10249            udf_func *udf= 0;
10250            LEX *lex= Lex;
10251            if (using_udf_functions &&
10252                (udf= find_udf($1.str, $1.length)) &&
10253                udf->type == UDFTYPE_AGGREGATE)
10254            {
10255              if (lex->current_select->inc_in_sum_expr())
10256              {
10257                my_parse_error(ER(ER_SYNTAX_ERROR));
10258                MYSQL_YYABORT;
10259              }
10260            }
10261            /* Temporary placing the result of find_udf in $3 */
10262            $<udf>$= udf;
10263#endif
10264          }
10265          opt_udf_expr_list ')'
10266          {
10267            THD *thd= YYTHD;
10268            Create_func *builder;
10269            Item *item= NULL;
10270
10271            if (sp_check_name(&$1))
10272            {
10273              MYSQL_YYABORT;
10274            }
10275
10276            /*
10277              Implementation note:
10278              names are resolved with the following order:
10279              - MySQL native functions,
10280              - User Defined Functions,
10281              - Stored Functions (assuming the current <use> database)
10282
10283              This will be revised with WL#2128 (SQL PATH)
10284            */
10285            builder= find_native_function_builder(thd, $1);
10286            if (builder)
10287            {
10288              item= builder->create_func(thd, $1, $4);
10289            }
10290            else
10291            {
10292#ifdef HAVE_DLOPEN
10293              /* Retrieving the result of find_udf */
10294              udf_func *udf= $<udf>3;
10295
10296              if (udf)
10297              {
10298                if (udf->type == UDFTYPE_AGGREGATE)
10299                {
10300                  Select->in_sum_expr--;
10301                }
10302
10303                item= Create_udf_func::s_singleton.create(thd, udf, $4);
10304              }
10305              else
10306#endif
10307              {
10308                builder= find_qualified_function_builder(thd);
10309                DBUG_ASSERT(builder);
10310                item= builder->create_func(thd, $1, $4);
10311              }
10312            }
10313
10314            if (! ($$= item))
10315            {
10316              MYSQL_YYABORT;
10317            }
10318          }
10319        | ident '.' ident '(' opt_expr_list ')'
10320          {
10321            THD *thd= YYTHD;
10322            Create_qfunc *builder;
10323            Item *item= NULL;
10324
10325            /*
10326              The following in practice calls:
10327              <code>Create_sp_func::create()</code>
10328              and builds a stored function.
10329
10330              However, it's important to maintain the interface between the
10331              parser and the implementation in item_create.cc clean,
10332              since this will change with WL#2128 (SQL PATH):
10333              - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native
10334              function version(),
10335              - MySQL.version() is the SQL 2003 syntax for the native function
10336              version() (a vendor can specify any schema).
10337            */
10338
10339            if (!$1.str ||
10340                (check_and_convert_db_name(&$1, FALSE) != IDENT_NAME_OK))
10341              MYSQL_YYABORT;
10342            if (sp_check_name(&$3))
10343            {
10344              MYSQL_YYABORT;
10345            }
10346
10347            builder= find_qualified_function_builder(thd);
10348            DBUG_ASSERT(builder);
10349            item= builder->create(thd, $1, $3, true, $5);
10350
10351            if (! ($$= item))
10352            {
10353              MYSQL_YYABORT;
10354            }
10355          }
10356        ;
10357
10358fulltext_options:
10359          opt_natural_language_mode opt_query_expansion
10360          { $$= $1 | $2; }
10361        | IN_SYM BOOLEAN_SYM MODE_SYM
10362          { $$= FT_BOOL; }
10363        ;
10364
10365opt_natural_language_mode:
10366          /* nothing */                         { $$= FT_NL; }
10367        | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM  { $$= FT_NL; }
10368        ;
10369
10370opt_query_expansion:
10371          /* nothing */                         { $$= 0;         }
10372        | WITH QUERY_SYM EXPANSION_SYM          { $$= FT_EXPAND; }
10373        ;
10374
10375opt_udf_expr_list:
10376        /* empty */     { $$= NULL; }
10377        | udf_expr_list { $$= $1; }
10378        ;
10379
10380udf_expr_list:
10381          udf_expr
10382          {
10383            $$= new (YYTHD->mem_root) List<Item>;
10384            if ($$ == NULL)
10385              MYSQL_YYABORT;
10386            $$->push_back($1);
10387          }
10388        | udf_expr_list ',' udf_expr
10389          {
10390            $1->push_back($3);
10391            $$= $1;
10392          }
10393        ;
10394
10395udf_expr:
10396          remember_name expr remember_end select_alias
10397          {
10398            /*
10399             Use Item::name as a storage for the attribute value of user
10400             defined function argument. It is safe to use Item::name
10401             because the syntax will not allow having an explicit name here.
10402             See WL#1017 re. udf attributes.
10403            */
10404            if ($4.str)
10405            {
10406              $2->item_name.copy($4.str, $4.length, system_charset_info, false);
10407            }
10408            /*
10409               A field has to have its proper name in order for name
10410               resolution to work, something we are only guaranteed if we
10411               parse it out. If we hijack the input stream with
10412               remember_name we may get quoted or escaped names.
10413            */
10414            else if ($2->type() != Item::FIELD_ITEM &&
10415                     $2->type() != Item::REF_ITEM /* For HAVING */ )
10416              $2->item_name.copy($1, (uint) ($3 - $1), YYTHD->charset());
10417            $$= $2;
10418          }
10419        ;
10420
10421sum_expr:
10422          AVG_SYM '(' in_sum_expr ')'
10423          {
10424            $$= new (YYTHD->mem_root) Item_sum_avg($3, FALSE);
10425            if ($$ == NULL)
10426              MYSQL_YYABORT;
10427          }
10428        | AVG_SYM '(' DISTINCT in_sum_expr ')'
10429          {
10430            $$= new (YYTHD->mem_root) Item_sum_avg($4, TRUE);
10431            if ($$ == NULL)
10432              MYSQL_YYABORT;
10433          }
10434        | BIT_AND  '(' in_sum_expr ')'
10435          {
10436            $$= new (YYTHD->mem_root) Item_sum_and($3);
10437            if ($$ == NULL)
10438              MYSQL_YYABORT;
10439          }
10440        | BIT_OR  '(' in_sum_expr ')'
10441          {
10442            $$= new (YYTHD->mem_root) Item_sum_or($3);
10443            if ($$ == NULL)
10444              MYSQL_YYABORT;
10445          }
10446        | BIT_XOR  '(' in_sum_expr ')'
10447          {
10448            $$= new (YYTHD->mem_root) Item_sum_xor($3);
10449            if ($$ == NULL)
10450              MYSQL_YYABORT;
10451          }
10452        | COUNT_SYM '(' opt_all '*' ')'
10453          {
10454            Item *item= new (YYTHD->mem_root) Item_int((int32) 0L,1);
10455            if (item == NULL)
10456              MYSQL_YYABORT;
10457            $$= new (YYTHD->mem_root) Item_sum_count(item);
10458            if ($$ == NULL)
10459              MYSQL_YYABORT;
10460          }
10461        | COUNT_SYM '(' in_sum_expr ')'
10462          {
10463            $$= new (YYTHD->mem_root) Item_sum_count($3);
10464            if ($$ == NULL)
10465              MYSQL_YYABORT;
10466          }
10467        | COUNT_SYM '(' DISTINCT
10468          { Select->in_sum_expr++; }
10469          expr_list
10470          { Select->in_sum_expr--; }
10471          ')'
10472          {
10473            $$= new (YYTHD->mem_root) Item_sum_count(* $5);
10474            if ($$ == NULL)
10475              MYSQL_YYABORT;
10476          }
10477        | MIN_SYM '(' in_sum_expr ')'
10478          {
10479            $$= new (YYTHD->mem_root) Item_sum_min($3);
10480            if ($$ == NULL)
10481              MYSQL_YYABORT;
10482          }
10483        /*
10484          According to ANSI SQL, DISTINCT is allowed and has
10485          no sense inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...)
10486          is processed like an ordinary MIN | MAX()
10487        */
10488        | MIN_SYM '(' DISTINCT in_sum_expr ')'
10489          {
10490            $$= new (YYTHD->mem_root) Item_sum_min($4);
10491            if ($$ == NULL)
10492              MYSQL_YYABORT;
10493          }
10494        | MAX_SYM '(' in_sum_expr ')'
10495          {
10496            $$= new (YYTHD->mem_root) Item_sum_max($3);
10497            if ($$ == NULL)
10498              MYSQL_YYABORT;
10499          }
10500        | MAX_SYM '(' DISTINCT in_sum_expr ')'
10501          {
10502            $$= new (YYTHD->mem_root) Item_sum_max($4);
10503            if ($$ == NULL)
10504              MYSQL_YYABORT;
10505          }
10506        | STD_SYM '(' in_sum_expr ')'
10507          {
10508            $$= new (YYTHD->mem_root) Item_sum_std($3, 0);
10509            if ($$ == NULL)
10510              MYSQL_YYABORT;
10511          }
10512        | VARIANCE_SYM '(' in_sum_expr ')'
10513          {
10514            $$= new (YYTHD->mem_root) Item_sum_variance($3, 0);
10515            if ($$ == NULL)
10516              MYSQL_YYABORT;
10517          }
10518        | STDDEV_SAMP_SYM '(' in_sum_expr ')'
10519          {
10520            $$= new (YYTHD->mem_root) Item_sum_std($3, 1);
10521            if ($$ == NULL)
10522              MYSQL_YYABORT;
10523          }
10524        | VAR_SAMP_SYM '(' in_sum_expr ')'
10525          {
10526            $$= new (YYTHD->mem_root) Item_sum_variance($3, 1);
10527            if ($$ == NULL)
10528              MYSQL_YYABORT;
10529          }
10530        | SUM_SYM '(' in_sum_expr ')'
10531          {
10532            $$= new (YYTHD->mem_root) Item_sum_sum($3, FALSE);
10533            if ($$ == NULL)
10534              MYSQL_YYABORT;
10535          }
10536        | SUM_SYM '(' DISTINCT in_sum_expr ')'
10537          {
10538            $$= new (YYTHD->mem_root) Item_sum_sum($4, TRUE);
10539            if ($$ == NULL)
10540              MYSQL_YYABORT;
10541          }
10542        | GROUP_CONCAT_SYM '(' opt_distinct
10543          { Select->in_sum_expr++; }
10544          expr_list opt_gorder_clause
10545          opt_gconcat_separator
10546          ')'
10547          {
10548            SELECT_LEX *sel= Select;
10549            sel->in_sum_expr--;
10550            $$= new (YYTHD->mem_root)
10551                  Item_func_group_concat(Lex->current_context(), $3, $5,
10552                                         sel->gorder_list, $7);
10553            if ($$ == NULL)
10554              MYSQL_YYABORT;
10555            $5->empty();
10556            sel->gorder_list.empty();
10557          }
10558        ;
10559
10560variable:
10561          '@'
10562          {
10563            if (! Lex->parsing_options.allows_variable)
10564            {
10565              my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
10566              MYSQL_YYABORT;
10567            }
10568          }
10569          variable_aux
10570          {
10571            $$= $3;
10572          }
10573        ;
10574
10575variable_aux:
10576          ident_or_text SET_VAR expr
10577          {
10578            Item_func_set_user_var *item;
10579            $$= item=
10580              new (YYTHD->mem_root) Item_func_set_user_var($1, $3, false);
10581            if ($$ == NULL)
10582              MYSQL_YYABORT;
10583            LEX *lex= Lex;
10584            lex->uncacheable(UNCACHEABLE_RAND);
10585            lex->set_var_list.push_back(item);
10586          }
10587        | ident_or_text
10588          {
10589            $$= new (YYTHD->mem_root) Item_func_get_user_var($1);
10590            if ($$ == NULL)
10591              MYSQL_YYABORT;
10592            LEX *lex= Lex;
10593            lex->uncacheable(UNCACHEABLE_RAND);
10594          }
10595        | '@' opt_var_ident_type ident_or_text opt_component
10596          {
10597            /* disallow "SELECT @@global.global.variable" */
10598            if ($3.str && $4.str && check_reserved_words(&$3))
10599            {
10600              my_parse_error(ER(ER_SYNTAX_ERROR));
10601              MYSQL_YYABORT;
10602            }
10603            if (!($$= get_system_var(YYTHD, $2, $3, $4)))
10604              MYSQL_YYABORT;
10605            if (!((Item_func_get_system_var*) $$)->is_written_to_binlog())
10606              Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_VARIABLE);
10607          }
10608        ;
10609
10610opt_distinct:
10611          /* empty */ { $$ = 0; }
10612        | DISTINCT    { $$ = 1; }
10613        ;
10614
10615opt_gconcat_separator:
10616          /* empty */
10617          {
10618            $$= new (YYTHD->mem_root) String(",", 1, &my_charset_latin1);
10619            if ($$ == NULL)
10620              MYSQL_YYABORT;
10621          }
10622        | SEPARATOR_SYM text_string { $$ = $2; }
10623        ;
10624
10625opt_gorder_clause:
10626          /* empty */
10627        | ORDER_SYM BY
10628          {
10629            LEX *lex= Lex;
10630            SELECT_LEX *sel= lex->current_select;
10631            if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
10632                sel->olap != UNSPECIFIED_OLAP_TYPE &&
10633                (sel->linkage != UNION_TYPE || sel->braces))
10634            {
10635              my_error(ER_WRONG_USAGE, MYF(0),
10636                       "CUBE/ROLLUP", "ORDER BY");
10637              MYSQL_YYABORT;
10638            }
10639          }
10640         gorder_list;
10641        ;
10642
10643gorder_list:
10644          gorder_list ',' order_ident order_dir
10645          { if (add_gorder_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
10646        | order_ident order_dir
10647          { if (add_gorder_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
10648        ;
10649
10650in_sum_expr:
10651          opt_all
10652          {
10653            LEX *lex= Lex;
10654            if (lex->current_select->inc_in_sum_expr())
10655            {
10656              my_parse_error(ER(ER_SYNTAX_ERROR));
10657              MYSQL_YYABORT;
10658            }
10659          }
10660          expr
10661          {
10662            Select->in_sum_expr--;
10663            $$= $3;
10664          }
10665        ;
10666
10667cast_type:
10668          BINARY opt_field_length
10669          { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; }
10670        | CHAR_SYM opt_field_length opt_binary
10671          { $$=ITEM_CAST_CHAR; Lex->dec= 0; }
10672        | NCHAR_SYM opt_field_length
10673          { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; }
10674        | SIGNED_SYM
10675          { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
10676        | SIGNED_SYM INT_SYM
10677          { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
10678        | UNSIGNED
10679          { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
10680        | UNSIGNED INT_SYM
10681          { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; }
10682        | DATE_SYM
10683          { $$= ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec= Lex->length= (char *) 0; }
10684        | TIME_SYM type_datetime_precision
10685          { $$= ITEM_CAST_TIME; Lex->charset= NULL; Lex->length= (char *) 0; }
10686        | DATETIME type_datetime_precision
10687          { $$= ITEM_CAST_DATETIME; Lex->charset= NULL; Lex->length= (char *) 0; }
10688        | DECIMAL_SYM float_options
10689          { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
10690        ;
10691
10692opt_expr_list:
10693          /* empty */ { $$= NULL; }
10694        | expr_list { $$= $1;}
10695        ;
10696
10697expr_list:
10698          expr
10699          {
10700            $$= new (YYTHD->mem_root) List<Item>;
10701            if ($$ == NULL)
10702              MYSQL_YYABORT;
10703            $$->push_back($1);
10704          }
10705        | expr_list ',' expr
10706          {
10707            $1->push_back($3);
10708            $$= $1;
10709          }
10710        ;
10711
10712ident_list_arg:
10713          ident_list          { $$= $1; }
10714        | '(' ident_list ')'  { $$= $2; }
10715        ;
10716
10717ident_list:
10718          simple_ident
10719          {
10720            $$= new (YYTHD->mem_root) List<Item>;
10721            if ($$ == NULL)
10722              MYSQL_YYABORT;
10723            $$->push_back($1);
10724          }
10725        | ident_list ',' simple_ident
10726          {
10727            $1->push_back($3);
10728            $$= $1;
10729          }
10730        ;
10731
10732opt_expr:
10733          /* empty */    { $$= NULL; }
10734        | expr           { $$= $1; }
10735        ;
10736
10737opt_else:
10738          /* empty */  { $$= NULL; }
10739        | ELSE expr    { $$= $2; }
10740        ;
10741
10742when_list:
10743          WHEN_SYM expr THEN_SYM expr
10744          {
10745            $$= new List<Item>;
10746            if ($$ == NULL)
10747              MYSQL_YYABORT;
10748            $$->push_back($2);
10749            $$->push_back($4);
10750          }
10751        | when_list WHEN_SYM expr THEN_SYM expr
10752          {
10753            $1->push_back($3);
10754            $1->push_back($5);
10755            $$= $1;
10756          }
10757        ;
10758
10759/* Equivalent to <table reference> in the SQL:2003 standard. */
10760/* Warning - may return NULL in case of incomplete SELECT */
10761table_ref:
10762          table_factor { $$=$1; }
10763        | join_table
10764          {
10765            LEX *lex= Lex;
10766            if (!($$= lex->current_select->nest_last_join(lex->thd)))
10767              MYSQL_YYABORT;
10768          }
10769        ;
10770
10771join_table_list:
10772          derived_table_list { MYSQL_YYABORT_UNLESS($$=$1); }
10773        ;
10774
10775/*
10776  The ODBC escape syntax for Outer Join is: '{' OJ join_table '}'
10777  The parser does not define OJ as a token, any ident is accepted
10778  instead in $2 (ident). Also, all productions from table_ref can
10779  be escaped, not only join_table. Both syntax extensions are safe
10780  and are ignored.
10781*/
10782esc_table_ref:
10783        table_ref { $$=$1; }
10784      | '{' ident table_ref '}' { $$=$3; }
10785      ;
10786
10787/* Equivalent to <table reference list> in the SQL:2003 standard. */
10788/* Warning - may return NULL in case of incomplete SELECT */
10789derived_table_list:
10790          esc_table_ref { $$=$1; }
10791        | derived_table_list ',' esc_table_ref
10792          {
10793            MYSQL_YYABORT_UNLESS($1 && ($$=$3));
10794          }
10795        ;
10796
10797/*
10798  Notice that JOIN is a left-associative operation, and it must be parsed
10799  as such, that is, the parser must process first the left join operand
10800  then the right one. Such order of processing ensures that the parser
10801  produces correct join trees which is essential for semantic analysis
10802  and subsequent optimization phases.
10803*/
10804join_table:
10805          /* INNER JOIN variants */
10806          /*
10807            Use %prec to evaluate production 'table_ref' before 'normal_join'
10808            so that [INNER | CROSS] JOIN is properly nested as other
10809            left-associative joins.
10810          */
10811          table_ref normal_join table_ref %prec TABLE_REF_PRIORITY
10812          { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); }
10813        | table_ref STRAIGHT_JOIN table_factor
10814          { MYSQL_YYABORT_UNLESS($1 && ($$=$3)); $3->straight=1; }
10815        | table_ref normal_join table_ref
10816          ON
10817          {
10818            MYSQL_YYABORT_UNLESS($1 && $3);
10819            /* Change the current name resolution context to a local context. */
10820            if (push_new_name_resolution_context(YYTHD, $1, $3))
10821              MYSQL_YYABORT;
10822            Select->parsing_place= IN_ON;
10823          }
10824          expr
10825          {
10826            add_join_on($3,$6);
10827            Lex->pop_context();
10828            Select->parsing_place= NO_MATTER;
10829          }
10830        | table_ref STRAIGHT_JOIN table_factor
10831          ON
10832          {
10833            MYSQL_YYABORT_UNLESS($1 && $3);
10834            /* Change the current name resolution context to a local context. */
10835            if (push_new_name_resolution_context(YYTHD, $1, $3))
10836              MYSQL_YYABORT;
10837            Select->parsing_place= IN_ON;
10838          }
10839          expr
10840          {
10841            $3->straight=1;
10842            add_join_on($3,$6);
10843            Lex->pop_context();
10844            Select->parsing_place= NO_MATTER;
10845          }
10846        | table_ref normal_join table_ref
10847          USING
10848          {
10849            MYSQL_YYABORT_UNLESS($1 && $3);
10850          }
10851          '(' using_list ')'
10852          { add_join_natural($1,$3,$7,Select); $$=$3; }
10853        | table_ref NATURAL JOIN_SYM table_factor
10854          {
10855            MYSQL_YYABORT_UNLESS($1 && ($$=$4));
10856            add_join_natural($1,$4,NULL,Select);
10857          }
10858
10859          /* LEFT JOIN variants */
10860        | table_ref LEFT opt_outer JOIN_SYM table_ref
10861          ON
10862          {
10863            MYSQL_YYABORT_UNLESS($1 && $5);
10864            /* Change the current name resolution context to a local context. */
10865            if (push_new_name_resolution_context(YYTHD, $1, $5))
10866              MYSQL_YYABORT;
10867            Select->parsing_place= IN_ON;
10868          }
10869          expr
10870          {
10871            add_join_on($5,$8);
10872            Lex->pop_context();
10873            $5->outer_join|=JOIN_TYPE_LEFT;
10874            $$=$5;
10875            Select->parsing_place= NO_MATTER;
10876          }
10877        | table_ref LEFT opt_outer JOIN_SYM table_factor
10878          {
10879            MYSQL_YYABORT_UNLESS($1 && $5);
10880          }
10881          USING '(' using_list ')'
10882          {
10883            add_join_natural($1,$5,$9,Select);
10884            $5->outer_join|=JOIN_TYPE_LEFT;
10885            $$=$5;
10886          }
10887        | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor
10888          {
10889            MYSQL_YYABORT_UNLESS($1 && $6);
10890            add_join_natural($1,$6,NULL,Select);
10891            $6->outer_join|=JOIN_TYPE_LEFT;
10892            $$=$6;
10893          }
10894
10895          /* RIGHT JOIN variants */
10896        | table_ref RIGHT opt_outer JOIN_SYM table_ref
10897          ON
10898          {
10899            MYSQL_YYABORT_UNLESS($1 && $5);
10900            /* Change the current name resolution context to a local context. */
10901            if (push_new_name_resolution_context(YYTHD, $1, $5))
10902              MYSQL_YYABORT;
10903            Select->parsing_place= IN_ON;
10904          }
10905          expr
10906          {
10907            LEX *lex= Lex;
10908            if (!($$= lex->current_select->convert_right_join()))
10909              MYSQL_YYABORT;
10910            add_join_on($$, $8);
10911            Lex->pop_context();
10912            Select->parsing_place= NO_MATTER;
10913          }
10914        | table_ref RIGHT opt_outer JOIN_SYM table_factor
10915          {
10916            MYSQL_YYABORT_UNLESS($1 && $5);
10917          }
10918          USING '(' using_list ')'
10919          {
10920            LEX *lex= Lex;
10921            if (!($$= lex->current_select->convert_right_join()))
10922              MYSQL_YYABORT;
10923            add_join_natural($$,$5,$9,Select);
10924          }
10925        | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor
10926          {
10927            MYSQL_YYABORT_UNLESS($1 && $6);
10928            add_join_natural($6,$1,NULL,Select);
10929            LEX *lex= Lex;
10930            if (!($$= lex->current_select->convert_right_join()))
10931              MYSQL_YYABORT;
10932          }
10933        ;
10934
10935normal_join:
10936          JOIN_SYM {}
10937        | INNER_SYM JOIN_SYM {}
10938        | CROSS JOIN_SYM {}
10939        ;
10940
10941/*
10942  table PARTITION (list of partitions), reusing using_list instead of creating
10943  a new rule for partition_list.
10944*/
10945opt_use_partition:
10946          /* empty */ { $$= 0;}
10947        | use_partition
10948        ;
10949
10950use_partition:
10951          PARTITION_SYM '(' using_list ')' have_partitioning
10952          {
10953            $$= $3;
10954          }
10955        ;
10956
10957/*
10958   This is a flattening of the rules <table factor> and <table primary>
10959   in the SQL:2003 standard, since we don't have <sample clause>
10960
10961   I.e.
10962   <table factor> ::= <table primary> [ <sample clause> ]
10963*/
10964/* Warning - may return NULL in case of incomplete SELECT */
10965table_factor:
10966          {
10967            SELECT_LEX *sel= Select;
10968            sel->table_join_options= 0;
10969          }
10970          table_ident opt_use_partition opt_table_alias opt_key_definition
10971          {
10972            if (!($$= Select->add_table_to_list(YYTHD, $2, $4,
10973                                                Select->get_table_join_options(),
10974                                                YYPS->m_lock_type,
10975                                                YYPS->m_mdl_type,
10976                                                Select->pop_index_hints(),
10977                                                $3)))
10978              MYSQL_YYABORT;
10979            Select->add_joined_table($$);
10980          }
10981        | select_derived_init get_select_lex select_derived2
10982          {
10983            LEX *lex= Lex;
10984            SELECT_LEX *sel= lex->current_select;
10985            if ($1)
10986            {
10987              if (sel->set_braces(1))
10988              {
10989                my_parse_error(ER(ER_SYNTAX_ERROR));
10990                MYSQL_YYABORT;
10991              }
10992              /* select in braces, can't contain global parameters */
10993              if (sel->master_unit()->fake_select_lex)
10994                sel->master_unit()->global_parameters=
10995                   sel->master_unit()->fake_select_lex;
10996            }
10997            if ($2->init_nested_join(lex->thd))
10998              MYSQL_YYABORT;
10999            $$= 0;
11000            /* incomplete derived tables return NULL, we must be
11001               nested in select_derived rule to be here. */
11002          }
11003          /*
11004            Represents a flattening of the following rules from the SQL:2003
11005            standard. This sub-rule corresponds to the sub-rule
11006            <table primary> ::= ... | <derived table> [ AS ] <correlation name>
11007
11008            The following rules have been flattened into query_expression_body
11009            (since we have no <with clause>).
11010
11011            <derived table> ::= <table subquery>
11012            <table subquery> ::= <subquery>
11013            <subquery> ::= <left paren> <query expression> <right paren>
11014            <query expression> ::= [ <with clause> ] <query expression body>
11015
11016            For the time being we use the non-standard rule
11017            select_derived_union which is a compromise between the standard
11018            and our parser. Possibly this rule could be replaced by our
11019            query_expression_body.
11020          */
11021        | '(' get_select_lex select_derived_union ')' opt_table_alias
11022          {
11023            /* Use $2 instead of Lex->current_select as derived table will
11024               alter value of Lex->current_select. */
11025            if (!($3 || $5) && $2->embedding &&
11026                !$2->embedding->nested_join->join_list.elements)
11027            {
11028              /* we have a derived table ($3 == NULL) but no alias,
11029                 Since we are nested in further parentheses so we
11030                 can pass NULL to the outer level parentheses
11031                 Permits parsing of "((((select ...))) as xyz)" */
11032              $$= 0;
11033            }
11034            else if (!$3)
11035            {
11036              /* Handle case of derived table, alias may be NULL if there
11037                 are no outer parentheses, add_table_to_list() will throw
11038                 error in this case */
11039              LEX *lex=Lex;
11040              SELECT_LEX *sel= lex->current_select;
11041              SELECT_LEX_UNIT *unit= sel->master_unit();
11042              lex->current_select= sel= unit->outer_select();
11043              Table_ident *ti= new Table_ident(unit);
11044              if (ti == NULL)
11045                MYSQL_YYABORT;
11046              if (!($$= sel->add_table_to_list(lex->thd,
11047                                               ti, $5, 0,
11048                                               TL_READ, MDL_SHARED_READ)))
11049
11050                MYSQL_YYABORT;
11051              sel->add_joined_table($$);
11052              lex->pop_context();
11053              lex->nest_level--;
11054            }
11055            else if ($5 != NULL)
11056            {
11057              /*
11058                Tables with or without joins within parentheses cannot
11059                have aliases, and we ruled out derived tables above.
11060              */
11061              my_parse_error(ER(ER_SYNTAX_ERROR));
11062              MYSQL_YYABORT;
11063            }
11064            else
11065            {
11066              /* nested join: FROM (t1 JOIN t2 ...),
11067                 nest_level is the same as in the outer query */
11068              $$= $3;
11069            }
11070          }
11071        ;
11072
11073/*
11074  This rule accepts just about anything. The reason is that we have
11075  empty-producing rules in the beginning of rules, in this case
11076  subselect_start. This forces bison to take a decision which rules to
11077  reduce by long before it has seen any tokens. This approach ties us
11078  to a very limited class of parseable languages, and unfortunately
11079  SQL is not one of them. The chosen 'solution' was this rule, which
11080  produces just about anything, even complete bogus statements, for
11081  instance ( table UNION SELECT 1 ).
11082
11083  Fortunately, we know that the semantic value returned by
11084  select_derived is NULL if it contained a derived table, and a pointer to
11085  the base table's TABLE_LIST if it was a base table. So in the rule
11086  regarding union's, we throw a parse error manually and pretend it
11087  was bison that did it.
11088
11089  Also worth noting is that this rule concerns query expressions in
11090  the from clause only. Top level select statements and other types of
11091  subqueries have their own union rules.
11092 */
11093select_derived_union:
11094          select_derived opt_union_order_or_limit
11095          {
11096            if ($1 && $2)
11097            {
11098              my_parse_error(ER(ER_SYNTAX_ERROR));
11099              MYSQL_YYABORT;
11100            }
11101          }
11102        | select_derived_union
11103          UNION_SYM
11104          union_option
11105          {
11106            if (add_select_to_union_list(Lex, (bool)$3, FALSE))
11107              MYSQL_YYABORT;
11108          }
11109          query_specification
11110          {
11111            /*
11112              Remove from the name resolution context stack the context of the
11113              last select in the union.
11114             */
11115            Lex->pop_context();
11116          }
11117          opt_union_order_or_limit
11118          {
11119            if ($1 != NULL)
11120            {
11121              my_parse_error(ER(ER_SYNTAX_ERROR));
11122              MYSQL_YYABORT;
11123            }
11124          }
11125        ;
11126
11127/* The equivalent of select_init2 for nested queries. */
11128select_init2_derived:
11129          select_part2_derived
11130          {
11131            LEX *lex= Lex;
11132            SELECT_LEX * sel= lex->current_select;
11133            if (lex->current_select->set_braces(0))
11134            {
11135              my_parse_error(ER(ER_SYNTAX_ERROR));
11136              MYSQL_YYABORT;
11137            }
11138            if (sel->linkage == UNION_TYPE &&
11139                sel->master_unit()->first_select()->braces)
11140            {
11141              my_parse_error(ER(ER_SYNTAX_ERROR));
11142              MYSQL_YYABORT;
11143            }
11144          }
11145        ;
11146
11147/* The equivalent of select_part2 for nested queries. */
11148select_part2_derived:
11149          {
11150            LEX *lex= Lex;
11151            SELECT_LEX *sel= lex->current_select;
11152            if (sel->linkage != UNION_TYPE)
11153              mysql_init_select(lex);
11154            lex->current_select->parsing_place= SELECT_LIST;
11155          }
11156          opt_query_expression_options select_item_list
11157          {
11158            Select->parsing_place= NO_MATTER;
11159          }
11160          opt_select_from select_lock_type
11161        ;
11162
11163/* handle contents of parentheses in join expression */
11164select_derived:
11165          get_select_lex
11166          {
11167            LEX *lex= Lex;
11168            if ($1->init_nested_join(lex->thd))
11169              MYSQL_YYABORT;
11170          }
11171          derived_table_list
11172          {
11173            LEX *lex= Lex;
11174            /* for normal joins, $3 != NULL and end_nested_join() != NULL,
11175               for derived tables, both must equal NULL */
11176
11177            if (!($$= $1->end_nested_join(lex->thd)) && $3)
11178              MYSQL_YYABORT;
11179            if (!$3 && $$)
11180            {
11181              my_parse_error(ER(ER_SYNTAX_ERROR));
11182              MYSQL_YYABORT;
11183            }
11184          }
11185        ;
11186
11187select_derived2:
11188          {
11189            LEX *lex= Lex;
11190            lex->derived_tables|= DERIVED_SUBQUERY;
11191            if (!lex->expr_allows_subselect ||
11192                lex->sql_command == (int)SQLCOM_PURGE)
11193            {
11194              my_parse_error(ER(ER_SYNTAX_ERROR));
11195              MYSQL_YYABORT;
11196            }
11197            if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE ||
11198                mysql_new_select(lex, 1))
11199              MYSQL_YYABORT;
11200            mysql_init_select(lex);
11201            lex->current_select->linkage= DERIVED_TABLE_TYPE;
11202            lex->current_select->parsing_place= SELECT_LIST;
11203          }
11204          select_options select_item_list
11205          {
11206            Select->parsing_place= NO_MATTER;
11207          }
11208          opt_select_from
11209        ;
11210
11211get_select_lex:
11212          /* Empty */ { $$= Select; }
11213        ;
11214
11215select_derived_init:
11216          SELECT_SYM
11217          {
11218            LEX *lex= Lex;
11219
11220            if (! lex->parsing_options.allows_derived)
11221            {
11222              my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
11223              MYSQL_YYABORT;
11224            }
11225
11226            SELECT_LEX *sel= lex->current_select;
11227            TABLE_LIST *embedding;
11228            if (!sel->embedding || sel->end_nested_join(lex->thd))
11229            {
11230              /* we are not in parentheses */
11231              my_parse_error(ER(ER_SYNTAX_ERROR));
11232              MYSQL_YYABORT;
11233            }
11234            embedding= Select->embedding;
11235            $$= embedding &&
11236                !embedding->nested_join->join_list.elements;
11237            /* return true if we are deeply nested */
11238          }
11239        ;
11240
11241opt_outer:
11242          /* empty */ {}
11243        | OUTER {}
11244        ;
11245
11246index_hint_clause:
11247          /* empty */
11248          {
11249            $$= old_mode ?  INDEX_HINT_MASK_JOIN : INDEX_HINT_MASK_ALL;
11250          }
11251        | FOR_SYM JOIN_SYM      { $$= INDEX_HINT_MASK_JOIN;  }
11252        | FOR_SYM ORDER_SYM BY  { $$= INDEX_HINT_MASK_ORDER; }
11253        | FOR_SYM GROUP_SYM BY  { $$= INDEX_HINT_MASK_GROUP; }
11254        ;
11255
11256index_hint_type:
11257          FORCE_SYM  { $$= INDEX_HINT_FORCE; }
11258        | IGNORE_SYM { $$= INDEX_HINT_IGNORE; }
11259        ;
11260
11261index_hint_definition:
11262          index_hint_type key_or_index index_hint_clause
11263          {
11264            Select->set_index_hint_type($1, $3);
11265          }
11266          '(' key_usage_list ')'
11267        | USE_SYM key_or_index index_hint_clause
11268          {
11269            Select->set_index_hint_type(INDEX_HINT_USE, $3);
11270          }
11271          '(' opt_key_usage_list ')'
11272       ;
11273
11274index_hints_list:
11275          index_hint_definition
11276        | index_hints_list index_hint_definition
11277        ;
11278
11279opt_index_hints_list:
11280          /* empty */
11281        | { Select->alloc_index_hints(YYTHD); } index_hints_list
11282        ;
11283
11284opt_key_definition:
11285          {  Select->clear_index_hints(); }
11286          opt_index_hints_list
11287        ;
11288
11289opt_key_usage_list:
11290          /* empty */ { Select->add_index_hint(YYTHD, NULL, 0); }
11291        | key_usage_list {}
11292        ;
11293
11294key_usage_element:
11295          ident
11296          { Select->add_index_hint(YYTHD, $1.str, $1.length); }
11297        | PRIMARY_SYM
11298          { Select->add_index_hint(YYTHD, (char *)"PRIMARY", 7); }
11299        ;
11300
11301key_usage_list:
11302          key_usage_element
11303        | key_usage_list ',' key_usage_element
11304        ;
11305
11306using_list:
11307          ident
11308          {
11309            if (!($$= new List<String>))
11310              MYSQL_YYABORT;
11311            String *s= new (YYTHD->mem_root) String((const char *) $1.str,
11312                                                    $1.length,
11313                                                    system_charset_info);
11314            if (s == NULL)
11315              MYSQL_YYABORT;
11316            $$->push_back(s);
11317          }
11318        | using_list ',' ident
11319          {
11320            String *s= new (YYTHD->mem_root) String((const char *) $3.str,
11321                                                    $3.length,
11322                                                    system_charset_info);
11323            if (s == NULL)
11324              MYSQL_YYABORT;
11325            $1->push_back(s);
11326            $$= $1;
11327          }
11328        ;
11329
11330interval:
11331          interval_time_stamp    {}
11332        | DAY_HOUR_SYM           { $$=INTERVAL_DAY_HOUR; }
11333        | DAY_MICROSECOND_SYM    { $$=INTERVAL_DAY_MICROSECOND; }
11334        | DAY_MINUTE_SYM         { $$=INTERVAL_DAY_MINUTE; }
11335        | DAY_SECOND_SYM         { $$=INTERVAL_DAY_SECOND; }
11336        | HOUR_MICROSECOND_SYM   { $$=INTERVAL_HOUR_MICROSECOND; }
11337        | HOUR_MINUTE_SYM        { $$=INTERVAL_HOUR_MINUTE; }
11338        | HOUR_SECOND_SYM        { $$=INTERVAL_HOUR_SECOND; }
11339        | MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; }
11340        | MINUTE_SECOND_SYM      { $$=INTERVAL_MINUTE_SECOND; }
11341        | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; }
11342        | YEAR_MONTH_SYM         { $$=INTERVAL_YEAR_MONTH; }
11343        ;
11344
11345interval_time_stamp:
11346          DAY_SYM         { $$=INTERVAL_DAY; }
11347        | WEEK_SYM        { $$=INTERVAL_WEEK; }
11348        | HOUR_SYM        { $$=INTERVAL_HOUR; }
11349        | MINUTE_SYM      { $$=INTERVAL_MINUTE; }
11350        | MONTH_SYM       { $$=INTERVAL_MONTH; }
11351        | QUARTER_SYM     { $$=INTERVAL_QUARTER; }
11352        | SECOND_SYM      { $$=INTERVAL_SECOND; }
11353        | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; }
11354        | YEAR_SYM        { $$=INTERVAL_YEAR; }
11355        ;
11356
11357date_time_type:
11358          DATE_SYM  {$$= MYSQL_TIMESTAMP_DATE; }
11359        | TIME_SYM  {$$= MYSQL_TIMESTAMP_TIME; }
11360        | TIMESTAMP {$$= MYSQL_TIMESTAMP_DATETIME; }
11361        | DATETIME  {$$= MYSQL_TIMESTAMP_DATETIME; }
11362        ;
11363
11364table_alias:
11365          /* empty */
11366        | AS
11367        | EQ
11368        ;
11369
11370opt_table_alias:
11371          /* empty */ { $$=0; }
11372        | table_alias ident
11373          {
11374            $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING));
11375            if ($$ == NULL)
11376              MYSQL_YYABORT;
11377          }
11378        ;
11379
11380opt_all:
11381          /* empty */
11382        | ALL
11383        ;
11384
11385where_clause:
11386          /* empty */  { Select->where= 0; }
11387        | WHERE
11388          {
11389            Select->parsing_place= IN_WHERE;
11390          }
11391          expr
11392          {
11393            SELECT_LEX *select= Select;
11394            select->where= $3;
11395            select->parsing_place= NO_MATTER;
11396            if ($3)
11397              $3->top_level_item();
11398          }
11399        ;
11400
11401having_clause:
11402          /* empty */
11403        | HAVING
11404          {
11405            Select->parsing_place= IN_HAVING;
11406          }
11407          expr
11408          {
11409            SELECT_LEX *sel= Select;
11410            sel->having= $3;
11411            sel->parsing_place= NO_MATTER;
11412            if ($3)
11413              $3->top_level_item();
11414          }
11415        ;
11416
11417opt_escape:
11418          ESCAPE_SYM simple_expr
11419          {
11420            Lex->escape_used= TRUE;
11421            $$= $2;
11422          }
11423        | /* empty */
11424          {
11425            THD *thd= YYTHD;
11426            Lex->escape_used= FALSE;
11427            $$= ((thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ?
11428                 new (thd->mem_root) Item_string("", 0, &my_charset_latin1) :
11429                 new (thd->mem_root) Item_string("\\", 1, &my_charset_latin1));
11430            if ($$ == NULL)
11431              MYSQL_YYABORT;
11432          }
11433        ;
11434
11435/*
11436   group by statement in select
11437*/
11438
11439group_clause:
11440          /* empty */
11441        | GROUP_SYM BY group_list olap_opt
11442        ;
11443
11444group_list:
11445          group_list ',' order_ident order_dir
11446          { if (add_group_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
11447        | order_ident order_dir
11448          { if (add_group_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
11449        ;
11450
11451olap_opt:
11452          /* empty */ {}
11453        | WITH_CUBE_SYM
11454          {
11455            /*
11456              'WITH CUBE' is reserved in the MySQL syntax, but not implemented,
11457              and cause LALR(2) conflicts.
11458              This syntax is not standard.
11459              MySQL syntax: GROUP BY col1, col2, col3 WITH CUBE
11460              SQL-2003: GROUP BY ... CUBE(col1, col2, col3)
11461            */
11462            LEX *lex=Lex;
11463            if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
11464            {
11465              my_error(ER_WRONG_USAGE, MYF(0), "WITH CUBE",
11466                       "global union parameters");
11467              MYSQL_YYABORT;
11468            }
11469            lex->current_select->olap= CUBE_TYPE;
11470            my_error(ER_NOT_SUPPORTED_YET, MYF(0), "CUBE");
11471            MYSQL_YYABORT;
11472          }
11473        | WITH_ROLLUP_SYM
11474          {
11475            /*
11476              'WITH ROLLUP' is needed for backward compatibility,
11477              and cause LALR(2) conflicts.
11478              This syntax is not standard.
11479              MySQL syntax: GROUP BY col1, col2, col3 WITH ROLLUP
11480              SQL-2003: GROUP BY ... ROLLUP(col1, col2, col3)
11481            */
11482            LEX *lex= Lex;
11483            if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
11484            {
11485              my_error(ER_WRONG_USAGE, MYF(0), "WITH ROLLUP",
11486                       "global union parameters");
11487              MYSQL_YYABORT;
11488            }
11489            if (lex->current_select->options & SELECT_DISTINCT)
11490            {
11491              // DISTINCT+ROLLUP does not work
11492              my_error(ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", "DISTINCT");
11493              MYSQL_YYABORT;
11494            }
11495            lex->current_select->olap= ROLLUP_TYPE;
11496          }
11497        ;
11498
11499/*
11500  Order by statement in ALTER TABLE
11501*/
11502
11503alter_order_clause:
11504          ORDER_SYM BY alter_order_list
11505        ;
11506
11507alter_order_list:
11508          alter_order_list ',' alter_order_item
11509        | alter_order_item
11510        ;
11511
11512alter_order_item:
11513          simple_ident_nospvar order_dir
11514          {
11515            THD *thd= YYTHD;
11516            bool ascending= ($2 == 1) ? true : false;
11517            if (add_order_to_list(thd, $1, ascending))
11518              MYSQL_YYABORT;
11519          }
11520        ;
11521
11522/*
11523   Order by statement in select
11524*/
11525
11526opt_order_clause:
11527          /* empty */
11528        | order_clause
11529        ;
11530
11531order_clause:
11532          ORDER_SYM BY
11533          {
11534            LEX *lex=Lex;
11535            SELECT_LEX *sel= lex->current_select;
11536            SELECT_LEX_UNIT *unit= sel-> master_unit();
11537            if (sel->linkage != GLOBAL_OPTIONS_TYPE &&
11538                sel->olap != UNSPECIFIED_OLAP_TYPE &&
11539                (sel->linkage != UNION_TYPE || sel->braces))
11540            {
11541              my_error(ER_WRONG_USAGE, MYF(0),
11542                       "CUBE/ROLLUP", "ORDER BY");
11543              MYSQL_YYABORT;
11544            }
11545            if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex)
11546            {
11547              /*
11548                A query of the of the form (SELECT ...) ORDER BY order_list is
11549                executed in the same way as the query
11550                SELECT ... ORDER BY order_list
11551                unless the SELECT construct contains ORDER BY or LIMIT clauses.
11552                Otherwise we create a fake SELECT_LEX if it has not been created
11553                yet.
11554              */
11555              SELECT_LEX *first_sl= unit->first_select();
11556              if (!unit->is_union() &&
11557                  (first_sl->order_list.elements ||
11558                   first_sl->select_limit) &&
11559                  unit->add_fake_select_lex(lex->thd))
11560                MYSQL_YYABORT;
11561            }
11562          }
11563          order_list
11564        ;
11565
11566order_list:
11567          order_list ',' order_ident order_dir
11568          { if (add_order_to_list(YYTHD, $3,(bool) $4)) MYSQL_YYABORT; }
11569        | order_ident order_dir
11570          { if (add_order_to_list(YYTHD, $1,(bool) $2)) MYSQL_YYABORT; }
11571        ;
11572
11573order_dir:
11574          /* empty */ { $$ =  1; }
11575        | ASC  { $$ =1; }
11576        | DESC { $$ =0; }
11577        ;
11578
11579opt_limit_clause_init:
11580          /* empty */
11581          {
11582            LEX *lex= Lex;
11583            SELECT_LEX *sel= lex->current_select;
11584            sel->offset_limit= 0;
11585            sel->select_limit= 0;
11586          }
11587        | limit_clause {}
11588        ;
11589
11590opt_limit_clause:
11591          /* empty */ {}
11592        | limit_clause {}
11593        ;
11594
11595limit_clause:
11596          LIMIT limit_options
11597          {
11598            if (Select->select_limit->fixed &&
11599                Select->select_limit->val_int() != 0)
11600            {
11601              Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
11602            }
11603          }
11604        ;
11605
11606limit_options:
11607          limit_option
11608          {
11609            SELECT_LEX *sel= Select;
11610            sel->select_limit= $1;
11611            sel->offset_limit= 0;
11612            sel->explicit_limit= 1;
11613          }
11614        | limit_option ',' limit_option
11615          {
11616            SELECT_LEX *sel= Select;
11617            sel->select_limit= $3;
11618            sel->offset_limit= $1;
11619            sel->explicit_limit= 1;
11620          }
11621        | limit_option OFFSET_SYM limit_option
11622          {
11623            SELECT_LEX *sel= Select;
11624            sel->select_limit= $1;
11625            sel->offset_limit= $3;
11626            sel->explicit_limit= 1;
11627          }
11628        ;
11629
11630limit_option:
11631        ident
11632        {
11633          THD *thd= YYTHD;
11634          LEX *lex= Lex;
11635          Lex_input_stream *lip= YYLIP;
11636          sp_head *sp= lex->sphead;
11637          const char *query_start_ptr=
11638            sp ? sp->m_parser_data.get_current_stmt_start_ptr() : NULL;
11639
11640          Item_splocal *v= create_item_for_sp_var(thd, $1, NULL,
11641                                                  query_start_ptr,
11642                                                  lip->get_tok_start(),
11643                                                  lip->get_ptr());
11644          if (!v)
11645            MYSQL_YYABORT;
11646
11647          lex->safe_to_cache_query= false;
11648
11649          if (v->type() != Item::INT_ITEM)
11650          {
11651            my_error(ER_WRONG_SPVAR_TYPE_IN_LIMIT, MYF(0));
11652            MYSQL_YYABORT;
11653          }
11654
11655          v->limit_clause_param= true;
11656          $$= v;
11657        }
11658        | param_marker
11659        {
11660          ((Item_param *) $1)->limit_clause_param= TRUE;
11661        }
11662        | ULONGLONG_NUM
11663          {
11664            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
11665            if ($$ == NULL)
11666              MYSQL_YYABORT;
11667          }
11668        | LONG_NUM
11669          {
11670            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
11671            if ($$ == NULL)
11672              MYSQL_YYABORT;
11673          }
11674        | NUM
11675          {
11676            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
11677            if ($$ == NULL)
11678              MYSQL_YYABORT;
11679          }
11680        ;
11681
11682delete_limit_clause:
11683          /* empty */
11684          {
11685            LEX *lex=Lex;
11686            lex->current_select->select_limit= 0;
11687          }
11688        | LIMIT limit_option
11689          {
11690            SELECT_LEX *sel= Select;
11691            sel->select_limit= $2;
11692            if (Select->select_limit->fixed &&
11693                Select->select_limit->val_int() != 0)
11694            {
11695              Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_LIMIT);
11696            }
11697            sel->explicit_limit= 1;
11698          }
11699        ;
11700
11701ulong_num:
11702          NUM           { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11703        | HEX_NUM       { $$= (ulong) strtol($1.str, (char**) 0, 16); }
11704        | LONG_NUM      { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11705        | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11706        | DECIMAL_NUM   { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11707        | FLOAT_NUM     { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11708        ;
11709
11710real_ulong_num:
11711          NUM           { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11712        | HEX_NUM       { $$= (ulong) strtol($1.str, (char**) 0, 16); }
11713        | LONG_NUM      { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11714        | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
11715        | dec_num_error { MYSQL_YYABORT; }
11716        ;
11717
11718ulonglong_num:
11719          NUM           { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11720        | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11721        | LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11722        | DECIMAL_NUM   { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11723        | FLOAT_NUM     { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11724        ;
11725
11726real_ulonglong_num:
11727          NUM           { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11728        | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11729        | LONG_NUM      { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); }
11730        | dec_num_error { MYSQL_YYABORT; }
11731        ;
11732
11733dec_num_error:
11734          dec_num
11735          { my_parse_error(ER(ER_ONLY_INTEGERS_ALLOWED)); }
11736        ;
11737
11738dec_num:
11739          DECIMAL_NUM
11740        | FLOAT_NUM
11741        ;
11742
11743procedure_analyse_clause:
11744          /* empty */
11745        | PROCEDURE_SYM ANALYSE_SYM
11746          {
11747            LEX *lex= Lex;
11748
11749            if (!lex->parsing_options.allows_select_procedure)
11750            {
11751              my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
11752              MYSQL_YYABORT;
11753            }
11754
11755            if (&lex->select_lex != lex->current_select)
11756            {
11757              my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
11758              MYSQL_YYABORT;
11759            }
11760
11761            if (lex->result != NULL)
11762            {
11763              my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "INTO");
11764              MYSQL_YYABORT;
11765            }
11766
11767            if ((lex->proc_analyse= new Proc_analyse_params) == NULL)
11768            {
11769              my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR));
11770              MYSQL_YYABORT;
11771            }
11772
11773            lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
11774          }
11775          '(' opt_procedure_analyse_params ')'
11776        ;
11777
11778opt_procedure_analyse_params:
11779          /* empty */ {}
11780        | procedure_analyse_param
11781          {
11782            Lex->proc_analyse->max_tree_elements= $1;
11783          }
11784        | procedure_analyse_param ',' procedure_analyse_param
11785          {
11786            Lex->proc_analyse->max_tree_elements= $1;
11787            Lex->proc_analyse->max_treemem= $3;
11788          }
11789        ;
11790
11791procedure_analyse_param:
11792          NUM
11793          {
11794            int error;
11795            $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error);
11796            if (error != 0)
11797            {
11798              my_error(ER_WRONG_PARAMETERS_TO_PROCEDURE, MYF(0), "ANALYSE");
11799              MYSQL_YYABORT;
11800            }
11801          }
11802        ;
11803
11804select_var_list_init:
11805          {
11806            LEX *lex=Lex;
11807            if (!lex->describe && (!(lex->result= new select_dumpvar())))
11808              MYSQL_YYABORT;
11809          }
11810          select_var_list
11811          {}
11812        ;
11813
11814select_var_list:
11815          select_var_list ',' select_var_ident
11816        | select_var_ident {}
11817        ;
11818
11819select_var_ident:
11820          '@' ident_or_text
11821          {
11822            LEX *lex=Lex;
11823            if (lex->result)
11824            {
11825              my_var *var= new my_var($2,0,0,(enum_field_types)0);
11826              if (var == NULL)
11827                MYSQL_YYABORT;
11828              ((select_dumpvar *)lex->result)->var_list.push_back(var);
11829            }
11830            else
11831            {
11832              /*
11833                The parser won't create select_result instance only
11834                if it's an EXPLAIN.
11835              */
11836              DBUG_ASSERT(lex->describe);
11837            }
11838          }
11839        | ident_or_text
11840          {
11841            LEX *lex= Lex;
11842#ifndef DBUG_OFF
11843            sp_head *sp= lex->sphead;
11844#endif
11845            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
11846            sp_variable *spv;
11847
11848            if (!pctx || !(spv= pctx->find_variable($1, false)))
11849            {
11850              my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
11851              MYSQL_YYABORT;
11852            }
11853            if (lex->result)
11854            {
11855              my_var *var= new my_var($1, 1, spv->offset, spv->type);
11856
11857              if (var == NULL)
11858                MYSQL_YYABORT;
11859
11860              ((select_dumpvar *) lex->result)->var_list.push_back(var);
11861
11862#ifndef DBUG_OFF
11863              var->sp= sp;
11864#endif
11865            }
11866            else
11867            {
11868              /*
11869                The parser won't create select_result instance only
11870                if it's an EXPLAIN.
11871              */
11872              DBUG_ASSERT(lex->describe);
11873            }
11874          }
11875        ;
11876
11877into:
11878          INTO
11879          {
11880            if (! Lex->parsing_options.allows_select_into)
11881            {
11882              my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
11883              MYSQL_YYABORT;
11884            }
11885          }
11886          into_destination
11887        ;
11888
11889into_destination:
11890          OUTFILE TEXT_STRING_filesystem
11891          {
11892            LEX *lex= Lex;
11893            lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
11894            if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
11895                !(lex->result= new select_export(lex->exchange)))
11896              MYSQL_YYABORT;
11897          }
11898          opt_load_data_charset
11899          { Lex->exchange->cs= $4; }
11900          opt_field_term opt_line_term
11901        | DUMPFILE TEXT_STRING_filesystem
11902          {
11903            LEX *lex=Lex;
11904            if (!lex->describe)
11905            {
11906              lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
11907              if (!(lex->exchange= new sql_exchange($2.str,1)))
11908                MYSQL_YYABORT;
11909              if (!(lex->result= new select_dump(lex->exchange)))
11910                MYSQL_YYABORT;
11911            }
11912          }
11913        | select_var_list_init
11914          {
11915            Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
11916          }
11917        ;
11918
11919/*
11920  DO statement
11921*/
11922
11923do:
11924          DO_SYM
11925          {
11926            LEX *lex=Lex;
11927            lex->sql_command = SQLCOM_DO;
11928            mysql_init_select(lex);
11929          }
11930          expr_list
11931          {
11932            Lex->insert_list= $3;
11933          }
11934        ;
11935
11936/*
11937  Drop : delete tables or index or user
11938*/
11939
11940drop:
11941          DROP opt_temporary table_or_tables if_exists
11942          {
11943            LEX *lex=Lex;
11944            lex->sql_command = SQLCOM_DROP_TABLE;
11945            lex->drop_temporary= $2;
11946            lex->drop_if_exists= $4;
11947            YYPS->m_lock_type= TL_UNLOCK;
11948            YYPS->m_mdl_type= MDL_EXCLUSIVE;
11949          }
11950          table_list opt_restrict
11951          {}
11952        | DROP INDEX_SYM ident ON table_ident {}
11953          {
11954            LEX *lex=Lex;
11955            Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str);
11956            if (ad == NULL)
11957              MYSQL_YYABORT;
11958            lex->sql_command= SQLCOM_DROP_INDEX;
11959            lex->alter_info.reset();
11960            lex->alter_info.flags= Alter_info::ALTER_DROP_INDEX;
11961            lex->alter_info.drop_list.push_back(ad);
11962            if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL,
11963                                                        TL_OPTION_UPDATING,
11964                                                        TL_READ_NO_INSERT,
11965                                                        MDL_SHARED_UPGRADABLE))
11966              MYSQL_YYABORT;
11967          }
11968          opt_index_lock_algorithm {}
11969        | DROP DATABASE if_exists ident
11970          {
11971            LEX *lex=Lex;
11972            lex->sql_command= SQLCOM_DROP_DB;
11973            lex->drop_if_exists=$3;
11974            lex->name= $4;
11975          }
11976        | DROP FUNCTION_SYM if_exists ident '.' ident
11977          {
11978            THD *thd= YYTHD;
11979            LEX *lex= thd->lex;
11980            sp_name *spname;
11981            if ($4.str &&
11982                (check_and_convert_db_name(&$4, FALSE) != IDENT_NAME_OK))
11983               MYSQL_YYABORT;
11984            if (lex->sphead)
11985            {
11986              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
11987              MYSQL_YYABORT;
11988            }
11989            lex->sql_command = SQLCOM_DROP_FUNCTION;
11990            lex->drop_if_exists= $3;
11991            spname= new sp_name($4, $6, true);
11992            if (spname == NULL)
11993              MYSQL_YYABORT;
11994            spname->init_qname(thd);
11995            lex->spname= spname;
11996          }
11997        | DROP FUNCTION_SYM if_exists ident
11998          {
11999            THD *thd= YYTHD;
12000            LEX *lex= thd->lex;
12001            LEX_STRING db= {0, 0};
12002            sp_name *spname;
12003            if (lex->sphead)
12004            {
12005              my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
12006              MYSQL_YYABORT;
12007            }
12008            if (thd->db && lex->copy_db_to(&db.str, &db.length))
12009              MYSQL_YYABORT;
12010            lex->sql_command = SQLCOM_DROP_FUNCTION;
12011            lex->drop_if_exists= $3;
12012            spname= new sp_name(db, $4, false);
12013            if (spname == NULL)
12014              MYSQL_YYABORT;
12015            spname->init_qname(thd);
12016            lex->spname= spname;
12017          }
12018        | DROP PROCEDURE_SYM if_exists sp_name
12019          {
12020            LEX *lex=Lex;
12021            if (lex->sphead)
12022            {
12023              my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
12024              MYSQL_YYABORT;
12025            }
12026            lex->sql_command = SQLCOM_DROP_PROCEDURE;
12027            lex->drop_if_exists= $3;
12028            lex->spname= $4;
12029          }
12030        | DROP USER clear_privileges user_list
12031          {
12032            Lex->sql_command = SQLCOM_DROP_USER;
12033          }
12034        | DROP VIEW_SYM if_exists
12035          {
12036            LEX *lex= Lex;
12037            lex->sql_command= SQLCOM_DROP_VIEW;
12038            lex->drop_if_exists= $3;
12039            YYPS->m_lock_type= TL_UNLOCK;
12040            YYPS->m_mdl_type= MDL_EXCLUSIVE;
12041          }
12042          table_list opt_restrict
12043          {}
12044        | DROP EVENT_SYM if_exists sp_name
12045          {
12046            Lex->drop_if_exists= $3;
12047            Lex->spname= $4;
12048            Lex->sql_command = SQLCOM_DROP_EVENT;
12049          }
12050        | DROP TRIGGER_SYM if_exists sp_name
12051          {
12052            LEX *lex= Lex;
12053            lex->sql_command= SQLCOM_DROP_TRIGGER;
12054            lex->drop_if_exists= $3;
12055            lex->spname= $4;
12056          }
12057        | DROP TABLESPACE tablespace_name drop_ts_options_list
12058          {
12059            LEX *lex= Lex;
12060            lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE;
12061          }
12062        | DROP LOGFILE_SYM GROUP_SYM logfile_group_name drop_ts_options_list
12063          {
12064            LEX *lex= Lex;
12065            lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP;
12066          }
12067        | DROP SERVER_SYM if_exists ident_or_text
12068          {
12069            Lex->sql_command = SQLCOM_DROP_SERVER;
12070            Lex->drop_if_exists= $3;
12071            Lex->server_options.server_name= $4.str;
12072            Lex->server_options.server_name_length= $4.length;
12073          }
12074        | DROP COMPRESSION_DICTIONARY_SYM if_exists ident
12075          {
12076            Lex->sql_command= SQLCOM_DROP_COMPRESSION_DICTIONARY;
12077            Lex->drop_if_exists= $3;
12078            Lex->ident= $4;
12079          }
12080        ;
12081
12082table_list:
12083          table_name
12084        | table_list ',' table_name
12085        ;
12086
12087table_name:
12088          table_ident
12089          {
12090            if (!Select->add_table_to_list(YYTHD, $1, NULL,
12091                                           TL_OPTION_UPDATING,
12092                                           YYPS->m_lock_type,
12093                                           YYPS->m_mdl_type))
12094              MYSQL_YYABORT;
12095          }
12096        ;
12097
12098table_name_with_opt_use_partition:
12099          table_ident opt_use_partition
12100          {
12101            if (!Select->add_table_to_list(YYTHD, $1, NULL,
12102                                           TL_OPTION_UPDATING,
12103                                           YYPS->m_lock_type,
12104                                           YYPS->m_mdl_type,
12105                                           NULL,
12106                                           $2))
12107              MYSQL_YYABORT;
12108          }
12109        ;
12110
12111table_alias_ref_list:
12112          table_alias_ref
12113        | table_alias_ref_list ',' table_alias_ref
12114        ;
12115
12116table_alias_ref:
12117          table_ident_opt_wild
12118          {
12119            if (!Select->add_table_to_list(YYTHD, $1, NULL,
12120                                           TL_OPTION_UPDATING | TL_OPTION_ALIAS,
12121                                           YYPS->m_lock_type,
12122                                           YYPS->m_mdl_type))
12123              MYSQL_YYABORT;
12124          }
12125        ;
12126
12127if_exists:
12128          /* empty */ { $$= 0; }
12129        | IF EXISTS { $$= 1; }
12130        ;
12131
12132opt_temporary:
12133          /* empty */ { $$= 0; }
12134        | TEMPORARY { $$= 1; }
12135        ;
12136
12137drop_ts_options_list:
12138          /* empty */
12139        | drop_ts_options
12140
12141drop_ts_options:
12142          drop_ts_option
12143        | drop_ts_options drop_ts_option
12144        | drop_ts_options_list ',' drop_ts_option
12145        ;
12146
12147drop_ts_option:
12148          opt_ts_engine
12149      	| ts_wait
12150
12151/*
12152** Insert : add new data to table
12153*/
12154
12155insert:
12156          INSERT
12157          {
12158            LEX *lex= Lex;
12159            lex->sql_command= SQLCOM_INSERT;
12160            lex->duplicates= DUP_ERROR;
12161            mysql_init_select(lex);
12162          }
12163          insert_lock_option
12164          opt_ignore insert2
12165          {
12166            Select->set_lock_for_tables($3);
12167            Lex->current_select= &Lex->select_lex;
12168          }
12169          insert_field_spec opt_insert_update
12170          {}
12171        ;
12172
12173replace:
12174          REPLACE
12175          {
12176            LEX *lex=Lex;
12177            lex->sql_command = SQLCOM_REPLACE;
12178            lex->duplicates= DUP_REPLACE;
12179            mysql_init_select(lex);
12180          }
12181          replace_lock_option insert2
12182          {
12183            Select->set_lock_for_tables($3);
12184            Lex->current_select= &Lex->select_lex;
12185          }
12186          insert_field_spec
12187          {}
12188        ;
12189
12190insert_lock_option:
12191          /* empty */
12192          {
12193#ifdef HAVE_QUERY_CACHE
12194            /*
12195              If it is SP we do not allow insert optimisation whan result of
12196              insert visible only after the table unlocking but everyone can
12197              read table.
12198            */
12199            $$= (Lex->sphead ? TL_WRITE_DEFAULT : TL_WRITE_CONCURRENT_INSERT);
12200#else
12201            $$= TL_WRITE_CONCURRENT_INSERT;
12202#endif
12203          }
12204        | LOW_PRIORITY  { $$= TL_WRITE_LOW_PRIORITY; }
12205        | DELAYED_SYM
12206        {
12207          Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
12208                                                    YYTHD->query());
12209          Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset +
12210                                           YYLIP->yyLength() + 1;
12211          $$= TL_WRITE_DELAYED;
12212
12213          push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
12214                              ER_WARN_DEPRECATED_SYNTAX,
12215                              ER(ER_WARN_DEPRECATED_SYNTAX),
12216                              "INSERT DELAYED", "INSERT");
12217        }
12218        | HIGH_PRIORITY { $$= TL_WRITE; }
12219        ;
12220
12221replace_lock_option:
12222          opt_low_priority { $$= $1; }
12223        | DELAYED_SYM
12224        {
12225          Lex->keyword_delayed_begin_offset= (uint)(YYLIP->get_tok_start() -
12226                                                    YYTHD->query());
12227          Lex->keyword_delayed_end_offset= Lex->keyword_delayed_begin_offset +
12228                                           YYLIP->yyLength() + 1;
12229          $$= TL_WRITE_DELAYED;
12230
12231          push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
12232                              ER_WARN_DEPRECATED_SYNTAX,
12233                              ER(ER_WARN_DEPRECATED_SYNTAX),
12234                              "REPLACE DELAYED", "REPLACE");
12235        }
12236        ;
12237
12238insert2:
12239          INTO insert_table {}
12240        | insert_table {}
12241        ;
12242
12243insert_table:
12244          table_name_with_opt_use_partition
12245          {
12246            LEX *lex=Lex;
12247            lex->field_list.empty();
12248            lex->many_values.empty();
12249            lex->insert_list=0;
12250          };
12251
12252insert_field_spec:
12253          insert_values {}
12254        | '(' ')' insert_values {}
12255        | '(' fields ')' insert_values {}
12256        | SET
12257          {
12258            LEX *lex=Lex;
12259            if (!(lex->insert_list = new List_item) ||
12260                lex->many_values.push_back(lex->insert_list))
12261              MYSQL_YYABORT;
12262          }
12263          ident_eq_list
12264        ;
12265
12266fields:
12267          fields ',' insert_ident { Lex->field_list.push_back($3); }
12268        | insert_ident { Lex->field_list.push_back($1); }
12269        ;
12270
12271insert_values:
12272          VALUES values_list {}
12273        | VALUE_SYM values_list {}
12274        | create_select
12275          { Select->set_braces(0);}
12276          union_clause {}
12277        | '(' create_select ')'
12278          { Select->set_braces(1);}
12279          union_opt {}
12280        ;
12281
12282values_list:
12283          values_list ','  no_braces
12284        | no_braces
12285        ;
12286
12287ident_eq_list:
12288          ident_eq_list ',' ident_eq_value
12289        | ident_eq_value
12290        ;
12291
12292ident_eq_value:
12293          simple_ident_nospvar equal expr_or_default
12294          {
12295            LEX *lex=Lex;
12296            if (lex->field_list.push_back($1) ||
12297                lex->insert_list->push_back($3))
12298              MYSQL_YYABORT;
12299          }
12300        ;
12301
12302equal:
12303          EQ {}
12304        | SET_VAR {}
12305        ;
12306
12307opt_equal:
12308          /* empty */ {}
12309        | equal {}
12310        ;
12311
12312no_braces:
12313          '('
12314          {
12315              if (!(Lex->insert_list = new List_item))
12316                MYSQL_YYABORT;
12317          }
12318          opt_values ')'
12319          {
12320            LEX *lex=Lex;
12321            if (lex->many_values.push_back(lex->insert_list))
12322              MYSQL_YYABORT;
12323          }
12324        ;
12325
12326opt_values:
12327          /* empty */ {}
12328        | values
12329        ;
12330
12331values:
12332          values ','  expr_or_default
12333          {
12334            if (Lex->insert_list->push_back($3))
12335              MYSQL_YYABORT;
12336          }
12337        | expr_or_default
12338          {
12339            if (Lex->insert_list->push_back($1))
12340              MYSQL_YYABORT;
12341          }
12342        ;
12343
12344expr_or_default:
12345          expr { $$= $1;}
12346        | DEFAULT
12347          {
12348            $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context());
12349            if ($$ == NULL)
12350              MYSQL_YYABORT;
12351          }
12352        ;
12353
12354opt_insert_update:
12355          /* empty */
12356        | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; }
12357          KEY_SYM UPDATE_SYM insert_update_list
12358        ;
12359
12360/* Update rows in a table */
12361
12362update:
12363          UPDATE_SYM
12364          {
12365            LEX *lex= Lex;
12366            mysql_init_select(lex);
12367            lex->sql_command= SQLCOM_UPDATE;
12368            lex->duplicates= DUP_ERROR;
12369          }
12370          opt_low_priority opt_ignore join_table_list
12371          SET update_list
12372          {
12373            LEX *lex= Lex;
12374            if (lex->select_lex.table_list.elements > 1)
12375              lex->sql_command= SQLCOM_UPDATE_MULTI;
12376            else if (lex->select_lex.get_table_list()->derived)
12377            {
12378              /* it is single table update and it is update of derived table */
12379              my_error(ER_NON_UPDATABLE_TABLE, MYF(0),
12380                       lex->select_lex.get_table_list()->alias, "UPDATE");
12381              MYSQL_YYABORT;
12382            }
12383            /*
12384              In case of multi-update setting write lock for all tables may
12385              be too pessimistic. We will decrease lock level if possible in
12386              mysql_multi_update().
12387            */
12388            Select->set_lock_for_tables($3);
12389          }
12390          where_clause opt_order_clause delete_limit_clause {}
12391        ;
12392
12393update_list:
12394          update_list ',' update_elem
12395        | update_elem
12396        ;
12397
12398update_elem:
12399          simple_ident_nospvar equal expr_or_default
12400          {
12401            if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3))
12402              MYSQL_YYABORT;
12403          }
12404        ;
12405
12406insert_update_list:
12407          insert_update_list ',' insert_update_elem
12408        | insert_update_elem
12409        ;
12410
12411insert_update_elem:
12412          simple_ident_nospvar equal expr_or_default
12413          {
12414          LEX *lex= Lex;
12415          if (lex->update_list.push_back($1) ||
12416              lex->value_list.push_back($3))
12417              MYSQL_YYABORT;
12418          }
12419        ;
12420
12421opt_low_priority:
12422          /* empty */ { $$= TL_WRITE_DEFAULT; }
12423        | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
12424        ;
12425
12426/* Delete rows from a table */
12427
12428delete:
12429          DELETE_SYM
12430          {
12431            LEX *lex= Lex;
12432            lex->sql_command= SQLCOM_DELETE;
12433            mysql_init_select(lex);
12434            YYPS->m_lock_type= TL_WRITE_DEFAULT;
12435            YYPS->m_mdl_type= MDL_SHARED_WRITE;
12436
12437            lex->ignore= 0;
12438            lex->select_lex.init_order();
12439          }
12440          opt_delete_options single_multi
12441        ;
12442
12443single_multi:
12444          FROM table_ident opt_use_partition
12445          {
12446            if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING,
12447                                           YYPS->m_lock_type,
12448                                           YYPS->m_mdl_type,
12449                                           NULL,
12450                                           $3))
12451              MYSQL_YYABORT;
12452            YYPS->m_lock_type= TL_READ_DEFAULT;
12453            YYPS->m_mdl_type= MDL_SHARED_READ;
12454          }
12455          where_clause opt_order_clause
12456          delete_limit_clause {}
12457        | table_wild_list
12458          {
12459            mysql_init_multi_delete(Lex);
12460            YYPS->m_lock_type= TL_READ_DEFAULT;
12461            YYPS->m_mdl_type= MDL_SHARED_READ;
12462          }
12463          FROM join_table_list where_clause
12464          {
12465            if (multi_delete_set_locks_and_link_aux_tables(Lex))
12466              MYSQL_YYABORT;
12467          }
12468        | FROM table_alias_ref_list
12469          {
12470            mysql_init_multi_delete(Lex);
12471            YYPS->m_lock_type= TL_READ_DEFAULT;
12472            YYPS->m_mdl_type= MDL_SHARED_READ;
12473          }
12474          USING join_table_list where_clause
12475          {
12476            if (multi_delete_set_locks_and_link_aux_tables(Lex))
12477              MYSQL_YYABORT;
12478          }
12479        ;
12480
12481table_wild_list:
12482          table_wild_one
12483        | table_wild_list ',' table_wild_one
12484        ;
12485
12486table_wild_one:
12487          ident opt_wild
12488          {
12489            Table_ident *ti= new Table_ident($1);
12490            if (ti == NULL)
12491              MYSQL_YYABORT;
12492            if (!Select->add_table_to_list(YYTHD,
12493                                           ti,
12494                                           NULL,
12495                                           TL_OPTION_UPDATING | TL_OPTION_ALIAS,
12496                                           YYPS->m_lock_type,
12497                                           YYPS->m_mdl_type))
12498              MYSQL_YYABORT;
12499          }
12500        | ident '.' ident opt_wild
12501          {
12502            Table_ident *ti= new Table_ident(YYTHD, $1, $3, 0);
12503            if (ti == NULL)
12504              MYSQL_YYABORT;
12505            if (!Select->add_table_to_list(YYTHD,
12506                                           ti,
12507                                           NULL,
12508                                           TL_OPTION_UPDATING | TL_OPTION_ALIAS,
12509                                           YYPS->m_lock_type,
12510                                           YYPS->m_mdl_type))
12511              MYSQL_YYABORT;
12512          }
12513        ;
12514
12515opt_wild:
12516          /* empty */ {}
12517        | '.' '*' {}
12518        ;
12519
12520opt_delete_options:
12521          /* empty */ {}
12522        | opt_delete_option opt_delete_options {}
12523        ;
12524
12525opt_delete_option:
12526          QUICK        { Select->options|= OPTION_QUICK; }
12527        | LOW_PRIORITY { YYPS->m_lock_type= TL_WRITE_LOW_PRIORITY; }
12528        | IGNORE_SYM   { Lex->ignore= 1; }
12529        ;
12530
12531truncate:
12532          TRUNCATE_SYM opt_table_sym
12533          {
12534            LEX* lex= Lex;
12535            lex->sql_command= SQLCOM_TRUNCATE;
12536            lex->alter_info.reset();
12537            lex->select_lex.options= 0;
12538            lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
12539            lex->select_lex.init_order();
12540            YYPS->m_lock_type= TL_WRITE;
12541            YYPS->m_mdl_type= MDL_EXCLUSIVE;
12542          }
12543          table_name
12544          {
12545            THD *thd= YYTHD;
12546            LEX* lex= thd->lex;
12547            DBUG_ASSERT(!lex->m_sql_cmd);
12548            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_truncate_table();
12549            if (lex->m_sql_cmd == NULL)
12550              MYSQL_YYABORT;
12551          }
12552        ;
12553
12554opt_table_sym:
12555          /* empty */
12556        | TABLE_SYM
12557        ;
12558
12559opt_profile_defs:
12560  /* empty */
12561  | profile_defs;
12562
12563profile_defs:
12564  profile_def
12565  | profile_defs ',' profile_def;
12566
12567profile_def:
12568  CPU_SYM
12569    {
12570      Lex->profile_options|= PROFILE_CPU;
12571    }
12572  | MEMORY_SYM
12573    {
12574      Lex->profile_options|= PROFILE_MEMORY;
12575    }
12576  | BLOCK_SYM IO_SYM
12577    {
12578      Lex->profile_options|= PROFILE_BLOCK_IO;
12579    }
12580  | CONTEXT_SYM SWITCHES_SYM
12581    {
12582      Lex->profile_options|= PROFILE_CONTEXT;
12583    }
12584  | PAGE_SYM FAULTS_SYM
12585    {
12586      Lex->profile_options|= PROFILE_PAGE_FAULTS;
12587    }
12588  | IPC_SYM
12589    {
12590      Lex->profile_options|= PROFILE_IPC;
12591    }
12592  | SWAPS_SYM
12593    {
12594      Lex->profile_options|= PROFILE_SWAPS;
12595    }
12596  | SOURCE_SYM
12597    {
12598      Lex->profile_options|= PROFILE_SOURCE;
12599    }
12600  | ALL
12601    {
12602      Lex->profile_options|= PROFILE_ALL;
12603    }
12604  ;
12605
12606opt_profile_args:
12607  /* empty */
12608    {
12609      Lex->profile_query_id= 0;
12610    }
12611  | FOR_SYM QUERY_SYM NUM
12612    {
12613      Lex->profile_query_id= atoi($3.str);
12614    }
12615  ;
12616
12617/* Show things */
12618
12619show:
12620          SHOW
12621          {
12622            LEX *lex=Lex;
12623            lex->wild=0;
12624            mysql_init_select(lex);
12625            lex->current_select->parsing_place= SELECT_LIST;
12626            memset(static_cast<void*>(&lex->create_info), 0,
12627                   sizeof(lex->create_info));
12628          }
12629          show_param
12630          {
12631            Select->parsing_place= NO_MATTER;
12632          }
12633        ;
12634
12635show_param:
12636           DATABASES wild_and_where
12637           {
12638             LEX *lex= Lex;
12639             lex->sql_command= SQLCOM_SHOW_DATABASES;
12640             if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA))
12641               MYSQL_YYABORT;
12642           }
12643         | opt_full TABLES opt_db wild_and_where
12644           {
12645             LEX *lex= Lex;
12646             lex->sql_command= SQLCOM_SHOW_TABLES;
12647             lex->select_lex.db= $3;
12648             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES))
12649               MYSQL_YYABORT;
12650           }
12651         | opt_full TRIGGERS_SYM opt_db wild_and_where
12652           {
12653             LEX *lex= Lex;
12654             lex->sql_command= SQLCOM_SHOW_TRIGGERS;
12655             lex->select_lex.db= $3;
12656             if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS))
12657               MYSQL_YYABORT;
12658           }
12659         | EVENTS_SYM opt_db wild_and_where
12660           {
12661             LEX *lex= Lex;
12662             lex->sql_command= SQLCOM_SHOW_EVENTS;
12663             lex->select_lex.db= $2;
12664             if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS))
12665               MYSQL_YYABORT;
12666           }
12667         | TABLE_SYM STATUS_SYM opt_db wild_and_where
12668           {
12669             LEX *lex= Lex;
12670             lex->sql_command= SQLCOM_SHOW_TABLE_STATUS;
12671             lex->select_lex.db= $3;
12672             if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES))
12673               MYSQL_YYABORT;
12674           }
12675        | OPEN_SYM TABLES opt_db wild_and_where
12676          {
12677            LEX *lex= Lex;
12678            lex->sql_command= SQLCOM_SHOW_OPEN_TABLES;
12679            lex->select_lex.db= $3;
12680            if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES))
12681              MYSQL_YYABORT;
12682          }
12683        | PLUGINS_SYM
12684          {
12685            LEX *lex= Lex;
12686            lex->sql_command= SQLCOM_SHOW_PLUGINS;
12687            if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS))
12688              MYSQL_YYABORT;
12689          }
12690        | ENGINE_SYM known_storage_engines show_engine_param
12691          { Lex->create_info.db_type= $2; }
12692        | ENGINE_SYM ALL show_engine_param
12693          { Lex->create_info.db_type= NULL; }
12694        | opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
12695          {
12696            LEX *lex= Lex;
12697            lex->sql_command= SQLCOM_SHOW_FIELDS;
12698            if ($5)
12699              $4->change_db($5);
12700            if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS))
12701              MYSQL_YYABORT;
12702          }
12703        | master_or_binary LOGS_SYM
12704          {
12705            Lex->sql_command = SQLCOM_SHOW_BINLOGS;
12706          }
12707        | SLAVE HOSTS_SYM
12708          {
12709            Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS;
12710          }
12711        | BINLOG_SYM EVENTS_SYM binlog_in binlog_from
12712          {
12713            LEX *lex= Lex;
12714            lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS;
12715          } opt_limit_clause_init
12716        | RELAYLOG_SYM EVENTS_SYM binlog_in binlog_from
12717          {
12718            LEX *lex= Lex;
12719            lex->sql_command= SQLCOM_SHOW_RELAYLOG_EVENTS;
12720          } opt_limit_clause_init
12721        | keys_or_index from_or_in table_ident opt_db where_clause
12722          {
12723            LEX *lex= Lex;
12724            lex->sql_command= SQLCOM_SHOW_KEYS;
12725            if ($4)
12726              $3->change_db($4);
12727            if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS))
12728              MYSQL_YYABORT;
12729          }
12730        | opt_storage ENGINES_SYM
12731          {
12732            LEX *lex=Lex;
12733            lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES;
12734            if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES))
12735              MYSQL_YYABORT;
12736          }
12737        | PRIVILEGES
12738          {
12739            LEX *lex=Lex;
12740            lex->sql_command= SQLCOM_SHOW_PRIVILEGES;
12741          }
12742        | COUNT_SYM '(' '*' ')' WARNINGS
12743          { (void) create_select_for_variable("warning_count"); }
12744        | COUNT_SYM '(' '*' ')' ERRORS
12745          { (void) create_select_for_variable("error_count"); }
12746        | WARNINGS opt_limit_clause_init
12747          { Lex->sql_command = SQLCOM_SHOW_WARNS;}
12748        | ERRORS opt_limit_clause_init
12749          { Lex->sql_command = SQLCOM_SHOW_ERRORS;}
12750        | PROFILES_SYM
12751          {
12752            push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
12753                                ER_WARN_DEPRECATED_SYNTAX,
12754                                ER(ER_WARN_DEPRECATED_SYNTAX),
12755                                "SHOW PROFILES", "Performance Schema");
12756            Lex->sql_command = SQLCOM_SHOW_PROFILES;
12757          }
12758        | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause_init
12759          {
12760            push_warning_printf(YYTHD, Sql_condition::WARN_LEVEL_WARN,
12761                                ER_WARN_DEPRECATED_SYNTAX,
12762                                ER(ER_WARN_DEPRECATED_SYNTAX),
12763                                "SHOW PROFILE", "Performance Schema");
12764            LEX *lex= Lex;
12765            lex->sql_command= SQLCOM_SHOW_PROFILE;
12766            if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
12767              YYABORT;
12768          }
12769        | opt_var_type STATUS_SYM wild_and_where
12770          {
12771            LEX *lex= Lex;
12772            lex->sql_command= SQLCOM_SHOW_STATUS;
12773            lex->option_type= $1;
12774            if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS))
12775              MYSQL_YYABORT;
12776          }
12777        | opt_full PROCESSLIST_SYM
12778          { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;}
12779        | opt_var_type  VARIABLES wild_and_where
12780          {
12781            LEX *lex= Lex;
12782            lex->sql_command= SQLCOM_SHOW_VARIABLES;
12783            lex->option_type= $1;
12784            if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES))
12785              MYSQL_YYABORT;
12786          }
12787        | charset wild_and_where
12788          {
12789            LEX *lex= Lex;
12790            lex->sql_command= SQLCOM_SHOW_CHARSETS;
12791            if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS))
12792              MYSQL_YYABORT;
12793          }
12794        | COLLATION_SYM wild_and_where
12795          {
12796            LEX *lex= Lex;
12797            lex->sql_command= SQLCOM_SHOW_COLLATIONS;
12798            if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS))
12799              MYSQL_YYABORT;
12800          }
12801        | GRANTS
12802          {
12803            LEX *lex=Lex;
12804            lex->sql_command= SQLCOM_SHOW_GRANTS;
12805            LEX_USER *curr_user;
12806            if (!(curr_user= (LEX_USER*) lex->thd->alloc(sizeof(st_lex_user))))
12807              MYSQL_YYABORT;
12808            memset(curr_user, 0, sizeof(st_lex_user));
12809            lex->grant_user= curr_user;
12810          }
12811        | GRANTS FOR_SYM user
12812          {
12813            LEX *lex=Lex;
12814            lex->sql_command= SQLCOM_SHOW_GRANTS;
12815            lex->grant_user=$3;
12816            lex->grant_user->password=null_lex_str;
12817          }
12818        | CREATE DATABASE opt_if_not_exists ident
12819          {
12820            Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
12821            Lex->create_info.options=$3;
12822            Lex->name= $4;
12823          }
12824        | CREATE TABLE_SYM table_ident
12825          {
12826            LEX *lex= Lex;
12827            lex->sql_command = SQLCOM_SHOW_CREATE;
12828            if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0))
12829              MYSQL_YYABORT;
12830            lex->only_view= 0;
12831            lex->create_info.storage_media= HA_SM_DEFAULT;
12832          }
12833        | CREATE VIEW_SYM table_ident
12834          {
12835            LEX *lex= Lex;
12836            lex->sql_command = SQLCOM_SHOW_CREATE;
12837            if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0))
12838              MYSQL_YYABORT;
12839            lex->only_view= 1;
12840          }
12841        | MASTER_SYM STATUS_SYM
12842          {
12843            Lex->sql_command = SQLCOM_SHOW_MASTER_STAT;
12844          }
12845        | SLAVE STATUS_SYM
12846          {
12847            Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
12848          }
12849	/* SHOW SLAVE STATUS NOLOCK */
12850        | SLAVE STATUS_SYM NOLOCK_SYM
12851          {
12852            Lex->sql_command = SQLCOM_SHOW_SLAVE_NOLOCK_STAT;
12853          }
12854        | SLAVE STATUS_SYM NONBLOCKING_SYM
12855          {
12856	    Lex->sql_command = SQLCOM_SHOW_SLAVE_NOLOCK_STAT;
12857          }
12858        | CLIENT_STATS_SYM wild_and_where
12859          {
12860           LEX *lex= Lex;
12861           Lex->sql_command= SQLCOM_SHOW_CLIENT_STATS;
12862           if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
12863             MYSQL_YYABORT;
12864          }
12865        | USER_STATS_SYM wild_and_where
12866          {
12867           LEX *lex= Lex;
12868           lex->sql_command= SQLCOM_SHOW_USER_STATS;
12869           if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
12870             MYSQL_YYABORT;
12871          }
12872        | THREAD_STATS_SYM wild_and_where
12873          {
12874           LEX *lex= Lex;
12875           Lex->sql_command= SQLCOM_SHOW_THREAD_STATS;
12876           if (prepare_schema_table(YYTHD, lex, 0, SCH_THREAD_STATS))
12877             MYSQL_YYABORT;
12878          }
12879        | TABLE_STATS_SYM wild_and_where
12880          {
12881           LEX *lex= Lex;
12882           lex->sql_command= SQLCOM_SHOW_TABLE_STATS;
12883           if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
12884             MYSQL_YYABORT;
12885          }
12886        | INDEX_STATS_SYM wild_and_where
12887          {
12888           LEX *lex= Lex;
12889           lex->sql_command= SQLCOM_SHOW_INDEX_STATS;
12890           if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
12891             MYSQL_YYABORT;
12892          }
12893        | CREATE PROCEDURE_SYM sp_name
12894          {
12895            LEX *lex= Lex;
12896
12897            lex->sql_command = SQLCOM_SHOW_CREATE_PROC;
12898            lex->spname= $3;
12899          }
12900        | CREATE FUNCTION_SYM sp_name
12901          {
12902            LEX *lex= Lex;
12903
12904            lex->sql_command = SQLCOM_SHOW_CREATE_FUNC;
12905            lex->spname= $3;
12906          }
12907        | CREATE TRIGGER_SYM sp_name
12908          {
12909            LEX *lex= Lex;
12910            lex->sql_command= SQLCOM_SHOW_CREATE_TRIGGER;
12911            lex->spname= $3;
12912          }
12913        | PROCEDURE_SYM STATUS_SYM wild_and_where
12914          {
12915            LEX *lex= Lex;
12916            lex->sql_command= SQLCOM_SHOW_STATUS_PROC;
12917            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
12918              MYSQL_YYABORT;
12919          }
12920        | FUNCTION_SYM STATUS_SYM wild_and_where
12921          {
12922            LEX *lex= Lex;
12923            lex->sql_command= SQLCOM_SHOW_STATUS_FUNC;
12924            if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES))
12925              MYSQL_YYABORT;
12926          }
12927        | PROCEDURE_SYM CODE_SYM sp_name
12928          {
12929            Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
12930            Lex->spname= $3;
12931          }
12932        | FUNCTION_SYM CODE_SYM sp_name
12933          {
12934            Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
12935            Lex->spname= $3;
12936          }
12937        | CREATE EVENT_SYM sp_name
12938          {
12939            Lex->spname= $3;
12940            Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT;
12941          }
12942        ;
12943
12944show_engine_param:
12945          STATUS_SYM
12946          { Lex->sql_command= SQLCOM_SHOW_ENGINE_STATUS; }
12947        | MUTEX_SYM
12948          { Lex->sql_command= SQLCOM_SHOW_ENGINE_MUTEX; }
12949        | LOGS_SYM
12950          { Lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS; }
12951        ;
12952
12953master_or_binary:
12954          MASTER_SYM
12955        | BINARY
12956        ;
12957
12958opt_storage:
12959          /* empty */
12960        | STORAGE_SYM
12961        ;
12962
12963opt_db:
12964          /* empty */  { $$= 0; }
12965        | from_or_in ident { $$= $2.str; }
12966        ;
12967
12968opt_full:
12969          /* empty */ { Lex->verbose=0; }
12970        | FULL        { Lex->verbose=1; }
12971        ;
12972
12973from_or_in:
12974          FROM
12975        | IN_SYM
12976        ;
12977
12978binlog_in:
12979          /* empty */            { Lex->mi.log_file_name = 0; }
12980        | IN_SYM TEXT_STRING_sys { Lex->mi.log_file_name = $2.str; }
12981        ;
12982
12983binlog_from:
12984          /* empty */        { Lex->mi.pos = 4; /* skip magic number */ }
12985        | FROM ulonglong_num { Lex->mi.pos = $2; }
12986        ;
12987
12988wild_and_where:
12989          /* empty */
12990        | LIKE TEXT_STRING_sys
12991          {
12992            Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length,
12993                                                    system_charset_info);
12994            if (Lex->wild == NULL)
12995              MYSQL_YYABORT;
12996          }
12997        | WHERE expr
12998          {
12999            Select->where= $2;
13000            if ($2)
13001              $2->top_level_item();
13002          }
13003        ;
13004
13005/* A Oracle compatible synonym for show */
13006describe:
13007          describe_command table_ident
13008          {
13009            LEX *lex= Lex;
13010            mysql_init_select(lex);
13011            lex->current_select->parsing_place= SELECT_LIST;
13012            lex->sql_command= SQLCOM_SHOW_FIELDS;
13013            lex->select_lex.db= 0;
13014            lex->verbose= 0;
13015            if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS))
13016              MYSQL_YYABORT;
13017          }
13018          opt_describe_column
13019          {
13020            Select->parsing_place= NO_MATTER;
13021          }
13022        | describe_command opt_extended_describe
13023          { Lex->describe|= DESCRIBE_NORMAL; }
13024          explanable_command
13025          { Lex->select_lex.options|= SELECT_DESCRIBE; }
13026        ;
13027
13028explanable_command:
13029          select
13030        | insert
13031        | replace
13032        | update
13033        | delete
13034        ;
13035
13036describe_command:
13037          DESC
13038        | DESCRIBE
13039        ;
13040
13041opt_extended_describe:
13042          /* empty */
13043          {
13044            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
13045              MYSQL_YYABORT;
13046          }
13047        | EXTENDED_SYM
13048          {
13049            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
13050              MYSQL_YYABORT;
13051            Lex->describe|= DESCRIBE_EXTENDED;
13052          }
13053        | PARTITIONS_SYM
13054          {
13055            if ((Lex->explain_format= new Explain_format_traditional) == NULL)
13056              MYSQL_YYABORT;
13057            Lex->describe|= DESCRIBE_PARTITIONS;
13058          }
13059        | FORMAT_SYM EQ ident_or_text
13060          {
13061            if (!my_strcasecmp(system_charset_info, $3.str, "JSON"))
13062            {
13063              if ((Lex->explain_format= new Explain_format_JSON) == NULL)
13064                MYSQL_YYABORT;
13065              Lex->describe|= DESCRIBE_EXTENDED | DESCRIBE_PARTITIONS;
13066            }
13067            else if (!my_strcasecmp(system_charset_info, $3.str, "TRADITIONAL"))
13068            {
13069              if ((Lex->explain_format= new Explain_format_traditional) == NULL)
13070                MYSQL_YYABORT;
13071            }
13072            else
13073            {
13074              my_error(ER_UNKNOWN_EXPLAIN_FORMAT, MYF(0), $3.str);
13075              MYSQL_YYABORT;
13076            }
13077          }
13078        ;
13079
13080opt_describe_column:
13081          /* empty */ {}
13082        | text_string { Lex->wild= $1; }
13083        | ident
13084          {
13085            Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,
13086                                                    $1.length,
13087                                                    system_charset_info);
13088            if (Lex->wild == NULL)
13089              MYSQL_YYABORT;
13090          }
13091        ;
13092
13093
13094/* flush things */
13095
13096flush:
13097          FLUSH_SYM opt_no_write_to_binlog
13098          {
13099            LEX *lex=Lex;
13100            lex->sql_command= SQLCOM_FLUSH;
13101            lex->type= 0;
13102            lex->no_write_to_binlog= $2;
13103          }
13104          flush_options
13105          {}
13106        ;
13107
13108flush_options:
13109          table_or_tables
13110          {
13111            Lex->type|= REFRESH_TABLES;
13112            /*
13113              Set type of metadata and table locks for
13114              FLUSH TABLES table_list [WITH READ LOCK].
13115            */
13116            YYPS->m_lock_type= TL_READ_NO_INSERT;
13117            YYPS->m_mdl_type= MDL_SHARED_HIGH_PRIO;
13118          }
13119          opt_table_list {}
13120          opt_flush_lock {}
13121        | flush_options_list
13122        ;
13123
13124opt_flush_lock:
13125          /* empty */ {}
13126        | WITH READ_SYM LOCK_SYM
13127          {
13128            TABLE_LIST *tables= Lex->query_tables;
13129            Lex->type|= REFRESH_READ_LOCK;
13130            for (; tables; tables= tables->next_global)
13131            {
13132              tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
13133              tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
13134              tables->open_type= OT_BASE_ONLY;      /* Ignore temporary tables. */
13135            }
13136          }
13137        | FOR_SYM
13138          {
13139            if (Lex->query_tables == NULL) // Table list can't be empty
13140            {
13141              my_parse_error(ER(ER_NO_TABLES_USED));
13142              MYSQL_YYABORT;
13143            }
13144          }
13145          EXPORT_SYM
13146          {
13147            TABLE_LIST *tables= Lex->query_tables;
13148            Lex->type|= REFRESH_FOR_EXPORT;
13149            for (; tables; tables= tables->next_global)
13150            {
13151              tables->mdl_request.set_type(MDL_SHARED_NO_WRITE);
13152              tables->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
13153              tables->open_type= OT_BASE_ONLY;      /* Ignore temporary tables. */
13154            }
13155          }
13156        ;
13157
13158flush_options_list:
13159          flush_options_list ',' flush_option
13160        | flush_option
13161          {}
13162        ;
13163
13164flush_option:
13165          ERROR_SYM LOGS_SYM
13166          { Lex->type|= REFRESH_ERROR_LOG; }
13167        | ENGINE_SYM LOGS_SYM
13168          { Lex->type|= REFRESH_ENGINE_LOG; }
13169        | GENERAL LOGS_SYM
13170          { Lex->type|= REFRESH_GENERAL_LOG; }
13171        | SLOW LOGS_SYM
13172          { Lex->type|= REFRESH_SLOW_LOG; }
13173        | BINARY LOGS_SYM
13174          { Lex->type|= REFRESH_BINARY_LOG; }
13175        | RELAY LOGS_SYM
13176          { Lex->type|= REFRESH_RELAY_LOG; }
13177        | QUERY_SYM CACHE_SYM
13178          { Lex->type|= REFRESH_QUERY_CACHE_FREE; }
13179        | HOSTS_SYM
13180          { Lex->type|= REFRESH_HOSTS; }
13181        | PRIVILEGES
13182          { Lex->type|= REFRESH_GRANT; }
13183        | LOGS_SYM
13184          { Lex->type|= REFRESH_LOG; }
13185        | STATUS_SYM
13186          { Lex->type|= REFRESH_STATUS; }
13187        | CLIENT_STATS_SYM
13188          { Lex->type|= REFRESH_CLIENT_STATS; }
13189        | USER_STATS_SYM
13190          { Lex->type|= REFRESH_USER_STATS; }
13191        | THREAD_STATS_SYM
13192          { Lex->type|= REFRESH_THREAD_STATS; }
13193        | TABLE_STATS_SYM
13194          { Lex->type|= REFRESH_TABLE_STATS; }
13195        | INDEX_STATS_SYM
13196          { Lex->type|= REFRESH_INDEX_STATS; }
13197        | DES_KEY_FILE
13198          { Lex->type|= REFRESH_DES_KEY_FILE; }
13199        | RESOURCES
13200          { Lex->type|= REFRESH_USER_RESOURCES; }
13201        | CHANGED_PAGE_BITMAPS_SYM
13202          { Lex->type|= REFRESH_FLUSH_PAGE_BITMAPS; }
13203        ;
13204
13205opt_table_list:
13206          /* empty */  {}
13207        | table_list {}
13208        ;
13209
13210reset:
13211          RESET_SYM
13212          {
13213            LEX *lex=Lex;
13214            lex->sql_command= SQLCOM_RESET; lex->type=0;
13215          }
13216          reset_options
13217          {}
13218        ;
13219
13220reset_options:
13221          reset_options ',' reset_option
13222        | reset_option
13223        ;
13224
13225reset_option:
13226          SLAVE               { Lex->type|= REFRESH_SLAVE; }
13227          slave_reset_options { }
13228        | MASTER_SYM          { Lex->type|= REFRESH_MASTER; }
13229        | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}
13230        | CHANGED_PAGE_BITMAPS_SYM
13231          { Lex->type |= REFRESH_RESET_PAGE_BITMAPS; }
13232        ;
13233
13234slave_reset_options:
13235          /* empty */ { Lex->reset_slave_info.all= false; }
13236        | ALL         { Lex->reset_slave_info.all= true; }
13237        ;
13238
13239purge:
13240          PURGE
13241          {
13242            LEX *lex=Lex;
13243            lex->type=0;
13244            lex->sql_command = SQLCOM_PURGE;
13245          }
13246          purge_options
13247          {}
13248        ;
13249
13250purge_options:
13251          master_or_binary LOGS_SYM purge_option
13252        | CHANGED_PAGE_BITMAPS_SYM BEFORE_SYM real_ulonglong_num
13253          {
13254            LEX *lex= Lex;
13255            lex->value_list.empty();
13256            lex->value_list.push_front(new Item_uint($3));
13257            lex->type= PURGE_BITMAPS_TO_LSN;
13258          }
13259        |  ARCHIVED_SYM LOGS_SYM purge_archive_option
13260        ;
13261
13262purge_option:
13263          TO_SYM TEXT_STRING_sys
13264          {
13265            Lex->to_log = $2.str;
13266          }
13267        | BEFORE_SYM expr
13268          {
13269            LEX *lex= Lex;
13270            lex->value_list.empty();
13271            lex->value_list.push_front($2);
13272            lex->sql_command= SQLCOM_PURGE_BEFORE;
13273          }
13274        ;
13275
13276purge_archive_option:
13277          TO_SYM TEXT_STRING_sys
13278          {
13279            Lex->to_log = $2.str;
13280            Lex->sql_command= SQLCOM_PURGE_ARCHIVE;
13281          }
13282        | BEFORE_SYM expr
13283          {
13284            LEX *lex= Lex;
13285            lex->value_list.empty();
13286            lex->value_list.push_front($2);
13287            lex->sql_command= SQLCOM_PURGE_ARCHIVE_BEFORE;
13288          }
13289        ;
13290
13291/* kill threads */
13292
13293kill:
13294          KILL_SYM kill_option expr
13295          {
13296            LEX *lex=Lex;
13297            lex->value_list.empty();
13298            lex->value_list.push_front($3);
13299            lex->sql_command= SQLCOM_KILL;
13300          }
13301        ;
13302
13303kill_option:
13304          /* empty */ { Lex->type= 0; }
13305        | CONNECTION_SYM { Lex->type= 0; }
13306        | QUERY_SYM      { Lex->type= ONLY_KILL_QUERY; }
13307        ;
13308
13309/* change database */
13310
13311use:
13312          USE_SYM ident
13313          {
13314            LEX *lex=Lex;
13315            lex->sql_command=SQLCOM_CHANGE_DB;
13316            lex->select_lex.db= $2.str;
13317          }
13318        ;
13319
13320/* import, export of files */
13321
13322load:
13323          LOAD data_or_xml
13324          {
13325            THD *thd= YYTHD;
13326            LEX *lex= thd->lex;
13327
13328            if (lex->sphead)
13329            {
13330              my_error(ER_SP_BADSTATEMENT, MYF(0),
13331                       $2 == FILETYPE_CSV ? "LOAD DATA" : "LOAD XML");
13332              MYSQL_YYABORT;
13333            }
13334          }
13335          load_data_lock opt_local INFILE TEXT_STRING_filesystem
13336          {
13337            LEX *lex=Lex;
13338            lex->sql_command= SQLCOM_LOAD;
13339            lex->local_file=  $5;
13340            lex->duplicates= DUP_ERROR;
13341            lex->ignore= 0;
13342            if (!(lex->exchange= new sql_exchange($7.str, 0, $2)))
13343              MYSQL_YYABORT;
13344          }
13345          opt_duplicate INTO TABLE_SYM table_ident opt_use_partition
13346          {
13347            LEX *lex=Lex;
13348            if (!Select->add_table_to_list(YYTHD, $12, NULL, TL_OPTION_UPDATING,
13349                                           $4, MDL_SHARED_WRITE, NULL, $13))
13350              MYSQL_YYABORT;
13351            lex->field_list.empty();
13352            lex->update_list.empty();
13353            lex->value_list.empty();
13354          }
13355          opt_load_data_charset
13356          { Lex->exchange->cs= $15; }
13357          opt_xml_rows_identified_by
13358          opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec
13359          opt_load_data_set_spec
13360          {}
13361          ;
13362
13363data_or_xml:
13364        DATA_SYM  { $$= FILETYPE_CSV; }
13365        | XML_SYM { $$= FILETYPE_XML; }
13366        ;
13367
13368opt_local:
13369          /* empty */ { $$=0;}
13370        | LOCAL_SYM { $$=1;}
13371        ;
13372
13373load_data_lock:
13374          /* empty */ { $$= TL_WRITE_DEFAULT; }
13375        | CONCURRENT
13376          {
13377#ifdef HAVE_QUERY_CACHE
13378            /*
13379              Ignore this option in SP to avoid problem with query cache
13380            */
13381            if (Lex->sphead != 0)
13382              $$= TL_WRITE_DEFAULT;
13383            else
13384#endif
13385              $$= TL_WRITE_CONCURRENT_INSERT;
13386          }
13387        | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }
13388        ;
13389
13390opt_duplicate:
13391          /* empty */ { Lex->duplicates=DUP_ERROR; }
13392        | REPLACE { Lex->duplicates=DUP_REPLACE; }
13393        | IGNORE_SYM { Lex->ignore= 1; }
13394        ;
13395
13396opt_field_term:
13397          /* empty */
13398        | COLUMNS field_term_list
13399        ;
13400
13401field_term_list:
13402          field_term_list field_term
13403        | field_term
13404        ;
13405
13406field_term:
13407          TERMINATED BY text_string
13408          {
13409            DBUG_ASSERT(Lex->exchange != 0);
13410            Lex->exchange->field_term= $3;
13411          }
13412        | OPTIONALLY ENCLOSED BY text_string
13413          {
13414            LEX *lex= Lex;
13415            DBUG_ASSERT(lex->exchange != 0);
13416            lex->exchange->enclosed= $4;
13417            lex->exchange->opt_enclosed= 1;
13418          }
13419        | ENCLOSED BY text_string
13420          {
13421            DBUG_ASSERT(Lex->exchange != 0);
13422            Lex->exchange->enclosed= $3;
13423          }
13424        | ESCAPED BY text_string
13425          {
13426            DBUG_ASSERT(Lex->exchange != 0);
13427            Lex->exchange->escaped= $3;
13428          }
13429        ;
13430
13431opt_line_term:
13432          /* empty */
13433        | LINES line_term_list
13434        ;
13435
13436line_term_list:
13437          line_term_list line_term
13438        | line_term
13439        ;
13440
13441line_term:
13442          TERMINATED BY text_string
13443          {
13444            DBUG_ASSERT(Lex->exchange != 0);
13445            Lex->exchange->line_term= $3;
13446          }
13447        | STARTING BY text_string
13448          {
13449            DBUG_ASSERT(Lex->exchange != 0);
13450            Lex->exchange->line_start= $3;
13451          }
13452        ;
13453
13454opt_xml_rows_identified_by:
13455        /* empty */ { }
13456        | ROWS_SYM IDENTIFIED_SYM BY text_string
13457          { Lex->exchange->line_term = $4; };
13458
13459opt_ignore_lines:
13460          /* empty */
13461        | IGNORE_SYM NUM lines_or_rows
13462          {
13463            DBUG_ASSERT(Lex->exchange != 0);
13464            Lex->exchange->skip_lines= atol($2.str);
13465          }
13466        ;
13467
13468lines_or_rows:
13469        LINES { }
13470
13471        | ROWS_SYM { }
13472        ;
13473
13474opt_field_or_var_spec:
13475          /* empty */ {}
13476        | '(' fields_or_vars ')' {}
13477        | '(' ')' {}
13478        ;
13479
13480fields_or_vars:
13481          fields_or_vars ',' field_or_var
13482          { Lex->field_list.push_back($3); }
13483        | field_or_var
13484          { Lex->field_list.push_back($1); }
13485        ;
13486
13487field_or_var:
13488          simple_ident_nospvar {$$= $1;}
13489        | '@' ident_or_text
13490          {
13491            $$= new (YYTHD->mem_root) Item_user_var_as_out_param($2);
13492            if ($$ == NULL)
13493              MYSQL_YYABORT;
13494          }
13495        ;
13496
13497opt_load_data_set_spec:
13498          /* empty */ {}
13499        | SET load_data_set_list {}
13500        ;
13501
13502load_data_set_list:
13503          load_data_set_list ',' load_data_set_elem
13504        | load_data_set_elem
13505        ;
13506
13507load_data_set_elem:
13508          simple_ident_nospvar equal remember_name expr_or_default remember_end
13509          {
13510            LEX *lex= Lex;
13511            uint length= (uint) ($5 - $3);
13512            String *val= new (YYTHD->mem_root) String($3,
13513                                                      length,
13514                                                      YYTHD->charset());
13515            if (val == NULL)
13516              MYSQL_YYABORT;
13517            if (lex->update_list.push_back($1) ||
13518                lex->value_list.push_back($4) ||
13519                lex->load_set_str_list.push_back(val))
13520                MYSQL_YYABORT;
13521            $4->item_name.copy($3, length, YYTHD->charset());
13522          }
13523        ;
13524
13525/* Common definitions */
13526
13527text_literal:
13528          TEXT_STRING
13529          {
13530            LEX_STRING tmp;
13531            THD *thd= YYTHD;
13532            const CHARSET_INFO *cs_con= thd->variables.collation_connection;
13533            const CHARSET_INFO *cs_cli= thd->variables.character_set_client;
13534            uint repertoire= thd->lex->text_string_is_7bit &&
13535                             my_charset_is_ascii_based(cs_cli) ?
13536                             MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
13537            if (thd->charset_is_collation_connection ||
13538                (repertoire == MY_REPERTOIRE_ASCII &&
13539                 my_charset_is_ascii_based(cs_con)))
13540              tmp= $1;
13541            else
13542            {
13543              if (thd->convert_string(&tmp, cs_con, $1.str, $1.length, cs_cli))
13544                MYSQL_YYABORT;
13545            }
13546            $$= new (thd->mem_root) Item_string(tmp.str, tmp.length, cs_con,
13547                                                DERIVATION_COERCIBLE,
13548                                                repertoire);
13549            if ($$ == NULL)
13550              MYSQL_YYABORT;
13551          }
13552        | NCHAR_STRING
13553          {
13554            uint repertoire= Lex->text_string_is_7bit ?
13555                             MY_REPERTOIRE_ASCII : MY_REPERTOIRE_UNICODE30;
13556            DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
13557            $$= new (YYTHD->mem_root) Item_string($1.str, $1.length,
13558                                                  national_charset_info,
13559                                                  DERIVATION_COERCIBLE,
13560                                                  repertoire);
13561            if ($$ == NULL)
13562              MYSQL_YYABORT;
13563          }
13564        | UNDERSCORE_CHARSET TEXT_STRING
13565          {
13566            Item_string *str= new (YYTHD->mem_root) Item_string($2.str,
13567                                                                $2.length, $1);
13568            if (str == NULL)
13569              MYSQL_YYABORT;
13570            str->set_repertoire_from_value();
13571            str->set_cs_specified(TRUE);
13572
13573            $$= str;
13574          }
13575        | text_literal TEXT_STRING_literal
13576          {
13577            Item_string* item= (Item_string*) $1;
13578            item->append($2.str, $2.length);
13579            if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
13580            {
13581              /*
13582                 If the string has been pure ASCII so far,
13583                 check the new part.
13584              */
13585              const CHARSET_INFO *cs= YYTHD->variables.collation_connection;
13586              item->collation.repertoire|= my_string_repertoire(cs,
13587                                                                $2.str,
13588                                                                $2.length);
13589            }
13590          }
13591        ;
13592
13593text_string:
13594          TEXT_STRING_literal
13595          {
13596            $$= new (YYTHD->mem_root) String($1.str,
13597                                             $1.length,
13598                                             YYTHD->variables.collation_connection);
13599            if ($$ == NULL)
13600              MYSQL_YYABORT;
13601          }
13602        | HEX_NUM
13603          {
13604            Item *tmp= new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
13605            if (tmp == NULL)
13606              MYSQL_YYABORT;
13607            /*
13608              it is OK only emulate fix_fields, because we need only
13609              value of constant
13610            */
13611            tmp->quick_fix_field();
13612            $$= tmp->val_str((String*) 0);
13613          }
13614        | BIN_NUM
13615          {
13616            Item *tmp= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
13617            if (tmp == NULL)
13618              MYSQL_YYABORT;
13619            /*
13620              it is OK only emulate fix_fields, because we need only
13621              value of constant
13622            */
13623            tmp->quick_fix_field();
13624            $$= tmp->val_str((String*) 0);
13625          }
13626        ;
13627
13628param_marker:
13629          PARAM_MARKER
13630          {
13631            THD *thd= YYTHD;
13632            LEX *lex= thd->lex;
13633            Lex_input_stream *lip= YYLIP;
13634            Item_param *item;
13635            if (! lex->parsing_options.allows_variable)
13636            {
13637              my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
13638              MYSQL_YYABORT;
13639            }
13640            item= new (thd->mem_root) Item_param((uint) (lip->get_tok_start() - thd->query()));
13641            if (!($$= item) || lex->param_list.push_back(item))
13642            {
13643              my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
13644              MYSQL_YYABORT;
13645            }
13646          }
13647        ;
13648
13649signed_literal:
13650          literal { $$ = $1; }
13651        | '+' NUM_literal { $$ = $2; }
13652        | '-' NUM_literal
13653          {
13654            $2->max_length++;
13655            $$= $2->neg();
13656          }
13657        ;
13658
13659
13660literal:
13661          text_literal { $$ = $1; }
13662        | NUM_literal { $$ = $1; }
13663        | temporal_literal { $$= $1; }
13664        | NULL_SYM
13665          {
13666            Lex_input_stream *lip= YYLIP;
13667            /*
13668              For the digest computation, in this context only,
13669              NULL is considered a literal, hence reduced to '?'
13670              REDUCE:
13671                TOK_GENERIC_VALUE := NULL_SYM
13672            */
13673            lip->reduce_digest_token(TOK_GENERIC_VALUE, NULL_SYM);
13674            $$ = new (YYTHD->mem_root) Item_null();
13675            if ($$ == NULL)
13676              MYSQL_YYABORT;
13677            YYLIP->next_state= MY_LEX_OPERATOR_OR_IDENT;
13678          }
13679        | FALSE_SYM
13680          {
13681            $$= new (YYTHD->mem_root) Item_int(NAME_STRING("FALSE"), 0, 1);
13682            if ($$ == NULL)
13683              MYSQL_YYABORT;
13684          }
13685        | TRUE_SYM
13686          {
13687            $$= new (YYTHD->mem_root) Item_int(NAME_STRING("TRUE"), 1, 1);
13688            if ($$ == NULL)
13689              MYSQL_YYABORT;
13690          }
13691        | HEX_NUM
13692          {
13693            $$ = new (YYTHD->mem_root) Item_hex_string($1.str, $1.length);
13694            if ($$ == NULL)
13695              MYSQL_YYABORT;
13696          }
13697        | BIN_NUM
13698          {
13699            $$= new (YYTHD->mem_root) Item_bin_string($1.str, $1.length);
13700            if ($$ == NULL)
13701              MYSQL_YYABORT;
13702          }
13703        | UNDERSCORE_CHARSET HEX_NUM
13704          {
13705            Item *tmp= new (YYTHD->mem_root) Item_hex_string($2.str, $2.length);
13706            if (tmp == NULL)
13707              MYSQL_YYABORT;
13708            /*
13709              it is OK only emulate fix_fieds, because we need only
13710              value of constant
13711            */
13712            tmp->quick_fix_field();
13713            String *str= tmp->val_str((String*) 0);
13714
13715            Item_string *item_str;
13716            item_str= new (YYTHD->mem_root)
13717                        Item_string(null_name_string, /* name will be set in select_item */
13718                                    str ? str->ptr() : "",
13719                                    str ? str->length() : 0,
13720                                    $1);
13721            if (!item_str ||
13722                !item_str->check_well_formed_result(&item_str->str_value,
13723                                                    true, //send error
13724                                                    true))  //truncate
13725            {
13726              MYSQL_YYABORT;
13727            }
13728
13729            item_str->set_repertoire_from_value();
13730            item_str->set_cs_specified(TRUE);
13731
13732            $$= item_str;
13733          }
13734        | UNDERSCORE_CHARSET BIN_NUM
13735          {
13736            Item *tmp= new (YYTHD->mem_root) Item_bin_string($2.str, $2.length);
13737            if (tmp == NULL)
13738              MYSQL_YYABORT;
13739            /*
13740              it is OK only emulate fix_fieds, because we need only
13741              value of constant
13742            */
13743            tmp->quick_fix_field();
13744            String *str= tmp->val_str((String*) 0);
13745
13746            Item_string *item_str;
13747            item_str= new (YYTHD->mem_root)
13748                        Item_string(null_name_string, /* name will be set in select_item */
13749                                    str ? str->ptr() : "",
13750                                    str ? str->length() : 0,
13751                                    $1);
13752            if (!item_str ||
13753                !item_str->check_well_formed_result(&item_str->str_value,
13754                                                    true, //send error
13755                                                    true)) //truncate
13756            {
13757              MYSQL_YYABORT;
13758            }
13759
13760            item_str->set_cs_specified(TRUE);
13761
13762            $$= item_str;
13763          }
13764        ;
13765
13766NUM_literal:
13767          NUM
13768          {
13769            int error;
13770            $$= new (YYTHD->mem_root)
13771                  Item_int($1,
13772                           (longlong) my_strtoll10($1.str, NULL, &error),
13773                           $1.length);
13774            if ($$ == NULL)
13775              MYSQL_YYABORT;
13776          }
13777        | LONG_NUM
13778          {
13779            int error;
13780            $$= new (YYTHD->mem_root)
13781                  Item_int($1,
13782                           (longlong) my_strtoll10($1.str, NULL, &error),
13783                           $1.length);
13784            if ($$ == NULL)
13785              MYSQL_YYABORT;
13786          }
13787        | ULONGLONG_NUM
13788          {
13789            $$= new (YYTHD->mem_root) Item_uint($1.str, $1.length);
13790            if ($$ == NULL)
13791              MYSQL_YYABORT;
13792          }
13793        | DECIMAL_NUM
13794          {
13795            $$= new (YYTHD->mem_root) Item_decimal($1.str, $1.length,
13796                                                   YYTHD->charset());
13797            if (($$ == NULL) || (YYTHD->is_error()))
13798            {
13799              MYSQL_YYABORT;
13800            }
13801          }
13802        | FLOAT_NUM
13803          {
13804            $$= new (YYTHD->mem_root) Item_float($1.str, $1.length);
13805            if (($$ == NULL) || (YYTHD->is_error()))
13806            {
13807              MYSQL_YYABORT;
13808            }
13809          }
13810        ;
13811
13812
13813temporal_literal:
13814        DATE_SYM TEXT_STRING
13815          {
13816            if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
13817                                              MYSQL_TYPE_DATE, true)))
13818              MYSQL_YYABORT;
13819          }
13820        | TIME_SYM TEXT_STRING
13821          {
13822            if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
13823                                              MYSQL_TYPE_TIME, true)))
13824              MYSQL_YYABORT;
13825          }
13826        | TIMESTAMP TEXT_STRING
13827          {
13828            if (!($$= create_temporal_literal(YYTHD, $2.str, $2.length, YYCSCL,
13829                                              MYSQL_TYPE_DATETIME, true)))
13830              MYSQL_YYABORT;
13831          }
13832        ;
13833
13834
13835
13836
13837/**********************************************************************
13838** Creating different items.
13839**********************************************************************/
13840
13841insert_ident:
13842          simple_ident_nospvar { $$=$1; }
13843        | table_wild { $$=$1; }
13844        ;
13845
13846table_wild:
13847          ident '.' '*'
13848          {
13849            SELECT_LEX *sel= Select;
13850            $$= new (YYTHD->mem_root) Item_field(Lex->current_context(),
13851                                                 NullS, $1.str, "*");
13852            if ($$ == NULL)
13853              MYSQL_YYABORT;
13854            sel->with_wild++;
13855          }
13856        | ident '.' ident '.' '*'
13857          {
13858            THD *thd= YYTHD;
13859            SELECT_LEX *sel= Select;
13860            const char* schema= thd->client_capabilities & CLIENT_NO_SCHEMA ?
13861                                  NullS : $1.str;
13862            $$= new (thd->mem_root) Item_field(Lex->current_context(),
13863                                               schema,
13864                                               $3.str,"*");
13865            if ($$ == NULL)
13866              MYSQL_YYABORT;
13867            sel->with_wild++;
13868          }
13869        ;
13870
13871order_ident:
13872          expr { $$=$1; }
13873        ;
13874
13875simple_ident:
13876          ident
13877          {
13878            THD *thd= YYTHD;
13879            LEX *lex= thd->lex;
13880            sp_pcontext *pctx = lex->get_sp_current_parsing_ctx();
13881            sp_variable *spv;
13882
13883            if (pctx && (spv= pctx->find_variable($1, false)))
13884            {
13885              Lex_input_stream *lip= &thd->m_parser_state->m_lip;
13886              sp_head *sp= lex->sphead;
13887
13888              DBUG_ASSERT(sp);
13889
13890              /* We're compiling a stored procedure and found a variable */
13891              if (! lex->parsing_options.allows_variable)
13892              {
13893                my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
13894                MYSQL_YYABORT;
13895              }
13896
13897              $$=
13898                create_item_for_sp_var(
13899                  thd, $1, spv,
13900                  sp->m_parser_data.get_current_stmt_start_ptr(),
13901                  lip->get_tok_start_prev(),
13902                  lip->get_tok_end());
13903
13904              if ($$ == NULL)
13905                MYSQL_YYABORT;
13906
13907              lex->safe_to_cache_query= false;
13908            }
13909            else
13910            {
13911              SELECT_LEX *sel=Select;
13912              if ((sel->parsing_place != IN_HAVING) ||
13913                  (sel->get_in_sum_expr() > 0))
13914              {
13915                $$= new (thd->mem_root) Item_field(Lex->current_context(),
13916                                                   NullS, NullS, $1.str);
13917              }
13918              else
13919              {
13920                $$= new (thd->mem_root) Item_ref(Lex->current_context(),
13921                                                 NullS, NullS, $1.str);
13922              }
13923              if ($$ == NULL)
13924                MYSQL_YYABORT;
13925            }
13926          }
13927        | simple_ident_q { $$= $1; }
13928        ;
13929
13930simple_ident_nospvar:
13931          ident
13932          {
13933            THD *thd= YYTHD;
13934            SELECT_LEX *sel=Select;
13935            if ((sel->parsing_place != IN_HAVING) ||
13936                (sel->get_in_sum_expr() > 0))
13937            {
13938              $$= new (thd->mem_root) Item_field(Lex->current_context(),
13939                                                 NullS, NullS, $1.str);
13940            }
13941            else
13942            {
13943              $$= new (thd->mem_root) Item_ref(Lex->current_context(),
13944                                               NullS, NullS, $1.str);
13945            }
13946            if ($$ == NULL)
13947              MYSQL_YYABORT;
13948          }
13949        | simple_ident_q { $$= $1; }
13950        ;
13951
13952simple_ident_q:
13953          ident '.' ident
13954          {
13955            THD *thd= YYTHD;
13956            LEX *lex= thd->lex;
13957            sp_head *sp= lex->sphead;
13958
13959            /*
13960              FIXME This will work ok in simple_ident_nospvar case because
13961              we can't meet simple_ident_nospvar in trigger now. But it
13962              should be changed in future.
13963            */
13964            if (sp && sp->m_type == SP_TYPE_TRIGGER &&
13965                (!my_strcasecmp(system_charset_info, $1.str, "NEW") ||
13966                 !my_strcasecmp(system_charset_info, $1.str, "OLD")))
13967            {
13968              Item_trigger_field *trg_fld;
13969              bool new_row= ($1.str[0]=='N' || $1.str[0]=='n');
13970
13971              if (sp->m_trg_chistics.event == TRG_EVENT_INSERT &&
13972                  !new_row)
13973              {
13974                my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT");
13975                MYSQL_YYABORT;
13976              }
13977
13978              if (sp->m_trg_chistics.event == TRG_EVENT_DELETE &&
13979                  new_row)
13980              {
13981                my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE");
13982                MYSQL_YYABORT;
13983              }
13984
13985              DBUG_ASSERT(!new_row ||
13986                          (sp->m_trg_chistics.event == TRG_EVENT_INSERT ||
13987                           sp->m_trg_chistics.event == TRG_EVENT_UPDATE));
13988              const bool read_only=
13989                !(new_row && sp->m_trg_chistics.action_time == TRG_ACTION_BEFORE);
13990              trg_fld= new (thd->mem_root)
13991                         Item_trigger_field(Lex->current_context(),
13992                                            new_row ?
13993                                              Item_trigger_field::NEW_ROW:
13994                                              Item_trigger_field::OLD_ROW,
13995                                            $3.str,
13996                                            SELECT_ACL,
13997                                            read_only);
13998              if (trg_fld == NULL)
13999                MYSQL_YYABORT;
14000
14001              /*
14002                Let us add this item to list of all Item_trigger_field objects
14003                in trigger.
14004              */
14005              lex->sphead->m_cur_instr_trig_field_items.link_in_list(
14006                trg_fld, &trg_fld->next_trg_field);
14007
14008              $$= trg_fld;
14009            }
14010            else
14011            {
14012              SELECT_LEX *sel= lex->current_select;
14013              if (sel->no_table_names_allowed)
14014              {
14015                my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
14016                         MYF(0), $1.str, thd->where);
14017              }
14018              if ((sel->parsing_place != IN_HAVING) ||
14019                  (sel->get_in_sum_expr() > 0))
14020              {
14021                $$= new (thd->mem_root) Item_field(Lex->current_context(),
14022                                                   NullS, $1.str, $3.str);
14023              }
14024              else
14025              {
14026                $$= new (thd->mem_root) Item_ref(Lex->current_context(),
14027                                                 NullS, $1.str, $3.str);
14028              }
14029              if ($$ == NULL)
14030                MYSQL_YYABORT;
14031            }
14032          }
14033        | '.' ident '.' ident
14034          {
14035            THD *thd= YYTHD;
14036            LEX *lex= thd->lex;
14037            SELECT_LEX *sel= lex->current_select;
14038            if (sel->no_table_names_allowed)
14039            {
14040              my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
14041                       MYF(0), $2.str, thd->where);
14042            }
14043            if ((sel->parsing_place != IN_HAVING) ||
14044                (sel->get_in_sum_expr() > 0))
14045            {
14046              $$= new (thd->mem_root) Item_field(Lex->current_context(),
14047                                                 NullS, $2.str, $4.str);
14048
14049            }
14050            else
14051            {
14052              $$= new (thd->mem_root) Item_ref(Lex->current_context(),
14053                                               NullS, $2.str, $4.str);
14054            }
14055            if ($$ == NULL)
14056              MYSQL_YYABORT;
14057          }
14058        | ident '.' ident '.' ident
14059          {
14060            THD *thd= YYTHD;
14061            LEX *lex= thd->lex;
14062            SELECT_LEX *sel= lex->current_select;
14063            const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
14064                                 NullS : $1.str);
14065            if (sel->no_table_names_allowed)
14066            {
14067              my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
14068                       MYF(0), $3.str, thd->where);
14069            }
14070            if ((sel->parsing_place != IN_HAVING) ||
14071                (sel->get_in_sum_expr() > 0))
14072            {
14073              $$= new (thd->mem_root) Item_field(Lex->current_context(),
14074                                                 schema,
14075                                                 $3.str, $5.str);
14076            }
14077            else
14078            {
14079              $$= new (thd->mem_root) Item_ref(Lex->current_context(),
14080                                               schema,
14081                                               $3.str, $5.str);
14082            }
14083            if ($$ == NULL)
14084              MYSQL_YYABORT;
14085          }
14086        ;
14087
14088field_ident:
14089          ident { $$=$1;}
14090        | ident '.' ident '.' ident
14091          {
14092            TABLE_LIST *table= Select->table_list.first;
14093            if (my_strcasecmp(table_alias_charset, $1.str, table->db))
14094            {
14095              my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
14096              MYSQL_YYABORT;
14097            }
14098            if (my_strcasecmp(table_alias_charset, $3.str,
14099                              table->table_name))
14100            {
14101              my_error(ER_WRONG_TABLE_NAME, MYF(0), $3.str);
14102              MYSQL_YYABORT;
14103            }
14104            $$=$5;
14105          }
14106        | ident '.' ident
14107          {
14108            TABLE_LIST *table= Select->table_list.first;
14109            if (my_strcasecmp(table_alias_charset, $1.str, table->alias))
14110            {
14111              my_error(ER_WRONG_TABLE_NAME, MYF(0), $1.str);
14112              MYSQL_YYABORT;
14113            }
14114            $$=$3;
14115          }
14116        | '.' ident { $$=$2;} /* For Delphi */
14117        ;
14118
14119table_ident:
14120          ident
14121          {
14122            $$= new Table_ident($1);
14123            if ($$ == NULL)
14124              MYSQL_YYABORT;
14125          }
14126        | ident '.' ident
14127          {
14128            $$= new Table_ident(YYTHD, $1,$3,0);
14129            if ($$ == NULL)
14130              MYSQL_YYABORT;
14131          }
14132        | '.' ident
14133          {
14134            /* For Delphi */
14135            $$= new Table_ident($2);
14136            if ($$ == NULL)
14137              MYSQL_YYABORT;
14138          }
14139        ;
14140
14141table_ident_opt_wild:
14142          ident opt_wild
14143          {
14144            $$= new Table_ident($1);
14145            if ($$ == NULL)
14146              MYSQL_YYABORT;
14147          }
14148        | ident '.' ident opt_wild
14149          {
14150            $$= new Table_ident(YYTHD, $1,$3,0);
14151            if ($$ == NULL)
14152              MYSQL_YYABORT;
14153          }
14154        ;
14155
14156table_ident_nodb:
14157          ident
14158          {
14159            LEX_STRING db={(char*) any_db,3};
14160            $$= new Table_ident(YYTHD, db,$1,0);
14161            if ($$ == NULL)
14162              MYSQL_YYABORT;
14163          }
14164        ;
14165
14166IDENT_sys:
14167          IDENT { $$= $1; }
14168        | IDENT_QUOTED
14169          {
14170            THD *thd= YYTHD;
14171
14172            if (thd->charset_is_system_charset)
14173            {
14174              const CHARSET_INFO *cs= system_charset_info;
14175              int dummy_error;
14176              uint wlen= cs->cset->well_formed_len(cs, $1.str,
14177                                                   $1.str+$1.length,
14178                                                   $1.length, &dummy_error);
14179              if (wlen < $1.length)
14180              {
14181                ErrConvString err($1.str, $1.length, &my_charset_bin);
14182                my_error(ER_INVALID_CHARACTER_STRING, MYF(0),
14183                         cs->csname, err.ptr());
14184                MYSQL_YYABORT;
14185              }
14186              $$= $1;
14187            }
14188            else
14189            {
14190              if (thd->convert_string(&$$, system_charset_info,
14191                                  $1.str, $1.length, thd->charset()))
14192                MYSQL_YYABORT;
14193            }
14194          }
14195        ;
14196
14197TEXT_STRING_sys_nonewline:
14198          TEXT_STRING_sys
14199          {
14200            if (!strcont($1.str, "\n"))
14201              $$= $1;
14202            else
14203            {
14204              my_error(ER_WRONG_VALUE, MYF(0), "argument contains not-allowed LF", $1.str);
14205              MYSQL_YYABORT;
14206            }
14207          }
14208        ;
14209
14210TEXT_STRING_sys:
14211          TEXT_STRING
14212          {
14213            THD *thd= YYTHD;
14214
14215            if (thd->charset_is_system_charset)
14216              $$= $1;
14217            else
14218            {
14219              if (thd->convert_string(&$$, system_charset_info,
14220                                  $1.str, $1.length, thd->charset()))
14221                MYSQL_YYABORT;
14222            }
14223          }
14224        ;
14225
14226TEXT_STRING_literal:
14227          TEXT_STRING
14228          {
14229            THD *thd= YYTHD;
14230
14231            if (thd->charset_is_collation_connection)
14232              $$= $1;
14233            else
14234            {
14235              if (thd->convert_string(&$$, thd->variables.collation_connection,
14236                                  $1.str, $1.length, thd->charset()))
14237                MYSQL_YYABORT;
14238            }
14239          }
14240        ;
14241
14242TEXT_STRING_filesystem:
14243          TEXT_STRING
14244          {
14245            THD *thd= YYTHD;
14246
14247            if (thd->charset_is_character_set_filesystem)
14248              $$= $1;
14249            else
14250            {
14251              if (thd->convert_string(&$$,
14252                                      thd->variables.character_set_filesystem,
14253                                      $1.str, $1.length, thd->charset()))
14254                MYSQL_YYABORT;
14255            }
14256          }
14257        ;
14258
14259ident:
14260          IDENT_sys    { $$=$1; }
14261        | keyword
14262          {
14263            THD *thd= YYTHD;
14264            $$.str= thd->strmake($1.str, $1.length);
14265            if ($$.str == NULL)
14266              MYSQL_YYABORT;
14267            $$.length= $1.length;
14268          }
14269        ;
14270
14271label_ident:
14272          IDENT_sys    { $$=$1; }
14273        | keyword_sp
14274          {
14275            THD *thd= YYTHD;
14276            $$.str= thd->strmake($1.str, $1.length);
14277            if ($$.str == NULL)
14278              MYSQL_YYABORT;
14279            $$.length= $1.length;
14280          }
14281        ;
14282
14283ident_or_text:
14284          ident           { $$=$1;}
14285        | TEXT_STRING_sys { $$=$1;}
14286        | LEX_HOSTNAME { $$=$1;}
14287        ;
14288
14289user:
14290          ident_or_text
14291          {
14292            THD *thd= YYTHD;
14293            if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
14294              MYSQL_YYABORT;
14295            $$->user= $1;
14296            $$->host.str= (char *) "%";
14297            $$->host.length= 1;
14298            $$->password= null_lex_str;
14299            $$->plugin= empty_lex_str;
14300            $$->auth= empty_lex_str;
14301            $$->uses_identified_by_clause= false;
14302            $$->uses_identified_with_clause= false;
14303            $$->uses_identified_by_password_clause= false;
14304            $$->uses_authentication_string_clause= false;
14305
14306            /*
14307              Trim whitespace as the values will go to a CHAR field
14308              when stored.
14309            */
14310            trim_whitespace(system_charset_info, &$$->user);
14311
14312            if (check_string_char_length(&$$->user, ER(ER_USERNAME),
14313                                         USERNAME_CHAR_LENGTH,
14314                                         system_charset_info, 0))
14315              MYSQL_YYABORT;
14316          }
14317        | ident_or_text '@' ident_or_text
14318          {
14319            THD *thd= YYTHD;
14320            if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
14321              MYSQL_YYABORT;
14322            $$->user= $1;
14323            $$->host= $3;
14324            $$->password= null_lex_str;
14325            $$->plugin= empty_lex_str;
14326            $$->auth= empty_lex_str;
14327            $$->uses_identified_by_clause= false;
14328            $$->uses_identified_with_clause= false;
14329            $$->uses_identified_by_password_clause= false;
14330            $$->uses_authentication_string_clause= false;
14331
14332            if (check_string_char_length(&$$->user, ER(ER_USERNAME),
14333                                         USERNAME_CHAR_LENGTH,
14334                                         system_charset_info, 0) ||
14335                check_host_name(&$$->host))
14336              MYSQL_YYABORT;
14337            /*
14338              Convert hostname part of username to lowercase.
14339              It's OK to use in-place lowercase as long as
14340              the character set is utf8.
14341            */
14342            my_casedn_str(system_charset_info, $$->host.str);
14343            /*
14344              Trim whitespace as the values will go to a CHAR field
14345              when stored.
14346            */
14347            trim_whitespace(system_charset_info, &$$->user);
14348            trim_whitespace(system_charset_info, &$$->host);
14349          }
14350        | CURRENT_USER optional_braces
14351          {
14352            if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
14353              MYSQL_YYABORT;
14354            /*
14355              empty LEX_USER means current_user and
14356              will be handled in the  get_current_user() function
14357              later
14358            */
14359            memset($$, 0, sizeof(LEX_USER));
14360          }
14361        ;
14362
14363/* Keyword that we allow for identifiers (except SP labels) */
14364keyword:
14365          keyword_sp            {}
14366        | ASCII_SYM             {}
14367        | BACKUP_SYM            {}
14368        | BEGIN_SYM             {}
14369        | BYTE_SYM              {}
14370        | CACHE_SYM             {}
14371        | CHARSET               {}
14372        | CHECKSUM_SYM          {}
14373        | CLOSE_SYM             {}
14374        | COMMENT_SYM           {}
14375        | COMMIT_SYM            {}
14376        | CONTAINS_SYM          {}
14377        | DEALLOCATE_SYM        {}
14378        | DO_SYM                {}
14379        | END                   {}
14380        | EXECUTE_SYM           {}
14381        | FLUSH_SYM             {}
14382        | FORMAT_SYM            {}
14383        | HANDLER_SYM           {}
14384        | HELP_SYM              {}
14385        | HOST_SYM              {}
14386        | INSTALL_SYM           {}
14387        | LANGUAGE_SYM          {}
14388        | NO_SYM                {}
14389        | OPEN_SYM              {}
14390        | OPTIONS_SYM           {}
14391        | OWNER_SYM             {}
14392        | PARSER_SYM            {}
14393        | PORT_SYM              {}
14394        | PREPARE_SYM           {}
14395        | REMOVE_SYM            {}
14396        | REPAIR                {}
14397        | RESET_SYM             {}
14398        | RESTORE_SYM           {}
14399        | ROLLBACK_SYM          {}
14400        | SAVEPOINT_SYM         {}
14401        | SECURITY_SYM          {}
14402        | SERVER_SYM            {}
14403        | SIGNED_SYM            {}
14404        | SOCKET_SYM            {}
14405        | SLAVE                 {}
14406        | SONAME_SYM            {}
14407        | START_SYM             {}
14408        | STOP_SYM              {}
14409        | TRUNCATE_SYM          {}
14410        | UNICODE_SYM           {}
14411        | UNINSTALL_SYM         {}
14412        | WRAPPER_SYM           {}
14413        | XA_SYM                {}
14414        | UPGRADE_SYM           {}
14415        ;
14416
14417/*
14418 * Keywords that we allow for labels in SPs.
14419 * Anything that's the beginning of a statement or characteristics
14420 * must be in keyword above, otherwise we get (harmful) shift/reduce
14421 * conflicts.
14422 */
14423keyword_sp:
14424          ACTION                   {}
14425        | ADDDATE_SYM              {}
14426        | AFTER_SYM                {}
14427        | AGAINST                  {}
14428        | AGGREGATE_SYM            {}
14429        | ALGORITHM_SYM            {}
14430        | ANALYSE_SYM              {}
14431        | ARCHIVED_SYM             {}
14432        | ANY_SYM                  {}
14433        | AT_SYM                   {}
14434        | AUTO_INC                 {}
14435        | AUTOEXTEND_SIZE_SYM      {}
14436        | AVG_ROW_LENGTH           {}
14437        | AVG_SYM                  {}
14438        | BINLOG_SYM               {}
14439        | BIT_SYM                  {}
14440        | BLOCK_SYM                {}
14441        | BOOL_SYM                 {}
14442        | BOOLEAN_SYM              {}
14443        | BTREE_SYM                {}
14444        | CASCADED                 {}
14445        | CATALOG_NAME_SYM         {}
14446        | CHAIN_SYM                {}
14447        | CHANGED                  {}
14448        | CHANGED_PAGE_BITMAPS_SYM {}
14449        | CIPHER_SYM               {}
14450        | CLIENT_STATS_SYM         {}
14451        | CLIENT_SYM               {}
14452        | CLASS_ORIGIN_SYM         {}
14453        | COALESCE                 {}
14454        | CODE_SYM                 {}
14455        | COLLATION_SYM            {}
14456        | COLUMN_NAME_SYM          {}
14457        | COLUMN_FORMAT_SYM        {}
14458        | COLUMNS                  {}
14459        | COMMITTED_SYM            {}
14460        | COMPACT_SYM              {}
14461        | COMPLETION_SYM           {}
14462        | COMPRESSED_SYM           {}
14463        | COMPRESSION_DICTIONARY_SYM {}
14464        | CONCURRENT               {}
14465        | CONNECTION_SYM           {}
14466        | CONSISTENT_SYM           {}
14467        | CONSTRAINT_CATALOG_SYM   {}
14468        | CONSTRAINT_SCHEMA_SYM    {}
14469        | CONSTRAINT_NAME_SYM      {}
14470        | CONTEXT_SYM              {}
14471        | CPU_SYM                  {}
14472        | CUBE_SYM                 {}
14473        /*
14474          Although a reserved keyword in SQL:2003 (and :2008),
14475          not reserved in MySQL per WL#2111 specification.
14476        */
14477        | CURRENT_SYM              {}
14478        | CURSOR_NAME_SYM          {}
14479        | DATA_SYM                 {}
14480        | DATAFILE_SYM             {}
14481        | DATETIME                 {}
14482        | DATE_SYM                 {}
14483        | DAY_SYM                  {}
14484        | DEFAULT_AUTH_SYM         {}
14485        | DEFINER_SYM              {}
14486        | DELAY_KEY_WRITE_SYM      {}
14487        | DES_KEY_FILE             {}
14488        | DIAGNOSTICS_SYM          {}
14489        | DIRECTORY_SYM            {}
14490        | DISABLE_SYM              {}
14491        | DISCARD                  {}
14492        | DISK_SYM                 {}
14493        | DUMPFILE                 {}
14494        | DUPLICATE_SYM            {}
14495        | DYNAMIC_SYM              {}
14496        | ENDS_SYM                 {}
14497        | ENUM                     {}
14498        | ENGINE_SYM               {}
14499        | ENGINES_SYM              {}
14500        | ERROR_SYM                {}
14501        | ERRORS                   {}
14502        | ESCAPE_SYM               {}
14503        | EVENT_SYM                {}
14504        | EVENTS_SYM               {}
14505        | EVERY_SYM                {}
14506        | EXCHANGE_SYM             {}
14507        | EXPANSION_SYM            {}
14508        | EXPIRE_SYM               {}
14509        | EXPORT_SYM               {}
14510        | EXTENDED_SYM             {}
14511        | EXTENT_SIZE_SYM          {}
14512        | FAULTS_SYM               {}
14513        | FAST_SYM                 {}
14514        | FOUND_SYM                {}
14515        | ENABLE_SYM               {}
14516        | FULL                     {}
14517        | FILE_SYM                 {}
14518        | FIRST_SYM                {}
14519        | FIXED_SYM                {}
14520        | GENERAL                  {}
14521        | GEOMETRY_SYM             {}
14522        | GEOMETRYCOLLECTION       {}
14523        | GET_FORMAT               {}
14524        | GRANTS                   {}
14525        | GLOBAL_SYM               {}
14526        | HASH_SYM                 {}
14527        | HOSTS_SYM                {}
14528        | HOUR_SYM                 {}
14529        | IDENTIFIED_SYM           {}
14530        | INDEX_STATS_SYM          {}
14531        | IGNORE_SERVER_IDS_SYM    {}
14532        | INVOKER_SYM              {}
14533        | IMPORT                   {}
14534        | INDEXES                  {}
14535        | INITIAL_SIZE_SYM         {}
14536        | IO_SYM                   {}
14537        | IPC_SYM                  {}
14538        | ISOLATION                {}
14539        | ISSUER_SYM               {}
14540        | INSERT_METHOD            {}
14541        | KEY_BLOCK_SIZE           {}
14542        | LAST_SYM                 {}
14543        | LEAVES                   {}
14544        | LESS_SYM                 {}
14545        | LEVEL_SYM                {}
14546        | LINESTRING               {}
14547        | LIST_SYM                 {}
14548        | LOCAL_SYM                {}
14549        | LOCKS_SYM                {}
14550        | LOGFILE_SYM              {}
14551        | LOGS_SYM                 {}
14552        | MAX_ROWS                 {}
14553        | MASTER_SYM               {}
14554        | MASTER_HEARTBEAT_PERIOD_SYM {}
14555        | MASTER_HOST_SYM          {}
14556        | MASTER_PORT_SYM          {}
14557        | MASTER_LOG_FILE_SYM      {}
14558        | MASTER_LOG_POS_SYM       {}
14559        | MASTER_USER_SYM          {}
14560        | MASTER_PASSWORD_SYM      {}
14561        | MASTER_SERVER_ID_SYM     {}
14562        | MASTER_CONNECT_RETRY_SYM {}
14563        | MASTER_RETRY_COUNT_SYM   {}
14564        | MASTER_DELAY_SYM         {}
14565        | MASTER_SSL_SYM           {}
14566        | MASTER_SSL_CA_SYM        {}
14567        | MASTER_SSL_CAPATH_SYM    {}
14568        | MASTER_SSL_CERT_SYM      {}
14569        | MASTER_SSL_CIPHER_SYM    {}
14570        | MASTER_SSL_CRL_SYM       {}
14571        | MASTER_SSL_CRLPATH_SYM   {}
14572        | MASTER_SSL_KEY_SYM       {}
14573        | MASTER_AUTO_POSITION_SYM {}
14574        | MAX_CONNECTIONS_PER_HOUR {}
14575        | MAX_QUERIES_PER_HOUR     {}
14576        | MAX_SIZE_SYM             {}
14577        | MAX_UPDATES_PER_HOUR     {}
14578        | MAX_USER_CONNECTIONS_SYM {}
14579        | MEDIUM_SYM               {}
14580        | MEMORY_SYM               {}
14581        | MERGE_SYM                {}
14582        | MESSAGE_TEXT_SYM         {}
14583        | MICROSECOND_SYM          {}
14584        | MIGRATE_SYM              {}
14585        | MINUTE_SYM               {}
14586        | MIN_ROWS                 {}
14587        | MODIFY_SYM               {}
14588        | MODE_SYM                 {}
14589        | MONTH_SYM                {}
14590        | MULTILINESTRING          {}
14591        | MULTIPOINT               {}
14592        | MULTIPOLYGON             {}
14593        | MUTEX_SYM                {}
14594        | MYSQL_ERRNO_SYM          {}
14595        | NAME_SYM                 {}
14596        | NAMES_SYM                {}
14597        | NATIONAL_SYM             {}
14598        | NCHAR_SYM                {}
14599        | NDBCLUSTER_SYM           {}
14600        | NEXT_SYM                 {}
14601        | NEW_SYM                  {}
14602        | NO_WAIT_SYM              {}
14603        | NODEGROUP_SYM            {}
14604        | NONE_SYM                 {}
14605        | NUMBER_SYM               {}
14606        | NVARCHAR_SYM             {}
14607        | OFFSET_SYM               {}
14608        | OLD_PASSWORD             {}
14609        | ONE_SYM                  {}
14610        | ONLY_SYM                 {}
14611        | PACK_KEYS_SYM            {}
14612        | PAGE_SYM                 {}
14613        | PARTIAL                  {}
14614        | PARTITIONING_SYM         {}
14615        | PARTITIONS_SYM           {}
14616        | PASSWORD                 {}
14617        | PHASE_SYM                {}
14618        | PLUGIN_DIR_SYM           {}
14619        | PLUGIN_SYM               {}
14620        | PLUGINS_SYM              {}
14621        | POINT_SYM                {}
14622        | POLYGON                  {}
14623        | PRESERVE_SYM             {}
14624        | PREV_SYM                 {}
14625        | PRIVILEGES               {}
14626        | PROCESS                  {}
14627        | PROCESSLIST_SYM          {}
14628        | PROFILE_SYM              {}
14629        | PROFILES_SYM             {}
14630        | PROXY_SYM                {}
14631        | QUARTER_SYM              {}
14632        | QUERY_SYM                {}
14633        | QUICK                    {}
14634        | READ_ONLY_SYM            {}
14635        | REBUILD_SYM              {}
14636        | RECOVER_SYM              {}
14637        | REDO_BUFFER_SIZE_SYM     {}
14638        | REDOFILE_SYM             {}
14639        | REDUNDANT_SYM            {}
14640        | RELAY                    {}
14641        | RELAYLOG_SYM             {}
14642        | RELAY_LOG_FILE_SYM       {}
14643        | RELAY_LOG_POS_SYM        {}
14644        | RELAY_THREAD             {}
14645        | RELOAD                   {}
14646        | REORGANIZE_SYM           {}
14647        | REPEATABLE_SYM           {}
14648        | REPLICATION              {}
14649        | RESOURCES                {}
14650        | RESUME_SYM               {}
14651        | RETURNED_SQLSTATE_SYM    {}
14652        | RETURNS_SYM              {}
14653        | REVERSE_SYM              {}
14654        | ROLLUP_SYM               {}
14655        | ROUTINE_SYM              {}
14656        | ROWS_SYM                 {}
14657        | ROW_COUNT_SYM            {}
14658        | ROW_FORMAT_SYM           {}
14659        | ROW_SYM                  {}
14660        | RTREE_SYM                {}
14661        | SCHEDULE_SYM             {}
14662        | SCHEMA_NAME_SYM          {}
14663        | SECOND_SYM               {}
14664        | SERIAL_SYM               {}
14665        | SERIALIZABLE_SYM         {}
14666        | SESSION_SYM              {}
14667        | SIMPLE_SYM               {}
14668        | SHARE_SYM                {}
14669        | SHUTDOWN                 {}
14670        | SLOW                     {}
14671        | SNAPSHOT_SYM             {}
14672        | SOUNDS_SYM               {}
14673        | SOURCE_SYM               {}
14674        | SQL_AFTER_GTIDS          {}
14675        | SQL_AFTER_MTS_GAPS       {}
14676        | SQL_BEFORE_GTIDS         {}
14677        | SQL_CACHE_SYM            {}
14678        | SQL_BUFFER_RESULT        {}
14679        | SQL_NO_CACHE_SYM         {}
14680        | SQL_THREAD               {}
14681        | STARTS_SYM               {}
14682        | STATS_AUTO_RECALC_SYM    {}
14683        | STATS_PERSISTENT_SYM     {}
14684        | STATS_SAMPLE_PAGES_SYM   {}
14685        | STATEMENT_SYM            {}
14686        | STATUS_SYM               {}
14687        | STORAGE_SYM              {}
14688        | STRING_SYM               {}
14689        | SUBCLASS_ORIGIN_SYM      {}
14690        | SUBDATE_SYM              {}
14691        | SUBJECT_SYM              {}
14692        | SUBPARTITION_SYM         {}
14693        | SUBPARTITIONS_SYM        {}
14694        | SUPER_SYM                {}
14695        | SUSPEND_SYM              {}
14696        | SWAPS_SYM                {}
14697        | SWITCHES_SYM             {}
14698        | TABLE_STATS_SYM          {}
14699        | TABLE_NAME_SYM           {}
14700        | TABLES                   {}
14701        | TABLE_CHECKSUM_SYM       {}
14702        | TABLESPACE               {}
14703        | TEMPORARY                {}
14704        | TEMPTABLE_SYM            {}
14705        | TEXT_SYM                 {}
14706        | THAN_SYM                 {}
14707        | THREAD_STATS_SYM         {}
14708        | TRANSACTION_SYM          {}
14709        | TRIGGERS_SYM             {}
14710        | TIMESTAMP                {}
14711        | TIMESTAMP_ADD            {}
14712        | TIMESTAMP_DIFF           {}
14713        | TIME_SYM                 {}
14714        | TOKU_UNCOMPRESSED_SYM    {}
14715        | TOKU_ZLIB_SYM            {}
14716        | TOKU_SNAPPY_SYM          {}
14717        | TOKU_QUICKLZ_SYM         {}
14718        | TOKU_LZMA_SYM            {}
14719        | TOKU_SMALL_SYM           {}
14720        | TOKU_FAST_SYM            {}
14721        | TOKU_DEFAULT_SYM         {}
14722        | TYPES_SYM                {}
14723        | TYPE_SYM                 {}
14724        | UDF_RETURNS_SYM          {}
14725        | FUNCTION_SYM             {}
14726        | UNCOMMITTED_SYM          {}
14727        | UNDEFINED_SYM            {}
14728        | UNDO_BUFFER_SIZE_SYM     {}
14729        | UNDOFILE_SYM             {}
14730        | UNKNOWN_SYM              {}
14731        | UNTIL_SYM                {}
14732        | USER                     {}
14733        | USER_STATS_SYM           {}
14734        | USE_FRM                  {}
14735        | VARIABLES                {}
14736        | VIEW_SYM                 {}
14737        | VALUE_SYM                {}
14738        | WARNINGS                 {}
14739        | WAIT_SYM                 {}
14740        | WEEK_SYM                 {}
14741        | WORK_SYM                 {}
14742        | WEIGHT_STRING_SYM        {}
14743        | X509_SYM                 {}
14744        | XML_SYM                  {}
14745        | YEAR_SYM                 {}
14746        ;
14747
14748/*
14749  SQLCOM_SET_OPTION statement.
14750
14751  Note that to avoid shift/reduce conflicts, we have separate rules for the
14752  first option listed in the statement.
14753*/
14754
14755set:
14756          SET
14757          {
14758            LEX *lex= Lex;
14759            mysql_init_select(lex);
14760            lex->sql_command= SQLCOM_SET_OPTION;
14761            lex->option_type= OPT_SESSION;
14762            lex->var_list.empty();
14763            lex->one_shot_set= 0;
14764            lex->autocommit= 0;
14765
14766            sp_create_assignment_lex(YYTHD, YY_TOKEN_END);
14767          }
14768          start_option_value_list
14769          {}
14770        | SET STATEMENT_SYM
14771          {
14772            LEX *lex= Lex;
14773            mysql_init_select(lex);
14774            lex->sql_command= SQLCOM_SET_OPTION;
14775	    /* Don't clear var_list in the case of recursive statement */
14776	    if (!lex->set_statement)
14777              lex->var_list.empty();
14778            lex->one_shot_set= 0;
14779            lex->autocommit= 0;
14780            lex->set_statement= true;
14781            lex->option_type= OPT_SESSION;
14782            sp_head *sp= lex->sphead;
14783            if (sp && !sp->is_invoked())
14784            {
14785              sp->m_parser_data.set_current_stmt_start_ptr(YY_TOKEN_START);
14786              sp->m_parser_data.set_option_start_ptr(YY_TOKEN_END);
14787            }
14788          }
14789          set_stmt_option_value_following_option_type_list FOR_SYM statement
14790	  {}
14791        ;
14792
14793set_stmt_option_value_following_option_type_list:
14794	/*
14795	  Only system variables can be used here. If this condition is changed
14796	  please check careful code under lex->option_type == OPT_STATEMENT
14797	  condition on wrong type casts.
14798	*/
14799          option_value_following_option_type
14800        | set_stmt_option_value_following_option_type_list ',' option_value_following_option_type
14801
14802// Start of option value list
14803start_option_value_list:
14804          option_value_no_option_type
14805          {
14806            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14807              MYSQL_YYABORT;
14808          }
14809          option_value_list_continued
14810        | TRANSACTION_SYM
14811          {
14812            Lex->option_type= OPT_DEFAULT;
14813          }
14814          transaction_characteristics
14815          {
14816            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14817              MYSQL_YYABORT;
14818          }
14819        | option_type
14820          {
14821            Lex->option_type= $1;
14822          }
14823          start_option_value_list_following_option_type
14824        ;
14825
14826
14827// Start of option value list, option_type was given
14828start_option_value_list_following_option_type:
14829          option_value_following_option_type
14830          {
14831            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14832              MYSQL_YYABORT;
14833          }
14834          option_value_list_continued
14835        | TRANSACTION_SYM transaction_characteristics
14836          {
14837            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14838              MYSQL_YYABORT;
14839          }
14840        ;
14841
14842// Remainder of the option value list after first option value.
14843option_value_list_continued:
14844          /* empty */
14845        | ',' option_value_list
14846        ;
14847
14848// Repeating list of option values after first option value.
14849option_value_list:
14850          {
14851            sp_create_assignment_lex(YYTHD, YY_TOKEN_START);
14852          }
14853          option_value
14854          {
14855            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14856              MYSQL_YYABORT;
14857          }
14858        | option_value_list ','
14859          {
14860            sp_create_assignment_lex(YYTHD, YY_TOKEN_START);
14861          }
14862          option_value
14863          {
14864            if (sp_create_assignment_instr(YYTHD, YY_TOKEN_END))
14865              MYSQL_YYABORT;
14866          }
14867        ;
14868
14869// Wrapper around option values following the first option value in the stmt.
14870option_value:
14871          option_type
14872          {
14873            Lex->option_type= $1;
14874          }
14875          option_value_following_option_type
14876        | option_value_no_option_type
14877        ;
14878
14879option_type:
14880          GLOBAL_SYM  { $$=OPT_GLOBAL; }
14881        | LOCAL_SYM   { $$=OPT_SESSION; }
14882        | SESSION_SYM { $$=OPT_SESSION; }
14883        ;
14884
14885opt_var_type:
14886          /* empty */ { $$=OPT_SESSION; }
14887        | GLOBAL_SYM  { $$=OPT_GLOBAL; }
14888        | LOCAL_SYM   { $$=OPT_SESSION; }
14889        | SESSION_SYM { $$=OPT_SESSION; }
14890        ;
14891
14892opt_var_ident_type:
14893          /* empty */     { $$=OPT_DEFAULT; }
14894        | GLOBAL_SYM '.'  { $$=OPT_GLOBAL; }
14895        | LOCAL_SYM '.'   { $$=OPT_SESSION; }
14896        | SESSION_SYM '.' { $$=OPT_SESSION; }
14897        ;
14898
14899// Option values with preceeding option_type.
14900option_value_following_option_type:
14901          internal_variable_name equal set_expr_or_default
14902          {
14903            THD *thd= YYTHD;
14904            LEX *lex= Lex;
14905            /*
14906              Ignore SET STATEMENT variables list on slaves because system
14907              variables are not replicated except certain variables set the
14908              values of whose are written to binlog event header and nothing
14909              additional is required to set them.
14910	    */
14911            if (!thd->slave_thread || !lex->set_statement)
14912	    {
14913              if ($1.var && $1.var != trg_new_row_fake_var)
14914              {
14915                /* It is a system variable. */
14916                if (set_system_variable(thd, &$1, lex->option_type, $3))
14917                  MYSQL_YYABORT;
14918              }
14919              else
14920              {
14921                /*
14922                  Not in trigger assigning value to new row,
14923                  and option_type preceeding local variable is illegal.
14924                */
14925                my_parse_error(ER(ER_SYNTAX_ERROR));
14926                MYSQL_YYABORT;
14927              }
14928            }
14929	  }
14930        ;
14931
14932// Option values without preceeding option_type.
14933option_value_no_option_type:
14934          internal_variable_name equal
14935          {
14936            sp_head *sp= Lex->sphead;
14937
14938            if (sp)
14939              sp->m_parser_data.push_expr_start_ptr(YY_TOKEN_START);
14940          }
14941          set_expr_or_default
14942          {
14943            THD *thd= YYTHD;
14944            LEX *lex= Lex;
14945            sp_head *sp= lex->sphead;
14946            const char *expr_start_ptr= NULL;
14947
14948            if (sp)
14949              expr_start_ptr= sp->m_parser_data.pop_expr_start_ptr();
14950
14951            if ($1.var == trg_new_row_fake_var)
14952            {
14953              DBUG_ASSERT(sp);
14954              DBUG_ASSERT(expr_start_ptr);
14955
14956              /* We are parsing trigger and this is a trigger NEW-field. */
14957
14958              LEX_STRING expr_query= EMPTY_STR;
14959
14960              if (!$4)
14961              {
14962                // This is: SET NEW.x = DEFAULT
14963                // DEFAULT clause is not supported in triggers.
14964
14965                my_parse_error(ER(ER_SYNTAX_ERROR));
14966                MYSQL_YYABORT;
14967              }
14968              else if (lex->is_metadata_used())
14969              {
14970                expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
14971
14972                if (!expr_query.str)
14973                  MYSQL_YYABORT;
14974              }
14975
14976              if (set_trigger_new_row(thd, $1.base_name, $4, expr_query))
14977                MYSQL_YYABORT;
14978            }
14979            else if ($1.var)
14980            {
14981              /* We're not parsing SP and this is a system variable. */
14982
14983              if (set_system_variable(thd, &$1, lex->option_type, $4))
14984                MYSQL_YYABORT;
14985            }
14986            else
14987            {
14988              DBUG_ASSERT(sp);
14989              DBUG_ASSERT(expr_start_ptr);
14990
14991              /* We're parsing SP and this is an SP-variable. */
14992
14993              sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
14994              sp_variable *spv= pctx->find_variable($1.base_name, false);
14995
14996              LEX_STRING expr_query= EMPTY_STR;
14997
14998              if (!$4)
14999              {
15000                // This is: SET x = DEFAULT, where x is a SP-variable.
15001                // This is not supported.
15002
15003                my_parse_error(ER(ER_SYNTAX_ERROR));
15004                MYSQL_YYABORT;
15005              }
15006              else if (lex->is_metadata_used())
15007              {
15008                expr_query= make_string(thd, expr_start_ptr, YY_TOKEN_END);
15009
15010                if (!expr_query.str)
15011                  MYSQL_YYABORT;
15012              }
15013
15014              /*
15015                NOTE: every SET-expression has its own LEX-object, even if it is
15016                a multiple SET-statement, like:
15017
15018                  SET spv1 = expr1, spv2 = expr2, ...
15019
15020                Every SET-expression has its own sp_instr_set. Thus, the
15021                instruction owns the LEX-object, i.e. the instruction is
15022                responsible for destruction of the LEX-object.
15023              */
15024
15025              sp_instr_set *i=
15026                new sp_instr_set(sp->instructions(), lex,
15027                                 spv->offset, $4, expr_query,
15028                                 true); // The instruction owns its lex.
15029
15030              if (!i || sp->add_instr(thd, i))
15031                MYSQL_YYABORT;
15032            }
15033          }
15034        | '@' ident_or_text equal expr
15035          {
15036            Item_func_set_user_var *item;
15037            item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4, false);
15038            if (item == NULL)
15039              MYSQL_YYABORT;
15040            set_var_user *var= new set_var_user(item);
15041            if (var == NULL)
15042              MYSQL_YYABORT;
15043            Lex->var_list.push_back(var);
15044          }
15045        | '@' '@' opt_var_ident_type internal_variable_name
15046          {
15047            if ($4.var == trg_new_row_fake_var)
15048            {
15049              my_parse_error(ER(ER_SYNTAX_ERROR));
15050              MYSQL_YYABORT;
15051            }
15052          }
15053          equal set_expr_or_default
15054          {
15055            THD *thd= YYTHD;
15056            struct sys_var_with_base tmp= $4;
15057            /* Lookup if necessary: must be a system variable. */
15058            if (tmp.var == NULL)
15059            {
15060              if (find_sys_var_null_base(thd, &tmp))
15061                MYSQL_YYABORT;
15062            }
15063            if (set_system_variable(thd, &tmp, $3, $7))
15064              MYSQL_YYABORT;
15065          }
15066        | charset old_or_new_charset_name_or_default
15067          {
15068            THD *thd= YYTHD;
15069            LEX *lex= thd->lex;
15070            int flags= $2 ? 0 : set_var_collation_client::SET_CS_DEFAULT;
15071            const CHARSET_INFO *cs2;
15072            cs2= $2 ? $2: global_system_variables.character_set_client;
15073            set_var_collation_client *var;
15074            var= new set_var_collation_client(flags,
15075                                              cs2,
15076                                              thd->variables.collation_database,
15077                                              cs2);
15078            if (var == NULL)
15079              MYSQL_YYABORT;
15080            lex->var_list.push_back(var);
15081          }
15082        | NAMES_SYM equal expr
15083          {
15084            LEX *lex= Lex;
15085            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
15086            LEX_STRING names= { C_STRING_WITH_LEN("names") };
15087
15088            if (pctx && pctx->find_variable(names, false))
15089              my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
15090            else
15091              my_parse_error(ER(ER_SYNTAX_ERROR));
15092
15093            MYSQL_YYABORT;
15094          }
15095        | NAMES_SYM charset_name_or_default opt_collate
15096          {
15097            LEX *lex= Lex;
15098            const CHARSET_INFO *cs2;
15099            const CHARSET_INFO *cs3;
15100            int flags= set_var_collation_client::SET_CS_NAMES
15101                       | ($2 ? 0 : set_var_collation_client::SET_CS_DEFAULT)
15102                       | ($3 ? set_var_collation_client::SET_CS_COLLATE : 0);
15103            cs2= $2 ? $2 : global_system_variables.character_set_client;
15104            cs3= $3 ? $3 : cs2;
15105            if (!my_charset_same(cs2, cs3))
15106            {
15107              my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
15108                       cs3->name, cs2->csname);
15109              MYSQL_YYABORT;
15110            }
15111            set_var_collation_client *var;
15112            var= new set_var_collation_client(flags, cs3, cs3, cs3);
15113            if (var == NULL)
15114              MYSQL_YYABORT;
15115            lex->var_list.push_back(var);
15116          }
15117        | PASSWORD equal text_or_password
15118          {
15119            THD *thd= YYTHD;
15120            LEX *lex= thd->lex;
15121            sp_head *sp= lex->sphead;
15122            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
15123            LEX_STRING pw= { C_STRING_WITH_LEN("password") };
15124
15125            if (pctx && pctx->find_variable(pw, false))
15126            {
15127              my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str);
15128              MYSQL_YYABORT;
15129            }
15130
15131            LEX_USER *user= (LEX_USER*) thd->alloc(sizeof(LEX_USER));
15132
15133            if (!user)
15134              MYSQL_YYABORT;
15135
15136            user->host=null_lex_str;
15137            user->user.str=thd->security_ctx->user;
15138            user->user.length= strlen(thd->security_ctx->user);
15139
15140            set_var_password *var= new set_var_password(user, $3);
15141            if (var == NULL)
15142              MYSQL_YYABORT;
15143
15144            lex->var_list.push_back(var);
15145            lex->autocommit= TRUE;
15146            lex->is_set_password_sql= true;
15147            lex->is_change_password= TRUE;
15148            lex->contains_plaintext_password= true;
15149
15150            if (sp)
15151              sp->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
15152          }
15153        | PASSWORD FOR_SYM user equal text_or_password
15154          {
15155            LEX_USER *user= $3;
15156            LEX *lex= Lex;
15157            set_var_password *var;
15158
15159            var= new set_var_password(user,$5);
15160            if (var == NULL)
15161              MYSQL_YYABORT;
15162            lex->var_list.push_back(var);
15163            lex->autocommit= TRUE;
15164            lex->is_set_password_sql= true;
15165            if (lex->sphead)
15166              lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
15167            /*
15168              'is_change_password' should be set if the user is setting his
15169              own password. This is later used to determine if the password
15170              expiration flag should be reset.
15171              Either the user exactly matches the currently authroized user or
15172              the CURRENT_USER keyword was used.
15173
15174              If CURRENT_USER was used for the <user> rule then
15175              user->user.str=0. See rule below:
15176
15177              user:
15178                 [..]
15179              | CURRENT_USER optional_braces
15180                {
15181                 [..]
15182                  memset($$, 0, sizeof(LEX_USER));
15183                }
15184            */
15185            if (user->user.str ||
15186                match_authorized_user(&current_thd->main_security_ctx,
15187                                      user))
15188              lex->is_change_password= TRUE;
15189            else
15190              lex->is_change_password= FALSE;
15191          }
15192        ;
15193
15194internal_variable_name:
15195          ident
15196          {
15197            THD *thd= YYTHD;
15198            LEX *lex= thd->lex;
15199            sp_pcontext *pctx= lex->get_sp_current_parsing_ctx();
15200            sp_variable *spv;
15201
15202            /* Best effort lookup for system variable. */
15203            if (!pctx || !(spv= pctx->find_variable($1, false)))
15204            {
15205              struct sys_var_with_base tmp= {NULL, $1};
15206
15207              /* Not an SP local variable */
15208              if (find_sys_var_null_base(thd, &tmp))
15209                MYSQL_YYABORT;
15210
15211              $$= tmp;
15212            }
15213            else
15214            {
15215              /*
15216                Possibly an SP local variable (or a shadowed sysvar).
15217                Will depend on the context of the SET statement.
15218              */
15219              $$.var= NULL;
15220              $$.base_name= $1;
15221            }
15222          }
15223        | ident '.' ident
15224          {
15225            LEX *lex= Lex;
15226            sp_head *sp= lex->sphead;
15227
15228            if (check_reserved_words(&$1))
15229            {
15230              my_parse_error(ER(ER_SYNTAX_ERROR));
15231              MYSQL_YYABORT;
15232            }
15233
15234            if (sp && sp->m_type == SP_TYPE_TRIGGER &&
15235                (!my_strcasecmp(system_charset_info, $1.str, "NEW") ||
15236                 !my_strcasecmp(system_charset_info, $1.str, "OLD")))
15237            {
15238              if ($1.str[0]=='O' || $1.str[0]=='o')
15239              {
15240                my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", "");
15241                MYSQL_YYABORT;
15242              }
15243              if (sp->m_trg_chistics.event == TRG_EVENT_DELETE)
15244              {
15245                my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0),
15246                         "NEW", "on DELETE");
15247                MYSQL_YYABORT;
15248              }
15249              if (sp->m_trg_chistics.action_time == TRG_ACTION_AFTER)
15250              {
15251                my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after ");
15252                MYSQL_YYABORT;
15253              }
15254              /* This special combination will denote field of NEW row */
15255              $$.var= trg_new_row_fake_var;
15256              $$.base_name= $3;
15257            }
15258            else
15259            {
15260              sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
15261              if (!tmp)
15262                MYSQL_YYABORT;
15263              if (!tmp->is_struct())
15264                my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str);
15265              $$.var= tmp;
15266              $$.base_name= $1;
15267            }
15268          }
15269        | DEFAULT '.' ident
15270          {
15271            sys_var *tmp=find_sys_var(YYTHD, $3.str, $3.length);
15272            if (!tmp)
15273              MYSQL_YYABORT;
15274            if (!tmp->is_struct())
15275              my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str);
15276            $$.var= tmp;
15277            $$.base_name.str=    (char*) "default";
15278            $$.base_name.length= 7;
15279          }
15280        ;
15281
15282transaction_characteristics:
15283          transaction_access_mode
15284        | isolation_level
15285        | transaction_access_mode ',' isolation_level
15286        | isolation_level ',' transaction_access_mode
15287        ;
15288
15289transaction_access_mode:
15290          transaction_access_mode_types
15291          {
15292            THD *thd= YYTHD;
15293            LEX *lex=Lex;
15294            Item *item= new (thd->mem_root) Item_int((int32) $1);
15295            if (item == NULL)
15296              MYSQL_YYABORT;
15297            set_var *var= new set_var(lex->option_type,
15298                                      find_sys_var(thd, "tx_read_only"),
15299                                      &null_lex_str,
15300                                      item);
15301            if (var == NULL)
15302              MYSQL_YYABORT;
15303            lex->var_list.push_back(var);
15304          }
15305        ;
15306
15307isolation_level:
15308          ISOLATION LEVEL_SYM isolation_types
15309          {
15310            THD *thd= YYTHD;
15311            LEX *lex=Lex;
15312            Item *item= new (thd->mem_root) Item_int((int32) $3);
15313            if (item == NULL)
15314              MYSQL_YYABORT;
15315            set_var *var= new set_var(lex->option_type,
15316                                      find_sys_var(thd, "tx_isolation"),
15317                                      &null_lex_str,
15318                                      item);
15319            if (var == NULL)
15320              MYSQL_YYABORT;
15321            lex->var_list.push_back(var);
15322          }
15323        ;
15324
15325transaction_access_mode_types:
15326          READ_SYM ONLY_SYM { $$= true; }
15327        | READ_SYM WRITE_SYM { $$= false; }
15328        ;
15329
15330isolation_types:
15331          READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; }
15332        | READ_SYM COMMITTED_SYM   { $$= ISO_READ_COMMITTED; }
15333        | REPEATABLE_SYM READ_SYM  { $$= ISO_REPEATABLE_READ; }
15334        | SERIALIZABLE_SYM         { $$= ISO_SERIALIZABLE; }
15335        ;
15336
15337text_or_password:
15338          TEXT_STRING { $$=$1.str;}
15339        | PASSWORD '(' TEXT_STRING ')'
15340          {
15341            if ($3.length == 0)
15342             $$= $3.str;
15343            else
15344            switch (YYTHD->variables.old_passwords) {
15345              case 1: $$= Item_func_old_password::
15346                alloc(YYTHD, $3.str, $3.length);
15347                break;
15348              case 0:
15349              case 2: $$= Item_func_password::
15350                create_password_hash_buffer(YYTHD, $3.str, $3.length);
15351                break;
15352            }
15353            if ($$ == NULL)
15354              MYSQL_YYABORT;
15355            Lex->contains_plaintext_password= true;
15356          }
15357        | OLD_PASSWORD '(' TEXT_STRING ')'
15358          {
15359		    WARN_DEPRECATED(YYTHD, "OLD_PASSWORD", "PASSWORD");
15360            $$= $3.length ? Item_func_old_password::
15361              alloc(YYTHD, $3.str, $3.length) :
15362              $3.str;
15363            if ($$ == NULL)
15364              MYSQL_YYABORT;
15365            Lex->contains_plaintext_password= true;
15366          }
15367        ;
15368
15369
15370set_expr_or_default:
15371          expr { $$=$1; }
15372        | DEFAULT { $$=0; }
15373        | ON
15374          {
15375            $$=new (YYTHD->mem_root) Item_string("ON",  2, system_charset_info);
15376            if ($$ == NULL)
15377              MYSQL_YYABORT;
15378          }
15379        | ALL
15380          {
15381            $$=new (YYTHD->mem_root) Item_string("ALL", 3, system_charset_info);
15382            if ($$ == NULL)
15383              MYSQL_YYABORT;
15384          }
15385        | BINARY
15386          {
15387            $$=new (YYTHD->mem_root) Item_string("binary", 6, system_charset_info);
15388            if ($$ == NULL)
15389              MYSQL_YYABORT;
15390          }
15391        ;
15392
15393/* Lock function */
15394
15395lock:
15396          LOCK_SYM lock_variant
15397          {
15398            if (Lex->sphead)
15399            {
15400              my_error(ER_SP_BADSTATEMENT, MYF(0), "LOCK");
15401              MYSQL_YYABORT;
15402            }
15403          }
15404        ;
15405
15406lock_variant:
15407          BINLOG_SYM FOR_SYM BACKUP_SYM
15408          {
15409            Lex->sql_command= SQLCOM_LOCK_BINLOG_FOR_BACKUP;
15410          }
15411        | TABLES FOR_SYM BACKUP_SYM
15412          {
15413            Lex->sql_command= SQLCOM_LOCK_TABLES_FOR_BACKUP;
15414          }
15415        | table_or_tables
15416          {
15417            Lex->sql_command= SQLCOM_LOCK_TABLES;
15418          }
15419          table_lock_list
15420          {}
15421        ;
15422
15423table_or_tables:
15424          TABLE_SYM
15425        | TABLES
15426        ;
15427
15428table_lock_list:
15429          table_lock
15430        | table_lock_list ',' table_lock
15431        ;
15432
15433table_lock:
15434          table_ident opt_table_alias lock_option
15435          {
15436            thr_lock_type lock_type= (thr_lock_type) $3;
15437            bool lock_for_write= (lock_type >= TL_WRITE_ALLOW_WRITE);
15438            if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type,
15439                                           (lock_for_write ?
15440                                            MDL_SHARED_NO_READ_WRITE :
15441                                            MDL_SHARED_READ)))
15442              MYSQL_YYABORT;
15443          }
15444        ;
15445
15446lock_option:
15447          READ_SYM               { $$= TL_READ_NO_INSERT; }
15448        | WRITE_SYM              { $$= TL_WRITE_DEFAULT; }
15449        | LOW_PRIORITY WRITE_SYM
15450          {
15451            $$= TL_WRITE_LOW_PRIORITY;
15452            WARN_DEPRECATED(YYTHD, "LOW_PRIORITY WRITE", "WRITE");
15453          }
15454        | READ_SYM LOCAL_SYM     { $$= TL_READ; }
15455        ;
15456
15457unlock:
15458          UNLOCK_SYM unlock_variant
15459          {
15460            if (Lex->sphead)
15461            {
15462              my_error(ER_SP_BADSTATEMENT, MYF(0), "UNLOCK");
15463              MYSQL_YYABORT;
15464            }
15465          }
15466	;
15467
15468unlock_variant:
15469          BINLOG_SYM
15470          {
15471            Lex->sql_command= SQLCOM_UNLOCK_BINLOG;
15472          }
15473        | table_or_tables
15474          {
15475            Lex->sql_command= SQLCOM_UNLOCK_TABLES;
15476          }
15477        ;
15478
15479/*
15480** Handler: direct access to ISAM functions
15481*/
15482
15483handler:
15484          HANDLER_SYM table_ident OPEN_SYM opt_table_alias
15485          {
15486            THD *thd= YYTHD;
15487            LEX *lex= Lex;
15488            if (lex->sphead)
15489            {
15490              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
15491              MYSQL_YYABORT;
15492            }
15493            lex->sql_command = SQLCOM_HA_OPEN;
15494            if (!lex->current_select->add_table_to_list(thd, $2, $4, 0))
15495              MYSQL_YYABORT;
15496            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_open();
15497            if (lex->m_sql_cmd == NULL)
15498              MYSQL_YYABORT;
15499          }
15500        | HANDLER_SYM table_ident_nodb CLOSE_SYM
15501          {
15502            THD *thd= YYTHD;
15503            LEX *lex= Lex;
15504            if (lex->sphead)
15505            {
15506              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
15507              MYSQL_YYABORT;
15508            }
15509            lex->sql_command = SQLCOM_HA_CLOSE;
15510            if (!lex->current_select->add_table_to_list(thd, $2, 0, 0))
15511              MYSQL_YYABORT;
15512            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_close();
15513            if (lex->m_sql_cmd == NULL)
15514              MYSQL_YYABORT;
15515          }
15516        | HANDLER_SYM table_ident_nodb READ_SYM
15517          {
15518            LEX *lex=Lex;
15519            if (lex->sphead)
15520            {
15521              my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER");
15522              MYSQL_YYABORT;
15523            }
15524            lex->expr_allows_subselect= FALSE;
15525            lex->sql_command = SQLCOM_HA_READ;
15526            Item *one= new (YYTHD->mem_root) Item_int((int32) 1);
15527            if (one == NULL)
15528              MYSQL_YYABORT;
15529            lex->current_select->select_limit= one;
15530            lex->current_select->offset_limit= 0;
15531            if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0))
15532              MYSQL_YYABORT;
15533          }
15534          handler_read_or_scan where_clause opt_limit_clause
15535          {
15536            THD *thd= YYTHD;
15537            LEX *lex= Lex;
15538            Lex->expr_allows_subselect= TRUE;
15539            /* Stored functions are not supported for HANDLER READ. */
15540            if (lex->uses_stored_routines())
15541            {
15542              my_error(ER_NOT_SUPPORTED_YET, MYF(0),
15543                       "stored functions in HANDLER ... READ");
15544              MYSQL_YYABORT;
15545            }
15546            lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_handler_read($5,
15547                                  lex->ident.str, lex->insert_list,
15548                                  thd->m_parser_state->m_yacc.m_ha_rkey_mode);
15549            if (lex->m_sql_cmd == NULL)
15550              MYSQL_YYABORT;
15551          }
15552        ;
15553
15554handler_read_or_scan:
15555          handler_scan_function       { Lex->ident= null_lex_str; $$=$1; }
15556        | ident handler_rkey_function { Lex->ident= $1; $$=$2; }
15557        ;
15558
15559handler_scan_function:
15560          FIRST_SYM { $$= RFIRST; }
15561        | NEXT_SYM  { $$= RNEXT;  }
15562        ;
15563
15564handler_rkey_function:
15565          FIRST_SYM { $$= RFIRST; }
15566        | NEXT_SYM  { $$= RNEXT;  }
15567        | PREV_SYM  { $$= RPREV;  }
15568        | LAST_SYM  { $$= RLAST;  }
15569        | handler_rkey_mode
15570          {
15571            YYTHD->m_parser_state->m_yacc.m_ha_rkey_mode= $1;
15572            Lex->insert_list= new List_item;
15573            if (! Lex->insert_list)
15574              MYSQL_YYABORT;
15575          }
15576          '(' values ')'
15577          {
15578            $$= RKEY;
15579          }
15580        ;
15581
15582handler_rkey_mode:
15583          EQ     { $$=HA_READ_KEY_EXACT;   }
15584        | GE     { $$=HA_READ_KEY_OR_NEXT; }
15585        | LE     { $$=HA_READ_KEY_OR_PREV; }
15586        | GT_SYM { $$=HA_READ_AFTER_KEY;   }
15587        | LT     { $$=HA_READ_BEFORE_KEY;  }
15588        ;
15589
15590/* GRANT / REVOKE */
15591
15592revoke:
15593          REVOKE clear_privileges { Lex->sql_command= SQLCOM_REVOKE; } revoke_command
15594          {}
15595        ;
15596
15597revoke_command:
15598          grant_privileges ON opt_table grant_ident FROM grant_list
15599          {
15600            LEX *lex= Lex;
15601            lex->type= 0;
15602          }
15603        | grant_privileges ON FUNCTION_SYM grant_ident FROM grant_list
15604          {
15605            LEX *lex= Lex;
15606            if (lex->columns.elements)
15607            {
15608              my_parse_error(ER(ER_SYNTAX_ERROR));
15609              MYSQL_YYABORT;
15610            }
15611            lex->type= TYPE_ENUM_FUNCTION;
15612          }
15613        | grant_privileges ON PROCEDURE_SYM grant_ident FROM grant_list
15614          {
15615            LEX *lex= Lex;
15616            if (lex->columns.elements)
15617            {
15618              my_parse_error(ER(ER_SYNTAX_ERROR));
15619              MYSQL_YYABORT;
15620            }
15621            lex->type= TYPE_ENUM_PROCEDURE;
15622          }
15623        | ALL opt_privileges ',' GRANT OPTION FROM grant_list
15624          {
15625            Lex->sql_command = SQLCOM_REVOKE_ALL;
15626          }
15627        | PROXY_SYM ON user FROM grant_list
15628          {
15629            LEX *lex= Lex;
15630            lex->users_list.push_front ($3);
15631            lex->type= TYPE_ENUM_PROXY;
15632          }
15633        ;
15634
15635grant:
15636          GRANT clear_privileges { Lex->sql_command= SQLCOM_GRANT; } grant_command
15637          {}
15638        ;
15639
15640grant_command:
15641          grant_privileges ON opt_table grant_ident TO_SYM grant_list
15642          require_clause grant_options
15643          {
15644            LEX *lex= Lex;
15645            lex->type= 0;
15646          }
15647        | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list
15648          require_clause grant_options
15649          {
15650            LEX *lex= Lex;
15651            if (lex->columns.elements)
15652            {
15653              my_parse_error(ER(ER_SYNTAX_ERROR));
15654              MYSQL_YYABORT;
15655            }
15656            lex->type= TYPE_ENUM_FUNCTION;
15657          }
15658        | grant_privileges ON PROCEDURE_SYM grant_ident TO_SYM grant_list
15659          require_clause grant_options
15660          {
15661            LEX *lex= Lex;
15662            if (lex->columns.elements)
15663            {
15664              my_parse_error(ER(ER_SYNTAX_ERROR));
15665              MYSQL_YYABORT;
15666            }
15667            lex->type= TYPE_ENUM_PROCEDURE;
15668          }
15669        | PROXY_SYM ON user TO_SYM grant_list opt_grant_option
15670          {
15671            LEX *lex= Lex;
15672            lex->users_list.push_front ($3);
15673            lex->type= TYPE_ENUM_PROXY;
15674          }
15675        ;
15676
15677opt_table:
15678          /* Empty */
15679        | TABLE_SYM
15680        ;
15681
15682grant_privileges:
15683          object_privilege_list
15684          {
15685            LEX *lex= Lex;
15686            if (lex->grant == GLOBAL_ACLS &&
15687                lex->sql_command == SQLCOM_REVOKE)
15688              lex->sql_command= SQLCOM_REVOKE_ALL;
15689          }
15690        | ALL opt_privileges
15691          {
15692            Lex->all_privileges= 1;
15693            Lex->grant= GLOBAL_ACLS;
15694          }
15695        ;
15696
15697opt_privileges:
15698          /* empty */
15699        | PRIVILEGES
15700        ;
15701
15702object_privilege_list:
15703          object_privilege
15704        | object_privilege_list ',' object_privilege
15705        ;
15706
15707object_privilege:
15708          SELECT_SYM
15709          { Lex->which_columns = SELECT_ACL;}
15710          opt_column_list {}
15711        | INSERT
15712          { Lex->which_columns = INSERT_ACL;}
15713          opt_column_list {}
15714        | UPDATE_SYM
15715          { Lex->which_columns = UPDATE_ACL; }
15716          opt_column_list {}
15717        | REFERENCES
15718          { Lex->which_columns = REFERENCES_ACL;}
15719          opt_column_list {}
15720        | DELETE_SYM              { Lex->grant |= DELETE_ACL;}
15721        | USAGE                   {}
15722        | INDEX_SYM               { Lex->grant |= INDEX_ACL;}
15723        | ALTER                   { Lex->grant |= ALTER_ACL;}
15724        | CREATE                  { Lex->grant |= CREATE_ACL;}
15725        | DROP                    { Lex->grant |= DROP_ACL;}
15726        | EXECUTE_SYM             { Lex->grant |= EXECUTE_ACL;}
15727        | RELOAD                  { Lex->grant |= RELOAD_ACL;}
15728        | SHUTDOWN                { Lex->grant |= SHUTDOWN_ACL;}
15729        | PROCESS                 { Lex->grant |= PROCESS_ACL;}
15730        | FILE_SYM                { Lex->grant |= FILE_ACL;}
15731        | GRANT OPTION            { Lex->grant |= GRANT_ACL;}
15732        | SHOW DATABASES          { Lex->grant |= SHOW_DB_ACL;}
15733        | SUPER_SYM               { Lex->grant |= SUPER_ACL;}
15734        | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;}
15735        | LOCK_SYM TABLES         { Lex->grant |= LOCK_TABLES_ACL; }
15736        | REPLICATION SLAVE       { Lex->grant |= REPL_SLAVE_ACL; }
15737        | REPLICATION CLIENT_SYM  { Lex->grant |= REPL_CLIENT_ACL; }
15738        | CREATE VIEW_SYM         { Lex->grant |= CREATE_VIEW_ACL; }
15739        | SHOW VIEW_SYM           { Lex->grant |= SHOW_VIEW_ACL; }
15740        | CREATE ROUTINE_SYM      { Lex->grant |= CREATE_PROC_ACL; }
15741        | ALTER ROUTINE_SYM       { Lex->grant |= ALTER_PROC_ACL; }
15742        | CREATE USER             { Lex->grant |= CREATE_USER_ACL; }
15743        | EVENT_SYM               { Lex->grant |= EVENT_ACL;}
15744        | TRIGGER_SYM             { Lex->grant |= TRIGGER_ACL; }
15745        | CREATE TABLESPACE       { Lex->grant |= CREATE_TABLESPACE_ACL; }
15746        ;
15747
15748opt_and:
15749          /* empty */ {}
15750        | AND_SYM {}
15751        ;
15752
15753require_list:
15754          require_list_element opt_and require_list
15755        | require_list_element
15756        ;
15757
15758require_list_element:
15759          SUBJECT_SYM TEXT_STRING
15760          {
15761            LEX *lex=Lex;
15762            if (lex->x509_subject)
15763            {
15764              my_error(ER_DUP_ARGUMENT, MYF(0), "SUBJECT");
15765              MYSQL_YYABORT;
15766            }
15767            lex->x509_subject=$2.str;
15768          }
15769        | ISSUER_SYM TEXT_STRING
15770          {
15771            LEX *lex=Lex;
15772            if (lex->x509_issuer)
15773            {
15774              my_error(ER_DUP_ARGUMENT, MYF(0), "ISSUER");
15775              MYSQL_YYABORT;
15776            }
15777            lex->x509_issuer=$2.str;
15778          }
15779        | CIPHER_SYM TEXT_STRING
15780          {
15781            LEX *lex=Lex;
15782            if (lex->ssl_cipher)
15783            {
15784              my_error(ER_DUP_ARGUMENT, MYF(0), "CIPHER");
15785              MYSQL_YYABORT;
15786            }
15787            lex->ssl_cipher=$2.str;
15788          }
15789        ;
15790
15791grant_ident:
15792          '*'
15793          {
15794            LEX *lex= Lex;
15795            size_t dummy;
15796            if (lex->copy_db_to(&lex->current_select->db, &dummy))
15797              MYSQL_YYABORT;
15798            if (lex->grant == GLOBAL_ACLS)
15799              lex->grant = DB_ACLS & ~GRANT_ACL;
15800            else if (lex->columns.elements)
15801            {
15802              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
15803                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
15804              MYSQL_YYABORT;
15805            }
15806          }
15807        | ident '.' '*'
15808          {
15809            LEX *lex= Lex;
15810            lex->current_select->db = $1.str;
15811            if (lex->grant == GLOBAL_ACLS)
15812              lex->grant = DB_ACLS & ~GRANT_ACL;
15813            else if (lex->columns.elements)
15814            {
15815              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
15816                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
15817              MYSQL_YYABORT;
15818            }
15819          }
15820        | '*' '.' '*'
15821          {
15822            LEX *lex= Lex;
15823            lex->current_select->db = NULL;
15824            if (lex->grant == GLOBAL_ACLS)
15825              lex->grant= GLOBAL_ACLS & ~GRANT_ACL;
15826            else if (lex->columns.elements)
15827            {
15828              my_message(ER_ILLEGAL_GRANT_FOR_TABLE,
15829                         ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0));
15830              MYSQL_YYABORT;
15831            }
15832          }
15833        | table_ident
15834          {
15835            LEX *lex=Lex;
15836            if (!lex->current_select->add_table_to_list(lex->thd, $1,NULL,
15837                                                        TL_OPTION_UPDATING))
15838              MYSQL_YYABORT;
15839            if (lex->grant == GLOBAL_ACLS)
15840              lex->grant =  TABLE_ACLS & ~GRANT_ACL;
15841          }
15842        ;
15843
15844user_list:
15845          user
15846          {
15847            if (Lex->users_list.push_back($1))
15848              MYSQL_YYABORT;
15849          }
15850        | user_list ',' user
15851          {
15852            if (Lex->users_list.push_back($3))
15853              MYSQL_YYABORT;
15854          }
15855        ;
15856
15857grant_list:
15858          grant_user
15859          {
15860            if (Lex->users_list.push_back($1))
15861              MYSQL_YYABORT;
15862          }
15863        | grant_list ',' grant_user
15864          {
15865            if (Lex->users_list.push_back($3))
15866              MYSQL_YYABORT;
15867          }
15868        ;
15869
15870grant_user:
15871          user IDENTIFIED_SYM BY TEXT_STRING
15872          {
15873            $$=$1; $1->password=$4;
15874            if (Lex->sql_command == SQLCOM_REVOKE)
15875            {
15876              my_parse_error(ER(ER_SYNTAX_ERROR));
15877              MYSQL_YYABORT;
15878            }
15879            String *password = new (YYTHD->mem_root) String((const char*)$4.str,
15880                                    YYTHD->variables.character_set_client);
15881            check_password_policy(password);
15882            /*
15883              1. Plugin must be resolved
15884              2. Password must be digested
15885            */
15886            $1->uses_identified_by_clause= true;
15887            Lex->contains_plaintext_password= true;
15888          }
15889        | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
15890          {
15891            if (Lex->sql_command == SQLCOM_REVOKE)
15892            {
15893              my_parse_error(ER(ER_SYNTAX_ERROR));
15894              MYSQL_YYABORT;
15895            }
15896            $$= $1;
15897            $1->password= $5;
15898            if (!strcmp($5.str, ""))
15899            {
15900              String *password= new (YYTHD->mem_root) String ((const char *)"",
15901                                     YYTHD->variables.character_set_client);
15902              check_password_policy(password);
15903            }
15904            /*
15905              1. Plugin must be resolved
15906            */
15907            $1->uses_identified_by_password_clause= true;
15908          }
15909        | user IDENTIFIED_SYM WITH ident_or_text
15910          {
15911            if (Lex->sql_command == SQLCOM_REVOKE)
15912            {
15913              my_parse_error(ER(ER_SYNTAX_ERROR));
15914              MYSQL_YYABORT;
15915            }
15916            $$= $1;
15917            $1->plugin= $4;
15918            $1->auth= empty_lex_str;
15919            $1->uses_identified_with_clause= true;
15920          }
15921        | user IDENTIFIED_SYM WITH ident_or_text AS TEXT_STRING_sys
15922          {
15923            if (Lex->sql_command == SQLCOM_REVOKE)
15924            {
15925              my_parse_error(ER(ER_SYNTAX_ERROR));
15926              MYSQL_YYABORT;
15927            }
15928            $$= $1;
15929            $1->plugin= $4;
15930            $1->auth= $6;
15931            $1->uses_identified_with_clause= true;
15932            $1->uses_authentication_string_clause= true;
15933          }
15934        | user
15935          {
15936            $$= $1;
15937            $1->password= null_lex_str;
15938          }
15939        ;
15940
15941opt_column_list:
15942          /* empty */
15943          {
15944            LEX *lex=Lex;
15945            lex->grant |= lex->which_columns;
15946          }
15947        | '(' column_list ')'
15948        ;
15949
15950column_list:
15951          column_list ',' column_list_id
15952        | column_list_id
15953        ;
15954
15955column_list_id:
15956          ident
15957          {
15958            String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info);
15959            if (new_str == NULL)
15960              MYSQL_YYABORT;
15961            List_iterator <LEX_COLUMN> iter(Lex->columns);
15962            class LEX_COLUMN *point;
15963            LEX *lex=Lex;
15964            while ((point=iter++))
15965            {
15966              if (!my_strcasecmp(system_charset_info,
15967                                 point->column.ptr(), new_str->ptr()))
15968                break;
15969            }
15970            lex->grant_tot_col|= lex->which_columns;
15971            if (point)
15972              point->rights |= lex->which_columns;
15973            else
15974            {
15975              LEX_COLUMN *col= new LEX_COLUMN (*new_str,lex->which_columns);
15976              if (col == NULL)
15977                MYSQL_YYABORT;
15978              lex->columns.push_back(col);
15979            }
15980          }
15981        ;
15982
15983require_clause:
15984          /* empty */
15985        | REQUIRE_SYM require_list
15986          {
15987            Lex->ssl_type=SSL_TYPE_SPECIFIED;
15988          }
15989        | REQUIRE_SYM SSL_SYM
15990          {
15991            Lex->ssl_type=SSL_TYPE_ANY;
15992          }
15993        | REQUIRE_SYM X509_SYM
15994          {
15995            Lex->ssl_type=SSL_TYPE_X509;
15996          }
15997        | REQUIRE_SYM NONE_SYM
15998          {
15999            Lex->ssl_type=SSL_TYPE_NONE;
16000          }
16001        ;
16002
16003grant_options:
16004          /* empty */ {}
16005        | WITH grant_option_list
16006        ;
16007
16008opt_grant_option:
16009          /* empty */ {}
16010        | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;}
16011        ;
16012
16013grant_option_list:
16014          grant_option_list grant_option {}
16015        | grant_option {}
16016        ;
16017
16018grant_option:
16019          GRANT OPTION { Lex->grant |= GRANT_ACL;}
16020        | MAX_QUERIES_PER_HOUR ulong_num
16021          {
16022            LEX *lex=Lex;
16023            lex->mqh.questions=$2;
16024            lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR;
16025          }
16026        | MAX_UPDATES_PER_HOUR ulong_num
16027          {
16028            LEX *lex=Lex;
16029            lex->mqh.updates=$2;
16030            lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR;
16031          }
16032        | MAX_CONNECTIONS_PER_HOUR ulong_num
16033          {
16034            LEX *lex=Lex;
16035            lex->mqh.conn_per_hour= $2;
16036            lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
16037          }
16038        | MAX_USER_CONNECTIONS_SYM ulong_num
16039          {
16040            LEX *lex=Lex;
16041            lex->mqh.user_conn= $2;
16042            lex->mqh.specified_limits|= USER_RESOURCES::USER_CONNECTIONS;
16043          }
16044        ;
16045
16046begin:
16047          BEGIN_SYM
16048          {
16049            LEX *lex=Lex;
16050            lex->sql_command = SQLCOM_BEGIN;
16051            lex->start_transaction_opt= 0;
16052          }
16053          opt_work {}
16054        ;
16055
16056opt_work:
16057          /* empty */ {}
16058        | WORK_SYM  {}
16059        ;
16060
16061opt_chain:
16062          /* empty */
16063          { $$= TVL_UNKNOWN; }
16064        | AND_SYM NO_SYM CHAIN_SYM { $$= TVL_NO; }
16065        | AND_SYM CHAIN_SYM        { $$= TVL_YES; }
16066        ;
16067
16068opt_release:
16069          /* empty */
16070          { $$= TVL_UNKNOWN; }
16071        | RELEASE_SYM        { $$= TVL_YES; }
16072        | NO_SYM RELEASE_SYM { $$= TVL_NO; }
16073;
16074
16075opt_savepoint:
16076          /* empty */ {}
16077        | SAVEPOINT_SYM {}
16078        ;
16079
16080commit:
16081          COMMIT_SYM opt_work opt_chain opt_release
16082          {
16083            LEX *lex=Lex;
16084            lex->sql_command= SQLCOM_COMMIT;
16085            /* Don't allow AND CHAIN RELEASE. */
16086            MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
16087            lex->tx_chain= $3;
16088            lex->tx_release= $4;
16089          }
16090        ;
16091
16092rollback:
16093          ROLLBACK_SYM opt_work opt_chain opt_release
16094          {
16095            LEX *lex=Lex;
16096            lex->sql_command= SQLCOM_ROLLBACK;
16097            /* Don't allow AND CHAIN RELEASE. */
16098            MYSQL_YYABORT_UNLESS($3 != TVL_YES || $4 != TVL_YES);
16099            lex->tx_chain= $3;
16100            lex->tx_release= $4;
16101          }
16102        | ROLLBACK_SYM opt_work
16103          TO_SYM opt_savepoint ident
16104          {
16105            LEX *lex=Lex;
16106            lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT;
16107            lex->ident= $5;
16108          }
16109        ;
16110
16111savepoint:
16112          SAVEPOINT_SYM ident
16113          {
16114            LEX *lex=Lex;
16115            lex->sql_command= SQLCOM_SAVEPOINT;
16116            lex->ident= $2;
16117          }
16118        ;
16119
16120release:
16121          RELEASE_SYM SAVEPOINT_SYM ident
16122          {
16123            LEX *lex=Lex;
16124            lex->sql_command= SQLCOM_RELEASE_SAVEPOINT;
16125            lex->ident= $3;
16126          }
16127        ;
16128
16129/*
16130   UNIONS : glue selects together
16131*/
16132
16133
16134union_clause:
16135          /* empty */ {}
16136        | union_list
16137        ;
16138
16139union_list:
16140          UNION_SYM union_option
16141          {
16142            if (add_select_to_union_list(Lex, (bool)$2, TRUE))
16143              MYSQL_YYABORT;
16144          }
16145          select_init
16146          {
16147            /*
16148              Remove from the name resolution context stack the context of the
16149              last select in the union.
16150            */
16151            Lex->pop_context();
16152          }
16153        ;
16154
16155union_opt:
16156          /* Empty */ { $$= 0; }
16157        | union_list { $$= 1; }
16158        | union_order_or_limit { $$= 1; }
16159        ;
16160
16161opt_union_order_or_limit:
16162	  /* Empty */ { $$= false; }
16163	| union_order_or_limit { $$= true; }
16164	;
16165
16166union_order_or_limit:
16167          {
16168            THD *thd= YYTHD;
16169            LEX *lex= thd->lex;
16170            DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
16171            SELECT_LEX *sel= lex->current_select;
16172            SELECT_LEX_UNIT *unit= sel->master_unit();
16173            SELECT_LEX *fake= unit->fake_select_lex;
16174            if (fake)
16175            {
16176              unit->global_parameters= fake;
16177              fake->no_table_names_allowed= 1;
16178              lex->current_select= fake;
16179            }
16180            thd->where= "global ORDER clause";
16181          }
16182          order_or_limit
16183          {
16184            THD *thd= YYTHD;
16185            thd->lex->current_select->no_table_names_allowed= 0;
16186            thd->where= "";
16187          }
16188        ;
16189
16190order_or_limit:
16191          order_clause opt_limit_clause_init
16192        | limit_clause
16193        ;
16194
16195union_option:
16196          /* empty */ { $$=1; }
16197        | DISTINCT  { $$=1; }
16198        | ALL       { $$=0; }
16199        ;
16200
16201query_specification:
16202          SELECT_SYM select_init2_derived
16203          {
16204            $$= Lex->current_select->master_unit()->first_select();
16205          }
16206        | '(' select_paren_derived ')'
16207          {
16208            $$= Lex->current_select->master_unit()->first_select();
16209          }
16210        ;
16211
16212query_expression_body:
16213          query_specification opt_union_order_or_limit
16214        | query_expression_body
16215          UNION_SYM union_option
16216          {
16217            if (add_select_to_union_list(Lex, (bool)$3, FALSE))
16218              MYSQL_YYABORT;
16219          }
16220          query_specification
16221          opt_union_order_or_limit
16222          {
16223            Lex->pop_context();
16224            $$= $1;
16225          }
16226        ;
16227
16228/* Corresponds to <query expression> in the SQL:2003 standard. */
16229subselect:
16230          subselect_start query_expression_body subselect_end
16231          {
16232            $$= $2;
16233          }
16234        ;
16235
16236subselect_start:
16237          {
16238            LEX *lex=Lex;
16239            if (!lex->expr_allows_subselect ||
16240               lex->sql_command == (int)SQLCOM_PURGE)
16241            {
16242              my_parse_error(ER(ER_SYNTAX_ERROR));
16243              MYSQL_YYABORT;
16244            }
16245            /*
16246              we are making a "derived table" for the parenthesis
16247              as we need to have a lex level to fit the union
16248              after the parenthesis, e.g.
16249              (SELECT .. ) UNION ...  becomes
16250              SELECT * FROM ((SELECT ...) UNION ...)
16251            */
16252            if (mysql_new_select(Lex, 1))
16253              MYSQL_YYABORT;
16254          }
16255        ;
16256
16257subselect_end:
16258          {
16259            LEX *lex=Lex;
16260
16261            lex->pop_context();
16262            SELECT_LEX *child= lex->current_select;
16263            lex->current_select = lex->current_select->outer_select();
16264            lex->nest_level--;
16265            lex->current_select->n_child_sum_items += child->n_sum_items;
16266
16267            /*
16268              A subquery (and all the subsequent query blocks in a UNION) can
16269              add columns to an outer query block. Reserve space for them.
16270              Aggregate functions in having clause can also add fields to an
16271              outer select.
16272            */
16273            for (SELECT_LEX *temp= child->master_unit()->first_select();
16274                 temp != NULL; temp= temp->next_select())
16275            {
16276              lex->current_select->select_n_where_fields+=
16277                temp->select_n_where_fields;
16278              lex->current_select->select_n_having_items+=
16279                temp->select_n_having_items;
16280            }
16281          }
16282        ;
16283
16284opt_query_expression_options:
16285          /* empty */
16286        | query_expression_option_list
16287        ;
16288
16289query_expression_option_list:
16290          query_expression_option_list query_expression_option
16291        | query_expression_option
16292        ;
16293
16294query_expression_option:
16295          STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
16296        | HIGH_PRIORITY
16297          {
16298            if (check_simple_select())
16299              MYSQL_YYABORT;
16300            YYPS->m_lock_type= TL_READ_HIGH_PRIORITY;
16301            YYPS->m_mdl_type= MDL_SHARED_READ;
16302            Select->options|= SELECT_HIGH_PRIORITY;
16303          }
16304        | DISTINCT         { Select->options|= SELECT_DISTINCT; }
16305        | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
16306        | SQL_BIG_RESULT   { Select->options|= SELECT_BIG_RESULT; }
16307        | SQL_BUFFER_RESULT
16308          {
16309            if (check_simple_select())
16310              MYSQL_YYABORT;
16311            Select->options|= OPTION_BUFFER_RESULT;
16312          }
16313        | SQL_CALC_FOUND_ROWS
16314          {
16315            if (check_simple_select())
16316              MYSQL_YYABORT;
16317            Select->options|= OPTION_FOUND_ROWS;
16318          }
16319        | ALL { Select->options|= SELECT_ALL; }
16320        ;
16321
16322/**************************************************************************
16323
16324 CREATE VIEW | TRIGGER | PROCEDURE statements.
16325
16326**************************************************************************/
16327
16328view_or_trigger_or_sp_or_event:
16329          definer definer_tail
16330          {}
16331        | no_definer no_definer_tail
16332          {}
16333        | view_replace_or_algorithm definer_opt view_tail
16334          {}
16335        ;
16336
16337definer_tail:
16338          view_tail
16339        | trigger_tail
16340        | sp_tail
16341        | sf_tail
16342        | event_tail
16343        ;
16344
16345no_definer_tail:
16346          view_tail
16347        | trigger_tail
16348        | sp_tail
16349        | sf_tail
16350        | udf_tail
16351        | event_tail
16352        ;
16353
16354/**************************************************************************
16355
16356 DEFINER clause support.
16357
16358**************************************************************************/
16359
16360definer_opt:
16361          no_definer
16362        | definer
16363        ;
16364
16365no_definer:
16366          /* empty */
16367          {
16368            /*
16369              We have to distinguish missing DEFINER-clause from case when
16370              CURRENT_USER specified as definer explicitly in order to properly
16371              handle CREATE TRIGGER statements which come to replication thread
16372              from older master servers (i.e. to create non-suid trigger in this
16373              case).
16374            */
16375            YYTHD->lex->definer= 0;
16376          }
16377        ;
16378
16379definer:
16380          DEFINER_SYM EQ user
16381          {
16382            YYTHD->lex->definer= get_current_user(YYTHD, $3);
16383          }
16384        ;
16385
16386/**************************************************************************
16387
16388 CREATE VIEW statement parts.
16389
16390**************************************************************************/
16391
16392view_replace_or_algorithm:
16393          view_replace
16394          {}
16395        | view_replace view_algorithm
16396          {}
16397        | view_algorithm
16398          {}
16399        ;
16400
16401view_replace:
16402          OR_SYM REPLACE
16403          { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; }
16404        ;
16405
16406view_algorithm:
16407          ALGORITHM_SYM EQ UNDEFINED_SYM
16408          { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; }
16409        | ALGORITHM_SYM EQ MERGE_SYM
16410          { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; }
16411        | ALGORITHM_SYM EQ TEMPTABLE_SYM
16412          { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; }
16413        ;
16414
16415view_suid:
16416          /* empty */
16417          { Lex->create_view_suid= VIEW_SUID_DEFAULT; }
16418        | SQL_SYM SECURITY_SYM DEFINER_SYM
16419          { Lex->create_view_suid= VIEW_SUID_DEFINER; }
16420        | SQL_SYM SECURITY_SYM INVOKER_SYM
16421          { Lex->create_view_suid= VIEW_SUID_INVOKER; }
16422        ;
16423
16424view_tail:
16425          view_suid VIEW_SYM table_ident
16426          {
16427            THD *thd= YYTHD;
16428            LEX *lex= thd->lex;
16429            lex->sql_command= SQLCOM_CREATE_VIEW;
16430            /* first table in list is target VIEW name */
16431            if (!lex->select_lex.add_table_to_list(thd, $3, NULL,
16432                                                   TL_OPTION_UPDATING,
16433                                                   TL_IGNORE,
16434                                                   MDL_EXCLUSIVE))
16435              MYSQL_YYABORT;
16436            lex->query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
16437          }
16438          view_list_opt AS view_select
16439        ;
16440
16441view_list_opt:
16442          /* empty */
16443          {}
16444        | '(' view_list ')'
16445        ;
16446
16447view_list:
16448          ident
16449            {
16450              Lex->view_list.push_back((LEX_STRING*)
16451              sql_memdup(&$1, sizeof(LEX_STRING)));
16452            }
16453        | view_list ',' ident
16454            {
16455              Lex->view_list.push_back((LEX_STRING*)
16456              sql_memdup(&$3, sizeof(LEX_STRING)));
16457            }
16458        ;
16459
16460view_select:
16461          {
16462            LEX *lex= Lex;
16463            lex->parsing_options.allows_variable= FALSE;
16464            lex->parsing_options.allows_select_into= FALSE;
16465            lex->parsing_options.allows_select_procedure= FALSE;
16466            lex->parsing_options.allows_derived= FALSE;
16467            lex->create_view_select.str= (char *) YYLIP->get_cpp_ptr();
16468          }
16469          view_select_aux view_check_option
16470          {
16471            THD *thd= YYTHD;
16472            LEX *lex= Lex;
16473            uint len= YYLIP->get_cpp_ptr() - lex->create_view_select.str;
16474            void *create_view_select= thd->memdup(lex->create_view_select.str, len);
16475            lex->create_view_select.length= len;
16476            lex->create_view_select.str= (char *) create_view_select;
16477            trim_whitespace(thd->charset(), &lex->create_view_select);
16478            lex->parsing_options.allows_variable= TRUE;
16479            lex->parsing_options.allows_select_into= TRUE;
16480            lex->parsing_options.allows_select_procedure= TRUE;
16481            lex->parsing_options.allows_derived= TRUE;
16482          }
16483        ;
16484
16485view_select_aux:
16486          create_view_select
16487          {
16488            if (Lex->current_select->set_braces(0))
16489            {
16490              my_parse_error(ER(ER_SYNTAX_ERROR));
16491              MYSQL_YYABORT;
16492            }
16493            /*
16494              For statment as "CREATE VIEW v1 AS SELECT1 UNION SELECT2",
16495              parsing of Select query (SELECT1) is completed and UNION_CLAUSE
16496              is not yet parsed. So check for
16497              Lex->current_select->master_unit()->first_select()->braces
16498              (as its done in "select_init2" for "select_part2" rule) is not
16499              done here.
16500            */
16501          }
16502          union_clause
16503        | '(' create_view_select_paren ')' union_opt
16504        ;
16505
16506create_view_select_paren:
16507          create_view_select
16508          {
16509            if (setup_select_in_parentheses(Lex))
16510              MYSQL_YYABORT;
16511          }
16512        | '(' create_view_select_paren ')'
16513        ;
16514
16515create_view_select:
16516          SELECT_SYM
16517          {
16518            Lex->current_select->table_list.save_and_clear(&Lex->save_list);
16519          }
16520          select_part2
16521          {
16522            Lex->current_select->table_list.push_front(&Lex->save_list);
16523          }
16524        ;
16525
16526view_check_option:
16527          /* empty */
16528          { Lex->create_view_check= VIEW_CHECK_NONE; }
16529        | WITH CHECK_SYM OPTION
16530          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
16531        | WITH CASCADED CHECK_SYM OPTION
16532          { Lex->create_view_check= VIEW_CHECK_CASCADED; }
16533        | WITH LOCAL_SYM CHECK_SYM OPTION
16534          { Lex->create_view_check= VIEW_CHECK_LOCAL; }
16535        ;
16536
16537/**************************************************************************
16538
16539 CREATE TRIGGER statement parts.
16540
16541**************************************************************************/
16542
16543trigger_tail:
16544          TRIGGER_SYM       /* $1 */
16545          remember_name     /* $2 */
16546          sp_name           /* $3 */
16547          trg_action_time   /* $4 */
16548          trg_event         /* $5 */
16549          ON                /* $6 */
16550          remember_name     /* $7 */
16551          {                 /* $8 */
16552            Lex->raw_trg_on_table_name_begin= YYLIP->get_tok_start();
16553          }
16554          table_ident       /* $9 */
16555          FOR_SYM           /* $10 */
16556          remember_name     /* $11 */
16557          {                 /* $12 */
16558            Lex->raw_trg_on_table_name_end= YYLIP->get_tok_start();
16559          }
16560          EACH_SYM          /* $13 */
16561          ROW_SYM           /* $14 */
16562          {                 /* $15 */
16563            THD *thd= YYTHD;
16564            LEX *lex= thd->lex;
16565            Lex_input_stream *lip= YYLIP;
16566
16567            if (lex->sphead)
16568            {
16569              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER");
16570              MYSQL_YYABORT;
16571            }
16572
16573            sp_head *sp= sp_start_parsing(thd, SP_TYPE_TRIGGER, $3);
16574
16575            if (!sp)
16576              MYSQL_YYABORT;
16577
16578            sp->m_trg_chistics.action_time= (enum trg_action_time_type) $4;
16579            sp->m_trg_chistics.event= (enum trg_event_type) $5;
16580            lex->stmt_definition_begin= $2;
16581            lex->ident.str= $7;
16582            lex->ident.length= $11 - $7;
16583
16584            lex->sphead= sp;
16585            lex->spname= $3;
16586
16587            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
16588            sp->m_chistics= &lex->sp_chistics;
16589            sp->set_body_start(thd, lip->get_cpp_ptr());
16590          }
16591          sp_proc_stmt /* $16 */
16592          { /* $17 */
16593            THD *thd= YYTHD;
16594            LEX *lex= Lex;
16595            sp_head *sp= lex->sphead;
16596
16597            sp_finish_parsing(thd);
16598
16599            lex->sql_command= SQLCOM_CREATE_TRIGGER;
16600
16601            if (sp->is_not_allowed_in_function("trigger"))
16602              MYSQL_YYABORT;
16603
16604            /*
16605              We have to do it after parsing trigger body, because some of
16606              sp_proc_stmt alternatives are not saving/restoring LEX, so
16607              lex->query_tables can be wiped out.
16608            */
16609            if (!lex->select_lex.add_table_to_list(thd, $9,
16610                                                   (LEX_STRING*) 0,
16611                                                   TL_OPTION_UPDATING,
16612                                                   TL_READ_NO_INSERT,
16613                                                   MDL_SHARED_NO_WRITE))
16614              MYSQL_YYABORT;
16615          }
16616        ;
16617
16618/**************************************************************************
16619
16620 CREATE FUNCTION | PROCEDURE statements parts.
16621
16622**************************************************************************/
16623
16624udf_tail:
16625          AGGREGATE_SYM remember_name FUNCTION_SYM ident
16626          RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
16627          {
16628            THD *thd= YYTHD;
16629            LEX *lex= thd->lex;
16630            if (is_native_function(thd, & $4))
16631            {
16632              my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
16633                       $4.str);
16634              MYSQL_YYABORT;
16635            }
16636            lex->sql_command = SQLCOM_CREATE_FUNCTION;
16637            lex->udf.type= UDFTYPE_AGGREGATE;
16638            lex->stmt_definition_begin= $2;
16639            lex->udf.name = $4;
16640            lex->udf.returns=(Item_result) $6;
16641            lex->udf.dl=$8.str;
16642          }
16643        | remember_name FUNCTION_SYM ident
16644          RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
16645          {
16646            THD *thd= YYTHD;
16647            LEX *lex= thd->lex;
16648            if (is_native_function(thd, & $3))
16649            {
16650              my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
16651                       $3.str);
16652              MYSQL_YYABORT;
16653            }
16654            lex->sql_command = SQLCOM_CREATE_FUNCTION;
16655            lex->udf.type= UDFTYPE_FUNCTION;
16656            lex->stmt_definition_begin= $1;
16657            lex->udf.name = $3;
16658            lex->udf.returns=(Item_result) $5;
16659            lex->udf.dl=$7.str;
16660          }
16661        ;
16662
16663sf_tail:
16664          remember_name /* $1 */
16665          FUNCTION_SYM /* $2 */
16666          sp_name /* $3 */
16667          '(' /* $4 */
16668          { /* $5 */
16669            THD *thd= YYTHD;
16670            LEX *lex= thd->lex;
16671
16672            lex->stmt_definition_begin= $1;
16673            lex->spname= $3;
16674
16675            if (lex->sphead)
16676            {
16677              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
16678              MYSQL_YYABORT;
16679            }
16680
16681            sp_head *sp= sp_start_parsing(thd, SP_TYPE_FUNCTION, lex->spname);
16682
16683            if (!sp)
16684              MYSQL_YYABORT;
16685
16686            lex->sphead= sp;
16687
16688            /*
16689              NOTE: the start of the parameters in the query string is
16690              YYLIP->get_cpp_tok_start() + 1. 1 is the length of '(', which the
16691              tokenizer has just passed (just YYLIP->get_cpp_tok_start() points
16692              to the '(').
16693            */
16694
16695            sp->m_parser_data.set_parameter_start_ptr(
16696              YYLIP->get_cpp_tok_start() + 1);
16697          }
16698          sp_fdparam_list /* $6 */
16699          ')' /* $7 */
16700          { /* $8 */
16701            Lex->sphead->m_parser_data.set_parameter_end_ptr(
16702              YYLIP->get_cpp_tok_start());
16703          }
16704          RETURNS_SYM /* $9 */
16705          { /* $10 */
16706            LEX *lex= Lex;
16707            lex->charset= NULL;
16708            lex->length= lex->dec= NULL;
16709            lex->interval_list.empty();
16710            lex->type= 0;
16711          }
16712          type_with_opt_collate /* $11 */
16713          { /* $12 */
16714            LEX *lex= Lex;
16715            sp_head *sp= lex->sphead;
16716            /*
16717              This was disabled in 5.1.12. See bug #20701
16718              When collation support in SP is implemented, then this test
16719              should be removed.
16720            */
16721            if (($11 == MYSQL_TYPE_STRING || $11 == MYSQL_TYPE_VARCHAR)
16722                && (lex->type & BINCMP_FLAG))
16723            {
16724              my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
16725              MYSQL_YYABORT;
16726            }
16727
16728            if (fill_field_definition(YYTHD, sp,
16729                                      (enum enum_field_types) $11,
16730                                      &sp->m_return_field_def))
16731              MYSQL_YYABORT;
16732
16733            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
16734          }
16735          sp_c_chistics /* $13 */
16736          { /* $14 */
16737            THD *thd= YYTHD;
16738            LEX *lex= thd->lex;
16739
16740            lex->sphead->m_chistics= &lex->sp_chistics;
16741            lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
16742          }
16743          sp_proc_stmt /* $15 */
16744          {
16745            THD *thd= YYTHD;
16746            LEX *lex= thd->lex;
16747            sp_head *sp= lex->sphead;
16748
16749            if (sp->is_not_allowed_in_function("function"))
16750              MYSQL_YYABORT;
16751
16752            sp_finish_parsing(thd);
16753
16754            lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
16755
16756            if (!(sp->m_flags & sp_head::HAS_RETURN))
16757            {
16758              my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
16759              MYSQL_YYABORT;
16760            }
16761
16762            if (is_native_function(thd, & sp->m_name))
16763            {
16764              /*
16765                This warning will be printed when
16766                [1] A client query is parsed,
16767                [2] A stored function is loaded by db_load_routine.
16768                Printing the warning for [2] is intentional, to cover the
16769                following scenario:
16770                - A user define a SF 'foo' using MySQL 5.N
16771                - An application uses select foo(), and works.
16772                - MySQL 5.{N+1} defines a new native function 'foo', as
16773                part of a new feature.
16774                - MySQL 5.{N+1} documentation is updated, and should mention
16775                that there is a potential incompatible change in case of
16776                existing stored function named 'foo'.
16777                - The user deploys 5.{N+1}. At this point, 'select foo()'
16778                means something different, and the user code is most likely
16779                broken (it's only safe if the code is 'select db.foo()').
16780                With a warning printed when the SF is loaded (which has to occur
16781                before the call), the warning will provide a hint explaining
16782                the root cause of a later failure of 'select foo()'.
16783                With no warning printed, the user code will fail with no
16784                apparent reason.
16785                Printing a warning each time db_load_routine is executed for
16786                an ambiguous function is annoying, since that can happen a lot,
16787                but in practice should not happen unless there *are* name
16788                collisions.
16789                If a collision exists, it should not be silenced but fixed.
16790              */
16791              push_warning_printf(thd,
16792                                  Sql_condition::WARN_LEVEL_NOTE,
16793                                  ER_NATIVE_FCT_NAME_COLLISION,
16794                                  ER(ER_NATIVE_FCT_NAME_COLLISION),
16795                                  sp->m_name.str);
16796            }
16797          }
16798        ;
16799
16800sp_tail:
16801          PROCEDURE_SYM remember_name sp_name
16802          {
16803            THD *thd= YYTHD;
16804            LEX *lex= Lex;
16805
16806            if (lex->sphead)
16807            {
16808              my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE");
16809              MYSQL_YYABORT;
16810            }
16811
16812            lex->stmt_definition_begin= $2;
16813
16814            sp_head *sp= sp_start_parsing(thd, SP_TYPE_PROCEDURE, $3);
16815
16816            if (!sp)
16817              MYSQL_YYABORT;
16818
16819            lex->sphead= sp;
16820          }
16821          '('
16822          {
16823            /*
16824              NOTE: the start of the parameters in the query string is
16825              YYLIP->get_cpp_tok_start() + 1. 1 is the length of '(', which the
16826              tokenizer has just passed (just YYLIP->get_cpp_tok_start() points
16827              to the '(').
16828            */
16829
16830            Lex->sphead->m_parser_data.set_parameter_start_ptr(
16831              YYLIP->get_cpp_tok_start() + 1);
16832          }
16833          sp_pdparam_list
16834          ')'
16835          {
16836            THD *thd= YYTHD;
16837            LEX *lex= thd->lex;
16838
16839            Lex->sphead->m_parser_data.set_parameter_end_ptr(
16840              YYLIP->get_cpp_tok_start());
16841
16842            memset(&lex->sp_chistics, 0, sizeof(st_sp_chistics));
16843          }
16844          sp_c_chistics
16845          {
16846            THD *thd= YYTHD;
16847            LEX *lex= thd->lex;
16848
16849            lex->sphead->m_chistics= &lex->sp_chistics;
16850            lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
16851          }
16852          sp_proc_stmt
16853          {
16854            THD *thd= YYTHD;
16855            LEX *lex= Lex;
16856
16857            sp_finish_parsing(thd);
16858
16859            lex->sql_command= SQLCOM_CREATE_PROCEDURE;
16860          }
16861        ;
16862
16863/*************************************************************************/
16864
16865xa:
16866          XA_SYM begin_or_start xid opt_join_or_resume
16867          {
16868            Lex->sql_command = SQLCOM_XA_START;
16869          }
16870        | XA_SYM END xid opt_suspend
16871          {
16872            Lex->sql_command = SQLCOM_XA_END;
16873          }
16874        | XA_SYM PREPARE_SYM xid
16875          {
16876            Lex->sql_command = SQLCOM_XA_PREPARE;
16877          }
16878        | XA_SYM COMMIT_SYM xid opt_one_phase
16879          {
16880            Lex->sql_command = SQLCOM_XA_COMMIT;
16881          }
16882        | XA_SYM ROLLBACK_SYM xid
16883          {
16884            Lex->sql_command = SQLCOM_XA_ROLLBACK;
16885          }
16886        | XA_SYM RECOVER_SYM
16887          {
16888            Lex->sql_command = SQLCOM_XA_RECOVER;
16889          }
16890        ;
16891
16892xid:
16893          text_string
16894          {
16895            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE);
16896            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
16897              MYSQL_YYABORT;
16898            Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0);
16899          }
16900          | text_string ',' text_string
16901          {
16902            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
16903            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
16904              MYSQL_YYABORT;
16905            Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length());
16906          }
16907          | text_string ',' text_string ',' ulong_num
16908          {
16909            MYSQL_YYABORT_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE);
16910            if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID))))
16911              MYSQL_YYABORT;
16912            Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length());
16913          }
16914        ;
16915
16916begin_or_start:
16917          BEGIN_SYM {}
16918        | START_SYM {}
16919        ;
16920
16921opt_join_or_resume:
16922          /* nothing */ { Lex->xa_opt=XA_NONE;        }
16923        | JOIN_SYM      { Lex->xa_opt=XA_JOIN;        }
16924        | RESUME_SYM    { Lex->xa_opt=XA_RESUME;      }
16925        ;
16926
16927opt_one_phase:
16928          /* nothing */     { Lex->xa_opt=XA_NONE;        }
16929        | ONE_SYM PHASE_SYM { Lex->xa_opt=XA_ONE_PHASE;   }
16930        ;
16931
16932opt_suspend:
16933          /* nothing */
16934          { Lex->xa_opt=XA_NONE;        }
16935        | SUSPEND_SYM
16936          { Lex->xa_opt=XA_SUSPEND;     }
16937          opt_migrate
16938        ;
16939
16940opt_migrate:
16941          /* nothing */       {}
16942        | FOR_SYM MIGRATE_SYM { Lex->xa_opt=XA_FOR_MIGRATE; }
16943        ;
16944
16945install:
16946          INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys
16947          {
16948            LEX *lex= Lex;
16949            lex->sql_command= SQLCOM_INSTALL_PLUGIN;
16950            lex->comment= $3;
16951            lex->ident= $5;
16952          }
16953        ;
16954
16955uninstall:
16956          UNINSTALL_SYM PLUGIN_SYM ident
16957          {
16958            LEX *lex= Lex;
16959            lex->sql_command= SQLCOM_UNINSTALL_PLUGIN;
16960            lex->comment= $3;
16961          }
16962        ;
16963
16964/**
16965  @} (end of group Parser)
16966*/
16967