sql_lex.cc 227 KB
Newer Older
Sergei Golubchik's avatar
Sergei Golubchik committed
1
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
2
   Copyright (c) 2009, 2018, MariaDB Corporation
unknown's avatar
unknown committed
3

unknown's avatar
unknown committed
4 5
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
unknown's avatar
unknown committed
6
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
7

unknown's avatar
unknown committed
8 9 10 11
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
unknown's avatar
unknown committed
12

unknown's avatar
unknown committed
13 14
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
15
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
unknown's avatar
unknown committed
16 17 18 19


/* A lexical scanner on a temporary buffer with a yacc interface */

20
#define MYSQL_LEX 1
21
#include "mariadb.h"
22 23 24 25
#include "sql_priv.h"
#include "sql_class.h"                          // sql_lex.h: SQLCOM_END
#include "sql_lex.h"
#include "sql_parse.h"                          // add_to_list
unknown's avatar
unknown committed
26 27 28
#include "item_create.h"
#include <m_ctype.h>
#include <hash.h>
29
#include "sp_head.h"
30
#include "sp.h"
31
#include "sql_select.h"
32
#include "sql_cte.h"
33
#include "sql_signal.h"
unknown's avatar
unknown committed
34

35

36
void LEX::parse_error(uint err_number)
37
{
38
  thd->parse_error(err_number);
39 40
}

unknown's avatar
unknown committed
41

42
static int lex_one_token(YYSTYPE *yylval, THD *thd);
43

44

45 46 47
/**
  LEX_STRING constant for null-string to be used in parser and other places.
*/
48 49 50 51 52 53
const LEX_STRING empty_lex_str=   {(char *) "", 0};
const LEX_CSTRING null_clex_str=  {NULL, 0};
const LEX_CSTRING empty_clex_str= {"", 0};
const LEX_CSTRING star_clex_str=  {"*", 1};
const LEX_CSTRING param_clex_str= {"?", 1};

54 55 56 57 58 59 60 61 62 63
/**
  @note The order of the elements of this array must correspond to
  the order of elements in enum_binlog_stmt_unsafe.
*/
const int
Query_tables_list::binlog_stmt_unsafe_errcode[BINLOG_STMT_UNSAFE_COUNT] =
{
  ER_BINLOG_UNSAFE_LIMIT,
  ER_BINLOG_UNSAFE_INSERT_DELAYED,
  ER_BINLOG_UNSAFE_SYSTEM_TABLE,
64
  ER_BINLOG_UNSAFE_AUTOINC_COLUMNS,
65 66
  ER_BINLOG_UNSAFE_UDF,
  ER_BINLOG_UNSAFE_SYSTEM_VARIABLE,
67
  ER_BINLOG_UNSAFE_SYSTEM_FUNCTION,
68
  ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS,
69 70
  ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE,
  ER_BINLOG_UNSAFE_MIXED_STATEMENT,
71 72
  ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT,
  ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE,
73
  ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT,
74 75 76
  ER_BINLOG_UNSAFE_REPLACE_SELECT,
  ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT,
  ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT,
77
  ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC,
78
  ER_BINLOG_UNSAFE_UPDATE_IGNORE,
79 80
  ER_BINLOG_UNSAFE_INSERT_TWO_KEYS,
  ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
81 82
};

83

84
/* Longest standard keyword name */
85

unknown's avatar
unknown committed
86 87
#define TOCK_NAME_LENGTH 24

88 89
/*
  The following data is based on the latin1 character set, and is only
unknown's avatar
unknown committed
90 91 92
  used when comparing keywords
*/

unknown's avatar
unknown committed
93 94
static uchar to_upper_lex[]=
{
unknown's avatar
unknown committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
   96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
  208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
};

113 114 115 116 117 118 119 120 121 122 123
/* 
  Names of the index hints (for error messages). Keep in sync with 
  index_hint_type 
*/

const char * index_hint_type_name[] =
{
  "IGNORE INDEX", 
  "USE INDEX", 
  "FORCE INDEX"
};
124

unknown's avatar
unknown committed
125 126 127 128 129 130 131
inline int lex_casecmp(const char *s, const char *t, uint len)
{
  while (len-- != 0 &&
	 to_upper_lex[(uchar) *s++] == to_upper_lex[(uchar) *t++]) ;
  return (int) len+1;
}

unknown's avatar
unknown committed
132
#include <lex_hash.h>
unknown's avatar
unknown committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153


void lex_init(void)
{
  uint i;
  DBUG_ENTER("lex_init");
  for (i=0 ; i < array_elements(symbols) ; i++)
    symbols[i].length=(uchar) strlen(symbols[i].name);
  for (i=0 ; i < array_elements(sql_functions) ; i++)
    sql_functions[i].length=(uchar) strlen(sql_functions[i].name);

  DBUG_VOID_RETURN;
}


void lex_free(void)
{					// Call this when daemon ends
  DBUG_ENTER("lex_free");
  DBUG_VOID_RETURN;
}

154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
/**
  Initialize lex object for use in fix_fields and parsing.

  SYNOPSIS
    init_lex_with_single_table()
    @param thd                 The thread object
    @param table               The table object
  @return Operation status
    @retval TRUE                An error occurred, memory allocation error
    @retval FALSE               Ok

  DESCRIPTION
    This function is used to initialize a lex object on the
    stack for use by fix_fields and for parsing. In order to
    work properly it also needs to initialize the
    Name_resolution_context object of the lexer.
    Finally it needs to set a couple of variables to ensure
    proper functioning of fix_fields.
*/

int
init_lex_with_single_table(THD *thd, TABLE *table, LEX *lex)
{
  TABLE_LIST *table_list;
  Table_ident *table_ident;
  SELECT_LEX *select_lex= &lex->select_lex;
  Name_resolution_context *context= &select_lex->context;
  /*
    We will call the parser to create a part_info struct based on the
    partition string stored in the frm file.
    We will use a local lex object for this purpose. However we also
    need to set the Name_resolution_object for this lex object. We
    do this by using add_table_to_list where we add the table that
    we're working with to the Name_resolution_context.
  */
  thd->lex= lex;
  lex_start(thd);
  context->init();
  if ((!(table_ident= new Table_ident(thd,
193
                                      &table->s->db,
194
                                      &table->s->table_name,
195
                                      TRUE))) ||
196 197 198 199 200 201 202
      (!(table_list= select_lex->add_table_to_list(thd,
                                                   table_ident,
                                                   NULL,
                                                   0))))
    return TRUE;
  context->resolve_in_table_list_only(table_list);
  lex->use_only_table_context= TRUE;
Sergei Golubchik's avatar
Sergei Golubchik committed
203
  lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VCOL_EXPR;
204 205 206
  select_lex->cur_pos_in_select_list= UNDEF_POS;
  table->map= 1; //To ensure correct calculation of const item
  table_list->table= table;
Sergei Golubchik's avatar
Sergei Golubchik committed
207
  table_list->cacheable_table= false;
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
  return FALSE;
}

/**
  End use of local lex with single table

  SYNOPSIS
    end_lex_with_single_table()
    @param thd               The thread object
    @param table             The table object
    @param old_lex           The real lex object connected to THD

  DESCRIPTION
    This function restores the real lex object after calling
    init_lex_with_single_table and also restores some table
    variables temporarily set.
*/

void
end_lex_with_single_table(THD *thd, TABLE *table, LEX *old_lex)
{
  LEX *lex= thd->lex;
  table->map= 0;
  table->get_fields_in_item_tree= FALSE;
  lex_end(lex);
  thd->lex= old_lex;
}

unknown's avatar
unknown committed
236

237 238 239 240 241 242
void
st_parsing_options::reset()
{
  allows_variable= TRUE;
}

243 244 245 246 247

/**
  Perform initialization of Lex_input_stream instance.

  Basically, a buffer for pre-processed query. This buffer should be large
248 249
  enough to keep multi-statement query. The allocation is done once in
  Lex_input_stream::init() in order to prevent memory pollution when
250 251 252
  the server is processing large multi-statement queries.
*/

253
bool Lex_input_stream::init(THD *thd,
unknown's avatar
unknown committed
254
			    char* buff,
255
			    size_t length)
256
{
257 258 259
  DBUG_EXECUTE_IF("bug42064_simulate_oom",
                  DBUG_SET("+d,simulate_out_of_memory"););

260
  m_cpp_buf= (char*) thd->alloc(length + 1);
261 262 263 264 265

  DBUG_EXECUTE_IF("bug42064_simulate_oom",
                  DBUG_SET("-d,bug42064_simulate_oom");); 

  if (m_cpp_buf == NULL)
266
    return true;
267 268

  m_thd= thd;
269
  reset(buff, length);
270

271
  return false;
272 273 274 275 276 277 278 279 280 281 282 283
}


/**
  Prepare Lex_input_stream instance state for use for handling next SQL statement.

  It should be called between two statements in a multi-statement query.
  The operation resets the input stream to the beginning-of-parse state,
  but does not reallocate m_cpp_buf.
*/

void
284
Lex_input_stream::reset(char *buffer, size_t length)
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
{
  yylineno= 1;
  yylval= NULL;
  lookahead_token= -1;
  lookahead_yylval= NULL;
  m_ptr= buffer;
  m_tok_start= NULL;
  m_tok_end= NULL;
  m_end_of_query= buffer + length;
  m_tok_start_prev= NULL;
  m_buf= buffer;
  m_buf_length= length;
  m_echo= TRUE;
  m_cpp_tok_start= NULL;
  m_cpp_tok_start_prev= NULL;
  m_cpp_tok_end= NULL;
  m_body_utf8= NULL;
  m_cpp_utf8_processed_ptr= NULL;
  next_state= MY_LEX_START;
  found_semicolon= NULL;
305
  ignore_space= MY_TEST(m_thd->variables.sql_mode & MODE_IGNORE_SPACE);
306 307 308 309
  stmt_prepare_mode= FALSE;
  multi_statements= TRUE;
  in_comment=NO_COMMENT;
  m_underscore_cs= NULL;
310
  m_cpp_ptr= m_cpp_buf;
311 312 313
}


unknown's avatar
unknown committed
314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
/**
  The operation is called from the parser in order to
  1) designate the intention to have utf8 body;
  1) Indicate to the lexer that we will need a utf8 representation of this
     statement;
  2) Determine the beginning of the body.

  @param thd        Thread context.
  @param begin_ptr  Pointer to the start of the body in the pre-processed
                    buffer.
*/

void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
{
  DBUG_ASSERT(begin_ptr);
  DBUG_ASSERT(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);

331
  size_t body_utf8_length= get_body_utf8_maximum_length(thd);
unknown's avatar
unknown committed
332 333 334 335 336 337 338 339

  m_body_utf8= (char *) thd->alloc(body_utf8_length + 1);
  m_body_utf8_ptr= m_body_utf8;
  *m_body_utf8_ptr= 0;

  m_cpp_utf8_processed_ptr= begin_ptr;
}

340

341
size_t Lex_input_stream::get_body_utf8_maximum_length(THD *thd)
342 343 344 345 346 347 348 349 350 351 352 353 354 355
{
  /*
    String literals can grow during escaping:
    1a. Character string '<TAB>' can grow to '\t', 3 bytes to 4 bytes growth.
    1b. Character string '1000 times <TAB>' grows from
        1002 to 2002 bytes (including quotes), which gives a little bit
        less than 2 times growth.
    "2" should be a reasonable multiplier that safely covers escaping needs.
  */
  return (m_buf_length / thd->variables.character_set_client->mbminlen) *
          my_charset_utf8_bin.mbmaxlen * 2/*for escaping*/;
}


unknown's avatar
unknown committed
356
/**
unknown's avatar
unknown committed
357
  @brief The operation appends unprocessed part of pre-processed buffer till
unknown's avatar
unknown committed
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to end_ptr.

  The idea is that some tokens in the pre-processed buffer (like character
  set introducers) should be skipped.

  Example:
    CPP buffer: SELECT 'str1', _latin1 'str2';
    m_cpp_utf8_processed_ptr -- points at the "SELECT ...";
    In order to skip "_latin1", the following call should be made:
      body_utf8_append(<pointer to "_latin1 ...">, <pointer to " 'str2'...">)

  @param ptr      Pointer in the pre-processed buffer, which specifies the
                  end of the chunk, which should be appended to the utf8
                  body.
  @param end_ptr  Pointer in the pre-processed buffer, to which
                  m_cpp_utf8_processed_ptr will be set in the end of the
                  operation.
*/

void Lex_input_stream::body_utf8_append(const char *ptr,
                                        const char *end_ptr)
{
  DBUG_ASSERT(m_cpp_buf <= ptr && ptr <= m_cpp_buf + m_buf_length);
  DBUG_ASSERT(m_cpp_buf <= end_ptr && end_ptr <= m_cpp_buf + m_buf_length);

  if (!m_body_utf8)
    return;

  if (m_cpp_utf8_processed_ptr >= ptr)
    return;

389
  size_t bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;
unknown's avatar
unknown committed
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422

  memcpy(m_body_utf8_ptr, m_cpp_utf8_processed_ptr, bytes_to_copy);
  m_body_utf8_ptr += bytes_to_copy;
  *m_body_utf8_ptr= 0;

  m_cpp_utf8_processed_ptr= end_ptr;
}

/**
  The operation appends unprocessed part of the pre-processed buffer till
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to ptr.

  @param ptr  Pointer in the pre-processed buffer, which specifies the end
              of the chunk, which should be appended to the utf8 body.
*/

void Lex_input_stream::body_utf8_append(const char *ptr)
{
  body_utf8_append(ptr, ptr);
}

/**
  The operation converts the specified text literal to the utf8 and appends
  the result to the utf8-body.

  @param thd      Thread context.
  @param txt      Text literal.
  @param txt_cs   Character set of the text literal.
  @param end_ptr  Pointer in the pre-processed buffer, to which
                  m_cpp_utf8_processed_ptr will be set in the end of the
                  operation.
*/

423
void Lex_input_stream::body_utf8_append_ident(THD *thd,
424
                                              const LEX_CSTRING *txt,
425
                                              const char *end_ptr)
unknown's avatar
unknown committed
426 427 428 429
{
  if (!m_cpp_utf8_processed_ptr)
    return;

430
  LEX_CSTRING utf_txt;
431
  CHARSET_INFO *txt_cs= thd->charset();
unknown's avatar
unknown committed
432

unknown's avatar
unknown committed
433
  if (!my_charset_same(txt_cs, &my_charset_utf8_general_ci))
unknown's avatar
unknown committed
434
  {
435 436
    LEX_STRING to;
    thd->convert_string(&to,
unknown's avatar
unknown committed
437
                        &my_charset_utf8_general_ci,
438
                        txt->str, (uint) txt->length,
unknown's avatar
unknown committed
439
                        txt_cs);
440 441 442
    utf_txt.str=    to.str;
    utf_txt.length= to.length;

unknown's avatar
unknown committed
443 444
  }
  else
445
    utf_txt= *txt;
unknown's avatar
unknown committed
446 447 448 449 450 451 452 453 454 455

  /* NOTE: utf_txt.length is in bytes, not in symbols. */

  memcpy(m_body_utf8_ptr, utf_txt.str, utf_txt.length);
  m_body_utf8_ptr += utf_txt.length;
  *m_body_utf8_ptr= 0;

  m_cpp_utf8_processed_ptr= end_ptr;
}

456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476



extern "C" {

/**
  Escape a character. Consequently puts "escape" and "wc" characters into
  the destination utf8 string.
  @param cs     - the character set (utf8)
  @param escape - the escape character (backslash, single quote, double quote)
  @param wc     - the character to be escaped
  @param str    - the destination string
  @param end    - the end of the destination string
  @returns      - a code according to the wc_mb() convension.
*/
int my_wc_mb_utf8_with_escape(CHARSET_INFO *cs, my_wc_t escape, my_wc_t wc,
                              uchar *str, uchar *end)
{
  DBUG_ASSERT(escape > 0);
  if (str + 1 >= end)
    return MY_CS_TOOSMALL2;  // Not enough space, need at least two bytes.
477
  *str= (uchar)escape;
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
  int cnvres= my_charset_utf8_handler.wc_mb(cs, wc, str + 1, end);
  if (cnvres > 0)
    return cnvres + 1;       // The character was normally put
  if (cnvres == MY_CS_ILUNI)
    return MY_CS_ILUNI;      // Could not encode "wc" (e.g. non-BMP character)
  DBUG_ASSERT(cnvres <= MY_CS_TOOSMALL);
  return cnvres - 1;         // Not enough space
}


/**
  Optionally escape a character.
  If "escape" is non-zero, then both "escape" and "wc" are put to
  the destination string. Otherwise, only "wc" is put.
  @param cs     - the character set (utf8)
  @param wc     - the character to be optionally escaped
  @param escape - the escape character, or 0
  @param ewc    - the escaped replacement of "wc" (e.g. 't' for '\t')
  @param str    - the destination string
  @param end    - the end of the destination string
  @returns      - a code according to the wc_mb() conversion.
*/
int my_wc_mb_utf8_opt_escape(CHARSET_INFO *cs,
                             my_wc_t wc, my_wc_t escape, my_wc_t ewc,
                             uchar *str, uchar *end)
{
  return escape ? my_wc_mb_utf8_with_escape(cs, escape, ewc, str, end) :
                  my_charset_utf8_handler.wc_mb(cs, wc, str, end);
}

/**
  Encode a character with optional backlash escaping and quote escaping.
  Quote marks are escaped using another quote mark.
  Additionally, if "escape" is non-zero, then special characters are
  also escaped using "escape".
  Otherwise (if "escape" is zero, e.g. in case of MODE_NO_BACKSLASH_ESCAPES),
  then special characters are not escaped and handled as normal characters.

  @param cs        - the character set (utf8)
  @param wc        - the character to be encoded
  @param str       - the destination string
  @param end       - the end of the destination string
  @param sep       - the string delimiter (e.g. ' or ")
  @param escape    - the escape character (backslash, or 0)
  @returns         - a code according to the wc_mb() convension.
*/
int my_wc_mb_utf8_escape(CHARSET_INFO *cs, my_wc_t wc, uchar *str, uchar *end,
                         my_wc_t sep, my_wc_t escape)
{
  DBUG_ASSERT(escape == 0 || escape == '\\');
  DBUG_ASSERT(sep == '"' || sep == '\'');
  switch (wc) {
  case 0:      return my_wc_mb_utf8_opt_escape(cs, wc, escape, '0', str, end);
  case '\t':   return my_wc_mb_utf8_opt_escape(cs, wc, escape, 't', str, end);
  case '\r':   return my_wc_mb_utf8_opt_escape(cs, wc, escape, 'r', str, end);
  case '\n':   return my_wc_mb_utf8_opt_escape(cs, wc, escape, 'n', str, end);
  case '\032': return my_wc_mb_utf8_opt_escape(cs, wc, escape, 'Z', str, end);
  case '\'':
  case '\"':
    if (wc == sep)
      return my_wc_mb_utf8_with_escape(cs, wc, wc, str, end);
  }
  return my_charset_utf8_handler.wc_mb(cs, wc, str, end); // No escaping needed
}


/** wc_mb() compatible routines for all sql_mode and delimiter combinations */
int my_wc_mb_utf8_escape_single_quote_and_backslash(CHARSET_INFO *cs,
                                                    my_wc_t wc,
                                                    uchar *str, uchar *end)
{
  return my_wc_mb_utf8_escape(cs, wc, str, end, '\'', '\\');
}


int my_wc_mb_utf8_escape_double_quote_and_backslash(CHARSET_INFO *cs,
                                                    my_wc_t wc,
                                                    uchar *str, uchar *end)
{
  return my_wc_mb_utf8_escape(cs, wc, str, end, '"', '\\');
}


int my_wc_mb_utf8_escape_single_quote(CHARSET_INFO *cs, my_wc_t wc,
                                      uchar *str, uchar *end)
{
  return my_wc_mb_utf8_escape(cs, wc, str, end, '\'', 0);
}


int my_wc_mb_utf8_escape_double_quote(CHARSET_INFO *cs, my_wc_t wc,
                                      uchar *str, uchar *end)
{
  return my_wc_mb_utf8_escape(cs, wc, str, end, '"', 0);
}

}; // End of extern "C"


/**
  Get an escaping function, depending on the current sql_mode and the
  string separator.
*/
my_charset_conv_wc_mb
Lex_input_stream::get_escape_func(THD *thd, my_wc_t sep) const
{
  return thd->backslash_escapes() ?
         (sep == '"' ? my_wc_mb_utf8_escape_double_quote_and_backslash:
                       my_wc_mb_utf8_escape_single_quote_and_backslash) :
         (sep == '"' ? my_wc_mb_utf8_escape_double_quote:
                       my_wc_mb_utf8_escape_single_quote);
}


/**
  Append a text literal to the end of m_body_utf8.
  The string is escaped according to the current sql_mode and the
  string delimiter (e.g. ' or ").

  @param thd       - current THD
  @param txt       - the string to be appended to m_body_utf8.
                     Note, the string must be already unescaped.
  @param cs        - the character set of the string
  @param end_ptr   - m_cpp_utf8_processed_ptr will be set to this value
                     (see body_utf8_append_ident for details)
  @param sep       - the string delimiter (single or double quote)
*/
void Lex_input_stream::body_utf8_append_escape(THD *thd,
606
                                               const LEX_CSTRING *txt,
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638
                                               CHARSET_INFO *cs,
                                               const char *end_ptr,
                                               my_wc_t sep)
{
  DBUG_ASSERT(sep == '\'' || sep == '"');
  if (!m_cpp_utf8_processed_ptr)
    return;
  uint errors;
  /**
    We previously alloced m_body_utf8 to be able to store the query with all
    strings properly escaped. See get_body_utf8_maximum_length().
    So here we have guaranteedly enough space to append any string literal
    with escaping. Passing txt->length*2 as "available space" is always safe.
    For better safety purposes we could calculate get_body_utf8_maximum_length()
    every time we append a string, but this would affect performance negatively,
    so let's check that we don't get beyond the allocated buffer in
    debug build only.
  */
  DBUG_ASSERT(m_body_utf8 + get_body_utf8_maximum_length(thd) >=
              m_body_utf8_ptr + txt->length * 2);
  uint32 cnv_length= my_convert_using_func(m_body_utf8_ptr, txt->length * 2,
                                           &my_charset_utf8_general_ci,
                                           get_escape_func(thd, sep),
                                           txt->str, txt->length,
                                           cs, cs->cset->mb_wc,
                                           &errors);
  m_body_utf8_ptr+= cnv_length;
  *m_body_utf8_ptr= 0;
  m_cpp_utf8_processed_ptr= end_ptr;
}


Sergei Golubchik's avatar
Sergei Golubchik committed
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
void Lex_input_stream::add_digest_token(uint token, LEX_YYSTYPE yylval)
{
  if (m_digest != NULL)
  {
    m_digest= digest_add_token(m_digest, token, yylval);
  }
}

void Lex_input_stream::reduce_digest_token(uint token_left, uint token_right)
{
  if (m_digest != NULL)
  {
    m_digest= digest_reduce_token(m_digest, token_left, token_right);
  }
}
654

655 656 657 658 659 660 661 662
void lex_start(THD *thd)
{
  DBUG_ENTER("lex_start");
  thd->lex->start(thd);
  DBUG_VOID_RETURN;
}


663 664 665 666 667 668
/*
  This is called before every query that is to be parsed.
  Because of this, it's critical to not do too much things here.
  (We already do too much here)
*/

669
void LEX::start(THD *thd_arg)
unknown's avatar
unknown committed
670
{
671
  DBUG_ENTER("LEX::start");
672 673
  DBUG_PRINT("info", ("This: %p thd_arg->lex: %p thd_arg->stmt_lex: %p",
             this, thd_arg->lex, thd_arg->stmt_lex));
unknown's avatar
unknown committed
674

675
  thd= unit.thd= thd_arg;
676
  
677
  DBUG_ASSERT(!explain);
unknown's avatar
unknown committed
678

679 680
  context_stack.empty();
  unit.init_query();
681
  current_select_number= 1;
682
  select_lex.linkage= UNSPECIFIED_TYPE;
unknown's avatar
unknown committed
683
  /* 'parent_lex' is used in init_query() so it must be before it. */
684 685 686 687 688
  select_lex.parent_lex= this;
  select_lex.init_query();
  curr_with_clause= 0;
  with_clauses_list= 0;
  with_clauses_list_last_next= &with_clauses_list;
689
  create_view= NULL;
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
  value_list.empty();
  update_list.empty();
  set_var_list.empty();
  param_list.empty();
  view_list.empty();
  with_column_list.empty();
  with_persistent_for_clause= FALSE;
  column_list= NULL;
  index_list= NULL;
  prepared_stmt_params.empty();
  auxiliary_table_list.empty();
  unit.next= unit.master= unit.link_next= unit.return_to= 0;
  unit.prev= unit.link_prev= 0;
  unit.slave= current_select= all_selects_list= &select_lex;
  select_lex.master= &unit;
  select_lex.prev= &unit.slave;
  select_lex.link_next= select_lex.slave= select_lex.next= 0;
  select_lex.link_prev= (st_select_lex_node**)&(all_selects_list);
  select_lex.options= 0;
  select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
  select_lex.init_order();
  select_lex.group_list.empty();
  if (select_lex.group_list_ptrs)
    select_lex.group_list_ptrs->clear();
  describe= 0;
  analyze_stmt= 0;
  explain_json= false;
  subqueries= FALSE;
  context_analysis_only= 0;
  derived_tables= 0;
  safe_to_cache_query= 1;
  parsing_options.reset();
  empty_field_list_on_rset= 0;
  select_lex.select_number= 1;
  part_info= 0;
  select_lex.in_sum_expr=0;
  select_lex.ftfunc_list_alloc.empty();
  select_lex.ftfunc_list= &select_lex.ftfunc_list_alloc;
  select_lex.group_list.empty();
  select_lex.order_list.empty();
  select_lex.gorder_list.empty();
  m_sql_cmd= NULL;
  duplicates= DUP_ERROR;
  ignore= 0;
  spname= NULL;
  spcont= NULL;
  proc_list.first= 0;
  escape_used= FALSE;
738
  default_used= FALSE;
739 740 741 742 743 744 745 746 747
  query_tables= 0;
  reset_query_tables_list(FALSE);
  expr_allows_subselect= TRUE;
  use_only_table_context= FALSE;
  parse_vcol_expr= FALSE;
  check_exists= FALSE;
  create_info.lex_start();
  verbose= 0;

748
  name= null_clex_str;
749 750 751 752 753 754 755 756
  event_parse_data= NULL;
  profile_options= PROFILE_NONE;
  nest_level=0 ;
  select_lex.nest_level_base= &unit;
  allow_sum_func= 0;
  in_sum_func= NULL;

  used_tables= 0;
757
  table_type= TABLE_TYPE_UNKNOWN;
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772
  reset_slave_info.all= false;
  limit_rows_examined= 0;
  limit_rows_examined_cnt= ULONGLONG_MAX;
  var_list.empty();
  stmt_var_list.empty();
  proc_list.elements=0;

  save_group_list.empty();
  save_order_list.empty();
  win_ref= NULL;
  win_frame= NULL;
  frame_top_bound= NULL;
  frame_bottom_bound= NULL;
  win_spec= NULL;

773 774
  vers_conditions.empty();

775
  is_lex_started= TRUE;
unknown's avatar
unknown committed
776
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
777 778 779 780
}

void lex_end(LEX *lex)
{
unknown's avatar
unknown committed
781
  DBUG_ENTER("lex_end");
782
  DBUG_PRINT("enter", ("lex: %p", lex));
unknown's avatar
unknown committed
783

784 785 786 787 788 789 790 791 792 793
  lex_end_stage1(lex);
  lex_end_stage2(lex);

  DBUG_VOID_RETURN;
}

void lex_end_stage1(LEX *lex)
{
  DBUG_ENTER("lex_end_stage1");

unknown's avatar
unknown committed
794
  /* release used plugins */
795 796 797 798 799
  if (lex->plugins.elements) /* No function call and no mutex if no plugins. */
  {
    plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, 
                       lex->plugins.elements);
  }
unknown's avatar
unknown committed
800 801
  reset_dynamic(&lex->plugins);

802 803 804 805 806 807 808 809 810 811 812 813 814 815
  if (lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_PREPARE)
  {
    /*
      Don't delete lex->sphead, it'll be needed for EXECUTE.
      Note that of all statements that populate lex->sphead
      only SQLCOM_COMPOUND can be PREPAREd
    */
    DBUG_ASSERT(lex->sphead == 0 || lex->sql_command == SQLCOM_COMPOUND);
  }
  else
  {
    delete lex->sphead;
    lex->sphead= NULL;
  }
816

817 818 819 820 821 822 823 824 825 826 827 828 829
  DBUG_VOID_RETURN;
}

/*
  MASTER INFO parameters (or state) is normally cleared towards the end
  of a statement. But in case of PS, the state needs to be preserved during
  its lifetime and should only be cleared on PS close or deallocation.
*/
void lex_end_stage2(LEX *lex)
{
  DBUG_ENTER("lex_end_stage2");

  /* Reset LEX_MASTER_INFO */
830
  lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER);
831
  delete_dynamic(&lex->delete_gtid_domain);
832

unknown's avatar
unknown committed
833
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
834 835
}

836 837 838 839
Yacc_state::~Yacc_state()
{
  if (yacc_yyss)
  {
840 841
    my_free(yacc_yyss);
    my_free(yacc_yyvs);
842
  }
unknown's avatar
unknown committed
843 844
}

