~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_lex.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 19:23:04 UTC
  • mfrom: (1089.1.14 merge)
  • Revision ID: brian@gaz-20090711192304-ootijyl5yf9jq9kd
Merge Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
/* A lexical scanner on a temporary buffer with a yacc interface */
18
18
 
19
19
#define DRIZZLE_LEX 1
20
 
#include <drizzled/server_includes.h>
21
 
 
22
 
static int lex_one_token(void *arg, void *yythd);
 
20
#include "drizzled/server_includes.h"
 
21
#include "drizzled/item/num.h"
 
22
#include "drizzled/error.h"
 
23
#include "drizzled/session.h"
 
24
#include "drizzled/sql_base.h"
 
25
#include "drizzled/lookup_symbol.h"
 
26
#include "drizzled/index_hint.h"
 
27
 
 
28
#include <ctype.h>
 
29
 
 
30
using namespace std;
 
31
 
 
32
static int lex_one_token(void *arg, void *yysession);
 
33
int DRIZZLElex(void *arg, void *yysession);
23
34
 
24
35
/*
25
36
  We are using pointer to this variable for distinguishing between assignment
26
37
  to NEW row field (when parsing trigger definition) and structured variable.
27
38
*/
28
 
 
29
39
sys_var *trg_new_row_fake_var= (sys_var*) 0x01;
30
40
 
31
41
/**
33
43
*/
34
44
const LEX_STRING null_lex_str= {NULL, 0};
35
45
 
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
 
 
95
 
  return;
96
 
}
97
 
 
98
 
 
99
 
void lex_free(void)
100
 
{                                       // Call this when daemon ends
101
 
  return;
102
 
}
103
 
 
104
 
 
105
 
void
106
 
st_parsing_options::reset()
107
 
{
108
 
  allows_variable= true;
109
 
  allows_select_into= true;
110
 
  allows_select_procedure= true;
111
 
  allows_derived= true;
112
 
}
113
 
 
114
 
Lex_input_stream::Lex_input_stream(THD *thd,
 
46
Lex_input_stream::Lex_input_stream(Session *session,
115
47
                                   const char* buffer,
116
48
                                   unsigned int length)
117
 
: m_thd(thd),
 
49
: m_session(session),
118
50
  yylineno(1),
119
51
  yytoklen(0),
120
52
  yylval(NULL),
136
68
  next_state(MY_LEX_START),
137
69
  found_semicolon(NULL),
138
70
  ignore_space(1),
139
 
  in_comment(NO_COMMENT),
140
 
  m_underscore_cs(NULL)
 
71
  in_comment(NO_COMMENT)
141
72
{
142
 
  m_cpp_buf= (char*) thd->alloc(length + 1);
 
73
  m_cpp_buf= (char*) session->alloc(length + 1);
143
74
  m_cpp_ptr= m_cpp_buf;
144
75
}
145
76
 
153
84
     statement;
154
85
  2) Determine the beginning of the body.
155
86
 
156
 
  @param thd        Thread context.
 
87
  @param session        Thread context.
157
88
  @param begin_ptr  Pointer to the start of the body in the pre-processed
158
89
                    buffer.
159
90
*/
160
 
 
161
 
void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
 
