sql_lex.cc 79.7 KB
Newer Older
unknown's avatar
unknown committed
1
/* Copyright (C) 2000-2006 MySQL AB
unknown's avatar
unknown committed
2

unknown's avatar
unknown committed
3 4
   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
5
   the Free Software Foundation; version 2 of the License.
unknown's avatar
unknown committed
6

unknown's avatar
unknown committed
7 8 9 10
   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
11

unknown's avatar
unknown committed
12 13 14 15 16 17 18
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


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

19
#define MYSQL_LEX 1
unknown's avatar
unknown committed
20 21 22 23
#include "mysql_priv.h"
#include "item_create.h"
#include <m_ctype.h>
#include <hash.h>
24 25
#include "sp.h"
#include "sp_head.h"
unknown's avatar
unknown committed
26

27 28 29 30
/*
  We are using pointer to this variable for distinguishing between assignment
  to NEW row field (when parsing trigger definition) and structured variable.
*/
31 32

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

34
/* Longest standard keyword name */
unknown's avatar
unknown committed
35 36
#define TOCK_NAME_LENGTH 24

37 38
/*
  The following data is based on the latin1 character set, and is only
unknown's avatar
unknown committed
39 40 41
  used when comparing keywords
*/

unknown's avatar
unknown committed
42 43
static uchar to_upper_lex[]=
{
unknown's avatar
unknown committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    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
};

62 63 64 65 66 67 68 69 70 71 72
/* 
  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"
};
73

unknown's avatar
unknown committed
74 75 76 77 78 79 80
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
81
#include <lex_hash.h>
unknown's avatar
unknown committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103


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


104 105 106 107 108 109 110 111 112
void
st_parsing_options::reset()
{
  allows_variable= TRUE;
  allows_select_into= TRUE;
  allows_select_procedure= TRUE;
  allows_derived= TRUE;
}

113 114 115 116 117 118 119
Lex_input_stream::Lex_input_stream(THD *thd,
                                   const char* buffer,
                                   unsigned int length)
: m_thd(thd),
  yylineno(1),
  yytoklen(0),
  yylval(NULL),
120 121 122 123 124 125
  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),
unknown's avatar
unknown committed
126
  m_buf_length(length),
unknown's avatar
unknown committed
127
  m_echo(TRUE),
128 129 130
  m_cpp_tok_start(NULL),
  m_cpp_tok_start_prev(NULL),
  m_cpp_tok_end(NULL),
unknown's avatar
unknown committed
131 132
  m_body_utf8(NULL),
  m_cpp_utf8_processed_ptr(NULL),
133 134
  next_state(MY_LEX_START),
  found_semicolon(NULL),
135
  ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)),
136
  stmt_prepare_mode(FALSE),
unknown's avatar
unknown committed
137 138
  in_comment(NO_COMMENT),
  m_underscore_cs(NULL)
139
{
140 141
  m_cpp_buf= (char*) thd->alloc(length + 1);
  m_cpp_ptr= m_cpp_buf;
142 143 144 145 146
}

Lex_input_stream::~Lex_input_stream()
{}

unknown's avatar
unknown committed
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
/**
  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);

  uint body_utf8_length=
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
    my_charset_utf8_bin.mbmaxlen;

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

/**
unknown's avatar
unknown committed
176
  @brief The operation appends unprocessed part of pre-processed buffer till
unknown's avatar
unknown committed
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 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
  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.
*/

void Lex_input_stream::body_utf8_append_literal(THD *thd,
                                                const LEX_STRING *txt,
                                                CHARSET_INFO *txt_cs,
                                                const char *end_ptr)
{
  if (!m_cpp_utf8_processed_ptr)
    return;

  LEX_STRING utf_txt;

unknown's avatar
unknown committed
252
  if (!my_charset_same(txt_cs, &my_charset_utf8_general_ci))
unknown's avatar
unknown committed
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
  {
    thd->convert_string(&utf_txt,
                        &my_charset_utf8_general_ci,
                        txt->str, txt->length,
                        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;
}

274

275 276 277 278 279 280
/*
  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)
*/

281
void lex_start(THD *thd)
unknown's avatar
unknown committed
282
{
unknown's avatar
unknown committed
283
  LEX *lex= thd->lex;
unknown's avatar
unknown committed
284 285 286 287
  DBUG_ENTER("lex_start");

  lex->thd= lex->unit.thd= thd;

unknown's avatar
unknown committed
288
  lex->context_stack.empty();
289 290
  lex->unit.init_query();
  lex->unit.init_select();
unknown's avatar
unknown committed
291 292
  /* 'parent_lex' is used in init_query() so it must be before it. */
  lex->select_lex.parent_lex= lex;
293 294
  lex->select_lex.init_query();
  lex->value_list.empty();
unknown's avatar
unknown committed
295
  lex->update_list.empty();
296
  lex->param_list.empty();
unknown's avatar
unknown committed
297
  lex->view_list.empty();
298
  lex->prepared_stmt_params.empty();
299
  lex->auxiliary_table_list.empty();
300 301 302 303 304 305 306 307 308 309
  lex->unit.next= lex->unit.master=
    lex->unit.link_next= lex->unit.return_to= 0;
  lex->unit.prev= lex->unit.link_prev= 0;
  lex->unit.slave= lex->unit.global_parameters= lex->current_select=
    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;
310
  lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED;
unknown's avatar
unknown committed
311 312
  lex->select_lex.init_order();
  lex->select_lex.group_list.empty();
313
  lex->describe= 0;
unknown's avatar
unknown committed
314
  lex->subqueries= FALSE;
unknown's avatar
unknown committed
315
  lex->view_prepare_mode= FALSE;
unknown's avatar
unknown committed
316
  lex->derived_tables= 0;
317 318
  lex->lock_option= TL_READ;
  lex->safe_to_cache_query= 1;
319
  lex->leaf_tables_insert= 0;
320
  lex->parsing_options.reset();
unknown's avatar
unknown committed
321
  lex->empty_field_list_on_rset= 0;
322
  lex->select_lex.select_number= 1;
unknown's avatar
unknown committed
323
  lex->length=0;
324
  lex->part_info= 0;
unknown's avatar
unknown committed
325
  lex->select_lex.in_sum_expr=0;
unknown's avatar
unknown committed
326
  lex->select_lex.ftfunc_list_alloc.empty();
327
  lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
unknown's avatar
unknown committed
328 329
  lex->select_lex.group_list.empty();
  lex->select_lex.order_list.empty();
330
  lex->sql_command= SQLCOM_END;
331
  lex->duplicates= DUP_ERROR;
332
  lex->ignore= 0;
unknown's avatar
unknown committed
333
  lex->spname= NULL;
334 335
  lex->sphead= NULL;
  lex->spcont= NULL;
unknown's avatar
unknown committed
336
  lex->proc_list.first= 0;
unknown's avatar
unknown committed
337
  lex->escape_used= FALSE;
unknown's avatar
unknown committed
338
  lex->query_tables= 0;
339
  lex->reset_query_tables_list(FALSE);
340
  lex->expr_allows_subselect= TRUE;
341
  lex->use_only_table_context= FALSE;
342

343 344
  lex->name.str= 0;
  lex->name.length= 0;
unknown's avatar
unknown committed
345
  lex->event_parse_data= NULL;
346

unknown's avatar
unknown committed
347 348 349
  lex->nest_level=0 ;
  lex->allow_sum_func= 0;
  lex->in_sum_func= NULL;
unknown's avatar
unknown committed
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
  /*
    ok, there must be a better solution for this, long-term
    I tried "bzero" in the sql_yacc.yy code, but that for
    some reason made the values zero, even if they were set
  */
  lex->server_options.server_name= 0;
  lex->server_options.server_name_length= 0;
  lex->server_options.host= 0;
  lex->server_options.db= 0;
  lex->server_options.username= 0;
  lex->server_options.password= 0;
  lex->server_options.scheme= 0;
  lex->server_options.socket= 0;
  lex->server_options.owner= 0;
  lex->server_options.port= -1;
unknown's avatar
unknown committed
365

unknown's avatar
unknown committed
366
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
367 368 369 370
}

void lex_end(LEX *lex)
{
unknown's avatar
unknown committed
371
  DBUG_ENTER("lex_end");
unknown's avatar
unknown committed
372
  DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
unknown's avatar
unknown committed
373 374 375 376 377 378 379
  if (lex->yacc_yyss)
  {
    my_free(lex->yacc_yyss, MYF(0));
    my_free(lex->yacc_yyvs, MYF(0));
    lex->yacc_yyss= 0;
    lex->yacc_yyvs= 0;
  }
unknown's avatar
unknown committed
380 381 382 383 384 385

  /* release used plugins */
  plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, 
                     lex->plugins.elements);
  reset_dynamic(&lex->plugins);

unknown's avatar
unknown committed
386
  DBUG_VOID_RETURN;
unknown's avatar
unknown committed
387 388 389
}


390
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
unknown's avatar
unknown committed
391
{
392
  const char *tok= lip->get_tok_start();
unknown's avatar
unknown committed
393

394
  SYMBOL *symbol= get_hash_symbol(tok, len, function);
unknown's avatar
unknown committed
395 396
  if (symbol)
  {
397 398 399 400
    lip->yylval->symbol.symbol=symbol;
    lip->yylval->symbol.str= (char*) tok;
    lip->yylval->symbol.length=len;

401
    if ((symbol->tok == NOT_SYM) &&
402
        (lip->m_thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE))
403 404
      return NOT2_SYM;
    if ((symbol->tok == OR_OR_SYM) &&
405
	!(lip->m_thd->variables.sql_mode & MODE_PIPES_AS_CONCAT))
406
      return OR2_SYM;
407

unknown's avatar
unknown committed
408 409 410 411 412
    return symbol->tok;
  }
  return 0;
}

413 414 415 416 417
/*
  Check if name is a keyword

  SYNOPSIS
    is_keyword()
418
    name      checked name (must not be empty)
419 420 421 422 423 424 425 426 427
    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)
{
428
  DBUG_ASSERT(len != 0);
429 430
  return get_hash_symbol(name,len,0)!=0;
}
unknown's avatar
unknown committed
431

432 433 434 435 436 437
bool is_lex_native_function(const LEX_STRING *name)
{
  DBUG_ASSERT(name != NULL);
  return (get_hash_symbol(name->str, name->length, 1) != 0);
}

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

440
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
unknown's avatar
unknown committed
441 442
{
  LEX_STRING tmp;
443
  lip->yyUnget();                       // ptr points now after last token char
444
  tmp.length=lip->yytoklen=length;
445
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
unknown's avatar
unknown committed
446 447 448 449

  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
450 451 452
  return tmp;
}

453 454 455 456 457 458 459
/* 
 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)
*/

460
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
461
                                   uint skip,
462
                                   uint length, char quote)
