sql_lex.cc 172 KB
Newer Older
Sergei Golubchik's avatar
Sergei Golubchik committed
1
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates.
2
   Copyright (c) 2009, 2016, MariaDB
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 <my_global.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"
unknown's avatar
unknown committed
33

34 35 36 37 38 39 40

void LEX::parse_error()
{
  thd->parse_error();
}


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

43 44 45 46
/*
  We are using pointer to this variable for distinguishing between assignment
  to NEW row field (when parsing trigger definition) and structured variable.
*/
47 48

sys_var *trg_new_row_fake_var= (sys_var*) 0x01;
49

50 51 52 53
/**
  LEX_STRING constant for null-string to be used in parser and other places.
*/
const LEX_STRING null_lex_str= {NULL, 0};
54
const LEX_STRING empty_lex_str= {(char *) "", 0};
55 56 57 58 59 60 61 62 63 64
/**
  @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,
65
  ER_BINLOG_UNSAFE_AUTOINC_COLUMNS,
66 67
  ER_BINLOG_UNSAFE_UDF,
  ER_BINLOG_UNSAFE_SYSTEM_VARIABLE,
68
  ER_BINLOG_UNSAFE_SYSTEM_FUNCTION,
69
  ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS,
70 71
  ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE,
  ER_BINLOG_UNSAFE_MIXED_STATEMENT,
72 73
  ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT,
  ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE,
74
  ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT,
75 76 77
  ER_BINLOG_UNSAFE_REPLACE_SELECT,
  ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT,
  ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT,
78
  ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC,
79
  ER_BINLOG_UNSAFE_UPDATE_IGNORE,
80 81
  ER_BINLOG_UNSAFE_INSERT_TWO_KEYS,
  ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST
82 83
};

84

85
/* Longest standard keyword name */
86

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

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

unknown's avatar
unknown committed
94 95
static uchar to_upper_lex[]=
{
unknown's avatar
unknown committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
    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
};

114 115 116 117 118 119 120 121 122 123 124
/* 
  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"
};
125

unknown's avatar
unknown committed
126 127 128 129 130 131 132
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
133
#include <lex_hash.h>
unknown's avatar
unknown committed
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154


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;
}

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
/**
  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,
                                      table->s->table_name,
                                      table->s->db, TRUE))) ||
      (!(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
			    unsigned int 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
unknown's avatar
unknown committed
284
Lex_input_stream::reset(char *buffer, unsigned int 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
  uint 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 342 343 344 345 346 347 348 349 350 351 352 353 354 355

uint Lex_input_stream::get_body_utf8_maximum_length(THD *thd)
{
  /*
    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 389 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
  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;

  int bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;

  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 424 425
void Lex_input_stream::body_utf8_append_ident(THD *thd,
                                              const LEX_STRING *txt,
                                              const char *end_ptr)
unknown's avatar
unknown committed
426 427 428 429 430
{
  if (!m_cpp_utf8_processed_ptr)
    return;

  LEX_STRING 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
  {
    thd->convert_string(&utf_txt,
                        &my_charset_utf8_general_ci,
437
                        txt->str, (uint) txt->length,
unknown's avatar
unknown committed
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
                        txt_cs);
  }
  else
  {
    utf_txt.str= txt->str;
    utf_txt.length= txt->length;
  }

  /* 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;
}

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



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.
476
  *str= (uchar)escape;
477 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 606 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
  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,
                                               const LEX_STRING *txt,
                                               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
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652
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);
  }
}
653

654 655 656 657 658 659
/*
  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)
*/

660
void lex_start(THD *thd)
unknown's avatar
unknown committed
661
{
unknown's avatar
unknown committed
662
  LEX *lex= thd->lex;
unknown's avatar
unknown committed
663 664 665
  DBUG_ENTER("lex_start");

  lex->thd= lex->unit.thd= thd;
666
  
667
  DBUG_ASSERT(!lex->explain);
unknown's avatar
unknown committed
668

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

738
  lex->name= null_lex_str;
unknown's avatar
unknown committed
739
  lex->event_parse_data= NULL;
unknown's avatar
unknown committed
740
  lex->profile_options= PROFILE_NONE;
unknown's avatar
unknown committed
741
  lex->nest_level=0 ;
unknown's avatar
unknown committed
742
  lex->select_lex.nest_level_base= &lex->unit;
unknown's avatar
unknown committed
743 744
  lex->allow_sum_func= 0;
  lex->in_sum_func= NULL;
unknown's avatar
unknown committed
745

746
  lex->used_tables= 0;
747
  lex->only_view= FALSE;
748
  lex->reset_slave_info.all= false;
749 750
  lex->limit_rows_examined= 0;
  lex->limit_rows_examined_cnt= ULONGLONG_MAX;
751 752
  lex->var_list.empty();
  lex->stmt_var_list.empty();
753
  lex->proc_list.elements=0;
754

755 756 757 758 759 760 761 762
  lex->save_group_list.empty();
  lex->save_order_list.empty();
  lex->win_ref= NULL;
  lex->win_frame= NULL;
  lex->frame_top_bound= NULL;
  lex->frame_bottom_bound= NULL;
  lex->win_spec= NULL;

763
  lex->is_lex_started= TRUE;
unknown's avatar
unknown committed
764
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
765 766 767 768
}

void lex_end(LEX *lex)
{
unknown's avatar
unknown committed
769
  DBUG_ENTER("lex_end");
unknown's avatar
unknown committed
770
  DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
unknown's avatar
unknown committed
771

772 773 774 775 776 777 778 779 780 781
  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
782
  /* release used plugins */
783 784 785 786 787
  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
788 789
  reset_dynamic(&lex->plugins);

790 791 792 793 794 795 796 797 798 799 800 801 802 803
  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;
  }
804

805 806 807 808 809 810 811 812 813 814 815 816 817
  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 */
818
  lex->mi.reset(lex->sql_command == SQLCOM_CHANGE_MASTER);
819

unknown's avatar
unknown committed
820
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
821 822
}

823 824 825 826
Yacc_state::~Yacc_state()
{
  if (yacc_yyss)
  {
827 828
    my_free(yacc_yyss);
    my_free(yacc_yyvs);
829
  }
unknown's avatar
unknown committed
830 831
}

832
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
unknown's avatar
unknown committed
833
{
834
  const char *tok= lip->get_tok_start();
unknown's avatar
unknown committed
835

836
  SYMBOL *symbol= get_hash_symbol(tok, len, function);
unknown's avatar
unknown committed
837 838
  if (symbol)
  {
839 840 841 842
    lip->yylval->symbol.symbol=symbol;
    lip->yylval->symbol.str= (char*) tok;
    lip->yylval->symbol.length=len;

843
    if ((symbol->tok == NOT_SYM) &&
844
        (lip->m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))
845 846
      return NOT2_SYM;
    if ((symbol->tok == OR_OR_SYM) &&
847
	!(lip->m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
848
      return OR2_SYM;
849

unknown's avatar
unknown committed
850 851 852 853 854
    return symbol->tok;
  }
  return 0;
}

855 856 857 858 859
/*
  Check if name is a keyword

  SYNOPSIS
    is_keyword()
860
    name      checked name (must not be empty)
861 862 863 864 865 866 867 868 869
    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)
{
870
  DBUG_ASSERT(len != 0);
871 872
  return get_hash_symbol(name,len,0)!=0;
}
unknown's avatar
unknown committed
873

874 875 876 877 878
/**
  Check if name is a sql function

    @param name      checked name

879
    @return is this a native function or not
880 881 882 883
    @retval 0         name is a function
    @retval 1         name isn't a function
*/

884 885 886
bool is_lex_native_function(const LEX_STRING *name)
{
  DBUG_ASSERT(name != NULL);
887
  return (get_hash_symbol(name->str, (uint) name->length, 1) != 0);
888 889
}

890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 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

bool is_native_function(THD *thd, const LEX_STRING *name)
{
  if (find_native_function_builder(thd, *name))
    return true;

  if (is_lex_native_function(name))
    return true;

  return false;
}


bool is_native_function_with_warn(THD *thd, const LEX_STRING *name)
{
  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
943 944
/* make a copy of token before ptr and set yytoklen */

945
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
unknown's avatar
unknown committed
946 947
{
  LEX_STRING tmp;
948
  lip->yyUnget();                       // ptr points now after last token char
949
  tmp.length= length;
950
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
unknown's avatar
unknown committed
951 952 953 954

  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
955 956 957
  return tmp;
}

958 959 960 961 962 963 964
/* 
 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)
*/

965
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
966
                                   uint skip,
967
                                   uint length, char quote)
968 969
{
  LEX_STRING tmp;
970 971
  const char *from, *end;
  char *to;
972
  lip->yyUnget();                       // ptr points now after last token char
973
  tmp.length= length;
974
  tmp.str=(char*) lip->m_thd->alloc(tmp.length+1);
975
  from= lip->get_tok_start() + skip;
976
  to= tmp.str;
977
  end= to+length;
unknown's avatar
unknown committed
978 979 980 981

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

982
  for ( ; to != end; )
983
  {
984
    if ((*to++= *from++) == quote)
unknown's avatar
unknown committed
985
    {
986
      from++;					// Skip double quotes
unknown's avatar
unknown committed
987 988
      lip->m_cpp_text_start++;
    }
989 990 991 992 993 994
  }
  *to= 0;					// End null for safety
  return tmp;
}


995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 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
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());
}


1061 1062 1063 1064
/*
  Return an unescaped text literal without quotes
  Fix sometimes to do only one scan of the string
*/
unknown's avatar
unknown committed
1065

1066
bool Lex_input_stream::get_text(Lex_string_with_metadata_st *dst, uint sep,
1067
                                int pre_skip, int post_skip)
unknown's avatar
unknown committed
1068
{
1069
  reg1 uchar c;
unknown's avatar
unknown committed
1070
  uint found_escape=0;
1071
  CHARSET_INFO *cs= m_thd->charset();
unknown's avatar
unknown committed
1072

1073
  dst->set_8bit(false);
1074
  while (! eof())
unknown's avatar
unknown committed
1075
  {
1076
    c= yyGet();
1077 1078
    if (c & 0x80)
      dst->set_8bit(true);
unknown's avatar
unknown committed
1079
#ifdef USE_MB
1080 1081 1082
    {
      int l;
      if (use_mb(cs) &&
1083
          (l = my_ismbchar(cs,
1084 1085 1086
                           get_ptr() -1,
                           get_end_of_query()))) {
        skip_binary(l-1);
1087
        continue;
1088
      }
unknown's avatar
unknown committed
1089 1090
    }
#endif
1091
    if (c == '\\' &&
1092
        !(m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
unknown's avatar
unknown committed
1093 1094
    {					// Escaped character
      found_escape=1;
1095 1096 1097
      if (eof())
	return true;
      yySkip();
unknown's avatar
unknown committed
1098 1099 1100
    }
    else if (c == sep)
    {
1101
      if (c == yyGet())                 // Check if two separators in a row
unknown's avatar
unknown committed
1102
      {
1103
        found_escape=1;                 // duplicate. Remember for delete
unknown's avatar
unknown committed
1104 1105 1106
	continue;
      }
      else
1107
        yyUnget();
unknown's avatar
unknown committed
1108 1109

      /* Found end. Unescape and return string */
1110
      const char *str, *end;
unknown's avatar
unknown committed
1111

1112 1113
      str= get_tok_start();
      end= get_ptr();
1114 1115 1116 1117 1118
      /* Extract the text from the token */
      str += pre_skip;
      end -= post_skip;
      DBUG_ASSERT(end >= str);

1119 1120 1121 1122 1123 1124
      if (!(dst->str= (char*) m_thd->alloc((uint) (end - str) + 1)))
      {
        dst->str= (char*) "";        // Sql_alloc has set error flag
        dst->length= 0;
        return true;
      }
unknown's avatar
unknown committed
1125

1126 1127
      m_cpp_text_start= get_cpp_tok_start() + pre_skip;
      m_cpp_text_end= get_cpp_ptr() - post_skip;
unknown's avatar
unknown committed
1128

unknown's avatar
unknown committed
1129 1130
      if (!found_escape)
      {
1131 1132
        memcpy(dst->str, str, dst->length= (end - str));
        dst->str[dst->length]= 0;
unknown's avatar
unknown committed
1133 1134 1135
      }
      else
      {
1136
        dst->length= unescape(cs, dst->str, str, end, sep);
unknown's avatar
unknown committed
1137
      }
1138
      return false;
unknown's avatar
unknown committed
1139 1140
    }
  }
1141
  return true;                         // unexpected end of query
unknown's avatar
unknown committed
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159
}


/*
** 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
1160 1161
static const char *unsigned_longlong_str="18446744073709551615";
static const uint unsigned_longlong_len=20;
unknown's avatar
unknown committed
1162

unknown's avatar
unknown committed
1163
static inline uint int_token(const char *str,uint length)
unknown's avatar
unknown committed
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
{
  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
1198
      return DECIMAL_NUM;
unknown's avatar
unknown committed
1199 1200 1201 1202
    else
    {
      cmp=signed_longlong_str+1;
      smaller=LONG_NUM;				// If <= signed_longlong_str
unknown's avatar
unknown committed
1203
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
    }
  }
  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
1217 1218
    {
      if (length > unsigned_longlong_len)
unknown's avatar
unknown committed
1219
        return DECIMAL_NUM;
unknown's avatar
unknown committed
1220 1221
      cmp=unsigned_longlong_str;
      smaller=ULONGLONG_NUM;
unknown's avatar
unknown committed
1222
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
1223
    }
unknown's avatar
unknown committed
1224 1225 1226 1227
    else
    {
      cmp=longlong_str;
      smaller=LONG_NUM;
1228
      bigger= ULONGLONG_NUM;
unknown's avatar
unknown committed
1229 1230 1231 1232 1233 1234
    }
  }
  while (*cmp && *cmp++ == *str++) ;
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
}

1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 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

/**
  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;
}


1282
/*
1283
  MYSQLlex remember the following states from the following MYSQLlex()
1284

1285 1286 1287
  @param yylval         [out]  semantic value of the token being parsed (yylval)
  @param thd            THD

1288 1289 1290 1291
  - 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
1292

1293
int MYSQLlex(YYSTYPE *yylval, THD *thd)
1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
{
  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
  int token;

  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;
  }

1311
  token= lex_one_token(yylval, thd);
1312
  lip->add_digest_token(token, yylval);
1313 1314 1315 1316 1317 1318 1319 1320 1321 1322

  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.
    */
1323
    token= lex_one_token(yylval, thd);
1324
    lip->add_digest_token(token, yylval);
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
    switch(token) {
    case CUBE_SYM:
      return WITH_CUBE_SYM;
    case ROLLUP_SYM:
      return WITH_ROLLUP_SYM;
    default:
      /*
        Save the token following 'WITH'
      */
      lip->lookahead_yylval= lip->yylval;
      lip->yylval= NULL;
      lip->lookahead_token= token;
      return WITH;
    }
    break;
  default:
    break;
  }
  return token;
}