91
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
162
92
{
163
93
  assert(begin_ptr);
164
94
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
165
95
 
166
 
  uint body_utf8_length=
167
 
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
 
96
  uint32_t body_utf8_length=
 
97
    (m_buf_length / default_charset_info->mbminlen) *
168
98
    my_charset_utf8_bin.mbmaxlen;
169
99
 
170
 
  m_body_utf8= (char *) thd->alloc(body_utf8_length + 1);
 
100
  m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
171
101
  m_body_utf8_ptr= m_body_utf8;
172
102
  *m_body_utf8_ptr= 0;
173
103
 
194
124
                  m_cpp_utf8_processed_ptr will be set in the end of the
195
125
                  operation.
196
126
*/
197
 
 
198
127
void Lex_input_stream::body_utf8_append(const char *ptr,
199
128
                                        const char *end_ptr)
200
129
{
223
152
  @param ptr  Pointer in the pre-processed buffer, which specifies the end
224
153
              of the chunk, which should be appended to the utf8 body.
225
154
*/
226
 
 
227
155
void Lex_input_stream::body_utf8_append(const char *ptr)
228
156
{
229
157
  body_utf8_append(ptr, ptr);
233
161
  The operation converts the specified text literal to the utf8 and appends
234
162
  the result to the utf8-body.
235
163
 
236
 
  @param thd      Thread context.
 
164
  @param session      Thread context.
237
165
  @param txt      Text literal.
238
166
  @param txt_cs   Character set of the text literal.
239
167
  @param end_ptr  Pointer in the pre-processed buffer, to which
240
168
                  m_cpp_utf8_processed_ptr will be set in the end of the
241
169
                  operation.
242
170
*/
243
 
 
244
 
void Lex_input_stream::body_utf8_append_literal(THD *thd,
245
 
                                                const LEX_STRING *txt,
246
 
                                                const CHARSET_INFO * const txt_cs,
 
171
void Lex_input_stream::body_utf8_append_literal(const LEX_STRING *txt,
247
172
                                                const char *end_ptr)
248
173
{
249
174
  if (!m_cpp_utf8_processed_ptr)
250
175
    return;
251
176
 
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
177
  /* NOTE: utf_txt.length is in bytes, not in symbols. */
268
178
 
269
 
  memcpy(m_body_utf8_ptr, utf_txt.str, utf_txt.length);
270
 
  m_body_utf8_ptr += utf_txt.length;
 
179
  memcpy(m_body_utf8_ptr, txt->str, txt->length);
 
180
  m_body_utf8_ptr += txt->length;
271
181
  *m_body_utf8_ptr= 0;
272
182
 
273
183
  m_cpp_utf8_processed_ptr= end_ptr;
274
184
}
275
185
 
276
 
 
277
186
/*
278
187
  This is called before every query that is to be parsed.
279
188
  Because of this, it's critical to not do too much things here.
280
189
  (We already do too much here)
281
190
*/
282
 
 
283
 
void lex_start(THD *thd)
 
191
void lex_start(Session *session)
284
192
{
285
 
  LEX *lex= thd->lex;
 
193
  LEX *lex= session->lex;
286
194
 
287
 
  lex->thd= lex->unit.thd= thd;
 
195
  lex->session= lex->unit.session= session;
288
196
 
289
197
  lex->context_stack.empty();
290
198
  lex->unit.init_query();
304
212
  lex->select_lex.master= &lex->unit;
305
213
  lex->select_lex.prev= &lex->unit.slave;
306
214
  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);
 
215
  lex->select_lex.link_prev= (Select_Lex_Node**)&(lex->all_selects_list);
308
216
  lex->select_lex.options= 0;
309
217
  lex->select_lex.init_order();
310
218
  lex->select_lex.group_list.empty();
311
219
  lex->describe= 0;
312
 
  lex->subqueries= false;
313
220
  lex->derived_tables= 0;
314
221
  lex->lock_option= TL_READ;
315
222
  lex->leaf_tables_insert= 0;
316
 
  lex->parsing_options.reset();
317
 
  lex->empty_field_list_on_rset= 0;
318
223
  lex->select_lex.select_number= 1;
319
224
  lex->length=0;
320
225
  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
226
  lex->select_lex.group_list.empty();
324
227
  lex->select_lex.order_list.empty();
325
228
  lex->sql_command= SQLCOM_END;
326
229
  lex->duplicates= DUP_ERROR;
327
230
  lex->ignore= 0;
328
 
  lex->proc_list.first= 0;
329
231
  lex->escape_used= false;
330
232
  lex->query_tables= 0;
331
233
  lex->reset_query_tables_list(false);
337
239
  lex->nest_level=0 ;
338
240
  lex->allow_sum_func= 0;
339
241
  lex->in_sum_func= NULL;
340
 
  /*
341
 
    ok, there must be a better solution for this, long-term
342
 
    I tried "memset" in the sql_yacc.yy code, but that for
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
242
 
355
243
  lex->is_lex_started= true;
356
 
  return;
 
244
  lex->create_table_proto= NULL;
357
245
}
358
246
 
359
247
void lex_end(LEX *lex)
360
248
{
361
249
  if (lex->yacc_yyss)
362
250
  {
363
 
    my_free(lex->yacc_yyss, MYF(0));
364
 
    my_free(lex->yacc_yyvs, MYF(0));
 
251
    free(lex->yacc_yyss);
 
252
    free(lex->yacc_yyvs);
365
253
    lex->yacc_yyss= 0;
366
254
    lex->yacc_yyvs= 0;
367
255
  }
368
256
 
369
 
  /* release used plugins */
370
 
  plugin_unlock_list(0, (plugin_ref*)lex->plugins.buffer, 
371
 
                     lex->plugins.elements);
372
 
  reset_dynamic(&lex->plugins);
 
257
  delete lex->result;
373
258
 
374
 
  return;
 
259
  if(lex->create_table_proto)
 
260
    delete lex->create_table_proto;
 
261
  lex->result= 0;
375
262
}
376
263
 
377
 
 
378
 
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
 
264
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
379
265
{
 
266
  /* Plenty of memory for the largest lex symbol we have */
 
267
  char tok_upper[64];
380
268
  const char *tok= lip->get_tok_start();
 
269
  uint32_t tok_pos= 0;
 
270
  for (;tok_pos<len && tok_pos<63;tok_pos++)
 
271
    tok_upper[tok_pos]=my_toupper(system_charset_info, tok[tok_pos]);
 
272
  tok_upper[tok_pos]=0;
381
273
 
382
 
  SYMBOL *symbol= get_hash_symbol(tok, len, function);
 
274
  const SYMBOL *symbol= lookup_symbol(tok_upper, len, function);
383
275
  if (symbol)
384
276
  {
385
277
    lip->yylval->symbol.symbol=symbol;
388
280
 
389
281
    return symbol->tok;
390
282
  }
 
283
 
391
284
  return 0;
392
285
}
393
286
 
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
 
{
409
 
  assert(len != 0);
410
 
  return get_hash_symbol(name,len,0)!=0;
411
 
}
412
 
 
413
287
bool is_lex_native_function(const LEX_STRING *name)
414
288
{
415
289
  assert(name != NULL);
416
 
  return (get_hash_symbol(name->str, name->length, 1) != 0);
 
290
  return (lookup_symbol(name->str, name->length, 1) != 0);
417
291
}
418
292
 
419
293
/* 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)
 
294
static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
422
295
{
423
296
  LEX_STRING tmp;
424
297
  lip->yyUnget();                       // ptr points now after last token char
425
298
  tmp.length=lip->yytoklen=length;
426
 
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
 
299
  tmp.str= lip->m_session->strmake(lip->get_tok_start() + skip, tmp.length);
427
300
 
428
301
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
429
302
  lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;
431
304
  return tmp;
432
305
}
433
306
 
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 
 
307
/*
 
308
 todo:
 
309
   There are no dangerous charsets in mysql for function
 
310
   get_quoted_token yet. But it should be fixed in the
438
311
   future to operate multichar strings (like ucs2)
439
312
*/
440
 
 
441
313
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
442
 
                                   uint skip,
443
 
                                   uint length, char quote)
 
314
                                   uint32_t skip,
 
315
                                   uint32_t length, char quote)
444
316
{
445
317
  LEX_STRING tmp;
446
318
  const char *from, *end;
447
319
  char *to;
448
320
  lip->yyUnget();                       // ptr points now after last token char
449
321
  tmp.length= lip->yytoklen=length;
450
 
  tmp.str=(char*) lip->m_thd->alloc(tmp.length+1);
 
322
  tmp.str=(char*) lip->m_session->alloc(tmp.length+1);
451
323
  from= lip->get_tok_start() + skip;
452
324
  to= tmp.str;
453
325
  end= to+length;
472
344
  Return an unescaped text literal without quotes
473
345
  Fix sometimes to do only one scan of the string
474
346
*/
475
 
 
476
347
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
477
348
{
478
 
  register uchar c,sep;
479
 
  uint found_escape=0;
480
 
  const CHARSET_INFO * const cs= lip->m_thd->charset();
 
349
  register unsigned char c,sep;
 
350
  bool found_escape= false;
 
351
  const CHARSET_INFO * const cs= lip->m_session->charset();
481
352
 
482
353
  lip->tok_bitmap= 0;
483
354
  sep= lip->yyGetLast();                        // String should end with this
487
358
    lip->tok_bitmap|= c;
488
359
#ifdef USE_MB
489
360
    {
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;
 
361
      if (use_mb(cs))
 
362
      {
 
363
        int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
364
        if (l != 0) 
 
365
        {
 
366
          lip->skip_binary(l-1);
 
367
          continue;
 
368
        }
497
369
      }
498
370
    }
499
371
#endif
500
372
    if (c == '\\')
501
373
    {                                   // Escaped character
502
 
      found_escape=1;
 
374
      found_escape= true;
503
375
      if (lip->eof())
504
 
        return 0;
 
376
        return 0;
505
377
      lip->yySkip();
506
378
    }
507
379
    else if (c == sep)
508
380
    {
509
381
      if (c == lip->yyGet())            // Check if two separators in a row
510
382
      {
511
 
        found_escape=1;                 // duplicate. Remember for delete
512
 
        continue;
 
383
        found_escape= true;                 // duplicate. Remember for delete
 
384
        continue;
513
385
      }
514
386
      else
515
387
        lip->yyUnget();
521
393
      str= lip->get_tok_start();
522
394
      end= lip->get_ptr();
523
395
      /* Extract the text from the token */
524
 
      str += pre_skip;
525
 
      end -= post_skip;
 
396
      str+= pre_skip;
 
397
      end-= post_skip;
526
398
      assert(end >= str);
527
399
 
528
 
      if (!(start= (char*) lip->m_thd->alloc((uint) (end-str)+1)))
529
 
        return (char*) "";              // Sql_alloc has set error flag
 
400
      if (!(start= (char*) lip->m_session->alloc((uint32_t) (end-str)+1)))
 
401
        return (char*) "";              // Sql_alloc has set error flag
530
402
 
531
403
      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
532
404
      lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;
533
405
 
534
 
      if (!found_escape)
 
406
      if (! found_escape)
535
407
      {
536
 
        lip->yytoklen=(uint) (end-str);
537
 
        memcpy(start,str,lip->yytoklen);
538
 
        start[lip->yytoklen]=0;
 
408
        lip->yytoklen= (uint32_t) (end-str);
 
409
        memcpy(start, str, lip->yytoklen);
 
410
        start[lip->yytoklen]= 0;
539
411
      }
540
412
      else
541
413
      {
542
414
        char *to;
543
415
 
544
 
        for (to=start ; str != end ; str++)
545
 
        {
 
416
        for (to= start; str != end; str++)
 
417
        {
546
418
#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
 
          }
 
419
          if (use_mb(cs))
 
420
          {
 
421
            int l= my_ismbchar(cs, str, end);
 
422
            if (l != 0)
 
423
            {
 
424
              while (l--)
 
425
                *to++= *str++;
 
426
              str--;
 
427
              continue;
 
428
            }
 
429
          }
555
430
#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:
 
431
          if (*str == '\\' && (str + 1) != end)
 
432
          {
 
433
            switch (*++str) {
 
434
            case 'n':
 
435
              *to++= '\n';
 
436
              break;
 
437
            case 't':
 
438
              *to++= '\t';
 
439
              break;
 
440
            case 'r':
 
441
              *to++= '\r';
 
442
              break;
 
443
            case 'b':
 
444
              *to++= '\b';
 
445
              break;
 
446
            case '0':
 
447
              *to++= 0;                 // Ascii null
 
448
              break;
 
449
            case 'Z':                   // ^Z must be escaped on Win32
 
450
              *to++= '\032';
 
451
              break;
 
452
            case '_':
 
453
            case '%':
 
454
              *to++= '\\';              // remember prefix for wildcard
 
455
              /* Fall through */
 
456
            default:
583
457
              *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);
 
458
              break;
 
459
            }
 
460
          }
 
461
          else if (*str == sep)
 
462
            *to++= *str++;              // Two ' or "
 
463
          else
 
464
            *to++ = *str;
 
465
        }
 
466
        *to= 0;
 
467
        lip->yytoklen= (uint32_t) (to - start);
594
468
      }
595
469
      return start;
596
470
    }
602
476
/*
603
477
** Calc type of integer; long integer, int64_t integer or real.
604
478
** Returns smallest type that match the string.
605
 
** When using unsigned long long values the result is converted to a real
 
479
** When using uint64_t values the result is converted to a real
606
480
** because else they will be unexpected sign changes because all calculation
607
481
** is done with int64_t or double.
608
482
*/
609
483
 
610
 
static const char *long_str="2147483647";
611
 
static const uint long_len=10;
612
 
static const char *signed_long_str="-2147483648";
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;
 
484
static const char *long_str= "2147483647";
 
485
static const uint32_t long_len= 10;
 
486
static const char *signed_long_str= "-2147483648";
 
487
static const char *int64_t_str= "9223372036854775807";
 
488
static const uint32_t int64_t_len= 19;
 
489
static const char *signed_int64_t_str= "-9223372036854775808";
 
490
static const uint32_t signed_int64_t_len= 19;
 
491
static const char *unsigned_int64_t_str= "18446744073709551615";
 
492
static const uint32_t unsigned_int64_t_len= 20;
619
493
 
620
 
static inline uint int_token(const char *str,uint length)
 
494
static inline uint32_t int_token(const char *str,uint32_t length)
621
495
{
622
496
  if (length < long_len)                        // quick normal case
623
497
    return NUM;
639
513
  if (length < long_len)
640
514
    return NUM;
641
515
 
642
 
  uint smaller,bigger;
 
516
  uint32_t smaller,bigger;
643
517
  const char *cmp;
644
518
  if (neg)
645
519
  {
686
560
    }
687
561
  }
688
562
  while (*cmp && *cmp++ == *str++) ;
689
 
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
 
563
  return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
690
564
}
691
565
 
692
 
 
693
566
/*
694
 
  MYSQLlex remember the following states from the following MYSQLlex()
 
567
  DRIZZLElex remember the following states from the following DRIZZLElex()
695
568
 
696
569
  - MY_LEX_EOQ                  Found end of query
697
570
  - MY_LEX_OPERATOR_OR_IDENT    Last state was an ident, text or number
698
571
                                (which can't be followed by a signed number)
699
572
*/
700
 
 
701
 
int MYSQLlex(void *arg, void *yythd)
 
573
int DRIZZLElex(void *arg, void *yysession)
702
574
{
703
 
  THD *thd= (THD *)yythd;
704
 
  Lex_input_stream *lip= thd->m_lip;
 
575
  Session *session= (Session *)yysession;
 
576
  Lex_input_stream *lip= session->m_lip;
705
577
  YYSTYPE *yylval=(YYSTYPE*) arg;
706
578
  int token;
707
579
 
718
590
    return token;
719
591
  }
720
592
 
721
 
  token= lex_one_token(arg, yythd);
 
593
  token= lex_one_token(arg, yysession);
722
594
 
723
595
  switch(token) {
724
596
  case WITH:
725
597
    /*
726
 
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
 
598
      Parsing 'WITH' 'ROLLUP' requires 2 look ups,
727
599
      which makes the grammar LALR(2).
728
600
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
729
601
      to transform the grammar into a LALR(1) grammar,
730
602
      which sql_yacc.yy can process.
731
603
    */
732
 
    token= lex_one_token(arg, yythd);
733
 
    switch(token) {
734
 
    case CUBE_SYM:
735
 
      return WITH_CUBE_SYM;
736
 
    case ROLLUP_SYM:
 
604
    token= lex_one_token(arg, yysession);
 
605
    if (token == ROLLUP_SYM)
 
606
    {
737
607
      return WITH_ROLLUP_SYM;
738
 
    default:
 
608
    }
 
609
    else
 
610
    {
739
611
      /*
740
612
        Save the token following 'WITH'
741
613
      */
744
616
      lip->lookahead_token= token;
745
617
      return WITH;
746
618
    }
747
 
    break;
748
619
  default:
749
620
    break;
750
621
  }
752
623
  return token;
753
624
}
754
625
 
755
 
int lex_one_token(void *arg, void *yythd)
 
626
int lex_one_token(void *arg, void *yysession)
756
627
{
757
628
  register unsigned char c= 0; /* Just set to shutup GCC */
758
629
  bool comment_closed;
759
630
  int   tokval, result_state;
760
631
  unsigned int length;
761
632
  enum my_lex_states state;
762
 
  THD *thd= (THD *)yythd;
763
 
  Lex_input_stream *lip= thd->m_lip;
764
 
  LEX *lex= thd->lex;
 
633
  Session *session= (Session *)yysession;
 
634
  Lex_input_stream *lip= session->m_lip;
 
635
  LEX *lex= session->lex;
765
636
  YYSTYPE *yylval=(YYSTYPE*) arg;
766
 
  const CHARSET_INFO * const cs= thd->charset();
767
 
  uchar *state_map= cs->state_map;
768
 
  uchar *ident_map= cs->ident_map;
 
637
  const CHARSET_INFO * const cs= session->charset();
 
638
  unsigned char *state_map= cs->state_map;
 
639
  unsigned char *ident_map= cs->ident_map;
769
640
 
770
641
  lip->yylval=yylval;                   // The global state
771
642
 
780
651
      // Skip starting whitespace
781
652
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
782
653
      {
783
 
        if (c == '\n')
784
 
          lip->yylineno++;
 
654
        if (c == '\n')
 
655
          lip->yylineno++;
785
656
 
786
657
        lip->yySkip();
787
658
      }
794
665
    case MY_LEX_ESCAPE:
795
666
      if (lip->yyGet() == 'N')
796
667
      {                                 // Allow \N as shortcut for NULL
797
 
        yylval->lex_str.str=(char*) "\\N";
798
 
        yylval->lex_str.length=2;
799
 
        return NULL_SYM;
 
668
        yylval->lex_str.str=(char*) "\\N";
 
669
        yylval->lex_str.length=2;
 
670
        return NULL_SYM;
800
671
      }
801
672
    case MY_LEX_CHAR:                   // Unknown or single char token
802
673
    case MY_LEX_SKIP:                   // This should not happen
809
680
      }
810
681
 
811
682
      if (c != ')')
812
 
        lip->next_state= MY_LEX_START;  // Allow signed numbers
 
683
        lip->next_state= MY_LEX_START;  // Allow signed numbers
813
684
 
814
685
      if (c == ',')
815
686
      {
830
701
    case MY_LEX_IDENT_OR_HEX:
831
702
      if (lip->yyPeek() == '\'')
832
703
      {                                 // Found x'hex-number'
833
 
        state= MY_LEX_HEX_NUMBER;
834
 
        break;
 
704
        state= MY_LEX_HEX_NUMBER;
 
705
        break;
835
706
      }
836
707
    case MY_LEX_IDENT_OR_BIN:
837
708
      if (lip->yyPeek() == '\'')
844
715
#if defined(USE_MB) && defined(USE_MB_IDENT)
845
716
      if (use_mb(cs))
846
717
      {
847
 
        result_state= IDENT_QUOTED;
 
718
        result_state= IDENT_QUOTED;
848
719
        if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
849
720
        {
850
721
          int l = my_ismbchar(cs,
860
731
        {
861
732
          if (my_mbcharlen(cs, c) > 1)
862
733
          {
863
 
            int l;
864
 
            if ((l = my_ismbchar(cs,
865
 
                                 lip->get_ptr() -1,
866
 
                                 lip->get_end_of_query())) == 0)
 
734
            int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
735
            if (l == 0)
867
736
              break;
868
737
            lip->skip_binary(l-1);
869
738
          }
887
756
        for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
888
757
      }
889
758
      if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
890
 
        lip->next_state=MY_LEX_IDENT_SEP;
 
759
              lip->next_state=MY_LEX_IDENT_SEP;
891
760
      else
892
761
      {                                 // '(' must follow directly if function
893
762
        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
 
        }
 
763
        if ((tokval = find_keyword(lip, length, c == '(')))
 
764
        {
 
765
          lip->next_state= MY_LEX_START;        // Allow signed numbers
 
766
          return(tokval);               // Was keyword
 
767
        }
899
768
        lip->yySkip();                  // next state does a unget
900
769
      }
901
770
      yylval->lex_str=get_token(lip, 0, length);
902
771
 
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
 
      {
912
 
        const CHARSET_INFO * const cs= get_charset_by_csname(yylval->lex_str.str + 1,
913
 
                                                             MY_CS_PRIMARY, MYF(0));
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
772
      lip->body_utf8_append(lip->m_cpp_text_start);
926
773
 
927
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
928
 
                                    lip->m_cpp_text_end);
 
774
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
929
775
 
930
776
      return(result_state);                     // IDENT or IDENT_QUOTED
931
777
 
935
781
      c= lip->yyGet();                  // should be '.'
936
782
      lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
937
783
      if (!ident_map[(uint8_t)lip->yyPeek()])            // Probably ` or "
938
 
        lip->next_state= MY_LEX_START;
 
784
        lip->next_state= MY_LEX_START;
939
785
      return((int) c);
940
786
 
941
787
    case MY_LEX_NUMBER_IDENT:           // number or ident which num-start
974
820
      while (my_isdigit(cs, (c = lip->yyGet()))) ;
975
821
      if (!ident_map[c])
976
822
      {                                 // Can't be identifier
977
 
        state=MY_LEX_INT_OR_REAL;
978
 
        break;
 
823
        state=MY_LEX_INT_OR_REAL;
 
824
        break;
979
825
      }
980
826
      if (c == 'e' || c == 'E')
981
827
      {
982
 
        // The following test is written this way to allow numbers of type 1e1
 
828
        // The following test is written this way to allow numbers of type 1e1
983
829
        if (my_isdigit(cs,lip->yyPeek()) ||
984
830
            (c=(lip->yyGet())) == '+' || c == '-')
985
 
        {                               // Allow 1E+10
 
831
        {                               // Allow 1E+10
986
832
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
987
 
          {
 
833
          {
988
834
            lip->yySkip();
989
835
            while (my_isdigit(cs,lip->yyGet())) ;
990
836
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
991
 
            return(FLOAT_NUM);
992
 
          }
993
 
        }
 
837
            return(FLOAT_NUM);
 
838
          }
 
839
        }
994
840
        lip->yyUnget();
995
841
      }
996
842
      // fall through
999
845
#if defined(USE_MB) && defined(USE_MB_IDENT)
1000
846
      if (use_mb(cs))
1001
847
      {
1002
 
        result_state= IDENT_QUOTED;
 
848
        result_state= IDENT_QUOTED;
1003
849
        while (ident_map[c=lip->yyGet()])
1004
850
        {
1005
851
          if (my_mbcharlen(cs, c) > 1)
1006
852
          {
1007
 
            int l;
1008
 
            if ((l = my_ismbchar(cs,
1009
 
                                 lip->get_ptr() -1,
1010
 
                                 lip->get_end_of_query())) == 0)
 
853
            int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
854
            if (l == 0)
1011
855
              break;
1012
856
            lip->skip_binary(l-1);
1013
857
          }
1021
865
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1022
866
      }
1023
867
      if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
1024
 
        lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
 
868
        lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
1025
869
 
1026
870
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
1027
871
 
1028
872
      lip->body_utf8_append(lip->m_cpp_text_start);
1029
873
 
1030
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
1031
 
                                    lip->m_cpp_text_end);
 
874
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1032
875
 
1033
876
      return(result_state);
1034
877
 
1035
878
    case MY_LEX_USER_VARIABLE_DELIMITER:        // Found quote char
1036
879
    {
1037
 
      uint double_quotes= 0;
 
880
      uint32_t double_quotes= 0;
1038
881
      char quote_char= c;                       // Used char
1039
882
      while ((c=lip->yyGet()))
1040
883
      {
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
 
        }
 
884
        int var_length;
 
885
        if ((var_length= my_mbcharlen(cs, c)) == 1)
 
886
        {
 
887
          if (c == quote_char)
 
888
          {
 
889
                  if (lip->yyPeek() != quote_char)
 
890
              break;
 
891
                  c=lip->yyGet();
 
892
            double_quotes++;
 
893
            continue;
 
894
          }
 
895
        }
1053
896
#ifdef USE_MB
1054
 
        else if (var_length < 1)
1055
 
          break;                                // Error
 
897
        else if (var_length < 1)
 
898
          break;                                // Error
1056
899
        lip->skip_binary(var_length-1);
1057
900
#endif
1058
901
      }
1059
902
      if (double_quotes)
1060
 
        yylval->lex_str=get_quoted_token(lip, 1,
1061
 
                                         lip->yyLength() - double_quotes -1,
1062
 
                                         quote_char);
 
903
              yylval->lex_str=get_quoted_token(lip, 1, lip->yyLength() - double_quotes -1, quote_char);
1063
904
      else
1064
905
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
1065
906
      if (c == quote_char)
1066
907
        lip->yySkip();                  // Skip end `
1067
908
      lip->next_state= MY_LEX_START;
1068
 
 
1069
909
      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
 
 
 
910
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1074
911
      return(IDENT_QUOTED);
1075
912
    }
1076
913
    case MY_LEX_INT_OR_REAL:            // Complete int or incomplete real
1077
914
      if (c != '.')
1078
915
      {                                 // Found complete integer number.
1079
916
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1080
 
        return int_token(yylval->lex_str.str,yylval->lex_str.length);
 
917
        return int_token(yylval->lex_str.str,yylval->lex_str.length);
1081
918
      }
1082
919
      // fall through
1083
920
    case MY_LEX_REAL:                   // Incomplete real number
1086
923
      if (c == 'e' || c == 'E')
1087
924
      {
1088
925
        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
 
        }
 
926
        if (c == '-' || c == '+')
 
927
                c = lip->yyGet();                     // Skip sign
 
928
        if (!my_isdigit(cs,c))
 
929
        {                               // No digit after sign
 
930
          state= MY_LEX_CHAR;
 
931
          break;
 
932
        }
1096
933
        while (my_isdigit(cs,lip->yyGet())) ;
1097
934
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
1098
 
        return(FLOAT_NUM);
 
935
        return(FLOAT_NUM);
1099
936
      }
1100
937
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1101
938
      return(DECIMAL_NUM);
1132
969
        lip->yySkip();
1133
970
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1134
971
      {
1135
 
        lip->next_state= MY_LEX_START;  // Allow signed numbers
1136
 
        return(tokval);
 
972
        lip->next_state= MY_LEX_START;  // Allow signed numbers
 
973
        return(tokval);
1137
974
      }
1138
975
      state = MY_LEX_CHAR;              // Something fishy found
1139
976
      break;
1148
985
      }
1149
986
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1150
987
      {
1151
 
        lip->next_state= MY_LEX_START;  // Found long op
1152
 
        return(tokval);
 
988
        lip->next_state= MY_LEX_START;  // Found long op
 
989
        return(tokval);
1153
990
      }
1154
991
      state = MY_LEX_CHAR;              // Something fishy found
1155
992
      break;
1157
994
    case MY_LEX_BOOL:
1158
995
      if (c != lip->yyPeek())
1159
996
      {
1160
 
        state=MY_LEX_CHAR;
1161
 
        break;
 
997
        state=MY_LEX_CHAR;
 
998
        break;
1162
999
      }
1163
1000
      lip->yySkip();
1164
1001
      tokval = find_keyword(lip,2,0);   // Is a bool operator
1175
1012
    case MY_LEX_STRING:                 // Incomplete text string
1176
1013
      if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
1177
1014
      {
1178
 
        state= MY_LEX_CHAR;             // Read char by char
1179
 
        break;
 
1015
        state= MY_LEX_CHAR;             // Read char by char
 
1016
        break;
1180
1017
      }
1181
1018
      yylval->lex_str.length=lip->yytoklen;
1182
1019
 
1183
1020
      lip->body_utf8_append(lip->m_cpp_text_start);
1184
1021
 
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;
 
1022
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1190
1023
 
1191
1024
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
1192
1025
      return(TEXT_STRING);
1200
1033
    case MY_LEX_LONG_COMMENT:           /* Long C comment? */
1201
1034
      if (lip->yyPeek() != '*')
1202
1035
      {
1203
 
        state=MY_LEX_CHAR;              // Probable division
1204
 
        break;
 
1036
        state=MY_LEX_CHAR;              // Probable division
 
1037
        break;
1205
1038
      }
1206
1039
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
1207
1040
      /* Reject '/' '*', since we might need to turn off the echo */
1218
1051
 
1219
1052
        /*
1220
1053
          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
 
1054
          '/' '*' '!', followed by digits ended by a non-digit.
 
1055
          There must be at least 5 digits for it to count
1226
1056
        */
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);
 