845
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
unknown's avatar
unknown committed
846
{
847
  const char *tok= lip->get_tok_start();
unknown's avatar
unknown committed
848

849
  SYMBOL *symbol= get_hash_symbol(tok, len, function);
unknown's avatar
unknown committed
850 851
  if (symbol)
  {
852 853 854 855
    lip->yylval->symbol.symbol=symbol;
    lip->yylval->symbol.str= (char*) tok;
    lip->yylval->symbol.length=len;

856
    if ((symbol->tok == NOT_SYM) &&
857
        (lip->m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))
858 859
      return NOT2_SYM;
    if ((symbol->tok == OR_OR_SYM) &&
860
	!(lip->m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
861
      return OR2_SYM;
862

unknown's avatar
unknown committed
863 864 865 866 867
    return symbol->tok;
  }
  return 0;
}

868 869 870 871 872
/*
  Check if name is a keyword

  SYNOPSIS
    is_keyword()
873
    name      checked name (must not be empty)
874 875 876 877 878 879 880 881 882
    len       length of checked name

  RETURN VALUES
    0         name is a keyword
    1         name isn't a keyword
*/

bool is_keyword(const char *name, uint len)
{
883
  DBUG_ASSERT(len != 0);
884 885
  return get_hash_symbol(name,len,0)!=0;
}
unknown's avatar
unknown committed
886

887 888 889 890 891
/**
  Check if name is a sql function

    @param name      checked name

892
    @return is this a native function or not
893 894 895 896
    @retval 0         name is a function
    @retval 1         name isn't a function
*/

897
bool is_lex_native_function(const LEX_CSTRING *name)
898 899
{
  DBUG_ASSERT(name != NULL);
900
  return (get_hash_symbol(name->str, (uint) name->length, 1) != 0);
901 902
}

903

904
bool is_native_function(THD *thd, const LEX_CSTRING *name)
905
{
906
  if (find_native_function_builder(thd, name))
907 908 909 910 911 912 913 914 915
    return true;

  if (is_lex_native_function(name))
    return true;

  return false;
}


916
bool is_native_function_with_warn(THD *thd, const LEX_CSTRING *name)
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955
{
  if (!is_native_function(thd, name))
    return false;
  /*
    This warning will be printed when
    [1] A client query is parsed,
    [2] A stored function is loaded by db_load_routine.
    Printing the warning for [2] is intentional, to cover the
    following scenario:
    - A user define a SF 'foo' using MySQL 5.N
    - An application uses select foo(), and works.
    - MySQL 5.{N+1} defines a new native function 'foo', as
    part of a new feature.
    - MySQL 5.{N+1} documentation is updated, and should mention
    that there is a potential incompatible change in case of
    existing stored function named 'foo'.
    - The user deploys 5.{N+1}. At this point, 'select foo()'
    means something different, and the user code is most likely
    broken (it's only safe if the code is 'select db.foo()').
    With a warning printed when the SF is loaded (which has to
    occur before the call), the warning will provide a hint
    explaining the root cause of a later failure of 'select foo()'.
    With no warning printed, the user code will fail with no
    apparent reason.
    Printing a warning each time db_load_routine is executed for
    an ambiguous function is annoying, since that can happen a lot,
    but in practice should not happen unless there *are* name
    collisions.
    If a collision exists, it should not be silenced but fixed.
  */
  push_warning_printf(thd,
                      Sql_condition::WARN_LEVEL_NOTE,
                      ER_NATIVE_FCT_NAME_COLLISION,
                      ER_THD(thd, ER_NATIVE_FCT_NAME_COLLISION),
                      name->str);
  return true;
}


unknown's avatar
unknown committed
956 957
/* make a copy of token before ptr and set yytoklen */

958
static LEX_CSTRING get_token(Lex_input_stream *lip, uint skip, uint length)
unknown's avatar
unknown committed
959
{
960
  LEX_CSTRING tmp;
961
  lip->yyUnget();                       // ptr points now after last token char
962
  tmp.length= length;
963
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
unknown's avatar
unknown committed
964 965 966 967

  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
  lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;

unknown's avatar
unknown committed
968 969 970
  return tmp;
}

971 972 973 974 975 976 977
/* 
 todo: 
   There are no dangerous charsets in mysql for function 
   get_quoted_token yet. But it should be fixed in the 
   future to operate multichar strings (like ucs2)
*/

978 979 980
static LEX_CSTRING get_quoted_token(Lex_input_stream *lip,
                                    uint skip,
                                    uint length, char quote)
981
{
982
  LEX_CSTRING tmp;
983 984
  const char *from, *end;
  char *to;
985
  lip->yyUnget();                       // ptr points now after last token char
986
  tmp.length= length;
987
  tmp.str= to= (char*) lip->m_thd->alloc(tmp.length+1);
988
  from= lip->get_tok_start() + skip;
989
  end= to+length;
unknown's avatar
unknown committed
990 991 992 993

  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
  lip->m_cpp_text_end= lip->m_cpp_text_start + length;

994
  for ( ; to != end; )
995
  {
996
    if ((*to++= *from++) == quote)
unknown's avatar
unknown committed
997
    {
998
      from++;					// Skip double quotes
unknown's avatar
unknown committed
999 1000
      lip->m_cpp_text_start++;
    }
1001 1002 1003 1004 1005 1006
  }
  *to= 0;					// End null for safety
  return tmp;
}


1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
static size_t
my_unescape(CHARSET_INFO *cs, char *to, const char *str, const char *end,
            int sep, bool backslash_escapes)
{
  char *start= to;
  for ( ; str != end ; str++)
  {
#ifdef USE_MB
    int l;
    if (use_mb(cs) && (l= my_ismbchar(cs, str, end)))
    {
      while (l--)
        *to++ = *str++;
      str--;
      continue;
    }
#endif
    if (backslash_escapes && *str == '\\' && str + 1 != end)
    {
      switch(*++str) {
      case 'n':
        *to++='\n';
        break;
      case 't':
        *to++= '\t';
        break;
      case 'r':
        *to++ = '\r';
        break;
      case 'b':
        *to++ = '\b';
        break;
      case '0':
        *to++= 0;                      // Ascii null
        break;
      case 'Z':                        // ^Z must be escaped on Win32
        *to++='\032';
        break;
      case '_':
      case '%':
        *to++= '\\';                   // remember prefix for wildcard
        /* Fall through */
      default:
        *to++= *str;
        break;
      }
    }
    else if (*str == sep)
      *to++= *str++;                // Two ' or "
    else
      *to++ = *str;
  }
  *to= 0;
  return to - start;
}


size_t
Lex_input_stream::unescape(CHARSET_INFO *cs, char *to,
                           const char *str, const char *end,
                           int sep)
{
  return my_unescape(cs, to, str, end, sep, m_thd->backslash_escapes());
}


1073 1074 1075 1076
/*
  Return an unescaped text literal without quotes
  Fix sometimes to do only one scan of the string
*/
unknown's avatar
unknown committed
1077

1078
bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep,
1079
                                int pre_skip, int post_skip)
unknown's avatar
unknown committed
1080
{
1081
  reg1 uchar c;
unknown's avatar
unknown committed
1082
  uint found_escape=0;
1083
  CHARSET_INFO *cs= m_thd->charset();
unknown's avatar
unknown committed
1084

1085
  dst->set_8bit(false);
1086
  while (! eof())
unknown's avatar
unknown committed
1087
  {
1088
    c= yyGet();
1089 1090
    if (c & 0x80)
      dst->set_8bit(true);
unknown's avatar
unknown committed
1091
#ifdef USE_MB
1092 1093 1094
    {
      int l;
      if (use_mb(cs) &&
1095
          (l = my_ismbchar(cs,
1096 1097 1098
                           get_ptr() -1,
                           get_end_of_query()))) {
        skip_binary(l-1);
1099
        continue;
1100
      }
unknown's avatar
unknown committed
1101 1102
    }
#endif
1103
    if (c == '\\' &&
1104
        !(m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
unknown's avatar
unknown committed
1105 1106
    {					// Escaped character
      found_escape=1;
1107 1108 1109
      if (eof())
	return true;
      yySkip();
unknown's avatar
unknown committed
1110 1111 1112
    }
    else if (c == sep)
    {
1113
      if (c == yyGet())                 // Check if two separators in a row
unknown's avatar
unknown committed
1114
      {
1115
        found_escape=1;                 // duplicate. Remember for delete
unknown's avatar
unknown committed
1116 1117 1118
	continue;
      }
      else
1119
        yyUnget();
unknown's avatar
unknown committed
1120 1121

      /* Found end. Unescape and return string */
1122
      const char *str, *end;
1123
      char *to;
unknown's avatar
unknown committed
1124

1125 1126
      str= get_tok_start();
      end= get_ptr();
1127 1128 1129 1130 1131
      /* Extract the text from the token */
      str += pre_skip;
      end -= post_skip;
      DBUG_ASSERT(end >= str);

1132
      if (!(to= (char*) m_thd->alloc((uint) (end - str) + 1)))
1133
      {
1134
        dst->str= "";        // Sql_alloc has set error flag
1135 1136 1137
        dst->length= 0;
        return true;
      }
1138
      dst->str= to;
unknown's avatar
unknown committed
1139

1140 1141
      m_cpp_text_start= get_cpp_tok_start() + pre_skip;
      m_cpp_text_end= get_cpp_ptr() - post_skip;
unknown's avatar
unknown committed
1142

unknown's avatar
unknown committed
1143 1144
      if (!found_escape)
      {
1145 1146
        memcpy(to, str, dst->length= (end - str));
        to[dst->length]= 0;
unknown's avatar
unknown committed
1147 1148 1149
      }
      else
      {
1150
        dst->length= unescape(cs, to, str, end, sep);
unknown's avatar
unknown committed
1151
      }
1152
      return false;
unknown's avatar
unknown committed
1153 1154
    }
  }
1155
  return true;                         // unexpected end of query
unknown's avatar
unknown committed
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
}


/*
** Calc type of integer; long integer, longlong integer or real.
** Returns smallest type that match the string.
** When using unsigned long long values the result is converted to a real
** because else they will be unexpected sign changes because all calculation
** is done with longlong or double.
*/

static const char *long_str="2147483647";
static const uint long_len=10;
static const char *signed_long_str="-2147483648";
static const char *longlong_str="9223372036854775807";
static const uint longlong_len=19;
static const char *signed_longlong_str="-9223372036854775808";
static const uint signed_longlong_len=19;
unknown's avatar
unknown committed
1174 1175
static const char *unsigned_longlong_str="18446744073709551615";
static const uint unsigned_longlong_len=20;
unknown's avatar
unknown committed
1176

unknown's avatar
unknown committed
1177
static inline uint int_token(const char *str,uint length)
unknown's avatar
unknown committed
1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211
{
  if (length < long_len)			// quick normal case
    return NUM;
  bool neg=0;

  if (*str == '+')				// Remove sign and pre-zeros
  {
    str++; length--;
  }
  else if (*str == '-')
  {
    str++; length--;
    neg=1;
  }
  while (*str == '0' && length)
  {
    str++; length --;
  }
  if (length < long_len)
    return NUM;

  uint smaller,bigger;
  const char *cmp;
  if (neg)
  {
    if (length == long_len)
    {
      cmp= signed_long_str+1;
      smaller=NUM;				// If <= signed_long_str
      bigger=LONG_NUM;				// If >= signed_long_str
    }
    else if (length < signed_longlong_len)
      return LONG_NUM;
    else if (length > signed_longlong_len)
unknown's avatar
unknown committed
1212
      return DECIMAL_NUM;
unknown's avatar
unknown committed
1213 1214 1215 1216
    else
    {
      cmp=signed_longlong_str+1;
      smaller=LONG_NUM;				// If <= signed_longlong_str
unknown's avatar
unknown committed
1217
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230
    }
  }
  else
  {
    if (length == long_len)
    {
      cmp= long_str;
      smaller=NUM;
      bigger=LONG_NUM;
    }
    else if (length < longlong_len)
      return LONG_NUM;
    else if (length > longlong_len)
unknown's avatar
unknown committed
1231 1232
    {
      if (length > unsigned_longlong_len)
unknown's avatar
unknown committed
1233
        return DECIMAL_NUM;
unknown's avatar
unknown committed
1234 1235
      cmp=unsigned_longlong_str;
      smaller=ULONGLONG_NUM;
unknown's avatar
unknown committed
1236
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
1237
    }
unknown's avatar
unknown committed
1238 1239 1240 1241
    else
    {
      cmp=longlong_str;
      smaller=LONG_NUM;
1242
      bigger= ULONGLONG_NUM;
unknown's avatar
unknown committed
1243 1244 1245 1246 1247 1248
    }
  }
  while (*cmp && *cmp++ == *str++) ;
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
}

1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295

/**
  Given a stream that is advanced to the first contained character in 
  an open comment, consume the comment.  Optionally, if we are allowed, 
  recurse so that we understand comments within this current comment.

  At this level, we do not support version-condition comments.  We might 
  have been called with having just passed one in the stream, though.  In 
  that case, we probably want to tolerate mundane comments inside.  Thus,
  the case for recursion.

  @retval  Whether EOF reached before comment is closed.
*/
bool consume_comment(Lex_input_stream *lip, int remaining_recursions_permitted)
{
  reg1 uchar c;
  while (! lip->eof())
  {
    c= lip->yyGet();

    if (remaining_recursions_permitted > 0)
    {
      if ((c == '/') && (lip->yyPeek() == '*'))
      {
        lip->yySkip(); /* Eat asterisk */
        consume_comment(lip, remaining_recursions_permitted-1);
        continue;
      }
    }

    if (c == '*')
    {
      if (lip->yyPeek() == '/')
      {
        lip->yySkip(); /* Eat slash */
        return FALSE;
      }
    }

    if (c == '\n')
      lip->yylineno++;
  }

  return TRUE;
}


1296
/*
1297
  MYSQLlex remember the following states from the following MYSQLlex()
1298

1299 1300 1301
  @param yylval         [out]  semantic value of the token being parsed (yylval)
  @param thd            THD

1302 1303 1304 1305
  - MY_LEX_EOQ			Found end of query
  - MY_LEX_OPERATOR_OR_IDENT	Last state was an ident, text or number
				(which can't be followed by a signed number)
*/
unknown's avatar
unknown committed
1306

1307
int MYSQLlex(YYSTYPE *yylval, THD *thd)
1308 1309 1310
{
  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
  int token;
Galina Shalygina's avatar
Galina Shalygina committed
1311
  
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
  if (lip->lookahead_token >= 0)
  {
    /*
      The next token was already parsed in advance,
      return it.
    */
    token= lip->lookahead_token;
    lip->lookahead_token= -1;
    *yylval= *(lip->lookahead_yylval);
    lip->lookahead_yylval= NULL;
    return token;
  }

1325
  token= lex_one_token(yylval, thd);
1326
  lip->add_digest_token(token, yylval);
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336

  switch(token) {
  case WITH:
    /*
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
      which makes the grammar LALR(2).
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
      to transform the grammar into a LALR(1) grammar,
      which sql_yacc.yy can process.
    */
1337
    token= lex_one_token(yylval, thd);
1338
    lip->add_digest_token(token, yylval);
1339 1340 1341 1342 1343
    switch(token) {
    case CUBE_SYM:
      return WITH_CUBE_SYM;
    case ROLLUP_SYM:
      return WITH_ROLLUP_SYM;
1344 1345
    case SYSTEM:
      return WITH_SYSTEM_SYM;
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355
    default:
      /*
        Save the token following 'WITH'
      */
      lip->lookahead_yylval= lip->yylval;
      lip->yylval= NULL;
      lip->lookahead_token= token;
      return WITH;
    }
    break;
1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
  case FOR_SYM:
    /*
     * Additional look-ahead to resolve doubtful cases like:
     * SELECT ... FOR UPDATE
     * SELECT ... FOR SYSTEM_TIME ... .
     */
    token= lex_one_token(yylval, thd);
    lip->add_digest_token(token, yylval);
    switch(token) {
    case SYSTEM_TIME_SYM:
      return FOR_SYSTEM_TIME_SYM;
    default:
      /*
        Save the token following 'FOR_SYM'
      */
      lip->lookahead_yylval= lip->yylval;
      lip->yylval= NULL;
      lip->lookahead_token= token;
      return FOR_SYM;
    }
    break;
Galina Shalygina's avatar
Galina Shalygina committed
1377
  case VALUES:
1378 1379
    if (thd->lex->current_select->parsing_place == IN_UPDATE_ON_DUP_KEY ||
        thd->lex->current_select->parsing_place == IN_PART_FUNC)
Galina Shalygina's avatar
Galina Shalygina committed
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
      return VALUE_SYM;
    token= lex_one_token(yylval, thd);
    lip->add_digest_token(token, yylval);
    switch(token) {
    case LESS_SYM:
      return VALUES_LESS_SYM;
    case IN_SYM:
      return VALUES_IN_SYM;
    default:
      lip->lookahead_yylval= lip->yylval;
      lip->yylval= NULL;
      lip->lookahead_token= token;
      return VALUES;
    }
    break;
1395 1396 1397 1398 1399 1400
  default:
    break;
  }
  return token;
}

1401 1402 1403 1404 1405
int ORAlex(YYSTYPE *yylval, THD *thd)
{
  return MYSQLlex(yylval, thd);
}

1406
static int lex_one_token(YYSTYPE *yylval, THD *thd)
unknown's avatar
unknown committed
1407
{
1408
  reg1	uchar UNINIT_VAR(c);
1409
  bool comment_closed;
1410
  int	tokval, result_state;
unknown's avatar
unknown committed
1411
  uint length;
unknown's avatar
unknown committed
1412
  enum my_lex_states state;
1413
  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
1414
  LEX *lex= thd->lex;
1415 1416 1417
  CHARSET_INFO *const cs= thd->charset();
  const uchar *const state_map= cs->state_map;
  const uchar *const ident_map= cs->ident_map;
unknown's avatar
unknown committed
1418

1419
  lip->yylval=yylval;			// The global state
1420

1421
  lip->start_token();
1422 1423
  state=lip->next_state;
  lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
unknown's avatar
unknown committed
1424 1425
  for (;;)
  {
1426
    switch (state) {
1427 1428
    case MY_LEX_OPERATOR_OR_IDENT:	// Next is operator or keyword
    case MY_LEX_START:			// Start of token
1429 1430
      // Skip starting whitespace
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
unknown's avatar
unknown committed
1431 1432
      {
	if (c == '\n')
1433
	  lip->yylineno++;
1434 1435

        lip->yySkip();
unknown's avatar
unknown committed
1436
      }
1437 1438 1439 1440

      /* Start of real token */
      lip->restart_token();
      c= lip->yyGet();
1441
      state= (enum my_lex_states) state_map[c];
unknown's avatar
unknown committed
1442
      break;
1443
    case MY_LEX_ESCAPE:
1444
      if (!lip->eof() && lip->yyGet() == 'N')
unknown's avatar
unknown committed
1445 1446 1447 1448 1449
      {					// Allow \N as shortcut for NULL
	yylval->lex_str.str=(char*) "\\N";
	yylval->lex_str.length=2;
	return NULL_SYM;
      }
1450
      /* Fall through */
1451 1452
    case MY_LEX_CHAR:			// Unknown or single char token
    case MY_LEX_SKIP:			// This should not happen
1453 1454 1455 1456 1457 1458
      if (c != ')')
	lip->next_state= MY_LEX_START;	// Allow signed numbers
      return((int) c);

    case MY_LEX_MINUS_OR_COMMENT:
      if (lip->yyPeek() == '-' &&
1459 1460
          (my_isspace(cs,lip->yyPeekn(1)) ||
           my_iscntrl(cs,lip->yyPeekn(1))))
1461 1462 1463 1464
      {
        state=MY_LEX_COMMENT;
        break;
      }
1465 1466
      lip->next_state= MY_LEX_START;	// Allow signed numbers
      return((int) c);
1467

1468 1469 1470 1471 1472 1473 1474 1475 1476
    case MY_LEX_PLACEHOLDER:
      /*
        Check for a placeholder: it should not precede a possible identifier
        because of binlogging: when a placeholder is replaced with
        its value in a query for the binlog, the query must stay
        grammatically correct.
      */
      lip->next_state= MY_LEX_START;	// Allow signed numbers
      if (lip->stmt_prepare_mode && !ident_map[(uchar) lip->yyPeek()])
1477
        return(PARAM_MARKER);
1478
      return((int) c);
1479

1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
    case MY_LEX_COMMA:
      lip->next_state= MY_LEX_START;	// Allow signed numbers
      /*
        Warning:
        This is a work around, to make the "remember_name" rule in
        sql/sql_yacc.yy work properly.
        The problem is that, when parsing "select expr1, expr2",
        the code generated by bison executes the *pre* action
        remember_name (see select_item) *before* actually parsing the
        first token of expr2.
      */
      lip->restart_token();
unknown's avatar
unknown committed
1492 1493
      return((int) c);

unknown's avatar
unknown committed
1494
    case MY_LEX_IDENT_OR_NCHAR:
1495 1496
    {
      uint sep;
1497 1498
      if (lip->yyPeek() != '\'')
      {
unknown's avatar
unknown committed
1499 1500 1501
	state= MY_LEX_IDENT;
	break;
      }
1502
      /* Found N'string' */
1503
      lip->yySkip();                         // Skip '
1504 1505
      if (lip->get_text(&yylval->lex_string_with_metadata,
                        (sep= lip->yyGetLast()), 2, 1))
unknown's avatar
unknown committed
1506
      {
1507 1508
	state= MY_LEX_CHAR;             // Read char by char
	break;
unknown's avatar
unknown committed
1509
      }
1510 1511

      lip->body_utf8_append(lip->m_cpp_text_start);
1512
      lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata,
1513 1514
                                   national_charset_info,
                                   lip->m_cpp_text_end, sep);
1515
      return(NCHAR_STRING);
1516
    }
1517
    case MY_LEX_IDENT_OR_HEX:
1518
      if (lip->yyPeek() == '\'')
1519
      {					// Found x'hex-number'
1520
	state= MY_LEX_HEX_NUMBER;
1521 1522
	break;
      }
1523
      /* fall through */
unknown's avatar
unknown committed
1524
    case MY_LEX_IDENT_OR_BIN:
1525
      if (lip->yyPeek() == '\'')
unknown's avatar
unknown committed
1526 1527 1528 1529
      {                                 // Found b'bin-number'
        state= MY_LEX_BIN_NUMBER;
        break;
      }
1530
      /* fall through */
1531
    case MY_LEX_IDENT:
1532
      const char *start;
unknown's avatar
unknown committed
1533
#if defined(USE_MB) && defined(USE_MB_IDENT)
1534
      if (use_mb(cs))
unknown's avatar
unknown committed
1535
      {
1536
	result_state= IDENT_QUOTED;
1537 1538 1539
        int char_length= my_charlen(cs, lip->get_ptr() - 1,
                                        lip->get_end_of_query());
        if (char_length <= 0)
unknown's avatar
unknown committed
1540
        {
1541 1542
          state= MY_LEX_CHAR;
          continue;
unknown's avatar
unknown committed
1543
        }
1544 1545
        lip->skip_binary(char_length - 1);

1546
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
1547
        {
1548 1549 1550 1551 1552
          char_length= my_charlen(cs, lip->get_ptr() - 1,
                                      lip->get_end_of_query());
          if (char_length <= 0)
            break;
          lip->skip_binary(char_length - 1);
unknown's avatar
unknown committed
1553 1554 1555 1556
        }
      }
      else
#endif
1557
      {
1558 1559 1560 1561
        for (result_state= c;
             ident_map[(uchar) (c= lip->yyGet())];
             result_state|= c)
          ;
unknown's avatar
unknown committed
1562 1563
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1564
      }
1565 1566
      length= lip->yyLength();
      start= lip->get_ptr();
1567
      if (lip->ignore_space)
unknown's avatar
unknown committed
1568
      {
unknown's avatar
unknown committed
1569 1570 1571 1572
        /*
          If we find a space then this can't be an identifier. We notice this
          below by checking start != lex->ptr.
        */
1573
        for (; state_map[(uchar) c] == MY_LEX_SKIP ; c= lip->yyGet())
1574 1575 1576 1577
        {
          if (c == '\n')
            lip->yylineno++;
        }
unknown's avatar
unknown committed
1578
      }
1579 1580
      if (start == lip->get_ptr() && c == '.' &&
          ident_map[(uchar) lip->yyPeek()])
1581
	lip->next_state=MY_LEX_IDENT_SEP;
unknown's avatar
unknown committed
1582 1583
      else
      {					// '(' must follow directly if function
1584 1585
        lip->yyUnget();
	if ((tokval = find_keyword(lip, length, c == '(')))
unknown's avatar
unknown committed
1586
	{
1587
	  lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1588 1589
	  return(tokval);		// Was keyword
	}
1590
        lip->yySkip();                  // next state does a unget
unknown's avatar
unknown committed
1591
      }
1592
      yylval->lex_str=get_token(lip, 0, length);
1593

unknown's avatar
unknown committed
1594
      /*
1595 1596
         Note: "SELECT _bla AS 'alias'"
         _bla should be considered as a IDENT if charset haven't been found.
unknown's avatar
unknown committed
1597
         So we don't use MYF(MY_WME) with get_charset_by_csname to avoid
1598 1599 1600
         producing an error.
      */

unknown's avatar
unknown committed
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
      if (yylval->lex_str.str[0] == '_')
      {
        CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1,
                                                MY_CS_PRIMARY, MYF(0));
        if (cs)
        {
          yylval->charset= cs;
          lip->m_underscore_cs= cs;

          lip->body_utf8_append(lip->m_cpp_text_start,
                                lip->get_cpp_tok_start() + length);
          return(UNDERSCORE_CHARSET);
        }
      }

      lip->body_utf8_append(lip->m_cpp_text_start);

1618
      lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end);
unknown's avatar
unknown committed
1619

1620
      return(result_state);			// IDENT or IDENT_QUOTED
unknown's avatar
unknown committed
1621

1622
    case MY_LEX_IDENT_SEP:                  // Found ident and now '.'
1623 1624
      yylval->lex_str.str= (char*) lip->get_ptr();
      yylval->lex_str.length= 1;
1625 1626 1627
      c= lip->yyGet();                          // should be '.'
      lip->next_state= MY_LEX_IDENT_START;      // Next is ident (not keyword)
      if (!ident_map[(uchar) lip->yyPeek()])    // Probably ` or "
1628
	lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
1629 1630
      return((int) c);

1631
    case MY_LEX_NUMBER_IDENT:		// number or ident which num-start
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649
      if (lip->yyGetLast() == '0')
      {
        c= lip->yyGet();
        if (c == 'x')
        {
          while (my_isxdigit(cs,(c = lip->yyGet()))) ;
          if ((lip->yyLength() >= 3) && !ident_map[c])
          {
            /* skip '0x' */
            yylval->lex_str=get_token(lip, 2, lip->yyLength()-2);
            return (HEX_NUM);
          }
          lip->yyUnget();
          state= MY_LEX_IDENT_START;
          break;
        }
        else if (c == 'b')
        {
1650 1651
          while ((c= lip->yyGet()) == '0' || c == '1')
            ;
1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
          if ((lip->yyLength() >= 3) && !ident_map[c])
          {
            /* Skip '0b' */
            yylval->lex_str= get_token(lip, 2, lip->yyLength()-2);
            return (BIN_NUM);
          }
          lip->yyUnget();
          state= MY_LEX_IDENT_START;
          break;
        }
        lip->yyUnget();
      }

      while (my_isdigit(cs, (c = lip->yyGet()))) ;
unknown's avatar
unknown committed
1666
      if (!ident_map[c])
unknown's avatar
unknown committed
1667
      {					// Can't be identifier
1668
	state=MY_LEX_INT_OR_REAL;
unknown's avatar
unknown committed
1669 1670 1671 1672
	break;
      }
      if (c == 'e' || c == 'E')
      {
unknown's avatar
unknown committed
1673
	// The following test is written this way to allow numbers of type 1e1
1674 1675
        if (my_isdigit(cs,lip->yyPeek()) ||
            (c=(lip->yyGet())) == '+' || c == '-')
unknown's avatar
unknown committed
1676
	{				// Allow 1E+10
1677
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
unknown's avatar
unknown committed
1678
	  {
1679 1680 1681
            lip->yySkip();
            while (my_isdigit(cs,lip->yyGet())) ;
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1682 1683 1684
	    return(FLOAT_NUM);
	  }
	}
1685
        lip->yyUnget();
unknown's avatar
unknown committed
1686
      }
unknown's avatar
unknown committed
1687
      // fall through
1688
    case MY_LEX_IDENT_START:			// We come here after '.'
1689
      result_state= IDENT;
unknown's avatar
unknown committed
1690
#if defined(USE_MB) && defined(USE_MB_IDENT)
1691
      if (use_mb(cs))
unknown's avatar
unknown committed
1692
      {
1693
	result_state= IDENT_QUOTED;
1694
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
1695
        {
1696 1697 1698 1699 1700
          int char_length= my_charlen(cs, lip->get_ptr() - 1,
                                          lip->get_end_of_query());
          if (char_length <= 0)
            break;
          lip->skip_binary(char_length - 1);
unknown's avatar
unknown committed
1701 1702 1703 1704
        }
      }
      else
#endif
unknown's avatar
unknown committed
1705
      {
1706 1707
        for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c)
          ;
unknown's avatar
unknown committed
1708 1709 1710
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
      }
1711
      if (c == '.' && ident_map[(uchar) lip->yyPeek()])
1712
	lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
unknown's avatar
unknown committed
1713

1714
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1715 1716 1717

      lip->body_utf8_append(lip->m_cpp_text_start);

1718
      lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end);
unknown's avatar
unknown committed
1719

1720
      return(result_state);
unknown's avatar
unknown committed
1721

1722
    case MY_LEX_USER_VARIABLE_DELIMITER:	// Found quote char
1723
    {
1724 1725
      uint double_quotes= 0;
      char quote_char= c;                       // Used char
1726
      while ((c=lip->yyGet()))
unknown's avatar
unknown committed
1727
      {
1728 1729 1730
        int var_length= my_charlen(cs, lip->get_ptr() - 1,
                                       lip->get_end_of_query());
        if (var_length == 1)
1731 1732 1733
	{
	  if (c == quote_char)
	  {
1734
            if (lip->yyPeek() != quote_char)
1735
	      break;
1736
            c=lip->yyGet();
1737 1738 1739
	    double_quotes++;
	    continue;
	  }
1740 1741
	}
#ifdef USE_MB
1742
        else if (var_length > 1)
1743
        {
1744
          lip->skip_binary(var_length - 1);
1745
        }
1746
#endif
unknown's avatar
unknown committed
1747
      }
1748
      if (double_quotes)
1749
	yylval->lex_str=get_quoted_token(lip, 1,
1750
                                         lip->yyLength() - double_quotes -1,
1751 1752
					 quote_char);
      else
1753
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
1754
      if (c == quote_char)
1755
        lip->yySkip();                  // Skip end `
1756
      lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
1757 1758 1759

      lip->body_utf8_append(lip->m_cpp_text_start);

1760
      lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end);
unknown's avatar
unknown committed
1761

1762
      return(IDENT_QUOTED);
1763
    }
1764
    case MY_LEX_INT_OR_REAL:		// Complete int or incomplete real
1765 1766 1767 1768 1769 1770 1771
      if (c != '.' || lip->yyPeek() == '.')
      {
        /*
          Found a complete integer number:
          - the number is either not followed by a dot at all, or
          - the number is followed by a double dot as in: FOR i IN 1..10
        */
1772
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1773
	return int_token(yylval->lex_str.str, (uint) yylval->lex_str.length);
unknown's avatar
unknown committed
1774 1775
      }
      // fall through
1776
    case MY_LEX_REAL:			// Incomplete real number
1777
      while (my_isdigit(cs,c = lip->yyGet())) ;
unknown's avatar
unknown committed
1778 1779 1780

      if (c == 'e' || c == 'E')
      {
1781
        c = lip->yyGet();
unknown's avatar
unknown committed
1782
	if (c == '-' || c == '+')
1783
          c = lip->yyGet();                     // Skip sign
1784
	if (!my_isdigit(cs,c))
unknown's avatar
unknown committed
1785
	{				// No digit after sign
1786
	  state= MY_LEX_CHAR;
unknown's avatar
unknown committed
1787 1788
	  break;
	}
1789 1790
        while (my_isdigit(cs,lip->yyGet())) ;
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1791 1792
	return(FLOAT_NUM);
      }
1793
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1794
      return(DECIMAL_NUM);
unknown's avatar
unknown committed
1795

1796
    case MY_LEX_HEX_NUMBER:		// Found x'hexstring'
1797 1798 1799 1800 1801 1802 1803 1804
      lip->yySkip();                    // Accept opening '
      while (my_isxdigit(cs, (c= lip->yyGet()))) ;
      if (c != '\'')
        return(ABORT_SYM);              // Illegal hex constant
      lip->yySkip();                    // Accept closing '
      length= lip->yyLength();          // Length of hexnum+3
      if ((length % 2) == 0)
        return(ABORT_SYM);              // odd number of hex digits
1805 1806 1807
      yylval->lex_str=get_token(lip,
                                2,          // skip x'
                                length-3);  // don't count x' and last '
Alexander Barkov's avatar
Alexander Barkov committed
1808
      return HEX_STRING;
1809

unknown's avatar
unknown committed
1810
    case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
1811
      lip->yySkip();                  // Accept opening '
1812 1813
      while ((c= lip->yyGet()) == '0' || c == '1')
        ;
unknown's avatar
unknown committed
1814
      if (c != '\'')
1815 1816 1817
        return(ABORT_SYM);            // Illegal hex constant
      lip->yySkip();                  // Accept closing '
      length= lip->yyLength();        // Length of bin-num + 3
1818 1819 1820 1821
      yylval->lex_str= get_token(lip,
                                 2,         // skip b'
                                 length-3); // don't count b' and last '
      return (BIN_NUM);
unknown's avatar
unknown committed
1822

1823
    case MY_LEX_CMP_OP:			// Incomplete comparison operator
1824
      lip->next_state= MY_LEX_START;	// Allow signed numbers
1825 1826
      if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP ||
          state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
unknown's avatar
unknown committed
1827
      {
1828 1829 1830 1831
        lip->yySkip();
        if ((tokval= find_keyword(lip, 2, 0)))
          return(tokval);
        lip->yyUnget();
unknown's avatar
unknown committed
1832
      }
1833
      return(c);
unknown's avatar
unknown committed
1834

1835
    case MY_LEX_LONG_CMP_OP:		// Incomplete comparison operator
1836
      lip->next_state= MY_LEX_START;
1837 1838
      if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP ||
          state_map[(uchar) lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
unknown's avatar
unknown committed
1839
      {
1840
        lip->yySkip();
1841
        if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP)
1842
        {
1843
          lip->yySkip();
1844 1845 1846 1847 1848 1849 1850
          if ((tokval= find_keyword(lip, 3, 0)))
            return(tokval);
          lip->yyUnget();
        }
        if ((tokval= find_keyword(lip, 2, 0)))
          return(tokval);
        lip->yyUnget();
unknown's avatar
unknown committed
1851
      }
1852
      return(c);
unknown's avatar
unknown committed
1853

1854
    case MY_LEX_BOOL:
1855
      if (c != lip->yyPeek())
unknown's avatar
unknown committed
1856
      {
1857
	state=MY_LEX_CHAR;
unknown's avatar
unknown committed
1858 1859
	break;
      }
1860
      lip->yySkip();
1861 1862
      tokval = find_keyword(lip,2,0);	// Is a bool operator
      lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1863 1864
      return(tokval);

1865
    case MY_LEX_STRING_OR_DELIMITER:
1866
      if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
1867
      {
1868
	state= MY_LEX_USER_VARIABLE_DELIMITER;
1869 1870 1871
	break;
      }
      /* " used for strings */
1872
      /* fall through */
1873
    case MY_LEX_STRING:			// Incomplete text string
1874 1875
    {
      uint sep;
1876 1877
      if (lip->get_text(&yylval->lex_string_with_metadata,
                        (sep= lip->yyGetLast()), 1, 1))
unknown's avatar
unknown committed
1878
      {
1879
	state= MY_LEX_CHAR;		// Read char by char
unknown's avatar
unknown committed
1880 1881
	break;
      }
1882
      CHARSET_INFO *strcs= lip->m_underscore_cs ? lip->m_underscore_cs : cs;
unknown's avatar
unknown committed
1883 1884
      lip->body_utf8_append(lip->m_cpp_text_start);

1885 1886
      lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata,
                                   strcs, lip->m_cpp_text_end, sep);
unknown's avatar
unknown committed
1887
      lip->m_underscore_cs= NULL;
unknown's avatar
unknown committed
1888
      return(TEXT_STRING);
1889
    }
1890
    case MY_LEX_COMMENT:			//  Comment
unknown's avatar
unknown committed
1891
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1892 1893
      while ((c = lip->yyGet()) != '\n' && c) ;
      lip->yyUnget();                   // Safety against eof
1894
      state = MY_LEX_START;		// Try again
unknown's avatar
unknown committed
1895
      break;
1896
    case MY_LEX_LONG_COMMENT:		/* Long C comment? */
1897
      if (lip->yyPeek() != '*')
unknown's avatar
unknown committed
1898
      {
1899
	state=MY_LEX_CHAR;		// Probable division
unknown's avatar
unknown committed
1900 1901
	break;
      }
unknown's avatar
unknown committed
1902
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1903 1904 1905
      /* Reject '/' '*', since we might need to turn off the echo */
      lip->yyUnget();

1906 1907
      lip->save_in_comment_state();