463 464
{
  LEX_STRING tmp;
465 466
  const char *from, *end;
  char *to;
467
  lip->yyUnget();                       // ptr points now after last token char
468 469
  tmp.length= lip->yytoklen=length;
  tmp.str=(char*) lip->m_thd->alloc(tmp.length+1);
470
  from= lip->get_tok_start() + skip;
471
  to= tmp.str;
472
  end= to+length;
unknown's avatar
unknown committed
473 474 475 476

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

477
  for ( ; to != end; )
478
  {
479
    if ((*to++= *from++) == quote)
unknown's avatar
unknown committed
480
    {
481
      from++;					// Skip double quotes
unknown's avatar
unknown committed
482 483
      lip->m_cpp_text_start++;
    }
484 485 486 487 488 489 490 491 492 493
  }
  *to= 0;					// End null for safety
  return tmp;
}


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

495
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
unknown's avatar
unknown committed
496 497 498
{
  reg1 uchar c,sep;
  uint found_escape=0;
499
  CHARSET_INFO *cs= lip->m_thd->charset();
unknown's avatar
unknown committed
500

501
  lip->tok_bitmap= 0;
502 503
  sep= lip->yyGetLast();                        // String should end with this
  while (! lip->eof())
unknown's avatar
unknown committed
504
  {
505
    c= lip->yyGet();
506
    lip->tok_bitmap|= c;
unknown's avatar
unknown committed
507
#ifdef USE_MB
508 509 510
    {
      int l;
      if (use_mb(cs) &&
511 512 513 514 515
          (l = my_ismbchar(cs,
                           lip->get_ptr() -1,
                           lip->get_end_of_query()))) {
        lip->skip_binary(l-1);
        continue;
516
      }
unknown's avatar
unknown committed
517 518
    }
#endif
519
    if (c == '\\' &&
520
        !(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
unknown's avatar
unknown committed
521 522
    {					// Escaped character
      found_escape=1;
523
      if (lip->eof())
unknown's avatar
unknown committed
524
	return 0;
525
      lip->yySkip();
unknown's avatar
unknown committed
526 527 528
    }
    else if (c == sep)
    {
529
      if (c == lip->yyGet())            // Check if two separators in a row
unknown's avatar
unknown committed
530
      {
531
        found_escape=1;                 // duplicate. Remember for delete
unknown's avatar
unknown committed
532 533 534
	continue;
      }
      else
535
        lip->yyUnget();
unknown's avatar
unknown committed
536 537

      /* Found end. Unescape and return string */
538 539
      const char *str, *end;
      char *start;
unknown's avatar
unknown committed
540

541 542 543 544 545 546 547
      str= lip->get_tok_start();
      end= lip->get_ptr();
      /* Extract the text from the token */
      str += pre_skip;
      end -= post_skip;
      DBUG_ASSERT(end >= str);

548
      if (!(start= (char*) lip->m_thd->alloc((uint) (end-str)+1)))
unknown's avatar
unknown committed
549
	return (char*) "";		// Sql_alloc has set error flag
unknown's avatar
unknown committed
550 551 552 553

      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
      lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;

unknown's avatar
unknown committed
554 555
      if (!found_escape)
      {
556 557 558
	lip->yytoklen=(uint) (end-str);
	memcpy(start,str,lip->yytoklen);
	start[lip->yytoklen]=0;
unknown's avatar
unknown committed
559 560 561
      }
      else
      {
562
        char *to;
563

unknown's avatar
unknown committed
564 565 566 567
	for (to=start ; str != end ; str++)
	{
#ifdef USE_MB
	  int l;
unknown's avatar
unknown committed
568
	  if (use_mb(cs) &&
569
              (l = my_ismbchar(cs, str, end))) {
unknown's avatar
unknown committed
570 571 572 573 574 575
	      while (l--)
		  *to++ = *str++;
	      str--;
	      continue;
	  }
#endif
576
	  if (!(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
577
              *str == '\\' && str+1 != end)
unknown's avatar
unknown committed
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
	  {
	    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:
603
              *to++= *str;
unknown's avatar
unknown committed
604 605 606
	      break;
	    }
	  }
607 608
	  else if (*str == sep)
	    *to++= *str++;		// Two ' or "
unknown's avatar
unknown committed
609 610 611 612
	  else
	    *to++ = *str;
	}
	*to=0;
613
	lip->yytoklen=(uint) (to-start);
unknown's avatar
unknown committed
614
      }
615
      return start;
unknown's avatar
unknown committed
616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
    }
  }
  return 0;					// unexpected end of query
}


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

unknown's avatar
unknown committed
640
static inline uint int_token(const char *str,uint length)
unknown's avatar
unknown committed
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
{
  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
675
      return DECIMAL_NUM;
unknown's avatar
unknown committed
676 677 678 679
    else
    {
      cmp=signed_longlong_str+1;
      smaller=LONG_NUM;				// If <= signed_longlong_str
unknown's avatar
unknown committed
680
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
681 682 683 684 685 686 687 688 689 690 691 692 693
    }
  }
  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
694 695
    {
      if (length > unsigned_longlong_len)
unknown's avatar
unknown committed
696
        return DECIMAL_NUM;
unknown's avatar
unknown committed
697 698
      cmp=unsigned_longlong_str;
      smaller=ULONGLONG_NUM;
unknown's avatar
unknown committed
699
      bigger=DECIMAL_NUM;
unknown's avatar
unknown committed
700
    }
unknown's avatar
unknown committed
701 702 703 704
    else
    {
      cmp=longlong_str;
      smaller=LONG_NUM;
705
      bigger= ULONGLONG_NUM;
unknown's avatar
unknown committed
706 707 708 709 710 711
    }
  }
  while (*cmp && *cmp++ == *str++) ;
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
}

712
/*
713
  MYSQLlex remember the following states from the following MYSQLlex()
714 715 716 717 718

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

720
int MYSQLlex(void *arg, void *yythd)
unknown's avatar
unknown committed
721 722
{
  reg1	uchar c;
723
  bool comment_closed;
724
  int	tokval, result_state;
unknown's avatar
unknown committed
725
  uint length;
unknown's avatar
unknown committed
726
  enum my_lex_states state;
727 728 729
  THD *thd= (THD *)yythd;
  Lex_input_stream *lip= thd->m_lip;
  LEX *lex= thd->lex;
unknown's avatar
unknown committed
730
  YYSTYPE *yylval=(YYSTYPE*) arg;
731
  CHARSET_INFO *cs= thd->charset();
732 733
  uchar *state_map= cs->state_map;
  uchar *ident_map= cs->ident_map;
unknown's avatar
unknown committed
734

735
  lip->yylval=yylval;			// The global state
736

737
  lip->start_token();
738 739
  state=lip->next_state;
  lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
unknown's avatar
unknown committed
740 741 742
  LINT_INIT(c);
  for (;;)
  {
743
    switch (state) {
744 745
    case MY_LEX_OPERATOR_OR_IDENT:	// Next is operator or keyword
    case MY_LEX_START:			// Start of token
746 747
      // Skip starting whitespace
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
unknown's avatar
unknown committed
748 749
      {
	if (c == '\n')
750
	  lip->yylineno++;
751 752

        lip->yySkip();
unknown's avatar
unknown committed
753
      }
754 755 756 757

      /* Start of real token */
      lip->restart_token();
      c= lip->yyGet();
758
      state= (enum my_lex_states) state_map[c];
unknown's avatar
unknown committed
759
      break;
760
    case MY_LEX_ESCAPE:
761
      if (lip->yyGet() == 'N')
unknown's avatar
unknown committed
762 763 764 765 766
      {					// Allow \N as shortcut for NULL
	yylval->lex_str.str=(char*) "\\N";
	yylval->lex_str.length=2;
	return NULL_SYM;
      }
767 768
    case MY_LEX_CHAR:			// Unknown or single char token
    case MY_LEX_SKIP:			// This should not happen
769 770 771
      if (c == '-' && lip->yyPeek() == '-' &&
          (my_isspace(cs,lip->yyPeekn(1)) ||
           my_iscntrl(cs,lip->yyPeekn(1))))
772 773 774 775
      {
        state=MY_LEX_COMMENT;
        break;
      }
776

unknown's avatar
unknown committed
777
      if (c != ')')
778
	lip->next_state= MY_LEX_START;	// Allow signed numbers
779

unknown's avatar
unknown committed
780
      if (c == ',')
781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801
      {
        /*
          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();
      }
      else
      {
        /*
          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.
        */
        if (c == '?' && lip->stmt_prepare_mode && !ident_map[lip->yyPeek()])
802
        return(PARAM_MARKER);
803 804
      }

unknown's avatar
unknown committed
805 806
      return((int) c);

unknown's avatar
unknown committed
807
    case MY_LEX_IDENT_OR_NCHAR:
808 809
      if (lip->yyPeek() != '\'')
      {
unknown's avatar
unknown committed
810 811 812
	state= MY_LEX_IDENT;
	break;
      }