1057
        const int MAX_VERSION_SIZE= 16;
 
1058
        char version_str[MAX_VERSION_SIZE];
 
1059
 
 
1060
        int pos= 0;
 
1061
        do
 
1062
        {
 
1063
          version_str[pos]= lip->yyPeekn(pos);
 
1064
          pos++;
 
1065
        } while ((pos < MAX_VERSION_SIZE-1) && isdigit(version_str[pos-1]));
 
1066
        version_str[pos]= 0;
 
1067
 
 
1068
        /* To keep some semblance of compatibility, we impose a 5 digit floor */
 
1069
        if (pos > 4)
 
1070
        {
 
1071
          uint64_t version;
 
1072
          version=strtoll(version_str, NULL, 10);
1243
1073
 
1244
1074
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1245
 
          lip->yySkipn(5);
 
1075
          lip->yySkipn(pos-1);
1246
1076
 
1247
1077
          if (version <= DRIZZLE_VERSION_ID)
1248
1078
          {
1311
1141
        state=MY_LEX_START;
1312
1142
      }
1313
1143
      else
1314
 
        state=MY_LEX_CHAR;              // Return '*'
 
1144
        state=MY_LEX_CHAR;              // Return '*'
1315
1145
      break;
1316
1146
    case MY_LEX_SET_VAR:                // Check if ':='
1317
1147
      if (lip->yyPeek() != '=')
1318
1148
      {
1319
 
        state=MY_LEX_CHAR;              // Return ':'
1320
 
        break;
 
1149
        state=MY_LEX_CHAR;              // Return ':'
 
1150
        break;
1321
1151
      }
1322
1152
      lip->yySkip();
1323
1153
      return (SET_VAR);
1324
1154
    case MY_LEX_SEMICOLON:                      // optional line terminator
1325
1155
      if (lip->yyPeek())
1326
1156
      {
1327
 
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS))
 