1908 1909
      if (lip->yyPeekn(2) == '!' ||
          (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!'))
unknown's avatar
unknown committed
1910
      {
1911
        bool maria_comment_syntax= lip->yyPeekn(2) == 'M';
1912 1913
        lip->in_comment= DISCARD_COMMENT;
        /* Accept '/' '*' '!', but do not keep this marker. */
unknown's avatar
unknown committed
1914
        lip->set_echo(FALSE);
1915
        lip->yySkipn(maria_comment_syntax ? 4 : 3);
1916 1917 1918

        /*
          The special comment format is very strict:
1919
          '/' '*' '!', followed by an optional 'M' and exactly
Michael Widenius's avatar
Michael Widenius committed
1920 1921 1922 1923 1924
          1-2 digits (major), 2 digits (minor), then 2 digits (dot).
          32302  -> 3.23.02
          50032  -> 5.0.32
          50114  -> 5.1.14
          100000 -> 10.0.0
1925
        */
1926 1927 1928 1929 1930
        if (  my_isdigit(cs, lip->yyPeekn(0))
           && my_isdigit(cs, lip->yyPeekn(1))
           && my_isdigit(cs, lip->yyPeekn(2))
           && my_isdigit(cs, lip->yyPeekn(3))
           && my_isdigit(cs, lip->yyPeekn(4))
1931 1932 1933
           )
        {
          ulong version;
1934 1935
          uint length= 5;
          char *end_ptr= (char*) lip->get_ptr()+length;
1936
          int error;
1937 1938 1939 1940 1941 1942
          if (my_isdigit(cs, lip->yyPeekn(5)))
          {
            end_ptr++;                          // 6 digit number
            length++;
          }

1943
          version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error);
1944

1945 1946 1947
          /*
            MySQL-5.7 has new features and might have new SQL syntax that
            MariaDB-10.0 does not understand. Ignore all versioned comments
1948
            with MySQL versions in the range 50700-999999, but
1949 1950 1951
            do not ignore MariaDB specific comments for the same versions.
          */ 
          if (version <= MYSQL_VERSION_ID &&
1952
              (version < 50700 || version > 99999 || maria_comment_syntax))
1953
          {
1954
            /* Accept 'M' 'm' 'm' 'd' 'd' */
1955
            lip->yySkipn(length);
1956
            /* Expand the content of the special comment as real code */
unknown's avatar
unknown committed
1957
            lip->set_echo(TRUE);
1958
            state=MY_LEX_START;
1959 1960 1961 1962
            break;  /* Do not treat contents as a comment.  */
          }
          else
          {
1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973
#ifdef WITH_WSREP
	    if (WSREP(thd) && version == 99997 && thd->wsrep_exec_mode == LOCAL_STATE)
	    {
	      WSREP_DEBUG("consistency check: %s", thd->query());
	      thd->wsrep_consistency_check= CONSISTENCY_CHECK_DECLARED;
	      lip->yySkipn(5);
	      lip->set_echo(TRUE);
	      state=MY_LEX_START;
	      break;  /* Do not treat contents as a comment.  */
	    }
#endif /* WITH_WSREP */
1974 1975 1976 1977 1978
            /*
              Patch and skip the conditional comment to avoid it
              being propagated infinitely (eg. to a slave).
            */
            char *pcom= lip->yyUnput(' ');
1979
            comment_closed= ! consume_comment(lip, 1);
1980 1981 1982 1983
            if (! comment_closed)
            {
              *pcom= '!';
            }
1984
            /* version allowed to have one level of comment inside. */
1985 1986 1987 1988
          }
        }
        else
        {
1989
          /* Not a version comment. */
1990
          state=MY_LEX_START;
unknown's avatar
unknown committed
1991
          lip->set_echo(TRUE);
1992 1993
          break;
        }
unknown's avatar
unknown committed
1994
      }
1995
      else
unknown's avatar
unknown committed
1996
      {
1997 1998 1999
        lip->in_comment= PRESERVE_COMMENT;
        lip->yySkip();                  // Accept /
        lip->yySkip();                  // Accept *
2000 2001
        comment_closed= ! consume_comment(lip, 0);
        /* regular comments can have zero comments inside. */
unknown's avatar
unknown committed
2002
      }
2003 2004 2005 2006 2007
      /*
        Discard:
        - regular '/' '*' comments,
        - special comments '/' '*' '!' for a future version,
        by scanning until we find a closing '*' '/' marker.
2008 2009 2010 2011 2012 2013 2014 2015 2016

        Nesting regular comments isn't allowed.  The first 
        '*' '/' returns the parser to the previous state.

        /#!VERSI oned containing /# regular #/ is allowed #/

		Inside one versioned comment, another versioned comment
		is treated as a regular discardable comment.  It gets
		no special parsing.
2017
      */
2018

2019 2020 2021
      /* Unbalanced comments with a missing '*' '/' are a syntax error */
      if (! comment_closed)
        return (ABORT_SYM);
2022
      state = MY_LEX_START;             // Try again
2023
      lip->restore_in_comment_state();
unknown's avatar
unknown committed
2024
      break;
2025
    case MY_LEX_END_LONG_COMMENT:
2026
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
unknown's avatar
unknown committed
2027
      {
2028 2029 2030 2031 2032 2033
        /* Reject '*' '/' */
        lip->yyUnget();
        /* Accept '*' '/', with the proper echo */
        lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
        lip->yySkipn(2);
        /* And start recording the tokens again */
unknown's avatar
unknown committed
2034
        lip->set_echo(TRUE);
2035 2036
        lip->in_comment=NO_COMMENT;
        state=MY_LEX_START;
unknown's avatar
unknown committed
2037 2038
      }
      else
2039
	state=MY_LEX_CHAR;		// Return '*'
unknown's avatar
unknown committed
2040
      break;
2041
    case MY_LEX_SET_VAR:		// Check if ':='
2042
      if (lip->yyPeek() != '=')
unknown's avatar
unknown committed
2043
      {
2044
	state=MY_LEX_CHAR;		// Return ':'
unknown's avatar
unknown committed
2045 2046
	break;
      }
2047
      lip->yySkip();
unknown's avatar
unknown committed
2048
      return (SET_VAR);
2049
    case MY_LEX_SEMICOLON:			// optional line terminator
2050 2051
      state= MY_LEX_CHAR;               // Return ';'
      break;
2052
    case MY_LEX_EOL:
2053
      if (lip->eof())
unknown's avatar
unknown committed
2054
      {
2055
        lip->yyUnget();                 // Reject the last '\0'
unknown's avatar
unknown committed
2056
        lip->set_echo(FALSE);
2057
        lip->yySkip();
unknown's avatar
unknown committed
2058
        lip->set_echo(TRUE);
2059 2060 2061
        /* Unbalanced comments with a missing '*' '/' are a syntax error */
        if (lip->in_comment != NO_COMMENT)
          return (ABORT_SYM);
2062 2063
        lip->next_state=MY_LEX_END;     // Mark for next loop
        return(END_OF_INPUT);
unknown's avatar
unknown committed
2064 2065 2066
      }
      state=MY_LEX_CHAR;
      break;
2067
    case MY_LEX_END:
2068
      lip->next_state=MY_LEX_END;
unknown's avatar
unknown committed
2069
      return(0);			// We found end of input last time
2070

2071
      /* Actually real shouldn't start with . but allow them anyhow */
2072
    case MY_LEX_REAL_OR_POINT:
2073
      if (my_isdigit(cs,(c= lip->yyPeek())))
2074
	state = MY_LEX_REAL;		// Real
2075 2076 2077 2078 2079
      else if (c == '.')
      {
        lip->yySkip();
        return DOT_DOT_SYM;
      }
unknown's avatar
unknown committed
2080 2081
      else
      {
2082
	state= MY_LEX_IDENT_SEP;	// return '.'
2083
        lip->yyUnget();                 // Put back '.'
unknown's avatar
unknown committed
2084 2085
      }
      break;
2086
    case MY_LEX_USER_END:		// end '@' of user@hostname
2087
      switch (state_map[(uchar) lip->yyPeek()]) {
2088 2089 2090
      case MY_LEX_STRING:
      case MY_LEX_USER_VARIABLE_DELIMITER:
      case MY_LEX_STRING_OR_DELIMITER:
unknown's avatar
unknown committed
2091
	break;
2092
      case MY_LEX_USER_END:
2093
	lip->next_state=MY_LEX_SYSTEM_VAR;
unknown's avatar
unknown committed
2094 2095
	break;
      default:
2096
	lip->next_state=MY_LEX_HOSTNAME;
unknown's avatar
unknown committed
2097 2098
	break;
      }
2099
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
2100 2101
      yylval->lex_str.length=1;
      return((int) '@');
2102
    case MY_LEX_HOSTNAME:		// end '@' of user@hostname
2103
      for (c=lip->yyGet() ;
2104
	   my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
2105 2106
           c= lip->yyGet()) ;
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
2107
      return(LEX_HOSTNAME);
2108
    case MY_LEX_SYSTEM_VAR:
2109
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
2110
      yylval->lex_str.length=1;
2111
      lip->yySkip();                                    // Skip '@'
2112
      lip->next_state= (state_map[(uchar) lip->yyPeek()] ==
2113 2114 2115
			MY_LEX_USER_VARIABLE_DELIMITER ?
			MY_LEX_OPERATOR_OR_IDENT :
			MY_LEX_IDENT_OR_KEYWORD);
unknown's avatar
unknown committed
2116
      return((int) '@');
2117
    case MY_LEX_IDENT_OR_KEYWORD:
unknown's avatar
unknown committed
2118 2119 2120 2121 2122
      /*
	We come here when we have found two '@' in a row.
	We should now be able to handle:
	[(global | local | session) .]variable_name
      */
2123

2124 2125
      for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c)
        ;
unknown's avatar
unknown committed
2126 2127
      /* If there were non-ASCII characters, mark that we must convert */
      result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
2128

unknown's avatar
unknown committed
2129
      if (c == '.')
2130
	lip->next_state=MY_LEX_IDENT_SEP;
2131 2132
      length= lip->yyLength();
      if (length == 0)
unknown's avatar
unknown committed
2133
        return(ABORT_SYM);              // Names must be nonempty.
2134
      if ((tokval= find_keyword(lip, length,0)))
unknown's avatar
unknown committed
2135
      {
2136
        lip->yyUnget();                         // Put back 'c'
unknown's avatar
unknown committed
2137 2138
	return(tokval);				// Was keyword
      }
2139
      yylval->lex_str=get_token(lip, 0, length);
unknown's avatar
unknown committed
2140 2141 2142

      lip->body_utf8_append(lip->m_cpp_text_start);

2143
      lip->body_utf8_append_ident(thd, &yylval->lex_str, lip->m_cpp_text_end);
unknown's avatar
unknown committed
2144

2145
      return(result_state);
unknown's avatar
unknown committed
2146 2147 2148
    }
  }
}
unknown's avatar
unknown committed
2149

2150

2151
void trim_whitespace(CHARSET_INFO *cs, LEX_CSTRING *str, size_t * prefix_length)
2152 2153 2154 2155 2156 2157
{
  /*
    TODO:
    This code assumes that there are no multi-bytes characters
    that can be considered white-space.
  */
2158

2159
  size_t plen= 0;
2160 2161
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
  {
2162
    plen++;
2163 2164 2165
    str->length --;
    str->str ++;
  }
2166 2167
  if (prefix_length)
    *prefix_length= plen;
2168 2169 2170 2171 2172 2173 2174 2175
  /*
    FIXME:
    Also, parsing backward is not safe with multi bytes characters
  */
  while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
  {
    str->length --;
  }
2176 2177
}

2178

unknown's avatar
unknown committed
2179 2180 2181 2182
/*
  st_select_lex structures initialisations
*/

Eugene Kosov's avatar
Eugene Kosov committed
2183
void st_select_lex_node::init_query_common()
unknown's avatar
unknown committed
2184
{
2185
  options= 0;
2186
  sql_cache= SQL_CACHE_UNSPECIFIED;
2187
  linkage= UNSPECIFIED_TYPE;
Michael Widenius's avatar
Michael Widenius committed
2188
  no_table_names_allowed= 0;
2189
  uncacheable= 0;
unknown's avatar
unknown committed
2190 2191 2192 2193
}

void st_select_lex_unit::init_query()
{
Eugene Kosov's avatar
Eugene Kosov committed
2194
  init_query_common();
2195
  linkage= GLOBAL_OPTIONS_TYPE;
2196 2197
  select_limit_cnt= HA_POS_ERROR;
  offset_limit_cnt= 0;
2198
  union_distinct= 0;
2199
  prepared= optimized= optimized_2= executed= 0;
Igor Babaev's avatar
Igor Babaev committed
2200
  optimize_started= 0;
unknown's avatar
unknown committed
2201
  item= 0;
2202 2203
  union_result= 0;
  table= 0;
unknown's avatar
unknown committed
2204
  fake_select_lex= 0;
2205
  saved_fake_select_lex= 0;
2206
  cleaned= 0;
2207
  item_list.empty();
2208
  describe= 0;
2209
  found_rows_for_union= 0;
2210
  derived= 0;
2211
  is_view= false;
2212 2213
  with_clause= 0;
  with_element= 0;
2214
  columns_are_renamed= false;
2215
  intersect_mark= NULL;
unknown's avatar
unknown committed
2216 2217 2218 2219
}

void st_select_lex::init_query()
{
Eugene Kosov's avatar
Eugene Kosov committed
2220
  init_query_common();
2221
  table_list.empty();
2222 2223
  top_join_list.empty();
  join_list= &top_join_list;
2224
  embedding= 0;
Igor Babaev's avatar
Igor Babaev committed
2225
  leaf_tables_prep.empty();
2226
  leaf_tables.empty();
unknown's avatar
unknown committed
2227
  item_list.empty();
Igor Babaev's avatar
Igor Babaev committed
2228
  min_max_opt_list.empty();
unknown's avatar
unknown committed
2229
  join= 0;
2230
  having= prep_having= where= prep_where= 0;
Igor Babaev's avatar
Igor Babaev committed
2231
  cond_pushed_into_where= cond_pushed_into_having= 0;
2232
  olap= UNSPECIFIED_OLAP_TYPE;
2233
  having_fix_field= 0;
2234 2235
  context.select_lex= this;
  context.init();
unknown's avatar
unknown committed
2236 2237 2238
  /*
    Add the name resolution context of the current (sub)query to the
    stack of contexts for the whole query.
2239 2240 2241 2242 2243
    TODO:
    push_context may return an error if there is no memory for a new
    element in the stack, however this method has no return value,
    thus push_context should be moved to a place where query
    initialization is checked for failure.
unknown's avatar
unknown committed
2244
  */
2245
  parent_lex->push_context(&context, parent_lex->thd->mem_root);
2246
  cond_count= between_count= with_wild= 0;
unknown's avatar
unknown committed
2247
  max_equal_elems= 0;
2248
  ref_pointer_array.reset();
unknown's avatar
unknown committed
2249
  select_n_where_fields= 0;
unknown's avatar
unknown committed
2250
  select_n_reserved= 0;
unknown's avatar
unknown committed
2251
  select_n_having_items= 0;
2252
  n_sum_items= 0;
2253
  n_child_sum_items= 0;
2254
  subquery_in_having= explicit_limit= 0;
2255
  is_item_list_lookup= 0;
2256
  first_execution= 1;
2257
  first_natural_join_processing= 1;
unknown's avatar
unknown committed
2258
  first_cond_optimization= 1;
2259
  parsing_place= NO_MATTER;
2260
  exclude_from_table_unique_test= no_wrap_view_item= FALSE;
unknown's avatar
unknown committed
2261
  nest_level= 0;
2262
  link_next= 0;
2263
  prep_leaf_list_state= UNINIT;
2264
  have_merged_subqueries= FALSE;
unknown's avatar
unknown committed
2265
  bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
2266
  select_list_tables= 0;
2267 2268
  m_non_agg_field_used= false;
  m_agg_func_used= false;
2269
  m_custom_agg_func_used= false;
2270 2271
  window_specs.empty();
  window_funcs.empty();
2272
  tvc= 0;
Galina Shalygina's avatar
Galina Shalygina committed
2273
  in_tvc= false;
2274
  versioned_tables= 0;
unknown's avatar
unknown committed
2275 2276 2277 2278
}

void st_select_lex::init_select()
{
2279
  sj_nests.empty();
Igor Babaev's avatar
Igor Babaev committed
2280
  sj_subselects.empty();
2281
  group_list.empty();
2282 2283
  if (group_list_ptrs)
    group_list_ptrs->clear();
2284 2285
  type= 0;
  db= null_clex_str;
2286 2287 2288
  having= 0;
  table_join_options= 0;
  in_sum_expr= with_wild= 0;
unknown's avatar
unknown committed
2289
  options= 0;
2290
  sql_cache= SQL_CACHE_UNSPECIFIED;
unknown's avatar
unknown committed
2291
  ftfunc_list_alloc.empty();
unknown's avatar
unknown committed
2292
  inner_sum_func_list= 0;
unknown's avatar
unknown committed
2293
  ftfunc_list= &ftfunc_list_alloc;
unknown's avatar
unknown committed
2294 2295
  order_list.elements= 0;
  order_list.first= 0;
2296
  order_list.next= &order_list.first;
2297 2298 2299
  /* Set limit and offset to default values */
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
  offset_limit= 0;      /* denotes the default offset = 0 */
unknown's avatar
unknown committed
2300
  with_sum_func= 0;
2301
  is_correlated= 0;
2302
  cur_pos_in_select_list= UNDEF_POS;
2303
  cond_value= having_value= Item::COND_UNDEF;
2304
  inner_refs_list.empty();
2305
  insert_tables= 0;
Igor Babaev's avatar
Igor Babaev committed
2306
  merged_into= 0;
2307 2308
  m_non_agg_field_used= false;
  m_agg_func_used= false;
2309
  m_custom_agg_func_used= false;
unknown's avatar
unknown committed
2310
  name_visibility_map= 0;
2311
  with_dep= 0;
2312
  join= 0;
2313
  lock_type= TL_READ_DEFAULT;
2314
  tvc= 0;
2315
  in_funcs.empty();
2316
  curr_tvc_name= 0;
Galina Shalygina's avatar
Galina Shalygina committed
2317
  in_tvc= false;
2318
  versioned_tables= 0;
unknown's avatar
unknown committed
2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332
}

/*
  st_select_lex structures linking
*/

/* include on level down */
void st_select_lex_node::include_down(st_select_lex_node *upper)
{
  if ((next= upper->slave))
    next->prev= &next;
  prev= &upper->slave;
  upper->slave= this;
  master= upper;
unknown's avatar
unknown committed
2333
  slave= 0;
unknown's avatar
unknown committed
2334 2335
}

unknown's avatar
unknown committed
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360

void st_select_lex_node::add_slave(st_select_lex_node *slave_arg)
{
  for (; slave; slave= slave->next)
    if (slave == slave_arg)
      return;

  if (slave)
  {
    st_select_lex_node *slave_arg_slave= slave_arg->slave;
    /* Insert in the front of list of slaves if any. */
    slave_arg->include_neighbour(slave);
    /* include_neighbour() sets slave_arg->slave=0, restore it. */
    slave_arg->slave= slave_arg_slave;
    /* Count on include_neighbour() setting the master. */
    DBUG_ASSERT(slave_arg->master == this);
  }
  else
  {
    slave= slave_arg;
    slave_arg->master= this;
  }
}


unknown's avatar
unknown committed
2361 2362
/*
  include on level down (but do not link)
unknown's avatar
unknown committed
2363

unknown's avatar
unknown committed
2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377
  SYNOPSYS
    st_select_lex_node::include_standalone()
    upper - reference on node underr which this node should be included
    ref - references on reference on this node
*/
void st_select_lex_node::include_standalone(st_select_lex_node *upper,
					    st_select_lex_node **ref)
{
  next= 0;
  prev= ref;
  master= upper;
  slave= 0;
}

unknown's avatar
unknown committed
2378 2379 2380 2381 2382 2383 2384 2385
/* include neighbour (on same level) */
void st_select_lex_node::include_neighbour(st_select_lex_node *before)
{
  if ((next= before->next))
    next->prev= &next;
  prev= &before->next;
  before->next= this;
  master= before->master;
unknown's avatar
unknown committed
2386
  slave= 0;
unknown's avatar
unknown committed
2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400
}

/* including in global SELECT_LEX list */
void st_select_lex_node::include_global(st_select_lex_node **plink)
{
  if ((link_next= *plink))
    link_next->link_prev= &link_next;
  link_prev= plink;
  *plink= this;
}

//excluding from global list (internal function)
void st_select_lex_node::fast_exclude()
{
unknown's avatar
unknown committed
2401
  if (link_prev)
unknown's avatar
unknown committed
2402 2403 2404 2405
  {
    if ((*link_prev= link_next))
      link_next->link_prev= link_prev;
  }
2406 2407 2408 2409
  // Remove slave structure
  for (; slave; slave= slave->next)
    slave->fast_exclude();
  
unknown's avatar
unknown committed
2410 2411
}

2412

2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443
/**
  @brief
    Insert a new chain of nodes into another chain before a particular link

  @param in/out
    ptr_pos_to_insert  the address of the chain pointer pointing to the link
                       before which the subchain has to be inserted
  @param   
    end_chain_node     the last link of the subchain to be inserted

  @details
    The method inserts the chain of nodes starting from this node and ending
    with the node nd_chain_node into another chain of nodes before the node
    pointed to by *ptr_pos_to_insert.
    It is assumed that ptr_pos_to_insert belongs to the chain where we insert.
    So it must be updated.

  @retval
    The method returns the pointer to the first link of the inserted chain
*/

st_select_lex_node *st_select_lex_node:: insert_chain_before(
				         st_select_lex_node **ptr_pos_to_insert,
                                         st_select_lex_node *end_chain_node)
{
  end_chain_node->link_next= *ptr_pos_to_insert;
  (*ptr_pos_to_insert)->link_prev= &end_chain_node->link_next;
  this->link_prev= ptr_pos_to_insert;
  return this;
}

Igor Babaev's avatar
Igor Babaev committed
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459

/*
  Detach the node from its master and attach it to a new master
*/

void st_select_lex_node::move_as_slave(st_select_lex_node *new_master)
{
  exclude_from_tree();
  if (new_master->slave)
  {
    st_select_lex_node *curr= new_master->slave;
    for ( ; curr->next ; curr= curr->next) ;
    prev= &curr->next;
  }
  else
    prev= &new_master->slave;
2460
  *prev= this;
Igor Babaev's avatar
Igor Babaev committed
2461 2462 2463 2464 2465
  next= 0;
  master= new_master;
}


2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477
/*
  Exclude a node from the tree lex structure, but leave it in the global
  list of nodes.
*/

void st_select_lex_node::exclude_from_tree()
{
  if ((*prev= next))
    next->prev= prev;
}


unknown's avatar
unknown committed
2478
/*
2479
  Exclude select_lex structure (except first (first select can't be
unknown's avatar
unknown committed
2480 2481 2482 2483
  deleted, because it is most upper select))
*/
void st_select_lex_node::exclude()
{
2484
  /* exclude from global list */
unknown's avatar
unknown committed
2485
  fast_exclude();
2486 2487
  /* exclude from other structures */
  exclude_from_tree();
unknown's avatar
unknown committed
2488 2489 2490 2491 2492 2493 2494
  /* 
     We do not need following statements, because prev pointer of first 
     list element point to master->slave
     if (master->slave == this)
       master->slave= next;
  */
}
2495

2496 2497 2498 2499 2500 2501 2502 2503 2504 2505

/*
  Exclude level of current unit from tree of SELECTs

  SYNOPSYS
    st_select_lex_unit::exclude_level()

  NOTE: units which belong to current will be brought up on level of
  currernt unit 
*/
unknown's avatar
unknown committed
2506 2507 2508
void st_select_lex_unit::exclude_level()
{
  SELECT_LEX_UNIT *units= 0, **units_last= &units;
unknown's avatar
unknown committed
2509
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
unknown's avatar
unknown committed
2510
  {
unknown's avatar
unknown committed
2511
    // unlink current level from global SELECTs list
unknown's avatar
unknown committed
2512 2513
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;
unknown's avatar
unknown committed
2514 2515

    // bring up underlay levels
unknown's avatar
unknown committed
2516 2517
    SELECT_LEX_UNIT **last= 0;
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
unknown's avatar
unknown committed
2518 2519
    {
      u->master= master;
unknown's avatar
unknown committed
2520
      last= (SELECT_LEX_UNIT**)&(u->next);
unknown's avatar
unknown committed
2521
    }
unknown's avatar
unknown committed
2522 2523 2524 2525 2526 2527 2528 2529
    if (last)
    {
      (*units_last)= sl->first_inner_unit();
      units_last= last;
    }
  }
  if (units)
  {
unknown's avatar
unknown committed
2530
    // include brought up levels in place of current
unknown's avatar
unknown committed
2531 2532
    (*prev)= units;
    (*units_last)= (SELECT_LEX_UNIT*)next;
unknown's avatar
unknown committed
2533 2534 2535
    if (next)
      next->prev= (SELECT_LEX_NODE**)units_last;
    units->prev= prev;
unknown's avatar
unknown committed
2536 2537
  }
  else
unknown's avatar
unknown committed
2538 2539
  {
    // exclude currect unit from list of nodes
unknown's avatar
unknown committed
2540
    (*prev)= next;
unknown's avatar
unknown committed
2541 2542 2543
    if (next)
      next->prev= prev;
  }
2544 2545
  // Mark it excluded
  prev= NULL;
unknown's avatar
unknown committed
2546 2547
}

2548

Oleksandr Byelkin's avatar
Oleksandr Byelkin committed
2549
#if 0
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559
/*
  Exclude subtree of current unit from tree of SELECTs

  SYNOPSYS
    st_select_lex_unit::exclude_tree()
*/
void st_select_lex_unit::exclude_tree()
{
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
  {
unknown's avatar
unknown committed
2560
    // unlink current level from global SELECTs list
2561 2562 2563
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;

unknown's avatar
unknown committed
2564
    // unlink underlay levels
2565 2566 2567 2568 2569
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
    {
      u->exclude_level();
    }
  }
unknown's avatar
unknown committed
2570
  // exclude currect unit from list of nodes
2571
  (*prev)= next;
unknown's avatar
unknown committed
2572 2573
  if (next)
    next->prev= prev;
2574
}
Oleksandr Byelkin's avatar
Oleksandr Byelkin committed
2575
#endif
2576 2577


unknown's avatar
unknown committed
2578 2579 2580 2581 2582
/*
  st_select_lex_node::mark_as_dependent mark all st_select_lex struct from 
  this to 'last' as dependent

  SYNOPSIS
2583
    last - pointer to last st_select_lex struct, before which all 
unknown's avatar
unknown committed
2584 2585 2586 2587 2588 2589
           st_select_lex have to be marked as dependent

  NOTE
    'last' should be reachable from this st_select_lex_node
*/

2590 2591
bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last,
                                      Item *dependency)
unknown's avatar
unknown committed
2592
{
2593 2594 2595

  DBUG_ASSERT(this != last);

unknown's avatar
unknown committed
2596 2597 2598 2599
  /*
    Mark all selects from resolved to 1 before select where was
    found table as depended (of select where was found table)
  */
2600 2601
  SELECT_LEX *s= this;
  do
Sergey Petrunya's avatar
Sergey Petrunya committed
2602
  {
2603
    if (!(s->uncacheable & UNCACHEABLE_DEPENDENT_GENERATED))
unknown's avatar
unknown committed
2604 2605
    {
      // Select is dependent of outer select
2606
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
2607
                       UNCACHEABLE_DEPENDENT_GENERATED;
2608
      SELECT_LEX_UNIT *munit= s->master_unit();
2609
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
2610
                       UNCACHEABLE_DEPENDENT_GENERATED;
2611 2612 2613
      for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
      {
        if (sl != s &&
2614 2615
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT_GENERATED |
                                 UNCACHEABLE_UNITED)))
2616 2617
          sl->uncacheable|= UNCACHEABLE_UNITED;
      }
unknown's avatar
unknown committed
2618
    }
2619 2620 2621 2622 2623

    Item_subselect *subquery_expr= s->master_unit()->item;
    if (subquery_expr && subquery_expr->mark_as_dependent(thd, last, 
                                                          dependency))
      return TRUE;
2624
  } while ((s= s->outer_select()) != last && s != 0);
2625 2626
  is_correlated= TRUE;
  this->master_unit()->item->is_correlated= TRUE;
2627
  return FALSE;
unknown's avatar
unknown committed
2628 2629
}

unknown's avatar
unknown committed
2630 2631 2632
/*
  prohibit using LIMIT clause
*/
unknown's avatar
unknown committed
2633
bool st_select_lex::test_limit()
unknown's avatar
unknown committed
2634
{
2635
  if (select_limit != 0)
unknown's avatar
unknown committed
2636 2637
  {
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
unknown's avatar
unknown committed
2638
             "LIMIT & IN/ALL/ANY/SOME subquery");
unknown's avatar
unknown committed
2639 2640 2641 2642
    return(1);
  }
  return(0);
}
2643

2644

2645

2646 2647 2648 2649 2650
st_select_lex* st_select_lex_unit::outer_select()
{
  return (st_select_lex*) master;
}

2651

2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720
ha_rows st_select_lex::get_offset()
{
  ulonglong val= 0;

  if (offset_limit)
  {
    // see comment for st_select_lex::get_limit()
    bool fix_fields_successful= true;
    if (!offset_limit->fixed)
    {
      fix_fields_successful= !offset_limit->fix_fields(master_unit()->thd,
                                                       NULL);

      DBUG_ASSERT(fix_fields_successful);
    }
    val= fix_fields_successful ? offset_limit->val_uint() : HA_POS_ERROR;
  }

  return (ha_rows)val;
}


ha_rows st_select_lex::get_limit()
{
  ulonglong val= HA_POS_ERROR;

  if (select_limit)
  {
    /*
      fix_fields() has not been called for select_limit. That's due to the
      historical reasons -- this item could be only of type Item_int, and
      Item_int does not require fix_fields(). Thus, fix_fields() was never
      called for select_limit.

      Some time ago, Item_splocal was also allowed for LIMIT / OFFSET clauses.
      However, the fix_fields() behavior was not updated, which led to a crash
      in some cases.

      There is no single place where to call fix_fields() for LIMIT / OFFSET
      items during the fix-fields-phase. Thus, for the sake of readability,
      it was decided to do it here, on the evaluation phase (which is a
      violation of design, but we chose the lesser of two evils).

      We can call fix_fields() here, because select_limit can be of two
      types only: Item_int and Item_splocal. Item_int::fix_fields() is trivial,
      and Item_splocal::fix_fields() (or rather Item_sp_variable::fix_fields())
      has the following properties:
        1) it does not affect other items;
        2) it does not fail.

      Nevertheless DBUG_ASSERT was added to catch future changes in
      fix_fields() implementation. Also added runtime check against a result
      of fix_fields() in order to handle error condition in non-debug build.
    */
    bool fix_fields_successful= true;
    if (!select_limit->fixed)
    {
      fix_fields_successful= !select_limit->fix_fields(master_unit()->thd,
                                                       NULL);

      DBUG_ASSERT(fix_fields_successful);
    }
    val= fix_fields_successful ? select_limit->val_uint() : HA_POS_ERROR;
  }

  return (ha_rows)val;
}


unknown's avatar
unknown committed
2721
bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
unknown's avatar
unknown committed
2722
{
unknown's avatar
unknown committed
2723
  return add_to_list(thd, order_list, item, asc);
unknown's avatar
unknown committed
2724
}
2725

2726

2727 2728 2729 2730 2731
bool st_select_lex::add_gorder_to_list(THD *thd, Item *item, bool asc)
{
  return add_to_list(thd, gorder_list, item, asc);
}

2732

unknown's avatar
unknown committed
2733
bool st_select_lex::add_item_to_list(THD *thd, Item *item)
2734
{
2735
  DBUG_ENTER("st_select_lex::add_item_to_list");
2736
  DBUG_PRINT("info", ("Item: %p", item));
2737
  DBUG_RETURN(item_list.push_back(item, thd->mem_root));
2738 2739
}

2740

unknown's avatar
unknown committed
2741
bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc)
2742
{
unknown's avatar
unknown committed
2743
  return add_to_list(thd, group_list, item, asc);
2744 2745
}

2746

2747
bool st_select_lex::add_ftfunc_to_list(THD *thd, Item_func_match *func)
2748
{
2749
  return !func || ftfunc_list->push_back(func, thd->mem_root); // end of memory?
2750 2751
}

2752

2753 2754 2755 2756 2757
st_select_lex* st_select_lex::outer_select()
{
  return (st_select_lex*) master->get_master();
}

2758

2759 2760 2761 2762 2763 2764
bool st_select_lex::inc_in_sum_expr()
{
  in_sum_expr++;
  return 0;
}

2765

2766 2767 2768 2769 2770
uint st_select_lex::get_in_sum_expr()
{
  return in_sum_expr;
}

2771

2772 2773
TABLE_LIST* st_select_lex::get_table_list()
{
2774
  return table_list.first;
2775 2776 2777 2778 2779 2780 2781
}

List<Item>* st_select_lex::get_item_list()
{
  return &item_list;
}

unknown's avatar
unknown committed
2782 2783 2784 2785 2786
ulong st_select_lex::get_table_join_options()
{
  return table_join_options;
}

2787

unknown's avatar
unknown committed
2788 2789
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{
2790 2791 2792
  // find_order_in_list() may need some extra space, so multiply by two.
  order_group_num*= 2;

2793
  /*
2794
    We have to create array in prepared statement memory if it is a
2795 2796
    prepared statement
  */
unknown's avatar
unknown committed
2797
  Query_arena *arena= thd->stmt_arena;
2798 2799 2800
  const uint n_elems= (n_sum_items +
                       n_child_sum_items +
                       item_list.elements +
Sergei Golubchik's avatar
Sergei Golubchik committed
2801
                       select_n_reserved +
2802 2803 2804
                       select_n_having_items +
                       select_n_where_fields +
                       order_group_num) * 5;
2805
  if (!ref_pointer_array.is_null())
2806
  {
2807 2808 2809 2810 2811 2812 2813
    /*
      We need to take 'n_sum_items' into account when allocating the array,
      and this may actually increase during the optimization phase due to
      MIN/MAX rewrite in Item_in_subselect::single_value_transformer.
      In the usual case we can reuse the array from the prepare phase.
      If we need a bigger array, we must allocate a new one.
     */
2814
    if (ref_pointer_array.size() >= n_elems)
2815 2816 2817 2818 2819 2820 2821
      return false;
   }
  Item **array= static_cast<Item**>(arena->alloc(sizeof(Item*) * n_elems));
  if (array != NULL)
    ref_pointer_array= Ref_ptr_array(array, n_elems);

  return array == NULL;
unknown's avatar
unknown committed
2822 2823
}

2824

2825
void st_select_lex_unit::print(String *str, enum_query_type query_type)
unknown's avatar
unknown committed
2826
{
2827
  bool union_all= !union_distinct;
2828 2829
  if (with_clause)
    with_clause->print(str, query_type);
unknown's avatar
unknown committed
2830 2831 2832 2833
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
  {
    if (sl != first_select())
    {
2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851
      switch (sl->linkage)
      {
      default:
        DBUG_ASSERT(0);
      case UNION_TYPE:
        str->append(STRING_WITH_LEN(" union "));
        if (union_all)
          str->append(STRING_WITH_LEN("all "));
        else if (union_distinct == sl)
          union_all= TRUE;
        break;
      case INTERSECT_TYPE:
        str->append(STRING_WITH_LEN(" intersect "));
        break;
      case EXCEPT_TYPE:
        str->append(STRING_WITH_LEN(" except "));
        break;
      }
unknown's avatar
unknown committed
2852 2853 2854
    }
    if (sl->braces)
      str->append('(');
2855
    sl->print(thd, str, query_type);
unknown's avatar
unknown committed
2856 2857 2858
    if (sl->braces)
      str->append(')');
  }
2859
  if (fake_select_lex)
unknown's avatar
unknown committed
2860 2861 2862
  {
    if (fake_select_lex->order_list.elements)
    {
2863
      str->append(STRING_WITH_LEN(" order by "));
2864 2865
      fake_select_lex->print_order(str,
        fake_select_lex->order_list.first,
2866
        query_type);
unknown's avatar
unknown committed
2867
    }
2868
    fake_select_lex->print_limit(thd, str, query_type);
unknown's avatar
unknown committed
2869
  }
2870 2871
  else if (saved_fake_select_lex)
    saved_fake_select_lex->print_limit(thd, str, query_type);
unknown's avatar
unknown committed
2872 2873 2874
}


2875 2876 2877
void st_select_lex::print_order(String *str,
                                ORDER *order,
                                enum_query_type query_type)