813
      /* Found N'string' */
814 815
      lip->yySkip();                         // Skip '
      if (!(yylval->lex_str.str = get_text(lip, 2, 1)))
unknown's avatar
unknown committed
816
      {
817 818
	state= MY_LEX_CHAR;             // Read char by char
	break;
unknown's avatar
unknown committed
819
      }
820
      yylval->lex_str.length= lip->yytoklen;
821
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
822
      return(NCHAR_STRING);
unknown's avatar
unknown committed
823

824
    case MY_LEX_IDENT_OR_HEX:
825
      if (lip->yyPeek() == '\'')
826
      {					// Found x'hex-number'
827
	state= MY_LEX_HEX_NUMBER;
828 829
	break;
      }
unknown's avatar
unknown committed
830
    case MY_LEX_IDENT_OR_BIN:
831
      if (lip->yyPeek() == '\'')
unknown's avatar
unknown committed
832 833 834 835
      {                                 // Found b'bin-number'
        state= MY_LEX_BIN_NUMBER;
        break;
      }
836
    case MY_LEX_IDENT:
837
      const char *start;
unknown's avatar
unknown committed
838
#if defined(USE_MB) && defined(USE_MB_IDENT)
839
      if (use_mb(cs))
unknown's avatar
unknown committed
840
      {
841
	result_state= IDENT_QUOTED;
842
        if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
unknown's avatar
unknown committed
843
        {
844 845 846
          int l = my_ismbchar(cs,
                              lip->get_ptr() -1,
                              lip->get_end_of_query());
unknown's avatar
unknown committed
847
          if (l == 0) {
848
            state = MY_LEX_CHAR;
unknown's avatar
unknown committed
849 850
            continue;
          }
851
          lip->skip_binary(l - 1);
unknown's avatar
unknown committed
852
        }
853
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
854
        {
855
          if (my_mbcharlen(cs, c) > 1)
unknown's avatar
unknown committed
856 857
          {
            int l;
858 859 860
            if ((l = my_ismbchar(cs,
                                 lip->get_ptr() -1,
                                 lip->get_end_of_query())) == 0)
unknown's avatar
unknown committed
861
              break;
862
            lip->skip_binary(l-1);
unknown's avatar
unknown committed
863 864 865 866 867
          }
        }
      }
      else
#endif
868
      {
869
        for (result_state= c; ident_map[c= lip->yyGet()]; result_state|= c);
unknown's avatar
unknown committed
870 871
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
872
      }
873 874
      length= lip->yyLength();
      start= lip->get_ptr();
875
      if (lip->ignore_space)
unknown's avatar
unknown committed
876
      {
unknown's avatar
unknown committed
877 878 879 880
        /*
          If we find a space then this can't be an identifier. We notice this
          below by checking start != lex->ptr.
        */
881
        for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet());
unknown's avatar
unknown committed
882
      }
883
      if (start == lip->get_ptr() && c == '.' && ident_map[lip->yyPeek()])
884
	lip->next_state=MY_LEX_IDENT_SEP;
unknown's avatar
unknown committed
885 886
      else
      {					// '(' must follow directly if function
887 888
        lip->yyUnget();
	if ((tokval = find_keyword(lip, length, c == '(')))
unknown's avatar
unknown committed
889
	{
890
	  lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
891 892
	  return(tokval);		// Was keyword
	}
893
        lip->yySkip();                  // next state does a unget
unknown's avatar
unknown committed
894
      }
895
      yylval->lex_str=get_token(lip, 0, length);
896

unknown's avatar
unknown committed
897
      /*
898 899
         Note: "SELECT _bla AS 'alias'"
         _bla should be considered as a IDENT if charset haven't been found.
unknown's avatar
unknown committed
900
         So we don't use MYF(MY_WME) with get_charset_by_csname to avoid
901 902 903
         producing an error.
      */

unknown's avatar
unknown committed
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
      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);

      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
                                    lip->m_cpp_text_end);

924
      return(result_state);			// IDENT or IDENT_QUOTED
unknown's avatar
unknown committed
925

926
    case MY_LEX_IDENT_SEP:		// Found ident and now '.'
927 928 929
      yylval->lex_str.str= (char*) lip->get_ptr();
      yylval->lex_str.length= 1;
      c= lip->yyGet();                  // should be '.'
930
      lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
931
      if (!ident_map[lip->yyPeek()])            // Probably ` or "
932
	lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
933 934
      return((int) c);

935
    case MY_LEX_NUMBER_IDENT:		// number or ident which num-start
936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968
      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')
        {
          while ((c= lip->yyGet()) == '0' || c == '1');
          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
969
      if (!ident_map[c])
unknown's avatar
unknown committed
970
      {					// Can't be identifier
971
	state=MY_LEX_INT_OR_REAL;
unknown's avatar
unknown committed
972 973 974 975
	break;
      }
      if (c == 'e' || c == 'E')
      {
unknown's avatar
unknown committed
976
	// The following test is written this way to allow numbers of type 1e1
977 978
        if (my_isdigit(cs,lip->yyPeek()) ||
            (c=(lip->yyGet())) == '+' || c == '-')
unknown's avatar
unknown committed
979
	{				// Allow 1E+10
980
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
unknown's avatar
unknown committed
981
	  {
982 983 984
            lip->yySkip();
            while (my_isdigit(cs,lip->yyGet())) ;
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
985 986 987
	    return(FLOAT_NUM);
	  }
	}
988
        lip->yyUnget();
unknown's avatar
unknown committed
989
      }
unknown's avatar
unknown committed
990
      // fall through
991
    case MY_LEX_IDENT_START:			// We come here after '.'
992
      result_state= IDENT;
unknown's avatar
unknown committed
993
#if defined(USE_MB) && defined(USE_MB_IDENT)
994
      if (use_mb(cs))
unknown's avatar
unknown committed
995
      {
996
	result_state= IDENT_QUOTED;
997
        while (ident_map[c=lip->yyGet()])
unknown's avatar
unknown committed
998
        {
999
          if (my_mbcharlen(cs, c) > 1)
unknown's avatar
unknown committed
1000 1001
          {
            int l;
1002 1003 1004
            if ((l = my_ismbchar(cs,
                                 lip->get_ptr() -1,
                                 lip->get_end_of_query())) == 0)
unknown's avatar
unknown committed
1005
              break;
1006
            lip->skip_binary(l-1);
unknown's avatar
unknown committed
1007 1008 1009 1010 1011
          }
        }
      }
      else
#endif
unknown's avatar
unknown committed
1012
      {
1013
        for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c);
unknown's avatar
unknown committed
1014 1015 1016
        /* If there were non-ASCII characters, mark that we must convert */
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
      }
1017
      if (c == '.' && ident_map[lip->yyPeek()])
1018
	lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
unknown's avatar
unknown committed
1019

1020
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1021 1022 1023 1024 1025 1026

      lip->body_utf8_append(lip->m_cpp_text_start);

      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
                                    lip->m_cpp_text_end);

1027
      return(result_state);
unknown's avatar
unknown committed
1028

1029
    case MY_LEX_USER_VARIABLE_DELIMITER:	// Found quote char
1030
    {
1031 1032
      uint double_quotes= 0;
      char quote_char= c;                       // Used char
1033
      while ((c=lip->yyGet()))
unknown's avatar
unknown committed
1034
      {
1035 1036
	int var_length;
	if ((var_length= my_mbcharlen(cs, c)) == 1)
1037 1038 1039
	{
	  if (c == quote_char)
	  {
1040
            if (lip->yyPeek() != quote_char)
1041
	      break;
1042
            c=lip->yyGet();
1043 1044 1045
	    double_quotes++;
	    continue;
	  }
1046 1047
	}
#ifdef USE_MB
1048
	else if (var_length < 1)
1049
	  break;				// Error
1050
        lip->skip_binary(var_length-1);
1051
#endif
unknown's avatar
unknown committed
1052
      }
1053
      if (double_quotes)
1054
	yylval->lex_str=get_quoted_token(lip, 1,
1055
                                         lip->yyLength() - double_quotes -1,
1056 1057
					 quote_char);
      else
1058
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
1059
      if (c == quote_char)
1060
        lip->yySkip();                  // Skip end `
1061
      lip->next_state= MY_LEX_START;
unknown's avatar
unknown committed
1062 1063 1064 1065 1066 1067

      lip->body_utf8_append(lip->m_cpp_text_start);

      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
                                    lip->m_cpp_text_end);

1068
      return(IDENT_QUOTED);
1069
    }
1070
    case MY_LEX_INT_OR_REAL:		// Complete int or incomplete real
unknown's avatar
unknown committed
1071 1072
      if (c != '.')
      {					// Found complete integer number.
1073
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1074 1075 1076
	return int_token(yylval->lex_str.str,yylval->lex_str.length);
      }
      // fall through
1077
    case MY_LEX_REAL:			// Incomplete real number
1078
      while (my_isdigit(cs,c = lip->yyGet())) ;
unknown's avatar
unknown committed
1079 1080 1081

      if (c == 'e' || c == 'E')
      {
1082
        c = lip->yyGet();
unknown's avatar
unknown committed
1083
	if (c == '-' || c == '+')
1084
          c = lip->yyGet();                     // Skip sign
1085
	if (!my_isdigit(cs,c))
unknown's avatar
unknown committed
1086
	{				// No digit after sign
1087
	  state= MY_LEX_CHAR;
unknown's avatar
unknown committed
1088 1089
	  break;
	}
1090 1091
        while (my_isdigit(cs,lip->yyGet())) ;
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1092 1093
	return(FLOAT_NUM);
      }
1094
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1095
      return(DECIMAL_NUM);
unknown's avatar
unknown committed
1096

1097
    case MY_LEX_HEX_NUMBER:		// Found x'hexstring'
1098 1099 1100 1101 1102 1103 1104 1105
      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
1106 1107 1108
      yylval->lex_str=get_token(lip,
                                2,          // skip x'
                                length-3);  // don't count x' and last '