1346 1347 1348 1349 1350
int ORAlex(YYSTYPE *yylval, THD *thd)
{
  return MYSQLlex(yylval, thd);
}

1351
static int lex_one_token(YYSTYPE *yylval, THD *thd)
unknown's avatar
unknown committed
1352
{
1353
  reg1	uchar UNINIT_VAR(c);
1354
  bool comment_closed;
1355
  int	tokval, result_state;
unknown's avatar
unknown committed
1356
  uint length;
unknown's avatar
unknown committed
1357
  enum my_lex_states state;
1358
  Lex_input_stream *lip= & thd->m_parser_state->m_lip;
1359
  LEX *lex= thd->lex;
1360 1361 1362
  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
1363

1364
  lip->yylval=yylval;			// The global state
1365

1366
  lip->start_token();
1367 1368
  state=lip->next_state;
  lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
unknown's avatar
unknown committed
1369 1370
  for (;;)
  {
1371
    switch (state) {
1372 1373
    case MY_LEX_OPERATOR_OR_IDENT:	// Next is operator or keyword
    case MY_LEX_START:			// Start of token
1374 1375
      // Skip starting whitespace
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
unknown's avatar
unknown committed
1376 1377
      {
	if (c == '\n')
1378
	  lip->yylineno++;
1379 1380

        lip->yySkip();
unknown's avatar
unknown committed
1381
      }
1382 1383 1384 1385

      /* Start of real token */
      lip->restart_token();
      c= lip->yyGet();
1386
      state= (enum my_lex_states) state_map[c];
unknown's avatar
unknown committed
1387
      break;
1388
    case MY_LEX_ESCAPE:
1389
      if (!lip->eof() && lip->yyGet() == 'N')
unknown's avatar
unknown committed
1390 1391 1392 1393 1394
      {					// Allow \N as shortcut for NULL
	yylval->lex_str.str=(char*) "\\N";
	yylval->lex_str.length=2;
	return NULL_SYM;
      }
1395
      /* Fall through */
1396 1397
    case MY_LEX_CHAR:			// Unknown or single char token
    case MY_LEX_SKIP:			// This should not happen
1398 1399 1400 1401 1402 1403
      if (c != ')')
	lip->next_state= MY_LEX_START;	// Allow signed numbers
      return((int) c);

    case MY_LEX_MINUS_OR_COMMENT:
      if (lip->yyPeek() == '-' &&
1404 1405
          (my_isspace(cs,lip->yyPeekn(1)) ||
           my_iscntrl(cs,lip->yyPeekn(1))))
1406 1407 1408 1409
      {
        state=MY_LEX_COMMENT;
        break;
      }
1410 1411
      lip->next_state= MY_LEX_START;	// Allow signed numbers
      return((int) c);
1412

1413 1414 1415 1416 1417 1418 1419 1420 1421
    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()])
1422
        return(PARAM_MARKER);
1423
      return((int) c);
1424

1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436
    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
1437 1438
      return((int) c);

unknown's avatar
unknown committed
1439
    case MY_LEX_IDENT_OR_NCHAR:
1440 1441
    {
      uint sep;
1442 1443
      if (lip->yyPeek() != '\'')
      {
unknown's avatar
unknown committed
1444 1445 1446
	state= MY_LEX_IDENT;
	break;
      }
1447
      /* Found N'string' */
1448
      lip->yySkip();                         // Skip '
1449 1450
      if (lip->get_text(&yylval->lex_string_with_metadata,
                        (sep= lip->yyGetLast()), 2, 1))
unknown's avatar
unknown committed
1451
      {
1452 1453
	state= MY_LEX_CHAR;             // Read char by char
	break;
unknown's avatar
unknown committed
1454
      }
1455 1456

      lip->body_utf8_append(lip->m_cpp_text_start);
1457
      lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata,
1458 1459
                                   national_charset_info,
                                   lip->m_cpp_text_end, sep);
1460
      return(NCHAR_STRING);
1461
    }
1462
    case MY_LEX_IDENT_OR_HEX:
1463
      if (lip->yyPeek() == '\'')
1464
      {					// Found x'hex-number'
1465
	state= MY_LEX_HEX_NUMBER;
1466 1467
	break;
      }
unknown's avatar
unknown committed
1468
    case MY_LEX_IDENT_OR_BIN:
1469
      if (lip->yyPeek() == '\'')
unknown's avatar
unknown committed
1470 1471 1472 1473
      {                                 // Found b'bin-number'
        state= MY_LEX_BIN_NUMBER;
        break;
      }
1474
    case MY_LEX_IDENT:
1475
      const char *start;
unknown's avatar
unknown committed
1476
#if defined(USE_MB) && defined(USE_MB_IDENT)
1477
      if (use_mb(cs))
unknown's avatar
unknown committed
1478
      {
1479
	result_state= IDENT_QUOTED;
1480 1481 1482
        int char_length= my_charlen(cs, lip->get_ptr() - 1,
                                        lip->get_end_of_query());
        if (char_length <= 0)
unknown's avatar
unknown committed
1483
        {
1484 1485
          state= MY_LEX_CHAR;
          continue;
unknown's avatar
unknown committed
1486
        }
1487 1488
        lip->skip_binary(char_length - 1);

1489
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
1490
        {
1491 1492 1493 1494 1495
          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
1496 1497 1498 1499
        }
      }
      else
#endif
1500
      {
1501 1502 1503 1504
        for (result_state= c;
             ident_map[(uchar) (c= lip->yyGet())];
             result_state|= c)
          ;
unknown's avatar
unknown committed
1505 1506
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1507
      }
1508 1509
      length= lip->yyLength();
      start= lip->get_ptr();
1510
      if (lip->ignore_space)
unknown's avatar
unknown committed
1511
      {
unknown's avatar
unknown committed
1512 1513 1514 1515
        /*
          If we find a space then this can't be an identifier. We notice this
          below by checking start != lex->ptr.
        */
1516
        for (; state_map[(uchar) c] == MY_LEX_SKIP ; c= lip->yyGet())
1517 1518 1519 1520
        {
          if (c == '\n')
            lip->yylineno++;
        }
unknown's avatar
unknown committed
1521
      }
1522 1523
      if (start == lip->get_ptr() && c == '.' &&
          ident_map[(uchar) lip->yyPeek()])
1524
	lip->next_state=MY_LEX_IDENT_SEP;
unknown's avatar
unknown committed
1525 1526
      else
      {					// '(' must follow directly if function
1527 1528
        lip->yyUnget();
	if ((tokval = find_keyword(lip, length, c == '(')))
unknown's avatar
unknown committed
1529
	{
1530
	  lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1531 1532
	  return(tokval);		// Was keyword
	}
1533
        lip->yySkip();                  // next state does a unget
unknown's avatar
unknown committed
1534
      }
1535
      yylval->lex_str=get_token(lip, 0, length);
1536

unknown's avatar
unknown committed
1537
      /*
1538 1539
         Note: "SELECT _bla AS 'alias'"
         _bla should be considered as a IDENT if charset haven't been found.
unknown's avatar
unknown committed
1540
         So we don't use MYF(MY_WME) with get_charset_by_csname to avoid
1541 1542 1543
         producing an error.
      */

unknown's avatar
unknown committed
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
      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);

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

1563
      return(result_state);			// IDENT or IDENT_QUOTED
unknown's avatar
unknown committed
1564

1565
    case MY_LEX_IDENT_SEP:                  // Found ident and now '.'
1566 1567
      yylval->lex_str.str= (char*) lip->get_ptr();
      yylval->lex_str.length= 1;
1568 1569 1570
      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 "
1571
	lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
1572 1573
      return((int) c);

1574
    case MY_LEX_NUMBER_IDENT:		// number or ident which num-start
1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
      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')
        {
1593 1594
          while ((c= lip->yyGet()) == '0' || c == '1')
            ;
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
          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
1609
      if (!ident_map[c])
unknown's avatar
unknown committed
1610
      {					// Can't be identifier
1611
	state=MY_LEX_INT_OR_REAL;
unknown's avatar
unknown committed
1612 1613 1614 1615
	break;
      }
      if (c == 'e' || c == 'E')
      {
unknown's avatar
unknown committed
1616
	// The following test is written this way to allow numbers of type 1e1
1617 1618
        if (my_isdigit(cs,lip->yyPeek()) ||
            (c=(lip->yyGet())) == '+' || c == '-')
unknown's avatar
unknown committed
1619
	{				// Allow 1E+10
1620
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
unknown's avatar
unknown committed
1621
	  {
1622 1623 1624
            lip->yySkip();
            while (my_isdigit(cs,lip->yyGet())) ;
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1625 1626 1627
	    return(FLOAT_NUM);
	  }
	}
1628
        lip->yyUnget();
unknown's avatar
unknown committed
1629
      }
unknown's avatar
unknown committed
1630
      // fall through
1631
    case MY_LEX_IDENT_START:			// We come here after '.'
1632
      result_state= IDENT;
unknown's avatar
unknown committed
1633
#if defined(USE_MB) && defined(USE_MB_IDENT)
1634
      if (use_mb(cs))
unknown's avatar
unknown committed
1635
      {
1636
	result_state= IDENT_QUOTED;
1637
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
1638
        {
1639 1640 1641 1642 1643
          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
1644 1645 1646 1647
        }
      }
      else
#endif
unknown's avatar
unknown committed
1648
      {
1649 1650
        for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c)
          ;
unknown's avatar
unknown committed
1651 1652 1653
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
      }
1654
      if (c == '.' && ident_map[(uchar) lip->yyPeek()])
1655
	lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
unknown's avatar
unknown committed
1656

1657
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1658 1659 1660

      lip->body_utf8_append(lip->m_cpp_text_start);

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

1663
      return(result_state);
unknown's avatar
unknown committed
1664

1665
    case MY_LEX_USER_VARIABLE_DELIMITER:	// Found quote char
1666
    {
1667 1668
      uint double_quotes= 0;
      char quote_char= c;                       // Used char
1669
      while ((c=lip->yyGet()))
unknown's avatar
unknown committed
1670
      {
1671 1672 1673
        int var_length= my_charlen(cs, lip->get_ptr() - 1,
                                       lip->get_end_of_query());
        if (var_length == 1)
1674 1675 1676
	{
	  if (c == quote_char)
	  {
1677
            if (lip->yyPeek() != quote_char)
1678
	      break;
1679
            c=lip->yyGet();
1680 1681 1682
	    double_quotes++;
	    continue;
	  }
1683 1684
	}
#ifdef USE_MB
1685
        else if (var_length > 1)
1686
        {
1687
          lip->skip_binary(var_length - 1);
1688
        }
1689
#endif
unknown's avatar
unknown committed
1690
      }
1691
      if (double_quotes)
1692
	yylval->lex_str=get_quoted_token(lip, 1,
1693
                                         lip->yyLength() - double_quotes -1,
1694 1695
					 quote_char);
      else
1696
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
1697
      if (c == quote_char)
1698
        lip->yySkip();                  // Skip end `
1699
      lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
1700 1701 1702

      lip->body_utf8_append(lip->m_cpp_text_start);

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

1705
      return(IDENT_QUOTED);
1706
    }
1707
    case MY_LEX_INT_OR_REAL:		// Complete int or incomplete real
unknown's avatar
unknown committed
1708 1709
      if (c != '.')
      {					// Found complete integer number.
1710
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1711
	return int_token(yylval->lex_str.str, (uint) yylval->lex_str.length);
unknown's avatar
unknown committed
1712 1713
      }
      // fall through
1714
    case MY_LEX_REAL:			// Incomplete real number
1715
      while (my_isdigit(cs,c = lip->yyGet())) ;
unknown's avatar
unknown committed
1716 1717 1718

      if (c == 'e' || c == 'E')
      {
1719
        c = lip->yyGet();
unknown's avatar
unknown committed
1720
	if (c == '-' || c == '+')
1721
          c = lip->yyGet();                     // Skip sign
1722
	if (!my_isdigit(cs,c))
unknown's avatar
unknown committed
1723
	{				// No digit after sign
1724
	  state= MY_LEX_CHAR;
unknown's avatar
unknown committed
1725 1726
	  break;
	}
1727 1728
        while (my_isdigit(cs,lip->yyGet())) ;
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1729 1730
	return(FLOAT_NUM);
      }
1731
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1732
      return(DECIMAL_NUM);
unknown's avatar
unknown committed
1733

1734
    case MY_LEX_HEX_NUMBER:		// Found x'hexstring'
1735 1736 1737 1738 1739 1740 1741 1742
      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
1743 1744 1745
      yylval->lex_str=get_token(lip,
                                2,          // skip x'
                                length-3);  // don't count x' and last '
Alexander Barkov's avatar
Alexander Barkov committed
1746
      return HEX_STRING;
1747

unknown's avatar
unknown committed
1748
    case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
1749
      lip->yySkip();                  // Accept opening '
1750 1751
      while ((c= lip->yyGet()) == '0' || c == '1')
        ;
unknown's avatar
unknown committed
1752
      if (c != '\'')
1753 1754 1755
        return(ABORT_SYM);            // Illegal hex constant
      lip->yySkip();                  // Accept closing '
      length= lip->yyLength();        // Length of bin-num + 3
1756 1757 1758 1759
      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
1760

1761
    case MY_LEX_CMP_OP:			// Incomplete comparison operator
1762
      lip->next_state= MY_LEX_START;	// Allow signed numbers
1763 1764
      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
1765
      {
1766 1767 1768 1769
        lip->yySkip();
        if ((tokval= find_keyword(lip, 2, 0)))
          return(tokval);
        lip->yyUnget();
unknown's avatar
unknown committed
1770
      }
1771
      return(c);
unknown's avatar
unknown committed
1772

1773
    case MY_LEX_LONG_CMP_OP:		// Incomplete comparison operator
1774
      lip->next_state= MY_LEX_START;
1775 1776
      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