unknown's avatar
unknown committed
2878 2879 2880
{
  for (; order; order= order->next)
  {
2881 2882
    if (order->counter_used)
    {
2883 2884 2885 2886 2887 2888 2889
      char buffer[20];
      size_t length= my_snprintf(buffer, 20, "%d", order->counter);
      str->append(buffer, (uint) length);
    }
    else
    {
      /* replace numeric reference with equivalent for ORDER constant */
2890
      if (order->item[0]->is_order_clause_position())
2891
      {
2892 2893
        /* make it expression instead of integer constant */
        str->append(STRING_WITH_LEN("''"));
2894 2895
      }
      else
2896
        (*order->item)->print(str, query_type);
2897
    }
2898 2899
    if (order->direction == ORDER::ORDER_DESC)
       str->append(STRING_WITH_LEN(" desc"));
unknown's avatar
unknown committed
2900 2901 2902 2903 2904
    if (order->next)
      str->append(',');
  }
}
 
2905

2906 2907 2908
void st_select_lex::print_limit(THD *thd,
                                String *str,
                                enum_query_type query_type)
unknown's avatar
unknown committed
2909
{
2910 2911
  SELECT_LEX_UNIT *unit= master_unit();
  Item_subselect *item= unit->item;
2912

2913
  if (item && unit->global_parameters() == this)
unknown's avatar
VIEW  
unknown committed
2914
  {
2915 2916 2917 2918 2919 2920 2921
    Item_subselect::subs_type subs_type= item->substype();
    if (subs_type == Item_subselect::EXISTS_SUBS ||
        subs_type == Item_subselect::IN_SUBS ||
        subs_type == Item_subselect::ALL_SUBS)
    {
      return;
    }
unknown's avatar
VIEW  
unknown committed
2922
  }
2923
  if (explicit_limit)
unknown's avatar
unknown committed
2924
  {
2925
    str->append(STRING_WITH_LEN(" limit "));
unknown's avatar
unknown committed
2926 2927
    if (offset_limit)
    {
2928
      offset_limit->print(str, query_type);
unknown's avatar
unknown committed
2929 2930
      str->append(',');
    }
2931
    select_limit->print(str, query_type);
unknown's avatar
unknown committed
2932 2933 2934
  }
}

2935

2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947
/**
  @brief Restore the LEX and THD in case of a parse error.

  This is a clean up call that is invoked by the Bison generated
  parser before returning an error from MYSQLparse. If your
  semantic actions manipulate with the global thread state (which
  is a very bad practice and should not normally be employed) and
  need a clean-up in case of error, and you can not use %destructor
  rule in the grammar file itself, this function should be used
  to implement the clean up.
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
2948
void LEX::cleanup_lex_after_parse_error(THD *thd)
2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
{
  /*
    Delete sphead for the side effect of restoring of the original
    LEX state, thd->lex, thd->mem_root and thd->free_list if they
    were replaced when parsing stored procedure statements.  We
    will never use sphead object after a parse error, so it's okay
    to delete it only for the sake of the side effect.
    TODO: make this functionality explicit in sp_head class.
    Sic: we must nullify the member of the main lex, not the
    current one that will be thrown away
  */
2960
  if (thd->lex->sphead)
2961
  {
2962
    sp_package *pkg;
2963
    thd->lex->sphead->restore_thd_mem_root(thd);
2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983
    if ((pkg= thd->lex->sphead->m_parent))
    {
      /*
        If a syntax error happened inside a package routine definition,
        then thd->lex points to the routine sublex. We need to restore to
        the top level LEX.
      */
      DBUG_ASSERT(pkg->m_top_level_lex);
      DBUG_ASSERT(pkg == pkg->m_top_level_lex->sphead);
      pkg->restore_thd_mem_root(thd);
      LEX *top= pkg->m_top_level_lex;
      delete pkg;
      thd->lex= top;
      thd->lex->sphead= NULL;
    }
    else
    {
      delete thd->lex->sphead;
      thd->lex->sphead= NULL;
    }
2984 2985
  }
}
unknown's avatar
VIEW  
unknown committed
2986

2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006
/*
  Initialize (or reset) Query_tables_list object.

  SYNOPSIS
    reset_query_tables_list()
      init  TRUE  - we should perform full initialization of object with
                    allocating needed memory
            FALSE - object is already initialized so we should only reset
                    its state so it can be used for parsing/processing
                    of new statement

  DESCRIPTION
    This method initializes Query_tables_list so it can be used as part
    of LEX object for parsing/processing of statement. One can also use
    this method to reset state of already initialized Query_tables_list
    so it can be used for processing of new statement.
*/

void Query_tables_list::reset_query_tables_list(bool init)
{
3007
  sql_command= SQLCOM_END;
unknown's avatar
unknown committed
3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018
  if (!init && query_tables)
  {
    TABLE_LIST *table= query_tables;
    for (;;)
    {
      delete table->view;
      if (query_tables_last == &table->next_global ||
          !(table= table->next_global))
        break;
    }
  }
3019 3020 3021 3022
  query_tables= 0;
  query_tables_last= &query_tables;
  query_tables_own_last= 0;
  if (init)
3023 3024 3025 3026 3027
  {
    /*
      We delay real initialization of hash (and therefore related
      memory allocation) until first insertion into this hash.
    */
Konstantin Osipov's avatar
Konstantin Osipov committed
3028
    my_hash_clear(&sroutines);
3029
  }
3030
  else if (sroutines.records)
3031 3032
  {
    /* Non-zero sroutines.records means that hash was initialized. */
3033
    my_hash_reset(&sroutines);
3034
  }
3035 3036 3037
  sroutines_list.empty();
  sroutines_list_own_last= sroutines_list.next;
  sroutines_list_own_elements= 0;
3038
  binlog_stmt_flags= 0;
3039
  stmt_accessed_table_flag= 0;
3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051
}


/*
  Destroy Query_tables_list object with freeing all resources used by it.

  SYNOPSIS
    destroy_query_tables_list()
*/

void Query_tables_list::destroy_query_tables_list()
{
Konstantin Osipov's avatar
Konstantin Osipov committed
3052
  my_hash_free(&sroutines);
3053 3054 3055
}


3056 3057 3058 3059
/*
  Initialize LEX object.

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3060
    LEX::LEX()
3061 3062 3063 3064 3065 3066 3067 3068 3069

  NOTE
    LEX object initialized with this constructor can be used as part of
    THD object for which one can safely call open_tables(), lock_tables()
    and close_thread_tables() functions. But it is not yet ready for
    statement parsing. On should use lex_start() function to prepare LEX
    for this.
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3070
LEX::LEX()
3071
  : explain(NULL), result(0), arena_for_set_stmt(0), mem_root_for_set_stmt(0),
3072
    option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0),
3073
    default_used(0), is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX)
3074
{
unknown's avatar
unknown committed
3075

3076 3077 3078
  init_dynamic_array2(&plugins, sizeof(plugin_ref), plugins_static_buffer,
                      INITIAL_LEX_PLUGIN_LIST_SIZE,
                      INITIAL_LEX_PLUGIN_LIST_SIZE, 0);
3079
  reset_query_tables_list(TRUE);
3080
  mi.init();
3081 3082 3083 3084
  init_dynamic_array2(&delete_gtid_domain, sizeof(ulong*),
                      gtid_domain_static_buffer,
                      initial_gtid_domain_buffer_size,
                      initial_gtid_domain_buffer_size, 0);
3085 3086 3087
}


unknown's avatar
VIEW  
unknown committed
3088
/*
3089
  Check whether the merging algorithm can be used on this VIEW
unknown's avatar
VIEW  
unknown committed
3090 3091

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3092
    LEX::can_be_merged()
unknown's avatar
VIEW  
unknown committed
3093

3094
  DESCRIPTION
3095 3096 3097
    We can apply merge algorithm if it is single SELECT view  with
    subqueries only in WHERE clause (we do not count SELECTs of underlying
    views, and second level subqueries) and we have not grpouping, ordering,
3098 3099 3100
    HAVING clause, aggregate functions, DISTINCT clause, LIMIT clause and
    several underlying tables.

unknown's avatar
VIEW  
unknown committed
3101 3102 3103 3104 3105
  RETURN
    FALSE - only temporary table algorithm can be used
    TRUE  - merge algorithm can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3106
bool LEX::can_be_merged()
unknown's avatar
VIEW  
unknown committed
3107 3108 3109 3110
{
  // TODO: do not forget implement case when select_lex.table_list.elements==0

  /* find non VIEW subqueries/unions */
3111 3112 3113
  bool selects_allow_merge= (select_lex.next_select() == 0 &&
                             !(select_lex.uncacheable &
                               UNCACHEABLE_RAND));
3114 3115
  if (selects_allow_merge)
  {
3116 3117 3118
    for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit();
         tmp_unit;
         tmp_unit= tmp_unit->next_unit())
3119
    {
3120
      if (tmp_unit->first_select()->parent_lex == this &&
3121
          (tmp_unit->item != 0 &&
3122
           (tmp_unit->item->place() != IN_WHERE &&
3123 3124
            tmp_unit->item->place() != IN_ON &&
            tmp_unit->item->place() != SELECT_LIST)))
3125 3126 3127 3128 3129 3130 3131 3132
      {
        selects_allow_merge= 0;
        break;
      }
    }
  }

  return (selects_allow_merge &&
unknown's avatar
VIEW  
unknown committed
3133 3134
	  select_lex.group_list.elements == 0 &&
	  select_lex.having == 0 &&
3135
          select_lex.with_sum_func == 0 &&
3136
	  select_lex.table_list.elements >= 1 &&
unknown's avatar
VIEW  
unknown committed
3137
	  !(select_lex.options & SELECT_DISTINCT) &&
3138
          select_lex.select_limit == 0);
unknown's avatar
VIEW  
unknown committed
3139 3140
}

3141

unknown's avatar
VIEW  
unknown committed
3142
/*
3143
  check if command can use VIEW with MERGE algorithm (for top VIEWs)
unknown's avatar
VIEW  
unknown committed
3144 3145

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3146
    LEX::can_use_merged()
unknown's avatar
VIEW  
unknown committed
3147

3148 3149 3150
  DESCRIPTION
    Only listed here commands can use merge algorithm in top level
    SELECT_LEX (for subqueries will be used merge algorithm if
Konstantin Osipov's avatar
Konstantin Osipov committed
3151
    LEX::can_not_use_merged() is not TRUE).
3152

unknown's avatar
VIEW  
unknown committed
3153 3154 3155 3156 3157
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3158
bool LEX::can_use_merged()
unknown's avatar
VIEW  
unknown committed
3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171
{
  switch (sql_command)
  {
  case SQLCOM_SELECT:
  case SQLCOM_CREATE_TABLE:
  case SQLCOM_UPDATE:
  case SQLCOM_UPDATE_MULTI:
  case SQLCOM_DELETE:
  case SQLCOM_DELETE_MULTI:
  case SQLCOM_INSERT:
  case SQLCOM_INSERT_SELECT:
  case SQLCOM_REPLACE:
  case SQLCOM_REPLACE_SELECT:
3172
  case SQLCOM_LOAD:
unknown's avatar
VIEW  
unknown committed
3173 3174 3175 3176 3177 3178
    return TRUE;
  default:
    return FALSE;
  }
}

3179
/*
3180
  Check if command can't use merged views in any part of command
3181 3182

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3183
    LEX::can_not_use_merged()
3184

3185 3186
  DESCRIPTION
    Temporary table algorithm will be used on all SELECT levels for queries
Konstantin Osipov's avatar
Konstantin Osipov committed
3187
    listed here (see also LEX::can_use_merged()).
3188

3189 3190 3191 3192 3193
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3194
bool LEX::can_not_use_merged()
3195 3196 3197 3198 3199
{
  switch (sql_command)
  {
  case SQLCOM_CREATE_VIEW:
  case SQLCOM_SHOW_CREATE:
3200 3201 3202 3203 3204 3205
  /*
    SQLCOM_SHOW_FIELDS is necessary to make 
    information schema tables working correctly with views.
    see get_schema_tables_result function
  */
  case SQLCOM_SHOW_FIELDS:
3206 3207 3208 3209 3210 3211
    return TRUE;
  default:
    return FALSE;
  }
}

unknown's avatar
VIEW  
unknown committed
3212 3213 3214 3215 3216 3217 3218 3219 3220 3221
/*
  Detect that we need only table structure of derived table/view

  SYNOPSIS
    only_view_structure()

  RETURN
    TRUE yes, we need only structure
    FALSE no, we need data
*/
unknown's avatar
unknown committed
3222

Konstantin Osipov's avatar
Konstantin Osipov committed
3223
bool LEX::only_view_structure()
unknown's avatar
VIEW  
unknown committed
3224
{
3225
  switch (sql_command) {
unknown's avatar
VIEW  
unknown committed
3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239
  case SQLCOM_SHOW_CREATE:
  case SQLCOM_SHOW_TABLES:
  case SQLCOM_SHOW_FIELDS:
  case SQLCOM_REVOKE_ALL:
  case SQLCOM_REVOKE:
  case SQLCOM_GRANT:
  case SQLCOM_CREATE_VIEW:
    return TRUE;
  default:
    return FALSE;
  }
}


unknown's avatar
unknown committed
3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251
/*
  Should Items_ident be printed correctly

  SYNOPSIS
    need_correct_ident()

  RETURN
    TRUE yes, we need only structure
    FALSE no, we need data
*/


Konstantin Osipov's avatar
Konstantin Osipov committed
3252
bool LEX::need_correct_ident()
unknown's avatar
unknown committed
3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264
{
  switch(sql_command)
  {
  case SQLCOM_SHOW_CREATE:
  case SQLCOM_SHOW_TABLES:
  case SQLCOM_CREATE_VIEW:
    return TRUE;
  default:
    return FALSE;
  }
}

3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281
/*
  Get effective type of CHECK OPTION for given view

  SYNOPSIS
    get_effective_with_check()
    view    given view

  NOTE
    It have not sense to set CHECK OPTION for SELECT satement or subqueries,
    so we do not.

  RETURN
    VIEW_CHECK_NONE      no need CHECK OPTION
    VIEW_CHECK_LOCAL     CHECK OPTION LOCAL
    VIEW_CHECK_CASCADED  CHECK OPTION CASCADED
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3282
uint8 LEX::get_effective_with_check(TABLE_LIST *view)
3283 3284 3285 3286 3287 3288 3289
{
  if (view->select_lex->master_unit() == &unit &&
      which_check_option_applicable())
    return (uint8)view->with_check;
  return VIEW_CHECK_NONE;
}

unknown's avatar
unknown committed
3290

3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309
/**
  This method should be called only during parsing.
  It is aware of compound statements (stored routine bodies)
  and will initialize the destination with the default
  database of the stored routine, rather than the default
  database of the connection it is parsed in.
  E.g. if one has no current database selected, or current database 
  set to 'bar' and then issues:

  CREATE PROCEDURE foo.p1() BEGIN SELECT * FROM t1 END//

  t1 is meant to refer to foo.t1, not to bar.t1.

  This method is needed to support this rule.

  @return TRUE in case of error (parsing should be aborted, FALSE in
  case of success
*/

3310
bool LEX::copy_db_to(LEX_CSTRING *to)
3311
{
3312
  if (sphead && sphead->m_name.str)
3313 3314 3315 3316 3317 3318
  {
    DBUG_ASSERT(sphead->m_db.str && sphead->m_db.length);
    /*
      It is safe to assign the string by-pointer, both sphead and
      its statements reside in the same memory root.
    */
3319
    *to= sphead->m_db;
3320 3321
    return FALSE;
  }
3322
  return thd->copy_db_to(to);
3323 3324
}

3325 3326
/**
  Initialize offset and limit counters.
unknown's avatar
unknown committed
3327

3328
  @param sl SELECT_LEX to get offset and limit from.
unknown's avatar
unknown committed
3329
*/
unknown's avatar
VIEW  
unknown committed
3330

unknown's avatar
unknown committed
3331
void st_select_lex_unit::set_limit(st_select_lex *sl)
3332
{
3333
  DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
3334

3335 3336 3337 3338
  offset_limit_cnt= sl->get_offset();
  select_limit_cnt= sl->get_limit();
  if (select_limit_cnt + offset_limit_cnt >= select_limit_cnt)
    select_limit_cnt+= offset_limit_cnt;
3339
  else
3340 3341
    select_limit_cnt= HA_POS_ERROR;
}
3342 3343


3344 3345
/**
  Decide if a temporary table is needed for the UNION.
3346

3347 3348 3349
  @retval true  A temporary table is needed.
  @retval false A temporary table is not needed.
 */
3350

3351 3352
bool st_select_lex_unit::union_needs_tmp_table()
{
3353 3354
  if (with_element && with_element->is_recursive)
    return true;
3355 3356 3357 3358 3359
  return union_distinct != NULL ||
    global_parameters()->order_list.elements != 0 ||
    thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
    thd->lex->sql_command == SQLCOM_REPLACE_SELECT;
}  
unknown's avatar
unknown committed
3360

3361
/**
3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381
  @brief Set the initial purpose of this TABLE_LIST object in the list of used
    tables.

  We need to track this information on table-by-table basis, since when this
  table becomes an element of the pre-locked list, it's impossible to identify
  which SQL sub-statement it has been originally used in.

  E.g.:

  User request:                 SELECT * FROM t1 WHERE f1();
  FUNCTION f1():                DELETE FROM t2; RETURN 1;
  BEFORE DELETE trigger on t2:  INSERT INTO t3 VALUES (old.a);

  For this user request, the pre-locked list will contain t1, t2, t3
  table elements, each needed for different DML.

  The trigger event map is updated to reflect INSERT, UPDATE, DELETE,
  REPLACE, LOAD DATA, CREATE TABLE .. SELECT, CREATE TABLE ..
  REPLACE SELECT statements, and additionally ON DUPLICATE KEY UPDATE
  clause.
3382 3383
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3384
void LEX::set_trg_event_type_for_tables()
3385
{
3386
  uint8 new_trg_event_map= 0;
3387
  DBUG_ENTER("LEX::set_trg_event_type_for_tables");
3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451

  /*
    Some auxiliary operations
    (e.g. GRANT processing) create TABLE_LIST instances outside
    the parser. Additionally, some commands (e.g. OPTIMIZE) change
    the lock type for a table only after parsing is done. Luckily,
    these do not fire triggers and do not need to pre-load them.
    For these TABLE_LISTs set_trg_event_type is never called, and
    trg_event_map is always empty. That means that the pre-locking
    algorithm will ignore triggers defined on these tables, if
    any, and the execution will either fail with an assert in
    sql_trigger.cc or with an error that a used table was not
    pre-locked, in case of a production build.

    TODO: this usage pattern creates unnecessary module dependencies
    and should be rewritten to go through the parser.
    Table list instances created outside the parser in most cases
    refer to mysql.* system tables. It is not allowed to have
    a trigger on a system table, but keeping track of
    initialization provides extra safety in case this limitation
    is circumvented.
  */

  switch (sql_command) {
  case SQLCOM_LOCK_TABLES:
  /*
    On a LOCK TABLE, all triggers must be pre-loaded for this TABLE_LIST
    when opening an associated TABLE.
  */
    new_trg_event_map= static_cast<uint8>
                        (1 << static_cast<int>(TRG_EVENT_INSERT)) |
                      static_cast<uint8>
                        (1 << static_cast<int>(TRG_EVENT_UPDATE)) |
                      static_cast<uint8>
                        (1 << static_cast<int>(TRG_EVENT_DELETE));
    break;
  /*
    Basic INSERT. If there is an additional ON DUPLIATE KEY UPDATE
    clause, it will be handled later in this method.
  */
  case SQLCOM_INSERT:                           /* fall through */
  case SQLCOM_INSERT_SELECT:
  /*
    LOAD DATA ... INFILE is expected to fire BEFORE/AFTER INSERT
    triggers.
    If the statement also has REPLACE clause, it will be
    handled later in this method.
  */
  case SQLCOM_LOAD:                             /* fall through */
  /*
    REPLACE is semantically equivalent to INSERT. In case
    of a primary or unique key conflict, it deletes the old
    record and inserts a new one. So we also may need to
    fire ON DELETE triggers. This functionality is handled
    later in this method.
  */
  case SQLCOM_REPLACE:                          /* fall through */
  case SQLCOM_REPLACE_SELECT:
  /*
    CREATE TABLE ... SELECT defaults to INSERT if the table or
    view already exists. REPLACE option of CREATE TABLE ...
    REPLACE SELECT is handled later in this method.
  */
  case SQLCOM_CREATE_TABLE:
3452
  case SQLCOM_CREATE_SEQUENCE:
3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486
    new_trg_event_map|= static_cast<uint8>
                          (1 << static_cast<int>(TRG_EVENT_INSERT));
    break;
  /* Basic update and multi-update */
  case SQLCOM_UPDATE:                           /* fall through */
  case SQLCOM_UPDATE_MULTI:
    new_trg_event_map|= static_cast<uint8>
                          (1 << static_cast<int>(TRG_EVENT_UPDATE));
    break;
  /* Basic delete and multi-delete */
  case SQLCOM_DELETE:                           /* fall through */
  case SQLCOM_DELETE_MULTI:
    new_trg_event_map|= static_cast<uint8>
                          (1 << static_cast<int>(TRG_EVENT_DELETE));
    break;
  default:
    break;
  }

  switch (duplicates) {
  case DUP_UPDATE:
    new_trg_event_map|= static_cast<uint8>
                          (1 << static_cast<int>(TRG_EVENT_UPDATE));
    break;
  case DUP_REPLACE:
    new_trg_event_map|= static_cast<uint8>
                          (1 << static_cast<int>(TRG_EVENT_DELETE));
    break;
  case DUP_ERROR:
  default:
    break;
  }


3487 3488 3489 3490 3491 3492 3493 3494
  /*
    Do not iterate over sub-selects, only the tables in the outermost
    SELECT_LEX can be modified, if any.
  */
  TABLE_LIST *tables= select_lex.get_table_list();

  while (tables)
  {
3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505
    /*
      This is a fast check to filter out statements that do
      not change data, or tables  on the right side, in case of
      INSERT .. SELECT, CREATE TABLE .. SELECT and so on.
      Here we also filter out OPTIMIZE statement and non-updateable
      views, for which lock_type is TL_UNLOCK or TL_READ after
      parsing.
    */
    if (static_cast<int>(tables->lock_type) >=
        static_cast<int>(TL_WRITE_ALLOW_WRITE))
      tables->trg_event_map= new_trg_event_map;
3506 3507
    tables= tables->next_local;
  }
3508
  DBUG_VOID_RETURN;
3509 3510 3511
}


3512
/*
3513 3514
  Unlink the first table from the global table list and the first table from
  outer select (lex->select_lex) local list
3515 3516 3517

  SYNOPSIS
    unlink_first_table()
3518
    link_to_local	Set to 1 if caller should link this table to local list
unknown's avatar
unknown committed
3519

unknown's avatar
VIEW  
unknown committed
3520
  NOTES
3521 3522
    We assume that first tables in both lists is the same table or the local
    list is empty.
3523 3524

  RETURN
3525
    0	If 'query_tables' == 0
unknown's avatar
VIEW  
unknown committed
3526
    unlinked table
3527
      In this case link_to_local is set.
unknown's avatar
unknown committed
3528

3529
*/
Konstantin Osipov's avatar
Konstantin Osipov committed
3530
TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
3531
{
unknown's avatar
VIEW  
unknown committed
3532 3533 3534 3535 3536 3537 3538 3539
  TABLE_LIST *first;
  if ((first= query_tables))
  {
    /*
      Exclude from global table list
    */
    if ((query_tables= query_tables->next_global))
      query_tables->prev_global= &query_tables;
3540 3541
    else
      query_tables_last= &query_tables;
unknown's avatar
VIEW  
unknown committed
3542 3543 3544 3545 3546
    first->next_global= 0;

    /*
      and from local list if it is not empty
    */
3547
    if ((*link_to_local= MY_TEST(select_lex.table_list.first)))
unknown's avatar
VIEW  
unknown committed
3548
    {
3549 3550
      select_lex.context.table_list= 
        select_lex.context.first_name_resolution_table= first->next_local;
3551
      select_lex.table_list.first= first->next_local;
unknown's avatar
VIEW  
unknown committed
3552 3553 3554
      select_lex.table_list.elements--;	//safety
      first->next_local= 0;
      /*
3555 3556
        Ensure that the global list has the same first table as the local
        list.
unknown's avatar
VIEW  
unknown committed
3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569
      */
      first_lists_tables_same();
    }
  }
  return first;
}


/*
  Bring first local table of first most outer select to first place in global
  table list

  SYNOPSYS
Konstantin Osipov's avatar
Konstantin Osipov committed
3570
     LEX::first_lists_tables_same()
unknown's avatar
VIEW  
unknown committed
3571 3572

  NOTES
3573 3574 3575 3576 3577 3578
    In many cases (for example, usual INSERT/DELETE/...) the first table of
    main SELECT_LEX have special meaning => check that it is the first table
    in global list and re-link to be first in the global list if it is
    necessary.  We need such re-linking only for queries with sub-queries in
    the select list, as only in this case tables of sub-queries will go to
    the global list first.
unknown's avatar
VIEW  
unknown committed
3579 3580
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3581
void LEX::first_lists_tables_same()
unknown's avatar
VIEW  
unknown committed
3582
{
3583
  TABLE_LIST *first_table= select_lex.table_list.first;
unknown's avatar
VIEW  
unknown committed
3584 3585
  if (query_tables != first_table && first_table != 0)
  {
3586
    TABLE_LIST *next;
unknown's avatar
VIEW  
unknown committed
3587 3588
    if (query_tables_last == &first_table->next_global)
      query_tables_last= first_table->prev_global;
3589

3590 3591 3592
    if (query_tables_own_last == &first_table->next_global)
      query_tables_own_last= first_table->prev_global;

3593
    if ((next= *first_table->prev_global= first_table->next_global))
unknown's avatar
VIEW  
unknown committed
3594 3595 3596 3597
      next->prev_global= first_table->prev_global;
    /* include in new place */
    first_table->next_global= query_tables;
    /*
3598 3599 3600
       We are sure that query_tables is not 0, because first_table was not
       first table in the global list => we can use
       query_tables->prev_global without check of query_tables
unknown's avatar
VIEW  
unknown committed
3601 3602 3603 3604 3605
    */
    query_tables->prev_global= &first_table->next_global;
    first_table->prev_global= &query_tables;
    query_tables= first_table;
  }
3606 3607
}

unknown's avatar
unknown committed
3608

3609
/*
unknown's avatar
unknown committed
3610
  Link table back that was unlinked with unlink_first_table()
3611 3612 3613

  SYNOPSIS
    link_first_table_back()
unknown's avatar
VIEW  
unknown committed
3614
    link_to_local	do we need link this table to local
3615 3616 3617 3618

  RETURN
    global list
*/
unknown's avatar
VIEW  
unknown committed
3619

Konstantin Osipov's avatar
Konstantin Osipov committed
3620
void LEX::link_first_table_back(TABLE_LIST *first,
unknown's avatar
VIEW  
unknown committed
3621
				   bool link_to_local)
3622
{
unknown's avatar
VIEW  
unknown committed
3623
  if (first)
3624
  {
unknown's avatar
VIEW  
unknown committed
3625 3626
    if ((first->next_global= query_tables))
      query_tables->prev_global= &first->next_global;
3627 3628
    else
      query_tables_last= &first->next_global;
unknown's avatar
VIEW  
unknown committed
3629 3630 3631 3632
    query_tables= first;

    if (link_to_local)
    {
3633
      first->next_local= select_lex.table_list.first;
unknown's avatar
unknown committed
3634
      select_lex.context.table_list= first;
3635
      select_lex.table_list.first= first;
unknown's avatar
VIEW  
unknown committed
3636 3637 3638 3639 3640 3641
      select_lex.table_list.elements++;	//safety
    }
  }
}


3642 3643 3644 3645 3646

/*
  cleanup lex for case when we open table by table for processing

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3647
    LEX::cleanup_after_one_table_open()
3648 3649 3650 3651 3652

  NOTE
    This method is mostly responsible for cleaning up of selects lists and
    derived tables state. To rollback changes in Query_tables_list one has
    to call Query_tables_list::reset_query_tables_list(FALSE).
3653 3654
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3655
void LEX::cleanup_after_one_table_open()
3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667
{
  /*
    thd->lex->derived_tables & additional units may be set if we open
    a view. It is necessary to clear thd->lex->derived_tables flag
    to prevent processing of derived tables during next open_and_lock_tables
    if next table is a real table and cleanup & remove underlying units
    NOTE: all units will be connected to thd->lex->select_lex, because we
    have not UNION on most upper level.
    */
  if (all_selects_list != &select_lex)
  {
    derived_tables= 0;
3668
    select_lex.exclude_from_table_unique_test= false;
3669 3670 3671 3672 3673 3674 3675 3676 3677 3678
    /* cleunup underlying units (units of VIEW) */
    for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
         un;
         un= un->next_unit())
      un->cleanup();
    /* reduce all selects list to default state */
    all_selects_list= &select_lex;
    /* remove underlying units (units of VIEW) subtree */
    select_lex.cut_subtree();
  }
3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690
}


/*
  Save current state of Query_tables_list for this LEX, and prepare it
  for processing of new statemnt.

  SYNOPSIS
    reset_n_backup_query_tables_list()
      backup  Pointer to Query_tables_list instance to be used for backup
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3691
void LEX::reset_n_backup_query_tables_list(Query_tables_list *backup)
3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709
{
  backup->set_query_tables_list(this);
  /*
    We have to perform full initialization here since otherwise we
    will damage backed up state.
  */
  this->reset_query_tables_list(TRUE);
}


/*
  Restore state of Query_tables_list for this LEX from backup.

  SYNOPSIS
    restore_backup_query_tables_list()
      backup  Pointer to Query_tables_list instance used for backup
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3710
void LEX::restore_backup_query_tables_list(Query_tables_list *backup)
3711 3712 3713
{
  this->destroy_query_tables_list();
  this->set_query_tables_list(backup);
3714 3715 3716
}


unknown's avatar
unknown committed
3717 3718 3719 3720
/*
  Checks for usage of routines and/or tables in a parsed statement

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3721
    LEX:table_or_sp_used()
unknown's avatar
unknown committed
3722 3723 3724 3725 3726 3727

  RETURN
    FALSE  No routines and tables used
    TRUE   Either or both routines and tables are used.
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3728
bool LEX::table_or_sp_used()
unknown's avatar
unknown committed
3729 3730 3731 3732 3733 3734 3735 3736 3737 3738
{
  DBUG_ENTER("table_or_sp_used");

  if (sroutines.records || query_tables)
    DBUG_RETURN(TRUE);

  DBUG_RETURN(FALSE);
}


3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757
/*
  Do end-of-prepare fixup for list of tables and their merge-VIEWed tables

  SYNOPSIS
    fix_prepare_info_in_table_list()
      thd  Thread handle
      tbl  List of tables to process

  DESCRIPTION
    Perform end-end-of prepare fixup for list of tables, if any of the tables
    is a merge-algorithm VIEW, recursively fix up its underlying tables as
    well.

*/

static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
{
  for (; tbl; tbl= tbl->next_local)
  {
unknown's avatar
unknown committed
3758
    if (tbl->on_expr && !tbl->prep_on_expr)
3759
    {
unknown's avatar
unknown committed
3760
      thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
3761 3762
      tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
    }
3763 3764 3765 3766 3767
    if (tbl->is_view_or_derived() && tbl->is_merged_derived())
    {
      SELECT_LEX *sel= tbl->get_single_select();
      fix_prepare_info_in_table_list(thd, sel->get_table_list());
    }
3768 3769 3770 3771
  }
}


unknown's avatar
VIEW  
unknown committed
3772
/*
3773
  Save WHERE/HAVING/ON clauses and replace them with disposable copies
unknown's avatar
VIEW  
unknown committed
3774 3775 3776

  SYNOPSIS
    st_select_lex::fix_prepare_information
3777 3778 3779 3780 3781 3782 3783 3784
      thd          thread handler
      conds        in/out pointer to WHERE condition to be met at execution
      having_conds in/out pointer to HAVING condition to be met at execution
  
  DESCRIPTION
    The passed WHERE and HAVING are to be saved for the future executions.
    This function saves it, and returns a copy which can be thrashed during
    this execution of the statement. By saving/thrashing here we mean only
3785 3786
    We also save the chain of ORDER::next in group_list, in case
    the list is modified by remove_const().
3787 3788 3789
    AND/OR trees.
    The function also calls fix_prepare_info_in_table_list that saves all
    ON expressions.    
unknown's avatar
VIEW  
unknown committed
3790 3791
*/

3792 3793
void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
                                            Item **having_conds)
unknown's avatar
VIEW  
unknown committed
3794
{
3795
  DBUG_ENTER("st_select_lex::fix_prepare_information");
unknown's avatar
unknown committed
3796
  if (!thd->stmt_arena->is_conventional() && first_execution)
unknown's avatar
VIEW  
unknown committed
3797
  {
3798
    Query_arena_stmt on_stmt_arena(thd);
unknown's avatar
VIEW  
unknown committed
3799
    first_execution= 0;
3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812
    if (group_list.first)
    {
      if (!group_list_ptrs)
      {
        void *mem= thd->stmt_arena->alloc(sizeof(Group_list_ptrs));
        group_list_ptrs= new (mem) Group_list_ptrs(thd->stmt_arena->mem_root);
      }
      group_list_ptrs->reserve(group_list.elements);
      for (ORDER *order= group_list.first; order; order= order->next)
      {
        group_list_ptrs->push_back(order);
      }
    }
3813 3814
    if (*conds)
    {
unknown's avatar
unknown committed
3815
      thd->check_and_register_item_tree(&prep_where, conds);
3816 3817
      *conds= where= prep_where->copy_andor_structure(thd);
    }
3818 3819
    if (*having_conds)
    {
unknown's avatar
unknown committed
3820
      thd->check_and_register_item_tree(&prep_having, having_conds);
3821 3822
      *having_conds= having= prep_having->copy_andor_structure(thd);
    }
3823
    fix_prepare_info_in_table_list(thd, table_list.first);
3824
  }
3825
  DBUG_VOID_RETURN;
3826 3827
}

unknown's avatar
unknown committed
3828

unknown's avatar
unknown committed
3829
/*
unknown's avatar
VIEW  
unknown committed
3830
  There are st_select_lex::add_table_to_list &
unknown's avatar
unknown committed
3831
  st_select_lex::set_lock_for_tables are in sql_parse.cc
unknown's avatar
unknown committed
3832

unknown's avatar
VIEW  
unknown committed
3833
  st_select_lex::print is in sql_select.cc
unknown's avatar
unknown committed
3834 3835

  st_select_lex_unit::prepare, st_select_lex_unit::exec,
3836 3837
  st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,
  st_select_lex_unit::change_result
unknown's avatar
unknown committed
3838
  are in sql_union.cc
unknown's avatar
unknown committed
3839
*/
3840

