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