~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2006 MySQL AB
2
3
   This program is free software; you can redistribute it and/or modify
4
   it under the terms of the GNU General Public License as published by
5
   the Free Software Foundation; version 2 of the License.
6
7
   This program is distributed in the hope that it will be useful,
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
   GNU General Public License for more details.
11
12
   You should have received a copy of the GNU General Public License
13
   along with this program; if not, write to the Free Software
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
16
17
/* A lexical scanner on a temporary buffer with a yacc interface */
18
19
#define MYSQL_LEX 1
20
#include "mysql_priv.h"
21
#include "item_create.h"
22
#include <m_ctype.h>
23
#include <hash.h>
24
25
static int lex_one_token(void *arg, void *yythd);
26
27
/*
28
  We are using pointer to this variable for distinguishing between assignment
29
  to NEW row field (when parsing trigger definition) and structured variable.
30
*/
31
32
sys_var *trg_new_row_fake_var= (sys_var*) 0x01;
33
34
/**
35
  LEX_STRING constant for null-string to be used in parser and other places.
36
*/
37
const LEX_STRING null_lex_str= {NULL, 0};
38
39
/* Longest standard keyword name */
40
41
#define TOCK_NAME_LENGTH 24
42
43
/*
44
  The following data is based on the latin1 character set, and is only
45
  used when comparing keywords
46
*/
47
48
static uchar to_upper_lex[]=
49
{
50
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
51
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
52
   32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
53
   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
54
   64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
55
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
56
   96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
57
   80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
58
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
59
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
60
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
61
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
62
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
63
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
64
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
65
  208,209,210,211,212,213,214,247,216,217,218,219,220,221,222,255
66
};
67
68
/* 
69
  Names of the index hints (for error messages). Keep in sync with 
70
  index_hint_type 
71
*/
72
73
const char * index_hint_type_name[] =
74
{
75
  "IGNORE INDEX", 
76
  "USE INDEX", 
77
  "FORCE INDEX"
78
};
79
80
inline int lex_casecmp(const char *s, const char *t, uint len)
81
{
82
  while (len-- != 0 &&
83
	 to_upper_lex[(uchar) *s++] == to_upper_lex[(uchar) *t++]) ;
84
  return (int) len+1;
85
}
86
87
#include <lex_hash.h>
88
89
90
void lex_init(void)
91
{
92
  uint i;
93
  DBUG_ENTER("lex_init");
94
  for (i=0 ; i < array_elements(symbols) ; i++)
95
    symbols[i].length=(uchar) strlen(symbols[i].name);
96
  for (i=0 ; i < array_elements(sql_functions) ; i++)
97
    sql_functions[i].length=(uchar) strlen(sql_functions[i].name);
98
99
  DBUG_VOID_RETURN;
100
}
101
102
103
void lex_free(void)
104
{					// Call this when daemon ends
105
  DBUG_ENTER("lex_free");
106
  DBUG_VOID_RETURN;
107
}
108
109
110
void
111
st_parsing_options::reset()
112
{
113
  allows_variable= TRUE;
114
  allows_select_into= TRUE;
115
  allows_select_procedure= TRUE;
116
  allows_derived= TRUE;
117
}
118
119
Lex_input_stream::Lex_input_stream(THD *thd,
120
                                   const char* buffer,
121
                                   unsigned int length)
122
: m_thd(thd),
123
  yylineno(1),
124
  yytoklen(0),
125
  yylval(NULL),
126
  lookahead_token(END_OF_INPUT),
127
  lookahead_yylval(NULL),
128
  m_ptr(buffer),
129
  m_tok_start(NULL),
130
  m_tok_end(NULL),
131
  m_end_of_query(buffer + length),
132
  m_tok_start_prev(NULL),
133
  m_buf(buffer),
134
  m_buf_length(length),
135
  m_echo(TRUE),
136
  m_cpp_tok_start(NULL),
137
  m_cpp_tok_start_prev(NULL),
138
  m_cpp_tok_end(NULL),
139
  m_body_utf8(NULL),
140
  m_cpp_utf8_processed_ptr(NULL),
141
  next_state(MY_LEX_START),
142
  found_semicolon(NULL),
143
  ignore_space(1),
144
  stmt_prepare_mode(FALSE),
145
  in_comment(NO_COMMENT),
146
  m_underscore_cs(NULL)
147
{
148
  m_cpp_buf= (char*) thd->alloc(length + 1);
149
  m_cpp_ptr= m_cpp_buf;
150
}
151
152
Lex_input_stream::~Lex_input_stream()
153
{}
154
155
/**
156
  The operation is called from the parser in order to
157
  1) designate the intention to have utf8 body;
158
  1) Indicate to the lexer that we will need a utf8 representation of this
159
     statement;
160
  2) Determine the beginning of the body.
161
162
  @param thd        Thread context.
163
  @param begin_ptr  Pointer to the start of the body in the pre-processed
164
                    buffer.
165
*/
166
167
void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
168
{
169
  DBUG_ASSERT(begin_ptr);
170
  DBUG_ASSERT(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
171
172
  uint body_utf8_length=
173
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
174
    my_charset_utf8_bin.mbmaxlen;
175
176
  m_body_utf8= (char *) thd->alloc(body_utf8_length + 1);
177
  m_body_utf8_ptr= m_body_utf8;
178
  *m_body_utf8_ptr= 0;
179
180
  m_cpp_utf8_processed_ptr= begin_ptr;
181
}
182
183
/**
184
  @brief The operation appends unprocessed part of pre-processed buffer till
185
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to end_ptr.
186
187
  The idea is that some tokens in the pre-processed buffer (like character
188
  set introducers) should be skipped.
189
190
  Example:
191
    CPP buffer: SELECT 'str1', _latin1 'str2';
192
    m_cpp_utf8_processed_ptr -- points at the "SELECT ...";
193
    In order to skip "_latin1", the following call should be made:
194
      body_utf8_append(<pointer to "_latin1 ...">, <pointer to " 'str2'...">)
195
196
  @param ptr      Pointer in the pre-processed buffer, which specifies the
197
                  end of the chunk, which should be appended to the utf8
198
                  body.
199
  @param end_ptr  Pointer in the pre-processed buffer, to which
200
                  m_cpp_utf8_processed_ptr will be set in the end of the
201
                  operation.
202
*/
203
204
void Lex_input_stream::body_utf8_append(const char *ptr,
205
                                        const char *end_ptr)
206
{
207
  DBUG_ASSERT(m_cpp_buf <= ptr && ptr <= m_cpp_buf + m_buf_length);
208
  DBUG_ASSERT(m_cpp_buf <= end_ptr && end_ptr <= m_cpp_buf + m_buf_length);
209
210
  if (!m_body_utf8)
211
    return;
212
213
  if (m_cpp_utf8_processed_ptr >= ptr)
214
    return;
215
216
  int bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;
217
218
  memcpy(m_body_utf8_ptr, m_cpp_utf8_processed_ptr, bytes_to_copy);
219
  m_body_utf8_ptr += bytes_to_copy;
220
  *m_body_utf8_ptr= 0;
221
222
  m_cpp_utf8_processed_ptr= end_ptr;
223
}
224
225
/**
226
  The operation appends unprocessed part of the pre-processed buffer till
227
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to ptr.
228
229
  @param ptr  Pointer in the pre-processed buffer, which specifies the end
230
              of the chunk, which should be appended to the utf8 body.
231
*/
232
233
void Lex_input_stream::body_utf8_append(const char *ptr)
234
{
235
  body_utf8_append(ptr, ptr);
236
}
237
238
/**
239
  The operation converts the specified text literal to the utf8 and appends
240
  the result to the utf8-body.
241
242
  @param thd      Thread context.
243
  @param txt      Text literal.
244
  @param txt_cs   Character set of the text literal.
245
  @param end_ptr  Pointer in the pre-processed buffer, to which
246
                  m_cpp_utf8_processed_ptr will be set in the end of the
247
                  operation.
248
*/
249
250
void Lex_input_stream::body_utf8_append_literal(THD *thd,
251
                                                const LEX_STRING *txt,
252
                                                CHARSET_INFO *txt_cs,
253
                                                const char *end_ptr)
254
{
255
  if (!m_cpp_utf8_processed_ptr)
256
    return;
257
258
  LEX_STRING utf_txt;
259
260
  if (!my_charset_same(txt_cs, &my_charset_utf8_general_ci))
261
  {
262
    thd->convert_string(&utf_txt,
263
                        &my_charset_utf8_general_ci,
264
                        txt->str, txt->length,
265
                        txt_cs);
266
  }
267
  else
268
  {
269
    utf_txt.str= txt->str;
270
    utf_txt.length= txt->length;
271
  }
272
273
  /* NOTE: utf_txt.length is in bytes, not in symbols. */
274
275
  memcpy(m_body_utf8_ptr, utf_txt.str, utf_txt.length);
276
  m_body_utf8_ptr += utf_txt.length;
277
  *m_body_utf8_ptr= 0;
278
279
  m_cpp_utf8_processed_ptr= end_ptr;
280
}
281
282
283
/*
284
  This is called before every query that is to be parsed.
285
  Because of this, it's critical to not do too much things here.
286
  (We already do too much here)
287
*/
288
289
void lex_start(THD *thd)
290
{
291
  LEX *lex= thd->lex;
292
  DBUG_ENTER("lex_start");
293
294
  lex->thd= lex->unit.thd= thd;
295
296
  lex->context_stack.empty();
297
  lex->unit.init_query();
298
  lex->unit.init_select();
299
  /* 'parent_lex' is used in init_query() so it must be before it. */
300
  lex->select_lex.parent_lex= lex;
301
  lex->select_lex.init_query();
302
  lex->value_list.empty();
303
  lex->update_list.empty();
304
  lex->param_list.empty();
305
  lex->view_list.empty();
306
  lex->auxiliary_table_list.empty();
307
  lex->unit.next= lex->unit.master=
308
    lex->unit.link_next= lex->unit.return_to= 0;
309
  lex->unit.prev= lex->unit.link_prev= 0;
310
  lex->unit.slave= lex->unit.global_parameters= lex->current_select=
311
    lex->all_selects_list= &lex->select_lex;
312
  lex->select_lex.master= &lex->unit;
313
  lex->select_lex.prev= &lex->unit.slave;
314
  lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
315
  lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
316
  lex->select_lex.options= 0;
317
  lex->select_lex.init_order();
318
  lex->select_lex.group_list.empty();
319
  lex->describe= 0;
320
  lex->subqueries= FALSE;
321
  lex->derived_tables= 0;
322
  lex->lock_option= TL_READ;
323
  lex->leaf_tables_insert= 0;
324
  lex->parsing_options.reset();
325
  lex->empty_field_list_on_rset= 0;
326
  lex->select_lex.select_number= 1;
327
  lex->length=0;
328
  lex->select_lex.in_sum_expr=0;
329
  lex->select_lex.ftfunc_list_alloc.empty();
330
  lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc;
331
  lex->select_lex.group_list.empty();
332
  lex->select_lex.order_list.empty();
333
  lex->sql_command= SQLCOM_END;
334
  lex->duplicates= DUP_ERROR;
335
  lex->ignore= 0;
336
  lex->proc_list.first= 0;
337
  lex->escape_used= FALSE;
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
  lex->name.str= 0;
344
  lex->name.length= 0;
345
  lex->nest_level=0 ;
346
  lex->allow_sum_func= 0;
347
  lex->in_sum_func= NULL;
348
  /*
349
    ok, there must be a better solution for this, long-term
350
    I tried "bzero" in the sql_yacc.yy code, but that for
351
    some reason made the values zero, even if they were set
352
  */
353
  lex->server_options.server_name= 0;
354
  lex->server_options.server_name_length= 0;
355
  lex->server_options.host= 0;
356
  lex->server_options.db= 0;
357
  lex->server_options.username= 0;
358
  lex->server_options.password= 0;
359
  lex->server_options.scheme= 0;
360
  lex->server_options.socket= 0;
361
  lex->server_options.owner= 0;
362
  lex->server_options.port= -1;
363
364
  lex->is_lex_started= TRUE;
365
  DBUG_VOID_RETURN;
366
}
367
368
void lex_end(LEX *lex)
369
{
370
  DBUG_ENTER("lex_end");
371
  DBUG_PRINT("enter", ("lex: 0x%lx", (long) lex));
372
  if (lex->yacc_yyss)
373
  {
374
    my_free(lex->yacc_yyss, MYF(0));
375
    my_free(lex->yacc_yyvs, MYF(0));
376
    lex->yacc_yyss= 0;
377
    lex->yacc_yyvs= 0;
378
  }
379
380
  /* release used plugins */
381
  plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, 
382
                     lex->plugins.elements);
383
  reset_dynamic(&lex->plugins);
384
385
  DBUG_VOID_RETURN;
386
}
387
388
389
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
390
{
391
  const char *tok= lip->get_tok_start();
392
393
  SYMBOL *symbol= get_hash_symbol(tok, len, function);
394
  if (symbol)
395
  {
396
    lip->yylval->symbol.symbol=symbol;
397
    lip->yylval->symbol.str= (char*) tok;
398
    lip->yylval->symbol.length=len;
399
400
    return symbol->tok;
401
  }
402
  return 0;
403
}
404
405
/*
406
  Check if name is a keyword
407
408
  SYNOPSIS
409
    is_keyword()
410
    name      checked name (must not be empty)
411
    len       length of checked name
412
413
  RETURN VALUES
414
    0         name is a keyword
415
    1         name isn't a keyword
416
*/
417
418
bool is_keyword(const char *name, uint len)
419
{
420
  DBUG_ASSERT(len != 0);
421
  return get_hash_symbol(name,len,0)!=0;
422
}
423
424
bool is_lex_native_function(const LEX_STRING *name)
425
{
426
  DBUG_ASSERT(name != NULL);
427
  return (get_hash_symbol(name->str, name->length, 1) != 0);
428
}
429
430
/* make a copy of token before ptr and set yytoklen */
431
432
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
433
{
434
  LEX_STRING tmp;
435
  lip->yyUnget();                       // ptr points now after last token char
436
  tmp.length=lip->yytoklen=length;
437
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
438
439
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
440
  lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;
441
442
  return tmp;
443
}
444
445
/* 
446
 todo: 
447
   There are no dangerous charsets in mysql for function 
448
   get_quoted_token yet. But it should be fixed in the 
449
   future to operate multichar strings (like ucs2)
450
*/
451
452
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
453
                                   uint skip,