1109 1110
      return (HEX_NUM);

unknown's avatar
unknown committed
1111
    case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
1112 1113
      lip->yySkip();                  // Accept opening '
      while ((c= lip->yyGet()) == '0' || c == '1');
unknown's avatar
unknown committed
1114
      if (c != '\'')
1115 1116 1117
        return(ABORT_SYM);            // Illegal hex constant
      lip->yySkip();                  // Accept closing '
      length= lip->yyLength();        // Length of bin-num + 3
1118 1119 1120 1121
      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
1122

1123
    case MY_LEX_CMP_OP:			// Incomplete comparison operator
1124 1125 1126 1127
      if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP ||
          state_map[lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
        lip->yySkip();
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
unknown's avatar
unknown committed
1128
      {
1129
	lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1130 1131
	return(tokval);
      }
1132
      state = MY_LEX_CHAR;		// Something fishy found
unknown's avatar
unknown committed
1133 1134
      break;

1135
    case MY_LEX_LONG_CMP_OP:		// Incomplete comparison operator
1136 1137
      if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP ||
          state_map[lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
unknown's avatar
unknown committed
1138
      {
1139 1140 1141
        lip->yySkip();
        if (state_map[lip->yyPeek()] == MY_LEX_CMP_OP)
          lip->yySkip();
unknown's avatar
unknown committed
1142
      }
1143
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
unknown's avatar
unknown committed
1144
      {
1145
	lip->next_state= MY_LEX_START;	// Found long op
unknown's avatar
unknown committed
1146 1147
	return(tokval);
      }
1148
      state = MY_LEX_CHAR;		// Something fishy found
unknown's avatar
unknown committed
1149 1150
      break;

1151
    case MY_LEX_BOOL:
1152
      if (c != lip->yyPeek())
unknown's avatar
unknown committed
1153
      {
1154
	state=MY_LEX_CHAR;
unknown's avatar
unknown committed
1155 1156
	break;
      }
1157
      lip->yySkip();
1158 1159
      tokval = find_keyword(lip,2,0);	// Is a bool operator
      lip->next_state= MY_LEX_START;	// Allow signed numbers
unknown's avatar
unknown committed
1160 1161
      return(tokval);

1162
    case MY_LEX_STRING_OR_DELIMITER:
1163
      if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
1164
      {
1165
	state= MY_LEX_USER_VARIABLE_DELIMITER;
1166 1167 1168
	break;
      }
      /* " used for strings */
1169
    case MY_LEX_STRING:			// Incomplete text string
1170
      if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
unknown's avatar
unknown committed
1171
      {
1172
	state= MY_LEX_CHAR;		// Read char by char
unknown's avatar
unknown committed
1173 1174
	break;
      }
1175
      yylval->lex_str.length=lip->yytoklen;
unknown's avatar
unknown committed
1176 1177 1178 1179 1180 1181 1182 1183 1184

      lip->body_utf8_append(lip->m_cpp_text_start);

      lip->body_utf8_append_literal(thd, &yylval->lex_str,
        lip->m_underscore_cs ? lip->m_underscore_cs : cs,
        lip->m_cpp_text_end);

      lip->m_underscore_cs= NULL;

1185
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
unknown's avatar
unknown committed
1186 1187
      return(TEXT_STRING);

1188
    case MY_LEX_COMMENT:			//  Comment
unknown's avatar
unknown committed
1189
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1190 1191
      while ((c = lip->yyGet()) != '\n' && c) ;
      lip->yyUnget();                   // Safety against eof
1192
      state = MY_LEX_START;		// Try again
unknown's avatar
unknown committed
1193
      break;
1194
    case MY_LEX_LONG_COMMENT:		/* Long C comment? */
1195
      if (lip->yyPeek() != '*')
unknown's avatar
unknown committed
1196
      {
1197
	state=MY_LEX_CHAR;		// Probable division
unknown's avatar
unknown committed
1198 1199
	break;
      }
unknown's avatar
unknown committed
1200
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1201 1202 1203 1204
      /* Reject '/' '*', since we might need to turn off the echo */
      lip->yyUnget();

      if (lip->yyPeekn(2) == '!')
unknown's avatar
unknown committed
1205
      {
1206 1207
        lip->in_comment= DISCARD_COMMENT;
        /* Accept '/' '*' '!', but do not keep this marker. */
unknown's avatar
unknown committed
1208
        lip->set_echo(FALSE);
1209 1210 1211 1212 1213 1214 1215
        lip->yySkip();
        lip->yySkip();
        lip->yySkip();

        /*
          The special comment format is very strict:
          '/' '*' '!', followed by exactly
1216 1217 1218 1219
          1 digit (major), 2 digits (minor), then 2 digits (dot).
          32302 -> 3.23.02
          50032 -> 5.0.32
          50114 -> 5.1.14
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
        */
        char version_str[6];
        version_str[0]= lip->yyPeekn(0);
        version_str[1]= lip->yyPeekn(1);
        version_str[2]= lip->yyPeekn(2);
        version_str[3]= lip->yyPeekn(3);
        version_str[4]= lip->yyPeekn(4);
        version_str[5]= 0;
        if (  my_isdigit(cs, version_str[0])
           && my_isdigit(cs, version_str[1])
           && my_isdigit(cs, version_str[2])
           && my_isdigit(cs, version_str[3])
           && my_isdigit(cs, version_str[4])
           )
        {
          ulong version;
          version=strtol(version_str, NULL, 10);

1238
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1239 1240 1241 1242 1243
          lip->yySkipn(5);

          if (version <= MYSQL_VERSION_ID)
          {
            /* Expand the content of the special comment as real code */
unknown's avatar
unknown committed
1244
            lip->set_echo(TRUE);
1245 1246 1247 1248 1249 1250 1251
            state=MY_LEX_START;
            break;
          }
        }
        else
        {
          state=MY_LEX_START;
unknown's avatar
unknown committed
1252
          lip->set_echo(TRUE);
1253 1254
          break;
        }
unknown's avatar
unknown committed
1255
      }
1256
      else
unknown's avatar
unknown committed
1257
      {
1258 1259 1260
        lip->in_comment= PRESERVE_COMMENT;
        lip->yySkip();                  // Accept /
        lip->yySkip();                  // Accept *
unknown's avatar
unknown committed
1261
      }
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271
      /*
        Discard:
        - regular '/' '*' comments,
        - special comments '/' '*' '!' for a future version,
        by scanning until we find a closing '*' '/' marker.
        Note: There is no such thing as nesting comments,
        the first '*' '/' sequence seen will mark the end.
      */
      comment_closed= FALSE;
      while (! lip->eof())
1272
      {
1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
        c= lip->yyGet();
        if (c == '*')
        {
          if (lip->yyPeek() == '/')
          {
            lip->yySkip();
            comment_closed= TRUE;
            state = MY_LEX_START;
            break;
          }
        }
        else if (c == '\n')
1285 1286
          lip->yylineno++;
      }
1287 1288 1289
      /* Unbalanced comments with a missing '*' '/' are a syntax error */
      if (! comment_closed)
        return (ABORT_SYM);
1290
      state = MY_LEX_START;             // Try again
1291
      lip->in_comment= NO_COMMENT;
unknown's avatar
unknown committed
1292
      lip->set_echo(TRUE);
unknown's avatar
unknown committed
1293
      break;
1294
    case MY_LEX_END_LONG_COMMENT:
1295
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
unknown's avatar
unknown committed
1296
      {
1297 1298 1299 1300 1301 1302
        /* 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
1303
        lip->set_echo(TRUE);
1304 1305
        lip->in_comment=NO_COMMENT;
        state=MY_LEX_START;
unknown's avatar
unknown committed
1306 1307
      }
      else
1308
	state=MY_LEX_CHAR;		// Return '*'
unknown's avatar
unknown committed
1309
      break;
1310
    case MY_LEX_SET_VAR:		// Check if ':='
1311
      if (lip->yyPeek() != '=')
unknown's avatar
unknown committed
1312
      {
1313
	state=MY_LEX_CHAR;		// Return ':'
unknown's avatar
unknown committed
1314 1315
	break;
      }
1316
      lip->yySkip();
unknown's avatar
unknown committed
1317
      return (SET_VAR);
1318
    case MY_LEX_SEMICOLON:			// optional line terminator
1319
      if (lip->yyPeek())
unknown's avatar
unknown committed
1320
      {
1321
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && 
1322
            !lip->stmt_prepare_mode)
1323
        {
unknown's avatar
unknown committed
1324
	  lex->safe_to_cache_query= 0;
1325
          lip->found_semicolon= lip->get_ptr();
unknown's avatar
unknown committed
1326
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
1327
          lip->next_state= MY_LEX_END;
unknown's avatar
unknown committed
1328
          lip->set_echo(TRUE);
unknown's avatar
unknown committed
1329
          return (END_OF_INPUT);
1330
        }
unknown's avatar
unknown committed
1331
        state= MY_LEX_CHAR;		// Return ';'
unknown's avatar
unknown committed
1332 1333
	break;
      }
1334 1335
      lip->next_state=MY_LEX_END;       // Mark for next loop
      return(END_OF_INPUT);
1336
    case MY_LEX_EOL:
1337
      if (lip->eof())
unknown's avatar
unknown committed
1338
      {
1339
        lip->yyUnget();                 // Reject the last '\0'
unknown's avatar
unknown committed
1340
        lip->set_echo(FALSE);
1341
        lip->yySkip();
unknown's avatar
unknown committed
1342
        lip->set_echo(TRUE);
1343 1344 1345
        /* Unbalanced comments with a missing '*' '/' are a syntax error */
        if (lip->in_comment != NO_COMMENT)
          return (ABORT_SYM);
1346 1347
        lip->next_state=MY_LEX_END;     // Mark for next loop
        return(END_OF_INPUT);
unknown's avatar
unknown committed
1348 1349 1350
      }
      state=MY_LEX_CHAR;
      break;
1351
    case MY_LEX_END:
1352
      lip->next_state=MY_LEX_END;
unknown's avatar
unknown committed
1353
      return(0);			// We found end of input last time
1354 1355
      
      /* Actually real shouldn't start with . but allow them anyhow */
1356
    case MY_LEX_REAL_OR_POINT:
1357
      if (my_isdigit(cs,lip->yyPeek()))
1358
	state = MY_LEX_REAL;		// Real
unknown's avatar
unknown committed
1359 1360
      else
      {
1361
	state= MY_LEX_IDENT_SEP;	// return '.'
1362
        lip->yyUnget();                 // Put back '.'
unknown's avatar
unknown committed
1363 1364
      }
      break;
1365
    case MY_LEX_USER_END:		// end '@' of user@hostname
1366
      switch (state_map[lip->yyPeek()]) {
1367 1368 1369
      case MY_LEX_STRING:
      case MY_LEX_USER_VARIABLE_DELIMITER:
      case MY_LEX_STRING_OR_DELIMITER:
unknown's avatar
unknown committed
1370
	break;
1371
      case MY_LEX_USER_END:
1372
	lip->next_state=MY_LEX_SYSTEM_VAR;
unknown's avatar
unknown committed
1373 1374
	break;
      default:
1375
	lip->next_state=MY_LEX_HOSTNAME;
unknown's avatar
unknown committed
1376 1377
	break;
      }
1378
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
1379 1380
      yylval->lex_str.length=1;
      return((int) '@');
1381
    case MY_LEX_HOSTNAME:		// end '@' of user@hostname
1382
      for (c=lip->yyGet() ;
1383
	   my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
1384 1385
           c= lip->yyGet()) ;
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
unknown's avatar
unknown committed
1386
      return(LEX_HOSTNAME);
1387
    case MY_LEX_SYSTEM_VAR:
1388
      yylval->lex_str.str=(char*) lip->get_ptr();
unknown's avatar
unknown committed
1389
      yylval->lex_str.length=1;
1390 1391
      lip->yySkip();                                    // Skip '@'
      lip->next_state= (state_map[lip->yyPeek()] ==
1392 1393 1394
			MY_LEX_USER_VARIABLE_DELIMITER ?
			MY_LEX_OPERATOR_OR_IDENT :
			MY_LEX_IDENT_OR_KEYWORD);
unknown's avatar
unknown committed
1395
      return((int) '@');
1396
    case MY_LEX_IDENT_OR_KEYWORD:
unknown's avatar
unknown committed
1397 1398 1399 1400 1401
      /*
	We come here when we have found two '@' in a row.
	We should now be able to handle:
	[(global | local | session) .]variable_name
      */
1402 1403

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

unknown's avatar
unknown committed
1407
      if (c == '.')
1408
	lip->next_state=MY_LEX_IDENT_SEP;
1409 1410
      length= lip->yyLength();
      if (length == 0)
unknown's avatar
unknown committed
1411
        return(ABORT_SYM);              // Names must be nonempty.
1412
      if ((tokval= find_keyword(lip, length,0)))
unknown's avatar
unknown committed
1413
      {
1414
        lip->yyUnget();                         // Put back 'c'
unknown's avatar
unknown committed
1415 1416
	return(tokval);				// Was keyword
      }
1417
      yylval->lex_str=get_token(lip, 0, length);
unknown's avatar
unknown committed
1418 1419 1420 1421 1422 1423

      lip->body_utf8_append(lip->m_cpp_text_start);

      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
                                    lip->m_cpp_text_end);

1424
      return(result_state);
unknown's avatar
unknown committed
1425 1426 1427
    }
  }
}
unknown's avatar
unknown committed
1428