1777
      {
1778
        lip->yySkip();
1779
        if (state_map[(uchar) lip->yyPeek()] == MY_LEX_CMP_OP)
1780
        {
1781
          lip->yySkip();
1782 1783 1784 1785 1786 1787 1788
          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
1789
      }
1790
      return(c);
unknown's avatar
unknown committed
1791

1792
    case MY_LEX_BOOL:
1793
      if (c != lip->yyPeek())
unknown's avatar
unknown committed
1794
      {
1795
	state=MY_LEX_CHAR;
unknown's avatar
unknown committed
1796 1797
	break;
      }
1798
      lip->yySkip();
1799 1800
      tokval = find_keyword(lip,2,0);	// Is a bool operator
      lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1801 1802
      return(tokval);

1803
    case MY_LEX_STRING_OR_DELIMITER:
1804
      if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
1805
      {
1806
	state= MY_LEX_USER_VARIABLE_DELIMITER;
1807 1808 1809
	break;
      }
      /* " used for strings */
1810
    case MY_LEX_STRING:			// Incomplete text string
1811 1812
    {
      uint sep;
1813 1814
      if (lip->get_text(&yylval->lex_string_with_metadata,
                        (sep= lip->yyGetLast()), 1, 1))
unknown's avatar
unknown committed
1815
      {
1816
	state= MY_LEX_CHAR;		// Read char by char
unknown's avatar
unknown committed
1817 1818
	break;
      }
1819
      CHARSET_INFO *strcs= lip->m_underscore_cs ? lip->m_underscore_cs : cs;
unknown's avatar
unknown committed
1820 1821
      lip->body_utf8_append(lip->m_cpp_text_start);

1822 1823
      lip->body_utf8_append_escape(thd, &yylval->lex_string_with_metadata,
                                   strcs, lip->m_cpp_text_end, sep);
unknown's avatar
unknown committed
1824
      lip->m_underscore_cs= NULL;
unknown's avatar
unknown committed
1825
      return(TEXT_STRING);
1826
    }
1827
    case MY_LEX_COMMENT:			//  Comment
unknown's avatar
unknown committed
1828
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1829 1830
      while ((c = lip->yyGet()) != '\n' && c) ;
      lip->yyUnget();                   // Safety against eof
1831
      state = MY_LEX_START;		// Try again
unknown's avatar
unknown committed
1832
      break;
1833
    case MY_LEX_LONG_COMMENT:		/* Long C comment? */
1834
      if (lip->yyPeek() != '*')
unknown's avatar
unknown committed
1835
      {
1836
	state=MY_LEX_CHAR;		// Probable division
unknown's avatar
unknown committed
1837 1838
	break;
      }
unknown's avatar
unknown committed
1839
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1840 1841 1842
      /* Reject '/' '*', since we might need to turn off the echo */
      lip->yyUnget();

1843 1844
      lip->save_in_comment_state();

1845 1846
      if (lip->yyPeekn(2) == '!' ||
          (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!'))
unknown's avatar
unknown committed
1847
      {
1848
        bool maria_comment_syntax= lip->yyPeekn(2) == 'M';
1849 1850
        lip->in_comment= DISCARD_COMMENT;
        /* Accept '/' '*' '!', but do not keep this marker. */
unknown's avatar
unknown committed
1851
        lip->set_echo(FALSE);
1852
        lip->yySkipn(maria_comment_syntax ? 4 : 3);
1853 1854 1855

        /*
          The special comment format is very strict:
1856
          '/' '*' '!', followed by an optional 'M' and exactly
Michael Widenius's avatar
Michael Widenius committed
1857 1858 1859 1860 1861
          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
1862
        */
1863 1864 1865 1866 1867
        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))
1868 1869 1870
           )
        {
          ulong version;
1871 1872
          uint length= 5;
          char *end_ptr= (char*) lip->get_ptr()+length;
1873
          int error;
1874 1875 1876 1877 1878 1879
          if (my_isdigit(cs, lip->yyPeekn(5)))
          {
            end_ptr++;                          // 6 digit number
            length++;
          }

1880
          version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error);
1881

1882 1883 1884
          /*
            MySQL-5.7 has new features and might have new SQL syntax that
            MariaDB-10.0 does not understand. Ignore all versioned comments
1885
            with MySQL versions in the range 50700-999999, but
1886 1887 1888
            do not ignore MariaDB specific comments for the same versions.
          */ 
          if (version <= MYSQL_VERSION_ID &&
1889
              (version < 50700 || version > 99999 || maria_comment_syntax))
1890
          {
1891
            /* Accept 'M' 'm' 'm' 'd' 'd' */
1892
            lip->yySkipn(length);
1893
            /* Expand the content of the special comment as real code */
unknown's avatar
unknown committed
1894
            lip->set_echo(TRUE);
1895
            state=MY_LEX_START;
1896 1897 1898 1899
            break;  /* Do not treat contents as a comment.  */
          }
          else
          {
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910
#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 */
1911 1912 1913 1914 1915
            /*
              Patch and skip the conditional comment to avoid it
              being propagated infinitely (eg. to a slave).
            */
            char *pcom= lip->yyUnput(' ');
1916
            comment_closed= ! consume_comment(lip, 1);
1917 1918 1919 1920
            if (! comment_closed)
            {
              *pcom= '!';
            }
1921
            /* version allowed to have one level of comment inside. */
1922 1923 1924 1925
          }
        }
        else
        {
1926
          /* Not a version comment. */
1927
          state=MY_LEX_START;
unknown's avatar
unknown committed
1928
          lip->set_echo(TRUE);
1929 1930
          break;
        }
unknown's avatar
unknown committed
1931
      }
1932
      else
unknown's avatar
unknown committed
1933
      {
1934 1935 1936
        lip->in_comment= PRESERVE_COMMENT;
        lip->yySkip();                  // Accept /
        lip->yySkip();                  // Accept *
1937 1938
        comment_closed= ! consume_comment(lip, 0);
        /* regular comments can have zero comments inside. */
unknown's avatar
unknown committed
1939
      }
1940 1941 1942 1943 1944
      /*
        Discard:
        - regular '/' '*' comments,
        - special comments '/' '*' '!' for a future version,
        by scanning until we find a closing '*' '/' marker.
1945 1946 1947 1948 1949 1950 1951 1952 1953

        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.
1954
      */
1955

1956 1957 1958
      /* Unbalanced comments with a missing '*' '/' are a syntax error */
      if (! comment_closed)
        return (ABORT_SYM);
1959
      state = MY_LEX_START;             // Try again
1960
      lip->restore_in_comment_state();
unknown's avatar
unknown committed
1961
      break;
1962
    case MY_LEX_END_LONG_COMMENT:
1963
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
unknown's avatar
unknown committed
1964
      {
1965 1966 1967 1968 1969 1970
        /* 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
1971
        lip->set_echo(TRUE);
1972 1973
        lip->in_comment=NO_COMMENT;
        state=MY_LEX_START;
unknown's avatar
unknown committed
1974 1975
      }
      else
1976
	state=MY_LEX_CHAR;		// Return '*'
unknown's avatar
unknown committed
1977
      break;
1978
    case MY_LEX_SET_VAR:		// Check if ':='
1979
      if (lip->yyPeek() != '=')
unknown's avatar
unknown committed
1980
      {
1981
	state=MY_LEX_CHAR;		// Return ':'
unknown's avatar
unknown committed
1982 1983
	break;
      }
1984
      lip->yySkip();
unknown's avatar
unknown committed
1985
      return (SET_VAR);
1986
    case MY_LEX_SEMICOLON:			// optional line terminator
1987 1988
      state= MY_LEX_CHAR;               // Return ';'
      break;
1989
    case MY_LEX_EOL:
1990
      if (lip->eof())
unknown's avatar
unknown committed
1991
      {
1992
        lip->yyUnget();                 // Reject the last '\0'
unknown's avatar
unknown committed
1993
        lip->set_echo(FALSE);
1994
        lip->yySkip();
unknown's avatar
unknown committed
1995
        lip->set_echo(TRUE);
1996 1997 1998
        /* Unbalanced comments with a missing '*' '/' are a syntax error */
        if (lip->in_comment != NO_COMMENT)
          return (ABORT_SYM);
1999 2000
        lip->next_state=MY_LEX_END;     // Mark for next loop
        return(END_OF_INPUT);
unknown's avatar
unknown committed
2001 2002 2003
      }
      state=MY_LEX_CHAR;
      break;
2004
    case MY_LEX_END:
2005
      lip->next_state=MY_LEX_END;
unknown's avatar
unknown committed
2006
      return(0);			// We found end of input last time
2007

2008
      /* Actually real shouldn't start with . but allow them anyhow */
2009
    case MY_LEX_REAL_OR_POINT:
2010
      if (my_isdigit(cs,(c= lip->yyPeek())))
2011
	state = MY_LEX_REAL;		// Real
2012 2013 2014 2015 2016
      else if (c == '.')
      {
        lip->yySkip();
        return DOT_DOT_SYM;
      }
unknown's avatar
unknown committed
2017 2018
      else
      {
2019
	state= MY_LEX_IDENT_SEP;	// return '.'
2020
        lip->yyUnget();                 // Put back '.'
unknown's avatar
unknown committed
2021 2022
      }
      break;
2023
    case MY_LEX_USER_END:		// end '@' of user@hostname
2024
      switch (state_map[(uchar) lip->yyPeek()]) {
2025 2026 2027
      case MY_LEX_STRING:
      case MY_LEX_USER_VARIABLE_DELIMITER:
      case MY_LEX_STRING_OR_DELIMITER:
unknown's avatar
unknown committed
2028
	break;
2029
      case MY_LEX_USER_END:
2030
	lip->next_state=MY_LEX_SYSTEM_VAR;
unknown's avatar
unknown committed
2031 2032
	break;
      default:
2033
	lip->next_state=MY_LEX_HOSTNAME;
unknown's avatar
unknown committed
2034 2035
	break;
      }
2036
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
2037 2038
      yylval->lex_str.length=1;
      return((int) '@');
2039
    case MY_LEX_HOSTNAME:		// end '@' of user@hostname
2040
      for (c=lip->yyGet() ;
2041
	   my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
2042 2043
           c= lip->yyGet()) ;
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
2044
      return(LEX_HOSTNAME);
2045
    case MY_LEX_SYSTEM_VAR:
2046
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
2047
      yylval->lex_str.length=1;
2048
      lip->yySkip();                                    // Skip '@'
2049
      lip->next_state= (state_map[(uchar) lip->yyPeek()] ==
2050 2051 2052
			MY_LEX_USER_VARIABLE_DELIMITER ?
			MY_LEX_OPERATOR_OR_IDENT :
			MY_LEX_IDENT_OR_KEYWORD);
unknown's avatar
unknown committed
2053
      return((int) '@');
2054
    case MY_LEX_IDENT_OR_KEYWORD:
unknown's avatar
unknown committed
2055 2056 2057 2058 2059
      /*
	We come here when we have found two '@' in a row.
	We should now be able to handle:
	[(global | local | session) .]variable_name
      */
2060

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

unknown's avatar
unknown committed
2066
      if (c == '.')
2067
	lip->next_state=MY_LEX_IDENT_SEP;
2068 2069
      length= lip->yyLength();
      if (length == 0)
unknown's avatar
unknown committed
2070
        return(ABORT_SYM);              // Names must be nonempty.
2071
      if ((tokval= find_keyword(lip, length,0)))
unknown's avatar
unknown committed
2072
      {
2073
        lip->yyUnget();                         // Put back 'c'
unknown's avatar
unknown committed
2074 2075
	return(tokval);				// Was keyword
      }
2076
      yylval->lex_str=get_token(lip, 0, length);
unknown's avatar
unknown committed
2077 2078 2079

      lip->body_utf8_append(lip->m_cpp_text_start);

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

2082
      return(result_state);
unknown's avatar
unknown committed
2083 2084 2085
    }
  }
}
unknown's avatar
unknown committed
2086

2087