454
                                   uint length, char quote)
455
{
456
  LEX_STRING tmp;
457
  const char *from, *end;
458
  char *to;
459
  lip->yyUnget();                       // ptr points now after last token char
460
  tmp.length= lip->yytoklen=length;
461
  tmp.str=(char*) lip->m_thd->alloc(tmp.length+1);
462
  from= lip->get_tok_start() + skip;
463
  to= tmp.str;
464
  end= to+length;
465
466
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
467
  lip->m_cpp_text_end= lip->m_cpp_text_start + length;
468
469
  for ( ; to != end; )
470
  {
471
    if ((*to++= *from++) == quote)
472
    {
473
      from++;					// Skip double quotes
474
      lip->m_cpp_text_start++;
475
    }
476
  }
477
  *to= 0;					// End null for safety
478
  return tmp;
479
}
480
481
482
/*
483
  Return an unescaped text literal without quotes
484
  Fix sometimes to do only one scan of the string
485
*/
486
487
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
488
{
489
  register uchar c,sep;
490
  uint found_escape=0;
491
  CHARSET_INFO *cs= lip->m_thd->charset();
492
493
  lip->tok_bitmap= 0;
494
  sep= lip->yyGetLast();                        // String should end with this
495
  while (! lip->eof())
496
  {
497
    c= lip->yyGet();
498
    lip->tok_bitmap|= c;
499
#ifdef USE_MB
500
    {
501
      int l;
502
      if (use_mb(cs) &&
503
          (l = my_ismbchar(cs,
504
                           lip->get_ptr() -1,
505
                           lip->get_end_of_query()))) {
506
        lip->skip_binary(l-1);
507
        continue;
508
      }
509
    }
510
#endif
511
    if (c == '\\')
512
    {					// Escaped character
513
      found_escape=1;
514
      if (lip->eof())
515
	return 0;
516
      lip->yySkip();
517
    }
518
    else if (c == sep)
519
    {
520
      if (c == lip->yyGet())            // Check if two separators in a row
521
      {
522
        found_escape=1;                 // duplicate. Remember for delete
523
	continue;
524
      }
525
      else
526
        lip->yyUnget();
527
528
      /* Found end. Unescape and return string */
529
      const char *str, *end;
530
      char *start;
531
532
      str= lip->get_tok_start();
533
      end= lip->get_ptr();
534
      /* Extract the text from the token */
535
      str += pre_skip;
536
      end -= post_skip;
537
      DBUG_ASSERT(end >= str);
538
539
      if (!(start= (char*) lip->m_thd->alloc((uint) (end-str)+1)))
540
	return (char*) "";		// Sql_alloc has set error flag
541
542
      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
543
      lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;
544
545
      if (!found_escape)
546
      {
547
	lip->yytoklen=(uint) (end-str);
548
	memcpy(start,str,lip->yytoklen);
549
	start[lip->yytoklen]=0;
550
      }
551
      else
552
      {
553
        char *to;
554
555
	for (to=start ; str != end ; str++)
556
	{
557
#ifdef USE_MB
558
	  int l;
559
	  if (use_mb(cs) &&
560
              (l = my_ismbchar(cs, str, end))) {
561
	      while (l--)
562
		  *to++ = *str++;
563
	      str--;
564
	      continue;
565
	  }
566
#endif
567
	  if (!(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
568
              *str == '\\' && str+1 != end)
569
	  {
570
	    switch(*++str) {
571
	    case 'n':
572
	      *to++='\n';
573
	      break;
574
	    case 't':
575
	      *to++= '\t';
576
	      break;
577
	    case 'r':
578
	      *to++ = '\r';
579
	      break;
580
	    case 'b':
581
	      *to++ = '\b';
582
	      break;
583
	    case '0':
584
	      *to++= 0;			// Ascii null
585
	      break;
586
	    case 'Z':			// ^Z must be escaped on Win32
587
	      *to++='\032';
588
	      break;
589
	    case '_':
590
	    case '%':
591
	      *to++= '\\';		// remember prefix for wildcard
592
	      /* Fall through */
593
	    default:
594
              *to++= *str;
595
	      break;
596
	    }
597
	  }
598
	  else if (*str == sep)
599
	    *to++= *str++;		// Two ' or "
600
	  else
601
	    *to++ = *str;
602
	}
603
	*to=0;
604
	lip->yytoklen=(uint) (to-start);
605
      }
606
      return start;
607
    }
608
  }
609
  return 0;					// unexpected end of query
610
}
611
612
613
/*
614
** Calc type of integer; long integer, longlong integer or real.
615
** Returns smallest type that match the string.
616
** When using unsigned long long values the result is converted to a real
617
** because else they will be unexpected sign changes because all calculation
618
** is done with longlong or double.
619
*/
620
621
static const char *long_str="2147483647";
622
static const uint long_len=10;
623
static const char *signed_long_str="-2147483648";
624
static const char *longlong_str="9223372036854775807";
625
static const uint longlong_len=19;
626
static const char *signed_longlong_str="-9223372036854775808";
627
static const uint signed_longlong_len=19;
628
static const char *unsigned_longlong_str="18446744073709551615";
629
static const uint unsigned_longlong_len=20;
630
631
static inline uint int_token(const char *str,uint length)
632
{
633
  if (length < long_len)			// quick normal case
634
    return NUM;
635
  bool neg=0;
636
637
  if (*str == '+')				// Remove sign and pre-zeros
638
  {
639
    str++; length--;
640
  }
641
  else if (*str == '-')
642
  {
643
    str++; length--;
644
    neg=1;
645
  }
646
  while (*str == '0' && length)
647
  {
648
    str++; length --;
649
  }
650
  if (length < long_len)
651
    return NUM;
652
653
  uint smaller,bigger;
654
  const char *cmp;
655
  if (neg)
656
  {
657
    if (length == long_len)
658
    {
659
      cmp= signed_long_str+1;
660
      smaller=NUM;				// If <= signed_long_str
661
      bigger=LONG_NUM;				// If >= signed_long_str
662
    }
663
    else if (length < signed_longlong_len)
664
      return LONG_NUM;
665
    else if (length > signed_longlong_len)
666
      return DECIMAL_NUM;
667
    else
668
    {
669
      cmp=signed_longlong_str+1;
670
      smaller=LONG_NUM;				// If <= signed_longlong_str
671
      bigger=DECIMAL_NUM;
672
    }
673
  }
674
  else
675
  {
676
    if (length == long_len)
677
    {
678
      cmp= long_str;
679
      smaller=NUM;
680
      bigger=LONG_NUM;
681
    }
682
    else if (length < longlong_len)
683
      return LONG_NUM;
684
    else if (length > longlong_len)
685
    {
686
      if (length > unsigned_longlong_len)
687
        return DECIMAL_NUM;
688
      cmp=unsigned_longlong_str;
689
      smaller=ULONGLONG_NUM;
690
      bigger=DECIMAL_NUM;
691
    }
692
    else
693
    {
694
      cmp=longlong_str;
695
      smaller=LONG_NUM;
696
      bigger= ULONGLONG_NUM;
697
    }
698
  }
699
  while (*cmp && *cmp++ == *str++) ;
700
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
701
}
702
703
704
/*
705
  MYSQLlex remember the following states from the following MYSQLlex()
706
707
  - MY_LEX_EOQ			Found end of query
708
  - MY_LEX_OPERATOR_OR_IDENT	Last state was an ident, text or number
709
				(which can't be followed by a signed number)
710
*/
711
712
int MYSQLlex(void *arg, void *yythd)
713
{
714
  THD *thd= (THD *)yythd;
715
  Lex_input_stream *lip= thd->m_lip;
716
  YYSTYPE *yylval=(YYSTYPE*) arg;
717
  int token;
718
719
  if (lip->lookahead_token != END_OF_INPUT)
720
  {
721
    /*
722
      The next token was already parsed in advance,
723
      return it.
724
    */
725
    token= lip->lookahead_token;
726
    lip->lookahead_token= END_OF_INPUT;
727
    *yylval= *(lip->lookahead_yylval);
728
    lip->lookahead_yylval= NULL;
729
    return token;
730
  }
731
732
  token= lex_one_token(arg, yythd);
733
734
  switch(token) {
735
  case WITH:
736
    /*
737
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
738
      which makes the grammar LALR(2).
739
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
740
      to transform the grammar into a LALR(1) grammar,
741
      which sql_yacc.yy can process.
742
    */
743
    token= lex_one_token(arg, yythd);
744
    switch(token) {
745
    case CUBE_SYM:
746
      return WITH_CUBE_SYM;
747
    case ROLLUP_SYM:
748
      return WITH_ROLLUP_SYM;
749
    default:
750
      /*
751
        Save the token following 'WITH'
752
      */
753
      lip->lookahead_yylval= lip->yylval;
754
      lip->yylval= NULL;
755
      lip->lookahead_token= token;
756
      return WITH;
757
    }
758
    break;
759
  default:
760
    break;
761
  }
762
763
  return token;
764
}
765
766
int lex_one_token(void *arg, void *yythd)
767
{
768
  register unsigned char c= 0; /* Just set to shutup GCC */
769
  bool comment_closed;
770
  int	tokval, result_state;
771
  unsigned int length;
772
  enum my_lex_states state;
773
  THD *thd= (THD *)yythd;
774
  Lex_input_stream *lip= thd->m_lip;
775
  LEX *lex= thd->lex;
776
  YYSTYPE *yylval=(YYSTYPE*) arg;
777
  CHARSET_INFO *cs= thd->charset();
778
  uchar *state_map= cs->state_map;
779
  uchar *ident_map= cs->ident_map;
780
781
  lip->yylval=yylval;			// The global state
782
783
  lip->start_token();
784
  state=lip->next_state;
785
  lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
786
  for (;;)
787
  {
788
    switch (state) {
789
    case MY_LEX_OPERATOR_OR_IDENT:	// Next is operator or keyword
790
    case MY_LEX_START:			// Start of token
791
      // Skip starting whitespace
792
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
793
      {
794
	if (c == '\n')
795
	  lip->yylineno++;
796
797
        lip->yySkip();
798
      }
799
800
      /* Start of real token */
801
      lip->restart_token();
802
      c= lip->yyGet();
803
      state= (enum my_lex_states) state_map[c];
804
      break;
805
    case MY_LEX_ESCAPE:
806
      if (lip->yyGet() == 'N')
807
      {					// Allow \N as shortcut for NULL
808
	yylval->lex_str.str=(char*) "\\N";
809
	yylval->lex_str.length=2;
810
	return NULL_SYM;
811
      }
812
    case MY_LEX_CHAR:			// Unknown or single char token
813
    case MY_LEX_SKIP:			// This should not happen
814
      if (c == '-' && lip->yyPeek() == '-' &&
815
          (my_isspace(cs,lip->yyPeekn(1)) ||
816
           my_iscntrl(cs,lip->yyPeekn(1))))
817
      {
818
        state=MY_LEX_COMMENT;
819
        break;
820
      }
821
822
      if (c != ')')
823
	lip->next_state= MY_LEX_START;	// Allow signed numbers
824
825
      if (c == ',')
826
      {
827
        /*
828
          Warning:
829
          This is a work around, to make the "remember_name" rule in
830
          sql/sql_yacc.yy work properly.
831
          The problem is that, when parsing "select expr1, expr2",
832
          the code generated by bison executes the *pre* action
833
          remember_name (see select_item) *before* actually parsing the
834
          first token of expr2.
835
        */
836
        lip->restart_token();
837
      }
838
      else
839
      {
840
        /*
841
          Check for a placeholder: it should not precede a possible identifier
842
          because of binlogging: when a placeholder is replaced with
843
          its value in a query for the binlog, the query must stay
844
          grammatically correct.
845
        */
846
        if (c == '?' && lip->stmt_prepare_mode && !ident_map[(uint8_t)(lip->yyPeek())])
847
        return(PARAM_MARKER);
848
      }
849
850
      return((int) c);
851
852
    case MY_LEX_IDENT_OR_NCHAR:
853
      if (lip->yyPeek() != '\'')
854
      {
855
	state= MY_LEX_IDENT;
856
	break;
857
      }
858
      /* Found N'string' */
859
      lip->yySkip();                         // Skip '
860
      if (!(yylval->lex_str.str = get_text(lip, 2, 1)))
861
      {
862
	state= MY_LEX_CHAR;             // Read char by char
863
	break;
864
      }
865
      yylval->lex_str.length= lip->yytoklen;
866
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
867
      return(NCHAR_STRING);
868
869
    case MY_LEX_IDENT_OR_HEX:
870
      if (lip->yyPeek() == '\'')
871
      {					// Found x'hex-number'
872
	state= MY_LEX_HEX_NUMBER;
873
	break;
874
      }
875
    case MY_LEX_IDENT_OR_BIN:
876
      if (lip->yyPeek() == '\'')
877
      {                                 // Found b'bin-number'
878
        state= MY_LEX_BIN_NUMBER;
879
        break;
880
      }
881
    case MY_LEX_IDENT:
882
      const char *start;
883
#if defined(USE_MB) && defined(USE_MB_IDENT)
884
      if (use_mb(cs))
885
      {
886
	result_state= IDENT_QUOTED;
887
        if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
888
        {
889
          int l = my_ismbchar(cs,
890
                              lip->get_ptr() -1,
891
                              lip->get_end_of_query());
892
          if (l == 0) {
893
            state = MY_LEX_CHAR;
894
            continue;
895
          }
896
          lip->skip_binary(l - 1);
897
        }
898
        while (ident_map[c=lip->yyGet()])
899
        {
900
          if (my_mbcharlen(cs, c) > 1)
901
          {
902
            int l;
903
            if ((l = my_ismbchar(cs,
904
                                 lip->get_ptr() -1,
905
                                 lip->get_end_of_query())) == 0)
906
              break;
907
            lip->skip_binary(l-1);
908
          }
909
        }
910
      }
911
      else
912
#endif
913
      {
914
        for (result_state= c; ident_map[c= lip->yyGet()]; result_state|= c) {};
915
        /* If there were non-ASCII characters, mark that we must convert */
916
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
917
      }
918
      length= lip->yyLength();
919
      start= lip->get_ptr();
920
      if (lip->ignore_space)
921
      {
922
        /*
923
          If we find a space then this can't be an identifier. We notice this
924
          below by checking start != lex->ptr.
925
        */
926
        for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
927
      }
928
      if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
929
	lip->next_state=MY_LEX_IDENT_SEP;
930
      else
931
      {					// '(' must follow directly if function
932
        lip->yyUnget();
933
	if ((tokval = find_keyword(lip, length, c == '(')))
934
	{
935
	  lip->next_state= MY_LEX_START;	// Allow signed numbers
936
	  return(tokval);		// Was keyword
937
	}
938
        lip->yySkip();                  // next state does a unget
939
      }
940
      yylval->lex_str=get_token(lip, 0, length);
941
942
      /*
943
         Note: "SELECT _bla AS 'alias'"
944
         _bla should be considered as a IDENT if charset haven't been found.
945
         So we don't use MYF(MY_WME) with get_charset_by_csname to avoid
946
         producing an error.
947
      */
948
949
      if (yylval->lex_str.str[0] == '_')
950
      {
951
        CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1,
952
                                                MY_CS_PRIMARY, MYF(0));
953
        if (cs)
954
        {
955
          yylval->charset= cs;
956
          lip->m_underscore_cs= cs;
957
958
          lip->body_utf8_append(lip->m_cpp_text_start,
959
                                lip->get_cpp_tok_start() + length);
960
          return(UNDERSCORE_CHARSET);
961
        }
962
      }
963
964
      lip->body_utf8_append(lip->m_cpp_text_start);
965
966
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
967
                                    lip->m_cpp_text_end);
968
969
      return(result_state);			// IDENT or IDENT_QUOTED
970
971
    case MY_LEX_IDENT_SEP:		// Found ident and now '.'
972
      yylval->lex_str.str= (char*) lip->get_ptr();
973
      yylval->lex_str.length= 1;
974
      c= lip->yyGet();                  // should be '.'
975
      lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
976
      if (!ident_map[(uint8_t)lip->yyPeek()])            // Probably ` or "
977
	lip->next_state= MY_LEX_START;
978
      return((int) c);
979
980
    case MY_LEX_NUMBER_IDENT:		// number or ident which num-start
981
      if (lip->yyGetLast() == '0')
982
      {
983
        c= lip->yyGet();
984
        if (c == 'x')
985
        {
986
          while (my_isxdigit(cs,(c = lip->yyGet()))) ;
987
          if ((lip->yyLength() >= 3) && !ident_map[c])
988
          {
989
            /* skip '0x' */
990
            yylval->lex_str=get_token(lip, 2, lip->yyLength()-2);
991
            return (HEX_NUM);
992
          }
993
          lip->yyUnget();
994
          state= MY_LEX_IDENT_START;
995
          break;
996
        }
997
        else if (c == 'b')
998
        {
999
          while ((c= lip->yyGet()) == '0' || c == '1') {};
1000
          if ((lip->yyLength() >= 3) && !ident_map[c])
1001
          {
1002
            /* Skip '0b' */
1003
            yylval->lex_str= get_token(lip, 2, lip->yyLength()-2);
1004
            return (BIN_NUM);
1005
          }
1006
          lip->yyUnget();
1007
          state= MY_LEX_IDENT_START;
1008
          break;
1009
        }
1010
        lip->yyUnget();
1011
      }
1012
1013
      while (my_isdigit(cs, (c = lip->yyGet()))) ;
1014
      if (!ident_map[c])
1015
      {					// Can't be identifier
1016
	state=MY_LEX_INT_OR_REAL;
1017
	break;
1018
      }
1019
      if (c == 'e' || c == 'E')
1020
      {
1021
	// The following test is written this way to allow numbers of type 1e1
1022
        if (my_isdigit(cs,lip->yyPeek()) ||
1023
            (c=(lip->yyGet())) == '+' || c == '-')
1024
	{				// Allow 1E+10
1025
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
1026
	  {
1027
            lip->yySkip();
1028
            while (my_isdigit(cs,lip->yyGet())) ;
1029
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
1030
	    return(FLOAT_NUM);
1031
	  }
1032
	}
1033
        lip->yyUnget();
1034
      }
1035
      // fall through
1036
    case MY_LEX_IDENT_START:			// We come here after '.'
1037
      result_state= IDENT;
1038
#if defined(USE_MB) && defined(USE_MB_IDENT)
1039
      if (use_mb(cs))
1040
      {
1041
	result_state= IDENT_QUOTED;
1042
        while (ident_map[c=lip->yyGet()])
1043
        {
1044
          if (my_mbcharlen(cs, c) > 1)
1045
          {
1046
            int l;
1047
            if ((l = my_ismbchar(cs,
1048
                                 lip->get_ptr() -1,
1049
                                 lip->get_end_of_query())) == 0)
1050
              break;
1051
            lip->skip_binary(l-1);
1052
          }
1053
        }
1054
      }
1055
      else
1056
#endif
1057
      {
1058
        for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c) {};
1059
        /* If there were non-ASCII characters, mark that we must convert */
1060
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1061
      }
1062
      if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
1063
	lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
1064
1065
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
1066
1067
      lip->body_utf8_append(lip->m_cpp_text_start);
1068
1069
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
1070
                                    lip->m_cpp_text_end);