1429

unknown's avatar
unknown committed
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442
/**
  Construct a copy of this object to be used for mysql_alter_table
  and mysql_create_table.

  Historically, these two functions modify their Alter_info
  arguments. This behaviour breaks re-execution of prepared
  statements and stored procedures and is compensated by always
  supplying a copy of Alter_info to these functions.

  @return You need to use check the error in THD for out
  of memory condition after calling this function.
*/

1443 1444 1445 1446 1447 1448 1449 1450 1451
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
  :drop_list(rhs.drop_list, mem_root),
  alter_list(rhs.alter_list, mem_root),
  key_list(rhs.key_list, mem_root),
  create_list(rhs.create_list, mem_root),
  flags(rhs.flags),
  keys_onoff(rhs.keys_onoff),
  tablespace_op(rhs.tablespace_op),
  partition_names(rhs.partition_names, mem_root),
unknown's avatar
unknown committed
1452 1453 1454 1455
  no_parts(rhs.no_parts),
  change_level(rhs.change_level),
  datetime_field(rhs.datetime_field),
  error_if_not_empty(rhs.error_if_not_empty)
1456 1457 1458 1459
{
  /*
    Make deep copies of used objects.
    This is not a fully deep copy - clone() implementations
unknown's avatar
unknown committed
1460
    of Alter_drop, Alter_column, Key, foreign_key, Key_part_spec
1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473
    do not copy string constants. At the same length the only
    reason we make a copy currently is that ALTER/CREATE TABLE
    code changes input Alter_info definitions, but string
    constants never change.
  */
  list_copy_and_replace_each_value(drop_list, mem_root);
  list_copy_and_replace_each_value(alter_list, mem_root);
  list_copy_and_replace_each_value(key_list, mem_root);
  list_copy_and_replace_each_value(create_list, mem_root);
  /* partition_names are not deeply copied currently */
}