1157
        if ((session->client_capabilities & CLIENT_MULTI_STATEMENTS))
1328
1158
        {
1329
1159
          lip->found_semicolon= lip->get_ptr();
1330
 
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
 
1160
          session->server_status|= SERVER_MORE_RESULTS_EXISTS;
1331
1161
          lip->next_state= MY_LEX_END;
1332
1162
          lip->set_echo(true);
1333
1163
          return (END_OF_INPUT);
1334
1164
        }
1335
1165
        state= MY_LEX_CHAR;             // Return ';'
1336
 
        break;
 
1166
        break;
1337
1167
      }
1338
1168
      lip->next_state=MY_LEX_END;       // Mark for next loop
1339
1169
      return(END_OF_INPUT);
1354
1184
      break;
1355
1185
    case MY_LEX_END:
1356
1186
      lip->next_state=MY_LEX_END;
1357
 
      return(0);                        // We found end of input last time
1358
 
      
 
1187
      return false;                     // We found end of input last time
 
1188
 
1359
1189
      /* Actually real shouldn't start with . but allow them anyhow */
1360
1190
    case MY_LEX_REAL_OR_POINT:
1361
1191
      if (my_isdigit(cs,lip->yyPeek()))
1362
 
        state = MY_LEX_REAL;            // Real
 
1192
        state= MY_LEX_REAL;             // Real
1363
1193
      else
1364
1194
      {
1365
 
        state= MY_LEX_IDENT_SEP;        // return '.'
 
1195
        state= MY_LEX_IDENT_SEP;        // return '.'
1366
1196
        lip->yyUnget();                 // Put back '.'
1367
1197
      }
1368
1198
      break;
1371
1201
      case MY_LEX_STRING:
1372
1202
      case MY_LEX_USER_VARIABLE_DELIMITER:
1373
1203
      case MY_LEX_STRING_OR_DELIMITER:
1374
 
        break;
 
1204
        break;
1375
1205
      case MY_LEX_USER_END:
1376
 
        lip->next_state=MY_LEX_SYSTEM_VAR;
1377
 
        break;
 
1206
        lip->next_state=MY_LEX_SYSTEM_VAR;
 
1207
        break;
1378
1208
      default:
1379
 
        lip->next_state=MY_LEX_HOSTNAME;
1380
 
        break;
 
1209
        lip->next_state=MY_LEX_HOSTNAME;
 
1210
        break;
1381
1211
      }
1382
1212
      yylval->lex_str.str=(char*) lip->get_ptr();
1383
1213
      yylval->lex_str.length=1;
1384
1214
      return((int) '@');