1071
1072
      return(result_state);
1073
1074
    case MY_LEX_USER_VARIABLE_DELIMITER:	// Found quote char
1075
    {
1076
      uint double_quotes= 0;
1077
      char quote_char= c;                       // Used char
1078
      while ((c=lip->yyGet()))
1079
      {
1080
	int var_length;
1081
	if ((var_length= my_mbcharlen(cs, c)) == 1)
1082
	{
1083
	  if (c == quote_char)
1084
	  {
1085
            if (lip->yyPeek() != quote_char)
1086
	      break;
1087
            c=lip->yyGet();
1088
	    double_quotes++;
1089
	    continue;
1090
	  }
1091
	}
1092
#ifdef USE_MB
1093
	else if (var_length < 1)
1094
	  break;				// Error
1095
        lip->skip_binary(var_length-1);
1096
#endif
1097
      }
1098
      if (double_quotes)
1099
	yylval->lex_str=get_quoted_token(lip, 1,
1100
                                         lip->yyLength() - double_quotes -1,
1101
					 quote_char);
1102
      else
1103
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
1104
      if (c == quote_char)
1105
        lip->yySkip();                  // Skip end `
1106
      lip->next_state= MY_LEX_START;
1107
1108
      lip->body_utf8_append(lip->m_cpp_text_start);
1109
1110
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
1111
                                    lip->m_cpp_text_end);