1474 1475 1476 1477 1478 1479 1480
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
{
  /*
    TODO:
    This code assumes that there are no multi-bytes characters
    that can be considered white-space.
  */
1481

1482 1483 1484 1485 1486
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
  {
    str->length --;
    str->str ++;
  }
1487

1488 1489 1490 1491 1492 1493 1494 1495
  /*
    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 --;
  }
1496 1497
}

1498

unknown's avatar
unknown committed
1499 1500 1501 1502 1503 1504
/*
  st_select_lex structures initialisations
*/

void st_select_lex_node::init_query()
{
1505
  options= 0;
1506
  sql_cache= SQL_CACHE_UNSPECIFIED;
1507
  linkage= UNSPECIFIED_TYPE;
1508 1509
  no_error= no_table_names_allowed= 0;
  uncacheable= 0;
unknown's avatar
unknown committed
1510 1511 1512 1513 1514 1515 1516 1517 1518
}

void st_select_lex_node::init_select()
{
}

void st_select_lex_unit::init_query()
{
  st_select_lex_node::init_query();
1519
  linkage= GLOBAL_OPTIONS_TYPE;
unknown's avatar
unknown committed
1520
  global_parameters= first_select();
1521 1522
  select_limit_cnt= HA_POS_ERROR;
  offset_limit_cnt= 0;
1523
  union_distinct= 0;
unknown's avatar
unknown committed
1524
  prepared= optimized= executed= 0;
unknown's avatar
unknown committed
1525
  item= 0;
1526 1527
  union_result= 0;
  table= 0;
unknown's avatar
unknown committed
1528
  fake_select_lex= 0;
1529
  cleaned= 0;
1530
  item_list.empty();
1531
  describe= 0;
1532
  found_rows_for_union= 0;
unknown's avatar
unknown committed
1533 1534 1535 1536 1537
}

void st_select_lex::init_query()
{
  st_select_lex_node::init_query();
1538
  table_list.empty();
1539 1540
  top_join_list.empty();
  join_list= &top_join_list;
1541
  embedding= leaf_tables= 0;
unknown's avatar
unknown committed
1542
  item_list.empty();
unknown's avatar
unknown committed
1543
  join= 0;
1544
  having= prep_having= where= prep_where= 0;
1545
  olap= UNSPECIFIED_OLAP_TYPE;
1546
  having_fix_field= 0;
1547 1548
  context.select_lex= this;
  context.init();
unknown's avatar
unknown committed
1549 1550 1551
  /*
    Add the name resolution context of the current (sub)query to the
    stack of contexts for the whole query.
1552 1553 1554 1555 1556
    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
1557 1558
  */
  parent_lex->push_context(&context);
1559
  cond_count= between_count= with_wild= 0;
unknown's avatar
unknown committed
1560
  max_equal_elems= 0;
1561
  conds_processed_with_permanent_arena= 0;
unknown's avatar
unknown committed
1562
  ref_pointer_array= 0;
unknown's avatar
unknown committed
1563
  select_n_where_fields= 0;
unknown's avatar
unknown committed
1564
  select_n_having_items= 0;
1565
  subquery_in_having= explicit_limit= 0;
1566
  is_item_list_lookup= 0;
1567
  first_execution= 1;
unknown's avatar
unknown committed
1568
  first_cond_optimization= 1;
1569
  parsing_place= NO_MATTER;
1570
  exclude_from_table_unique_test= no_wrap_view_item= FALSE;
unknown's avatar
unknown committed
1571
  nest_level= 0;
1572
  link_next= 0;
unknown's avatar
unknown committed
1573 1574 1575 1576 1577
}

void st_select_lex::init_select()
{
  st_select_lex_node::init_select();
1578
  group_list.empty();
unknown's avatar
unknown committed
1579
  type= db= 0;
1580 1581 1582
  having= 0;
  table_join_options= 0;
  in_sum_expr= with_wild= 0;
unknown's avatar
unknown committed
1583
  options= 0;
1584
  sql_cache= SQL_CACHE_UNSPECIFIED;
1585
  braces= 0;
unknown's avatar
unknown committed
1586
  interval_list.empty();
unknown's avatar
unknown committed
1587
  ftfunc_list_alloc.empty();
unknown's avatar
unknown committed
1588
  inner_sum_func_list= 0;
unknown's avatar
unknown committed
1589
  ftfunc_list= &ftfunc_list_alloc;
unknown's avatar
unknown committed
1590
  linkage= UNSPECIFIED_TYPE;
unknown's avatar
unknown committed
1591 1592
  order_list.elements= 0;
  order_list.first= 0;
1593
  order_list.next= (uchar**) &order_list.first;
1594 1595 1596
  /* 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
1597
  with_sum_func= 0;
1598
  is_correlated= 0;
1599 1600
  cur_pos_in_select_list= UNDEF_POS;
  non_agg_fields.empty();
1601
  cond_value= having_value= Item::COND_UNDEF;
1602
  inner_refs_list.empty();
unknown's avatar
unknown committed
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616
}

/*
  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
1617
  slave= 0;
unknown's avatar
unknown committed
1618 1619
}

unknown's avatar
unknown committed
1620 1621
/*
  include on level down (but do not link)
unknown's avatar
unknown committed
1622

unknown's avatar
unknown committed
1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636
  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
1637 1638 1639 1640 1641 1642 1643 1644
/* 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
1645
  slave= 0;
unknown's avatar
unknown committed
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
}

/* 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
1660
  if (link_prev)
unknown's avatar
unknown committed
1661 1662 1663 1664
  {
    if ((*link_prev= link_next))
      link_next->link_prev= link_prev;
  }
1665 1666 1667 1668
  // Remove slave structure
  for (; slave; slave= slave->next)
    slave->fast_exclude();
  
unknown's avatar
unknown committed
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
}

/*
  excluding select_lex structure (except first (first select can't be
  deleted, because it is most upper select))
*/
void st_select_lex_node::exclude()
{
  //exclude from global list
  fast_exclude();
  //exclude from other structures
  if ((*prev= next))
    next->prev= prev;
  /* 
     We do not need following statements, because prev pointer of first 
     list element point to master->slave
     if (master->slave == this)
       master->slave= next;
  */
}
1689

1690 1691 1692 1693 1694 1695 1696 1697 1698 1699

/*
  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
1700 1701 1702
void st_select_lex_unit::exclude_level()
{
  SELECT_LEX_UNIT *units= 0, **units_last= &units;
unknown's avatar
unknown committed
1703
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
unknown's avatar
unknown committed
1704
  {
unknown's avatar
unknown committed
1705
    // unlink current level from global SELECTs list
unknown's avatar
unknown committed
1706 1707
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;
unknown's avatar
unknown committed
1708 1709

    // bring up underlay levels
unknown's avatar
unknown committed
1710 1711
    SELECT_LEX_UNIT **last= 0;
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
unknown's avatar
unknown committed
1712 1713
    {
      u->master= master;
unknown's avatar
unknown committed
1714
      last= (SELECT_LEX_UNIT**)&(u->next);
unknown's avatar
unknown committed
1715
    }
unknown's avatar
unknown committed
1716 1717 1718 1719 1720 1721 1722 1723
    if (last)
    {
      (*units_last)= sl->first_inner_unit();
      units_last= last;
    }
  }
  if (units)
  {
unknown's avatar
unknown committed
1724
    // include brought up levels in place of current
unknown's avatar
unknown committed
1725 1726
    (*prev)= units;
    (*units_last)= (SELECT_LEX_UNIT*)next;
unknown's avatar
unknown committed
1727 1728 1729
    if (next)
      next->prev= (SELECT_LEX_NODE**)units_last;
    units->prev= prev;
unknown's avatar
unknown committed
1730 1731
  }
  else
unknown's avatar
unknown committed
1732 1733
  {
    // exclude currect unit from list of nodes
unknown's avatar
unknown committed
1734
    (*prev)= next;
unknown's avatar
unknown committed
1735 1736 1737
    if (next)
      next->prev= prev;
  }
unknown's avatar
unknown committed
1738 1739
}

1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750

/*
  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
1751
    // unlink current level from global SELECTs list
1752 1753 1754
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
      sl->link_next->link_prev= sl->link_prev;

unknown's avatar
unknown committed
1755
    // unlink underlay levels
1756 1757 1758 1759 1760
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
    {
      u->exclude_level();
    }
  }
unknown's avatar
unknown committed
1761
  // exclude currect unit from list of nodes
1762
  (*prev)= next;
unknown's avatar
unknown committed
1763 1764
  if (next)
    next->prev= prev;
1765 1766 1767
}


unknown's avatar
unknown committed
1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779
/*
  st_select_lex_node::mark_as_dependent mark all st_select_lex struct from 
  this to 'last' as dependent

  SYNOPSIS
    last - pointer to last st_select_lex struct, before wich all 
           st_select_lex have to be marked as dependent

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

unknown's avatar
unknown committed
1780
void st_select_lex::mark_as_dependent(st_select_lex *last)
unknown's avatar
unknown committed
1781 1782 1783 1784 1785
{
  /*
    Mark all selects from resolved to 1 before select where was
    found table as depended (of select where was found table)
  */
unknown's avatar
unknown committed
1786
  for (SELECT_LEX *s= this;
1787
       s && s != last;
unknown's avatar
unknown committed
1788
       s= s->outer_select())
1789
    if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
unknown's avatar
unknown committed
1790 1791
    {
      // Select is dependent of outer select
1792 1793
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
                       UNCACHEABLE_DEPENDENT;
1794
      SELECT_LEX_UNIT *munit= s->master_unit();
1795 1796 1797 1798 1799 1800 1801 1802
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
                       UNCACHEABLE_DEPENDENT;
      for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
      {
        if (sl != s &&
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
          sl->uncacheable|= UNCACHEABLE_UNITED;
      }
unknown's avatar
unknown committed
1803
    }
1804 1805
  is_correlated= TRUE;
  this->master_unit()->item->is_correlated= TRUE;
unknown's avatar
unknown committed
1806 1807
}

1808 1809 1810 1811 1812
bool st_select_lex_node::set_braces(bool value)      { return 1; }
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; }
1813
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd, Table_ident *table,
1814
						  LEX_STRING *alias,
unknown's avatar
unknown committed
1815
						  ulong table_join_options,
1816
						  thr_lock_type flags,
unknown's avatar
unknown committed
1817
						  List<Index_hint> *hints,
unknown's avatar
unknown committed
1818
                                                  LEX_STRING *option)
1819 1820 1821
{
  return 0;
}
unknown's avatar
unknown committed
1822 1823 1824 1825 1826 1827 1828 1829
ulong st_select_lex_node::get_table_join_options()
{
  return 0;
}

/*
  prohibit using LIMIT clause
*/
unknown's avatar
unknown committed
1830
bool st_select_lex::test_limit()
unknown's avatar
unknown committed
1831
{
1832
  if (select_limit != 0)
unknown's avatar
unknown committed
1833 1834
  {
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
unknown's avatar
unknown committed
1835
             "LIMIT & IN/ALL/ANY/SOME subquery");
unknown's avatar
unknown committed
1836 1837 1838 1839 1840 1841
    return(1);
  }
  // no sense in ORDER BY without LIMIT
  order_list.empty();
  return(0);
}
1842

1843

1844 1845 1846 1847 1848
st_select_lex_unit* st_select_lex_unit::master_unit()
{
    return this;
}

1849

1850 1851 1852 1853 1854
st_select_lex* st_select_lex_unit::outer_select()
{
  return (st_select_lex*) master;
}

1855

unknown's avatar
unknown committed
1856
bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
unknown's avatar
unknown committed
1857
{
unknown's avatar
unknown committed
1858
  return add_to_list(thd, order_list, item, asc);
unknown's avatar
unknown committed
1859
}
1860

1861

unknown's avatar
unknown committed
1862
bool st_select_lex::add_item_to_list(THD *thd, Item *item)
1863
{
1864
  DBUG_ENTER("st_select_lex::add_item_to_list");
unknown's avatar
unknown committed
1865
  DBUG_PRINT("info", ("Item: 0x%lx", (long) item));
1866
  DBUG_RETURN(item_list.push_back(item));
1867 1868
}

1869

unknown's avatar
unknown committed
1870
bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc)
1871
{
unknown's avatar
unknown committed
1872
  return add_to_list(thd, group_list, item, asc);
1873 1874
}

1875

1876 1877 1878 1879 1880
bool st_select_lex::add_ftfunc_to_list(Item_func_match *func)
{
  return !func || ftfunc_list->push_back(func); // end of memory?
}

1881

1882 1883 1884 1885 1886
st_select_lex_unit* st_select_lex::master_unit()
{
  return (st_select_lex_unit*) master;
}

1887

1888 1889 1890 1891 1892
st_select_lex* st_select_lex::outer_select()
{
  return (st_select_lex*) master->get_master();
}

1893

1894 1895 1896 1897 1898 1899
bool st_select_lex::set_braces(bool value)
{
  braces= value;
  return 0; 
}

1900

1901 1902 1903 1904 1905 1906
bool st_select_lex::inc_in_sum_expr()
{
  in_sum_expr++;
  return 0;
}

1907

1908 1909 1910 1911 1912
uint st_select_lex::get_in_sum_expr()
{
  return in_sum_expr;
}

1913

1914 1915 1916 1917 1918 1919 1920 1921 1922 1923
TABLE_LIST* st_select_lex::get_table_list()
{
  return (TABLE_LIST*) table_list.first;
}

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

unknown's avatar
unknown committed
1924 1925 1926 1927 1928
ulong st_select_lex::get_table_join_options()
{
  return table_join_options;
}

1929

unknown's avatar
unknown committed
1930 1931 1932 1933
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
{
  if (ref_pointer_array)
    return 0;
1934 1935 1936 1937 1938

  /*
    We have to create array in prepared statement memory if it is
    prepared statement
  */
unknown's avatar
unknown committed
1939
  Query_arena *arena= thd->stmt_arena;
unknown's avatar
unknown committed
1940
  return (ref_pointer_array=
1941 1942 1943
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
                                                 item_list.elements +
                                                 select_n_having_items +
unknown's avatar
unknown committed
1944
                                                 select_n_where_fields +
1945
                                                 order_group_num)*5)) == 0;