2088
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str, uint *prefix_length)
2089 2090 2091 2092 2093 2094
{
  /*
    TODO:
    This code assumes that there are no multi-bytes characters
    that can be considered white-space.
  */
2095

2096
  *prefix_length= 0;
2097 2098
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
  {
2099
    (*prefix_length)++;
2100 2101 2102
    str->length --;
    str->str ++;
  }
2103

2104 2105 2106 2107 2108 2109 2110 2111
  /*
    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 --;
  }
2112 2113
}

2114

unknown's avatar
unknown committed
2115 2116 2117 2118 2119 2120
/*
  st_select_lex structures initialisations
*/

void st_select_lex_node::init_query()
{
2121
  options= 0;
2122
  sql_cache= SQL_CACHE_UNSPECIFIED;
2123
  linkage= UNSPECIFIED_TYPE;
Michael Widenius's avatar
Michael Widenius committed
2124
  no_table_names_allowed= 0;
2125
  uncacheable= 0;
unknown's avatar
unknown committed
2126 2127 2128 2129 2130 2131 2132 2133 2134
}

void st_select_lex_node::init_select()
{
}

void st_select_lex_unit::init_query()
{
  st_select_lex_node::init_query();
2135
  linkage= GLOBAL_OPTIONS_TYPE;
2136 2137
  select_limit_cnt= HA_POS_ERROR;
  offset_limit_cnt= 0;
2138
  union_distinct= 0;
unknown's avatar
unknown committed
2139
  prepared= optimized= executed= 0;
Igor Babaev's avatar
Igor Babaev committed
2140
  optimize_started= 0;
unknown's avatar
unknown committed
2141
  item= 0;
2142 2143
  union_result= 0;
  table= 0;
unknown's avatar
unknown committed
2144
  fake_select_lex= 0;
2145
  saved_fake_select_lex= 0;
2146
  cleaned= 0;
2147
  item_list.empty();
2148
  describe= 0;
2149
  found_rows_for_union= 0;
2150
  derived= 0;
2151
  is_view= false;
2152 2153
  with_clause= 0;
  with_element= 0;
2154
  columns_are_renamed= false;
2155
  intersect_mark= NULL;
unknown's avatar
unknown committed
2156 2157 2158 2159 2160
}

void st_select_lex::init_query()
{
  st_select_lex_node::init_query();
2161
  table_list.empty();
2162 2163
  top_join_list.empty();
  join_list= &top_join_list;
2164
  embedding= 0;
Igor Babaev's avatar
Igor Babaev committed
2165
  leaf_tables_prep.empty();
2166
  leaf_tables.empty();
unknown's avatar
unknown committed
2167
  item_list.empty();
unknown's avatar
unknown committed
2168
  join= 0;
2169
  having= prep_having= where= prep_where= 0;
Igor Babaev's avatar
Igor Babaev committed
2170
  cond_pushed_into_where= cond_pushed_into_having= 0;
2171
  olap= UNSPECIFIED_OLAP_TYPE;
2172
  having_fix_field= 0;
2173 2174
  context.select_lex= this;
  context.init();
unknown's avatar
unknown committed
2175 2176 2177
  /*
    Add the name resolution context of the current (sub)query to the
    stack of contexts for the whole query.
2178 2179 2180 2181 2182
    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
2183
  */
2184
  parent_lex->push_context(&context, parent_lex->thd->mem_root);
2185
  cond_count= between_count= with_wild= 0;
unknown's avatar
unknown committed
2186
  max_equal_elems= 0;
2187
  ref_pointer_array.reset();
unknown's avatar
unknown committed
2188
  select_n_where_fields= 0;
unknown's avatar
unknown committed
2189
  select_n_reserved= 0;
unknown's avatar
unknown committed
2190
  select_n_having_items= 0;
2191
  n_sum_items= 0;
2192
  n_child_sum_items= 0;
2193
  subquery_in_having= explicit_limit= 0;
2194
  is_item_list_lookup= 0;
2195
  first_execution= 1;
2196
  first_natural_join_processing= 1;
unknown's avatar
unknown committed
2197
  first_cond_optimization= 1;
2198
  parsing_place= NO_MATTER;
2199
  exclude_from_table_unique_test= no_wrap_view_item= FALSE;
unknown's avatar
unknown committed
2200
  nest_level= 0;
2201
  link_next= 0;
2202
  prep_leaf_list_state= UNINIT;
2203
  have_merged_subqueries= FALSE;
unknown's avatar
unknown committed
2204
  bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
2205
  select_list_tables= 0;
2206 2207
  m_non_agg_field_used= false;
  m_agg_func_used= false;
2208 2209
  window_specs.empty();
  window_funcs.empty();
unknown's avatar
unknown committed
2210 2211 2212 2213 2214
}

void st_select_lex::init_select()
{
  st_select_lex_node::init_select();
2215
  sj_nests.empty();
Igor Babaev's avatar
Igor Babaev committed
2216
  sj_subselects.empty();
2217
  group_list.empty();
2218 2219
  if (group_list_ptrs)
    group_list_ptrs->clear();
unknown's avatar
unknown committed
2220
  type= db= 0;
2221 2222 2223
  having= 0;
  table_join_options= 0;
  in_sum_expr= with_wild= 0;
unknown's avatar
unknown committed
2224
  options= 0;
2225
  sql_cache= SQL_CACHE_UNSPECIFIED;
unknown's avatar
unknown committed
2226
  ftfunc_list_alloc.empty();
unknown's avatar
unknown committed
2227
  inner_sum_func_list= 0;
unknown's avatar
unknown committed
2228
  ftfunc_list= &ftfunc_list_alloc;
unknown's avatar
unknown committed
2229 2230
  order_list.elements= 0;
  order_list.first= 0;
2231
  order_list.next= &order_list.first;
2232 2233 2234
  /* 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
2235
  with_sum_func= 0;
2236
  is_correlated= 0;
2237
  cur_pos_in_select_list= UNDEF_POS;
2238
  cond_value= having_value= Item::COND_UNDEF;
2239
  inner_refs_list.empty();
2240
  insert_tables= 0;
Igor Babaev's avatar
Igor Babaev committed
2241
  merged_into= 0;
2242 2243
  m_non_agg_field_used= false;
  m_agg_func_used= false;
unknown's avatar
unknown committed
2244
  name_visibility_map= 0;
2245
  with_dep= 0;
2246
  join= 0;
2247
  lock_type= TL_READ_DEFAULT;
unknown's avatar
unknown committed
2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
}

/*
  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
2262
  slave= 0;
unknown's avatar
unknown committed
2263 2264
}

unknown's avatar
unknown committed
2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289

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
2290 2291
/*
  include on level down (but do not link)
unknown's avatar
unknown committed
2292

unknown's avatar
unknown committed
2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306
  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
2307 2308 2309 2310 2311 2312 2313 2314
/* 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
2315
  slave= 0;
unknown's avatar
unknown committed
2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329
}

/* 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
2330
  if (link_prev)
unknown's avatar
unknown committed
2331 2332 2333 2334
  {
    if ((*link_prev= link_next))
      link_next->link_prev= link_prev;
  }
2335 2336 2337 2338
  // Remove slave structure
  for (; slave; slave= slave->next)
    slave->fast_exclude();
  
unknown's avatar
unknown committed
2339 2340
}

2341

2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
/**
  @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;
}

2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384
/*
  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
2385
/*
2386
  Exclude select_lex structure (except first (first select can't be
unknown's avatar
unknown committed
2387 2388 2389 2390
  deleted, because it is most upper select))
*/
void st_select_lex_node::exclude()
{
2391
  /* exclude from global list */
unknown's avatar
unknown committed
2392
  fast_exclude();
2393 2394
  /* exclude from other structures */
  exclude_from_tree();
unknown's avatar
unknown committed
2395 2396 2397 2398 2399 2400 2401
  /* 
     We do not need following statements, because prev pointer of first 
     list element point to master->slave
     if (master->slave == this)
       master->slave= next;
  */
}
2402

2403 2404 2405 2406 2407 2408 2409 2410 2411 2412

/*
  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
2413 2414 2415
void st_select_lex_unit::exclude_level()
{
  SELECT_LEX_UNIT *units= 0, **units_last= &units;
unknown's avatar
unknown committed
2416
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
unknown's avatar
unknown committed
2417
  {
unknown's avatar
unknown committed
2418
    // unlink current level from global SELECTs list
unknown's avatar
unknown committed
2419 2420
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;
unknown's avatar
unknown committed
2421 2422

    // bring up underlay levels
unknown's avatar
unknown committed
2423 2424
    SELECT_LEX_UNIT **last= 0;
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
unknown's avatar
unknown committed
2425 2426
    {
      u->master= master;
unknown's avatar
unknown committed
2427
      last= (SELECT_LEX_UNIT**)&(u->next);
unknown's avatar
unknown committed
2428
    }
unknown's avatar
unknown committed
2429 2430 2431 2432 2433 2434 2435 2436
    if (last)
    {
      (*units_last)= sl->first_inner_unit();
      units_last= last;
    }
  }
  if (units)
  {
unknown's avatar
unknown committed
2437
    // include brought up levels in place of current
unknown's avatar
unknown committed
2438 2439
    (*prev)= units;
    (*units_last)= (SELECT_LEX_UNIT*)next;
unknown's avatar
unknown committed
2440 2441 2442
    if (next)
      next->prev= (SELECT_LEX_NODE**)units_last;
    units->prev= prev;
unknown's avatar
unknown committed
2443 2444
  }
  else
unknown's avatar
unknown committed
2445 2446
  {
    // exclude currect unit from list of nodes
unknown's avatar
unknown committed
2447
    (*prev)= next;
unknown's avatar
unknown committed
2448 2449 2450
    if (next)
      next->prev= prev;
  }
2451 2452
  // Mark it excluded
  prev= NULL;
unknown's avatar
unknown committed
2453 2454
}

2455

Oleksandr Byelkin's avatar
Oleksandr Byelkin committed
2456
#if 0
2457 2458 2459 2460 2461 2462 2463 2464 2465 2466
/*
  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
2467
    // unlink current level from global SELECTs list
2468 2469 2470
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;

unknown's avatar
unknown committed
2471
    // unlink underlay levels
2472 2473 2474 2475 2476
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
    {
      u->exclude_level();
    }
  }
unknown's avatar
unknown committed
2477
  // exclude currect unit from list of nodes
2478
  (*prev)= next;
unknown's avatar
unknown committed
2479 2480
  if (next)
    next->prev= prev;
2481
}
Oleksandr Byelkin's avatar
Oleksandr Byelkin committed
2482
#endif
2483 2484


unknown's avatar
unknown committed
2485 2486 2487 2488 2489
/*
  st_select_lex_node::mark_as_dependent mark all st_select_lex struct from 
  this to 'last' as dependent

  SYNOPSIS
2490
    last - pointer to last st_select_lex struct, before which all 
unknown's avatar
unknown committed
2491 2492 2493 2494 2495 2496
           st_select_lex have to be marked as dependent

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

2497 2498
bool st_select_lex::mark_as_dependent(THD *thd, st_select_lex *last,
                                      Item *dependency)
unknown's avatar
unknown committed
2499
{
2500 2501 2502

  DBUG_ASSERT(this != last);

unknown's avatar
unknown committed
2503 2504 2505 2506
  /*
    Mark all selects from resolved to 1 before select where was
    found table as depended (of select where was found table)
  */
2507 2508
  SELECT_LEX *s= this;
  do
Sergey Petrunya's avatar
Sergey Petrunya committed
2509
  {
2510
    if (!(s->uncacheable & UNCACHEABLE_DEPENDENT_GENERATED))
unknown's avatar
unknown committed
2511 2512
    {
      // Select is dependent of outer select
2513
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
2514
                       UNCACHEABLE_DEPENDENT_GENERATED;
2515
      SELECT_LEX_UNIT *munit= s->master_unit();
2516
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
2517
                       UNCACHEABLE_DEPENDENT_GENERATED;
2518 2519 2520
      for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
      {
        if (sl != s &&
2521 2522
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT_GENERATED |
                                 UNCACHEABLE_UNITED)))
2523 2524
          sl->uncacheable|= UNCACHEABLE_UNITED;
      }
unknown's avatar
unknown committed
2525
    }
2526 2527 2528 2529 2530

    Item_subselect *subquery_expr= s->master_unit()->item;
    if (subquery_expr && subquery_expr->mark_as_dependent(thd, last, 
                                                          dependency))
      return TRUE;
2531
  } while ((s= s->outer_select()) != last && s != 0);
2532 2533
  is_correlated= TRUE;
  this->master_unit()->item->is_correlated= TRUE;
2534
  return FALSE;
unknown's avatar
unknown committed
2535 2536
}

2537 2538 2539 2540
bool st_select_lex_node::inc_in_sum_expr()           { return 1; }
uint st_select_lex_node::get_in_sum_expr()           { return 0; }
TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
List<Item>* st_select_lex_node::get_item_list()      { return 0; }
2541
TABLE_LIST *st_select_lex_node::add_table_to_list(THD *thd, Table_ident *table,
2542
						  LEX_STRING *alias,
unknown's avatar
unknown committed
2543
						  ulong table_join_options,
2544
						  thr_lock_type flags,
2545
                                                  enum_mdl_type mdl_type,
unknown's avatar
unknown committed
2546
						  List<Index_hint> *hints,
2547
                                                  List<String> *partition_names,
unknown's avatar
unknown committed
2548
                                                  LEX_STRING *option)
2549 2550 2551
{
  return 0;
}
unknown's avatar
unknown committed
2552 2553 2554 2555 2556 2557 2558 2559
ulong st_select_lex_node::get_table_join_options()
{
  return 0;
}

/*
  prohibit using LIMIT clause
*/
unknown's avatar
unknown committed
2560
bool st_select_lex::test_limit()
unknown's avatar
unknown committed
2561
{
2562
  if (select_limit != 0)
unknown's avatar
unknown committed
2563 2564
  {
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
unknown's avatar
unknown committed
2565
             "LIMIT & IN/ALL/ANY/SOME subquery");
unknown's avatar
unknown committed
2566 2567 2568 2569
    return(1);
  }
  return(0);
}
2570

2571

2572

2573 2574 2575 2576 2577
st_select_lex* st_select_lex_unit::outer_select()
{
  return (st_select_lex*) master;
}

2578

2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647
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
2648
bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
unknown's avatar
unknown committed
2649
{
unknown's avatar
unknown committed
2650
  return add_to_list(thd, order_list, item, asc);
unknown's avatar
unknown committed
2651
}
2652

2653

2654 2655 2656 2657 2658
bool st_select_lex::add_gorder_to_list(THD *thd, Item *item, bool asc)
{
  return add_to_list(thd, gorder_list, item, asc);
}

2659

unknown's avatar
unknown committed
2660
bool st_select_lex::add_item_to_list(THD *thd, Item *item)
2661
{
2662
  DBUG_ENTER("st_select_lex::add_item_to_list");
unknown's avatar
unknown committed
2663
  DBUG_PRINT("info", ("Item: 0x%lx", (long) item));
2664
  DBUG_RETURN(item_list.push_back(item, thd->mem_root));
2665 2666
}

2667

unknown's avatar
unknown committed
2668
bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc)
2669
{
unknown's avatar
unknown committed
2670
  return add_to_list(thd, group_list, item, asc);
2671 2672
}

2673

2674
bool st_select_lex::add_ftfunc_to_list(THD *thd, Item_func_match *func)
2675
{
2676
  return !func || ftfunc_list->push_back(func, thd->mem_root); // end of memory?
2677 2678
}

2679

2680 2681 2682 2683 2684
st_select_lex* st_select_lex::outer_select()
{
  return (st_select_lex*) master->get_master();
}

2685

2686 2687 2688 2689 2690 2691
bool st_select_lex::inc_in_sum_expr()
{
  in_sum_expr++;
  return 0;
}

2692

2693 2694 2695 2696 2697
uint st_select_lex::get_in_sum_expr()
{
  return in_sum_expr;
}

2698

2699 2700
TABLE_LIST* st_select_lex::get_table_list()
{
2701
  return table_list.first;
2702 2703 2704 2705 2706 2707 2708
}

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

unknown's avatar
unknown committed
2709 2710 2711 2712 2713
ulong st_select_lex::get_table_join_options()
{
  return table_join_options;
}

2714