1112
1113
      return(IDENT_QUOTED);
1114
    }
1115
    case MY_LEX_INT_OR_REAL:		// Complete int or incomplete real
1116
      if (c != '.')
1117
      {					// Found complete integer number.
1118
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1119
	return int_token(yylval->lex_str.str,yylval->lex_str.length);
1120
      }
1121
      // fall through
1122
    case MY_LEX_REAL:			// Incomplete real number
1123
      while (my_isdigit(cs,c = lip->yyGet())) ;
1124
1125
      if (c == 'e' || c == 'E')
1126
      {
1127
        c = lip->yyGet();
1128
	if (c == '-' || c == '+')
1129
          c = lip->yyGet();                     // Skip sign
1130
	if (!my_isdigit(cs,c))
1131
	{				// No digit after sign
1132
	  state= MY_LEX_CHAR;
1133
	  break;
1134
	}
1135
        while (my_isdigit(cs,lip->yyGet())) ;
1136
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1137
	return(FLOAT_NUM);
1138
      }
1139
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1140
      return(DECIMAL_NUM);
1141
1142
    case MY_LEX_HEX_NUMBER:		// Found x'hexstring'
1143
      lip->yySkip();                    // Accept opening '
1144
      while (my_isxdigit(cs, (c= lip->yyGet()))) ;
1145
      if (c != '\'')
1146
        return(ABORT_SYM);              // Illegal hex constant
1147
      lip->yySkip();                    // Accept closing '
1148
      length= lip->yyLength();          // Length of hexnum+3
1149
      if ((length % 2) == 0)
1150
        return(ABORT_SYM);              // odd number of hex digits
1151
      yylval->lex_str=get_token(lip,
1152
                                2,          // skip x'
1153
                                length-3);  // don't count x' and last '
1154
      return (HEX_NUM);
1155
1156
    case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
1157
      lip->yySkip();                  // Accept opening '
1158
      while ((c= lip->yyGet()) == '0' || c == '1') {};
1159
      if (c != '\'')
1160
        return(ABORT_SYM);            // Illegal hex constant
1161
      lip->yySkip();                  // Accept closing '
1162
      length= lip->yyLength();        // Length of bin-num + 3
1163
      yylval->lex_str= get_token(lip,
1164
                                 2,         // skip b'
1165
                                 length-3); // don't count b' and last '
1166
      return (BIN_NUM);
1167
1168
    case MY_LEX_CMP_OP:			// Incomplete comparison operator
1169
      if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
1170
          state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
1171
        lip->yySkip();
1172
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1173
      {
1174
	lip->next_state= MY_LEX_START;	// Allow signed numbers
1175
	return(tokval);
1176
      }
1177
      state = MY_LEX_CHAR;		// Something fishy found
1178
      break;
1179
1180
    case MY_LEX_LONG_CMP_OP:		// Incomplete comparison operator
1181
      if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
1182
          state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
1183
      {
1184
        lip->yySkip();
1185
        if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP)
1186
          lip->yySkip();
1187
      }
1188
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1189
      {
1190
	lip->next_state= MY_LEX_START;	// Found long op
1191
	return(tokval);
1192
      }
1193
      state = MY_LEX_CHAR;		// Something fishy found
1194
      break;
1195
1196
    case MY_LEX_BOOL:
1197
      if (c != lip->yyPeek())
1198
      {
1199
	state=MY_LEX_CHAR;
1200
	break;
1201
      }
1202
      lip->yySkip();
1203
      tokval = find_keyword(lip,2,0);	// Is a bool operator
1204
      lip->next_state= MY_LEX_START;	// Allow signed numbers
1205
      return(tokval);
1206
1207
    case MY_LEX_STRING_OR_DELIMITER:
1208
      if (0)
1209
      {
1210
        state= MY_LEX_USER_VARIABLE_DELIMITER;
1211
        break;
1212
      }
1213
      /* " used for strings */
1214
    case MY_LEX_STRING:			// Incomplete text string
1215
      if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
1216
      {
1217
	state= MY_LEX_CHAR;		// Read char by char
1218
	break;
1219
      }
1220
      yylval->lex_str.length=lip->yytoklen;
1221
1222
      lip->body_utf8_append(lip->m_cpp_text_start);
1223
1224
      lip->body_utf8_append_literal(thd, &yylval->lex_str,
1225
        lip->m_underscore_cs ? lip->m_underscore_cs : cs,
1226
        lip->m_cpp_text_end);
1227
1228
      lip->m_underscore_cs= NULL;
1229
1230
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
1231
      return(TEXT_STRING);
1232
1233
    case MY_LEX_COMMENT:			//  Comment
1234
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1235
      while ((c = lip->yyGet()) != '\n' && c) ;
1236
      lip->yyUnget();                   // Safety against eof
1237
      state = MY_LEX_START;		// Try again
1238
      break;
1239
    case MY_LEX_LONG_COMMENT:		/* Long C comment? */
1240
      if (lip->yyPeek() != '*')
1241
      {
1242
	state=MY_LEX_CHAR;		// Probable division
1243
	break;
1244
      }
1245
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1246
      /* Reject '/' '*', since we might need to turn off the echo */
1247
      lip->yyUnget();
1248
1249
      if (lip->yyPeekn(2) == '!')
1250
      {
1251
        lip->in_comment= DISCARD_COMMENT;
1252
        /* Accept '/' '*' '!', but do not keep this marker. */
1253
        lip->set_echo(FALSE);
1254
        lip->yySkip();
1255
        lip->yySkip();
1256
        lip->yySkip();
1257
1258
        /*
1259
          The special comment format is very strict:
1260
          '/' '*' '!', followed by exactly
1261
          1 digit (major), 2 digits (minor), then 2 digits (dot).
1262
          32302 -> 3.23.02
1263
          50032 -> 5.0.32
1264
          50114 -> 5.1.14
1265
        */
1266
        char version_str[6];
1267
        version_str[0]= lip->yyPeekn(0);
1268
        version_str[1]= lip->yyPeekn(1);
1269
        version_str[2]= lip->yyPeekn(2);
1270
        version_str[3]= lip->yyPeekn(3);
1271
        version_str[4]= lip->yyPeekn(4);
1272
        version_str[5]= 0;
1273
        if (  my_isdigit(cs, version_str[0])
1274
           && my_isdigit(cs, version_str[1])
1275
           && my_isdigit(cs, version_str[2])
1276
           && my_isdigit(cs, version_str[3])
1277
           && my_isdigit(cs, version_str[4])
1278
           )
1279
        {
1280
          ulong version;
1281
          version=strtol(version_str, NULL, 10);
1282
1283
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1284
          lip->yySkipn(5);
1285
1286
          if (version <= MYSQL_VERSION_ID)
1287
          {
1288
            /* Expand the content of the special comment as real code */
1289
            lip->set_echo(TRUE);
1290
            state=MY_LEX_START;
1291
            break;
1292
          }
1293
        }
1294
        else
1295
        {
1296
          state=MY_LEX_START;
1297
          lip->set_echo(TRUE);
1298
          break;
1299
        }
1300
      }
1301
      else
1302
      {
1303
        lip->in_comment= PRESERVE_COMMENT;
1304
        lip->yySkip();                  // Accept /
1305
        lip->yySkip();                  // Accept *
1306
      }
1307
      /*
1308
        Discard:
1309
        - regular '/' '*' comments,
1310
        - special comments '/' '*' '!' for a future version,
1311
        by scanning until we find a closing '*' '/' marker.
1312
        Note: There is no such thing as nesting comments,
1313
        the first '*' '/' sequence seen will mark the end.
1314
      */
1315
      comment_closed= FALSE;
1316
      while (! lip->eof())
1317
      {
1318
        c= lip->yyGet();
1319
        if (c == '*')
1320
        {
1321
          if (lip->yyPeek() == '/')
1322
          {
1323
            lip->yySkip();
1324
            comment_closed= TRUE;
1325
            state = MY_LEX_START;
1326
            break;
1327
          }
1328
        }
1329
        else if (c == '\n')
1330
          lip->yylineno++;
1331
      }
1332
      /* Unbalanced comments with a missing '*' '/' are a syntax error */
1333
      if (! comment_closed)
1334
        return (ABORT_SYM);
1335
      state = MY_LEX_START;             // Try again
1336
      lip->in_comment= NO_COMMENT;
1337
      lip->set_echo(TRUE);
1338
      break;
1339
    case MY_LEX_END_LONG_COMMENT:
1340
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
1341
      {
1342
        /* Reject '*' '/' */
1343
        lip->yyUnget();
1344
        /* Accept '*' '/', with the proper echo */
1345
        lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
1346
        lip->yySkipn(2);
1347
        /* And start recording the tokens again */
1348
        lip->set_echo(TRUE);
1349
        lip->in_comment=NO_COMMENT;
1350
        state=MY_LEX_START;
1351
      }
1352
      else
1353
	state=MY_LEX_CHAR;		// Return '*'
1354
      break;
1355
    case MY_LEX_SET_VAR:		// Check if ':='
1356
      if (lip->yyPeek() != '=')
1357
      {
1358
	state=MY_LEX_CHAR;		// Return ':'
1359
	break;
1360
      }
1361
      lip->yySkip();
1362
      return (SET_VAR);
1363
    case MY_LEX_SEMICOLON:			// optional line terminator
1364
      if (lip->yyPeek())
1365
      {
1366
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && 
1367
            !lip->stmt_prepare_mode)
1368
        {
1369
          lip->found_semicolon= lip->get_ptr();
1370
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
1371
          lip->next_state= MY_LEX_END;
1372
          lip->set_echo(TRUE);
1373
          return (END_OF_INPUT);
1374
        }
1375
        state= MY_LEX_CHAR;		// Return ';'
1376
	break;
1377
      }
1378
      lip->next_state=MY_LEX_END;       // Mark for next loop
1379
      return(END_OF_INPUT);
1380
    case MY_LEX_EOL:
1381
      if (lip->eof())
1382
      {
1383
        lip->yyUnget();                 // Reject the last '\0'
1384
        lip->set_echo(FALSE);
1385
        lip->yySkip();
1386
        lip->set_echo(TRUE);
1387
        /* Unbalanced comments with a missing '*' '/' are a syntax error */
1388
        if (lip->in_comment != NO_COMMENT)
1389
          return (ABORT_SYM);
1390
        lip->next_state=MY_LEX_END;     // Mark for next loop
1391
        return(END_OF_INPUT);
1392
      }
1393
      state=MY_LEX_CHAR;
1394
      break;
1395
    case MY_LEX_END:
1396
      lip->next_state=MY_LEX_END;
1397
      return(0);			// We found end of input last time