1385
1215
    case MY_LEX_HOSTNAME:               // end '@' of user@hostname
1386
1216
      for (c=lip->yyGet() ;
1387
 
           my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
 
1217
           my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
1388
1218
           c= lip->yyGet()) ;
1389
1219
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1390
1220
      return(LEX_HOSTNAME);
1399
1229
      return((int) '@');
1400
1230
    case MY_LEX_IDENT_OR_KEYWORD:
1401
1231
      /*
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
 
1232
        We come here when we have found two '@' in a row.
 
1233
        We should now be able to handle:
 
1234
        [(global | local | session) .]variable_name
1405
1235
      */
1406
1236
 
1407
1237
      for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
1409
1239
      result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1410
1240
 
1411
1241
      if (c == '.')
1412
 
        lip->next_state=MY_LEX_IDENT_SEP;
 
1242
        lip->next_state=MY_LEX_IDENT_SEP;
1413
1243
      length= lip->yyLength();
1414
1244
      if (length == 0)
1415
1245
        return(ABORT_SYM);              // Names must be nonempty.
1416
1246
      if ((tokval= find_keyword(lip, length,0)))
1417
1247
      {
1418
1248
        lip->yyUnget();                         // Put back 'c'
1419
 
        return(tokval);                         // Was keyword
 
1249
        return(tokval);                         // Was keyword
1420
1250
      }
1421
1251
      yylval->lex_str=get_token(lip, 0, length);
1422
1252
 
1423
1253
      lip->body_utf8_append(lip->m_cpp_text_start);
1424
1254
 
1425
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
1426
 
                                    lip->m_cpp_text_end);
 
1255
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1427
1256
 
1428
1257
      return(result_state);
1429
1258
    }
1430
1259
  }
1431
1260
}
1432
1261
 
1433
 
 
1434
1262
/**
1435
1263
  Construct a copy of this object to be used for mysql_alter_table
1436
1264
  and mysql_create_table.
1440
1268
  statements and stored procedures and is compensated by always
1441
1269
  supplying a copy of Alter_info to these functions.
1442
1270
 
1443
 
  @return You need to use check the error in THD for out
 
1271
  @return You need to use check the error in Session for out
1444
1272
  of memory condition after calling this function.
1445
1273
*/
1446
 
 
1447
1274
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
1448
1275
  :drop_list(rhs.drop_list, mem_root),
1449
1276
  alter_list(rhs.alter_list, mem_root),
1472
1299
  list_copy_and_replace_each_value(create_list, mem_root);
1473
1300
}
1474
1301
 
1475
 
 
1476
1302
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
1477
1303
{
1478
1304
  /*
1480
1306
    This code assumes that there are no multi-bytes characters
1481
1307
    that can be considered white-space.
1482
1308
  */
1483
 
 
1484
1309
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
1485
1310
  {
1486
 
    str->length --;
1487
 
    str->str ++;
 
1311
    str->length--;
 
1312
    str->str++;
1488
1313
  }
1489
1314
 
1490
1315
  /*
1493
1318
  */
1494
1319
  while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
1495
1320
  {
1496
 
    str->length --;
 
1321
    str->length--;
1497
1322
  }
1498
1323
}
1499
1324
 
1500
 
 
1501
1325
/*
1502
 
  st_select_lex structures initialisations
 
1326
  Select_Lex structures initialisations
1503
1327
*/
1504
 
 
1505
 
void st_select_lex_node::init_query()
 
1328
void Select_Lex_Node::init_query()
1506
1329
{
1507
1330
  options= 0;
1508
1331
  linkage= UNSPECIFIED_TYPE;
1510
1333
  uncacheable= 0;
1511
1334
}
1512
1335
 
1513
 
void st_select_lex_node::init_select()
 
1336
void Select_Lex_Node::init_select()
1514
1337
{
1515
1338
}
1516
1339
 
1517
 
void st_select_lex_unit::init_query()
 
1340
void Select_Lex_Unit::init_query()
1518
1341
{
1519
 
  st_select_lex_node::init_query();
 
1342
  Select_Lex_Node::init_query();
1520
1343
  linkage= GLOBAL_OPTIONS_TYPE;
1521
1344
  global_parameters= first_select();
1522
1345
  select_limit_cnt= HA_POS_ERROR;
1533
1356
  found_rows_for_union= 0;
1534
1357
}
1535
1358
 
1536
 
void st_select_lex::init_query()
 
1359
void Select_Lex::init_query()
1537
1360
{
1538
 
  st_select_lex_node::init_query();
 
1361
  Select_Lex_Node::init_query();
1539
1362
  table_list.empty();
1540
1363
  top_join_list.empty();
1541
1364
  join_list= &top_join_list;
1559
1382
  parent_lex->push_context(&context);
1560
1383
  cond_count= between_count= with_wild= 0;
1561
1384
  max_equal_elems= 0;
1562
 
  conds_processed_with_permanent_arena= 0;
1563
1385
  ref_pointer_array= 0;
1564
1386
  select_n_where_fields= 0;
1565
1387
  select_n_having_items= 0;
1566
1388
  subquery_in_having= explicit_limit= 0;
1567
1389
  is_item_list_lookup= 0;
1568
 
  first_execution= 1;
1569
 
  first_cond_optimization= 1;
1570
1390
  parsing_place= NO_MATTER;
1571
1391
  exclude_from_table_unique_test= false;
1572
1392
  nest_level= 0;
1573
1393
  link_next= 0;
1574
1394
}
1575
1395
 
1576
 
void st_select_lex::init_select()
 
1396
void Select_Lex::init_select()
1577
1397
{
1578
 
  st_select_lex_node::init_select();
1579
1398
  sj_nests.empty();
1580
1399
  group_list.empty();
1581
1400
  type= db= 0;
1585
1404
  options= 0;
1586
1405
  braces= 0;
1587
1406
  interval_list.empty();
1588
 
  ftfunc_list_alloc.empty();
1589
1407
  inner_sum_func_list= 0;
1590
 
  ftfunc_list= &ftfunc_list_alloc;
1591
1408
  linkage= UNSPECIFIED_TYPE;
1592
1409
  order_list.elements= 0;
1593
1410
  order_list.first= 0;
1594
 
  order_list.next= (uchar**) &order_list.first;
 
1411
  order_list.next= (unsigned char**) &order_list.first;
1595
1412
  /* Set limit and offset to default values */
1596
1413
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1597
1414
  offset_limit= 0;      /* denotes the default offset = 0 */
1601
1418
  non_agg_fields.empty();
1602
1419
  cond_value= having_value= Item::COND_UNDEF;
1603
1420
  inner_refs_list.empty();
1604
 
  full_group_by_flag= 0;
 
1421
  full_group_by_flag.reset();
1605
1422
}
1606
1423
 
1607
1424
/*
1608
 
  st_select_lex structures linking
 
1425
  Select_Lex structures linking
1609
1426
*/
1610
1427
 
1611
1428
/* include on level down */
1612
 
void st_select_lex_node::include_down(st_select_lex_node *upper)
 