unknown's avatar
unknown committed
2715 2716
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{
2717 2718 2719
  // find_order_in_list() may need some extra space, so multiply by two.
  order_group_num*= 2;

2720
  /*
2721
    We have to create array in prepared statement memory if it is a
2722 2723
    prepared statement
  */
unknown's avatar
unknown committed
2724
  Query_arena *arena= thd->stmt_arena;
2725 2726 2727
  const uint n_elems= (n_sum_items +
                       n_child_sum_items +
                       item_list.elements +
Sergei Golubchik's avatar
Sergei Golubchik committed
2728
                       select_n_reserved +
2729 2730 2731
                       select_n_having_items +
                       select_n_where_fields +
                       order_group_num) * 5;
2732
  if (!ref_pointer_array.is_null())
2733 2734 2735 2736 2737 2738 2739 2740
  {
    /*
      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.
    */
2741
    if (ref_pointer_array.size() == n_elems)
2742 2743
      return false;

2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758
    /*
      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.
     */
    if (ref_pointer_array.size() == n_elems)
      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
2759 2760
}

2761

2762
void st_select_lex_unit::print(String *str, enum_query_type query_type)
unknown's avatar
unknown committed
2763
{
2764
  bool union_all= !union_distinct;
2765 2766
  if (with_clause)
    with_clause->print(str, query_type);
unknown's avatar
unknown committed
2767 2768 2769 2770
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
  {
    if (sl != first_select())
    {
2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788
      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
2789 2790 2791
    }
    if (sl->braces)
      str->append('(');
2792
    sl->print(thd, str, query_type);
unknown's avatar
unknown committed
2793 2794 2795
    if (sl->braces)
      str->append(')');
  }
2796
  if (fake_select_lex)
unknown's avatar
unknown committed
2797 2798 2799
  {
    if (fake_select_lex->order_list.elements)
    {
2800
      str->append(STRING_WITH_LEN(" order by "));
2801 2802
      fake_select_lex->print_order(str,
        fake_select_lex->order_list.first,
2803
        query_type);
unknown's avatar
unknown committed
2804
    }
2805
    fake_select_lex->print_limit(thd, str, query_type);
unknown's avatar
unknown committed
2806
  }
2807 2808
  else if (saved_fake_select_lex)
    saved_fake_select_lex->print_limit(thd, str, query_type);
unknown's avatar
unknown committed
2809 2810 2811
}


2812 2813 2814
void st_select_lex::print_order(String *str,
                                ORDER *order,
                                enum_query_type query_type)
unknown's avatar
unknown committed
2815 2816 2817
{
  for (; order; order= order->next)
  {
2818 2819
    if (order->counter_used)
    {
2820 2821 2822 2823 2824 2825 2826 2827 2828
      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 */
      if (order->item[0]->type() == Item::INT_ITEM &&
          order->item[0]->basic_const_item())
2829
      {
2830 2831
        /* make it expression instead of integer constant */
        str->append(STRING_WITH_LEN("''"));
2832 2833
      }
      else
2834
        (*order->item)->print(str, query_type);
2835
    }
2836 2837
    if (order->direction == ORDER::ORDER_DESC)
       str->append(STRING_WITH_LEN(" desc"));
unknown's avatar
unknown committed
2838 2839 2840 2841 2842
    if (order->next)
      str->append(',');
  }
}
 
2843

2844 2845 2846
void st_select_lex::print_limit(THD *thd,
                                String *str,
                                enum_query_type query_type)
unknown's avatar
unknown committed
2847
{
2848 2849
  SELECT_LEX_UNIT *unit= master_unit();
  Item_subselect *item= unit->item;
2850

2851
  if (item && unit->global_parameters() == this)
unknown's avatar
VIEW  
unknown committed
2852
  {
2853 2854 2855 2856 2857 2858 2859
    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
2860
  }
2861
  if (explicit_limit)
unknown's avatar
unknown committed
2862
  {
2863
    str->append(STRING_WITH_LEN(" limit "));
unknown's avatar
unknown committed
2864 2865
    if (offset_limit)
    {
2866
      offset_limit->print(str, query_type);
unknown's avatar
unknown committed
2867 2868
      str->append(',');
    }
2869
    select_limit->print(str, query_type);
unknown's avatar
unknown committed
2870 2871 2872
  }
}

2873

2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885
/**
  @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
2886
void LEX::cleanup_lex_after_parse_error(THD *thd)
2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897
{
  /*
    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
  */
2898
  if (thd->lex->sphead)
2899
  {
2900
    thd->lex->sphead->restore_thd_mem_root(thd);
2901 2902 2903 2904
    delete thd->lex->sphead;
    thd->lex->sphead= NULL;
  }
}
unknown's avatar
VIEW  
unknown committed
2905

2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925
/*
  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)
{
2926
  sql_command= SQLCOM_END;
unknown's avatar
unknown committed
2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937
  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;
    }
  }
2938 2939 2940 2941
  query_tables= 0;
  query_tables_last= &query_tables;
  query_tables_own_last= 0;
  if (init)
2942 2943 2944 2945 2946
  {
    /*
      We delay real initialization of hash (and therefore related
      memory allocation) until first insertion into this hash.
    */
Konstantin Osipov's avatar
Konstantin Osipov committed
2947
    my_hash_clear(&sroutines);
2948
  }
2949
  else if (sroutines.records)
2950 2951
  {
    /* Non-zero sroutines.records means that hash was initialized. */
2952
    my_hash_reset(&sroutines);
2953
  }
2954 2955 2956
  sroutines_list.empty();
  sroutines_list_own_last= sroutines_list.next;
  sroutines_list_own_elements= 0;
2957
  binlog_stmt_flags= 0;
2958
  stmt_accessed_table_flag= 0;
2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970
}


/*
  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
2971
  my_hash_free(&sroutines);
2972 2973 2974
}


2975 2976 2977 2978
/*
  Initialize LEX object.

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
2979
    LEX::LEX()
2980 2981 2982 2983 2984 2985 2986 2987 2988

  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
2989
LEX::LEX()
2990
  : explain(NULL),
2991
    result(0), arena_for_set_stmt(0), mem_root_for_set_stmt(0),
2992
    option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0),
2993
    is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX)
2994
{
unknown's avatar
unknown committed
2995

2996 2997 2998
  init_dynamic_array2(&plugins, sizeof(plugin_ref), plugins_static_buffer,
                      INITIAL_LEX_PLUGIN_LIST_SIZE,
                      INITIAL_LEX_PLUGIN_LIST_SIZE, 0);
2999
  reset_query_tables_list(TRUE);
3000
  mi.init();
3001 3002 3003
}


unknown's avatar
VIEW  
unknown committed
3004
/*
3005
  Check whether the merging algorithm can be used on this VIEW
unknown's avatar
VIEW  
unknown committed
3006 3007

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3008
    LEX::can_be_merged()
unknown's avatar
VIEW  
unknown committed
3009

3010
  DESCRIPTION
3011 3012 3013
    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,
3014 3015 3016
    HAVING clause, aggregate functions, DISTINCT clause, LIMIT clause and
    several underlying tables.

unknown's avatar
VIEW  
unknown committed
3017 3018 3019 3020 3021
  RETURN
    FALSE - only temporary table algorithm can be used
    TRUE  - merge algorithm can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3022
bool LEX::can_be_merged()
unknown's avatar
VIEW  
unknown committed
3023 3024 3025 3026
{
  // TODO: do not forget implement case when select_lex.table_list.elements==0

  /* find non VIEW subqueries/unions */
3027 3028 3029
  bool selects_allow_merge= (select_lex.next_select() == 0 &&
                             !(select_lex.uncacheable &
                               UNCACHEABLE_RAND));
3030 3031
  if (selects_allow_merge)
  {
3032 3033 3034
    for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit();
         tmp_unit;
         tmp_unit= tmp_unit->next_unit())
3035
    {
3036
      if (tmp_unit->first_select()->parent_lex == this &&
3037
          (tmp_unit->item != 0 &&
3038
           (tmp_unit->item->place() != IN_WHERE &&
3039 3040
            tmp_unit->item->place() != IN_ON &&
            tmp_unit->item->place() != SELECT_LIST)))
3041 3042 3043 3044 3045 3046 3047 3048
      {
        selects_allow_merge= 0;
        break;
      }
    }
  }

  return (selects_allow_merge &&
unknown's avatar
VIEW  
unknown committed
3049 3050
	  select_lex.group_list.elements == 0 &&
	  select_lex.having == 0 &&
3051
          select_lex.with_sum_func == 0 &&
3052
	  select_lex.table_list.elements >= 1 &&
unknown's avatar
VIEW  
unknown committed
3053
	  !(select_lex.options & SELECT_DISTINCT) &&
3054
          select_lex.select_limit == 0);
unknown's avatar
VIEW  
unknown committed
3055 3056
}

3057

unknown's avatar
VIEW  
unknown committed
3058
/*
3059
  check if command can use VIEW with MERGE algorithm (for top VIEWs)
unknown's avatar
VIEW  
unknown committed
3060 3061

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3062
    LEX::can_use_merged()
unknown's avatar
VIEW  
unknown committed
3063

3064 3065 3066
  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
3067
    LEX::can_not_use_merged() is not TRUE).
3068

unknown's avatar
VIEW  
unknown committed
3069 3070 3071 3072 3073
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3074
bool LEX::can_use_merged()
unknown's avatar
VIEW  
unknown committed
3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087
{
  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:
3088
  case SQLCOM_LOAD:
unknown's avatar
VIEW  
unknown committed
3089 3090 3091 3092 3093 3094
    return TRUE;
  default:
    return FALSE;
  }
}

3095
/*
3096
  Check if command can't use merged views in any part of command
3097 3098

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3099
    LEX::can_not_use_merged()
3100

3101 3102
  DESCRIPTION
    Temporary table algorithm will be used on all SELECT levels for queries
Konstantin Osipov's avatar
Konstantin Osipov committed
3103
    listed here (see also LEX::can_use_merged()).
3104

3105 3106 3107 3108 3109
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3110
bool LEX::can_not_use_merged()
3111 3112 3113 3114 3115
{
  switch (sql_command)
  {
  case SQLCOM_CREATE_VIEW:
  case SQLCOM_SHOW_CREATE:
3116 3117 3118 3119 3120 3121
  /*
    SQLCOM_SHOW_FIELDS is necessary to make 
    information schema tables working correctly with views.
    see get_schema_tables_result function
  */
  case SQLCOM_SHOW_FIELDS:
3122 3123 3124 3125 3126 3127
    return TRUE;
  default:
    return FALSE;
  }
}

unknown's avatar
VIEW  
unknown committed
3128 3129 3130 3131 3132 3133 3134 3135 3136 3137
/*
  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
3138

Konstantin Osipov's avatar
Konstantin Osipov committed
3139
bool LEX::only_view_structure()
unknown's avatar
VIEW  
unknown committed
3140
{
3141
  switch (sql_command) {
unknown's avatar
VIEW  
unknown committed
3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155
  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
3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167
/*
  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
3168
bool LEX::need_correct_ident()
unknown's avatar
unknown committed
3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180
{
  switch(sql_command)
  {
  case SQLCOM_SHOW_CREATE:
  case SQLCOM_SHOW_TABLES:
  case SQLCOM_CREATE_VIEW:
    return TRUE;
  default:
    return FALSE;
  }
}

3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197
/*
  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
3198
uint8 LEX::get_effective_with_check(TABLE_LIST *view)
3199 3200 3201 3202 3203 3204 3205
{
  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
3206

3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226
/**
  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
*/

bool
Konstantin Osipov's avatar
Konstantin Osipov committed
3227
LEX::copy_db_to(char **p_db, size_t *p_db_length) const
3228
{
3229
  if (sphead && sphead->m_name.str)
3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243
  {
    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.
    */
    *p_db= sphead->m_db.str;
    if (p_db_length)
      *p_db_length= sphead->m_db.length;
    return FALSE;
  }
  return thd->copy_db_to(p_db, p_db_length);
}

3244 3245
/**
  Initialize offset and limit counters.
unknown's avatar
unknown committed
3246

3247
  @param sl SELECT_LEX to get offset and limit from.
unknown's avatar
unknown committed
3248
*/
unknown's avatar
VIEW  
unknown committed
3249

unknown's avatar
unknown committed
3250
void st_select_lex_unit::set_limit(st_select_lex *sl)
3251
{
3252
  DBUG_ASSERT(!thd->stmt_arena->is_stmt_prepare());
3253

3254 3255 3256 3257
  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;
3258
  else
3259 3260
    select_limit_cnt= HA_POS_ERROR;
}
3261 3262


3263 3264
/**
  Decide if a temporary table is needed for the UNION.
3265

3266 3267 3268
  @retval true  A temporary table is needed.
  @retval false A temporary table is not needed.
 */
3269