3841 3842 3843 3844 3845
/*
  Sets the kind of hints to be added by the calls to add_index_hint().

  SYNOPSIS
    set_index_hint_type()
3846 3847
      type_arg     The kind of hints to be added from now on.
      clause       The clause to use for hints to be added from now on.
3848 3849 3850 3851 3852 3853 3854 3855

  DESCRIPTION
    Used in filling up the tagged hints list.
    This list is filled by first setting the kind of the hint as a 
    context variable and then adding hints of the current kind.
    Then the context variable index_hint_type can be reset to the
    next hint type.
*/
3856
void st_select_lex::set_index_hint_type(enum index_hint_type type_arg,
3857 3858
                                        index_clause_map clause)
{ 
3859
  current_index_hint_type= type_arg;
3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873
  current_index_hint_clause= clause;
}


/*
  Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).

  SYNOPSIS
    alloc_index_hints()
      thd         current thread.
*/

void st_select_lex::alloc_index_hints (THD *thd)
{ 
unknown's avatar
unknown committed
3874
  index_hints= new (thd->mem_root) List<Index_hint>(); 
3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891
}



/*
  adds an element to the array storing index usage hints 
  (ADD/FORCE/IGNORE INDEX).

  SYNOPSIS
    add_index_hint()
      thd         current thread.
      str         name of the index.
      length      number of characters in str.

  RETURN VALUE
    0 on success, non-zero otherwise
*/
3892
bool st_select_lex::add_index_hint (THD *thd, const char *str, size_t length)
3893
{
3894
  return index_hints->push_front(new (thd->mem_root) 
unknown's avatar
unknown committed
3895
                                 Index_hint(current_index_hint_type,
3896
                                            current_index_hint_clause,
3897
                                            str, length), thd->mem_root);
3898
}
3899

3900

3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917
/**
  Optimize all subqueries that have not been flattened into semi-joins.

  @details
  This functionality is a method of SELECT_LEX instead of JOIN because
  SQL statements as DELETE/UPDATE do not have a corresponding JOIN object.

  @see JOIN::optimize_unflattened_subqueries

  @param const_only  Restrict subquery optimization to constant subqueries

  @return Operation status
  @retval FALSE     success.
  @retval TRUE      error occurred.
*/

bool st_select_lex::optimize_unflattened_subqueries(bool const_only)
3918
{
3919 3920 3921 3922
  SELECT_LEX_UNIT *next_unit= NULL;
  for (SELECT_LEX_UNIT *un= first_inner_unit();
       un;
       un= next_unit ? next_unit : un->next_unit())
3923 3924
  {
    Item_subselect *subquery_predicate= un->item;
3925 3926
    next_unit= NULL;

3927 3928
    if (subquery_predicate)
    {
3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940
      if (!subquery_predicate->fixed)
      {
	/*
	 This subquery was excluded as part of some expression so it is
	 invisible from all prepared expression.
       */
	next_unit= un->next_unit();
	un->exclude_level();
	if (next_unit)
	  continue;
	break;
      }
Sergey Petrunya's avatar
Sergey Petrunya committed
3941 3942
      if (subquery_predicate->substype() == Item_subselect::IN_SUBS)
      {
3943
        Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
Sergey Petrunya's avatar
Sergey Petrunya committed
3944 3945 3946 3947
        if (in_subs->is_jtbm_merged)
          continue;
      }

3948 3949 3950 3951 3952 3953
      if (const_only && !subquery_predicate->const_item())
      {
        /* Skip non-constant subqueries if the caller asked so. */
        continue;
      }

unknown's avatar
unknown committed
3954
      bool empty_union_result= true;
3955
      bool is_correlated_unit= false;
3956 3957
      bool first= true;
      bool union_plan_saved= false;
unknown's avatar
unknown committed
3958 3959 3960 3961
      /*
        If the subquery is a UNION, optimize all the subqueries in the UNION. If
        there is no UNION, then the loop will execute once for the subquery.
      */
3962 3963 3964
      for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
      {
        JOIN *inner_join= sl->join;
3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975
        if (first)
          first= false;
        else
        {
          if (!union_plan_saved)
          {
            union_plan_saved= true;
            if (un->save_union_explain(un->thd->lex->explain))
              return true; /* Failure */
          }
        }
3976 3977
        if (!inner_join)
          continue;
3978
        SELECT_LEX *save_select= un->thd->lex->current_select;
3979
        ulonglong save_options;
3980
        int res;
3981
        /* We need only 1 row to determine existence */
3982
        un->set_limit(un->global_parameters());
3983
        un->thd->lex->current_select= sl;
3984
        save_options= inner_join->select_options;
3985
        if (options & SELECT_DESCRIBE)
3986 3987
        {
          /* Optimize the subquery in the context of EXPLAIN. */
3988
          sl->set_explain_type(FALSE);
unknown's avatar
unknown committed
3989 3990
          sl->options|= SELECT_DESCRIBE;
          inner_join->select_options|= SELECT_DESCRIBE;
3991
        }
3992
        res= inner_join->optimize();
3993 3994
        sl->update_correlated_cache();
        is_correlated_unit|= sl->is_correlated;
3995
        inner_join->select_options= save_options;
3996
        un->thd->lex->current_select= save_select;
3997

3998 3999
        Explain_query *eq;
        if ((eq= inner_join->thd->lex->explain))
4000
        {
4001 4002
          Explain_select *expl_sel;
          if ((expl_sel= eq->get_select(inner_join->select_lex->select_number)))
4003 4004
          {
            sl->set_explain_type(TRUE);
4005
            expl_sel->select_type= sl->type;
4006 4007
          }
        }
4008

unknown's avatar
unknown committed
4009 4010 4011 4012 4013 4014 4015 4016
        if (empty_union_result)
        {
          /*
            If at least one subquery in a union is non-empty, the UNION result
            is non-empty. If there is no UNION, the only subquery is non-empy.
          */
          empty_union_result= inner_join->empty_result();
        }
4017 4018 4019
        if (res)
          return TRUE;
      }
unknown's avatar
unknown committed
4020 4021
      if (empty_union_result)
        subquery_predicate->no_rows_in_result();
4022 4023 4024
      if (!is_correlated_unit)
        un->uncacheable&= ~UNCACHEABLE_DEPENDENT;
      subquery_predicate->is_correlated= is_correlated_unit;
4025 4026 4027
    }
  }
  return FALSE;
4028 4029 4030
}


4031

4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045
/**
  @brief Process all derived tables/views of the SELECT.

  @param lex    LEX of this thread
  @param phase  phases to run derived tables/views through

  @details
  This function runs specified 'phases' on all tables from the
  table_list of this select.

  @return FALSE ok.
  @return TRUE an error occur.
*/

Sergei Golubchik's avatar
Sergei Golubchik committed
4046
bool st_select_lex::handle_derived(LEX *lex, uint phases)
4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111
{
  for (TABLE_LIST *cursor= (TABLE_LIST*) table_list.first;
       cursor;
       cursor= cursor->next_local)
  {
    if (cursor->is_view_or_derived() && cursor->handle_derived(lex, phases))
      return TRUE;
  }
  return FALSE;
}


/**
  @brief
  Returns first unoccupied table map and table number

  @param map     [out] return found map
  @param tablenr [out] return found tablenr

  @details
  Returns first unoccupied table map and table number in this select.
  Map and table are returned in *'map' and *'tablenr' accordingly.

  @retrun TRUE  no free table map/table number
  @return FALSE found free table map/table number
*/

bool st_select_lex::get_free_table_map(table_map *map, uint *tablenr)
{
  *map= 0;
  *tablenr= 0;
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);
  while ((tl= ti++))
  {
    if (tl->table->map > *map)
      *map= tl->table->map;
    if (tl->table->tablenr > *tablenr)
      *tablenr= tl->table->tablenr;
  }
  (*map)<<= 1;
  (*tablenr)++;
  if (*tablenr >= MAX_TABLES)
    return TRUE;
  return FALSE;
}


/**
  @brief
  Append given table to the leaf_tables list.

  @param link  Offset to which list in table structure to use
  @param table Table to append

  @details
  Append given 'table' to the leaf_tables list using the 'link' offset.
  If the 'table' is linked with other tables through next_leaf/next_local
  chains then whole list will be appended.
*/

void st_select_lex::append_table_to_list(TABLE_LIST *TABLE_LIST::*link,
                                         TABLE_LIST *table)
{
  TABLE_LIST *tl;
Igor Babaev's avatar
Igor Babaev committed
4112
  for (tl= leaf_tables.head(); tl->*link; tl= tl->*link) ;
4113 4114 4115
  tl->*link= table;
}

Igor Babaev's avatar
Igor Babaev committed
4116

4117 4118
/*
  @brief
Igor Babaev's avatar
Igor Babaev committed
4119
  Replace given table from the leaf_tables list for a list of tables 
4120

Igor Babaev's avatar
Igor Babaev committed
4121 4122
  @param table Table to replace
  @param list  List to substititute the table for
4123 4124

  @details
Igor Babaev's avatar
Igor Babaev committed
4125
  Replace 'table' from the leaf_tables list for a list of tables 'tbl_list'.
4126 4127
*/

Igor Babaev's avatar
Igor Babaev committed
4128
void st_select_lex::replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list)
4129 4130 4131 4132 4133 4134 4135
{
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);
  while ((tl= ti++))
  {
    if (tl == table)
    {
Igor Babaev's avatar
Igor Babaev committed
4136
      ti.replace(tbl_list);
4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235
      break;
    }
  }
}


/**
  @brief
  Assigns new table maps to tables in the leaf_tables list

  @param derived    Derived table to take initial table map from
  @param map        table map to begin with
  @param tablenr    table number to begin with
  @param parent_lex new parent select_lex

  @details
  Assign new table maps/table numbers to all tables in the leaf_tables list.
  'map'/'tablenr' are used for the first table and shifted to left/
  increased for each consequent table in the leaf_tables list.
  If the 'derived' table is given then it's table map/number is used for the
  first table in the list and 'map'/'tablenr' are used for the second and
  all consequent tables.
  The 'parent_lex' is set as the new parent select_lex for all tables in the
  list.
*/

void st_select_lex::remap_tables(TABLE_LIST *derived, table_map map,
                                 uint tablenr, SELECT_LEX *parent_lex)
{
  bool first_table= TRUE;
  TABLE_LIST *tl;
  table_map first_map;
  uint first_tablenr;

  if (derived && derived->table)
  {
    first_map= derived->table->map;
    first_tablenr= derived->table->tablenr;
  }
  else
  {
    first_map= map;
    map<<= 1;
    first_tablenr= tablenr++;
  }
  /*
    Assign table bit/table number.
    To the first table of the subselect the table bit/tablenr of the
    derived table is assigned. The rest of tables are getting bits
    sequentially, starting from the provided table map/tablenr.
  */
  List_iterator<TABLE_LIST> ti(leaf_tables);
  while ((tl= ti++))
  {
    if (first_table)
    {
      first_table= FALSE;
      tl->table->set_table_map(first_map, first_tablenr);
    }
    else
    {
      tl->table->set_table_map(map, tablenr);
      tablenr++;
      map<<= 1;
    }
    SELECT_LEX *old_sl= tl->select_lex;
    tl->select_lex= parent_lex;
    for(TABLE_LIST *emb= tl->embedding;
        emb && emb->select_lex == old_sl;
        emb= emb->embedding)
      emb->select_lex= parent_lex;
  }
}

/**
  @brief
  Merge a subquery into this select.

  @param derived     derived table of the subquery to be merged
  @param subq_select select_lex of the subquery
  @param map         table map for assigning to merged tables from subquery
  @param table_no    table number for assigning to merged tables from subquery

  @details
  This function merges a subquery into its parent select. In short the
  merge operation appends the subquery FROM table list to the parent's
  FROM table list. In more details:
    .) the top_join_list of the subquery is wrapped into a join_nest
       and attached to 'derived'
    .) subquery's leaf_tables list  is merged with the leaf_tables
       list of this select_lex
    .) the table maps and table numbers of the tables merged from
       the subquery are adjusted to reflect their new binding to
       this select

  @return TRUE  an error occur
  @return FALSE ok
*/

Igor Babaev's avatar
Igor Babaev committed
4236 4237
bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
                                SELECT_LEX *subq_select,
4238 4239 4240 4241
                                uint table_no, table_map map)
{
  derived->wrap_into_nested_join(subq_select->top_join_list);

4242
  ftfunc_list->append(subq_select->ftfunc_list);
Igor Babaev's avatar
Igor Babaev committed
4243 4244 4245
  if (join ||
      thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
      thd->lex->sql_command == SQLCOM_DELETE_MULTI)
4246
  {
Igor Babaev's avatar
Igor Babaev committed
4247 4248 4249
    List_iterator_fast<Item_in_subselect> li(subq_select->sj_subselects);
    Item_in_subselect *in_subq;
    while ((in_subq= li++))
4250
    {
4251
      sj_subselects.push_back(in_subq, thd->mem_root);
Igor Babaev's avatar
Igor Babaev committed
4252 4253
      if (in_subq->emb_on_expr_nest == NO_JOIN_NEST)
         in_subq->emb_on_expr_nest= derived;
4254
    }
4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270

    uint cnt= sizeof(expr_cache_may_be_used)/sizeof(bool);
    for (uint i= 0; i < cnt; i++)
    {
      if (subq_select->expr_cache_may_be_used[i])
	expr_cache_may_be_used[i]= true;
    }

    List_iterator_fast<Item_func_in> it(subq_select->in_funcs);
    Item_func_in *in_func;
    while ((in_func= it++))
    {
      in_funcs.push_back(in_func, thd->mem_root);
      if (in_func->emb_on_expr_nest == NO_JOIN_NEST)
        in_func->emb_on_expr_nest= derived;
    }
4271 4272 4273 4274 4275
  }

  /* Walk through child's tables and adjust table map, tablenr,
   * parent_lex */
  subq_select->remap_tables(derived, map, table_no, this);
Igor Babaev's avatar
Igor Babaev committed
4276
  subq_select->merged_into= this;
Igor Babaev's avatar
Igor Babaev committed
4277 4278 4279

  replace_leaf_table(derived, subq_select->leaf_tables);

4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316
  return FALSE;
}


/**
  @brief
  Mark tables from the leaf_tables list as belong to a derived table.

  @param derived   tables will be marked as belonging to this derived

  @details
  Run through the leaf_list and mark all tables as belonging to the 'derived'.
*/

void SELECT_LEX::mark_as_belong_to_derived(TABLE_LIST *derived)
{
  /* Mark tables as belonging to this DT */
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);
  while ((tl= ti++))
    tl->belong_to_derived= derived;
}


/**
  @brief
  Update used_tables cache for this select

  @details
  This function updates used_tables cache of ON expressions of all tables
  in the leaf_tables list and of the conds expression (if any).
*/

void SELECT_LEX::update_used_tables()
{
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);
Igor Babaev's avatar
Igor Babaev committed
4317

4318 4319
  while ((tl= ti++))
  {
Igor Babaev's avatar
Igor Babaev committed
4320
    if (tl->table && !tl->is_view_or_derived())
Igor Babaev's avatar
Igor Babaev committed
4321
    {
Igor Babaev's avatar
Igor Babaev committed
4322
      TABLE_LIST *embedding= tl->embedding;
Igor Babaev's avatar
Igor Babaev committed
4323 4324 4325 4326 4327 4328 4329 4330
      for (embedding= tl->embedding; embedding; embedding=embedding->embedding)
      {
        if (embedding->is_view_or_derived())
	{
          DBUG_ASSERT(embedding->is_merged_derived());
          TABLE *tab= tl->table;
          tab->covering_keys= tab->s->keys_for_keyread;
          tab->covering_keys.intersect(tab->keys_in_use_for_query);
4331 4332 4333 4334 4335 4336 4337 4338 4339
          /*
            View/derived was merged. Need to recalculate read_set/vcol_set
            bitmaps here. For example:
              CREATE VIEW v1 AS SELECT f1,f2,f3 FROM t1;
              SELECT f1 FROM v1;
            Initially, the view definition will put all f1,f2,f3 in the
            read_set for t1. But after the view is merged, only f1 should
            be in the read_set.
          */
Igor Babaev's avatar
Igor Babaev committed
4340
          bitmap_clear_all(tab->read_set);
4341 4342
          if (tab->vcol_set)
            bitmap_clear_all(tab->vcol_set);
Igor Babaev's avatar
Igor Babaev committed
4343 4344 4345 4346
          break;
        }
      }
    }
Igor Babaev's avatar
Igor Babaev committed
4347 4348 4349 4350 4351 4352
  }

  ti.rewind();
  while ((tl= ti++))
  {
    TABLE_LIST *embedding= tl;
Igor Babaev's avatar
Igor Babaev committed
4353
    do
Igor Babaev's avatar
Igor Babaev committed
4354
    {
Igor Babaev's avatar
Igor Babaev committed
4355
      bool maybe_null;
4356
      if ((maybe_null= MY_TEST(embedding->outer_join)))
Igor Babaev's avatar
Igor Babaev committed
4357 4358 4359 4360
      {
	tl->table->maybe_null= maybe_null;
        break;
      }
Igor Babaev's avatar
Igor Babaev committed
4361
    }
Igor Babaev's avatar
Igor Babaev committed
4362
    while ((embedding= embedding->embedding));
4363 4364 4365 4366 4367
    if (tl->on_expr)
    {
      tl->on_expr->update_used_tables();
      tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
    }
4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380
    /*
      - There is no need to check sj_on_expr, because merged semi-joins inject
        sj_on_expr into the parent's WHERE clase.
      - For non-merged semi-joins (aka JTBMs), we need to check their
        left_expr. There is no need to check the rest of the subselect, we know
        it is uncorrelated and so cannot refer to any tables in this select.
    */
    if (tl->jtbm_subselect)
    {
      Item *left_expr= tl->jtbm_subselect->left_expr;
      left_expr->walk(&Item::update_table_bitmaps_processor, FALSE, NULL);
    }

Igor Babaev's avatar
Igor Babaev committed
4381
    embedding= tl->embedding;
4382 4383 4384 4385 4386 4387 4388 4389 4390 4391
    while (embedding)
    {
      if (embedding->on_expr && 
          embedding->nested_join->join_list.head() == tl)
      {
        embedding->on_expr->update_used_tables();
        embedding->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
      }
      tl= embedding;
      embedding= tl->embedding;
4392
    }
4393
  }
Igor Babaev's avatar
Igor Babaev committed
4394

4395 4396 4397 4398 4399
  if (join->conds)
  {
    join->conds->update_used_tables();
    join->conds->walk(&Item::eval_not_null_tables, 0, NULL);
  }
Igor Babaev's avatar
Igor Babaev committed
4400 4401 4402 4403 4404 4405 4406
  if (join->having)
  {
    join->having->update_used_tables();
  }

  Item *item;
  List_iterator_fast<Item> it(join->fields_list);
4407
  select_list_tables= 0;
Igor Babaev's avatar
Igor Babaev committed
4408 4409 4410
  while ((item= it++))
  {
    item->update_used_tables();
4411
    select_list_tables|= item->used_tables();
Igor Babaev's avatar
Igor Babaev committed
4412 4413 4414 4415 4416 4417 4418 4419 4420 4421
  }
  Item_outer_ref *ref;
  List_iterator_fast<Item_outer_ref> ref_it(inner_refs_list);
  while ((ref= ref_it++))
  {
    item= ref->outer_ref;
    item->update_used_tables();
  }
  for (ORDER *order= group_list.first; order; order= order->next)
    (*order->item)->update_used_tables();
4422 4423
  if (!master_unit()->is_unit_op() ||
      master_unit()->global_parameters() != this)
Igor Babaev's avatar
Igor Babaev committed
4424 4425 4426
  {
    for (ORDER *order= order_list.first; order; order= order->next)
      (*order->item)->update_used_tables();
unknown's avatar
unknown committed
4427 4428
  }
  join->result->update_used_tables();
4429 4430
}

4431

4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447
/**
  @brief
  Update is_correlated cache for this select

  @details
*/

void st_select_lex::update_correlated_cache()
{
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);

  is_correlated= false;

  while ((tl= ti++))
  {
4448
    //    is_correlated|= tl->is_with_table_recursive_reference();
4449
    if (tl->on_expr)
4450
      is_correlated|= MY_TEST(tl->on_expr->used_tables() & OUTER_REF_TABLE_BIT);
4451 4452 4453 4454
    for (TABLE_LIST *embedding= tl->embedding ; embedding ;
         embedding= embedding->embedding)
    {
      if (embedding->on_expr)
4455 4456
        is_correlated|= MY_TEST(embedding->on_expr->used_tables() &
                                OUTER_REF_TABLE_BIT);
4457 4458 4459 4460
    }
  }

  if (join->conds)
4461
    is_correlated|= MY_TEST(join->conds->used_tables() & OUTER_REF_TABLE_BIT);
4462

4463 4464
  is_correlated|= join->having_is_correlated;

4465
  if (join->having)
4466
    is_correlated|= MY_TEST(join->having->used_tables() & OUTER_REF_TABLE_BIT);
4467 4468

  if (join->tmp_having)
4469 4470
    is_correlated|= MY_TEST(join->tmp_having->used_tables() &
                            OUTER_REF_TABLE_BIT);
4471 4472 4473 4474

  Item *item;
  List_iterator_fast<Item> it(join->fields_list);
  while ((item= it++))
4475
    is_correlated|= MY_TEST(item->used_tables() & OUTER_REF_TABLE_BIT);
4476 4477

  for (ORDER *order= group_list.first; order; order= order->next)
4478 4479
    is_correlated|= MY_TEST((*order->item)->used_tables() &
                            OUTER_REF_TABLE_BIT);
4480

4481
  if (!master_unit()->is_unit_op())
4482 4483
  {
    for (ORDER *order= order_list.first; order; order= order->next)
4484 4485
      is_correlated|= MY_TEST((*order->item)->used_tables() &
                              OUTER_REF_TABLE_BIT);
4486 4487 4488 4489 4490 4491 4492
  }

  if (!is_correlated)
    uncacheable&= ~UNCACHEABLE_DEPENDENT;
}


4493 4494
/**
  Set the EXPLAIN type for this subquery.
Sergey Petrunya's avatar
Sergey Petrunya committed
4495 4496 4497
  
  @param on_the_fly  TRUE<=> We're running a SHOW EXPLAIN command, so we must 
                     not change any variables
4498 4499
*/

4500
void st_select_lex::set_explain_type(bool on_the_fly)
4501
{
4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521
  bool is_primary= FALSE;
  if (next_select())
    is_primary= TRUE;

  if (!is_primary && first_inner_unit())
  {
    /*
      If there is at least one materialized derived|view then it's a PRIMARY select.
      Otherwise, all derived tables/views were merged and this select is a SIMPLE one.
    */
    for (SELECT_LEX_UNIT *un= first_inner_unit(); un; un= un->next_unit())
    {
      if ((!un->derived || un->derived->is_materialized_derived()))
      {
        is_primary= TRUE;
        break;
      }
    }
  }

4522 4523 4524
  if (on_the_fly && !is_primary && have_merged_subqueries)
    is_primary= TRUE;

4525 4526 4527
  SELECT_LEX *first= master_unit()->first_select();
  /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
  uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541
  
  bool using_materialization= FALSE;
  Item_subselect *parent_item;
  if ((parent_item= master_unit()->item) &&
      parent_item->substype() == Item_subselect::IN_SUBS)
  {
    Item_in_subselect *in_subs= (Item_in_subselect*)parent_item;
    /*
      Surprisingly, in_subs->is_set_strategy() can return FALSE here,
      even for the last invocation of this function for the select.
    */
    if (in_subs->test_strategy(SUBS_MATERIALIZATION))
      using_materialization= TRUE;
  }
4542

4543 4544 4545 4546 4547 4548 4549 4550 4551 4552
  if (&master_unit()->thd->lex->select_lex == this)
  {
     type= is_primary ? "PRIMARY" : "SIMPLE";
  }
  else
  {
    if (this == first)
    {
      /* If we're a direct child of a UNION, we're the first sibling there */
      if (linkage == DERIVED_TABLE_TYPE)
4553 4554 4555 4556 4557 4558
      {
        if (is_uncacheable & UNCACHEABLE_DEPENDENT)
          type= "LATERAL DERIVED";
        else
          type= "DERIVED";
      }
4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573
      else if (using_materialization)
        type= "MATERIALIZED";
      else
      {
         if (is_uncacheable & UNCACHEABLE_DEPENDENT)
           type= "DEPENDENT SUBQUERY";
         else
         {
           type= is_uncacheable? "UNCACHEABLE SUBQUERY" :
                                 "SUBQUERY";
         }
      }
    }
    else
    {
4574
      switch (linkage)
4575
      {
4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588
      case INTERSECT_TYPE:
        type= "INTERSECT";
        break;
      case EXCEPT_TYPE:
        type= "EXCEPT";
        break;
      default:
        /* This a non-first sibling in UNION */
        if (is_uncacheable & UNCACHEABLE_DEPENDENT)
          type= "DEPENDENT UNION";
        else if (using_materialization)
          type= "MATERIALIZED UNION";
        else
4589
        {
4590 4591 4592 4593 4594 4595 4596 4597 4598
          type= is_uncacheable ? "UNCACHEABLE UNION": "UNION";
          if (this == master_unit()->fake_select_lex)
            type= unit_operation_text[master_unit()->common_op()];
          /*
            join below may be =NULL when this functions is called at an early
            stage. It will be later called again and we will set the correct
            value.
          */
          if (join)
4599
          {
4600
            bool uses_cte= false;
4601 4602 4603 4604
            for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_BUSH_ROOTS,
                                                       WITH_CONST_TABLES);
                 tab;
                 tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
4605
            {
4606 4607 4608 4609
              /*
                pos_in_table_list=NULL for e.g. post-join aggregation JOIN_TABs.
              */
              if (tab->table && tab->table->pos_in_table_list &&
4610 4611
                  tab->table->pos_in_table_list->with &&
                  tab->table->pos_in_table_list->with->is_recursive)
4612 4613 4614 4615
              {
                uses_cte= true;
                break;
              }
4616
            }
4617 4618
            if (uses_cte)
              type= "RECURSIVE UNION";
4619 4620
          }
        }
4621
        break;
4622 4623 4624
      }
    }
  }
4625 4626

  if (!on_the_fly)
4627
    options|= SELECT_DESCRIBE;
4628
}
4629 4630


4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641
/**
  @brief
  Increase estimated number of records for a derived table/view

  @param records  number of records to increase estimate by

  @details
  This function increases estimated number of records by the 'records'
  for the derived table to which this select belongs to.
*/

Vladislav Vaintroub's avatar
Vladislav Vaintroub committed
4642
void SELECT_LEX::increase_derived_records(ha_rows records)
4643 4644 4645 4646
{
  SELECT_LEX_UNIT *unit= master_unit();
  DBUG_ASSERT(unit->derived);

Igor Babaev's avatar
Igor Babaev committed
4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659
  if (unit->with_element && unit->with_element->is_recursive)
  {
    st_select_lex *first_recursive= unit->with_element->first_recursive;
    st_select_lex *sl= unit->first_select();
    for ( ; sl != first_recursive; sl= sl->next_select())
    {
      if (sl == this)
        break;
    }
    if (sl == first_recursive)
      return; 
  }
  
4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673
  select_unit *result= (select_unit*)unit->result;
  switch (linkage)
  {
  case INTERSECT_TYPE:
    // result of intersect can't be more then one of components
    set_if_smaller(result->records, records);
  case EXCEPT_TYPE:
    // in worse case none of record will be removed
    break;
  default:
    // usual UNION
    result->records+= records;
    break;
  }
4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692
}


/**
  @brief
  Mark select's derived table as a const one.

  @param empty Whether select has an empty result set

  @details
  Mark derived table/view of this select as a constant one (to
  materialize it at the optimization phase) unless this select belongs to a
  union. Estimated number of rows is incremented if this select has non empty
  result set.
*/

void SELECT_LEX::mark_const_derived(bool empty)
{
  TABLE_LIST *derived= master_unit()->derived;
Igor Babaev's avatar
Igor Babaev committed
4693 4694
  /* join == NULL in  DELETE ... RETURNING */
  if (!(join && join->thd->lex->describe) && derived)
4695 4696 4697
  {
    if (!empty)
      increase_derived_records(1);
Igor Babaev's avatar
Igor Babaev committed
4698 4699
    if (!master_unit()->is_unit_op() && !derived->is_merged_derived() &&
        !(join && join->with_two_phase_optimization))
4700 4701 4702 4703
      derived->fill_me= TRUE;
  }
}

Igor Babaev's avatar
Igor Babaev committed
4704

4705 4706
bool st_select_lex::save_leaf_tables(THD *thd)
{
4707 4708
  Query_arena *arena, backup;
  arena= thd->activate_stmt_arena_if_needed(&backup);
4709 4710 4711 4712 4713

  List_iterator_fast<TABLE_LIST> li(leaf_tables);
  TABLE_LIST *table;
  while ((table= li++))
  {
4714
    if (leaf_tables_exec.push_back(table, thd->mem_root))
4715
      return 1;
4716 4717
    table->tablenr_exec= table->get_tablenr();
    table->map_exec= table->get_map();
Igor Babaev's avatar
Igor Babaev committed
4718 4719 4720
    if (join && (join->select_options & SELECT_DESCRIBE))
      table->maybe_null_exec= 0;
    else
4721
      table->maybe_null_exec= table->table?  table->table->maybe_null: 0;
4722 4723 4724 4725 4726 4727 4728
  }
  if (arena)
    thd->restore_active_arena(arena, &backup);

  return 0;
}

4729

4730
bool LEX::save_prep_leaf_tables()
Igor Babaev's avatar
Igor Babaev committed
4731 4732
{
  if (!thd->save_prep_leaf_list)
4733
    return FALSE;
Igor Babaev's avatar
Igor Babaev committed
4734 4735

  Query_arena *arena= thd->stmt_arena, backup;
4736
  arena= thd->activate_stmt_arena_if_needed(&backup);
4737 4738 4739 4740 4741 4742 4743 4744 4745
  //It is used for DETETE/UPDATE so top level has only one SELECT
  DBUG_ASSERT(select_lex.next_select() == NULL);
  bool res= select_lex.save_prep_leaf_tables(thd);

  if (arena)
    thd->restore_active_arena(arena, &backup);

  if (res)
    return TRUE;
Igor Babaev's avatar
Igor Babaev committed
4746

4747 4748 4749
  thd->save_prep_leaf_list= FALSE;
  return FALSE;
}
Igor Babaev's avatar
Igor Babaev committed
4750

4751 4752 4753

bool st_select_lex::save_prep_leaf_tables(THD *thd)
{
Igor Babaev's avatar
Igor Babaev committed
4754 4755
  List_iterator_fast<TABLE_LIST> li(leaf_tables);
  TABLE_LIST *table;
4756 4757 4758 4759 4760 4761 4762 4763 4764 4765

  /*
    Check that the SELECT_LEX was really prepared and so tables are setup.

    It can be subquery in SET clause of UPDATE which was not prepared yet, so
    its tables are not yet setup and ready for storing.
  */
  if (prep_leaf_list_state != READY)
    return FALSE;

Igor Babaev's avatar
Igor Babaev committed
4766 4767 4768
  while ((table= li++))
  {
    if (leaf_tables_prep.push_back(table))
4769 4770
      return TRUE;
  }
4771
  prep_leaf_list_state= SAVED;
4772 4773 4774 4775 4776 4777 4778
  for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
  {
    for (SELECT_LEX *sl= u->first_select(); sl; sl= sl->next_select())
    {
      if (sl->save_prep_leaf_tables(thd))
        return TRUE;
    }
Igor Babaev's avatar
Igor Babaev committed
4779 4780
  }

4781
  return FALSE;
Igor Babaev's avatar
Igor Babaev committed
4782 4783 4784
}


4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813
/*
  Return true if this select_lex has been converted into a semi-join nest
  within 'ancestor'.

  We need a loop to check this because there could be several nested
  subselects, like

    SELECT ... FROM grand_parent 
      WHERE expr1 IN (SELECT ... FROM parent 
                        WHERE expr2 IN ( SELECT ... FROM child)

  which were converted into:
  
    SELECT ... 
    FROM grand_parent SEMI_JOIN (parent JOIN child) 
    WHERE 
      expr1 AND expr2

  In this case, both parent and child selects were merged into the parent.
*/

bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
{
  bool all_merged= TRUE;
  for (SELECT_LEX *sl= this; sl && sl!=ancestor;
       sl=sl->outer_select())
  {
    Item *subs= sl->master_unit()->item;
    if (subs && subs->type() == Item::SUBSELECT_ITEM && 
unknown's avatar
unknown committed
4814 4815
        ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
        ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
4816 4817 4818
    {
      continue;
    }
4819 4820 4821 4822 4823 4824

    if (sl->master_unit()->derived &&
      sl->master_unit()->derived->is_merged_derived())
    {
      continue;
    }
4825 4826 4827 4828 4829 4830
    all_merged= FALSE;
    break;
  }
  return all_merged;
}

4831 4832 4833 4834
/* 
  This is used by SHOW EXPLAIN. It assuses query plan has been already 
  collected into QPF structures and we only need to print it out.
*/
4835

Sergey Petrunya's avatar
Sergey Petrunya committed
4836
int LEX::print_explain(select_result_sink *output, uint8 explain_flags,
Sergei Petrunia's avatar
Sergei Petrunia committed
4837
                       bool is_analyze, bool *printed_anything)
4838
{
4839
  int res;
4840
  if (explain && explain->have_query_plan())
4841
  {
Sergei Petrunia's avatar
Sergei Petrunia committed
4842
    res= explain->print_explain(output, explain_flags, is_analyze);
4843
    *printed_anything= true;
4844 4845 4846
  }
  else
  {
4847 4848
    res= 0;
    *printed_anything= false;
4849
  }
4850
  return res;
4851 4852
}

4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871

/**
  Allocates and set arena for SET STATEMENT old values.

  @param backup          where to save backup of arena.

  @retval 1 Error
  @retval 0 OK
*/

bool LEX::set_arena_for_set_stmt(Query_arena *backup)
{
  DBUG_ENTER("LEX::set_arena_for_set_stmt");
  DBUG_ASSERT(arena_for_set_stmt== 0);
  if (!mem_root_for_set_stmt)
  {
    mem_root_for_set_stmt= new MEM_ROOT();
    if (!(mem_root_for_set_stmt))
      DBUG_RETURN(1);
4872 4873
    init_sql_alloc(mem_root_for_set_stmt, "set_stmt",
                   ALLOC_ROOT_SET, ALLOC_ROOT_SET, MYF(MY_THREAD_SPECIFIC));
4874 4875 4876 4877 4878
  }
  if (!(arena_for_set_stmt= new(mem_root_for_set_stmt)
        Query_arena_memroot(mem_root_for_set_stmt,
                            Query_arena::STMT_INITIALIZED)))
    DBUG_RETURN(1);
4879 4880 4881
  DBUG_PRINT("info", ("mem_root: %p  arena: %p",
                      mem_root_for_set_stmt,
                      arena_for_set_stmt));
4882 4883 4884 4885 4886 4887 4888 4889 4890 4891
  thd->set_n_backup_active_arena(arena_for_set_stmt, backup);
  DBUG_RETURN(0);
}


void LEX::reset_arena_for_set_stmt(Query_arena *backup)
{
  DBUG_ENTER("LEX::reset_arena_for_set_stmt");
  DBUG_ASSERT(arena_for_set_stmt);
  thd->restore_active_arena(arena_for_set_stmt, backup);
4892 4893 4894
  DBUG_PRINT("info", ("mem_root: %p  arena: %p",
                      arena_for_set_stmt->mem_root,
                      arena_for_set_stmt));
4895 4896 4897 4898 4899 4900 4901 4902 4903
  DBUG_VOID_RETURN;
}


void LEX::free_arena_for_set_stmt()
{
  DBUG_ENTER("LEX::free_arena_for_set_stmt");
  if (!arena_for_set_stmt)
    return;
4904 4905 4906
  DBUG_PRINT("info", ("mem_root: %p  arena: %p",
                      arena_for_set_stmt->mem_root,
                      arena_for_set_stmt));
4907 4908 4909 4910 4911 4912 4913
  arena_for_set_stmt->free_items();
  delete(arena_for_set_stmt);
  free_root(mem_root_for_set_stmt, MYF(MY_KEEP_PREALLOC));
  arena_for_set_stmt= 0;
  DBUG_VOID_RETURN;
}

4914 4915 4916 4917 4918 4919 4920 4921
void LEX::restore_set_statement_var()
{
  DBUG_ENTER("LEX::restore_set_statement_var");
  if (!old_var_list.is_empty())
  {
    DBUG_PRINT("info", ("vars: %d", old_var_list.elements));
    sql_set_variables(thd, &old_var_list, false);
    old_var_list.empty();
4922
    free_arena_for_set_stmt();
4923
  }
4924
  DBUG_ASSERT(!is_arena_for_set_stmt());
4925 4926
  DBUG_VOID_RETURN;
}
4927

4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963
unit_common_op st_select_lex_unit::common_op()
{
  SELECT_LEX *first= first_select();
  bool first_op= TRUE;
  unit_common_op operation= OP_MIX; // if no op
  for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
  {
    if (sl != first)
    {
      unit_common_op op;
      switch (sl->linkage)
      {
      case INTERSECT_TYPE:
        op= OP_INTERSECT;
        break;
      case EXCEPT_TYPE:
        op= OP_EXCEPT;
        break;
      default:
        op= OP_UNION;
        break;
      }
      if (first_op)
      {
        operation= op;
        first_op= FALSE;
      }
      else
      {
        if (operation != op)
          operation= OP_MIX;
      }
    }
  }
  return operation;
}
4964
/*
4965 4966
  Save explain structures of a UNION. The only variable member is whether the 
  union has "Using filesort".
Sergey Petrunya's avatar
Sergey Petrunya committed
4967

4968
  There is also save_union_explain_part2() function, which is called before we read
Sergey Petrunya's avatar
Sergey Petrunya committed
4969
  UNION's output.
Sergey Petrunya's avatar
Sergey Petrunya committed
4970

Sergey Petrunya's avatar
Sergey Petrunya committed
4971
  The reason for it is examples like this:
Sergey Petrunya's avatar
Sergey Petrunya committed
4972

Sergey Petrunya's avatar
Sergey Petrunya committed
4973 4974 4975 4976 4977 4978
     SELECT col1 FROM t1 UNION SELECT col2 FROM t2 ORDER BY (select ... from t3 ...)

  Here, the (select ... from t3 ...) subquery must be a child of UNION's
  st_select_lex. However, it is not connected as child until a very late 
  stage in execution.
*/
Sergey Petrunya's avatar
Sergey Petrunya committed
4979

4980
int st_select_lex_unit::save_union_explain(Explain_query *output)
4981 4982
{
  SELECT_LEX *first= first_select();
4983 4984 4985 4986

  if (output->get_union(first->select_number))
    return 0; /* Already added */
    
4987 4988 4989
  Explain_union *eu= 
    new (output->mem_root) Explain_union(output->mem_root, 
                                         thd->lex->analyze_stmt);
4990

4991 4992 4993
  if (with_element && with_element->is_recursive)
    eu->is_recursive_cte= true;
 
4994
  if (derived)
4995 4996 4997 4998 4999
    eu->connection_type= Explain_node::EXPLAIN_NODE_DERIVED;
  /* 
    Note: Non-merged semi-joins cannot be made out of UNIONs currently, so we
    dont ever set EXPLAIN_NODE_NON_MERGED_SJ.
  */
5000
  for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
5001
    eu->add_select(sl->select_number);
5002

5003
  eu->fake_select_type= unit_operation_text[eu->operation= common_op()];
5004 5005
  eu->using_filesort= MY_TEST(global_parameters()->order_list.first);
  eu->using_tmp= union_needs_tmp_table();
5006

Sergey Petrunya's avatar
Sergey Petrunya committed
5007
  // Save the UNION node
5008
  output->add_node(eu);
5009

5010 5011
  if (eu->get_select_id() == 1)
    output->query_plan_ready();
5012

5013 5014 5015 5016
  return 0;
}


5017 5018 5019 5020 5021
/*
  @see  st_select_lex_unit::save_union_explain
*/

int st_select_lex_unit::save_union_explain_part2(Explain_query *output)
5022
{
5023
  Explain_union *eu= output->get_union(first_select()->select_number);
5024
  if (fake_select_lex)
5025
  {
5026 5027 5028 5029 5030
    for (SELECT_LEX_UNIT *unit= fake_select_lex->first_inner_unit(); 
         unit; unit= unit->next_unit())
    {
      if (!(unit->item && unit->item->eliminated))
      {
5031
        eu->add_child(unit->first_select()->select_number);
5032 5033
      }
    }
5034
    fake_select_lex->join->explain= &eu->fake_select_lex_explain;
5035
  }
Sergey Petrunya's avatar
Sergey Petrunya committed
5036
  return 0;
5037 5038 5039
}


5040 5041 5042 5043 5044
/**
  A routine used by the parser to decide whether we are specifying a full
  partitioning or if only partitions to add or to split.

  @note  This needs to be outside of WITH_PARTITION_STORAGE_ENGINE since it
unknown's avatar
unknown committed
5045
  is used from the sql parser that doesn't have any ifdef's
5046 5047 5048 5049 5050

  @retval  TRUE    Yes, it is part of a management partition command
  @retval  FALSE          No, not a management partition command
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
5051
bool LEX::is_partition_management() const
5052 5053
{
  return (sql_command == SQLCOM_ALTER_TABLE &&
5054 5055
          (alter_info.partition_flags ==  ALTER_PARTITION_ADD ||
           alter_info.partition_flags ==  ALTER_PARTITION_REORGANIZE));
5056 5057
}

5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122

/**
  Exclude last added SELECT_LEX (current) in the UNIT and return pointer in it
  (previous become currect)

  @return detached SELECT_LEX or NULL in case of error
*/

SELECT_LEX *LEX::exclude_last_select()
{
  DBUG_ENTER("SELECT_LEX::exclude_last_select");
  SELECT_LEX *exclude= current_select;
  SELECT_LEX_UNIT *unit= exclude->master_unit();
  SELECT_LEX *sl;
  DBUG_ASSERT(unit->first_select() != exclude);
  /* we should go through the list to correctly set current_select */
  for(sl= unit->first_select();
      sl->next_select() && sl->next_select() != exclude;
      sl= sl->next_select());
  DBUG_PRINT("info", ("excl: %p  unit: %p  prev: %p", exclude, unit, sl));
  if (!sl)
    DBUG_RETURN(NULL);
  DBUG_ASSERT(exclude->next_select() == NULL);
  exclude->exclude_from_tree();
  current_select= sl;
  DBUG_RETURN(exclude);
}


/**
  Put given (new) SELECT_LEX level below after currect (last) SELECT

  LAST SELECT -> DUMMY SELECT
                     |
                     V
                 NEW UNIT
                     |
                     V
                 NEW SELECT

  SELECT (*LAST*) ... FROM (SELECT (*NEW*) ... )

  @param nselect         Select to put one level below

  @retval TRUE  Error
  @retval FALSE OK
*/

bool LEX::add_unit_in_brackets(SELECT_LEX *nselect)
{
  DBUG_ENTER("LEX::add_unit_in_brackets");
  bool distinct= nselect->master_unit()->union_distinct == nselect;
  bool rc= add_select_to_union_list(distinct, nselect->linkage, 0);
  if (rc)
    DBUG_RETURN(TRUE);
  SELECT_LEX* dummy_select= current_select;
  dummy_select->automatic_brackets= TRUE;
  dummy_select->linkage= nselect->linkage;

  /* stuff dummy SELECT * FROM (...) */
  Name_resolution_context *context= &dummy_select->context;
  context->init();

  /* add SELECT list*/
  Item *item= new (thd->mem_root)
5123
    Item_field(thd, context, NULL, NULL, &star_clex_str);
5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141
  if (item == NULL)
    DBUG_RETURN(TRUE);
  if (add_item_to_list(thd, item))
    DBUG_RETURN(TRUE);
  (dummy_select->with_wild)++;

  rc= mysql_new_select(this, 1, nselect);
  nselect->linkage= DERIVED_TABLE_TYPE;
  DBUG_ASSERT(nselect->outer_select() == dummy_select);

  current_select= dummy_select;
  current_select->nest_level--;

  SELECT_LEX_UNIT *unit= nselect->master_unit();
  Table_ident *ti= new (thd->mem_root) Table_ident(unit);
  if (ti == NULL)
    DBUG_RETURN(TRUE);
  char buff[10];
5142
  LEX_CSTRING alias;
5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184
  alias.length= my_snprintf(buff, sizeof(buff),
                            "__%u", dummy_select->select_number);
  alias.str= thd->strmake(buff, alias.length);
  if (!alias.str)
    DBUG_RETURN(TRUE);

  TABLE_LIST *table_list;
  if (!(table_list= dummy_select->add_table_to_list(thd, ti, &alias,
                                                    0, TL_READ,
                                                    MDL_SHARED_READ)))
    DBUG_RETURN(TRUE);
  context->resolve_in_table_list_only(table_list);
  dummy_select->add_joined_table(table_list);

  derived_tables|= DERIVED_SUBQUERY;

  current_select= nselect;
  current_select->nest_level++;
  DBUG_RETURN(rc);
}


/**
  Checks if we need finish "automatic brackets" mode

  INTERSECT has higher priority then UNION and EXCEPT, so when it is need we
  automatically create lower layer for INTERSECT (automatic brackets) and
  here we check if we should return back one level up during parsing procedure.
*/

void LEX::check_automatic_up(enum sub_select_type type)
{
  if (type != INTERSECT_TYPE &&
      current_select->linkage == INTERSECT_TYPE &&
      current_select->outer_select() &&
      current_select->outer_select()->automatic_brackets)
  {
    nest_level--;
    current_select= current_select->outer_select();
  }
}

5185

5186
sp_variable *LEX::sp_param_init(LEX_CSTRING *name)
5187 5188 5189
{
  if (spcont->find_variable(name, true))
  {
5190
    my_error(ER_SP_DUP_PARAM, MYF(0), name->str);
5191 5192 5193
    return NULL;
  }
  sp_variable *spvar= spcont->add_variable(thd, name);
5194
  init_last_field(&spvar->field_def, name,
5195 5196 5197 5198 5199 5200 5201
                  thd->variables.collation_database);
  return spvar;
}


bool LEX::sp_param_fill_definition(sp_variable *spvar)
{
5202
  return sphead->fill_spvar_definition(thd, last_field, &spvar->name);
5203 5204 5205
}


5206 5207 5208 5209 5210 5211 5212 5213 5214
void LEX::set_stmt_init()
{
  sql_command= SQLCOM_SET_OPTION;
  mysql_init_select(this);
  option_type= OPT_SESSION;
  autocommit= 0;
};


5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250
/**
  Find a local or a package body variable by name.
  @param IN  name    - the variable name
  @param OUT ctx     - NULL, if the variable was not found,
                       or LEX::spcont (if a local variable was found)
                       or the package top level context
                       (if a package variable was found)
  @param OUT handler - NULL, if the variable was not found,
                       or a pointer to rcontext handler
  @retval            - the variable (if found), or NULL otherwise.
*/
sp_variable *
LEX::find_variable(const LEX_CSTRING *name,
                   sp_pcontext **ctx,
                   const Sp_rcontext_handler **rh) const
{
  sp_variable *spv;
  if (spcont && (spv= spcont->find_variable(name, false)))
  {
    *ctx= spcont;
    *rh= &sp_rcontext_handler_local;
    return spv;
  }
  sp_package *pkg= sphead ? sphead->m_parent : NULL;
  if (pkg && (spv= pkg->find_package_variable(name)))
  {
    *ctx= pkg->get_parse_context()->child_context(0);
    *rh= &sp_rcontext_handler_package_body;
    return spv;
  }
  *ctx= NULL;
  *rh= NULL;
  return NULL;
}


5251
bool LEX::is_trigger_new_or_old_reference(const LEX_CSTRING *name) const
5252
{
5253
  return sphead && sphead->m_handler->type() == TYPE_ENUM_TRIGGER &&
5254 5255 5256
         name->length == 3 &&
         (!my_strcasecmp(system_charset_info, name->str, "NEW") ||
          !my_strcasecmp(system_charset_info, name->str, "OLD"));
5257 5258 5259
}


5260 5261
void LEX::sp_variable_declarations_init(THD *thd, int nvars)
{
5262
  sp_variable *spvar= spcont->get_last_context_variable();
5263 5264 5265

  sphead->reset_lex(thd);
  spcont->declare_var_boundary(nvars);
5266
  thd->lex->init_last_field(&spvar->field_def, &spvar->name,
5267 5268 5269
                            thd->variables.collation_database);
}

5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285

bool LEX::sp_variable_declarations_set_default(THD *thd, int nvars,
                                               Item *dflt_value_item)
{
  if (!dflt_value_item &&
      !(dflt_value_item= new (thd->mem_root) Item_null(thd)))
    return true;

  for (uint i= 0 ; i < (uint) nvars ; i++)
  {
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
    bool last= i + 1 == (uint) nvars;
    spvar->default_value= dflt_value_item;
    /* The last instruction is responsible for freeing LEX. */
    sp_instr_set *is= new (this->thd->mem_root)
                      sp_instr_set(sphead->instructions(),
5286 5287
                                   spcont, &sp_rcontext_handler_local,
                                   spvar->offset, dflt_value_item,
5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305
                                   this, last);
    if (is == NULL || sphead->add_instr(is))
      return true;
  }
  return false;
}


bool
LEX::sp_variable_declarations_copy_type_finalize(THD *thd, int nvars,
                                                 const Column_definition &ref,
                                                 Row_definition_list *fields,
                                                 Item *default_value)
{
  for (uint i= 0 ; i < (uint) nvars; i++)
  {
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
    spvar->field_def.set_type(ref);
5306 5307 5308 5309 5310
    if (fields)
    {
      DBUG_ASSERT(ref.type_handler() == &type_handler_row);
      spvar->field_def.set_row_field_definitions(fields);
    }
5311 5312 5313 5314 5315 5316 5317 5318 5319
    spvar->field_def.field_name= spvar->name;
  }
  if (sp_variable_declarations_set_default(thd, nvars, default_value))
    return true;
  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


5320
bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
5321
                                            const Column_definition *cdef,
5322 5323
                                            Item *dflt_value_item)
{
5324 5325 5326
  DBUG_ASSERT(cdef);
  Column_definition tmp(*cdef);
  if (sphead->fill_spvar_definition(thd, &tmp))
5327
    return true;
5328 5329 5330 5331
  return sp_variable_declarations_copy_type_finalize(thd, nvars, tmp, NULL,
                                                     dflt_value_item);
}

5332

5333 5334 5335 5336 5337
bool LEX::sp_variable_declarations_row_finalize(THD *thd, int nvars,
                                                Row_definition_list *row,
                                                Item *dflt_value_item)
{
  DBUG_ASSERT(row);
5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349
  /*
    Prepare all row fields.
    Note, we do it only one time outside of the below loop.
    The converted list in "row" is further reused by all variable
    declarations processed by the current call.
    Example:
      DECLARE
        a, b, c ROW(x VARCHAR(10) CHARACTER SET utf8);
      BEGIN
        ...
      END;
  */
5350
  if (sphead->row_fill_field_definitions(thd, row))
5351
    return true;
5352

5353
  for (uint i= 0 ; i < (uint) nvars ; i++)
5354
  {
5355
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
5356
    spvar->field_def.set_row_field_definitions(row);
5357
    if (sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name))
5358 5359 5360
      return true;
  }

5361 5362
  if (sp_variable_declarations_set_default(thd, nvars, dflt_value_item))
    return true;
5363 5364 5365 5366 5367
  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


5368 5369 5370 5371 5372 5373 5374 5375 5376
/**
  Finalize a %ROWTYPE declaration, e.g.:
    DECLARE a,b,c,d t1%ROWTYPE := ROW(1,2,3);

  @param thd   - the current thd
  @param nvars - the number of variables in the declaration
  @param ref   - the table or cursor name (see comments below)
  @param def   - the default value, e.g., ROW(1,2,3), or NULL (no default).
*/
5377 5378 5379 5380 5381
bool
LEX::sp_variable_declarations_rowtype_finalize(THD *thd, int nvars,
                                               Qualified_column_ident *ref,
                                               Item *def)
{
5382 5383
  uint coffp;
  const sp_pcursor *pcursor= ref->table.str && ref->db.str ? NULL :
5384 5385
                             spcont->find_cursor(&ref->m_column, &coffp,
                                                 false);
5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405
  if (pcursor)
    return sp_variable_declarations_cursor_rowtype_finalize(thd, nvars,
                                                            coffp, def);
  /*
    When parsing a qualified identifier chain, the parser does not know yet
    if it's going to be a qualified column name (for %TYPE),
    or a qualified table name (for %ROWTYPE). So it collects the chain
    into Qualified_column_ident.
    Now we know that it was actually a qualified table name (%ROWTYPE).
    Create a new Table_ident from Qualified_column_ident,
    shifting fields as follows:
    - ref->m_column becomes table_ref->table
    - ref->table    becomes table_ref->db
  */
  return sp_variable_declarations_table_rowtype_finalize(thd, nvars,
                                                         ref->table,
                                                         ref->m_column,
                                                         def);
}

5406

5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423
bool
LEX::sp_variable_declarations_table_rowtype_finalize(THD *thd, int nvars,
                                                     const LEX_CSTRING &db,
                                                     const LEX_CSTRING &table,
                                                     Item *def)
{
  Table_ident *table_ref;
  if (!(table_ref= new (thd->mem_root) Table_ident(thd, &db, &table, false)))
    return true;
  // Loop through all variables in the same declaration
  for (uint i= 0 ; i < (uint) nvars; i++)
  {
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
    spvar->field_def.set_table_rowtype_ref(table_ref);
    sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name);
  }
  if (sp_variable_declarations_set_default(thd, nvars, def))
5424
    return true;
5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437
  // Make sure sp_rcontext is created using the invoker security context:
  sphead->m_flags|= sp_head::HAS_COLUMN_TYPE_REFS;
  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


bool
LEX::sp_variable_declarations_cursor_rowtype_finalize(THD *thd, int nvars,
                                                      uint offset,
                                                      Item *def)
{
  const sp_pcursor *pcursor= spcont->find_cursor(offset);
5438

5439
  // Loop through all variables in the same declaration
5440
  for (uint i= 0 ; i < (uint) nvars; i++)
5441
  {
5442
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
5443

5444
    spvar->field_def.set_cursor_rowtype_ref(offset);
5445 5446 5447 5448 5449 5450 5451
    sp_instr_cursor_copy_struct *instr=
      new (thd->mem_root) sp_instr_cursor_copy_struct(sphead->instructions(),
                                                      spcont, pcursor->lex(),
                                                      spvar->offset);
    if (instr == NULL || sphead->add_instr(instr))
     return true;

5452
    sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name);
5453
  }
5454 5455
  if (sp_variable_declarations_set_default(thd, nvars, def))
    return true;
5456 5457 5458 5459 5460 5461 5462
  // Make sure sp_rcontext is created using the invoker security context:
  sphead->m_flags|= sp_head::HAS_COLUMN_TYPE_REFS;
  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


5463 5464 5465 5466 5467 5468
/*
  Add declarations for table column and SP variable anchor types:
  - DECLARE spvar1 TYPE OF db1.table1.column1;
  - DECLARE spvar1 TYPE OF table1.column1;
  - DECLARE spvar1 TYPE OF spvar0;
*/
5469 5470 5471 5472
bool
LEX::sp_variable_declarations_with_ref_finalize(THD *thd, int nvars,
                                                Qualified_column_ident *ref,
                                                Item *def)
5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483
{
  return ref->db.length == 0 && ref->table.length == 0 ?
    sp_variable_declarations_vartype_finalize(thd, nvars, ref->m_column, def) :
    sp_variable_declarations_column_type_finalize(thd, nvars, ref, def);
}


bool
LEX::sp_variable_declarations_column_type_finalize(THD *thd, int nvars,
                                                   Qualified_column_ident *ref,
                                                   Item *def)
5484
{
5485
  for (uint i= 0 ; i < (uint) nvars; i++)
5486
  {
5487
    sp_variable *spvar= spcont->get_last_context_variable((uint) nvars - 1 - i);
5488
    spvar->field_def.set_column_type_ref(ref);
5489
    spvar->field_def.field_name= spvar->name;
5490 5491
  }
  sphead->m_flags|= sp_head::HAS_COLUMN_TYPE_REFS;
5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540
  if (sp_variable_declarations_set_default(thd, nvars, def))
    return true;
  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


bool
LEX::sp_variable_declarations_vartype_finalize(THD *thd, int nvars,
                                               const LEX_CSTRING &ref,
                                               Item *default_value)
{
  sp_variable *t;
  if (!spcont || !(t= spcont->find_variable(&ref, false)))
  {
    my_error(ER_SP_UNDECLARED_VAR, MYF(0), ref.str);
    return true;
  }

  if (t->field_def.is_cursor_rowtype_ref())
  {
    uint offset= t->field_def.cursor_rowtype_offset();
    return sp_variable_declarations_cursor_rowtype_finalize(thd, nvars,
                                                            offset,
                                                            default_value);
  }

  if (t->field_def.is_column_type_ref())
  {
    Qualified_column_ident *tmp= t->field_def.column_type_ref();
    return sp_variable_declarations_column_type_finalize(thd, nvars, tmp,
                                                         default_value);
  }

  if (t->field_def.is_table_rowtype_ref())
  {
    const Table_ident *tmp= t->field_def.table_rowtype_ref();
    return sp_variable_declarations_table_rowtype_finalize(thd, nvars,
                                                           tmp->db,
                                                           tmp->table,
                                                           default_value);
  }

  // A reference to a scalar or a row variable with an explicit data type
  return sp_variable_declarations_copy_type_finalize(thd, nvars,
                                                     t->field_def,
                                                     t->field_def.
                                                       row_field_definitions(),
                                                     default_value);
5541 5542 5543
}


5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567
/**********************************************************************
  The FOR LOOP statement

  This syntax:
    FOR i IN lower_bound .. upper_bound
    LOOP
      statements;
    END LOOP;

  is translated into:

    DECLARE
      i INT := lower_bound;
      j INT := upper_bound;
    BEGIN
      WHILE i <= j
      LOOP
        statements;
        i:= i + 1;
      END LOOP;
    END;
*/


5568
sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name,
5569 5570 5571 5572
                                           Item *value)
{
  sp_variable *spvar= spcont->add_variable(thd, name);
  spcont->declare_var_boundary(1);
5573
  spvar->field_def.field_name= spvar->name;
5574
  spvar->field_def.set_handler(&type_handler_longlong);
5575 5576
  type_handler_longlong.Column_definition_prepare_stage2(&spvar->field_def,
                                                         NULL, HA_CAN_GEOMETRY);
5577 5578 5579 5580 5581 5582
  if (!value && !(value= new (thd->mem_root) Item_null(thd)))
    return NULL;

  spvar->default_value= value;
  sp_instr_set *is= new (this->thd->mem_root)
                    sp_instr_set(sphead->instructions(),
5583 5584
                                 spcont, &sp_rcontext_handler_local,
                                 spvar->offset, value,
5585 5586
                                 this, true);
  if (is == NULL || sphead->add_instr(is))
5587
    return NULL;
5588 5589 5590 5591 5592
  spcont->declare_var_boundary(0);
  return spvar;
}


5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621
bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd,
                                                Lex_for_loop_bounds_st *bounds,
                                                sp_lex_cursor *cur)
{
  Item *item;
  DBUG_ASSERT(sphead);
  LEX_CSTRING name= {STRING_WITH_LEN("[implicit_cursor]") };
  if (sp_declare_cursor(thd, &name, cur, NULL, true))
    return true;
  DBUG_ASSERT(thd->lex == this);
  if (!(bounds->m_index= new (thd->mem_root) sp_assignment_lex(thd, this)))
    return true;
  bounds->m_index->sp_lex_in_use= true;
  sphead->reset_lex(thd, bounds->m_index);
  DBUG_ASSERT(thd->lex != this);
  if (!(item= new (thd->mem_root) Item_field(thd,
                                             thd->lex->current_context(),
                                             NullS, NullS, &name)))
    return true;
  bounds->m_index->set_item_and_free_list(item, NULL);
  if (thd->lex->sphead->restore_lex(thd))
    return true;
  DBUG_ASSERT(thd->lex == this);
  bounds->m_direction= 1;
  bounds->m_upper_bound= NULL;
  bounds->m_implicit_cursor= true;
  return false;
}

5622 5623
sp_variable *
LEX::sp_add_for_loop_cursor_variable(THD *thd,
5624
                                     const LEX_CSTRING *name,
5625
                                     const sp_pcursor *pcursor,
5626 5627 5628
                                     uint coffset,
                                     sp_assignment_lex *param_lex,
                                     Item_args *parameters)
5629 5630
{
  sp_variable *spvar= spcont->add_variable(thd, name);
5631 5632
  if (!spvar)
    return NULL;
5633
  spcont->declare_var_boundary(1);
5634
  sphead->fill_spvar_definition(thd, &spvar->field_def, &spvar->name);
5635 5636
  if (!(spvar->default_value= new (thd->mem_root) Item_null(thd)))
    return NULL;
5637

5638
  spvar->field_def.set_cursor_rowtype_ref(coffset);
5639

5640 5641
  if (sphead->add_for_loop_open_cursor(thd, spcont, spvar, pcursor, coffset,
                                       param_lex, parameters))
5642 5643 5644
    return NULL;

  spcont->declare_var_boundary(0);
5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661
  return spvar;
}


/**
  Generate a code for a FOR loop condition:
  - Make Item_splocal for the FOR loop index variable
  - Make Item_splocal for the FOR loop upper bound variable
  - Make a comparison function item on top of these two variables
*/
bool LEX::sp_for_loop_condition(THD *thd, const Lex_for_loop_st &loop)
{
  Item_splocal *args[2];
  for (uint i= 0 ; i < 2; i++)
  {
    sp_variable *src= i == 0 ? loop.m_index : loop.m_upper_bound;
    args[i]= new (thd->mem_root)
5662 5663
              Item_splocal(thd, &sp_rcontext_handler_local,
                           &src->name, src->offset, src->type_handler());
5664 5665
    if (args[i] == NULL)
      return true;
5666
#ifdef DBUG_ASSERT_EXISTS
5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680
    args[i]->m_sp= sphead;
#endif
  }

  Item *expr= loop.m_direction > 0 ?
    (Item *) new (thd->mem_root) Item_func_le(thd, args[0], args[1]) :
    (Item *) new (thd->mem_root) Item_func_ge(thd, args[0], args[1]);
  return !expr || sp_while_loop_expression(thd, expr);
}


/**
  Generate the FOR LOOP condition code in its own lex
*/
5681 5682
bool LEX::sp_for_loop_intrange_condition_test(THD *thd,
                                              const Lex_for_loop_st &loop)
5683
{
5684
  spcont->set_for_loop(loop);
5685 5686 5687 5688 5689 5690 5691
  sphead->reset_lex(thd);
  if (thd->lex->sp_for_loop_condition(thd, loop))
    return true;
  return thd->lex->sphead->restore_lex(thd);
}


5692 5693 5694
bool LEX::sp_for_loop_cursor_condition_test(THD *thd,
                                            const Lex_for_loop_st &loop)
{
5695
  const LEX_CSTRING *cursor_name;
5696
  Item *expr;
5697 5698
  spcont->set_for_loop(loop);
  sphead->reset_lex(thd);
5699 5700
  cursor_name= spcont->find_cursor(loop.m_cursor_offset);
  DBUG_ASSERT(cursor_name);
5701
  if (!(expr= new (thd->mem_root) Item_func_cursor_found(thd, cursor_name,
5702 5703
                                                         loop.m_cursor_offset)))
    return true;
5704 5705 5706 5707 5708 5709 5710
  if (thd->lex->sp_while_loop_expression(thd, expr))
    return true;
  return thd->lex->sphead->restore_lex(thd);
}


bool LEX::sp_for_loop_intrange_declarations(THD *thd, Lex_for_loop_st *loop,
5711
                                            const LEX_CSTRING *index,
5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729
                                            const Lex_for_loop_bounds_st &bounds)
{
  if (!(loop->m_index=
        bounds.m_index->sp_add_for_loop_variable(thd, index,
                                                 bounds.m_index->get_item())))
    return true;
  if (!(loop->m_upper_bound=
        bounds.m_upper_bound->sp_add_for_loop_upper_bound(thd,
                                           bounds.m_upper_bound->get_item())))
     return true;
  loop->m_direction= bounds.m_direction;
  loop->m_implicit_cursor= 0;
  return false;
}


bool LEX::sp_for_loop_cursor_declarations(THD *thd,
                                          Lex_for_loop_st *loop,
5730
                                          const LEX_CSTRING *index,
5731 5732 5733 5734 5735
                                          const Lex_for_loop_bounds_st &bounds)
{
  Item *item= bounds.m_index->get_item();
  Item_splocal *item_splocal;
  Item_field *item_field;
5736
  Item_func_sp *item_func_sp= NULL;
5737
  LEX_CSTRING name;
5738
  uint coffs, param_count= 0;
5739 5740 5741 5742 5743 5744 5745
  const sp_pcursor *pcursor;

  if ((item_splocal= item->get_item_splocal()))
    name= item_splocal->m_name;
  else if ((item_field= item->type() == Item::FIELD_ITEM ?
                        static_cast<Item_field *>(item) : NULL) &&
           item_field->table_name == NULL)
5746
    name= item_field->field_name;
5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767
  else if (item->type() == Item::FUNC_ITEM &&
           static_cast<Item_func*>(item)->functype() == Item_func::FUNC_SP &&
           !static_cast<Item_func_sp*>(item)->get_sp_name()->m_explicit_name)
  {
    /*
      When a FOR LOOP for a cursor with parameters is parsed:
        FOR index IN cursor(1,2,3) LOOP
          statements;
        END LOOP;
      the parser scans "cursor(1,2,3)" using the "expr" rule,
      so it thinks that cursor(1,2,3) is a stored function call.
      It's not easy to implement this without using "expr" because
      of grammar conflicts.
      As a side effect, the Item_func_sp and its arguments in the parentheses
      belong to the same LEX. This is different from an explicit
      "OPEN cursor(1,2,3)" where every expression belongs to a separate LEX.
    */
    item_func_sp= static_cast<Item_func_sp*>(item);
    name= item_func_sp->get_sp_name()->m_name;
    param_count= item_func_sp->argument_count();
  }
5768 5769 5770 5771 5772
  else
  {
    thd->parse_error();
    return true;
  }
5773
  if (!(pcursor= spcont->find_cursor_with_error(&name, &coffs, false)) ||
5774
      pcursor->check_param_count_with_error(param_count))
5775 5776 5777
    return true;

  if (!(loop->m_index= sp_add_for_loop_cursor_variable(thd, index,
5778 5779 5780
                                                       pcursor, coffs,
                                                       bounds.m_index,
                                                       item_func_sp)))
5781 5782 5783 5784 5785 5786 5787 5788 5789
    return true;
  loop->m_upper_bound= NULL;
  loop->m_direction= bounds.m_direction;
  loop->m_cursor_offset= coffs;
  loop->m_implicit_cursor= bounds.m_implicit_cursor;
  return false;
}


5790 5791 5792 5793 5794 5795
/**
  Generate a code for a FOR loop index increment
*/
bool LEX::sp_for_loop_increment(THD *thd, const Lex_for_loop_st &loop)
{
  Item_splocal *splocal= new (thd->mem_root)
5796 5797
    Item_splocal(thd, &sp_rcontext_handler_local,
                      &loop.m_index->name, loop.m_index->offset,
5798
                      loop.m_index->type_handler());
5799 5800
  if (splocal == NULL)
    return true;
5801
#ifdef DBUG_ASSERT_EXISTS
5802 5803 5804 5805 5806 5807
  splocal->m_sp= sphead;
#endif
  Item_int *inc= new (thd->mem_root) Item_int(thd, loop.m_direction);
  if (!inc)
    return true;
  Item *expr= new (thd->mem_root) Item_func_plus(thd, splocal, inc);
5808
  if (!expr ||
5809 5810
      sphead->set_local_variable(thd, spcont, &sp_rcontext_handler_local,
                                 loop.m_index, expr, this, true))
5811 5812 5813 5814 5815
    return true;
  return false;
}


5816
bool LEX::sp_for_loop_intrange_finalize(THD *thd, const Lex_for_loop_st &loop)
5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831
{
  sphead->reset_lex(thd);

  // Generate FOR LOOP index increment in its own lex
  DBUG_ASSERT(this != thd->lex);
  if (thd->lex->sp_for_loop_increment(thd, loop) ||
      thd->lex->sphead->restore_lex(thd))
    return true;

  // Generate a jump to the beginning of the loop
  DBUG_ASSERT(this == thd->lex);
  return sp_while_loop_finalize(thd);
}