1429
void Select_Lex_Node::include_down(Select_Lex_Node *upper)
1613
1430
{
1614
1431
  if ((next= upper->slave))
1615
1432
    next->prev= &next;
1623
1440
  include on level down (but do not link)
1624
1441
 
1625
1442
  SYNOPSYS
1626
 
    st_select_lex_node::include_standalone()
 
1443
    Select_Lex_Node::include_standalone()
1627
1444
    upper - reference on node underr which this node should be included
1628
1445
    ref - references on reference on this node
1629
1446
*/
1630
 
void st_select_lex_node::include_standalone(st_select_lex_node *upper,
1631
 
                                            st_select_lex_node **ref)
 
1447
void Select_Lex_Node::include_standalone(Select_Lex_Node *upper,
 
1448
                                            Select_Lex_Node **ref)
1632
1449
{
1633
1450
  next= 0;
1634
1451
  prev= ref;
1637
1454
}
1638
1455
 
1639
1456
/* include neighbour (on same level) */
1640
 
void st_select_lex_node::include_neighbour(st_select_lex_node *before)
 
1457
void Select_Lex_Node::include_neighbour(Select_Lex_Node *before)
1641
1458
{
1642
1459
  if ((next= before->next))
1643
1460
    next->prev= &next;
1647
1464
  slave= 0;
1648
1465
}
1649
1466
 
1650
 
/* including in global SELECT_LEX list */
1651
 
void st_select_lex_node::include_global(st_select_lex_node **plink)
 
1467
/* including in global Select_Lex list */
 
1468
void Select_Lex_Node::include_global(Select_Lex_Node **plink)
1652
1469
{
1653
1470
  if ((link_next= *plink))
1654
1471
    link_next->link_prev= &link_next;
1657
1474
}
1658
1475
 
1659
1476
//excluding from global list (internal function)
1660
 
void st_select_lex_node::fast_exclude()
 
1477
void Select_Lex_Node::fast_exclude()
1661
1478
{
1662
1479
  if (link_prev)
1663
1480
  {
1667
1484
  // Remove slave structure
1668
1485
  for (; slave; slave= slave->next)
1669
1486
    slave->fast_exclude();
1670
 
  
 
1487
 
1671
1488
}
1672
1489
 
1673
1490
/*
1674
1491
  excluding select_lex structure (except first (first select can't be
1675
1492
  deleted, because it is most upper select))
1676
1493
*/
1677
 
void st_select_lex_node::exclude()
 
1494
void Select_Lex_Node::exclude()
1678
1495
{
1679
1496
  //exclude from global list
1680
1497
  fast_exclude();
1681
1498
  //exclude from other structures
1682
1499
  if ((*prev= next))
1683
1500
    next->prev= prev;
1684
 
  /* 
1685
 
     We do not need following statements, because prev pointer of first 
 
1501
  /*
 
1502
     We do not need following statements, because prev pointer of first
1686
1503
     list element point to master->slave
1687
1504
     if (master->slave == this)
1688
1505
       master->slave= next;
1694
1511
  Exclude level of current unit from tree of SELECTs
1695
1512
 
1696
1513
  SYNOPSYS
1697
 
    st_select_lex_unit::exclude_level()
 
1514
    Select_Lex_Unit::exclude_level()
1698
1515
 
1699
1516
  NOTE: units which belong to current will be brought up on level of
1700
 
  currernt unit 
 
1517
  currernt unit
1701
1518
*/
1702
 
void st_select_lex_unit::exclude_level()
 
1519
void Select_Lex_Unit::exclude_level()
1703
1520
{
1704
 
  SELECT_LEX_UNIT *units= 0, **units_last= &units;
1705
 
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
1521
  Select_Lex_Unit *units= 0, **units_last= &units;
 
1522
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1706
1523
  {
1707
1524
    // unlink current level from global SELECTs list
1708
1525
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
1709
1526
      sl->link_next->link_prev= sl->link_prev;
1710
1527
 
1711
1528
    // 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())
 
1529
    Select_Lex_Unit **last= 0;
 
1530
    for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
1714
1531
    {
1715
1532
      u->master= master;
1716
 
      last= (SELECT_LEX_UNIT**)&(u->next);
 
1533
      last= (Select_Lex_Unit**)&(u->next);
1717
1534
    }
1718
1535
    if (last)
1719
1536
    {
1725
1542
  {
1726
1543
    // include brought up levels in place of current
1727
1544
    (*prev)= units;
1728
 
    (*units_last)= (SELECT_LEX_UNIT*)next;
 
1545
    (*units_last)= (Select_Lex_Unit*)next;
1729
1546
    if (next)
1730
 
      next->prev= (SELECT_LEX_NODE**)units_last;
 
1547
      next->prev= (Select_Lex_Node**)units_last;
1731
1548
    units->prev= prev;
1732
1549
  }
1733
1550
  else
1739
1556
  }
1740
1557
}
1741
1558
 
1742
 
 
1743
1559
/*
1744
1560
  Exclude subtree of current unit from tree of SELECTs
1745
 
 
1746
 
  SYNOPSYS
1747
 
    st_select_lex_unit::exclude_tree()
1748
1561
*/
1749
 
void st_select_lex_unit::exclude_tree()
 
1562
void Select_Lex_Unit::exclude_tree()
1750
1563
{
1751
 
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
1564
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1752
1565
  {
1753
1566
    // unlink current level from global SELECTs list
1754
1567
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
1755
1568
      sl->link_next->link_prev= sl->link_prev;
1756
1569
 
1757
1570
    // unlink underlay levels
1758
 
    for (SELECT_LEX_UNIT *u= sl->first_inner_unit(); u; u= u->next_unit())
 
1571
    for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
1759
1572
    {
1760
1573
      u->exclude_level();
1761
1574
    }
1766
1579
    next->prev= prev;
1767
1580
}
1768
1581
 
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)
 
1582
/**
 
1583
 * Mark all Select_Lex struct from this to 'last' as dependent
 
1584
 *
 
1585
 * @param Pointer to last Select_Lex struct, before wich all
 
1586
 *        Select_Lex have to be marked as dependent
 
1587
 * @note 'last' should be reachable from this Select_Lex_Node
 
1588
 */
 
1589
void Select_Lex::mark_as_dependent(Select_Lex *last)
1783
1590
{
1784
1591
  /*
1785
1592
    Mark all selects from resolved to 1 before select where was
1786
1593
    found table as depended (of select where was found table)
1787
1594
  */
1788
 
  for (SELECT_LEX *s= this;
 
1595
  for (Select_Lex *s= this;
1789
1596
       s && s != last;
1790
1597
       s= s->outer_select())
1791
1598
  {
1794
1601
      // Select is dependent of outer select
1795
1602
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
1796
1603
                       UNCACHEABLE_DEPENDENT;
1797
 
      SELECT_LEX_UNIT *munit= s->master_unit();
 
1604
      Select_Lex_Unit *munit= s->master_unit();
1798
1605
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
1799
1606
                       UNCACHEABLE_DEPENDENT;
1800
 
      for (SELECT_LEX *sl= munit->first_select(); sl ; sl= sl->next_select())
 
1607
      for (Select_Lex *sl= munit->first_select(); sl ; sl= sl->next_select())
1801
1608
      {
1802
1609
        if (sl != s &&
1803
1610
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
1811
1618
  }
1812
1619
}
1813
1620
 
1814
 
bool st_select_lex_node::set_braces(bool value __attribute__((unused)))
1815
 
{ return 1; }
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; }
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)))
 
1621
bool Select_Lex_Node::set_braces(bool)
 
1622
{ return true; }
 
1623
 
 
1624
bool Select_Lex_Node::inc_in_sum_expr()
 
1625
{ return true; }
 
1626
 
 
1627
uint32_t Select_Lex_Node::get_in_sum_expr() 
 
1628
{ return 0; }
 
1629
 
 
1630
TableList* Select_Lex_Node::get_table_list()
 
1631
{ return NULL; }
 
1632
 
 
1633
List<Item>* Select_Lex_Node::get_item_list()
 
1634
{ return NULL; }
 
1635
 
 
1636
TableList *Select_Lex_Node::add_table_to_list (Session *, Table_ident *, LEX_STRING *, uint32_t,
 
1637
                                                  thr_lock_type, List<Index_hint> *, LEX_STRING *)
1827
1638
{
1828
1639
  return 0;
1829
1640
}
1830
 
uint32_t st_select_lex_node::get_table_join_options()
 
1641
 
 
1642
uint32_t Select_Lex_Node::get_table_join_options()
1831
1643
{
1832
1644
  return 0;
1833
1645
}
1835
1647
/*
1836
1648
  prohibit using LIMIT clause
1837
1649
*/
1838
 
bool st_select_lex::test_limit()
 
1650
bool Select_Lex::test_limit()
1839
1651
{
1840
1652
  if (select_limit != 0)
1841
1653
  {
1842
1654
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
1843
1655
             "LIMIT & IN/ALL/ANY/SOME subquery");
1844
 
    return(1);
 
1656
    return true;
1845
1657
  }
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
 
 
1868
 
bool st_select_lex::add_item_to_list(THD *thd __attribute__((unused)),
1869
 
                                     Item *item)
 
1658
  return false;
 
1659
}
 
1660
 
 
1661
Select_Lex_Unit* Select_Lex_Unit::master_unit()
 
1662
{
 
1663
  return this;
 
1664
}
 
1665
 
 
1666
Select_Lex* Select_Lex_Unit::outer_select()
 
1667
{
 
1668
  return (Select_Lex*) master;
 
1669
}
 
1670
 
 
1671
bool Select_Lex::add_order_to_list(Session *session, Item *item, bool asc)
 
1672
{
 
1673
  return add_to_list(session, order_list, item, asc);
 
1674
}
 
1675
 
 
1676
bool Select_Lex::add_item_to_list(Session *, Item *item)
1870
1677
{
1871
1678
  return(item_list.push_back(item));
1872
1679
}
1873
1680
 
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)
 
1681
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
 
1682
{
 
1683
  return add_to_list(session, group_list, item, asc);
 
1684
}
 
1685
 
 
1686
Select_Lex_Unit* Select_Lex::master_unit()
 
1687
{
 
1688
  return (Select_Lex_Unit*) master;
 
1689
}
 
1690
 
 
1691
Select_Lex* Select_Lex::outer_select()
 
1692
{
 
1693
  return (Select_Lex*) master->get_master();
 
1694
}
 
1695
 
 
1696
bool Select_Lex::set_braces(bool value)
1894
1697
{
1895
1698
  braces= value;
1896
 
  return 0; 
 
1699
  return false;
1897
1700
}
1898
1701
 
1899
 
 
1900
 
bool st_select_lex::inc_in_sum_expr()
 
1702
bool Select_Lex::inc_in_sum_expr()
1901
1703
{
1902
1704
  in_sum_expr++;
1903
 
  return 0;
 
1705
  return false;
1904
1706
}
1905
1707
 
1906
 
 
1907
 
uint st_select_lex::get_in_sum_expr()
 
1708
uint32_t Select_Lex::get_in_sum_expr()
1908
1709
{
1909
1710
  return in_sum_expr;
1910
1711
}
1911
1712
 
1912
 
 
1913
 
TABLE_LIST* st_select_lex::get_table_list()
 
1713
TableList* Select_Lex::get_table_list()
1914
1714
{
1915
 
  return (TABLE_LIST*) table_list.first;
 
1715
  return (TableList*) table_list.first;
1916
1716
}
1917
1717
 
1918
 
List<Item>* st_select_lex::get_item_list()
 
1718
List<Item>* Select_Lex::get_item_list()
1919
1719
{
1920
1720
  return &item_list;
1921
1721
}
1922
1722
 
1923
 
uint32_t st_select_lex::get_table_join_options()
 
1723
uint32_t Select_Lex::get_table_join_options()
1924
1724
{
1925
1725
  return table_join_options;
1926
1726
}
1927
1727
 
1928
 
 
1929
 
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
 
1728
bool Select_Lex::setup_ref_array(Session *session, uint32_t order_group_num)
1930
1729
{
1931
1730
  if (ref_pointer_array)
1932
 
    return 0;
 
1731
    return false;
1933
1732
 
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
1733
  return (ref_pointer_array=
1940
 
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
 
1734
          (Item **)session->alloc(sizeof(Item*) * (n_child_sum_items +
1941
1735
                                                 item_list.elements +
1942
1736
                                                 select_n_having_items +
1943
1737
                                                 select_n_where_fields +
1944
1738
                                                 order_group_num)*5)) == 0;
1945
1739
}
1946
1740
 
1947
 
 
1948
 
void st_select_lex_unit::print(String *str, enum_query_type query_type)
 
1741
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
1949
1742
{
1950
1743
  bool union_all= !union_distinct;
1951
 
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
 
1744
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1952
1745
  {
1953
1746
    if (sl != first_select())
1954
1747
    {
1960
1753
    }
1961
1754
    if (sl->braces)
1962
1755
      str->append('(');
1963
 
    sl->print(thd, str, query_type);
 
1756
    sl->print(session, str, query_type);
1964
1757
    if (sl->braces)
1965
1758
      str->append(')');
1966
1759
  }
1971
1764
      str->append(STRING_WITH_LEN(" order by "));
1972
1765
      fake_select_lex->print_order(
1973
1766
        str,
1974
 
        (ORDER *) fake_select_lex->order_list.first,
 
1767
        (order_st *) fake_select_lex->order_list.first,
1975
1768
        query_type);
1976
1769
    }
1977
 
    fake_select_lex->print_limit(thd, str, query_type);
 
1770
    fake_select_lex->print_limit(session, str, query_type);
1978
1771
  }