3270 3271
bool st_select_lex_unit::union_needs_tmp_table()
{
3272 3273
  if (with_element && with_element->is_recursive)
    return true;
3274 3275 3276 3277 3278
  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
3279

3280
/**
3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300
  @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.
3301 3302
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3303
void LEX::set_trg_event_type_for_tables()
3304
{
3305
  uint8 new_trg_event_map= 0;
3306
  DBUG_ENTER("LEX::set_trg_event_type_for_tables");
3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404

  /*
    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:
    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;
  }


3405 3406 3407 3408 3409 3410 3411 3412
  /*
    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)
  {
3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423
    /*
      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;
3424 3425
    tables= tables->next_local;
  }
3426
  DBUG_VOID_RETURN;
3427 3428 3429
}


3430
/*
3431 3432
  Unlink the first table from the global table list and the first table from
  outer select (lex->select_lex) local list
3433 3434 3435

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

unknown's avatar
VIEW  
unknown committed
3438
  NOTES
3439 3440
    We assume that first tables in both lists is the same table or the local
    list is empty.
3441 3442

  RETURN
3443
    0	If 'query_tables' == 0
unknown's avatar
VIEW  
unknown committed
3444
    unlinked table
3445
      In this case link_to_local is set.
unknown's avatar
unknown committed
3446

3447
*/
Konstantin Osipov's avatar
Konstantin Osipov committed
3448
TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
3449
{
unknown's avatar
VIEW  
unknown committed
3450 3451 3452 3453 3454 3455 3456 3457
  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;
3458 3459
    else
      query_tables_last= &query_tables;
unknown's avatar
VIEW  
unknown committed
3460 3461 3462 3463 3464
    first->next_global= 0;

    /*
      and from local list if it is not empty
    */
3465
    if ((*link_to_local= MY_TEST(select_lex.table_list.first)))
unknown's avatar
VIEW  
unknown committed
3466
    {
3467 3468
      select_lex.context.table_list= 
        select_lex.context.first_name_resolution_table= first->next_local;
3469
      select_lex.table_list.first= first->next_local;
unknown's avatar
VIEW  
unknown committed
3470 3471 3472
      select_lex.table_list.elements--;	//safety
      first->next_local= 0;
      /*
3473 3474
        Ensure that the global list has the same first table as the local
        list.
unknown's avatar
VIEW  
unknown committed
3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487
      */
      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
3488
     LEX::first_lists_tables_same()
unknown's avatar
VIEW  
unknown committed
3489 3490

  NOTES
3491 3492 3493 3494 3495 3496
    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
3497 3498
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3499
void LEX::first_lists_tables_same()
unknown's avatar
VIEW  
unknown committed
3500
{
3501
  TABLE_LIST *first_table= select_lex.table_list.first;
unknown's avatar
VIEW  
unknown committed
3502 3503
  if (query_tables != first_table && first_table != 0)
  {
3504
    TABLE_LIST *next;
unknown's avatar
VIEW  
unknown committed
3505 3506
    if (query_tables_last == &first_table->next_global)
      query_tables_last= first_table->prev_global;
3507

3508 3509 3510
    if (query_tables_own_last == &first_table->next_global)
      query_tables_own_last= first_table->prev_global;

3511
    if ((next= *first_table->prev_global= first_table->next_global))
unknown's avatar
VIEW  
unknown committed
3512 3513 3514 3515
      next->prev_global= first_table->prev_global;
    /* include in new place */
    first_table->next_global= query_tables;
    /*
3516 3517 3518
       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
3519 3520 3521 3522 3523
    */
    query_tables->prev_global= &first_table->next_global;
    first_table->prev_global= &query_tables;
    query_tables= first_table;
  }
3524 3525
}

unknown's avatar
unknown committed
3526

3527
/*
unknown's avatar
unknown committed
3528
  Link table back that was unlinked with unlink_first_table()
3529 3530 3531

  SYNOPSIS
    link_first_table_back()
unknown's avatar
VIEW  
unknown committed
3532
    link_to_local	do we need link this table to local
3533 3534 3535 3536

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

Konstantin Osipov's avatar
Konstantin Osipov committed
3538
void LEX::link_first_table_back(TABLE_LIST *first,
unknown's avatar
VIEW  
unknown committed
3539
				   bool link_to_local)
3540
{
unknown's avatar
VIEW  
unknown committed
3541
  if (first)
3542
  {
unknown's avatar
VIEW  
unknown committed
3543 3544
    if ((first->next_global= query_tables))
      query_tables->prev_global= &first->next_global;
3545 3546
    else
      query_tables_last= &first->next_global;
unknown's avatar
VIEW  
unknown committed
3547 3548 3549 3550
    query_tables= first;

    if (link_to_local)
    {
3551
      first->next_local= select_lex.table_list.first;
unknown's avatar
unknown committed
3552
      select_lex.context.table_list= first;
3553
      select_lex.table_list.first= first;
unknown's avatar
VIEW  
unknown committed
3554 3555 3556 3557 3558 3559
      select_lex.table_list.elements++;	//safety
    }
  }
}


3560 3561 3562 3563 3564

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

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3565
    LEX::cleanup_after_one_table_open()
3566 3567 3568 3569 3570

  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).
3571 3572
*/

Konstantin Osipov's avatar
Konstantin Osipov committed
3573
void LEX::cleanup_after_one_table_open()
3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585
{
  /*
    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;
3586
    select_lex.exclude_from_table_unique_test= false;
3587 3588 3589 3590 3591 3592 3593 3594 3595 3596
    /* 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();
  }
3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608
}


/*
  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
3609
void LEX::reset_n_backup_query_tables_list(Query_tables_list *backup)
3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627
{
  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
3628
void LEX::restore_backup_query_tables_list(Query_tables_list *backup)
3629 3630 3631
{
  this->destroy_query_tables_list();
  this->set_query_tables_list(backup);
3632 3633 3634
}


unknown's avatar
unknown committed
3635 3636 3637 3638
/*
  Checks for usage of routines and/or tables in a parsed statement

  SYNOPSIS
Konstantin Osipov's avatar
Konstantin Osipov committed
3639
    LEX:table_or_sp_used()
unknown's avatar
unknown committed
3640 3641 3642 3643 3644 3645

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

Konstantin Osipov's avatar
Konstantin Osipov committed
3646
bool LEX::table_or_sp_used()
unknown's avatar
unknown committed
3647 3648 3649 3650 3651 3652 3653 3654 3655 3656
{
  DBUG_ENTER("table_or_sp_used");

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

  DBUG_RETURN(FALSE);
}


3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675
/*
  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
3676
    if (tbl->on_expr && !tbl->prep_on_expr)
3677
    {
unknown's avatar
unknown committed
3678
      thd->check_and_register_item_tree(&tbl->prep_on_expr, &tbl->on_expr);
3679 3680
      tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
    }
3681 3682 3683 3684 3685
    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());
    }
3686 3687 3688 3689
  }
}


unknown's avatar
VIEW  
unknown committed
3690
/*
3691
  Save WHERE/HAVING/ON clauses and replace them with disposable copies
unknown's avatar
VIEW  
unknown committed
3692 3693 3694

  SYNOPSIS
    st_select_lex::fix_prepare_information
3695 3696 3697 3698 3699 3700 3701 3702
      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
3703 3704
    We also save the chain of ORDER::next in group_list, in case
    the list is modified by remove_const().
3705 3706 3707
    AND/OR trees.
    The function also calls fix_prepare_info_in_table_list that saves all
    ON expressions.    
unknown's avatar
VIEW  
unknown committed
3708 3709
*/

3710 3711
void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
                                            Item **having_conds)
unknown's avatar
VIEW  
unknown committed
3712
{
3713
  DBUG_ENTER("st_select_lex::fix_prepare_information");
unknown's avatar
unknown committed
3714
  if (!thd->stmt_arena->is_conventional() && first_execution)
unknown's avatar
VIEW  
unknown committed
3715 3716
  {
    first_execution= 0;
3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729
    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);
      }
    }
3730 3731
    if (*conds)
    {
unknown's avatar
unknown committed
3732
      thd->check_and_register_item_tree(&prep_where, conds);
3733 3734
      *conds= where= prep_where->copy_andor_structure(thd);
    }
3735 3736
    if (*having_conds)
    {
unknown's avatar
unknown committed
3737
      thd->check_and_register_item_tree(&prep_having, having_conds);
3738 3739
      *having_conds= having= prep_having->copy_andor_structure(thd);
    }
3740
    fix_prepare_info_in_table_list(thd, table_list.first);
3741
  }
3742
  DBUG_VOID_RETURN;
3743 3744
}

unknown's avatar
unknown committed
3745

unknown's avatar
unknown committed
3746
/*
unknown's avatar
VIEW  
unknown committed
3747
  There are st_select_lex::add_table_to_list &
unknown's avatar
unknown committed
3748
  st_select_lex::set_lock_for_tables are in sql_parse.cc
unknown's avatar
unknown committed
3749

unknown's avatar
VIEW  
unknown committed
3750
  st_select_lex::print is in sql_select.cc
unknown's avatar
unknown committed
3751 3752

  st_select_lex_unit::prepare, st_select_lex_unit::exec,
3753 3754
  st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,
  st_select_lex_unit::change_result
unknown's avatar
unknown committed
3755
  are in sql_union.cc
unknown's avatar
unknown committed
3756
*/
3757

3758 3759 3760 3761 3762
/*
  Sets the kind of hints to be added by the calls to add_index_hint().

  SYNOPSIS
    set_index_hint_type()
3763 3764
      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.
3765 3766 3767 3768 3769 3770 3771 3772

  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.
*/
3773
void st_select_lex::set_index_hint_type(enum index_hint_type type_arg,
3774 3775
                                        index_clause_map clause)
{ 
3776
  current_index_hint_type= type_arg;
3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790
  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
3791
  index_hints= new (thd->mem_root) List<Index_hint>(); 
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810
}



/*
  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
*/
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
{
3811
  return index_hints->push_front(new (thd->mem_root) 
unknown's avatar
unknown committed
3812
                                 Index_hint(current_index_hint_type,
3813
                                            current_index_hint_clause,
3814
                                            str, length), thd->mem_root);
3815
}
3816

3817

3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834
/**
  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)
3835
{
3836 3837 3838 3839
  SELECT_LEX_UNIT *next_unit= NULL;
  for (SELECT_LEX_UNIT *un= first_inner_unit();
       un;
       un= next_unit ? next_unit : un->next_unit())
3840 3841
  {
    Item_subselect *subquery_predicate= un->item;
3842 3843
    next_unit= NULL;

3844 3845
    if (subquery_predicate)
    {
3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857
      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
3858 3859
      if (subquery_predicate->substype() == Item_subselect::IN_SUBS)
      {
3860
        Item_in_subselect *in_subs= (Item_in_subselect*) subquery_predicate;
Sergey Petrunya's avatar
Sergey Petrunya committed
3861 3862 3863 3864
        if (in_subs->is_jtbm_merged)
          continue;
      }

3865 3866 3867 3868 3869 3870
      if (const_only && !subquery_predicate->const_item())
      {
        /* Skip non-constant subqueries if the caller asked so. */
        continue;
      }

unknown's avatar
unknown committed
3871
      bool empty_union_result= true;
3872
      bool is_correlated_unit= false;
3873 3874
      bool first= true;
      bool union_plan_saved= false;
unknown's avatar
unknown committed
3875 3876 3877 3878
      /*
        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.
      */
3879 3880 3881
      for (SELECT_LEX *sl= un->first_select(); sl; sl= sl->next_select())
      {
        JOIN *inner_join= sl->join;
3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892
        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 */
          }
        }
3893 3894
        if (!inner_join)
          continue;
3895
        SELECT_LEX *save_select= un->thd->lex->current_select;
3896
        ulonglong save_options;
3897
        int res;
3898
        /* We need only 1 row to determine existence */
3899
        un->set_limit(un->global_parameters());
3900
        un->thd->lex->current_select= sl;
3901
        save_options= inner_join->select_options;
3902
        if (options & SELECT_DESCRIBE)
3903 3904
        {
          /* Optimize the subquery in the context of EXPLAIN. */
3905
          sl->set_explain_type(FALSE);
unknown's avatar
unknown committed
3906 3907
          sl->options|= SELECT_DESCRIBE;
          inner_join->select_options|= SELECT_DESCRIBE;
3908
        }
3909
        res= inner_join->optimize();
3910 3911
        sl->update_correlated_cache();
        is_correlated_unit|= sl->is_correlated;
3912
        inner_join->select_options= save_options;
3913
        un->thd->lex->current_select= save_select;
3914

3915 3916
        Explain_query *eq;
        if ((eq= inner_join->thd->lex->explain))
3917
        {
3918 3919
          Explain_select *expl_sel;
          if ((expl_sel= eq->get_select(inner_join->select_lex->select_number)))
3920 3921
          {
            sl->set_explain_type(TRUE);
3922
            expl_sel->select_type= sl->type;
3923 3924
          }
        }
3925

unknown's avatar
unknown committed
3926 3927 3928 3929 3930 3931 3932 3933
        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();
        }
3934 3935 3936
        if (res)
          return TRUE;
      }
unknown's avatar
unknown committed
3937 3938
      if (empty_union_result)
        subquery_predicate->no_rows_in_result();
3939 3940 3941
      if (!is_correlated_unit)
        un->uncacheable&= ~UNCACHEABLE_DEPENDENT;
      subquery_predicate->is_correlated= is_correlated_unit;
3942 3943 3944
    }
  }
  return FALSE;
3945 3946 3947
}


3948

3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962
/**
  @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
3963
bool st_select_lex::handle_derived(LEX *lex, uint phases)
3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028
{
  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
4029
  for (tl= leaf_tables.head(); tl->*link; tl= tl->*link) ;
4030 4031 4032
  tl->*link= table;
}

Igor Babaev's avatar
Igor Babaev committed
4033

4034 4035
/*
  @brief
Igor Babaev's avatar
Igor Babaev committed
4036
  Replace given table from the leaf_tables list for a list of tables 
4037

Igor Babaev's avatar
Igor Babaev committed
4038 4039
  @param table Table to replace
  @param list  List to substititute the table for
4040 4041

  @details
Igor Babaev's avatar
Igor Babaev committed
4042
  Replace 'table' from the leaf_tables list for a list of tables 'tbl_list'.
4043 4044
*/