1398
      
1399
      /* Actually real shouldn't start with . but allow them anyhow */
1400
    case MY_LEX_REAL_OR_POINT:
1401
      if (my_isdigit(cs,lip->yyPeek()))
1402
	state = MY_LEX_REAL;		// Real
1403
      else
1404
      {
1405
	state= MY_LEX_IDENT_SEP;	// return '.'
1406
        lip->yyUnget();                 // Put back '.'
1407
      }
1408
      break;
1409
    case MY_LEX_USER_END:		// end '@' of user@hostname
1410
      switch (state_map[(uint8_t)lip->yyPeek()]) {
1411
      case MY_LEX_STRING:
1412
      case MY_LEX_USER_VARIABLE_DELIMITER:
1413
      case MY_LEX_STRING_OR_DELIMITER:
1414
	break;
1415
      case MY_LEX_USER_END:
1416
	lip->next_state=MY_LEX_SYSTEM_VAR;
1417
	break;
1418
      default:
1419
	lip->next_state=MY_LEX_HOSTNAME;
1420
	break;
1421
      }
1422
      yylval->lex_str.str=(char*) lip->get_ptr();
1423
      yylval->lex_str.length=1;
1424
      return((int) '@');
1425
    case MY_LEX_HOSTNAME:		// end '@' of user@hostname
1426
      for (c=lip->yyGet() ;
1427
	   my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
1428
           c= lip->yyGet()) ;
1429
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1430
      return(LEX_HOSTNAME);
1431
    case MY_LEX_SYSTEM_VAR:
1432
      yylval->lex_str.str=(char*) lip->get_ptr();
1433
      yylval->lex_str.length=1;
1434
      lip->yySkip();                                    // Skip '@'
1435
      lip->next_state= (state_map[(uint8_t)lip->yyPeek()] ==
1436
			MY_LEX_USER_VARIABLE_DELIMITER ?
1437
			MY_LEX_OPERATOR_OR_IDENT :
1438
			MY_LEX_IDENT_OR_KEYWORD);
1439
      return((int) '@');
1440
    case MY_LEX_IDENT_OR_KEYWORD:
1441
      /*
1442
	We come here when we have found two '@' in a row.
1443
	We should now be able to handle:
1444
	[(global | local | session) .]variable_name
1445
      */
1446
1447
      for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
1448
      /* If there were non-ASCII characters, mark that we must convert */
1449
      result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1450
1451
      if (c == '.')
1452
	lip->next_state=MY_LEX_IDENT_SEP;
1453
      length= lip->yyLength();
1454
      if (length == 0)
1455
        return(ABORT_SYM);              // Names must be nonempty.
1456
      if ((tokval= find_keyword(lip, length,0)))
1457
      {
1458
        lip->yyUnget();                         // Put back 'c'
1459
	return(tokval);				// Was keyword
1460
      }
1461
      yylval->lex_str=get_token(lip, 0, length);
1462
1463
      lip->body_utf8_append(lip->m_cpp_text_start);
1464
1465
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
1466
                                    lip->m_cpp_text_end);
1467
1468
      return(result_state);
1469
    }
1470
  }
1471
}
1472
1473
1474
/**
1475
  Construct a copy of this object to be used for mysql_alter_table
1476
  and mysql_create_table.
1477
1478
  Historically, these two functions modify their Alter_info
1479
  arguments. This behaviour breaks re-execution of prepared
1480
  statements and stored procedures and is compensated by always
1481
  supplying a copy of Alter_info to these functions.
1482
1483
  @return You need to use check the error in THD for out
1484
  of memory condition after calling this function.
1485
*/
1486
1487
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
1488
  :drop_list(rhs.drop_list, mem_root),
1489
  alter_list(rhs.alter_list, mem_root),
1490
  key_list(rhs.key_list, mem_root),
1491
  create_list(rhs.create_list, mem_root),
1492
  flags(rhs.flags),
1493
  keys_onoff(rhs.keys_onoff),
1494
  tablespace_op(rhs.tablespace_op),
1495
  no_parts(rhs.no_parts),
1496
  build_method(rhs.build_method),
1497
  datetime_field(rhs.datetime_field),
1498
  error_if_not_empty(rhs.error_if_not_empty)
1499
{
1500
  /*
1501
    Make deep copies of used objects.
1502
    This is not a fully deep copy - clone() implementations
1503
    of Alter_drop, Alter_column, Key, foreign_key, Key_part_spec
1504
    do not copy string constants. At the same length the only
1505
    reason we make a copy currently is that ALTER/CREATE TABLE
1506
    code changes input Alter_info definitions, but string
1507
    constants never change.
1508
  */
1509
  list_copy_and_replace_each_value(drop_list, mem_root);
1510
  list_copy_and_replace_each_value(alter_list, mem_root);
1511
  list_copy_and_replace_each_value(key_list, mem_root);
1512
  list_copy_and_replace_each_value(create_list, mem_root);
1513
}
1514
1515
1516
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
1517
{
1518
  /*
1519
    TODO:
1520
    This code assumes that there are no multi-bytes characters
1521
    that can be considered white-space.
1522
  */
1523
1524
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
1525
  {
1526
    str->length --;
1527
    str->str ++;
1528
  }
1529
1530
  /*
1531
    FIXME:
1532
    Also, parsing backward is not safe with multi bytes characters
1533
  */
1534
  while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
1535
  {
1536
    str->length --;
1537
  }
1538
}
1539
1540
1541
/*
1542
  st_select_lex structures initialisations
1543
*/
1544
1545
void st_select_lex_node::init_query()
1546
{
1547
  options= 0;
1548
  linkage= UNSPECIFIED_TYPE;
1549
  no_error= no_table_names_allowed= 0;
1550
  uncacheable= 0;
1551
}
1552
1553
void st_select_lex_node::init_select()
1554
{
1555
}
1556
1557
void st_select_lex_unit::init_query()
1558
{
1559
  st_select_lex_node::init_query();
1560
  linkage= GLOBAL_OPTIONS_TYPE;
1561
  global_parameters= first_select();
1562
  select_limit_cnt= HA_POS_ERROR;
1563
  offset_limit_cnt= 0;
1564
  union_distinct= 0;
1565
  prepared= optimized= executed= 0;
1566
  item= 0;
1567
  union_result= 0;
1568
  table= 0;
1569
  fake_select_lex= 0;
1570
  cleaned= 0;
1571
  item_list.empty();
1572
  describe= 0;
1573
  found_rows_for_union= 0;
1574
}
1575
1576
void st_select_lex::init_query()
1577
{
1578
  st_select_lex_node::init_query();
1579
  table_list.empty();
1580
  top_join_list.empty();
1581
  join_list= &top_join_list;
1582
  embedding= leaf_tables= 0;
1583
  item_list.empty();
1584
  join= 0;
1585
  having= prep_having= where= prep_where= 0;
1586
  olap= UNSPECIFIED_OLAP_TYPE;
1587
  having_fix_field= 0;
1588
  context.select_lex= this;
1589
  context.init();
1590
  /*
1591
    Add the name resolution context of the current (sub)query to the
1592
    stack of contexts for the whole query.
1593
    TODO:
1594
    push_context may return an error if there is no memory for a new
1595
    element in the stack, however this method has no return value,
1596
    thus push_context should be moved to a place where query
1597
    initialization is checked for failure.
1598
  */
1599
  parent_lex->push_context(&context);
1600
  cond_count= between_count= with_wild= 0;
1601
  max_equal_elems= 0;
1602
  conds_processed_with_permanent_arena= 0;
1603
  ref_pointer_array= 0;
1604
  select_n_where_fields= 0;
1605
  select_n_having_items= 0;
1606
  subquery_in_having= explicit_limit= 0;
1607
  is_item_list_lookup= 0;
1608
  first_execution= 1;
1609
  first_cond_optimization= 1;
1610
  parsing_place= NO_MATTER;
1611
  exclude_from_table_unique_test= no_wrap_view_item= FALSE;
1612
  nest_level= 0;
1613
  link_next= 0;
1614
}
1615
1616
void st_select_lex::init_select()
1617
{
1618
  st_select_lex_node::init_select();
1619
  sj_nests.empty();
1620
  group_list.empty();
1621
  type= db= 0;
1622
  having= 0;
1623
  table_join_options= 0;
1624
  in_sum_expr= with_wild= 0;
1625
  options= 0;
1626
  braces= 0;
1627
  interval_list.empty();
1628
  ftfunc_list_alloc.empty();
1629
  inner_sum_func_list= 0;
1630
  ftfunc_list= &ftfunc_list_alloc;
1631
  linkage= UNSPECIFIED_TYPE;
1632
  order_list.elements= 0;
1633
  order_list.first= 0;
1634
  order_list.next= (uchar**) &order_list.first;
1635
  /* Set limit and offset to default values */
1636
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1637
  offset_limit= 0;      /* denotes the default offset = 0 */
1638
  with_sum_func= 0;
1639
  is_correlated= 0;
1640
  cur_pos_in_select_list= UNDEF_POS;
1641
  non_agg_fields.empty();
1642
  cond_value= having_value= Item::COND_UNDEF;
1643
  inner_refs_list.empty();
1644
  full_group_by_flag= 0;
1645
}
1646
1647
/*
1648
  st_select_lex structures linking
1649
*/
1650
1651
/* include on level down */
1652
void st_select_lex_node::include_down(st_select_lex_node *upper)
1653
{
1654
  if ((next= upper->slave))
1655
    next->prev= &next;
1656
  prev= &upper->slave;
1657
  upper->slave= this;
1658
  master= upper;
1659
  slave= 0;
1660
}
1661
1662
/*
1663
  include on level down (but do not link)
1664
1665
  SYNOPSYS
1666
    st_select_lex_node::include_standalone()
1667
    upper - reference on node underr which this node should be included
1668
    ref - references on reference on this node
1669
*/
1670
void st_select_lex_node::include_standalone(st_select_lex_node *upper,
1671
					    st_select_lex_node **ref)