1979
1772
}
1980
1773
 
1981
 
 
1982
 
void st_select_lex::print_order(String *str,
1983
 
                                ORDER *order,
 
1774
void Select_Lex::print_order(String *str,
 
1775
                                order_st *order,
1984
1776
                                enum_query_type query_type)
1985
1777
{
1986
1778
  for (; order; order= order->next)
1988
1780
    if (order->counter_used)
1989
1781
    {
1990
1782
      char buffer[20];
1991
 
      uint length= snprintf(buffer, 20, "%d", order->counter);
 
1783
      uint32_t length= snprintf(buffer, 20, "%d", order->counter);
1992
1784
      str->append(buffer, length);
1993
1785
    }
1994
1786
    else
1999
1791
      str->append(',');
2000
1792
  }
2001
1793
}
2002
 
 
2003
1794
 
2004
 
void st_select_lex::print_limit(THD *thd __attribute__((unused)),
2005
 
                                String *str,
 
1795
void Select_Lex::print_limit(Session *, String *str,
2006
1796
                                enum_query_type query_type)
2007
1797
{
2008
 
  SELECT_LEX_UNIT *unit= master_unit();
 
1798
  Select_Lex_Unit *unit= master_unit();
2009
1799
  Item_subselect *item= unit->item;
2010
1800
 
2011
1801
  if (item && unit->global_parameters == this)
2024
1814
                    ((Item_in_subselect*)item)->exec_method ==
2025
1815
                    Item_in_subselect::MATERIALIZATION) ?
2026
1816
                   true :
2027
 
                   (select_limit->val_int() == 1LL) &&
 
1817
                   (select_limit->val_int() == 1L) &&
2028
1818
                   offset_limit == 0));
2029
1819
      return;
2030
1820
    }
2042
1832
}
2043
1833
 
2044
1834
/**
2045
 
  @brief Restore the LEX and THD in case of a parse error.
 
1835
  @brief Restore the LEX and Session in case of a parse error.
2046
1836
 
2047
1837
  This is a clean up call that is invoked by the Bison generated
2048
 
  parser before returning an error from MYSQLparse. If your
 
1838
  parser before returning an error from DRIZZLEparse. If your
2049
1839
  semantic actions manipulate with the global thread state (which
2050
1840
  is a very bad practice and should not normally be employed) and
2051
1841
  need a clean-up in case of error, and you can not use %destructor
2052
1842
  rule in the grammar file itself, this function should be used
2053
1843
  to implement the clean up.
2054
1844
*/
2055
 
 
2056
 
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((unused)))
 
1845
void LEX::cleanup_lex_after_parse_error(Session *)
2057
1846
{
2058
1847
}
2059
1848
 
2074
1863
    this method to reset state of already initialized Query_tables_list
2075
1864
    so it can be used for processing of new statement.
2076
1865
*/
2077
 
 
2078
1866
void Query_tables_list::reset_query_tables_list(bool init)
2079
1867
{
2080
1868
  if (!init && query_tables)
2081
1869
  {
2082
 
    TABLE_LIST *table= query_tables;
 
1870
    TableList *table= query_tables;
2083
1871
    for (;;)
2084
1872
    {
2085
1873
      if (query_tables_last == &table->next_global ||
2090
1878
  query_tables= 0;
2091
1879
  query_tables_last= &query_tables;
2092
1880
  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
 
 
 
1881
}
2125
1882
 
2126
1883
/*
2127
1884
  Initialize LEX object.
2128
1885
 
2129
1886
  SYNOPSIS
2130
 
    st_lex::st_lex()
 
1887
    LEX::LEX()
2131
1888
 
2132
1889
  NOTE
2133
1890
    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()
 
1891
    Session object for which one can safely call open_tables(), lock_tables()
2135
1892
    and close_thread_tables() functions. But it is not yet ready for
2136
1893
    statement parsing. On should use lex_start() function to prepare LEX
2137
1894
    for this.
2138
1895
*/
2139
 
 
2140
 
st_lex::st_lex()
 
1896
LEX::LEX()
2141
1897
  :result(0), yacc_yyss(0), yacc_yyvs(0),
2142
1898
   sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
2143
1899
{
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);
2149
1900
  reset_query_tables_list(true);
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
2167
 
    false - only temporary table algorithm can be used
2168
 
    true  - merge algorithm can be used
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
2213
 
    st_lex::can_not_use_merged() is not true).
2214
 
 
2215
 
  RETURN
2216
 
    false - command can't use merged VIEWs
2217
 
    true  - VIEWs with MERGE algorithms can be used
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:
2235
 
    return true;
2236
 
  default:
2237
 
    return false;
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
2252
 
    false - command can't use merged VIEWs
2253
 
    true  - VIEWs with MERGE algorithms can be used
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:
2266
 
    return true;
2267
 
  default:
2268
 
    return false;
2269
 
  }
 
1901
  create_table_proto= NULL;
2270
1902
}
2271
1903
 
2272
1904
/*
2279
1911
    true yes, we need only structure
2280
1912
    false no, we need data
2281
1913
*/
2282
 
 
2283
 
bool st_lex::only_view_structure()
 
1914
bool LEX::only_view_structure()
2284
1915
{
2285
1916
  switch (sql_command) {
2286
1917
  case SQLCOM_SHOW_CREATE:
2292
1923
  }
2293
1924
}
2294
1925
 
2295
 
 
2296
1926
/*
2297
1927
  Should Items_ident be printed correctly
2298
1928
 
2303
1933
    true yes, we need only structure
2304
1934
    false no, we need data
2305
1935
*/
2306
 
 
2307
 
 
2308
 
bool st_lex::need_correct_ident()
 
1936
bool LEX::need_correct_ident()
2309
1937
{
2310
1938
  switch(sql_command)
2311
1939
  {
2317
1945
  }
2318
1946
}
2319
1947
 
2320
 
 
2321
1948
/**
2322
1949
  This method should be called only during parsing.
2323
1950
  It is aware of compound statements (stored routine bodies)
2324
1951
  and will initialize the destination with the default
2325
1952
  database of the stored routine, rather than the default
2326
1953
  database of the connection it is parsed in.
2327
 
  E.g. if one has no current database selected, or current database 
 
1954
  E.g. if one has no current database selected, or current database
2328
1955
  set to 'bar' and then issues:
2329
1956
 
2330
1957
  CREATE PROCEDURE foo.p1() BEGIN SELECT * FROM t1 END//
2336
1963
  @return true in case of error (parsing should be aborted, false in
2337
1964
  case of success
2338
1965
*/
2339
 
 
2340
 
bool
2341
 
st_lex::copy_db_to(char **p_db, size_t *p_db_length) const
 
1966
bool LEX::copy_db_to(char **p_db, size_t *p_db_length) const
2342
1967
{
2343
 
  return thd->copy_db_to(p_db, p_db_length);
 
1968
  return session->copy_db_to(p_db, p_db_length);
2344
1969
}
2345
1970
 
2346
1971
/*
2347
1972
  initialize limit counters
2348
1973
 
2349
1974
  SYNOPSIS
2350
 
    st_select_lex_unit::set_limit()
2351
 
    values      - SELECT_LEX with initial values for counters
 
1975
    Select_Lex_Unit::set_limit()
 
1976
    values      - Select_Lex with initial values for counters
2352
1977
*/
2353
 
 
2354
 
void st_select_lex_unit::set_limit(st_select_lex *sl)
 