Igor Babaev's avatar
Igor Babaev committed
4045
void st_select_lex::replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list)
4046 4047 4048 4049 4050 4051 4052
{
  TABLE_LIST *tl;
  List_iterator<TABLE_LIST> ti(leaf_tables);
  while ((tl= ti++))
  {
    if (tl == table)
    {
Igor Babaev's avatar
Igor Babaev committed
4053
      ti.replace(tbl_list);
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 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152
      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
4153 4154
bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
                                SELECT_LEX *subq_select,
4155 4156 4157 4158
                                uint table_no, table_map map)
{
  derived->wrap_into_nested_join(subq_select->top_join_list);

4159
  ftfunc_list->append(subq_select->ftfunc_list);
Igor Babaev's avatar
Igor Babaev committed
4160 4161 4162
  if (join ||
      thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
      thd->lex->sql_command == SQLCOM_DELETE_MULTI)
4163
  {
Igor Babaev's avatar
Igor Babaev committed
4164 4165 4166
    List_iterator_fast<Item_in_subselect> li(subq_select->sj_subselects);
    Item_in_subselect *in_subq;
    while ((in_subq= li++))
4167
    {
4168
      sj_subselects.push_back(in_subq, thd->mem_root);
Igor Babaev's avatar
Igor Babaev committed
4169 4170
      if (in_subq->emb_on_expr_nest == NO_JOIN_NEST)
         in_subq->emb_on_expr_nest= derived;
4171 4172 4173 4174 4175 4176
    }
  }

  /* 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
4177
  subq_select->merged_into= this;
Igor Babaev's avatar
Igor Babaev committed
4178 4179 4180

  replace_leaf_table(derived, subq_select->leaf_tables);

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
  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
4218

4219 4220
  while ((tl= ti++))
  {
Igor Babaev's avatar
Igor Babaev committed
4221
    if (tl->table && !tl->is_view_or_derived())
Igor Babaev's avatar
Igor Babaev committed
4222
    {
Igor Babaev's avatar
Igor Babaev committed
4223
      TABLE_LIST *embedding= tl->embedding;
Igor Babaev's avatar
Igor Babaev committed
4224 4225 4226 4227 4228 4229 4230 4231
      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);
4232 4233 4234 4235 4236 4237 4238 4239 4240
          /*
            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
4241
          bitmap_clear_all(tab->read_set);
4242 4243
          if (tab->vcol_set)
            bitmap_clear_all(tab->vcol_set);
Igor Babaev's avatar
Igor Babaev committed
4244 4245 4246 4247
          break;
        }
      }
    }
Igor Babaev's avatar
Igor Babaev committed
4248 4249 4250 4251 4252 4253
  }

  ti.rewind();
  while ((tl= ti++))
  {
    TABLE_LIST *embedding= tl;
Igor Babaev's avatar
Igor Babaev committed
4254
    do
Igor Babaev's avatar
Igor Babaev committed
4255
    {
Igor Babaev's avatar
Igor Babaev committed
4256
      bool maybe_null;
4257
      if ((maybe_null= MY_TEST(embedding->outer_join)))
Igor Babaev's avatar
Igor Babaev committed
4258 4259 4260 4261
      {
	tl->table->maybe_null= maybe_null;
        break;
      }
Igor Babaev's avatar
Igor Babaev committed
4262
    }
Igor Babaev's avatar
Igor Babaev committed
4263
    while ((embedding= embedding->embedding));
4264 4265 4266 4267 4268
    if (tl->on_expr)
    {
      tl->on_expr->update_used_tables();
      tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
    }
4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281
    /*
      - 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
4282
    embedding= tl->embedding;
4283 4284 4285 4286 4287 4288 4289 4290 4291 4292
    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;
4293
    }
4294
  }
Igor Babaev's avatar
Igor Babaev committed
4295

4296 4297 4298 4299 4300
  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
4301 4302 4303 4304 4305 4306 4307
  if (join->having)
  {
    join->having->update_used_tables();
  }

  Item *item;
  List_iterator_fast<Item> it(join->fields_list);
4308
  select_list_tables= 0;
Igor Babaev's avatar
Igor Babaev committed
4309 4310 4311
  while ((item= it++))
  {
    item->update_used_tables();
4312
    select_list_tables|= item->used_tables();
Igor Babaev's avatar
Igor Babaev committed
4313 4314 4315 4316 4317 4318 4319 4320 4321 4322
  }
  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();
4323 4324
  if (!master_unit()->is_unit_op() ||
      master_unit()->global_parameters() != this)
Igor Babaev's avatar
Igor Babaev committed
4325 4326 4327
  {
    for (ORDER *order= order_list.first; order; order= order->next)
      (*order->item)->update_used_tables();
unknown's avatar
unknown committed
4328 4329
  }
  join->result->update_used_tables();
4330 4331
}

4332

4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348
/**
  @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++))
  {
4349
    //    is_correlated|= tl->is_with_table_recursive_reference();
4350
    if (tl->on_expr)
4351
      is_correlated|= MY_TEST(tl->on_expr->used_tables() & OUTER_REF_TABLE_BIT);
4352 4353 4354 4355
    for (TABLE_LIST *embedding= tl->embedding ; embedding ;
         embedding= embedding->embedding)
    {
      if (embedding->on_expr)
4356 4357
        is_correlated|= MY_TEST(embedding->on_expr->used_tables() &
                                OUTER_REF_TABLE_BIT);
4358 4359 4360 4361
    }
  }

  if (join->conds)
4362
    is_correlated|= MY_TEST(join->conds->used_tables() & OUTER_REF_TABLE_BIT);
4363

4364 4365
  is_correlated|= join->having_is_correlated;

4366
  if (join->having)
4367
    is_correlated|= MY_TEST(join->having->used_tables() & OUTER_REF_TABLE_BIT);
4368 4369

  if (join->tmp_having)
4370 4371
    is_correlated|= MY_TEST(join->tmp_having->used_tables() &
                            OUTER_REF_TABLE_BIT);
4372 4373 4374 4375

  Item *item;
  List_iterator_fast<Item> it(join->fields_list);
  while ((item= it++))
4376
    is_correlated|= MY_TEST(item->used_tables() & OUTER_REF_TABLE_BIT);
4377 4378

  for (ORDER *order= group_list.first; order; order= order->next)
4379 4380
    is_correlated|= MY_TEST((*order->item)->used_tables() &
                            OUTER_REF_TABLE_BIT);
4381

4382
  if (!master_unit()->is_unit_op())
4383 4384
  {
    for (ORDER *order= order_list.first; order; order= order->next)
4385 4386
      is_correlated|= MY_TEST((*order->item)->used_tables() &
                              OUTER_REF_TABLE_BIT);
4387 4388 4389 4390 4391 4392 4393
  }

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


4394 4395
/**
  Set the EXPLAIN type for this subquery.
Sergey Petrunya's avatar
Sergey Petrunya committed
4396 4397 4398
  
  @param on_the_fly  TRUE<=> We're running a SHOW EXPLAIN command, so we must 
                     not change any variables
4399 4400
*/

4401
void st_select_lex::set_explain_type(bool on_the_fly)
4402
{
4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422
  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;
      }
    }
  }

4423 4424 4425
  if (on_the_fly && !is_primary && have_merged_subqueries)
    is_primary= TRUE;

4426 4427 4428
  SELECT_LEX *first= master_unit()->first_select();
  /* drop UNCACHEABLE_EXPLAIN, because it is for internal usage only */
  uint8 is_uncacheable= (uncacheable & ~UNCACHEABLE_EXPLAIN);
4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442
  
  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;
  }
4443

4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469
  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)
        type= "DERIVED";
      else if (using_materialization)
        type= "MATERIALIZED";
      else
      {
         if (is_uncacheable & UNCACHEABLE_DEPENDENT)
           type= "DEPENDENT SUBQUERY";
         else
         {
           type= is_uncacheable? "UNCACHEABLE SUBQUERY" :
                                 "SUBQUERY";
         }
      }
    }
    else
    {
4470
      switch (linkage)
4471
      {
4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484
      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
4485
        {
4486 4487 4488 4489 4490 4491 4492 4493 4494
          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)
4495
          {
4496 4497 4498
            bool uses_cte= false;
            for (JOIN_TAB *tab= first_explain_order_tab(join); tab;
                 tab= next_explain_order_tab(join, tab))
4499
            {
4500 4501 4502 4503 4504
              if (tab->table && tab->table->pos_in_table_list->with)
              {
                uses_cte= true;
                break;
              }
4505
            }
4506 4507
            if (uses_cte)
              type= "RECURSIVE UNION";
4508 4509
          }
        }
4510
        break;
4511 4512 4513
      }
    }
  }
4514 4515

  if (!on_the_fly)
4516
    options|= SELECT_DESCRIBE;
4517
}
4518 4519


4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530
/**
  @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
4531
void SELECT_LEX::increase_derived_records(ha_rows records)
4532 4533 4534 4535
{
  SELECT_LEX_UNIT *unit= master_unit();
  DBUG_ASSERT(unit->derived);

Igor Babaev's avatar
Igor Babaev committed
4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548
  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; 
  }
  
4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562
  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;
  }
4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581
}


/**
  @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
4582 4583
  /* join == NULL in  DELETE ... RETURNING */
  if (!(join && join->thd->lex->describe) && derived)
4584 4585 4586
  {
    if (!empty)
      increase_derived_records(1);
4587
    if (!master_unit()->is_unit_op() && !derived->is_merged_derived())
4588 4589 4590 4591
      derived->fill_me= TRUE;
  }
}

Igor Babaev's avatar
Igor Babaev committed
4592

4593 4594
bool st_select_lex::save_leaf_tables(THD *thd)
{
4595 4596
  Query_arena *arena, backup;
  arena= thd->activate_stmt_arena_if_needed(&backup);
4597 4598 4599 4600 4601

  List_iterator_fast<TABLE_LIST> li(leaf_tables);
  TABLE_LIST *table;
  while ((table= li++))
  {
4602
    if (leaf_tables_exec.push_back(table, thd->mem_root))
4603
      return 1;
4604 4605
    table->tablenr_exec= table->get_tablenr();
    table->map_exec= table->get_map();
Igor Babaev's avatar
Igor Babaev committed
4606 4607 4608
    if (join && (join->select_options & SELECT_DESCRIBE))
      table->maybe_null_exec= 0;
    else
4609
      table->maybe_null_exec= table->table?  table->table->maybe_null: 0;
4610 4611 4612 4613 4614 4615 4616
  }
  if (arena)
    thd->restore_active_arena(arena, &backup);

  return 0;
}

4617

4618
bool LEX::save_prep_leaf_tables()
Igor Babaev's avatar
Igor Babaev committed
4619 4620
{
  if (!thd->save_prep_leaf_list)
4621
    return FALSE;
Igor Babaev's avatar
Igor Babaev committed
4622 4623

  Query_arena *arena= thd->stmt_arena, backup;
4624
  arena= thd->activate_stmt_arena_if_needed(&backup);
4625 4626 4627 4628 4629 4630 4631 4632 4633
  //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
4634

4635 4636 4637
  thd->save_prep_leaf_list= FALSE;
  return FALSE;
}
Igor Babaev's avatar
Igor Babaev committed
4638

4639 4640 4641

bool st_select_lex::save_prep_leaf_tables(THD *thd)
{
Igor Babaev's avatar
Igor Babaev committed
4642 4643
  List_iterator_fast<TABLE_LIST> li(leaf_tables);
  TABLE_LIST *table;
4644 4645 4646 4647 4648 4649 4650 4651 4652 4653

  /*
    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
4654 4655 4656
  while ((table= li++))
  {
    if (leaf_tables_prep.push_back(table))
4657 4658
      return TRUE;
  }
4659
  prep_leaf_list_state= SAVED;
4660 4661 4662 4663 4664 4665 4666
  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
4667 4668
  }

4669
  return FALSE;
Igor Babaev's avatar
Igor Babaev committed
4670 4671 4672
}


4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701
/*
  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
4702 4703
        ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
        ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
4704 4705 4706
    {
      continue;
    }
4707 4708 4709 4710 4711 4712

    if (sl->master_unit()->derived &&
      sl->master_unit()->derived->is_merged_derived())
    {
      continue;
    }
4713 4714 4715 4716 4717 4718
    all_merged= FALSE;
    break;
  }
  return all_merged;
}

4719 4720 4721 4722
/* 
  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.
*/
4723

Sergey Petrunya's avatar
Sergey Petrunya committed
4724
int LEX::print_explain(select_result_sink *output, uint8 explain_flags,
Sergei Petrunia's avatar
Sergei Petrunia committed
4725
                       bool is_analyze, bool *printed_anything)
4726
{
4727
  int res;
4728
  if (explain && explain->have_query_plan())
4729
  {
Sergei Petrunia's avatar
Sergei Petrunia committed
4730
    res= explain->print_explain(output, explain_flags, is_analyze);
4731
    *printed_anything= true;
4732 4733 4734
  }
  else
  {
4735 4736
    res= 0;
    *printed_anything= false;
4737
  }
4738
  return res;
4739 4740
}

4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801

/**
  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);
    init_sql_alloc(mem_root_for_set_stmt, ALLOC_ROOT_SET, ALLOC_ROOT_SET,
                   MYF(MY_THREAD_SPECIFIC));
  }
  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);
  DBUG_PRINT("info", ("mem_root: 0x%lx  arena: 0x%lx",
                      (ulong) mem_root_for_set_stmt,
                      (ulong) arena_for_set_stmt));
  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);
  DBUG_PRINT("info", ("mem_root: 0x%lx  arena: 0x%lx",
                      (ulong) arena_for_set_stmt->mem_root,
                      (ulong) arena_for_set_stmt));
  DBUG_VOID_RETURN;
}


void LEX::free_arena_for_set_stmt()
{
  DBUG_ENTER("LEX::free_arena_for_set_stmt");
  if (!arena_for_set_stmt)
    return;
  DBUG_PRINT("info", ("mem_root: 0x%lx  arena: 0x%lx",
                      (ulong) arena_for_set_stmt->mem_root,
                      (ulong) arena_for_set_stmt));
  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;
}

4802 4803 4804 4805 4806 4807 4808 4809
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();
4810
    free_arena_for_set_stmt();
4811
  }
4812
  DBUG_ASSERT(!is_arena_for_set_stmt());
4813 4814
  DBUG_VOID_RETURN;
}
4815

4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851
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;
}
4852
/*
4853 4854
  Save explain structures of a UNION. The only variable member is whether the 
  union has "Using filesort".
Sergey Petrunya's avatar
Sergey Petrunya committed
4855

4856
  There is also save_union_explain_part2() function, which is called before we read
Sergey Petrunya's avatar
Sergey Petrunya committed
4857
  UNION's output.
Sergey Petrunya's avatar
Sergey Petrunya committed
4858

Sergey Petrunya's avatar
Sergey Petrunya committed
4859
  The reason for it is examples like this:
Sergey Petrunya's avatar
Sergey Petrunya committed
4860

Sergey Petrunya's avatar
Sergey Petrunya committed
4861 4862 4863 4864 4865 4866
     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
4867

4868
int st_select_lex_unit::save_union_explain(Explain_query *output)
4869 4870
{
  SELECT_LEX *first= first_select();
4871 4872 4873 4874

  if (output->get_union(first->select_number))
    return 0; /* Already added */
    
4875 4876 4877
  Explain_union *eu= 
    new (output->mem_root) Explain_union(output->mem_root, 
                                         thd->lex->analyze_stmt);
4878

4879 4880 4881
  if (with_element && with_element->is_recursive)
    eu->is_recursive_cte= true;
 
4882
  if (derived)
4883 4884 4885 4886 4887
    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.
  */
4888
  for (SELECT_LEX *sl= first; sl; sl= sl->next_select())
4889
    eu->add_select(sl->select_number);
4890

4891
  eu->fake_select_type= unit_operation_text[eu->operation= common_op()];
4892 4893
  eu->using_filesort= MY_TEST(global_parameters()->order_list.first);
  eu->using_tmp= union_needs_tmp_table();
4894

Sergey Petrunya's avatar
Sergey Petrunya committed
4895
  // Save the UNION node
4896
  output->add_node(eu);
4897

4898 4899
  if (eu->get_select_id() == 1)
    output->query_plan_ready();
4900

4901 4902 4903 4904
  return 0;
}


4905 4906 4907 4908 4909
/*
  @see  st_select_lex_unit::save_union_explain
*/

int st_select_lex_unit::save_union_explain_part2(Explain_query *output)
4910
{
4911
  Explain_union *eu= output->get_union(first_select()->select_number);
4912
  if (fake_select_lex)
4913
  {
4914 4915 4916 4917 4918
    for (SELECT_LEX_UNIT *unit= fake_select_lex->first_inner_unit(); 
         unit; unit= unit->next_unit())
    {
      if (!(unit->item && unit->item->eliminated))
      {
4919
        eu->add_child(unit->first_select()->select_number);
4920 4921
      }
    }
4922
    fake_select_lex->join->explain= &eu->fake_select_lex_explain;
4923
  }
Sergey Petrunya's avatar
Sergey Petrunya committed
4924
  return 0;
4925 4926 4927
}