1672
{
1673
  next= 0;
1674
  prev= ref;
1675
  master= upper;
1676
  slave= 0;
1677
}
1678
1679
/* include neighbour (on same level) */
1680
void st_select_lex_node::include_neighbour(st_select_lex_node *before)
1681
{
1682
  if ((next= before->next))
1683
    next->prev= &next;
1684
  prev= &before->next;
1685
  before->next= this;
1686
  master= before->master;
1687
  slave= 0;
1688
}
1689
1690
/* including in global SELECT_LEX list */
1691
void st_select_lex_node::include_global(st_select_lex_node **plink)
1692
{
1693
  if ((link_next= *plink))
1694
    link_next->link_prev= &link_next;
1695
  link_prev= plink;
1696
  *plink= this;
1697
}
1698
1699
//excluding from global list (internal function)
1700
void st_select_lex_node::fast_exclude()
1701
{
1702
  if (link_prev)
1703
  {
1704
    if ((*link_prev= link_next))
1705
      link_next->link_prev= link_prev;
1706
  }
1707
  // Remove slave structure
1708
  for (; slave; slave= slave->next)
1709
    slave->fast_exclude();
1710
  
1711
}
1712
1713
/*
1714
  excluding select_lex structure (except first (first select can't be
1715
  deleted, because it is most upper select))
1716
*/
1717
void st_select_lex_node::exclude()
1718
{
1719
  //exclude from global list
1720
  fast_exclude();
1721
  //exclude from other structures
1722
  if ((*prev= next))
1723
    next->prev= prev;
1724
  /* 
1725
     We do not need following statements, because prev pointer of first 
1726
     list element point to master->slave
1727
     if (master->slave == this)
1728
       master->slave= next;
1729
  */
1730
}
1731
1732
1733
/*
1734
  Exclude level of current unit from tree of SELECTs
1735
1736
  SYNOPSYS
1737
    st_select_lex_unit::exclude_level()
1738
1739
  NOTE: units which belong to current will be brought up on level of
1740
  currernt unit 
1741
*/
1742
void st_select_lex_unit::exclude_level()
1743
{
1744
  SELECT_LEX_UNIT *units= 0, **units_last= &units;
1745
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1746
  {
1747
    // unlink current level from global SELECTs list
1748
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
1749
      sl->link_next->link_prev= sl->link_prev;
1750
1751
    // bring up underlay levels
1752
    SELECT_LEX_UNIT **last= 0;
1753
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
1754
    {
1755
      u->master= master;
1756
      last= (SELECT_LEX_UNIT**)&(u->next);
1757
    }
1758
    if (last)
1759
    {
1760
      (*units_last)= sl->first_inner_unit();
1761
      units_last= last;
1762
    }
1763
  }
1764
  if (units)
1765
  {
1766
    // include brought up levels in place of current
1767
    (*prev)= units;
1768
    (*units_last)= (SELECT_LEX_UNIT*)next;
1769
    if (next)
1770
      next->prev= (SELECT_LEX_NODE**)units_last;
1771
    units->prev= prev;
1772
  }
1773
  else
1774
  {
1775
    // exclude currect unit from list of nodes
1776
    (*prev)= next;
1777
    if (next)
1778
      next->prev= prev;
1779
  }
1780
}
1781
1782
1783
/*
1784
  Exclude subtree of current unit from tree of SELECTs
1785
1786
  SYNOPSYS
1787
    st_select_lex_unit::exclude_tree()
1788
*/
1789
void st_select_lex_unit::exclude_tree()
1790
{
1791
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1792
  {
1793
    // unlink current level from global SELECTs list
1794
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
1795
      sl->link_next->link_prev= sl->link_prev;
1796
1797
    // unlink underlay levels
1798
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
1799
    {
1800
      u->exclude_level();
1801
    }
1802
  }
1803
  // exclude currect unit from list of nodes
1804
  (*prev)= next;
1805
  if (next)
1806
    next->prev= prev;
1807
}
1808
1809
1810
/*
1811
  st_select_lex_node::mark_as_dependent mark all st_select_lex struct from 
1812
  this to 'last' as dependent
1813
1814
  SYNOPSIS
1815
    last - pointer to last st_select_lex struct, before wich all 
1816
           st_select_lex have to be marked as dependent
1817
1818
  NOTE
1819
    'last' should be reachable from this st_select_lex_node
1820
*/
1821
1822
void st_select_lex::mark_as_dependent(st_select_lex *last)
1823
{
1824
  /*
1825
    Mark all selects from resolved to 1 before select where was
1826
    found table as depended (of select where was found table)
1827
  */
1828
  for (SELECT_LEX *s= this;
1829
       s && s != last;
1830
       s= s->outer_select())
1831
  {
1832
    if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
1833
    {
1834
      // Select is dependent of outer select
1835
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
1836
                       UNCACHEABLE_DEPENDENT;
1837
      SELECT_LEX_UNIT *munit= s->master_unit();
1838
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
1839
                       UNCACHEABLE_DEPENDENT;
1840
      for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
1841
      {
1842
        if (sl != s &&
1843
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
1844
          sl->uncacheable|= UNCACHEABLE_UNITED;
1845
      }
1846
    }
1847
    s->is_correlated= TRUE;
1848
    Item_subselect *subquery_predicate= s->master_unit()->item;
1849
    if (subquery_predicate)
1850
      subquery_predicate->is_correlated= TRUE;
1851
  }
1852
}
1853
77.1.15 by Monty Taylor
Bunch of warning cleanups.
1854
bool st_select_lex_node::set_braces(bool value __attribute__((__unused__)))
1855
{ return 1; }
1 by brian
clean slate
1856
bool st_select_lex_node::inc_in_sum_expr()           { return 1; }
1857
uint st_select_lex_node::get_in_sum_expr()           { return 0; }
1858
TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
1859
List<Item>* st_select_lex_node::get_item_list()      { return 0; }
77.1.15 by Monty Taylor
Bunch of warning cleanups.
1860
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd __attribute__((__unused__)),
1861
                                                   Table_ident *table __attribute__((__unused__)),
1862
						  LEX_STRING *alias __attribute__((__unused__)),
1863
						  ulong table_join_options __attribute__((__unused__)),
1864
						  thr_lock_type flags __attribute__((__unused__)),
1865
						  List<Index_hint> *hints __attribute__((__unused__)),
1866
                                                  LEX_STRING *option __attribute__((__unused__)))
1 by brian
clean slate
1867
{
1868
  return 0;
1869
}
1870
ulong st_select_lex_node::get_table_join_options()
1871
{
1872
  return 0;
1873
}
1874
1875
/*
1876
  prohibit using LIMIT clause
1877
*/
1878
bool st_select_lex::test_limit()
1879
{
1880
  if (select_limit != 0)
1881
  {
1882
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
1883
             "LIMIT & IN/ALL/ANY/SOME subquery");
1884
    return(1);
1885
  }
1886
  return(0);
1887
}
1888
1889
1890
st_select_lex_unit* st_select_lex_unit::master_unit()
1891
{
1892
    return this;
1893
}
1894
1895
1896
st_select_lex* st_select_lex_unit::outer_select()
1897
{
1898
  return (st_select_lex*) master;
1899
}
1900
1901
1902
bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
1903
{
1904
  return add_to_list(thd, order_list, item, asc);
1905
}
1906
1907
77.1.15 by Monty Taylor
Bunch of warning cleanups.
1908
bool st_select_lex::add_item_to_list(THD *thd __attribute__((__unused__)),
1909
                                     Item *item)
1 by brian
clean slate
1910
{
1911
  DBUG_ENTER("st_select_lex::add_item_to_list");
1912
  DBUG_PRINT("info", ("Item: 0x%lx", (long) item));
1913
  DBUG_RETURN(item_list.push_back(item));
1914
}
1915
1916
1917
bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc)
1918
{
1919
  return add_to_list(thd, group_list, item, asc);
1920
}
1921
1922
1923
st_select_lex_unit* st_select_lex::master_unit()
1924
{
1925
  return (st_select_lex_unit*) master;
1926
}
1927
1928
1929
st_select_lex* st_select_lex::outer_select()
1930
{
1931
  return (st_select_lex*) master->get_master();
1932
}
1933
1934
1935
bool st_select_lex::set_braces(bool value)
1936
{
1937
  braces= value;
1938
  return 0; 
1939
}
1940
1941
1942
bool st_select_lex::inc_in_sum_expr()
1943
{
1944
  in_sum_expr++;
1945
  return 0;
1946
}
1947
1948
1949
uint st_select_lex::get_in_sum_expr()
1950
{
1951
  return in_sum_expr;
1952
}
1953
1954
1955
TABLE_LIST* st_select_lex::get_table_list()
1956
{
1957
  return (TABLE_LIST*) table_list.first;
1958
}
1959
1960
List<Item>* st_select_lex::get_item_list()
1961
{
1962
  return &item_list;
1963
}
1964
1965
ulong st_select_lex::get_table_join_options()
1966
{
1967
  return table_join_options;
1968
}
1969
1970
1971
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
1972
{
1973
  if (ref_pointer_array)
1974
    return 0;
1975
1976
  /*
1977
    We have to create array in prepared statement memory if it is
1978
    prepared statement
1979
  */
1980
  Query_arena *arena= thd->stmt_arena;
1981
  return (ref_pointer_array=
1982
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
1983
                                                 item_list.elements +
1984
                                                 select_n_having_items +
1985
                                                 select_n_where_fields +
1986
                                                 order_group_num)*5)) == 0;
1987
}
1988
1989
1990
void st_select_lex_unit::print(String *str, enum_query_type query_type)
1991
{
1992
  bool union_all= !union_distinct;
1993
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
1994
  {
1995
    if (sl != first_select())
1996
    {
1997
      str->append(STRING_WITH_LEN(" union "));
1998
      if (union_all)
1999
	str->append(STRING_WITH_LEN("all "));
2000
      else if (union_distinct == sl)
2001
        union_all= TRUE;
2002
    }
2003
    if (sl->braces)
2004
      str->append('(');
2005
    sl->print(thd, str, query_type);
2006
    if (sl->braces)
2007
      str->append(')');
2008
  }
2009
  if (fake_select_lex == global_parameters)
2010
  {
2011
    if (fake_select_lex->order_list.elements)
2012
    {
2013
      str->append(STRING_WITH_LEN(" order by "));
2014
      fake_select_lex->print_order(
2015
        str,
2016
        (ORDER *) fake_select_lex->order_list.first,
2017
        query_type);
2018
    }
2019
    fake_select_lex->print_limit(thd, str, query_type);
2020
  }
2021
}
2022
2023
2024
void st_select_lex::print_order(String *str,
2025
                                ORDER *order,
2026
                                enum_query_type query_type)
2027
{
2028
  for (; order; order= order->next)
2029
  {
2030
    if (order->counter_used)
2031
    {
2032
      char buffer[20];
77.1.18 by Monty Taylor
Removed my_vsnprintf and my_snprintf.
2033
      uint length= snprintf(buffer, 20, "%d", order->counter);
1 by brian
clean slate
2034
      str->append(buffer, length);
2035
    }
2036
    else
2037
      (*order->item)->print(str, query_type);
2038
    if (!order->asc)
2039
      str->append(STRING_WITH_LEN(" desc"));
2040
    if (order->next)
2041
      str->append(',');
2042
  }
2043
}
2044
 
2045
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2046
void st_select_lex::print_limit(THD *thd __attribute__((__unused__)),
1 by brian
clean slate
2047
                                String *str,
2048
                                enum_query_type query_type)