5832 5833 5834 5835
bool LEX::sp_for_loop_cursor_finalize(THD *thd, const Lex_for_loop_st &loop)
{
  sp_instr_cfetch *instr=
    new (thd->mem_root) sp_instr_cfetch(sphead->instructions(),
5836
                                        spcont, loop.m_cursor_offset, false);
5837 5838 5839 5840 5841 5842 5843
  if (instr == NULL || sphead->add_instr(instr))
    return true;
  instr->add_to_varlist(loop.m_index);
  // Generate a jump to the beginning of the loop
  return sp_while_loop_finalize(thd);
}

5844 5845
/***************************************************************************/

5846
bool LEX::sp_declare_cursor(THD *thd, const LEX_CSTRING *name,
5847
                            sp_lex_cursor *cursor_stmt,
5848
                            sp_pcontext *param_ctx, bool add_cpush_instr)
5849 5850 5851 5852 5853 5854
{
  uint offp;
  sp_instr_cpush *i;

  if (spcont->find_cursor(name, &offp, true))
  {
5855
    my_error(ER_SP_DUP_CURS, MYF(0), name->str);
5856 5857
    return true;
  }
5858
  cursor_stmt->set_cursor_name(name);
5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870

  if (spcont->add_cursor(name, param_ctx, cursor_stmt))
    return true;

  if (add_cpush_instr)
  {
    i= new (thd->mem_root)
         sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
                        spcont->current_cursor_count() - 1);
    return i == NULL || sphead->add_instr(i);
  }
  return false;
5871 5872 5873 5874 5875 5876 5877 5878 5879 5880
}


/**
  Generate an SP code for an "OPEN cursor_name" statement.
  @param thd
  @param name       - Name of the cursor
  @param parameters - Cursor parameters, e.g. OPEN c(1,2,3)
  @returns          - false on success, true on error
*/
5881
bool LEX::sp_open_cursor(THD *thd, const LEX_CSTRING *name,
5882 5883 5884 5885
                         List<sp_assignment_lex> *parameters)
{
  uint offset;
  const sp_pcursor *pcursor;
5886 5887 5888 5889
  uint param_count= parameters ? parameters->elements : 0;
  return !(pcursor= spcont->find_cursor_with_error(name, &offset, false)) ||
         pcursor->check_param_count_with_error(param_count) ||
         sphead->add_open_cursor(thd, spcont, offset,
5890
                                 pcursor->param_context(), parameters);
5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910
}


bool LEX::sp_handler_declaration_init(THD *thd, int type)
{
  sp_handler *h= spcont->add_handler(thd, (sp_handler::enum_type) type);

  spcont= spcont->push_context(thd, sp_pcontext::HANDLER_SCOPE);

  sp_instr_hpush_jump *i=
    new (thd->mem_root) sp_instr_hpush_jump(sphead->instructions(), spcont, h);

  if (i == NULL || sphead->add_instr(i))
    return true;

  /* For continue handlers, mark end of handler scope. */
  if (type == sp_handler::CONTINUE &&
      sphead->push_backpatch(thd, i, spcont->last_label()))
    return true;

5911
  if (sphead->push_backpatch(thd, i, spcont->push_label(thd, &empty_clex_str, 0)))
5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941
    return true;

  return false;
}


bool LEX::sp_handler_declaration_finalize(THD *thd, int type)
{
  sp_label *hlab= spcont->pop_label(); /* After this hdlr */
  sp_instr_hreturn *i;

  if (type == sp_handler::CONTINUE)
  {
    i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
    if (i == NULL ||
        sphead->add_instr(i))
      return true;
  }
  else
  {  /* EXIT or UNDO handler, just jump to the end of the block */
    i= new (thd->mem_root) sp_instr_hreturn(sphead->instructions(), spcont);
    if (i == NULL ||
        sphead->add_instr(i) ||
        sphead->push_backpatch(thd, i, spcont->last_label())) /* Block end */
      return true;
  }
  sphead->backpatch(hlab);
  spcont= spcont->pop_context();
  return false;
}
5942

5943

5944
void LEX::sp_block_init(THD *thd, const LEX_CSTRING *label)
5945
{
5946
  spcont->push_label(thd, label, sphead->instructions(), sp_label::BEGIN);
5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981
  spcont= spcont->push_context(thd, sp_pcontext::REGULAR_SCOPE);
}


bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
                                      class sp_label **splabel)
{
  sp_head *sp= sphead;
  sp_pcontext *ctx= spcont;
  sp_instr *i;

  sp->backpatch(ctx->last_label()); /* We always have a label */
  if (spblock.hndlrs)
  {
    i= new (thd->mem_root)
      sp_instr_hpop(sp->instructions(), ctx, spblock.hndlrs);
    if (i == NULL ||
        sp->add_instr(i))
      return true;
  }
  if (spblock.curs)
  {
    i= new (thd->mem_root)
      sp_instr_cpop(sp->instructions(), ctx, spblock.curs);
    if (i == NULL ||
        sp->add_instr(i))
      return true;
  }
  spcont= ctx->pop_context();
  *splabel= spcont->pop_label();
  return false;
}


bool LEX::sp_block_finalize(THD *thd, const Lex_spblock_st spblock,
5982
                            const LEX_CSTRING *end_label)
5983 5984 5985 5986
{
  sp_label *splabel;
  if (sp_block_finalize(thd, spblock, &splabel))
    return true;
5987
  if (end_label->str &&
5988 5989
      lex_string_cmp(system_charset_info,
                     end_label, &splabel->name) != 0)
5990
  {
5991
    my_error(ER_SP_LABEL_MISMATCH, MYF(0), end_label->str);
5992 5993 5994 5995 5996 5997
    return true;
  }
  return false;
}


5998
sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name)
5999 6000
{
  sp_name *res;
6001 6002
  LEX_CSTRING db;
  if (check_routine_name(name) ||
6003
      copy_db_to(&db) ||
6004
      (!(res= new (thd->mem_root) sp_name(&db, name, false))))
6005 6006 6007 6008 6009
    return NULL;
  return res;
}


6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034
/**
  When a package routine name is stored in memory in Database_qualified_name,
  the dot character is used to delimit package name from the routine name,
  e.g.:
    m_db=   'test';   -- database 'test'
    m_name= 'p1.p1';  -- package 'p1', routine 'p1'
  See database_qualified_name::make_package_routine_name() for details.
  Disallow package routine names with dots,
  to avoid ambiguity when interpreting m_name='p1.p1.p1', between:
    a.  package 'p1.p1' + routine 'p1'
    b.  package 'p1'    + routine 'p1.p1'
  m_name='p1.p1.p1' will always mean (a).
*/
sp_name *LEX::make_sp_name_package_routine(THD *thd, const LEX_CSTRING *name)
{
  sp_name *res= make_sp_name(thd, name);
  if (res && strchr(res->m_name.str, '.'))
  {
    my_error(ER_SP_WRONG_NAME, MYF(0), res->m_name.str);
    res= NULL;
  }
  return res;
}


6035 6036
sp_name *LEX::make_sp_name(THD *thd, const LEX_CSTRING *name1,
                                     const LEX_CSTRING *name2)
6037 6038
{
  sp_name *res;
6039 6040 6041 6042
  LEX_CSTRING norm_name1;
  if (!name1->str ||
      !thd->make_lex_string(&norm_name1, name1->str, name1->length) ||
      check_db_name((LEX_STRING *) &norm_name1))
6043
  {
6044
    my_error(ER_WRONG_DB_NAME, MYF(0), name1->str);
6045 6046
    return NULL;
  }
6047
  if (check_routine_name(name2) ||
6048
      (!(res= new (thd->mem_root) sp_name(&norm_name1, name2, true))))
6049 6050 6051 6052 6053
    return NULL;
  return res;
}


6054 6055
sp_head *LEX::make_sp_head(THD *thd, const sp_name *name,
                           const Sp_handler *sph)
6056
{
6057
  sp_package *package= get_sp_package();
6058 6059 6060
  sp_head *sp;

  /* Order is important here: new - reset - init */
6061
  if ((sp= new sp_head(package, sph)))
6062 6063 6064 6065
  {
    sp->reset_thd_mem_root(thd);
    sp->init(this);
    if (name)
6066 6067 6068 6069 6070 6071 6072 6073 6074 6075
    {
      if (package)
        sp->make_package_routine_name(sp->get_main_mem_root(),
                                      package->m_db,
                                      package->m_name,
                                      name->m_name);
      else
        sp->init_sp_name(name);
      sp->make_qname(sp->get_main_mem_root(), &sp->m_qname);
    }
6076 6077
    sphead= sp;
  }
6078
  sp_chistics.init();
6079 6080 6081 6082
  return sp;
}


6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107
sp_head *LEX::make_sp_head_no_recursive(THD *thd, const sp_name *name,
                                        const Sp_handler *sph)
{
  sp_package *package= thd->lex->get_sp_package();
  /*
    Sp_handler::sp_clone_and_link_routine() generates a standalone-alike
    statement to clone package routines for recursion, e.g.:
      CREATE PROCEDURE p1 AS BEGIN NULL; END;
    Translate a standalone routine handler to the corresponding
    package routine handler if we're cloning a package routine, e.g.:
      sp_handler_procedure -> sp_handler_package_procedure
      sp_handler_function  -> sp_handler_package_function
  */
  if (package && package->m_is_cloning_routine)
    sph= sph->package_routine_handler();
  if (!sphead ||
      (package &&
       (sph == &sp_handler_package_procedure ||
        sph == &sp_handler_package_function)))
    return make_sp_head(thd, name, sph);
  my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), sph->type_str());
  return NULL;
}


6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133
bool LEX::sp_body_finalize_procedure(THD *thd)
{
  if (sphead->check_unresolved_goto())
    return true;
  sphead->set_stmt_end(thd);
  sphead->restore_thd_mem_root(thd);
  return false;
}


bool LEX::sp_body_finalize_function(THD *thd)
{
  if (sphead->is_not_allowed_in_function("function"))
    return true;
  if (!(sphead->m_flags & sp_head::HAS_RETURN))
  {
    my_error(ER_SP_NORETURN, MYF(0), ErrConvDQName(sphead).ptr());
    return true;
  }
  if (sp_body_finalize_procedure(thd))
    return true;
  (void) is_native_function_with_warn(thd, &sphead->m_name);
  return false;
}


6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150
bool LEX::sp_block_with_exceptions_finalize_declarations(THD *thd)
{
  /*
    [ DECLARE declarations ]
    BEGIN executable_section
    [ EXCEPTION exceptions ]
    END

    We are now at the "BEGIN" keyword.
    We have collected all declarations, including DECLARE HANDLER directives.
    But there will be possibly more handlers in the EXCEPTION section.

    Generate a forward jump from the end of the DECLARE section to the
    beginning of the EXCEPTION section, over the executable section.
  */
  return sphead->add_instr_jump(thd, spcont);
}
6151 6152


6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175
bool
LEX::sp_block_with_exceptions_finalize_executable_section(THD *thd,
                                         uint executable_section_ip)
{
  /*
    We're now at the end of "executable_section" of the block,
    near the "EXCEPTION" or the "END" keyword.
    Generate a jump to the END of the block over the EXCEPTION section.
  */
  if (sphead->add_instr_jump_forward_with_backpatch(thd, spcont))
    return true;
  /*
    Set the destination for the jump that we added in
    sp_block_with_exceptions_finalize_declarations().
  */
  sp_instr *instr= sphead->get_instr(executable_section_ip - 1);
  instr->backpatch(sphead->instructions(), spcont);
  return false;
}


bool
LEX::sp_block_with_exceptions_finalize_exceptions(THD *thd,
6176 6177
                                                  uint executable_section_ip,
                                                  uint exception_count)
6178
{
6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189
  if (!exception_count)
  {
    /*
      The jump from the end of DECLARE section to
      the beginning of the EXCEPTION section that we added in
      sp_block_with_exceptions_finalize_declarations() is useless
      if there were no exceptions.
      Replace it to "no operation".
    */
    return sphead->replace_instr_to_nop(thd, executable_section_ip - 1);
  }
6190 6191 6192 6193 6194 6195 6196
  /*
    Generate a jump from the end of the EXCEPTION code
    to the executable section.
  */
  return sphead->add_instr_jump(thd, spcont, executable_section_ip);
}

6197

6198 6199 6200 6201 6202 6203 6204 6205
bool LEX::sp_block_with_exceptions_add_empty(THD *thd)
{
  uint ip= sphead->instructions();
  return sp_block_with_exceptions_finalize_executable_section(thd, ip) ||
         sp_block_with_exceptions_finalize_exceptions(thd, ip, 0);
}


6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225
bool LEX::sp_change_context(THD *thd, const sp_pcontext *ctx, bool exclusive)
{
  uint n;
  uint ip= sphead->instructions();
  if ((n= spcont->diff_handlers(ctx, exclusive)))
  {
    sp_instr_hpop *hpop= new (thd->mem_root) sp_instr_hpop(ip++, spcont, n);
    if (hpop == NULL || sphead->add_instr(hpop))
      return true;
  }
  if ((n= spcont->diff_cursors(ctx, exclusive)))
  {
    sp_instr_cpop *cpop= new (thd->mem_root) sp_instr_cpop(ip++, spcont, n);
    if (cpop == NULL || sphead->add_instr(cpop))
      return true;
  }
  return false;
}


6226
bool LEX::sp_leave_statement(THD *thd, const LEX_CSTRING *label_name)
6227 6228 6229 6230
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab)
  {
6231
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", label_name->str);
6232 6233
    return true;
  }
6234
  return sp_exit_block(thd, lab, NULL);
6235 6236
}

6237
bool LEX::sp_goto_statement(THD *thd, const LEX_CSTRING *label_name)
halfspawn's avatar
halfspawn committed
6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263
{
  sp_label *lab= spcont->find_goto_label(label_name);
  if (!lab || lab->ip == 0)
  {
    sp_label *delayedlabel;
    if (!lab)
    {
      // Label not found --> add forward jump to an unknown label
      spcont->push_goto_label(thd, label_name, 0, sp_label::GOTO);
      delayedlabel= spcont->last_goto_label();
    }
    else
    {
      delayedlabel= lab;
    }
    return sphead->push_backpatch_goto(thd, spcont, delayedlabel);
  }
  else
  {
    // Label found (backward goto)
    return sp_change_context(thd, lab->ctx, false) ||
           sphead->add_instr_jump(thd, spcont, lab->ip); /* Jump back */
  }
  return false;
}

6264
bool LEX::sp_push_goto_label(THD *thd, const LEX_CSTRING *label_name)
halfspawn's avatar
halfspawn committed
6265 6266 6267 6268 6269 6270
{
  sp_label *lab= spcont->find_goto_label(label_name, false);
  if (lab)
  {
    if  (lab->ip != 0)
    {
6271
      my_error(ER_SP_LABEL_REDEFINE, MYF(0), label_name->str);
halfspawn's avatar
halfspawn committed
6272 6273 6274 6275
      return true;
    }
    lab->ip= sphead->instructions();

6276
    sp_label *beginblocklabel= spcont->find_label(&empty_clex_str);
halfspawn's avatar
halfspawn committed
6277 6278 6279 6280 6281 6282 6283 6284
    sphead->backpatch_goto(thd, lab, beginblocklabel);
  }
  else
  {
    spcont->push_goto_label(thd, label_name, sphead->instructions());
  }
  return false;
}
6285

6286 6287
bool LEX::sp_exit_block(THD *thd, sp_label *lab)
{
6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301
  /*
    When jumping to a BEGIN-END block end, the target jump
    points to the block hpop/cpop cleanup instructions,
    so we should exclude the block context here.
    When jumping to something else (i.e., SP_LAB_ITER),
    there are no hpop/cpop at the jump destination,
    so we should include the block context here for cleanup.
  */
  bool exclusive= (lab->type == sp_label::BEGIN);
  return sp_change_context(thd, lab->ctx, exclusive) ||
         sphead->add_instr_jump_forward_with_backpatch(thd, spcont, lab);
}


6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322
bool LEX::sp_exit_block(THD *thd, sp_label *lab, Item *when)
{
  if (!when)
    return sp_exit_block(thd, lab);

  DBUG_ASSERT(sphead == thd->lex->sphead);
  DBUG_ASSERT(spcont == thd->lex->spcont);
  sp_instr_jump_if_not *i= new (thd->mem_root)
                           sp_instr_jump_if_not(sphead->instructions(),
                                                spcont,
                                                when, thd->lex);
  if (i == NULL ||
      sphead->add_instr(i) ||
      sp_exit_block(thd, lab))
    return true;
  i->backpatch(sphead->instructions(), spcont);
  return false;
}


bool LEX::sp_exit_statement(THD *thd, Item *item)
6323 6324 6325 6326 6327 6328 6329 6330
{
  sp_label *lab= spcont->find_label_current_loop_start();
  if (!lab)
  {
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "EXIT", "");
    return true;
  }
  DBUG_ASSERT(lab->type == sp_label::ITERATION);
6331
  return sp_exit_block(thd, lab, item);
6332 6333 6334
}


6335
bool LEX::sp_exit_statement(THD *thd, const LEX_CSTRING *label_name, Item *item)
6336 6337 6338 6339
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab || lab->type != sp_label::ITERATION)
  {
6340
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "EXIT", label_name->str);
6341 6342
    return true;
  }
6343
  return sp_exit_block(thd, lab, item);
6344 6345 6346
}


6347
bool LEX::sp_iterate_statement(THD *thd, const LEX_CSTRING *label_name)
6348 6349 6350 6351
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab || lab->type != sp_label::ITERATION)
  {
6352
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", label_name->str);
6353 6354
    return true;
  }
6355 6356 6357 6358 6359 6360
  return sp_continue_loop(thd, lab);
}


bool LEX::sp_continue_loop(THD *thd, sp_label *lab)
{
6361 6362 6363 6364 6365 6366 6367 6368 6369
  if (lab->ctx->for_loop().m_index)
  {
    // We're in a FOR loop, increment the index variable before backward jump
    sphead->reset_lex(thd);
    DBUG_ASSERT(this != thd->lex);
    if (thd->lex->sp_for_loop_increment(thd, lab->ctx->for_loop()) ||
        thd->lex->sphead->restore_lex(thd))
      return true;
  }
6370 6371 6372 6373 6374
  return sp_change_context(thd, lab->ctx, false) ||
         sphead->add_instr_jump(thd, spcont, lab->ip); /* Jump back */
}


6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407
bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when)
{
  if (!when)
    return sp_continue_loop(thd, lab);

  DBUG_ASSERT(sphead == thd->lex->sphead);
  DBUG_ASSERT(spcont == thd->lex->spcont);
  sp_instr_jump_if_not *i= new (thd->mem_root)
                           sp_instr_jump_if_not(sphead->instructions(),
                                                spcont,
                                                when, thd->lex);
  if (i == NULL ||
      sphead->add_instr(i) ||
      sp_continue_loop(thd, lab))
    return true;
  i->backpatch(sphead->instructions(), spcont);
  return false;
}


bool LEX::sp_continue_statement(THD *thd, Item *when)
{
  sp_label *lab= spcont->find_label_current_loop_start();
  if (!lab)
  {
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", "");
    return true;
  }
  DBUG_ASSERT(lab->type == sp_label::ITERATION);
  return sp_continue_loop(thd, lab, when);
}


6408 6409
bool LEX::sp_continue_statement(THD *thd, const LEX_CSTRING *label_name,
                                Item *when)
6410 6411 6412 6413
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab || lab->type != sp_label::ITERATION)
  {
6414
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "CONTINUE", label_name->str);
6415 6416 6417 6418 6419 6420
    return true;
  }
  return sp_continue_loop(thd, lab, when);
}


6421 6422 6423 6424
bool LEX::maybe_start_compound_statement(THD *thd)
{
  if (!sphead)
  {
6425
    if (!make_sp_head(thd, NULL, &sp_handler_procedure))
6426
      return true;
6427
    sphead->set_suid(SP_IS_NOT_SUID);
6428 6429 6430 6431 6432 6433
    sphead->set_body_start(thd, thd->m_parser_state->m_lip.get_cpp_ptr());
  }
  return false;
}


6434
bool LEX::sp_push_loop_label(THD *thd, const LEX_CSTRING *label_name)
6435 6436 6437 6438
{
  sp_label *lab= spcont->find_label(label_name);
  if (lab)
  {
6439
    my_error(ER_SP_LABEL_REDEFINE, MYF(0), label_name->str);
6440 6441
    return true;
  }
6442 6443
  spcont->push_label(thd, label_name, sphead->instructions(),
                     sp_label::ITERATION);
6444 6445 6446 6447 6448 6449 6450 6451 6452
  return false;
}


bool LEX::sp_push_loop_empty_label(THD *thd)
{
  if (maybe_start_compound_statement(thd))
    return true;
  /* Unlabeled controls get an empty label. */
6453
  spcont->push_label(thd, &empty_clex_str, sphead->instructions(),
6454
                     sp_label::ITERATION);
6455 6456 6457 6458
  return false;
}


6459
bool LEX::sp_pop_loop_label(THD *thd, const LEX_CSTRING *label_name)
6460 6461 6462
{
  sp_label *lab= spcont->pop_label();
  sphead->backpatch(lab);
6463
  if (label_name->str &&
6464 6465
      lex_string_cmp(system_charset_info, label_name,
                     &lab->name) != 0)
6466
  {
6467
    my_error(ER_SP_LABEL_MISMATCH, MYF(0), label_name->str);
6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481
    return true;
  }
  return false;
}


void LEX::sp_pop_loop_empty_label(THD *thd)
{
  sp_label *lab= spcont->pop_label();
  sphead->backpatch(lab);
  DBUG_ASSERT(lab->name.length == 0);
}


6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506
bool LEX::sp_while_loop_expression(THD *thd, Item *expr)
{
  sp_instr_jump_if_not *i= new (thd->mem_root)
    sp_instr_jump_if_not(sphead->instructions(), spcont, expr, this);
  return i == NULL ||
         /* Jumping forward */
         sphead->push_backpatch(thd, i, spcont->last_label()) ||
         sphead->new_cont_backpatch(i) ||
         sphead->add_instr(i);
}


bool LEX::sp_while_loop_finalize(THD *thd)
{
  sp_label *lab= spcont->last_label();  /* Jumping back */
  sp_instr_jump *i= new (thd->mem_root)
    sp_instr_jump(sphead->instructions(), spcont, lab->ip);
  if (i == NULL ||
      sphead->add_instr(i))
    return true;
  sphead->do_cont_backpatch();
  return false;
}


6507 6508 6509
Item *LEX::create_and_link_Item_trigger_field(THD *thd,
                                              const LEX_CSTRING *name,
                                              bool new_row)
6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547
{
  Item_trigger_field *trg_fld;

  if (trg_chistics.event == TRG_EVENT_INSERT && !new_row)
  {
    my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT");
    return NULL;
  }

  if (trg_chistics.event == TRG_EVENT_DELETE && new_row)
  {
    my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE");
    return NULL;
  }

  DBUG_ASSERT(!new_row ||
              (trg_chistics.event == TRG_EVENT_INSERT ||
               trg_chistics.event == TRG_EVENT_UPDATE));

  const bool tmp_read_only=
    !(new_row && trg_chistics.action_time == TRG_ACTION_BEFORE);
  trg_fld= new (thd->mem_root)
             Item_trigger_field(thd, current_context(),
                                new_row ?
                                  Item_trigger_field::NEW_ROW:
                                  Item_trigger_field::OLD_ROW,
                                name, SELECT_ACL, tmp_read_only);
  /*
    Let us add this item to list of all Item_trigger_field objects
    in trigger.
  */
  if (trg_fld)
      trg_table_fields.link_in_list(trg_fld, &trg_fld->next_trg_field);

  return trg_fld;
}


6548
Item_param *LEX::add_placeholder(THD *thd, const LEX_CSTRING *name,
6549
                                 const char *start, const char *end)
6550
{
6551 6552 6553 6554 6555
  if (!thd->m_parser_state->m_lip.stmt_prepare_mode)
  {
    thd->parse_error(ER_SYNTAX_ERROR, start);
    return NULL;
  }
6556 6557 6558 6559 6560
  if (!parsing_options.allows_variable)
  {
    my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
    return NULL;
  }
6561 6562

  Query_fragment pos(thd, sphead, start, end);
6563
  Item_param *item= new (thd->mem_root) Item_param(thd, name,
6564
                                                   pos.pos(), pos.length());
6565 6566 6567 6568 6569 6570 6571 6572 6573
  if (!item || param_list.push_back(item, thd->mem_root))
  {
    my_error(ER_OUT_OF_RESOURCES, MYF(0));
    return NULL;
  }
  return item;
}


6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591
bool LEX::add_signal_statement(THD *thd, const sp_condition_value *v)
{
  Yacc_state *state= &thd->m_parser_state->m_yacc;
  sql_command= SQLCOM_SIGNAL;
  m_sql_cmd= new (thd->mem_root) Sql_cmd_signal(v, state->m_set_signal_info);
  return m_sql_cmd == NULL;
}


bool LEX::add_resignal_statement(THD *thd, const sp_condition_value *v)
{
  Yacc_state *state= &thd->m_parser_state->m_yacc;
  sql_command= SQLCOM_RESIGNAL;
  m_sql_cmd= new (thd->mem_root) Sql_cmd_resignal(v, state->m_set_signal_info);
  return m_sql_cmd == NULL;
}


6592
Item *LEX::create_item_ident_nospvar(THD *thd,
6593 6594
                                     const LEX_CSTRING *a,
                                     const LEX_CSTRING *b)
6595 6596 6597 6598 6599 6600 6601 6602 6603
{
  DBUG_ASSERT(this == thd->lex);
  /*
    FIXME This will work ok in simple_ident_nospvar case because
    we can't meet simple_ident_nospvar in trigger now. But it
    should be changed in future.
  */
  if (is_trigger_new_or_old_reference(a))
  {
6604
    bool new_row= (a->str[0]=='N' || a->str[0]=='n');
6605

6606
    return create_and_link_Item_trigger_field(thd, b, new_row);
6607 6608 6609 6610
  }

  if (current_select->no_table_names_allowed)
  {
6611
    my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), a->str, thd->where);
6612 6613 6614 6615 6616
    return NULL;
  }
  if ((current_select->parsing_place != IN_HAVING) ||
      (current_select->get_in_sum_expr() > 0))
    return new (thd->mem_root) Item_field(thd, current_context(),
6617
                                          NullS, a->str, b);
6618
  return new (thd->mem_root) Item_ref(thd, current_context(),
6619
                                      NullS, a->str, b);
6620 6621 6622
}


6623
Item_splocal *LEX::create_item_spvar_row_field(THD *thd,
6624
                                               const Sp_rcontext_handler *rh,
6625 6626
                                               const LEX_CSTRING *a,
                                               const LEX_CSTRING *b,
6627
                                               sp_variable *spv,
6628 6629
                                               const char *start,
                                               const char *end)
6630 6631 6632 6633 6634 6635 6636
{
  if (!parsing_options.allows_variable)
  {
    my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
    return NULL;
  }

6637
  Query_fragment pos(thd, sphead, start, end);
6638
  Item_splocal *item;
6639 6640
  if (spv->field_def.is_table_rowtype_ref() ||
      spv->field_def.is_cursor_rowtype_ref())
6641 6642
  {
    if (!(item= new (thd->mem_root)
6643
                Item_splocal_row_field_by_name(thd, rh, a, b, spv->offset,
6644
                                               &type_handler_null,
6645
                                               pos.pos(), pos.length())))
6646 6647 6648 6649 6650 6651 6652 6653
      return NULL;
  }
  else
  {
    uint row_field_offset;
    const Spvar_definition *def;
    if (!(def= spv->find_row_field(a, b, &row_field_offset)))
      return NULL;
6654

6655
    if (!(item= new (thd->mem_root)
6656
                Item_splocal_row_field(thd, rh, a, b,
6657
                                       spv->offset, row_field_offset,
6658
                                       def->type_handler(),
6659
                                       pos.pos(), pos.length())))
6660 6661
      return NULL;
  }
6662
#ifdef DBUG_ASSERT_EXISTS
6663 6664 6665 6666 6667 6668 6669
  item->m_sp= sphead;
#endif
  safe_to_cache_query=0;
  return item;
}


6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683
my_var *LEX::create_outvar(THD *thd, const LEX_CSTRING *name)
{
  const Sp_rcontext_handler *rh;
  sp_variable *spv;
  if ((spv= find_variable(name, &rh)))
    return result ? new (thd->mem_root)
                    my_var_sp(rh, name, spv->offset,
                              spv->type_handler(), sphead) :
                    NULL /* EXPLAIN */;
  my_error(ER_SP_UNDECLARED_VAR, MYF(0), name->str);
  return NULL;
}


6684
my_var *LEX::create_outvar(THD *thd,
6685 6686
                           const LEX_CSTRING *a,
                           const LEX_CSTRING *b)
6687
{
6688
  const Sp_rcontext_handler *rh;
6689
  sp_variable *t;
6690
  if (!(t= find_variable(a, &rh)))
6691
  {
6692
    my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str);
6693 6694 6695 6696 6697 6698
    return NULL;
  }
  uint row_field_offset;
  if (!t->find_row_field(a, b, &row_field_offset))
    return NULL;
  return result ?
6699
    new (thd->mem_root) my_var_sp_row_field(rh, a, b, t->offset,
6700
                                            row_field_offset, sphead) :
6701
    NULL /* EXPLAIN */;
6702 6703 6704
}


6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729
Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident)
{
  TABLE_LIST *table;
  if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
                                                 TL_OPTION_SEQUENCE,
                                                 TL_WRITE_ALLOW_WRITE,
                                                 MDL_SHARED_WRITE)))
    return NULL;
  return new (thd->mem_root) Item_func_nextval(thd, table);
}


Item *LEX::create_item_func_lastval(THD *thd, Table_ident *table_ident)
{
  TABLE_LIST *table;
  if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
                                                 TL_OPTION_SEQUENCE,
                                                 TL_READ,
                                                 MDL_SHARED_READ)))
    return NULL;
  return new (thd->mem_root) Item_func_lastval(thd, table);
}


Item *LEX::create_item_func_nextval(THD *thd,
6730 6731
                                    const LEX_CSTRING *db,
                                    const LEX_CSTRING *name)
6732 6733 6734 6735 6736 6737 6738 6739 6740
{
  Table_ident *table_ident;
  if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false)))
    return NULL;
  return create_item_func_nextval(thd, table_ident);
}


Item *LEX::create_item_func_lastval(THD *thd,
6741 6742
                                    const LEX_CSTRING *db,
                                    const LEX_CSTRING *name)
6743 6744 6745 6746 6747 6748 6749 6750
{
  Table_ident *table_ident;
  if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false)))
    return NULL;
  return create_item_func_lastval(thd, table_ident);
}


6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765
Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident,
                                   longlong nextval, ulonglong round,
                                   bool is_used)
{
  TABLE_LIST *table;
  if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
                                                 TL_OPTION_SEQUENCE,
                                                 TL_WRITE_ALLOW_WRITE,
                                                 MDL_SHARED_WRITE)))
    return NULL;
  return new (thd->mem_root) Item_func_setval(thd, table, nextval, round,
                                              is_used);
}


6766
Item *LEX::create_item_ident(THD *thd,
6767 6768
                             const LEX_CSTRING *a,
                             const LEX_CSTRING *b,
6769
                             const char *start, const char *end)
6770
{
6771
  const Sp_rcontext_handler *rh;
6772
  sp_variable *spv;
6773
  if ((spv= find_variable(a, &rh)) &&
6774 6775 6776
      (spv->field_def.is_row() ||
       spv->field_def.is_table_rowtype_ref() ||
       spv->field_def.is_cursor_rowtype_ref()))
6777
    return create_item_spvar_row_field(thd, rh, a, b, spv, start, end);
6778

6779
  if ((thd->variables.sql_mode & MODE_ORACLE) && b->length == 7)
6780 6781
  {
    if (!my_strnncoll(system_charset_info,
6782
                      (const uchar *) b->str, 7,
6783
                      (const uchar *) "NEXTVAL", 7))
6784
      return create_item_func_nextval(thd, &null_clex_str, a);
6785
    else if (!my_strnncoll(system_charset_info,
6786
                          (const uchar *) b->str, 7,
6787
                          (const uchar *) "CURRVAL", 7))
6788
      return create_item_func_lastval(thd, &null_clex_str, a);
6789 6790
  }

6791 6792 6793 6794
  return create_item_ident_nospvar(thd, a, b);
}


6795
Item *LEX::create_item_ident(THD *thd,
6796 6797 6798
                             const LEX_CSTRING *a,
                             const LEX_CSTRING *b,
                             const LEX_CSTRING *c)
6799 6800
{
  const char *schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
6801
                       NullS : a->str);
6802

6803
  if ((thd->variables.sql_mode & MODE_ORACLE) && c->length == 7)
6804 6805
  {
    if (!my_strnncoll(system_charset_info,
6806
                      (const uchar *) c->str, 7,
6807 6808 6809
                      (const uchar *) "NEXTVAL", 7))
      return create_item_func_nextval(thd, a, b);
    else if (!my_strnncoll(system_charset_info,
6810
                          (const uchar *) c->str, 7,
6811 6812 6813 6814 6815 6816
                          (const uchar *) "CURRVAL", 7))
      return create_item_func_lastval(thd, a, b);
  }

  if (current_select->no_table_names_allowed)
  {
6817
    my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b->str, thd->where);
6818 6819 6820 6821 6822
    return NULL;
  }
  if (current_select->parsing_place != IN_HAVING ||
      current_select->get_in_sum_expr() > 0)
    return new (thd->mem_root) Item_field(thd, current_context(),
6823
                                          schema, b->str, c);
6824
  return new (thd->mem_root) Item_ref(thd, current_context(),
6825
                                      schema, b->str, c);
6826 6827
}

6828 6829

Item *LEX::create_item_limit(THD *thd,
6830
                             const LEX_CSTRING *a,
6831
                             const char *start, const char *end)
6832
{
6833
  const Sp_rcontext_handler *rh;
6834
  sp_variable *spv;
6835
  if (!(spv= find_variable(a, &rh)))
6836
  {
6837
    my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str);
6838 6839 6840
    return NULL;
  }

6841
  Query_fragment pos(thd, sphead, start, end);
6842
  Item_splocal *item;
6843
  if (!(item= new (thd->mem_root) Item_splocal(thd, rh, a,
6844
                                               spv->offset, spv->type_handler(),
6845
                                               pos.pos(), pos.length())))
6846
    return NULL;
6847
#ifdef DBUG_ASSERT_EXISTS
6848 6849 6850 6851
  item->m_sp= sphead;
#endif
  safe_to_cache_query= 0;

6852
  if (!item->is_valid_limit_clause_variable_with_error())
6853
    return NULL;
6854

6855 6856 6857 6858 6859 6860
  item->limit_clause_param= true;
  return item;
}