4928 4929 4930 4931 4932
/**
  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
4933
  is used from the sql parser that doesn't have any ifdef's
4934 4935 4936 4937 4938

  @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
4939
bool LEX::is_partition_management() const
4940 4941
{
  return (sql_command == SQLCOM_ALTER_TABLE &&
4942 4943
          (alter_info.flags ==  Alter_info::ALTER_ADD_PARTITION ||
           alter_info.flags ==  Alter_info::ALTER_REORGANIZE_PARTITION));
4944 4945
}

4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072

/**
  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)
    Item_field(thd, context, NULL, NULL, "*");
  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];
  LEX_STRING alias;
  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();
  }
}

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

sp_variable *LEX::sp_param_init(LEX_STRING name)
{
  if (spcont->find_variable(name, true))
  {
    my_error(ER_SP_DUP_PARAM, MYF(0), name.str);
    return NULL;
  }
  sp_variable *spvar= spcont->add_variable(thd, name);
  init_last_field(&spvar->field_def, name.str,
                  thd->variables.collation_database);
  return spvar;
}


bool LEX::sp_param_fill_definition(sp_variable *spvar)
{
  if (sphead->fill_field_definition(thd, last_field))
    return true;
  spvar->field_def.field_name= spvar->name.str;
  spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
  return false;
}


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 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 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 5185 5186 5187 5188 5189 5190 5191 5192
void LEX::set_stmt_init()
{
  sql_command= SQLCOM_SET_OPTION;
  mysql_init_select(this);
  option_type= OPT_SESSION;
  autocommit= 0;
};


bool LEX::init_internal_variable(struct sys_var_with_base *variable,
                                 LEX_STRING name)
{
  sp_variable *spv;

  /* Best effort lookup for system variable. */
  if (!spcont || !(spv = spcont->find_variable(name, false)))
  {
    struct sys_var_with_base tmp= {NULL, name};

    /* Not an SP local variable */
    if (find_sys_var_null_base(thd, &tmp))
      return true;

    *variable= tmp;
    return false;
  }

  /*
    Possibly an SP local variable (or a shadowed sysvar).
    Will depend on the context of the SET statement.
  */
  variable->var= NULL;
  variable->base_name= name;
  return false;
}


bool LEX::init_internal_variable(struct sys_var_with_base *variable,
                                 LEX_STRING dbname, LEX_STRING name)
{
  if (check_reserved_words(&dbname))
  {
    thd->parse_error();
    return true;
  }
  if (sphead && sphead->m_type == TYPE_ENUM_TRIGGER &&
      (!my_strcasecmp(system_charset_info, dbname.str, "NEW") ||
       !my_strcasecmp(system_charset_info, dbname.str, "OLD")))
  {
    if (dbname.str[0]=='O' || dbname.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;
    }
    /* This special combination will denote field of NEW row */
    variable->var= trg_new_row_fake_var;
    variable->base_name= name;
    return false;
  }

  sys_var *tmp= find_sys_var(thd, name.str, name.length);
  if (!tmp)
    return true;
  if (!tmp->is_struct())
    my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name.str);
  variable->var= tmp;
  variable->base_name= dbname;
  return false;
}


bool LEX::init_default_internal_variable(struct sys_var_with_base *variable,
                                         LEX_STRING name)
{
  sys_var *tmp= find_sys_var(thd, name.str, name.length);
  if (!tmp)
    return true;
  if (!tmp->is_struct())
    my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), name.str);
  variable->var= tmp;
  variable->base_name.str=    (char*) "default";
  variable->base_name.length= 7;
  return false;
}

5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206
void LEX::sp_variable_declarations_init(THD *thd, int nvars)
{
  // get the last variable:
  uint num_vars= spcont->context_var_count();
  uint var_idx= spcont->var_context2runtime(num_vars - 1);
  sp_variable *spvar= spcont->find_variable(var_idx);

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

bool LEX::sp_variable_declarations_finalize(THD *thd, int nvars,
5207
                                            const Column_definition &cdef,
5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226
                                            Item *dflt_value_item)
{
  uint num_vars= spcont->context_var_count();

  if (!dflt_value_item &&
      !(dflt_value_item= new (thd->mem_root) Item_null(thd)))
    return true;
  /* QQ Set to the var_type with null_value? */

  for (uint i= num_vars - nvars ; i < num_vars ; i++)
  {
    uint var_idx= spcont->var_context2runtime(i);
    sp_variable *spvar= spcont->find_variable(var_idx);
    bool last= i == num_vars - 1;

    if (!spvar)
      return true;

    if (!last)
5227
      spvar->field_def= cdef;
5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240

    spvar->default_value= dflt_value_item;
    spvar->field_def.field_name= spvar->name.str;

    if (sphead->fill_field_definition(thd, &spvar->field_def))
      return true;

    spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;

    /* The last instruction is responsible for freeing LEX. */
    sp_instr_set *is= new (this->thd->mem_root)
                       sp_instr_set(sphead->instructions(),
                                    spcont, var_idx, dflt_value_item,
5241
                                    spvar->field_def.sql_type, this, last);
5242 5243 5244 5245 5246 5247 5248 5249 5250
    if (is == NULL || sphead->add_instr(is))
      return true;
  }

  spcont->declare_var_boundary(0);
  return sphead->restore_lex(thd);
}


5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319
/**********************************************************************
  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;
*/


sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_STRING name,
                                           Item *value)
{
  sp_variable *spvar= spcont->add_variable(thd, name);
  spcont->declare_var_boundary(1);
  spvar->field_def= Column_definition(spvar->name.str, MYSQL_TYPE_LONGLONG);
  if (sp_variable_declarations_finalize(thd, 1, spvar->field_def, value))
    return NULL;
  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)
              Item_splocal(thd, src->name, src->offset, src->sql_type());
    if (args[i] == NULL)
      return true;
#ifndef DBUG_OFF
    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
*/
bool LEX::sp_for_loop_index_and_bounds(THD *thd, const Lex_for_loop_st &loop)
{
5320
  spcont->set_for_loop(loop);
5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368
  sphead->reset_lex(thd);
  if (thd->lex->sp_for_loop_condition(thd, loop))
    return true;
  return thd->lex->sphead->restore_lex(thd);
}


/**
  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)
    Item_splocal(thd, loop.m_index->name, loop.m_index->offset,
                      loop.m_index->sql_type());
  if (splocal == NULL)
    return true;
#ifndef DBUG_OFF
  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);
  if (!expr || set_local_variable(loop.m_index, expr))
    return true;
  return false;
}


bool LEX::sp_for_loop_finalize(THD *thd, const Lex_for_loop_st &loop)
{
  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);
}


/***************************************************************************/

5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433
bool LEX::sp_declare_cursor(THD *thd, const LEX_STRING name, LEX *cursor_stmt)
{
  uint offp;
  sp_instr_cpush *i;

  if (spcont->find_cursor(name, &offp, true))
  {
    my_error(ER_SP_DUP_CURS, MYF(0), name.str);
    return true;
  }
  i= new (thd->mem_root)
       sp_instr_cpush(sphead->instructions(), spcont, cursor_stmt,
                      spcont->current_cursor_count());
  return i == NULL || sphead->add_instr(i) || spcont->add_cursor(name);
}


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;

  if (sphead->push_backpatch(thd, i, spcont->push_label(thd, empty_lex_str, 0)))
    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;
}
5434

5435 5436 5437

void LEX::sp_block_init(THD *thd, const LEX_STRING label)
{
5438
  spcont->push_label(thd, label, sphead->instructions(), sp_label::BEGIN);
5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489
  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,
                            const LEX_STRING end_label)
{
  sp_label *splabel;
  if (sp_block_finalize(thd, spblock, &splabel))
    return true;
  if (end_label.str &&
      my_strcasecmp(system_charset_info,
                    end_label.str, splabel->name.str) != 0)
  {
    my_error(ER_SP_LABEL_MISMATCH, MYF(0), end_label.str);
    return true;
  }
  return false;
}


5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510
sp_head *LEX::make_sp_head(THD *thd, sp_name *name,
                           enum stored_procedure_type type)
{
  sp_head *sp;

  /* Order is important here: new - reset - init */
  if ((sp= new sp_head()))
  {
    sp->reset_thd_mem_root(thd);
    sp->init(this);
    sp->m_type= type;
    if (name)
      sp->init_sp_name(thd, name);
    sp->m_chistics= &sp_chistics;
    sphead= sp;
  }
  bzero(&sp_chistics, sizeof(sp_chistics));
  return sp;
}


5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527
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);
}
5528 5529


5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552
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,
5553 5554
                                                  uint executable_section_ip,
                                                  uint exception_count)
5555
{
5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566
  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);
  }
5567 5568 5569 5570 5571 5572 5573
  /*
    Generate a jump from the end of the EXCEPTION code
    to the executable section.
  */
  return sphead->add_instr_jump(thd, spcont, executable_section_ip);
}

5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602

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;
}


bool LEX::sp_leave_statement(THD *thd, const LEX_STRING label_name)
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab)
  {
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", label_name.str);
    return true;
  }
5603
  return sp_exit_block(thd, lab, NULL);
5604 5605
}

5606

5607 5608
bool LEX::sp_exit_block(THD *thd, sp_label *lab)
{
5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622
  /*
    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);
}


5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645
bool LEX::sp_exit_block(THD *thd, sp_label *lab, Item *when)
{
  if (!when)
    return sp_exit_block(thd, lab);

  sphead->reset_lex(thd); // This changes thd->lex
  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) ||
      sphead->restore_lex(thd) ||
      sp_exit_block(thd, lab))
    return true;
  i->backpatch(sphead->instructions(), spcont);
  return false;
}


bool LEX::sp_exit_statement(THD *thd, Item *item)
5646 5647 5648 5649 5650 5651 5652 5653
{
  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);
5654
  return sp_exit_block(thd, lab, item);
5655 5656 5657
}


5658
bool LEX::sp_exit_statement(THD *thd, const LEX_STRING label_name, Item *item)
5659 5660 5661 5662 5663 5664 5665
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab || lab->type != sp_label::ITERATION)
  {
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "EXIT", label_name);
    return true;
  }
5666
  return sp_exit_block(thd, lab, item);
5667 5668 5669
}


5670 5671 5672 5673 5674 5675 5676 5677
bool LEX::sp_iterate_statement(THD *thd, const LEX_STRING label_name)
{
  sp_label *lab= spcont->find_label(label_name);
  if (!lab || lab->type != sp_label::ITERATION)
  {
    my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", label_name.str);
    return true;
  }
5678 5679 5680 5681 5682 5683
  return sp_continue_loop(thd, lab);
}


bool LEX::sp_continue_loop(THD *thd, sp_label *lab)
{
5684 5685 5686 5687 5688 5689 5690 5691 5692
  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;
  }
5693 5694 5695 5696 5697
  return sp_change_context(thd, lab->ctx, false) ||
         sphead->add_instr_jump(thd, spcont, lab->ip); /* Jump back */
}


5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744
bool LEX::sp_continue_loop(THD *thd, sp_label *lab, Item *when)
{
  if (!when)
    return sp_continue_loop(thd, lab);

  sphead->reset_lex(thd); // This changes thd->lex
  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) ||
      sphead->restore_lex(thd) ||
      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);
}


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


5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765
bool LEX::maybe_start_compound_statement(THD *thd)
{
  if (!sphead)
  {
    if (!make_sp_head(thd, NULL, TYPE_ENUM_PROCEDURE))
      return true;
    sp_chistics.suid= SP_IS_NOT_SUID;
    sphead->set_body_start(thd, thd->m_parser_state->m_lip.get_cpp_ptr());
  }
  return false;
}


bool LEX::sp_push_loop_label(THD *thd, const LEX_STRING label_name)
{
  sp_label *lab= spcont->find_label(label_name);
  if (lab)
  {
    my_error(ER_SP_LABEL_REDEFINE, MYF(0), label_name.str);
    return true;
  }
5766 5767
  spcont->push_label(thd, label_name, sphead->instructions(),
                     sp_label::ITERATION);
5768 5769 5770 5771 5772 5773 5774 5775 5776
  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. */
5777 5778
  spcont->push_label(thd, empty_lex_str, sphead->instructions(),
                     sp_label::ITERATION);
5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805
  return false;
}


bool LEX::sp_pop_loop_label(THD *thd, const LEX_STRING label_name)
{
  sp_label *lab= spcont->pop_label();
  sphead->backpatch(lab);
  if (label_name.str &&
      my_strcasecmp(system_charset_info, label_name.str,
                                         lab->name.str) != 0)
  {
    my_error(ER_SP_LABEL_MISMATCH, MYF(0), label_name.str);
    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);
}


5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830
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;
}


5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 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 5942 5943 5944 5945 5946 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
#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
5977

5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991

/**
  @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. 
*/

void st_select_lex::collect_grouping_fields(THD *thd) 
{
5992
  grouping_tmp_fields.empty();
5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 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 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 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 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 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166
  List_iterator<Item> li(join->fields_list);
  Item *item= li++;
  for (uint i= 0; i < master_unit()->derived->table->s->fields; i++, (item=li++))
  {
    for (ORDER *ord= join->group_list; ord; ord= ord->next)
    {
      if ((*ord->item)->eq((Item*)item, 0))
      {
	Grouping_tmp_field *grouping_tmp_field= 
	  new Grouping_tmp_field(master_unit()->derived->table->field[i], item);
	grouping_tmp_fields.push_back(grouping_tmp_field);
      }
    }
  }
}

/**
  @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.
*/ 

void st_select_lex::check_cond_extraction_for_grouping_fields(Item *cond,
                                              Item_processor check_processor)
{
  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++))
    {
      check_cond_extraction_for_grouping_fields(item, check_processor);
      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();
    }
  }
  else 
    cond->set_extraction_flag(cond->walk(check_processor, 
				   0, (uchar *) this) ?
     NO_EXTRACTION_FL : FULL_EXTRACTION_FL);
}


/**
  @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
    (cond => C). The method tries to build the most restictive such
    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,
						    bool no_top_clones)
{
  if (cond->get_extraction_flag() == FULL_EXTRACTION_FL)
  {
    if (no_top_clones)
      return cond;
    cond->clear_extraction_flag();
    return cond->build_clone(thd, thd->mem_root);
  }
  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)
      {
	DBUG_ASSERT(cond_and);
	item->clear_extraction_flag();
	continue;
      }
      Item *fix= build_cond_for_grouping_fields(thd, item,
						no_top_clones & cond_and);
      if (!fix)
      {
	if (cond_and)
	  continue;
	break;
      }
      new_cond->argument_list()->push_back(fix, thd->mem_root);
    }
    
    if (!cond_and && item)
    {
      while((item= li++))
	item->clear_extraction_flag();
      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;
}