2049
{
2050
  SELECT_LEX_UNIT *unit= master_unit();
2051
  Item_subselect *item= unit->item;
2052
2053
  if (item && unit->global_parameters == this)
2054
  {
2055
    Item_subselect::subs_type subs_type= item->substype();
2056
    if (subs_type == Item_subselect::EXISTS_SUBS ||
2057
        subs_type == Item_subselect::IN_SUBS ||
2058
        subs_type == Item_subselect::ALL_SUBS)
2059
    {
2060
      DBUG_ASSERT(!item->fixed ||
2061
                  /*
2062
                    If not using materialization both:
2063
                    select_limit == 1, and there should be no offset_limit.
2064
                  */
2065
                  (((subs_type == Item_subselect::IN_SUBS) &&
2066
                    ((Item_in_subselect*)item)->exec_method ==
2067
                    Item_in_subselect::MATERIALIZATION) ?
2068
                   TRUE :
80.1.1 by Brian Aker
LL() cleanup
2069
                   (select_limit->val_int() == 1LL) &&
1 by brian
clean slate
2070
                   offset_limit == 0));
2071
      return;
2072
    }
2073
  }
2074
  if (explicit_limit)
2075
  {
2076
    str->append(STRING_WITH_LEN(" limit "));
2077
    if (offset_limit)
2078
    {
2079
      offset_limit->print(str, query_type);
2080
      str->append(',');
2081
    }
2082
    select_limit->print(str, query_type);
2083
  }
2084
}
2085
2086
/**
2087
  @brief Restore the LEX and THD in case of a parse error.
2088
2089
  This is a clean up call that is invoked by the Bison generated
2090
  parser before returning an error from MYSQLparse. If your
2091
  semantic actions manipulate with the global thread state (which
2092
  is a very bad practice and should not normally be employed) and
2093
  need a clean-up in case of error, and you can not use %destructor
2094
  rule in the grammar file itself, this function should be used
2095
  to implement the clean up.
2096
*/
2097
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2098
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((__unused__)))
1 by brian
clean slate
2099
{
2100
}
2101
2102
/*
2103
  Initialize (or reset) Query_tables_list object.
2104
2105
  SYNOPSIS
2106
    reset_query_tables_list()
2107
      init  TRUE  - we should perform full initialization of object with
2108
                    allocating needed memory
2109
            FALSE - object is already initialized so we should only reset
2110
                    its state so it can be used for parsing/processing
2111
                    of new statement
2112
2113
  DESCRIPTION
2114
    This method initializes Query_tables_list so it can be used as part
2115
    of LEX object for parsing/processing of statement. One can also use
2116
    this method to reset state of already initialized Query_tables_list
2117
    so it can be used for processing of new statement.
2118
*/
2119
2120
void Query_tables_list::reset_query_tables_list(bool init)
2121
{
2122
  if (!init && query_tables)
2123
  {
2124
    TABLE_LIST *table= query_tables;
2125
    for (;;)
2126
    {
2127
      if (query_tables_last == &table->next_global ||
2128
          !(table= table->next_global))
2129
        break;
2130
    }
2131
  }
2132
  query_tables= 0;
2133
  query_tables_last= &query_tables;
2134
  query_tables_own_last= 0;
2135
  if (init)
2136
  {
2137
    /*
2138
      We delay real initialization of hash (and therefore related
2139
      memory allocation) until first insertion into this hash.
2140
    */
2141
    hash_clear(&sroutines);
2142
  }
2143
  else if (sroutines.records)
2144
  {
2145
    /* Non-zero sroutines.records means that hash was initialized. */
2146
    my_hash_reset(&sroutines);
2147
  }
2148
  sroutines_list.empty();
2149
  sroutines_list_own_last= sroutines_list.next;
2150
  sroutines_list_own_elements= 0;
2151
  binlog_stmt_flags= 0;
2152
}
2153
2154
2155
/*
2156
  Destroy Query_tables_list object with freeing all resources used by it.
2157
2158
  SYNOPSIS
2159
    destroy_query_tables_list()
2160
*/
2161
2162
void Query_tables_list::destroy_query_tables_list()
2163
{
2164
  hash_free(&sroutines);
2165
}
2166
2167
2168
/*
2169
  Initialize LEX object.
2170
2171
  SYNOPSIS
2172
    st_lex::st_lex()
2173
2174
  NOTE
2175
    LEX object initialized with this constructor can be used as part of
2176
    THD object for which one can safely call open_tables(), lock_tables()
2177
    and close_thread_tables() functions. But it is not yet ready for
2178
    statement parsing. On should use lex_start() function to prepare LEX
2179
    for this.
2180
*/
2181
2182
st_lex::st_lex()
2183
  :result(0), yacc_yyss(0), yacc_yyvs(0),
2184
   sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
2185
{
2186
2187
  my_init_dynamic_array2(&plugins, sizeof(plugin_ref),
2188
                         plugins_static_buffer,
2189
                         INITIAL_LEX_PLUGIN_LIST_SIZE, 
2190
                         INITIAL_LEX_PLUGIN_LIST_SIZE);
2191
  reset_query_tables_list(TRUE);
2192
}
2193
2194
2195
/*
2196
  Check whether the merging algorithm can be used on this VIEW
2197
2198
  SYNOPSIS
2199
    st_lex::can_be_merged()
2200
2201
  DESCRIPTION
2202
    We can apply merge algorithm if it is single SELECT view  with
2203
    subqueries only in WHERE clause (we do not count SELECTs of underlying
2204
    views, and second level subqueries) and we have not grpouping, ordering,
2205
    HAVING clause, aggregate functions, DISTINCT clause, LIMIT clause and
2206
    several underlying tables.
2207
2208
  RETURN
2209
    FALSE - only temporary table algorithm can be used
2210
    TRUE  - merge algorithm can be used
2211
*/
2212
2213
bool st_lex::can_be_merged()
2214
{
2215
  // TODO: do not forget implement case when select_lex.table_list.elements==0
2216
2217
  /* find non VIEW subqueries/unions */
2218
  bool selects_allow_merge= select_lex.next_select() == 0;
2219
  if (selects_allow_merge)
2220
  {
2221
    for (SELECT_LEX_UNIT *tmp_unit= select_lex.first_inner_unit();
2222
         tmp_unit;
2223
         tmp_unit= tmp_unit->next_unit())
2224
    {
2225
      if (tmp_unit->first_select()->parent_lex == this &&
2226
          (tmp_unit->item == 0 ||
2227
           (tmp_unit->item->place() != IN_WHERE &&
2228
            tmp_unit->item->place() != IN_ON)))
2229
      {
2230
        selects_allow_merge= 0;
2231
        break;
2232
      }
2233
    }
2234
  }
2235
2236
  return (selects_allow_merge &&
2237
	  select_lex.group_list.elements == 0 &&
2238
	  select_lex.having == 0 &&
2239
          select_lex.with_sum_func == 0 &&
2240
	  select_lex.table_list.elements >= 1 &&
2241
	  !(select_lex.options & SELECT_DISTINCT) &&
2242
          select_lex.select_limit == 0);
2243
}
2244
2245
2246
/*
2247
  check if command can use VIEW with MERGE algorithm (for top VIEWs)
2248
2249
  SYNOPSIS
2250
    st_lex::can_use_merged()
2251
2252
  DESCRIPTION
2253
    Only listed here commands can use merge algorithm in top level
2254
    SELECT_LEX (for subqueries will be used merge algorithm if
2255
    st_lex::can_not_use_merged() is not TRUE).
2256
2257
  RETURN
2258
    FALSE - command can't use merged VIEWs
2259
    TRUE  - VIEWs with MERGE algorithms can be used
2260
*/
2261
2262
bool st_lex::can_use_merged()
2263
{
2264
  switch (sql_command)
2265
  {
2266
  case SQLCOM_SELECT:
2267
  case SQLCOM_CREATE_TABLE:
2268
  case SQLCOM_UPDATE:
2269
  case SQLCOM_UPDATE_MULTI:
2270
  case SQLCOM_DELETE:
2271
  case SQLCOM_DELETE_MULTI:
2272
  case SQLCOM_INSERT:
2273
  case SQLCOM_INSERT_SELECT:
2274
  case SQLCOM_REPLACE:
2275
  case SQLCOM_REPLACE_SELECT:
2276
  case SQLCOM_LOAD:
2277
    return TRUE;
2278
  default:
2279
    return FALSE;
2280
  }
2281
}
2282
2283
/*
2284
  Check if command can't use merged views in any part of command
2285
2286
  SYNOPSIS
2287
    st_lex::can_not_use_merged()
2288
2289
  DESCRIPTION
2290
    Temporary table algorithm will be used on all SELECT levels for queries
2291
    listed here (see also st_lex::can_use_merged()).
2292
2293
  RETURN
2294
    FALSE - command can't use merged VIEWs
2295
    TRUE  - VIEWs with MERGE algorithms can be used
2296
*/
2297
2298
bool st_lex::can_not_use_merged()
2299
{
2300
  switch (sql_command)
2301
  {
2302
  /*
2303
    SQLCOM_SHOW_FIELDS is necessary to make 
2304
    information schema tables working correctly with views.
2305
    see get_schema_tables_result function
2306
  */
2307
  case SQLCOM_SHOW_FIELDS:
2308
    return TRUE;
2309
  default:
2310
    return FALSE;
2311
  }
2312
}
2313
2314
/*
2315
  Detect that we need only table structure of derived table/view
2316
2317
  SYNOPSIS
2318
    only_view_structure()
2319
2320
  RETURN
2321
    TRUE yes, we need only structure
2322
    FALSE no, we need data
2323
*/
2324
2325
bool st_lex::only_view_structure()
2326
{
2327
  switch (sql_command) {
2328
  case SQLCOM_SHOW_CREATE:
2329
  case SQLCOM_SHOW_TABLES:
2330
  case SQLCOM_SHOW_FIELDS:
2331
    return TRUE;
2332
  default:
2333
    return FALSE;
2334
  }
2335
}
2336
2337
2338
/*
2339
  Should Items_ident be printed correctly
2340
2341
  SYNOPSIS
2342
    need_correct_ident()
2343
2344
  RETURN
2345
    TRUE yes, we need only structure
2346
    FALSE no, we need data
2347
*/
2348
2349
2350
bool st_lex::need_correct_ident()
2351
{
2352
  switch(sql_command)
2353
  {
2354
  case SQLCOM_SHOW_CREATE:
2355
  case SQLCOM_SHOW_TABLES:
2356
    return TRUE;
2357
  default:
2358
    return FALSE;
2359
  }
2360
}
2361
2362
/*
2363
  Get effective type of CHECK OPTION for given view
2364
2365
  SYNOPSIS
2366
    get_effective_with_check()
2367
    view    given view
2368
2369
  NOTE
2370
    It have not sense to set CHECK OPTION for SELECT satement or subqueries,
2371
    so we do not.
2372
2373
  RETURN
2374
    VIEW_CHECK_NONE      no need CHECK OPTION
2375
    VIEW_CHECK_LOCAL     CHECK OPTION LOCAL
2376
    VIEW_CHECK_CASCADED  CHECK OPTION CASCADED
2377
*/
2378
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2379
uint8 st_lex::get_effective_with_check(TABLE_LIST *view __attribute__((__unused__)))
1 by brian
clean slate
2380
{
2381
  return 0;
2382
}
2383
2384
2385
/**
2386
  This method should be called only during parsing.
2387
  It is aware of compound statements (stored routine bodies)
2388
  and will initialize the destination with the default
2389
  database of the stored routine, rather than the default
2390
  database of the connection it is parsed in.
2391
  E.g. if one has no current database selected, or current database 
2392
  set to 'bar' and then issues:
2393
2394
  CREATE PROCEDURE foo.p1() BEGIN SELECT * FROM t1 END//
2395
2396
  t1 is meant to refer to foo.t1, not to bar.t1.
2397
2398
  This method is needed to support this rule.
2399
2400
  @return TRUE in case of error (parsing should be aborted, FALSE in
2401
  case of success
2402
*/
2403
2404
bool
2405
st_lex::copy_db_to(char **p_db, size_t *p_db_length) const
2406
{
2407
  return thd->copy_db_to(p_db, p_db_length);
2408
}
2409
2410
/*
2411
  initialize limit counters
2412
2413
  SYNOPSIS
2414
    st_select_lex_unit::set_limit()
2415
    values	- SELECT_LEX with initial values for counters
2416
*/
2417
2418
void st_select_lex_unit::set_limit(st_select_lex *sl)
2419
{
2420
  ha_rows select_limit_val;
2421
  ulonglong val;
2422
2423
  val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
2424
  select_limit_val= (ha_rows)val;
2425
#ifndef BIG_TABLES
2426
  /* 
2427
    Check for overflow : ha_rows can be smaller then ulonglong if
2428
    BIG_TABLES is off.
2429
    */
2430
  if (val != (ulonglong)select_limit_val)
2431
    select_limit_val= HA_POS_ERROR;
2432
#endif
2433
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
80.1.1 by Brian Aker
LL() cleanup
2434
                                                 0ULL);