unknown's avatar
unknown committed
1946 1947
}

1948

unknown's avatar
unknown committed
1949 1950
void st_select_lex_unit::print(String *str)
{
1951
  bool union_all= !union_distinct;
unknown's avatar
unknown committed
1952 1953 1954 1955
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
  {
    if (sl != first_select())
    {
1956
      str->append(STRING_WITH_LEN(" union "));
1957
      if (union_all)
1958
	str->append(STRING_WITH_LEN("all "));
1959
      else if (union_distinct == sl)
1960
        union_all= TRUE;
unknown's avatar
unknown committed
1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971
    }
    if (sl->braces)
      str->append('(');
    sl->print(thd, str);
    if (sl->braces)
      str->append(')');
  }
  if (fake_select_lex == global_parameters)
  {
    if (fake_select_lex->order_list.elements)
    {
1972
      str->append(STRING_WITH_LEN(" order by "));
unknown's avatar
unknown committed
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985
      fake_select_lex->print_order(str,
				   (ORDER *) fake_select_lex->
				   order_list.first);
    }
    fake_select_lex->print_limit(thd, str);
  }
}


void st_select_lex::print_order(String *str, ORDER *order)
{
  for (; order; order= order->next)
  {
1986 1987 1988
    if (order->counter_used)
    {
      char buffer[20];
unknown's avatar
unknown committed
1989 1990
      uint length= my_snprintf(buffer, 20, "%d", order->counter);
      str->append(buffer, length);
1991 1992 1993
    }
    else
      (*order->item)->print(str);
unknown's avatar
unknown committed
1994
    if (!order->asc)
1995
      str->append(STRING_WITH_LEN(" desc"));
unknown's avatar
unknown committed
1996 1997 1998 1999 2000
    if (order->next)
      str->append(',');
  }
}
 
2001

unknown's avatar
unknown committed
2002 2003
void st_select_lex::print_limit(THD *thd, String *str)
{
2004 2005 2006
  SELECT_LEX_UNIT *unit= master_unit();
  Item_subselect *item= unit->item;
  if (item && unit->global_parameters == this &&
unknown's avatar
VIEW  
unknown committed
2007 2008 2009 2010
      (item->substype() == Item_subselect::EXISTS_SUBS ||
       item->substype() == Item_subselect::IN_SUBS ||
       item->substype() == Item_subselect::ALL_SUBS))
  {
2011 2012
    DBUG_ASSERT(!item->fixed ||
                select_limit->val_int() == LL(1) && offset_limit == 0);
unknown's avatar
VIEW  
unknown committed
2013 2014 2015
    return;
  }

2016
  if (explicit_limit)
unknown's avatar
unknown committed
2017
  {
2018
    str->append(STRING_WITH_LEN(" limit "));
unknown's avatar
unknown committed
2019 2020
    if (offset_limit)
    {
2021
      offset_limit->print(str);
unknown's avatar
unknown committed
2022 2023
      str->append(',');
    }
2024
    select_limit->print(str);
unknown's avatar
unknown committed
2025 2026 2027
  }
}

2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
/**
  @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.
*/

void st_lex::cleanup_lex_after_parse_error(THD *thd)
{
  /*
    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
  */
2052
  if (thd->lex->sphead)
2053 2054 2055 2056 2057
  {
    delete thd->lex->sphead;
    thd->lex->sphead= NULL;
  }
}
unknown's avatar
VIEW  
unknown committed
2058

2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078
/*
  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)
{
unknown's avatar
unknown committed
2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089
  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;
    }
  }
2090 2091 2092 2093
  query_tables= 0;
  query_tables_last= &query_tables;
  query_tables_own_last= 0;
  if (init)
2094 2095 2096 2097 2098 2099 2100
  {
    /*
      We delay real initialization of hash (and therefore related
      memory allocation) until first insertion into this hash.
    */
    hash_clear(&sroutines);
  }
2101
  else if (sroutines.records)
2102 2103
  {
    /* Non-zero sroutines.records means that hash was initialized. */
2104
    my_hash_reset(&sroutines);
2105
  }
2106 2107 2108
  sroutines_list.empty();
  sroutines_list_own_last= sroutines_list.next;
  sroutines_list_own_elements= 0;
2109
  binlog_stmt_flags= 0;
2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125
}


/*
  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()
{
  hash_free(&sroutines);
}


2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140
/*
  Initialize LEX object.

  SYNOPSIS
    st_lex::st_lex()

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

st_lex::st_lex()
unknown's avatar
unknown committed
2141
  :result(0), yacc_yyss(0), yacc_yyvs(0),
unknown's avatar
unknown committed
2142
   sql_command(SQLCOM_END), option_type(OPT_DEFAULT)
2143
{
unknown's avatar
unknown committed
2144

unknown's avatar
unknown committed
2145 2146 2147 2148
  my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
                         plugins_static_buffer,
                         INITIAL_LEX_PLUGIN_LIST_SIZE, 
                         INITIAL_LEX_PLUGIN_LIST_SIZE);
2149
  reset_query_tables_list(TRUE);
2150 2151 2152
}


unknown's avatar
VIEW  
unknown committed
2153
/*
2154
  Check whether the merging algorithm can be used on this VIEW
unknown's avatar
VIEW  
unknown committed
2155 2156 2157 2158

  SYNOPSIS
    st_lex::can_be_merged()

2159
  DESCRIPTION
2160 2161 2162
    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,
2163 2164 2165
    HAVING clause, aggregate functions, DISTINCT clause, LIMIT clause and
    several underlying tables.

unknown's avatar
VIEW  
unknown committed
2166 2167 2168 2169 2170 2171 2172 2173 2174 2175
  RETURN
    FALSE - only temporary table algorithm can be used
    TRUE  - merge algorithm can be used
*/

bool st_lex::can_be_merged()
{
  // TODO: do not forget implement case when select_lex.table_list.elements==0

  /* find non VIEW subqueries/unions */
2176 2177 2178
  bool selects_allow_merge= select_lex.next_select() == 0;
  if (selects_allow_merge)
  {
2179 2180 2181
    for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit();
         tmp_unit;
         tmp_unit= tmp_unit->next_unit())
2182
    {
2183 2184 2185 2186
      if (tmp_unit->first_select()->parent_lex == this &&
          (tmp_unit->item == 0 ||
           (tmp_unit->item->place() != IN_WHERE &&
            tmp_unit->item->place() != IN_ON)))
2187 2188 2189 2190 2191 2192 2193 2194
      {
        selects_allow_merge= 0;
        break;
      }
    }
  }

  return (selects_allow_merge &&
unknown's avatar
VIEW  
unknown committed
2195 2196
	  select_lex.group_list.elements == 0 &&
	  select_lex.having == 0 &&
2197
          select_lex.with_sum_func == 0 &&
2198
	  select_lex.table_list.elements >= 1 &&
unknown's avatar
VIEW  
unknown committed
2199
	  !(select_lex.options & SELECT_DISTINCT) &&
2200
          select_lex.select_limit == 0);
unknown's avatar
VIEW  
unknown committed
2201 2202
}

2203

unknown's avatar
VIEW  
unknown committed
2204
/*
2205
  check if command can use VIEW with MERGE algorithm (for top VIEWs)
unknown's avatar
VIEW  
unknown committed
2206 2207 2208 2209

  SYNOPSIS
    st_lex::can_use_merged()

2210 2211 2212 2213 2214
  DESCRIPTION
    Only listed here commands can use merge algorithm in top level
    SELECT_LEX (for subqueries will be used merge algorithm if
    st_lex::can_not_use_merged() is not TRUE).

unknown's avatar
VIEW  
unknown committed
2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

bool st_lex::can_use_merged()
{
  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:
2234
  case SQLCOM_LOAD:
unknown's avatar
VIEW  
unknown committed
2235 2236 2237 2238 2239 2240
    return TRUE;
  default:
    return FALSE;
  }
}

2241
/*
2242
  Check if command can't use merged views in any part of command
2243 2244 2245 2246

  SYNOPSIS
    st_lex::can_not_use_merged()

2247 2248 2249 2250
  DESCRIPTION
    Temporary table algorithm will be used on all SELECT levels for queries
    listed here (see also st_lex::can_use_merged()).

2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
  RETURN
    FALSE - command can't use merged VIEWs
    TRUE  - VIEWs with MERGE algorithms can be used
*/

bool st_lex::can_not_use_merged()
{
  switch (sql_command)
  {
  case SQLCOM_CREATE_VIEW:
  case SQLCOM_SHOW_CREATE:
2262 2263 2264 2265 2266 2267
  /*
    SQLCOM_SHOW_FIELDS is necessary to make 
    information schema tables working correctly with views.
    see get_schema_tables_result function
  */
  case SQLCOM_SHOW_FIELDS:
2268 2269 2270 2271 2272 2273
    return TRUE;
  default:
    return FALSE;
  }
}

unknown's avatar
VIEW  
unknown committed
2274 2275 2276 2277 2278 2279 2280 2281 2282 2283
/*
  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
2284

unknown's avatar
VIEW  
unknown committed
2285 2286
bool st_lex::only_view_structure()
{
2287
  switch (sql_command) {
unknown's avatar
VIEW  
unknown committed
2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301
  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
2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326
/*
  Should Items_ident be printed correctly

  SYNOPSIS
    need_correct_ident()

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


bool st_lex::need_correct_ident()
{
  switch(sql_command)
  {
  case SQLCOM_SHOW_CREATE:
  case SQLCOM_SHOW_TABLES:
  case SQLCOM_CREATE_VIEW:
    return TRUE;
  default:
    return FALSE;
  }
}

2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343
/*
  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
*/