Item *LEX::create_item_limit(THD *thd,
6861 6862
                             const LEX_CSTRING *a,
                             const LEX_CSTRING *b,
6863
                             const char *start, const char *end)
6864
{
6865
  const Sp_rcontext_handler *rh;
6866
  sp_variable *spv;
6867
  if (!(spv= find_variable(a, &rh)))
6868
  {
6869
    my_error(ER_SP_UNDECLARED_VAR, MYF(0), a->str);
6870 6871 6872 6873 6874
    return NULL;
  }
  // Qualified %TYPE variables are not possible
  DBUG_ASSERT(!spv->field_def.column_type_ref());
  Item_splocal *item;
6875
  if (!(item= create_item_spvar_row_field(thd, rh, a, b, spv, start, end)))
6876
    return NULL;
6877
  if (!item->is_valid_limit_clause_variable_with_error())
6878 6879 6880 6881 6882 6883
    return NULL;
  item->limit_clause_param= true;
  return item;
}


6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895
bool LEX::set_user_variable(THD *thd, const LEX_CSTRING *name, Item *val)
{
  Item_func_set_user_var *item;
  set_var_user *var;
  if (!(item= new (thd->mem_root) Item_func_set_user_var(thd, name,  val)) ||
      !(var= new (thd->mem_root) set_var_user(item)))
    return true;
  var_list.push_back(var, thd->mem_root);
  return false;
}


6896
Item *LEX::create_item_ident_nosp(THD *thd, LEX_CSTRING *name)
6897 6898 6899 6900
{
  if (current_select->parsing_place != IN_HAVING ||
      current_select->get_in_sum_expr() > 0)
    return new (thd->mem_root) Item_field(thd, current_context(),
6901
                                          NullS, NullS, name);
6902 6903

  return new (thd->mem_root) Item_ref(thd, current_context(),
6904
                                      NullS, NullS, name);
6905 6906 6907
}


6908
Item *LEX::create_item_ident_sp(THD *thd, LEX_CSTRING *name,
6909 6910
                                const char *start,
                                const char *end)
6911
{
6912
  const Sp_rcontext_handler *rh;
6913 6914
  sp_variable *spv;
  DBUG_ASSERT(spcont);
6915
  DBUG_ASSERT(sphead);
6916
  if ((spv= find_variable(name, &rh)))
6917 6918 6919 6920 6921 6922 6923 6924
  {
    /* We're compiling a stored procedure and found a variable */
    if (!parsing_options.allows_variable)
    {
      my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
      return NULL;
    }

6925
    Query_fragment pos(thd, sphead, start, end);
6926
    Item_splocal *splocal= spv->field_def.is_column_type_ref() ?
6927
      new (thd->mem_root) Item_splocal_with_delayed_data_type(thd, rh, name,
6928
                                                              spv->offset,
6929 6930
                                                              pos.pos(),
                                                              pos.length()) :
6931
      new (thd->mem_root) Item_splocal(thd, rh, name,
6932
                                       spv->offset, spv->type_handler(),
6933
                                       pos.pos(), pos.length());
6934 6935
    if (splocal == NULL)
      return NULL;
6936
#ifdef DBUG_ASSERT_EXISTS
6937 6938 6939 6940 6941 6942 6943 6944
    splocal->m_sp= sphead;
#endif
    safe_to_cache_query= 0;
    return splocal;
  }

  if (thd->variables.sql_mode & MODE_ORACLE)
  {
6945
    if (!my_strcasecmp(system_charset_info, name->str, "SQLCODE"))
6946
      return new (thd->mem_root) Item_func_sqlcode(thd);
6947
    if (!my_strcasecmp(system_charset_info, name->str, "SQLERRM"))
6948 6949 6950 6951 6952 6953
      return new (thd->mem_root) Item_func_sqlerrm(thd);
  }
  return create_item_ident_nosp(thd, name);
}


6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964

bool LEX::set_variable(const LEX_CSTRING *name, Item *item)
{
  sp_pcontext *ctx;
  const Sp_rcontext_handler *rh;
  sp_variable *spv= find_variable(name, &ctx, &rh);
  return spv ? sphead->set_local_variable(thd, ctx, rh, spv, item, this, true) :
               set_system_variable(option_type, name, item);
}


6965 6966 6967 6968
/**
  Generate instructions for:
    SET x.y= expr;
*/
6969 6970
bool LEX::set_variable(const LEX_CSTRING *name1,
                       const LEX_CSTRING *name2,
6971 6972
                       Item *item)
{
6973 6974
  const Sp_rcontext_handler *rh;
  sp_pcontext *ctx;
6975
  sp_variable *spv;
6976
  if (spcont && (spv= find_variable(name1, &ctx, &rh)))
6977
  {
6978 6979
    if (spv->field_def.is_table_rowtype_ref() ||
        spv->field_def.is_cursor_rowtype_ref())
6980 6981
      return sphead->set_local_variable_row_field_by_name(thd, ctx,
                                                          rh,
6982 6983
                                                          spv, name2,
                                                          item, this);
6984 6985 6986
    // A field of a ROW variable
    uint row_field_offset;
    return !spv->find_row_field(name1, name2, &row_field_offset) ||
6987
           sphead->set_local_variable_row_field(thd, ctx, rh,
6988 6989 6990 6991
                                                spv, row_field_offset,
                                                item, this);
  }

6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007
  if (is_trigger_new_or_old_reference(name1))
    return set_trigger_field(name1, name2, item);

  return set_system_variable(thd, option_type, name1, name2, item);
}


bool LEX::set_default_system_variable(enum_var_type var_type,
                                      const LEX_CSTRING *name,
                                      Item *val)
{
  static LEX_CSTRING default_base_name= {STRING_WITH_LEN("default")};
  sys_var *var= find_sys_var(thd, name->str, name->length);
  if (!var)
    return true;
  if (!var->is_struct())
7008
  {
7009
    my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name->str);
7010 7011
    return true;
  }
7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039
  return set_system_variable(var_type, var, &default_base_name, val);
}


bool LEX::set_system_variable(enum_var_type var_type,
                              const LEX_CSTRING *name,
                              Item *val)
{
  sys_var *var= find_sys_var(thd, name->str, name->length);
  DBUG_ASSERT(thd->is_error() || var != NULL);
  return var ? set_system_variable(var_type, var, &null_clex_str, val) : true;
}


bool LEX::set_system_variable(THD *thd, enum_var_type var_type,
                              const LEX_CSTRING *name1,
                              const LEX_CSTRING *name2,
                              Item *val)
{
  sys_var *tmp;
  if (check_reserved_words(name1) ||
      !(tmp= find_sys_var_ex(thd, name2->str, name2->length, true, false)))
  {
    my_error(ER_UNKNOWN_STRUCTURED_VARIABLE, MYF(0),
             (int) name1->length, name1->str);
    return true;
  }
  if (!tmp->is_struct())
7040
  {
7041
    my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name2->str);
7042 7043
    return true;
  }
7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067
  return set_system_variable(var_type, tmp, name1, val);
}


bool LEX::set_trigger_field(const LEX_CSTRING *name1, const LEX_CSTRING *name2,
                            Item *val)
{
  DBUG_ASSERT(is_trigger_new_or_old_reference(name1));
  if (name1->str[0]=='O' || name1->str[0]=='o')
  {
    my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", "");
    return true;
  }
  if (trg_chistics.event == TRG_EVENT_DELETE)
  {
    my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE");
    return true;
  }
  if (trg_chistics.action_time == TRG_ACTION_AFTER)
  {
    my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after ");
    return true;
  }
  return set_trigger_new_row(name2, val);
7068 7069 7070
}


7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216
#ifdef MYSQL_SERVER
uint binlog_unsafe_map[256];

#define UNSAFE(a, b, c) \
  { \
  DBUG_PRINT("unsafe_mixed_statement", ("SETTING BASE VALUES: %s, %s, %02X\n", \
    LEX::stmt_accessed_table_string(a), \
    LEX::stmt_accessed_table_string(b), \
    c)); \
  unsafe_mixed_statement(a, b, c); \
  }

/*
  Sets the combination given by "a" and "b" and automatically combinations
  given by other types of access, i.e. 2^(8 - 2), as unsafe.

  It may happen a colision when automatically defining a combination as unsafe.
  For that reason, a combination has its unsafe condition redefined only when
  the new_condition is greater then the old. For instance,
  
     . (BINLOG_DIRECT_ON & TRX_CACHE_NOT_EMPTY) is never overwritten by 
     . (BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF).
*/
void unsafe_mixed_statement(LEX::enum_stmt_accessed_table a,
                            LEX::enum_stmt_accessed_table b, uint condition)
{
  int type= 0;
  int index= (1U << a) | (1U << b);
  
  
  for (type= 0; type < 256; type++)
  {
    if ((type & index) == index)
    {
      binlog_unsafe_map[type] |= condition;
    }
  }
}
/*
  The BINLOG_* AND TRX_CACHE_* values can be combined by using '&' or '|',
  which means that both conditions need to be satisfied or any of them is
  enough. For example, 
    
    . BINLOG_DIRECT_ON & TRX_CACHE_NOT_EMPTY means that the statment is
    unsafe when the option is on and trx-cache is not empty;

    . BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF means the statement is unsafe
    in all cases.

    . TRX_CACHE_EMPTY | TRX_CACHE_NOT_EMPTY means the statement is unsafe
    in all cases. Similar as above.
*/
void binlog_unsafe_map_init()
{
  memset((void*) binlog_unsafe_map, 0, sizeof(uint) * 256);

  /*
    Classify a statement as unsafe when there is a mixed statement and an
    on-going transaction at any point of the execution if:

      1. The mixed statement is about to update a transactional table and
      a non-transactional table.

      2. The mixed statement is about to update a transactional table and
      read from a non-transactional table.

      3. The mixed statement is about to update a non-transactional table
      and temporary transactional table.

      4. The mixed statement is about to update a temporary transactional
      table and read from a non-transactional table.

      5. The mixed statement is about to update a transactional table and
      a temporary non-transactional table.
     
      6. The mixed statement is about to update a transactional table and
      read from a temporary non-transactional table.

      7. The mixed statement is about to update a temporary transactional
      table and temporary non-transactional table.

      8. The mixed statement is about to update a temporary transactional
      table and read from a temporary non-transactional table.

    After updating a transactional table if:

      9. The mixed statement is about to update a non-transactional table
      and read from a transactional table.

      10. The mixed statement is about to update a non-transactional table
      and read from a temporary transactional table.

      11. The mixed statement is about to update a temporary non-transactional
      table and read from a transactional table.
      
      12. The mixed statement is about to update a temporary non-transactional
      table and read from a temporary transactional table.

      13. The mixed statement is about to update a temporary non-transactional
      table and read from a non-transactional table.

    The reason for this is that locks acquired may not protected a concurrent
    transaction of interfering in the current execution and by consequence in
    the result.
  */
  /* Case 1. */
  UNSAFE(LEX::STMT_WRITES_TRANS_TABLE, LEX::STMT_WRITES_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF);
  /* Case 2. */
  UNSAFE(LEX::STMT_WRITES_TRANS_TABLE, LEX::STMT_READS_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF);
  /* Case 3. */
  UNSAFE(LEX::STMT_WRITES_NON_TRANS_TABLE, LEX::STMT_WRITES_TEMP_TRANS_TABLE,
    BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF);
  /* Case 4. */
  UNSAFE(LEX::STMT_WRITES_TEMP_TRANS_TABLE, LEX::STMT_READS_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF);
  /* Case 5. */
  UNSAFE(LEX::STMT_WRITES_TRANS_TABLE, LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON);
  /* Case 6. */
  UNSAFE(LEX::STMT_WRITES_TRANS_TABLE, LEX::STMT_READS_TEMP_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON);
  /* Case 7. */
  UNSAFE(LEX::STMT_WRITES_TEMP_TRANS_TABLE, LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON);
  /* Case 8. */
  UNSAFE(LEX::STMT_WRITES_TEMP_TRANS_TABLE, LEX::STMT_READS_TEMP_NON_TRANS_TABLE,
    BINLOG_DIRECT_ON);
  /* Case 9. */
  UNSAFE(LEX::STMT_WRITES_NON_TRANS_TABLE, LEX::STMT_READS_TRANS_TABLE,
    (BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF) & TRX_CACHE_NOT_EMPTY);
  /* Case 10 */
  UNSAFE(LEX::STMT_WRITES_NON_TRANS_TABLE, LEX::STMT_READS_TEMP_TRANS_TABLE,
    (BINLOG_DIRECT_ON | BINLOG_DIRECT_OFF) & TRX_CACHE_NOT_EMPTY);
  /* Case 11. */
  UNSAFE(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE, LEX::STMT_READS_TRANS_TABLE,
    BINLOG_DIRECT_ON & TRX_CACHE_NOT_EMPTY);
  /* Case 12. */
  UNSAFE(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE, LEX::STMT_READS_TEMP_TRANS_TABLE,
    BINLOG_DIRECT_ON & TRX_CACHE_NOT_EMPTY);
  /* Case 13. */
  UNSAFE(LEX::STMT_WRITES_TEMP_NON_TRANS_TABLE, LEX::STMT_READS_NON_TRANS_TABLE,
     BINLOG_DIRECT_OFF & TRX_CACHE_NOT_EMPTY);
}
#endif
7217

7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229

/**
  @brief
  Finding fiels that are used in the GROUP BY of this st_select_lex
    
  @param thd  The thread handle

  @details
    This method looks through the fields which are used in the GROUP BY of this 
    st_select_lex and saves this fields. 
*/

7230 7231
void st_select_lex::collect_grouping_fields(THD *thd,
                                            ORDER *grouping_list) 
7232
{
7233
  grouping_tmp_fields.empty();
7234 7235 7236 7237
  List_iterator<Item> li(join->fields_list);
  Item *item= li++;
  for (uint i= 0; i < master_unit()->derived->table->s->fields; i++, (item=li++))
  {
7238
    for (ORDER *ord= grouping_list; ord; ord= ord->next)
7239 7240 7241
    {
      if ((*ord->item)->eq((Item*)item, 0))
      {
7242 7243 7244
        Field_pair *grouping_tmp_field=
          new Field_pair(master_unit()->derived->table->field[i], item);
        grouping_tmp_fields.push_back(grouping_tmp_field);
7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272
      }
    }
  }
}

/**
  @brief
   For a condition check possibility of exraction a formula over grouping fields 
  
  @param cond  The condition whose subformulas are to be analyzed
  
  @details
    This method traverses the AND-OR condition cond and for each subformula of
    the condition it checks whether it can be usable for the extraction of a
    condition over the grouping fields of this select. The method uses
    the call-back parameter check_processor to ckeck whether a primary formula
    depends only on grouping fields.
    The subformulas that are not usable are marked with the flag NO_EXTRACTION_FL.
    The subformulas that can be entierly extracted are marked with the flag 
    FULL_EXTRACTION_FL.
  @note
    This method is called before any call of extract_cond_for_grouping_fields.
    The flag NO_EXTRACTION_FL set in a subformula allows to avoid building clone
    for the subformula when extracting the pushable condition.
    The flag FULL_EXTRACTION_FL allows to delete later all top level conjuncts
    from cond.
*/ 

Igor Babaev's avatar
Igor Babaev committed
7273
void 
7274
st_select_lex::check_cond_extraction_for_grouping_fields(Item *cond)
7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286
{
  cond->clear_extraction_flag();
  if (cond->type() == Item::COND_ITEM)
  {
    bool and_cond= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
    List<Item> *arg_list=  ((Item_cond*) cond)->argument_list();
    List_iterator<Item> li(*arg_list);
    uint count= 0;         // to count items not containing NO_EXTRACTION_FL
    uint count_full= 0;    // to count items with FULL_EXTRACTION_FL
    Item *item;
    while ((item=li++))
    {
7287
      check_cond_extraction_for_grouping_fields(item);
7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307
      if (item->get_extraction_flag() !=  NO_EXTRACTION_FL)
      {
        count++;
        if (item->get_extraction_flag() == FULL_EXTRACTION_FL)
          count_full++;
      }
      else if (!and_cond)
        break;
    }
    if ((and_cond && count == 0) || item)
      cond->set_extraction_flag(NO_EXTRACTION_FL);
    if (count_full == arg_list->elements)
      cond->set_extraction_flag(FULL_EXTRACTION_FL);
    if (cond->get_extraction_flag() != 0)
    {
      li.rewind();
      while ((item=li++))
        item->clear_extraction_flag();
    }
  }
Igor Babaev's avatar
Igor Babaev committed
7308 7309 7310 7311 7312 7313
  else
  {
    int fl= cond->excl_dep_on_grouping_fields(this) ?
      FULL_EXTRACTION_FL : NO_EXTRACTION_FL;
    cond->set_extraction_flag(fl);
  }
7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335
}


/**
  @brief
  Build condition extractable from the given one depended on grouping fields
 
  @param thd           The thread handle
  @param cond          The condition from which the condition depended 
                       on grouping fields is to be extracted
  @param no_top_clones If it's true then no clones for the top fully 
                       extractable conjuncts are built

  @details
    For the given condition cond this method finds out what condition depended
    only on the grouping fields can be extracted from cond. If such condition C
    exists the method builds the item for it.
    This method uses the flags NO_EXTRACTION_FL and FULL_EXTRACTION_FL set by the
    preliminary call of st_select_lex::check_cond_extraction_for_grouping_fields
    to figure out whether a subformula depends only on these fields or not.
  @note
    The built condition C is always implied by the condition cond
7336
    (cond => C). The method tries to build the least restictive such
7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348
    condition (i.e. for any other condition C' such that cond => C'
    we have C => C').
  @note
    The build item is not ready for usage: substitution for the field items
    has to be done and it has to be re-fixed.
  
  @retval
    the built condition depended only on grouping fields if such a condition exists
    NULL if there is no such a condition
*/ 

Item *st_select_lex::build_cond_for_grouping_fields(THD *thd, Item *cond,
7349
                                                    bool no_top_clones)
7350 7351 7352 7353 7354 7355
{
  if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
  {
    if (no_top_clones)
      return cond;
    cond->clear_extraction_flag();
7356
    return cond->build_clone(thd);
7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376
  }
  if (cond->type() == Item::COND_ITEM)
  {
    bool cond_and= false;
    Item_cond *new_cond;
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
    {
      cond_and= true;
      new_cond=  new (thd->mem_root) Item_cond_and(thd);
    }
    else
      new_cond= new (thd->mem_root) Item_cond_or(thd);
    if (!new_cond)
      return 0;		
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
    Item *item;
    while ((item=li++))
    {
      if (item->get_extraction_flag() == NO_EXTRACTION_FL)
      {
7377 7378 7379
        DBUG_ASSERT(cond_and);
        item->clear_extraction_flag();
        continue;
7380 7381
      }
      Item *fix= build_cond_for_grouping_fields(thd, item,
7382
                                                no_top_clones & cond_and);
7383 7384
      if (!fix)
      {
7385 7386 7387
        if (cond_and)
          continue;
        break;
7388 7389 7390 7391 7392 7393 7394
      }
      new_cond->argument_list()->push_back(fix, thd->mem_root);
    }
    
    if (!cond_and && item)
    {
      while((item= li++))
7395
        item->clear_extraction_flag();
7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409
      return 0;
    }
    switch (new_cond->argument_list()->elements) 
    {
    case 0:
      return 0;			
    case 1:
      return new_cond->argument_list()->head();
    default:
      return new_cond;
    }
  }
  return 0;
}
7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429


int set_statement_var_if_exists(THD *thd, const char *var_name,
                                size_t var_name_length, ulonglong value)
{
  sys_var *sysvar;
  if (thd->lex->sql_command == SQLCOM_CREATE_VIEW)
  {
    my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "[NO]WAIT");
    return 1;
  }
  if (thd->lex->sphead)
  {
    my_error(ER_SP_BADSTATEMENT, MYF(0), "[NO]WAIT");
    return 1;
  }
  if ((sysvar= find_sys_var_ex(thd, var_name, var_name_length, true, false)))
  {
    Item *item= new (thd->mem_root) Item_uint(thd, value);
    set_var *var= new (thd->mem_root) set_var(thd, OPT_SESSION, sysvar,
7430
                                              &null_clex_str, item);
7431 7432 7433 7434 7435 7436 7437 7438 7439

    if (!item || !var || thd->lex->stmt_var_list.push_back(var, thd->mem_root))
    {
      my_error(ER_OUT_OF_RESOURCES, MYF(0));
      return 1;
    }
  }
  return 0;
}
7440 7441


7442
bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
7443 7444 7445 7446 7447 7448
{
  uint offset;
  sp_instr_cfetch *i;

  if (!spcont->find_cursor(name, &offset, false))
  {
7449
    my_error(ER_SP_CURSOR_MISMATCH, MYF(0), name->str);
7450 7451 7452
    return true;
  }
  i= new (thd->mem_root)
7453 7454
    sp_instr_cfetch(sphead->instructions(), spcont, offset,
                    !(thd->variables.sql_mode & MODE_ORACLE));
7455 7456 7457 7458
  if (i == NULL || sphead->add_instr(i))
    return true;
  return false;
}
7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504


bool LEX::create_or_alter_view_finalize(THD *thd, Table_ident *table_ident)
{
  sql_command= SQLCOM_CREATE_VIEW;
  /* first table in list is target VIEW name */
  if (!select_lex.add_table_to_list(thd, table_ident, NULL,
                                    TL_OPTION_UPDATING,
                                    TL_IGNORE,
                                    MDL_EXCLUSIVE))
    return true;
  query_tables->open_strategy= TABLE_LIST::OPEN_STUB;
  return false;
}


bool LEX::add_alter_view(THD *thd, uint16 algorithm,
                         enum_view_suid suid,
                         Table_ident *table_ident)
{
  if (sphead)
  {
    my_error(ER_SP_BADSTATEMENT, MYF(0), "ALTER VIEW");
    return true;
  }
  if (!(create_view= new (thd->mem_root)
                     Create_view_info(VIEW_ALTER, algorithm, suid)))
    return true;
  return create_or_alter_view_finalize(thd, table_ident);
}


bool LEX::add_create_view(THD *thd, DDL_options_st ddl,
                          uint16 algorithm, enum_view_suid suid,
                          Table_ident *table_ident)
{
  if (set_create_options_with_check(ddl))
    return true;
  if (!(create_view= new (thd->mem_root)
                     Create_view_info(ddl.or_replace() ?
                                      VIEW_CREATE_OR_REPLACE :
                                      VIEW_CREATE_NEW,
                                      algorithm, suid)))
    return true;
  return create_or_alter_view_finalize(thd, table_ident);
}
7505 7506 7507 7508


bool LEX::call_statement_start(THD *thd, sp_name *name)
{
7509 7510
  Database_qualified_name pkgname(&null_clex_str, &null_clex_str);
  const Sp_handler *sph= &sp_handler_procedure;
7511 7512
  sql_command= SQLCOM_CALL;
  value_list.empty();
7513 7514 7515 7516
  if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
                                      name, &sph, &pkgname))
    return true;
  if (!(m_sql_cmd= new (thd->mem_root) Sql_cmd_call(name, sph)))
7517
    return true;
7518 7519 7520
  sph->add_used_routine(this, thd, name);
  if (pkgname.m_name.length)
    sp_handler_package_body.add_used_routine(this, thd, &pkgname);
7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539
  return false;
}


bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name)
{
  sp_name *spname= make_sp_name(thd, name);
  return !spname || call_statement_start(thd, spname);
}


bool LEX::call_statement_start(THD *thd, const LEX_CSTRING *name1,
                                         const LEX_CSTRING *name2)
{
  sp_name *spname= make_sp_name(thd, name1, name2);
  return !spname || call_statement_start(thd, spname);
}


7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631
sp_package *LEX::get_sp_package() const
{
  return sphead ? sphead->get_package() : NULL;
}


sp_package *LEX::create_package_start(THD *thd,
                                      enum_sql_command command,
                                      const Sp_handler *sph,
                                      const sp_name *name_arg,
                                      DDL_options_st options)
{
  sp_package *pkg;
  if (sphead)
  {
    my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), sph->type_str());
    return NULL;
  }
  if (set_command_with_check(command, options))
    return NULL;
  if (sph->type() == TYPE_ENUM_PACKAGE_BODY)
  {
    /*
      If we start parsing a "CREATE PACKAGE BODY", we need to load
      the corresponding "CREATE PACKAGE", for the following reasons:
      1. "CREATE PACKAGE BODY" is allowed only if "CREATE PACKAGE"
         was done earlier for the same package name.
         So if "CREATE PACKAGE" does not exist, we throw an error here.
      2. When parsing "CREATE PACKAGE BODY", we need to know all package
         public and private routine names, to translate procedure and
         function calls correctly.
         For example, this statement inside a package routine:
           CALL p;
         can be translated to:
           CALL db.pkg.p; -- p is a known (public or private) package routine
           CALL db.p;     -- p is not a known package routine
    */
    sp_head *spec;
    int ret= sp_handler_package_spec.
               sp_cache_routine_reentrant(thd, name_arg, &spec);
    if (!spec)
    {
      if (!ret)
        my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
                 "PACKAGE", ErrConvDQName(name_arg).ptr());
      return 0;
    }
  }
  if (!(pkg= new sp_package(this, name_arg, sph)))
    return NULL;
  pkg->reset_thd_mem_root(thd);
  pkg->init(this);
  pkg->make_qname(pkg->get_main_mem_root(), &pkg->m_qname);
  sphead= pkg;
  return pkg;
}


bool LEX::create_package_finalize(THD *thd,
                                  const sp_name *name,
                                  const sp_name *name2,
                                  const char *body_start,
                                  const char *body_end)
{
  if (name2 &&
      (name2->m_explicit_name != name->m_explicit_name ||
       strcmp(name2->m_db.str, name->m_db.str) ||
       !Sp_handler::eq_routine_name(name2->m_name, name->m_name)))
  {
    bool exp= name2->m_explicit_name || name->m_explicit_name;
    my_error(ER_END_IDENTIFIER_DOES_NOT_MATCH, MYF(0),
             exp ? ErrConvDQName(name2).ptr() : name2->m_name.str,
             exp ? ErrConvDQName(name).ptr() : name->m_name.str);
    return true;
  }
  sphead->m_body.length= body_end - body_start;
  if (!(sphead->m_body.str= thd->strmake(body_start, sphead->m_body.length)))
    return true;

  size_t not_used;
  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
  sphead->m_defstr.length= lip->get_cpp_ptr() - lip->get_cpp_buf();
  sphead->m_defstr.str= thd->strmake(lip->get_cpp_buf(), sphead->m_defstr.length);
  trim_whitespace(thd->charset(), &sphead->m_defstr, &not_used);

  sphead->restore_thd_mem_root(thd);
  sp_package *pkg= sphead->get_package();
  DBUG_ASSERT(pkg);
  return pkg->validate_after_parser(thd);
}


7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643
bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg,
                            stored_procedure_type type_arg)
{
  if (columns.elements)
  {
    thd->parse_error();
    return true;
  }
  sql_command= sql_command_arg,
  type= type_arg;
  return false;
}
7644 7645


7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661
Item *LEX::make_item_func_substr(THD *thd, Item *a, Item *b, Item *c)
{
  return (thd->variables.sql_mode & MODE_ORACLE) ?
    new (thd->mem_root) Item_func_substr_oracle(thd, a, b, c) :
    new (thd->mem_root) Item_func_substr(thd, a, b, c);
}


Item *LEX::make_item_func_substr(THD *thd, Item *a, Item *b)
{
  return (thd->variables.sql_mode & MODE_ORACLE) ?
    new (thd->mem_root) Item_func_substr_oracle(thd, a, b) :
    new (thd->mem_root) Item_func_substr(thd, a, b);
}


7662 7663 7664 7665 7666 7667 7668 7669 7670
Item *LEX::make_item_func_replace(THD *thd,
                                  Item *org,
                                  Item *find,
                                  Item *replace)
{
  return (thd->variables.sql_mode & MODE_ORACLE) ?
    new (thd->mem_root) Item_func_replace_oracle(thd, org, find, replace) :
    new (thd->mem_root) Item_func_replace(thd, org, find, replace);
}
7671 7672 7673


bool SELECT_LEX::vers_push_field(THD *thd, TABLE_LIST *table, const LEX_CSTRING field_name)
7674
{
7675
  DBUG_ASSERT(field_name.str);
7676
  Item_field *fld= new (thd->mem_root) Item_field(thd, &context,
7677 7678
                                                  table->db.str, table->alias.str, &field_name);
  if (!fld || item_list.push_back(fld))
7679 7680 7681 7682
    return true;

  if (thd->lex->view_list.elements)
  {
7683 7684
    LEX_CSTRING *l;
    if (!(l= thd->make_clex_string(field_name.str, field_name.length)))
7685
      return true;
7686
    thd->lex->view_list.push_back(l);
7687 7688 7689 7690
  }

  return false;
}
7691

7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752

Item *Lex_trim_st::make_item_func_trim_std(THD *thd) const
{
  if (m_remove)
  {
    switch (m_spec) {
    case TRIM_BOTH:
      return new (thd->mem_root) Item_func_trim(thd, m_source, m_remove);
    case TRIM_LEADING:
      return new (thd->mem_root) Item_func_ltrim(thd, m_source, m_remove);
    case TRIM_TRAILING:
     return new (thd->mem_root) Item_func_rtrim(thd, m_source, m_remove);
    }
  }

  switch (m_spec) {
  case TRIM_BOTH:
    return new (thd->mem_root) Item_func_trim(thd, m_source);
  case TRIM_LEADING:
    return new (thd->mem_root) Item_func_ltrim(thd, m_source);
  case TRIM_TRAILING:
   return new (thd->mem_root) Item_func_rtrim(thd, m_source);
  }
  DBUG_ASSERT(0);
  return NULL;
}


Item *Lex_trim_st::make_item_func_trim_oracle(THD *thd) const
{
  if (m_remove)
  {
    switch (m_spec) {
    case TRIM_BOTH:
      return new (thd->mem_root) Item_func_trim_oracle(thd, m_source, m_remove);
    case TRIM_LEADING:
      return new (thd->mem_root) Item_func_ltrim_oracle(thd, m_source, m_remove);
    case TRIM_TRAILING:
     return new (thd->mem_root) Item_func_rtrim_oracle(thd, m_source, m_remove);
    }
  }

  switch (m_spec) {
  case TRIM_BOTH:
    return new (thd->mem_root) Item_func_trim_oracle(thd, m_source);
  case TRIM_LEADING:
    return new (thd->mem_root) Item_func_ltrim_oracle(thd, m_source);
  case TRIM_TRAILING:
   return new (thd->mem_root) Item_func_rtrim_oracle(thd, m_source);
  }
  DBUG_ASSERT(0);
  return NULL;
}


Item *Lex_trim_st::make_item_func_trim(THD *thd) const
{
  return (thd->variables.sql_mode & MODE_ORACLE) ?
         make_item_func_trim_oracle(thd) :
         make_item_func_trim_std(thd);
}
7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877


/**
  @brief
    Extract from given item a condition pushable into WHERE clause

  @param thd             the thread handle
  @param cond            the item to extract a condition to be pushed
                         into WHERE
  @param remaining_cond  the condition that will remain of cond after
                         the pushdown of its parts into the WHERE clause
  @param transformer     the transformer callback function to be
                         applied to the condition so it can be pushed
                         down into the WHERE clause of this select
  @param arg             parameter to be passed to the transformer

  @details
    This method checks if cond entirely or its parts can be
    pushed into the WHERE clause of this select and prepares it for pushing.

    First it checks wherever this select doesn't have any aggregation function
    in its projection and GROUP BY clause. If so cond can be entirely
    pushed into the WHERE clause of this select but before its fields should
    be transformed with transformer_for_where to make it pushable.

    Otherwise the method checks wherever any condition depending only on
    grouping fields can be extracted from cond. If there is any it prepares it
    for pushing using grouping_field_transformer_for_where and if it happens to
    be a conjunct of cond it removes it from cond. It saves the result of
    removal in remaining_cond.
    The extracted condition is saved in cond_pushed_into_where of this select.

  @note
    When looking for pushable condition the method considers only the grouping
    fields from the list grouping_tmp_fields whose elements are of the type
    Field_pair. This list must be prepared before the call of the
    function.

  @note
    This method is called for pushdown conditions into materialized
    derived tables/views optimization.
    Item::derived_field_transformer_for_where is passed as the actual
    callback function.
    Also it is called for pushdown conditions into materialized IN subqueries.
    Item::in_subq_field_transformer_for_where is passed as the actual
    callback function.
*/

void st_select_lex::pushdown_cond_into_where_clause(THD *thd, Item *cond,
                                                    Item **remaining_cond,
                                                    Item_transformer transformer,
                                                    uchar *arg)
{
  if (!cond_pushdown_is_allowed())
    return;
  thd->lex->current_select= this;
  if (have_window_funcs())
  {
    Item *cond_over_partition_fields;
    check_cond_extraction_for_grouping_fields(cond);
    cond_over_partition_fields=
      build_cond_for_grouping_fields(thd, cond, true);
    if (cond_over_partition_fields)
      cond_over_partition_fields= cond_over_partition_fields->transform(thd,
                                &Item::grouping_field_transformer_for_where,
                                (uchar*) this);
    if (cond_over_partition_fields)
    {
      cond_over_partition_fields->walk(
        &Item::cleanup_excluding_const_fields_processor, 0, 0);
      cond_pushed_into_where= cond_over_partition_fields;
    }

    return;
  }

  if (!join->group_list && !with_sum_func)
  {
    cond=
      cond->transform(thd, transformer, arg);
    if (cond)
    {
      cond->walk(
        &Item::cleanup_excluding_const_fields_processor, 0, 0);
      cond_pushed_into_where= cond;
    }

    return;
  }

  /*
    Figure out what can be extracted from cond
    that could be pushed into the WHERE clause of this select
  */
  Item *cond_over_grouping_fields;
  check_cond_extraction_for_grouping_fields(cond);
  cond_over_grouping_fields=
    build_cond_for_grouping_fields(thd, cond, true);

  /*
    Transform the references to the columns from the cond
    pushed into the WHERE clause of this select to make them usable in
    the new context
  */
  if (cond_over_grouping_fields)
    cond_over_grouping_fields= cond_over_grouping_fields->transform(thd,
                            &Item::grouping_field_transformer_for_where,
                            (uchar*) this);

  if (cond_over_grouping_fields)
  {

    /*
      In cond remove top conjuncts that has been pushed into the WHERE
      clause of this select
    */
    cond= remove_pushed_top_conjuncts(thd, cond);

    cond_over_grouping_fields->walk(
      &Item::cleanup_excluding_const_fields_processor, 0, 0);
    cond_pushed_into_where= cond_over_grouping_fields;
  }

  *remaining_cond= cond;
}