1 by brian
clean slate
2435
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2436
  if (select_limit_cnt < select_limit_val)
2437
    select_limit_cnt= HA_POS_ERROR;		// no limit
2438
}
2439
2440
2441
/*
2442
  Unlink the first table from the global table list and the first table from
2443
  outer select (lex->select_lex) local list
2444
2445
  SYNOPSIS
2446
    unlink_first_table()
2447
    link_to_local	Set to 1 if caller should link this table to local list
2448
2449
  NOTES
2450
    We assume that first tables in both lists is the same table or the local
2451
    list is empty.
2452
2453
  RETURN
2454
    0	If 'query_tables' == 0
2455
    unlinked table
2456
      In this case link_to_local is set.
2457
2458
*/
2459
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
2460
{
2461
  TABLE_LIST *first;
2462
  if ((first= query_tables))
2463
  {
2464
    /*
2465
      Exclude from global table list
2466
    */
2467
    if ((query_tables= query_tables->next_global))
2468
      query_tables->prev_global= &query_tables;
2469
    else
2470
      query_tables_last= &query_tables;
2471
    first->next_global= 0;
2472
2473
    /*
2474
      and from local list if it is not empty
2475
    */
2476
    if ((*link_to_local= test(select_lex.table_list.first)))
2477
    {
2478
      select_lex.context.table_list= 
2479
        select_lex.context.first_name_resolution_table= first->next_local;
2480
      select_lex.table_list.first= (uchar*) (first->next_local);
2481
      select_lex.table_list.elements--;	//safety
2482
      first->next_local= 0;
2483
      /*
2484
        Ensure that the global list has the same first table as the local
2485
        list.
2486
      */
2487
      first_lists_tables_same();
2488
    }
2489
  }
2490
  return first;
2491
}
2492
2493
2494
/*
2495
  Bring first local table of first most outer select to first place in global
2496
  table list
2497
2498
  SYNOPSYS
2499
     st_lex::first_lists_tables_same()
2500
2501
  NOTES
2502
    In many cases (for example, usual INSERT/DELETE/...) the first table of
2503
    main SELECT_LEX have special meaning => check that it is the first table
2504
    in global list and re-link to be first in the global list if it is
2505
    necessary.  We need such re-linking only for queries with sub-queries in
2506
    the select list, as only in this case tables of sub-queries will go to
2507
    the global list first.
2508
*/
2509
2510
void st_lex::first_lists_tables_same()
2511
{
2512
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
2513
  if (query_tables != first_table && first_table != 0)
2514
  {
2515
    TABLE_LIST *next;
2516
    if (query_tables_last == &first_table->next_global)
2517
      query_tables_last= first_table->prev_global;
2518
2519
    if ((next= *first_table->prev_global= first_table->next_global))
2520
      next->prev_global= first_table->prev_global;
2521
    /* include in new place */
2522
    first_table->next_global= query_tables;
2523
    /*
2524
       We are sure that query_tables is not 0, because first_table was not
2525
       first table in the global list => we can use
2526
       query_tables->prev_global without check of query_tables
2527
    */
2528
    query_tables->prev_global= &first_table->next_global;
2529
    first_table->prev_global= &query_tables;
2530
    query_tables= first_table;
2531
  }
2532
}
2533
2534
2535
/*
2536
  Link table back that was unlinked with unlink_first_table()
2537
2538
  SYNOPSIS
2539
    link_first_table_back()
2540
    link_to_local	do we need link this table to local
2541
2542
  RETURN
2543
    global list
2544
*/
2545
2546
void st_lex::link_first_table_back(TABLE_LIST *first,
2547
				   bool link_to_local)
2548
{
2549
  if (first)
2550
  {
2551
    if ((first->next_global= query_tables))
2552
      query_tables->prev_global= &first->next_global;
2553
    else
2554
      query_tables_last= &first->next_global;
2555
    query_tables= first;
2556
2557
    if (link_to_local)
2558
    {
2559
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
2560
      select_lex.context.table_list= first;
2561
      select_lex.table_list.first= (uchar*) first;
2562
      select_lex.table_list.elements++;	//safety
2563
    }
2564
  }
2565
}
2566
2567
2568
2569
/*
2570
  cleanup lex for case when we open table by table for processing
2571
2572
  SYNOPSIS
2573
    st_lex::cleanup_after_one_table_open()
2574
2575
  NOTE
2576
    This method is mostly responsible for cleaning up of selects lists and
2577
    derived tables state. To rollback changes in Query_tables_list one has
2578
    to call Query_tables_list::reset_query_tables_list(FALSE).
2579
*/
2580
2581
void st_lex::cleanup_after_one_table_open()
2582
{
2583
  /*
2584
    thd->lex->derived_tables & additional units may be set if we open
2585
    a view. It is necessary to clear thd->lex->derived_tables flag
2586
    to prevent processing of derived tables during next open_and_lock_tables
2587
    if next table is a real table and cleanup & remove underlying units
2588
    NOTE: all units will be connected to thd->lex->select_lex, because we
2589
    have not UNION on most upper level.
2590
    */
2591
  if (all_selects_list != &select_lex)
2592
  {
2593
    derived_tables= 0;
2594
    /* cleunup underlying units (units of VIEW) */
2595
    for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
2596
         un;
2597
         un= un->next_unit())
2598
      un->cleanup();
2599
    /* reduce all selects list to default state */
2600
    all_selects_list= &select_lex;
2601
    /* remove underlying units (units of VIEW) subtree */
2602
    select_lex.cut_subtree();
2603
  }
2604
}
2605
2606
2607
/*
2608
  Save current state of Query_tables_list for this LEX, and prepare it
2609
  for processing of new statemnt.
2610
2611
  SYNOPSIS
2612
    reset_n_backup_query_tables_list()
2613
      backup  Pointer to Query_tables_list instance to be used for backup
2614
*/
2615
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2616
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
1 by brian
clean slate
2617
{
2618
}
2619
2620
2621
/*
2622
  Restore state of Query_tables_list for this LEX from backup.
2623
2624
  SYNOPSIS
2625
    restore_backup_query_tables_list()
2626
      backup  Pointer to Query_tables_list instance used for backup
2627
*/
2628
77.1.15 by Monty Taylor
Bunch of warning cleanups.
2629
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
1 by brian
clean slate
2630
{
2631
}
2632
2633
2634
/*
2635
  Checks for usage of routines and/or tables in a parsed statement
2636
2637
  SYNOPSIS
2638
    st_lex:table_or_sp_used()
2639
2640
  RETURN
2641
    FALSE  No routines and tables used
2642
    TRUE   Either or both routines and tables are used.
2643
*/
2644
2645
bool st_lex::table_or_sp_used()
2646
{
2647
  DBUG_ENTER("table_or_sp_used");
2648
2649
  if (sroutines.records || query_tables)
2650
    DBUG_RETURN(TRUE);
2651
2652
  DBUG_RETURN(FALSE);
2653
}
2654
2655
2656
/*
2657
  Do end-of-prepare fixup for list of tables and their merge-VIEWed tables
2658
2659
  SYNOPSIS
2660
    fix_prepare_info_in_table_list()
2661
      thd  Thread handle
2662
      tbl  List of tables to process
2663
2664
  DESCRIPTION
2665
    Perform end-end-of prepare fixup for list of tables, if any of the tables
2666
    is a merge-algorithm VIEW, recursively fix up its underlying tables as
2667
    well.
2668
2669
*/
2670
2671
static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
2672
{
2673
  for (; tbl; tbl= tbl->next_local)
2674
  {
2675
    if (tbl->on_expr)
2676
    {
2677
      tbl->prep_on_expr= tbl->on_expr;
2678
      tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
2679
    }
2680
    fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
2681
  }
2682
}
2683
2684
2685
/*
2686
  Save WHERE/HAVING/ON clauses and replace them with disposable copies
2687
2688
  SYNOPSIS
2689
    st_select_lex::fix_prepare_information
2690
      thd          thread handler
2691
      conds        in/out pointer to WHERE condition to be met at execution
2692
      having_conds in/out pointer to HAVING condition to be met at execution
2693
  
2694
  DESCRIPTION
2695
    The passed WHERE and HAVING are to be saved for the future executions.
2696
    This function saves it, and returns a copy which can be thrashed during
2697
    this execution of the statement. By saving/thrashing here we mean only
2698
    AND/OR trees.
2699
    The function also calls fix_prepare_info_in_table_list that saves all
2700
    ON expressions.    
2701
*/
2702
2703
void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
2704
                                            Item **having_conds)
2705
{
2706
  if (thd->stmt_arena->is_conventional() == false && first_execution)
2707
  {
2708
    first_execution= 0;
2709
    if (*conds)
2710
    {
2711
      prep_where= *conds;
2712
      *conds= where= prep_where->copy_andor_structure(thd);
2713
    }
2714
    if (*having_conds)
2715
    {
2716
      prep_having= *having_conds;
2717
      *having_conds= having= prep_having->copy_andor_structure(thd);
2718
    }
2719
    fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
2720
  }
2721
}
2722
2723
2724
/*
2725
  There are st_select_lex::add_table_to_list &
2726
  st_select_lex::set_lock_for_tables are in sql_parse.cc
2727
2728
  st_select_lex::print is in sql_select.cc
2729
2730
  st_select_lex_unit::prepare, st_select_lex_unit::exec,
2731
  st_select_lex_unit::cleanup, st_select_lex_unit::reinit_exec_mechanism,
2732
  st_select_lex_unit::change_result
2733
  are in sql_union.cc
2734
*/
2735
2736
/*
2737
  Sets the kind of hints to be added by the calls to add_index_hint().
2738
2739
  SYNOPSIS
2740
    set_index_hint_type()
2741
      type_arg     The kind of hints to be added from now on.
2742
      clause       The clause to use for hints to be added from now on.
2743
2744
  DESCRIPTION
2745
    Used in filling up the tagged hints list.
2746
    This list is filled by first setting the kind of the hint as a 
2747
    context variable and then adding hints of the current kind.
2748
    Then the context variable index_hint_type can be reset to the
2749
    next hint type.
2750
*/
2751
void st_select_lex::set_index_hint_type(enum index_hint_type type_arg,
2752
                                        index_clause_map clause)
2753
{ 
2754
  current_index_hint_type= type_arg;
2755
  current_index_hint_clause= clause;
2756
}
2757
2758
2759
/*
2760
  Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
2761
2762
  SYNOPSIS
2763
    alloc_index_hints()
2764
      thd         current thread.
2765
*/
2766
2767
void st_select_lex::alloc_index_hints (THD *thd)
2768
{ 
2769
  index_hints= new (thd->mem_root) List<Index_hint>(); 
2770
}
2771
2772
2773
2774
/*
2775
  adds an element to the array storing index usage hints 
2776
  (ADD/FORCE/IGNORE INDEX).
2777
2778
  SYNOPSIS
2779
    add_index_hint()
2780
      thd         current thread.
2781
      str         name of the index.
2782
      length      number of characters in str.
2783
2784
  RETURN VALUE
2785
    0 on success, non-zero otherwise
2786
*/
2787
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
2788
{
2789
  return index_hints->push_front (new (thd->mem_root) 
2790
                                 Index_hint(current_index_hint_type,
2791
                                            current_index_hint_clause,
2792
                                            str, length));
2793
}