2344
uint8 st_lex::get_effective_with_check(TABLE_LIST *view)
2345 2346 2347 2348 2349 2350 2351
{
  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
2352

2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372
/**
  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
2373
st_lex::copy_db_to(char **p_db, size_t *p_db_length) const
2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389
{
  if (sphead)
  {
    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);
}

unknown's avatar
unknown committed
2390 2391 2392 2393 2394 2395 2396
/*
  initialize limit counters

  SYNOPSIS
    st_select_lex_unit::set_limit()
    values	- SELECT_LEX with initial values for counters
*/
unknown's avatar
VIEW  
unknown committed
2397

unknown's avatar
unknown committed
2398
void st_select_lex_unit::set_limit(st_select_lex *sl)
2399
{
2400
  ha_rows select_limit_val;
2401
  ulonglong val;
2402

unknown's avatar
unknown committed
2403
  DBUG_ASSERT(! thd->stmt_arena->is_stmt_prepare());
2404 2405 2406 2407 2408 2409 2410 2411 2412 2413
  val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
  select_limit_val= (ha_rows)val;
#ifndef BIG_TABLES
  /* 
    Check for overflow : ha_rows can be smaller then ulonglong if
    BIG_TABLES is off.
    */
  if (val != (ulonglong)select_limit_val)
    select_limit_val= HA_POS_ERROR;
#endif
2414 2415
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
                                                 ULL(0));
2416 2417
  select_limit_cnt= select_limit_val + offset_limit_cnt;
  if (select_limit_cnt < select_limit_val)
2418 2419 2420
    select_limit_cnt= HA_POS_ERROR;		// no limit
}

unknown's avatar
unknown committed
2421

2422
/**
2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
  @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.
2443 2444 2445 2446
*/

void st_lex::set_trg_event_type_for_tables()
{
2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545
  uint8 new_trg_event_map= 0;

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


2546 2547 2548 2549 2550 2551 2552 2553
  /*
    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)
  {
2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564
    /*
      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;
2565 2566 2567 2568 2569
    tables= tables->next_local;
  }
}


2570
/*
2571 2572
  Unlink the first table from the global table list and the first table from
  outer select (lex->select_lex) local list
2573 2574 2575

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

unknown's avatar
VIEW  
unknown committed
2578
  NOTES
2579 2580
    We assume that first tables in both lists is the same table or the local
    list is empty.
2581 2582

  RETURN
2583
    0	If 'query_tables' == 0
unknown's avatar
VIEW  
unknown committed
2584
    unlinked table
2585
      In this case link_to_local is set.
unknown's avatar
unknown committed
2586

2587
*/
unknown's avatar
VIEW  
unknown committed
2588
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
2589
{
unknown's avatar
VIEW  
unknown committed
2590 2591 2592 2593 2594 2595 2596 2597
  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;
2598 2599
    else
      query_tables_last= &query_tables;
unknown's avatar
VIEW  
unknown committed
2600 2601 2602 2603 2604 2605 2606
    first->next_global= 0;

    /*
      and from local list if it is not empty
    */
    if ((*link_to_local= test(select_lex.table_list.first)))
    {
2607 2608
      select_lex.context.table_list= 
        select_lex.context.first_name_resolution_table= first->next_local;
2609
      select_lex.table_list.first= (uchar*) (first->next_local);
unknown's avatar
VIEW  
unknown committed
2610 2611 2612
      select_lex.table_list.elements--;	//safety
      first->next_local= 0;
      /*
2613 2614
        Ensure that the global list has the same first table as the local
        list.
unknown's avatar
VIEW  
unknown committed
2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630
      */
      first_lists_tables_same();
    }
  }
  return first;
}


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

  SYNOPSYS
     st_lex::first_lists_tables_same()

  NOTES
2631 2632 2633 2634 2635 2636
    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
2637 2638 2639 2640 2641 2642 2643
*/

void st_lex::first_lists_tables_same()
{
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
  if (query_tables != first_table && first_table != 0)
  {
2644
    TABLE_LIST *next;
unknown's avatar
VIEW  
unknown committed
2645 2646
    if (query_tables_last == &first_table->next_global)
      query_tables_last= first_table->prev_global;
2647

2648
    if ((next= *first_table->prev_global= first_table->next_global))
unknown's avatar
VIEW  
unknown committed
2649 2650 2651 2652
      next->prev_global= first_table->prev_global;
    /* include in new place */
    first_table->next_global= query_tables;
    /*
2653 2654 2655
       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
2656 2657 2658 2659 2660
    */
    query_tables->prev_global= &first_table->next_global;
    first_table->prev_global= &query_tables;
    query_tables= first_table;
  }
2661 2662
}

unknown's avatar
unknown committed
2663

2664
/*
unknown's avatar
unknown committed
2665
  Link table back that was unlinked with unlink_first_table()
2666 2667 2668

  SYNOPSIS
    link_first_table_back()
unknown's avatar
VIEW  
unknown committed
2669
    link_to_local	do we need link this table to local
2670 2671 2672 2673

  RETURN
    global list
*/
unknown's avatar
VIEW  
unknown committed
2674 2675 2676

void st_lex::link_first_table_back(TABLE_LIST *first,
				   bool link_to_local)
2677
{
unknown's avatar
VIEW  
unknown committed
2678
  if (first)
2679
  {
unknown's avatar
VIEW  
unknown committed
2680 2681
    if ((first->next_global= query_tables))
      query_tables->prev_global= &first->next_global;
2682 2683
    else
      query_tables_last= &first->next_global;
unknown's avatar
VIEW  
unknown committed
2684 2685 2686 2687 2688
    query_tables= first;

    if (link_to_local)
    {
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
unknown's avatar
unknown committed
2689
      select_lex.context.table_list= first;
2690
      select_lex.table_list.first= (uchar*) first;
unknown's avatar
VIEW  
unknown committed
2691 2692 2693 2694 2695 2696
      select_lex.table_list.elements++;	//safety
    }
  }
}


2697 2698 2699 2700 2701 2702

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

  SYNOPSIS
    st_lex::cleanup_after_one_table_open()
2703 2704 2705 2706 2707

  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).
2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732
*/

void st_lex::cleanup_after_one_table_open()
{
  /*
    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;
    /* 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();
  }
2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767
}


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

void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup)
{
  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
*/

void st_lex::restore_backup_query_tables_list(Query_tables_list *backup)
{
  this->destroy_query_tables_list();
  this->set_query_tables_list(backup);
2768 2769 2770
}


unknown's avatar
unknown committed
2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792
/*
  Checks for usage of routines and/or tables in a parsed statement

  SYNOPSIS
    st_lex:table_or_sp_used()

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

bool st_lex::table_or_sp_used()
{
  DBUG_ENTER("table_or_sp_used");

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

  DBUG_RETURN(FALSE);
}


2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821
/*
  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)
  {
    if (tbl->on_expr)
    {
      tbl->prep_on_expr= tbl->on_expr;
      tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
    }
    fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
  }
}


unknown's avatar
VIEW  
unknown committed
2822
/*
2823
  Save WHERE/HAVING/ON clauses and replace them with disposable copies
unknown's avatar
VIEW  
unknown committed
2824 2825 2826

  SYNOPSIS
    st_select_lex::fix_prepare_information
2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837
      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
    AND/OR trees.
    The function also calls fix_prepare_info_in_table_list that saves all
    ON expressions.    
unknown's avatar
VIEW  
unknown committed
2838 2839
*/

2840 2841
void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
                                            Item **having_conds)
unknown's avatar
VIEW  
unknown committed
2842
{
unknown's avatar
unknown committed
2843
  if (!thd->stmt_arena->is_conventional() && first_execution)
unknown's avatar
VIEW  
unknown committed
2844 2845
  {
    first_execution= 0;
2846 2847 2848 2849 2850
    if (*conds)
    {
      prep_where= *conds;
      *conds= where= prep_where->copy_andor_structure(thd);
    }
2851 2852 2853 2854 2855
    if (*having_conds)
    {
      prep_having= *having_conds;
      *having_conds= having= prep_having->copy_andor_structure(thd);
    }
2856
    fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
2857 2858 2859
  }
}

unknown's avatar
unknown committed
2860

unknown's avatar
unknown committed
2861
/*
unknown's avatar
VIEW  
unknown committed
2862
  There are st_select_lex::add_table_to_list &
unknown's avatar
unknown committed
2863
  st_select_lex::set_lock_for_tables are in sql_parse.cc
unknown's avatar
unknown committed
2864

unknown's avatar
VIEW  
unknown committed
2865
  st_select_lex::print is in sql_select.cc
unknown's avatar
unknown committed
2866 2867

  st_select_lex_unit::prepare, st_select_lex_unit::exec,
2868 2869
  st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,
  st_select_lex_unit::change_result
unknown's avatar
unknown committed
2870
  are in sql_union.cc
unknown's avatar
unknown committed
2871
*/
2872

2873 2874 2875 2876 2877
/*
  Sets the kind of hints to be added by the calls to add_index_hint().

  SYNOPSIS
    set_index_hint_type()
2878 2879
      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.
2880 2881 2882 2883 2884 2885 2886 2887

  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.
*/
2888
void st_select_lex::set_index_hint_type(enum index_hint_type type_arg,
2889 2890
                                        index_clause_map clause)
{ 
2891
  current_index_hint_type= type_arg;
2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905
  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
2906
  index_hints= new (thd->mem_root) List<Index_hint>(); 
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926
}



/*
  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)
{
  return index_hints->push_front (new (thd->mem_root) 
unknown's avatar
unknown committed
2927
                                 Index_hint(current_index_hint_type,
2928 2929 2930
                                            current_index_hint_clause,
                                            str, length));
}
2931 2932 2933 2934 2935 2936

/**
  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
2937
  is used from the sql parser that doesn't have any ifdef's
2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949

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

bool st_lex::is_partition_management() const
{
  return (sql_command == SQLCOM_ALTER_TABLE &&
          (alter_info.flags == ALTER_ADD_PARTITION ||
           alter_info.flags == ALTER_REORGANIZE_PARTITION));
}