1978
void Select_Lex_Unit::set_limit(Select_Lex *sl)
2355
1979
{
2356
1980
  ha_rows select_limit_val;
2357
1981
  uint64_t val;
2358
1982
 
2359
1983
  val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
2360
1984
  select_limit_val= (ha_rows)val;
2361
 
#ifndef BIG_TABLES
2362
 
  /* 
 
1985
  /*
2363
1986
    Check for overflow : ha_rows can be smaller then uint64_t if
2364
1987
    BIG_TABLES is off.
2365
1988
    */
2366
1989
  if (val != (uint64_t)select_limit_val)
2367
1990
    select_limit_val= HA_POS_ERROR;
2368
 
#endif
2369
1991
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
2370
 
                                                 0ULL);
 
1992
                                                 0UL);
2371
1993
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2372
1994
  if (select_limit_cnt < select_limit_val)
2373
1995
    select_limit_cnt= HA_POS_ERROR;             // no limit
2374
1996
}
2375
1997
 
2376
 
 
2377
1998
/*
2378
1999
  Unlink the first table from the global table list and the first table from
2379
2000
  outer select (lex->select_lex) local list
2392
2013
      In this case link_to_local is set.
2393
2014
 
2394
2015
*/
2395
 
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
 
2016
TableList *LEX::unlink_first_table(bool *link_to_local)
2396
2017
{
2397
 
  TABLE_LIST *first;
 
2018
  TableList *first;
2398
2019
  if ((first= query_tables))
2399
2020
  {
2400
2021
    /*
2411
2032
    */
2412
2033
    if ((*link_to_local= test(select_lex.table_list.first)))
2413
2034
    {
2414
 
      select_lex.context.table_list= 
 
2035
      select_lex.context.table_list=
2415
2036
        select_lex.context.first_name_resolution_table= first->next_local;
2416
 
      select_lex.table_list.first= (uchar*) (first->next_local);
 
2037
      select_lex.table_list.first= (unsigned char*) (first->next_local);
2417
2038
      select_lex.table_list.elements--; //safety
2418
2039
      first->next_local= 0;
2419
2040
      /*
2426
2047
  return first;
2427
2048
}
2428
2049
 
2429
 
 
2430
2050
/*
2431
2051
  Bring first local table of first most outer select to first place in global
2432
2052
  table list
2433
2053
 
2434
2054
  SYNOPSYS
2435
 
     st_lex::first_lists_tables_same()
 
2055
     LEX::first_lists_tables_same()
2436
2056
 
2437
2057
  NOTES
2438
2058
    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
 
2059
    main Select_Lex have special meaning => check that it is the first table
2440
2060
    in global list and re-link to be first in the global list if it is
2441
2061
    necessary.  We need such re-linking only for queries with sub-queries in
2442
2062
    the select list, as only in this case tables of sub-queries will go to
2443
2063
    the global list first.
2444
2064
*/
2445
 
 
2446
 
void st_lex::first_lists_tables_same()
 
2065
void LEX::first_lists_tables_same()
2447
2066
{
2448
 
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
 
2067
  TableList *first_table= (TableList*) select_lex.table_list.first;
2449
2068
  if (query_tables != first_table && first_table != 0)
2450
2069
  {
2451
 
    TABLE_LIST *next;
 
2070
    TableList *next;
2452
2071
    if (query_tables_last == &first_table->next_global)
2453
2072
      query_tables_last= first_table->prev_global;
2454
2073
 
2467
2086
  }
2468
2087
}
2469
2088
 
2470
 
 
2471
2089
/*
2472
2090
  Link table back that was unlinked with unlink_first_table()
2473
2091
 
2478
2096
  RETURN
2479
2097
    global list
2480
2098
*/
2481
 
 
2482
 
void st_lex::link_first_table_back(TABLE_LIST *first,
2483
 
                                   bool link_to_local)
 
2099
void LEX::link_first_table_back(TableList *first, bool link_to_local)
2484
2100
{
2485
2101
  if (first)
2486
2102
  {
2492
2108
 
2493
2109
    if (link_to_local)
2494
2110
    {
2495
 
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
 
2111
      first->next_local= (TableList*) select_lex.table_list.first;
2496
2112
      select_lex.context.table_list= first;
2497
 
      select_lex.table_list.first= (uchar*) first;
 
2113
      select_lex.table_list.first= (unsigned char*) first;
2498
2114
      select_lex.table_list.elements++; //safety
2499
2115
    }
2500
2116
  }
2501
2117
}
2502
2118
 
2503
 
 
2504
 
 
2505
2119
/*
2506
2120
  cleanup lex for case when we open table by table for processing
2507
2121
 
2508
2122
  SYNOPSIS
2509
 
    st_lex::cleanup_after_one_table_open()
 
2123
    LEX::cleanup_after_one_table_open()
2510
2124
 
2511
2125
  NOTE
2512
2126
    This method is mostly responsible for cleaning up of selects lists and
2513
2127
    derived tables state. To rollback changes in Query_tables_list one has
2514
2128
    to call Query_tables_list::reset_query_tables_list(false).
2515
2129
*/
2516
 
 
2517
 
void st_lex::cleanup_after_one_table_open()
 
2130
void LEX::cleanup_after_one_table_open()
2518
2131
{
2519
2132
  /*
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
 
2133
    session->lex->derived_tables & additional units may be set if we open
 
2134
    a view. It is necessary to clear session->lex->derived_tables flag
2522
2135
    to prevent processing of derived tables during next open_and_lock_tables
2523
2136
    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
 
2137
    NOTE: all units will be connected to session->lex->select_lex, because we
2525
2138
    have not UNION on most upper level.
2526
2139
    */
2527
2140
  if (all_selects_list != &select_lex)
2528
2141
  {
2529
2142
    derived_tables= 0;
2530
2143
    /* cleunup underlying units (units of VIEW) */
2531
 
    for (SELECT_LEX_UNIT *un= select_lex.first_inner_unit();
 
2144
    for (Select_Lex_Unit *un= select_lex.first_inner_unit();
2532
2145
         un;
2533
2146
         un= un->next_unit())
2534
2147
      un->cleanup();
2539
2152
  }
2540
2153
}
2541
2154
 
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
 
 
2552
 
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
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
 
 
2565
 
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
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
2577
 
    false  No routines and tables used
2578
 
    true   Either or both routines and tables are used.
2579
 
*/
2580
 
 
2581
 
bool st_lex::table_or_sp_used()
2582
 
{
2583
 
  if (sroutines.records || query_tables)
2584
 
    return(true);
2585
 
 
2586
 
  return(false);
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
 
2155
/*
 
2156
  There are Select_Lex::add_table_to_list &
 
2157
  Select_Lex::set_lock_for_tables are in sql_parse.cc
 
2158
 
 
2159
  Select_Lex::print is in sql_select.cc
 
2160
 
 
2161
  Select_Lex_Unit::prepare, Select_Lex_Unit::exec,
 
2162
  Select_Lex_Unit::cleanup, Select_Lex_Unit::reinit_exec_mechanism,
 
2163
  Select_Lex_Unit::change_result
2628
2164
  are in sql_union.cc
2629
2165
*/
2630
2166
 
2638
2174
 
2639
2175
  DESCRIPTION
2640
2176
    Used in filling up the tagged hints list.
2641
 
    This list is filled by first setting the kind of the hint as a 
 
2177
    This list is filled by first setting the kind of the hint as a
2642
2178
    context variable and then adding hints of the current kind.
2643
2179
    Then the context variable index_hint_type can be reset to the
2644
2180
    next hint type.
2645
2181
*/
2646
 
void st_select_lex::set_index_hint_type(enum index_hint_type type_arg,
2647
 
                                        index_clause_map clause)
2648
 
 
2182
void Select_Lex::set_index_hint_type(enum index_hint_type type_arg, index_clause_map clause)
 
2183
{
2649
2184
  current_index_hint_type= type_arg;
2650
2185
  current_index_hint_clause= clause;
2651
2186
}
2652
2187
 
2653
 
 
2654
2188
/*
2655
2189
  Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
2656
2190
 
2657
2191
  SYNOPSIS
2658
2192
    alloc_index_hints()
2659
 
      thd         current thread.
 
2193
      session         current thread.
2660
2194
*/
2661
 
 
2662
 
void st_select_lex::alloc_index_hints (THD *thd)
2663
 
2664
 
  index_hints= new (thd->mem_root) List<Index_hint>(); 
 
2195
void Select_Lex::alloc_index_hints (Session *session)
 
2196
{
 
2197
  index_hints= new (session->mem_root) List<Index_hint>();
2665
2198
}
2666
2199
 
2667
 
 
2668
 
 
2669
2200
/*
2670
 
  adds an element to the array storing index usage hints 
 
2201
  adds an element to the array storing index usage hints
2671
2202
  (ADD/FORCE/IGNORE INDEX).
2672
2203
 
2673
2204
  SYNOPSIS
2674
2205
    add_index_hint()
2675
 
      thd         current thread.
 
2206
      session         current thread.
2676
2207
      str         name of the index.
2677
2208
      length      number of characters in str.
2678
2209
 
2679
2210
  RETURN VALUE
2680
2211
    0 on success, non-zero otherwise
2681
2212
*/
2682
 
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
 
2213
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
2683
2214
{
2684
 
  return index_hints->push_front (new (thd->mem_root) 
 
2215
  return index_hints->push_front (new (session->mem_root)
2685
2216
                                 Index_hint(current_index_hint_type,
2686
2217
                                            current_index_hint_clause,
2687
2218
                                            str, length));