~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/sql_lex.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2006 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
/* A lexical scanner on a temporary buffer with a yacc interface */
 
18
 
 
19
#include "config.h"
 
20
#define DRIZZLE_LEX 1
 
21
#include "drizzled/configmake.h"
 
22
#include "drizzled/item/num.h"
 
23
#include "drizzled/error.h"
 
24
#include "drizzled/session.h"
 
25
#include "drizzled/sql_base.h"
 
26
#include "drizzled/lookup_symbol.h"
 
27
#include "drizzled/index_hint.h"
 
28
 
 
29
#include <ctype.h>
 
30
 
 
31
using namespace std;
 
32
 
 
33
/* Stay outside of the namespace because otherwise bison goes nuts */
 
34
int DRIZZLElex(void *arg, void *yysession);
 
35
 
 
36
namespace drizzled
 
37
{
 
38
 
 
39
static int lex_one_token(void *arg, void *yysession);
 
40
 
 
41
/**
 
42
  save order by and tables in own lists.
 
43
*/
 
44
static bool add_to_list(Session *session, SQL_LIST &list, Item *item, bool asc)
 
45
{
 
46
  order_st *order;
 
47
  if (!(order = (order_st *) session->alloc(sizeof(order_st))))
 
48
    return(1);
 
49
  order->item_ptr= item;
 
50
  order->item= &order->item_ptr;
 
51
  order->asc = asc;
 
52
  order->free_me=0;
 
53
  order->used=0;
 
54
  order->counter_used= 0;
 
55
  list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
 
56
  return(0);
 
57
}
 
58
 
 
59
/**
 
60
  LEX_STRING constant for null-string to be used in parser and other places.
 
61
*/
 
62
const LEX_STRING null_lex_str= {NULL, 0};
 
63
 
 
64
Lex_input_stream::Lex_input_stream(Session *session,
 
65
                                   const char* buffer,
 
66
                                   unsigned int length)
 
67
: m_session(session),
 
68
  yylineno(1),
 
69
  yytoklen(0),
 
70
  yylval(NULL),
 
71
  lookahead_token(END_OF_INPUT),
 
72
  lookahead_yylval(NULL),
 
73
  m_ptr(buffer),
 
74
  m_tok_start(NULL),
 
75
  m_tok_end(NULL),
 
76
  m_end_of_query(buffer + length),
 
77
  m_tok_start_prev(NULL),
 
78
  m_buf(buffer),
 
79
  m_buf_length(length),
 
80
  m_echo(true),
 
81
  m_cpp_tok_start(NULL),
 
82
  m_cpp_tok_start_prev(NULL),
 
83
  m_cpp_tok_end(NULL),
 
84
  m_body_utf8(NULL),
 
85
  m_cpp_utf8_processed_ptr(NULL),
 
86
  next_state(MY_LEX_START),
 
87
  ignore_space(1),
 
88
  in_comment(NO_COMMENT)
 
89
{
 
90
  m_cpp_buf= (char*) session->alloc(length + 1);
 
91
  m_cpp_ptr= m_cpp_buf;
 
92
}
 
93
 
 
94
Lex_input_stream::~Lex_input_stream()
 
95
{}
 
96
 
 
97
/**
 
98
  The operation is called from the parser in order to
 
99
  1) designate the intention to have utf8 body;
 
100
  1) Indicate to the lexer that we will need a utf8 representation of this
 
101
     statement;
 
102
  2) Determine the beginning of the body.
 
103
 
 
104
  @param session        Thread context.
 
105
  @param begin_ptr  Pointer to the start of the body in the pre-processed
 
106
                    buffer.
 
107
*/
 
108
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
 
109
{
 
110
  assert(begin_ptr);
 
111
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
 
112
 
 
113
  uint32_t body_utf8_length=
 
114
    (m_buf_length / default_charset_info->mbminlen) *
 
115
    my_charset_utf8_bin.mbmaxlen;
 
116
 
 
117
  m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
 
118
  m_body_utf8_ptr= m_body_utf8;
 
119
  *m_body_utf8_ptr= 0;
 
120
 
 
121
  m_cpp_utf8_processed_ptr= begin_ptr;
 
122
}
 
123
 
 
124
/**
 
125
  @brief The operation appends unprocessed part of pre-processed buffer till
 
126
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to end_ptr.
 
127
 
 
128
  The idea is that some tokens in the pre-processed buffer (like character
 
129
  set introducers) should be skipped.
 
130
 
 
131
  Example:
 
132
    CPP buffer: SELECT 'str1', _latin1 'str2';
 
133
    m_cpp_utf8_processed_ptr -- points at the "SELECT ...";
 
134
    In order to skip "_latin1", the following call should be made:
 
135
      body_utf8_append(<pointer to "_latin1 ...">, <pointer to " 'str2'...">)
 
136
 
 
137
  @param ptr      Pointer in the pre-processed buffer, which specifies the
 
138
                  end of the chunk, which should be appended to the utf8
 
139
                  body.
 
140
  @param end_ptr  Pointer in the pre-processed buffer, to which
 
141
                  m_cpp_utf8_processed_ptr will be set in the end of the
 
142
                  operation.
 
143
*/
 
144
void Lex_input_stream::body_utf8_append(const char *ptr,
 
145
                                        const char *end_ptr)
 
146
{
 
147
  assert(m_cpp_buf <= ptr && ptr <= m_cpp_buf + m_buf_length);
 
148
  assert(m_cpp_buf <= end_ptr && end_ptr <= m_cpp_buf + m_buf_length);
 
149
 
 
150
  if (!m_body_utf8)
 
151
    return;
 
152
 
 
153
  if (m_cpp_utf8_processed_ptr >= ptr)
 
154
    return;
 
155
 
 
156
  int bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;
 
157
 
 
158
  memcpy(m_body_utf8_ptr, m_cpp_utf8_processed_ptr, bytes_to_copy);
 
159
  m_body_utf8_ptr += bytes_to_copy;
 
160
  *m_body_utf8_ptr= 0;
 
161
 
 
162
  m_cpp_utf8_processed_ptr= end_ptr;
 
163
}
 
164
 
 
165
/**
 
166
  The operation appends unprocessed part of the pre-processed buffer till
 
167
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to ptr.
 
168
 
 
169
  @param ptr  Pointer in the pre-processed buffer, which specifies the end
 
170
              of the chunk, which should be appended to the utf8 body.
 
171
*/
 
172
void Lex_input_stream::body_utf8_append(const char *ptr)
 
173
{
 
174
  body_utf8_append(ptr, ptr);
 
175
}
 
176
 
 
177
/**
 
178
  The operation converts the specified text literal to the utf8 and appends
 
179
  the result to the utf8-body.
 
180
 
 
181
  @param session      Thread context.
 
182
  @param txt      Text literal.
 
183
  @param txt_cs   Character set of the text literal.
 
184
  @param end_ptr  Pointer in the pre-processed buffer, to which
 
185
                  m_cpp_utf8_processed_ptr will be set in the end of the
 
186
                  operation.
 
187
*/
 
188
void Lex_input_stream::body_utf8_append_literal(const LEX_STRING *txt,
 
189
                                                const char *end_ptr)
 
190
{
 
191
  if (!m_cpp_utf8_processed_ptr)
 
192
    return;
 
193
 
 
194
  /* NOTE: utf_txt.length is in bytes, not in symbols. */
 
195
 
 
196
  memcpy(m_body_utf8_ptr, txt->str, txt->length);
 
197
  m_body_utf8_ptr += txt->length;
 
198
  *m_body_utf8_ptr= 0;
 
199
 
 
200
  m_cpp_utf8_processed_ptr= end_ptr;
 
201
}
 
202
 
 
203
/*
 
204
  This is called before every query that is to be parsed.
 
205
  Because of this, it's critical to not do too much things here.
 
206
  (We already do too much here)
 
207
*/
 
208
void lex_start(Session *session)
 
209
{
 
210
  LEX *lex= session->lex;
 
211
 
 
212
  lex->session= lex->unit.session= session;
 
213
 
 
214
  lex->context_stack.empty();
 
215
  lex->unit.init_query();
 
216
  lex->unit.init_select();
 
217
  /* 'parent_lex' is used in init_query() so it must be before it. */
 
218
  lex->select_lex.parent_lex= lex;
 
219
  lex->select_lex.init_query();
 
220
  lex->value_list.empty();
 
221
  lex->update_list.empty();
 
222
  lex->auxiliary_table_list.empty();
 
223
  lex->unit.next= lex->unit.master=
 
224
    lex->unit.link_next= lex->unit.return_to= 0;
 
225
  lex->unit.prev= lex->unit.link_prev= 0;
 
226
  lex->unit.slave= lex->unit.global_parameters= lex->current_select=
 
227
    lex->all_selects_list= &lex->select_lex;
 
228
  lex->select_lex.master= &lex->unit;
 
229
  lex->select_lex.prev= &lex->unit.slave;
 
230
  lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
 
231
  lex->select_lex.link_prev= (Select_Lex_Node**)&(lex->all_selects_list);
 
232
  lex->select_lex.options= 0;
 
233
  lex->select_lex.init_order();
 
234
  lex->select_lex.group_list.empty();
 
235
  lex->describe= 0;
 
236
  lex->derived_tables= 0;
 
237
  lex->lock_option= TL_READ;
 
238
  lex->leaf_tables_insert= 0;
 
239
  lex->select_lex.select_number= 1;
 
240
  lex->length=0;
 
241
  lex->select_lex.in_sum_expr=0;
 
242
  lex->select_lex.group_list.empty();
 
243
  lex->select_lex.order_list.empty();
 
244
  lex->sql_command= SQLCOM_END;
 
245
  lex->duplicates= DUP_ERROR;
 
246
  lex->ignore= 0;
 
247
  lex->escape_used= false;
 
248
  lex->query_tables= 0;
 
249
  lex->reset_query_tables_list(false);
 
250
  lex->expr_allows_subselect= true;
 
251
  lex->use_only_table_context= false;
 
252
 
 
253
  lex->name.str= 0;
 
254
  lex->name.length= 0;
 
255
  lex->nest_level=0 ;
 
256
  lex->allow_sum_func= 0;
 
257
  lex->in_sum_func= NULL;
 
258
 
 
259
  lex->is_lex_started= true;
 
260
  lex->statement= NULL;
 
261
}
 
262
 
 
263
void lex_end(LEX *lex)
 
264
{
 
265
  if (lex->yacc_yyss)
 
266
  {
 
267
    free(lex->yacc_yyss);
 
268
    free(lex->yacc_yyvs);
 
269
    lex->yacc_yyss= 0;
 
270
    lex->yacc_yyvs= 0;
 
271
  }
 
272
 
 
273
  delete lex->result;
 
274
 
 
275
  lex->result= 0;
 
276
 
 
277
  if (lex->statement) 
 
278
    delete lex->statement;
 
279
}
 
280
 
 
281
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
 
282
{
 
283
  /* Plenty of memory for the largest lex symbol we have */
 
284
  char tok_upper[64];
 
285
  const char *tok= lip->get_tok_start();
 
286
  uint32_t tok_pos= 0;
 
287
  for (;tok_pos<len && tok_pos<63;tok_pos++)
 
288
    tok_upper[tok_pos]=my_toupper(system_charset_info, tok[tok_pos]);
 
289
  tok_upper[tok_pos]=0;
 
290
 
 
291
  const SYMBOL *symbol= lookup_symbol(tok_upper, len, function);
 
292
  if (symbol)
 
293
  {
 
294
    lip->yylval->symbol.symbol=symbol;
 
295
    lip->yylval->symbol.str= (char*) tok;
 
296
    lip->yylval->symbol.length=len;
 
297
 
 
298
    return symbol->tok;
 
299
  }
 
300
 
 
301
  return 0;
 
302
}
 
303
 
 
304
bool is_lex_native_function(const LEX_STRING *name)
 
305
{
 
306
  assert(name != NULL);
 
307
  return (lookup_symbol(name->str, name->length, 1) != 0);
 
308
}
 
309
 
 
310
/* make a copy of token before ptr and set yytoklen */
 
311
static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
 
312
{
 
313
  LEX_STRING tmp;
 
314
  lip->yyUnget();                       // ptr points now after last token char
 
315
  tmp.length=lip->yytoklen=length;
 
316
  tmp.str= lip->m_session->strmake(lip->get_tok_start() + skip, tmp.length);
 
317
 
 
318
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
 
319
  lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;
 
320
 
 
321
  return tmp;
 
322
}
 
323
 
 
324
/*
 
325
 todo:
 
326
   There are no dangerous charsets in mysql for function
 
327
   get_quoted_token yet. But it should be fixed in the
 
328
   future to operate multichar strings (like ucs2)
 
329
*/
 
330
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
 
331
                                   uint32_t skip,
 
332
                                   uint32_t length, char quote)
 
333
{
 
334
  LEX_STRING tmp;
 
335
  const char *from, *end;
 
336
  char *to;
 
337
  lip->yyUnget();                       // ptr points now after last token char
 
338
  tmp.length= lip->yytoklen=length;
 
339
  tmp.str=(char*) lip->m_session->alloc(tmp.length+1);
 
340
  from= lip->get_tok_start() + skip;
 
341
  to= tmp.str;
 
342
  end= to+length;
 
343
 
 
344
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
 
345
  lip->m_cpp_text_end= lip->m_cpp_text_start + length;
 
346
 
 
347
  for ( ; to != end; )
 
348
  {
 
349
    if ((*to++= *from++) == quote)
 
350
    {
 
351
      from++;                                   // Skip double quotes
 
352
      lip->m_cpp_text_start++;
 
353
    }
 
354
  }
 
355
  *to= 0;                                       // End null for safety
 
356
  return tmp;
 
357
}
 
358
 
 
359
 
 
360
/*
 
361
  Return an unescaped text literal without quotes
 
362
  Fix sometimes to do only one scan of the string
 
363
*/
 
364
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
 
365
{
 
366
  register unsigned char c,sep;
 
367
  bool found_escape= false;
 
368
  const CHARSET_INFO * const cs= lip->m_session->charset();
 
369
 
 
370
  lip->tok_bitmap= 0;
 
371
  sep= lip->yyGetLast();                        // String should end with this
 
372
  while (! lip->eof())
 
373
  {
 
374
    c= lip->yyGet();
 
375
    lip->tok_bitmap|= c;
 
376
    {
 
377
      if (use_mb(cs))
 
378
      {
 
379
        int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
380
        if (l != 0) 
 
381
        {
 
382
          lip->skip_binary(l-1);
 
383
          continue;
 
384
        }
 
385
      }
 
386
    }
 
387
    if (c == '\\')
 
388
    {                                   // Escaped character
 
389
      found_escape= true;
 
390
      if (lip->eof())
 
391
        return 0;
 
392
      lip->yySkip();
 
393
    }
 
394
    else if (c == sep)
 
395
    {
 
396
      if (c == lip->yyGet())            // Check if two separators in a row
 
397
      {
 
398
        found_escape= true;                 // duplicate. Remember for delete
 
399
        continue;
 
400
      }
 
401
      else
 
402
        lip->yyUnget();
 
403
 
 
404
      /* Found end. Unescape and return string */
 
405
      const char *str, *end;
 
406
      char *start;
 
407
 
 
408
      str= lip->get_tok_start();
 
409
      end= lip->get_ptr();
 
410
      /* Extract the text from the token */
 
411
      str+= pre_skip;
 
412
      end-= post_skip;
 
413
      assert(end >= str);
 
414
 
 
415
      if (!(start= (char*) lip->m_session->alloc((uint32_t) (end-str)+1)))
 
416
        return (char*) "";              // memory::SqlAlloc has set error flag
 
417
 
 
418
      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
 
419
      lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;
 
420
 
 
421
      if (! found_escape)
 
422
      {
 
423
        lip->yytoklen= (uint32_t) (end-str);
 
424
        memcpy(start, str, lip->yytoklen);
 
425
        start[lip->yytoklen]= 0;
 
426
      }
 
427
      else
 
428
      {
 
429
        char *to;
 
430
 
 
431
        for (to= start; str != end; str++)
 
432
        {
 
433
          if (use_mb(cs))
 
434
          {
 
435
            int l= my_ismbchar(cs, str, end);
 
436
            if (l != 0)
 
437
            {
 
438
              while (l--)
 
439
                *to++= *str++;
 
440
              str--;
 
441
              continue;
 
442
            }
 
443
          }
 
444
          if (*str == '\\' && (str + 1) != end)
 
445
          {
 
446
            switch (*++str) {
 
447
            case 'n':
 
448
              *to++= '\n';
 
449
              break;
 
450
            case 't':
 
451
              *to++= '\t';
 
452
              break;
 
453
            case 'r':
 
454
              *to++= '\r';
 
455
              break;
 
456
            case 'b':
 
457
              *to++= '\b';
 
458
              break;
 
459
            case '0':
 
460
              *to++= 0;                 // Ascii null
 
461
              break;
 
462
            case 'Z':                   // ^Z must be escaped on Win32
 
463
              *to++= '\032';
 
464
              break;
 
465
            case '_':
 
466
            case '%':
 
467
              *to++= '\\';              // remember prefix for wildcard
 
468
              /* Fall through */
 
469
            default:
 
470
              *to++= *str;
 
471
              break;
 
472
            }
 
473
          }
 
474
          else if (*str == sep)
 
475
            *to++= *str++;              // Two ' or "
 
476
          else
 
477
            *to++ = *str;
 
478
        }
 
479
        *to= 0;
 
480
        lip->yytoklen= (uint32_t) (to - start);
 
481
      }
 
482
      return start;
 
483
    }
 
484
  }
 
485
  return 0;                                     // unexpected end of query
 
486
}
 
487
 
 
488
 
 
489
/*
 
490
** Calc type of integer; long integer, int64_t integer or real.
 
491
** Returns smallest type that match the string.
 
492
** When using uint64_t values the result is converted to a real
 
493
** because else they will be unexpected sign changes because all calculation
 
494
** is done with int64_t or double.
 
495
*/
 
496
 
 
497
static const char *long_str= "2147483647";
 
498
static const uint32_t long_len= 10;
 
499
static const char *signed_long_str= "-2147483648";
 
500
static const char *int64_t_str= "9223372036854775807";
 
501
static const uint32_t int64_t_len= 19;
 
502
static const char *signed_int64_t_str= "-9223372036854775808";
 
503
static const uint32_t signed_int64_t_len= 19;
 
504
static const char *unsigned_int64_t_str= "18446744073709551615";
 
505
static const uint32_t unsigned_int64_t_len= 20;
 
506
 
 
507
static inline uint32_t int_token(const char *str,uint32_t length)
 
508
{
 
509
  if (length < long_len)                        // quick normal case
 
510
    return NUM;
 
511
  bool neg=0;
 
512
 
 
513
  if (*str == '+')                              // Remove sign and pre-zeros
 
514
  {
 
515
    str++; length--;
 
516
  }
 
517
  else if (*str == '-')
 
518
  {
 
519
    str++; length--;
 
520
    neg=1;
 
521
  }
 
522
  while (*str == '0' && length)
 
523
  {
 
524
    str++; length --;
 
525
  }
 
526
  if (length < long_len)
 
527
    return NUM;
 
528
 
 
529
  uint32_t smaller,bigger;
 
530
  const char *cmp;
 
531
  if (neg)
 
532
  {
 
533
    if (length == long_len)
 
534
    {
 
535
      cmp= signed_long_str+1;
 
536
      smaller=NUM;                              // If <= signed_long_str
 
537
      bigger=LONG_NUM;                          // If >= signed_long_str
 
538
    }
 
539
    else if (length < signed_int64_t_len)
 
540
      return LONG_NUM;
 
541
    else if (length > signed_int64_t_len)
 
542
      return DECIMAL_NUM;
 
543
    else
 
544
    {
 
545
      cmp=signed_int64_t_str+1;
 
546
      smaller=LONG_NUM;                         // If <= signed_int64_t_str
 
547
      bigger=DECIMAL_NUM;
 
548
    }
 
549
  }
 
550
  else
 
551
  {
 
552
    if (length == long_len)
 
553
    {
 
554
      cmp= long_str;
 
555
      smaller=NUM;
 
556
      bigger=LONG_NUM;
 
557
    }
 
558
    else if (length < int64_t_len)
 
559
      return LONG_NUM;
 
560
    else if (length > int64_t_len)
 
561
    {
 
562
      if (length > unsigned_int64_t_len)
 
563
        return DECIMAL_NUM;
 
564
      cmp=unsigned_int64_t_str;
 
565
      smaller=ULONGLONG_NUM;
 
566
      bigger=DECIMAL_NUM;
 
567
    }
 
568
    else
 
569
    {
 
570
      cmp=int64_t_str;
 
571
      smaller=LONG_NUM;
 
572
      bigger= ULONGLONG_NUM;
 
573
    }
 
574
  }
 
575
  while (*cmp && *cmp++ == *str++) ;
 
576
  return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
 
577
}
 
578
 
 
579
} /* namespace drizzled */
 
580
/*
 
581
  DRIZZLElex remember the following states from the following DRIZZLElex()
 
582
 
 
583
  - MY_LEX_EOQ                  Found end of query
 
584
  - MY_LEX_OPERATOR_OR_IDENT    Last state was an ident, text or number
 
585
                                (which can't be followed by a signed number)
 
586
*/
 
587
int DRIZZLElex(void *arg, void *yysession)
 
588
{
 
589
  drizzled::Session *session= (drizzled::Session *)yysession;
 
590
  drizzled::Lex_input_stream *lip= session->m_lip;
 
591
  YYSTYPE *yylval=(YYSTYPE*) arg;
 
592
  int token;
 
593
 
 
594
  if (lip->lookahead_token != END_OF_INPUT)
 
595
  {
 
596
    /*
 
597
      The next token was already parsed in advance,
 
598
      return it.
 
599
    */
 
600
    token= lip->lookahead_token;
 
601
    lip->lookahead_token= END_OF_INPUT;
 
602
    *yylval= *(lip->lookahead_yylval);
 
603
    lip->lookahead_yylval= NULL;
 
604
    return token;
 
605
  }
 
606
 
 
607
  token= drizzled::lex_one_token(arg, yysession);
 
608
 
 
609
  switch(token) {
 
610
  case WITH:
 
611
    /*
 
612
      Parsing 'WITH' 'ROLLUP' requires 2 look ups,
 
613
      which makes the grammar LALR(2).
 
614
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
 
615
      to transform the grammar into a LALR(1) grammar,
 
616
      which sql_yacc.yy can process.
 
617
    */
 
618
    token= drizzled::lex_one_token(arg, yysession);
 
619
    if (token == ROLLUP_SYM)
 
620
    {
 
621
      return WITH_ROLLUP_SYM;
 
622
    }
 
623
    else
 
624
    {
 
625
      /*
 
626
        Save the token following 'WITH'
 
627
      */
 
628
      lip->lookahead_yylval= lip->yylval;
 
629
      lip->yylval= NULL;
 
630
      lip->lookahead_token= token;
 
631
      return WITH;
 
632
    }
 
633
  default:
 
634
    break;
 
635
  }
 
636
 
 
637
  return token;
 
638
}
 
639
 
 
640
namespace drizzled
 
641
{
 
642
 
 
643
int lex_one_token(void *arg, void *yysession)
 
644
{
 
645
  register unsigned char c= 0; /* Just set to shutup GCC */
 
646
  bool comment_closed;
 
647
  int   tokval, result_state;
 
648
  unsigned int length;
 
649
  enum my_lex_states state;
 
650
  Session *session= (Session *)yysession;
 
651
  Lex_input_stream *lip= session->m_lip;
 
652
  LEX *lex= session->lex;
 
653
  YYSTYPE *yylval=(YYSTYPE*) arg;
 
654
  const CHARSET_INFO * const cs= session->charset();
 
655
  unsigned char *state_map= cs->state_map;
 
656
  unsigned char *ident_map= cs->ident_map;
 
657
 
 
658
  lip->yylval=yylval;                   // The global state
 
659
 
 
660
  lip->start_token();
 
661
  state=lip->next_state;
 
662
  lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
 
663
  for (;;)
 
664
  {
 
665
    switch (state) {
 
666
    case MY_LEX_OPERATOR_OR_IDENT:      // Next is operator or keyword
 
667
    case MY_LEX_START:                  // Start of token
 
668
      // Skip starting whitespace
 
669
      while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
 
670
      {
 
671
        if (c == '\n')
 
672
          lip->yylineno++;
 
673
 
 
674
        lip->yySkip();
 
675
      }
 
676
 
 
677
      /* Start of real token */
 
678
      lip->restart_token();
 
679
      c= lip->yyGet();
 
680
      state= (enum my_lex_states) state_map[c];
 
681
      break;
 
682
    case MY_LEX_ESCAPE:
 
683
      if (lip->yyGet() == 'N')
 
684
      {                                 // Allow \N as shortcut for NULL
 
685
        yylval->lex_str.str=(char*) "\\N";
 
686
        yylval->lex_str.length=2;
 
687
        return NULL_SYM;
 
688
      }
 
689
    case MY_LEX_CHAR:                   // Unknown or single char token
 
690
    case MY_LEX_SKIP:                   // This should not happen
 
691
      if (c == '-' && lip->yyPeek() == '-' &&
 
692
          (my_isspace(cs,lip->yyPeekn(1)) ||
 
693
           my_iscntrl(cs,lip->yyPeekn(1))))
 
694
      {
 
695
        state=MY_LEX_COMMENT;
 
696
        break;
 
697
      }
 
698
 
 
699
      if (c != ')')
 
700
        lip->next_state= MY_LEX_START;  // Allow signed numbers
 
701
 
 
702
      if (c == ',')
 
703
      {
 
704
        /*
 
705
          Warning:
 
706
          This is a work around, to make the "remember_name" rule in
 
707
          sql/sql_yacc.yy work properly.
 
708
          The problem is that, when parsing "select expr1, expr2",
 
709
          the code generated by bison executes the *pre* action
 
710
          remember_name (see select_item) *before* actually parsing the
 
711
          first token of expr2.
 
712
        */
 
713
        lip->restart_token();
 
714
      }
 
715
 
 
716
      return((int) c);
 
717
 
 
718
    case MY_LEX_IDENT_OR_HEX:
 
719
      if (lip->yyPeek() == '\'')
 
720
      {                                 // Found x'hex-number'
 
721
        state= MY_LEX_HEX_NUMBER;
 
722
        break;
 
723
      }
 
724
    case MY_LEX_IDENT_OR_BIN:
 
725
      if (lip->yyPeek() == '\'')
 
726
      {                                 // Found b'bin-number'
 
727
        state= MY_LEX_BIN_NUMBER;
 
728
        break;
 
729
      }
 
730
    case MY_LEX_IDENT:
 
731
      const char *start;
 
732
      if (use_mb(cs))
 
733
      {
 
734
        result_state= IDENT_QUOTED;
 
735
        if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
 
736
        {
 
737
          int l = my_ismbchar(cs,
 
738
                              lip->get_ptr() -1,
 
739
                              lip->get_end_of_query());
 
740
          if (l == 0) {
 
741
            state = MY_LEX_CHAR;
 
742
            continue;
 
743
          }
 
744
          lip->skip_binary(l - 1);
 
745
        }
 
746
        while (ident_map[c=lip->yyGet()])
 
747
        {
 
748
          if (my_mbcharlen(cs, c) > 1)
 
749
          {
 
750
            int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
751
            if (l == 0)
 
752
              break;
 
753
            lip->skip_binary(l-1);
 
754
          }
 
755
        }
 
756
      }
 
757
      else
 
758
      {
 
759
        for (result_state= c; ident_map[c= lip->yyGet()]; result_state|= c) {};
 
760
        /* If there were non-ASCII characters, mark that we must convert */
 
761
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
 
762
      }
 
763
      length= lip->yyLength();
 
764
      start= lip->get_ptr();
 
765
      if (lip->ignore_space)
 
766
      {
 
767
        /*
 
768
          If we find a space then this can't be an identifier. We notice this
 
769
          below by checking start != lex->ptr.
 
770
        */
 
771
        for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
 
772
      }
 
773
      if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
 
774
              lip->next_state=MY_LEX_IDENT_SEP;
 
775
      else
 
776
      {                                 // '(' must follow directly if function
 
777
        lip->yyUnget();
 
778
        if ((tokval = find_keyword(lip, length, c == '(')))
 
779
        {
 
780
          lip->next_state= MY_LEX_START;        // Allow signed numbers
 
781
          return(tokval);               // Was keyword
 
782
        }
 
783
        lip->yySkip();                  // next state does a unget
 
784
      }
 
785
      yylval->lex_str=get_token(lip, 0, length);
 
786
 
 
787
      lip->body_utf8_append(lip->m_cpp_text_start);
 
788
 
 
789
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
 
790
 
 
791
      return(result_state);                     // IDENT or IDENT_QUOTED
 
792
 
 
793
    case MY_LEX_IDENT_SEP:              // Found ident and now '.'
 
794
      yylval->lex_str.str= (char*) lip->get_ptr();
 
795
      yylval->lex_str.length= 1;
 
796
      c= lip->yyGet();                  // should be '.'
 
797
      lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
 
798
      if (!ident_map[(uint8_t)lip->yyPeek()])            // Probably ` or "
 
799
        lip->next_state= MY_LEX_START;
 
800
      return((int) c);
 
801
 
 
802
    case MY_LEX_NUMBER_IDENT:           // number or ident which num-start
 
803
      if (lip->yyGetLast() == '0')
 
804
      {
 
805
        c= lip->yyGet();
 
806
        if (c == 'x')
 
807
        {
 
808
          while (my_isxdigit(cs,(c = lip->yyGet()))) ;
 
809
          if ((lip->yyLength() >= 3) && !ident_map[c])
 
810
          {
 
811
            /* skip '0x' */
 
812
            yylval->lex_str=get_token(lip, 2, lip->yyLength()-2);
 
813
            return (HEX_NUM);
 
814
          }
 
815
          lip->yyUnget();
 
816
          state= MY_LEX_IDENT_START;
 
817
          break;
 
818
        }
 
819
        else if (c == 'b')
 
820
        {
 
821
          while ((c= lip->yyGet()) == '0' || c == '1') {};
 
822
          if ((lip->yyLength() >= 3) && !ident_map[c])
 
823
          {
 
824
            /* Skip '0b' */
 
825
            yylval->lex_str= get_token(lip, 2, lip->yyLength()-2);
 
826
            return (BIN_NUM);
 
827
          }
 
828
          lip->yyUnget();
 
829
          state= MY_LEX_IDENT_START;
 
830
          break;
 
831
        }
 
832
        lip->yyUnget();
 
833
      }
 
834
 
 
835
      while (my_isdigit(cs, (c = lip->yyGet()))) ;
 
836
      if (!ident_map[c])
 
837
      {                                 // Can't be identifier
 
838
        state=MY_LEX_INT_OR_REAL;
 
839
        break;
 
840
      }
 
841
      if (c == 'e' || c == 'E')
 
842
      {
 
843
        // The following test is written this way to allow numbers of type 1e1
 
844
        if (my_isdigit(cs,lip->yyPeek()) ||
 
845
            (c=(lip->yyGet())) == '+' || c == '-')
 
846
        {                               // Allow 1E+10
 
847
          if (my_isdigit(cs,lip->yyPeek()))     // Number must have digit after sign
 
848
          {
 
849
            lip->yySkip();
 
850
            while (my_isdigit(cs,lip->yyGet())) ;
 
851
            yylval->lex_str=get_token(lip, 0, lip->yyLength());
 
852
            return(FLOAT_NUM);
 
853
          }
 
854
        }
 
855
        lip->yyUnget();
 
856
      }
 
857
      // fall through
 
858
    case MY_LEX_IDENT_START:                    // We come here after '.'
 
859
      result_state= IDENT;
 
860
      if (use_mb(cs))
 
861
      {
 
862
        result_state= IDENT_QUOTED;
 
863
        while (ident_map[c=lip->yyGet()])
 
864
        {
 
865
          if (my_mbcharlen(cs, c) > 1)
 
866
          {
 
867
            int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
 
868
            if (l == 0)
 
869
              break;
 
870
            lip->skip_binary(l-1);
 
871
          }
 
872
        }
 
873
      }
 
874
      else
 
875
      {
 
876
        for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c) {};
 
877
        /* If there were non-ASCII characters, mark that we must convert */
 
878
        result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
 
879
      }
 
880
      if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
 
881
        lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
 
882
 
 
883
      yylval->lex_str= get_token(lip, 0, lip->yyLength());
 
884
 
 
885
      lip->body_utf8_append(lip->m_cpp_text_start);
 
886
 
 
887
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
 
888
 
 
889
      return(result_state);
 
890
 
 
891
    case MY_LEX_USER_VARIABLE_DELIMITER:        // Found quote char
 
892
    {
 
893
      uint32_t double_quotes= 0;
 
894
      char quote_char= c;                       // Used char
 
895
      while ((c=lip->yyGet()))
 
896
      {
 
897
        int var_length;
 
898
        if ((var_length= my_mbcharlen(cs, c)) == 1)
 
899
        {
 
900
          if (c == quote_char)
 
901
          {
 
902
                  if (lip->yyPeek() != quote_char)
 
903
              break;
 
904
                  c=lip->yyGet();
 
905
            double_quotes++;
 
906
            continue;
 
907
          }
 
908
        }
 
909
        else if (var_length < 1)
 
910
          break;                                // Error
 
911
        lip->skip_binary(var_length-1);
 
912
      }
 
913
      if (double_quotes)
 
914
              yylval->lex_str=get_quoted_token(lip, 1, lip->yyLength() - double_quotes -1, quote_char);
 
915
      else
 
916
        yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
 
917
      if (c == quote_char)
 
918
        lip->yySkip();                  // Skip end `
 
919
      lip->next_state= MY_LEX_START;
 
920
      lip->body_utf8_append(lip->m_cpp_text_start);
 
921
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
 
922
      return(IDENT_QUOTED);
 
923
    }
 
924
    case MY_LEX_INT_OR_REAL:            // Complete int or incomplete real
 
925
      if (c != '.')
 
926
      {                                 // Found complete integer number.
 
927
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
 
928
        return int_token(yylval->lex_str.str,yylval->lex_str.length);
 
929
      }
 
930
      // fall through
 
931
    case MY_LEX_REAL:                   // Incomplete real number
 
932
      while (my_isdigit(cs,c = lip->yyGet())) ;
 
933
 
 
934
      if (c == 'e' || c == 'E')
 
935
      {
 
936
        c = lip->yyGet();
 
937
        if (c == '-' || c == '+')
 
938
                c = lip->yyGet();                     // Skip sign
 
939
        if (!my_isdigit(cs,c))
 
940
        {                               // No digit after sign
 
941
          state= MY_LEX_CHAR;
 
942
          break;
 
943
        }
 
944
        while (my_isdigit(cs,lip->yyGet())) ;
 
945
        yylval->lex_str=get_token(lip, 0, lip->yyLength());
 
946
        return(FLOAT_NUM);
 
947
      }
 
948
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
 
949
      return(DECIMAL_NUM);
 
950
 
 
951
    case MY_LEX_HEX_NUMBER:             // Found x'hexstring'
 
952
      lip->yySkip();                    // Accept opening '
 
953
      while (my_isxdigit(cs, (c= lip->yyGet()))) ;
 
954
      if (c != '\'')
 
955
        return(ABORT_SYM);              // Illegal hex constant
 
956
      lip->yySkip();                    // Accept closing '
 
957
      length= lip->yyLength();          // Length of hexnum+3
 
958
      if ((length % 2) == 0)
 
959
        return(ABORT_SYM);              // odd number of hex digits
 
960
      yylval->lex_str=get_token(lip,
 
961
                                2,          // skip x'
 
962
                                length-3);  // don't count x' and last '
 
963
      return (HEX_NUM);
 
964
 
 
965
    case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
 
966
      lip->yySkip();                  // Accept opening '
 
967
      while ((c= lip->yyGet()) == '0' || c == '1') {};
 
968
      if (c != '\'')
 
969
        return(ABORT_SYM);            // Illegal hex constant
 
970
      lip->yySkip();                  // Accept closing '
 
971
      length= lip->yyLength();        // Length of bin-num + 3
 
972
      yylval->lex_str= get_token(lip,
 
973
                                 2,         // skip b'
 
974
                                 length-3); // don't count b' and last '
 
975
      return (BIN_NUM);
 
976
 
 
977
    case MY_LEX_CMP_OP:                 // Incomplete comparison operator
 
978
      if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
 
979
          state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
 
980
        lip->yySkip();
 
981
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
 
982
      {
 
983
        lip->next_state= MY_LEX_START;  // Allow signed numbers
 
984
        return(tokval);
 
985
      }
 
986
      state = MY_LEX_CHAR;              // Something fishy found
 
987
      break;
 
988
 
 
989
    case MY_LEX_LONG_CMP_OP:            // Incomplete comparison operator
 
990
      if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
 
991
          state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
 
992
      {
 
993
        lip->yySkip();
 
994
        if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP)
 
995
          lip->yySkip();
 
996
      }
 
997
      if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
 
998
      {
 
999
        lip->next_state= MY_LEX_START;  // Found long op
 
1000
        return(tokval);
 
1001
      }
 
1002
      state = MY_LEX_CHAR;              // Something fishy found
 
1003
      break;
 
1004
 
 
1005
    case MY_LEX_BOOL:
 
1006
      if (c != lip->yyPeek())
 
1007
      {
 
1008
        state=MY_LEX_CHAR;
 
1009
        break;
 
1010
      }
 
1011
      lip->yySkip();
 
1012
      tokval = find_keyword(lip,2,0);   // Is a bool operator
 
1013
      lip->next_state= MY_LEX_START;    // Allow signed numbers
 
1014
      return(tokval);
 
1015
 
 
1016
    case MY_LEX_STRING_OR_DELIMITER:
 
1017
      if (0)
 
1018
      {
 
1019
        state= MY_LEX_USER_VARIABLE_DELIMITER;
 
1020
        break;
 
1021
      }
 
1022
      /* " used for strings */
 
1023
    case MY_LEX_STRING:                 // Incomplete text string
 
1024
      if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
 
1025
      {
 
1026
        state= MY_LEX_CHAR;             // Read char by char
 
1027
        break;
 
1028
      }
 
1029
      yylval->lex_str.length=lip->yytoklen;
 
1030
 
 
1031
      lip->body_utf8_append(lip->m_cpp_text_start);
 
1032
 
 
1033
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
 
1034
 
 
1035
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
 
1036
      return(TEXT_STRING);
 
1037
 
 
1038
    case MY_LEX_COMMENT:                        //  Comment
 
1039
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
 
1040
      while ((c = lip->yyGet()) != '\n' && c) ;
 
1041
      lip->yyUnget();                   // Safety against eof
 
1042
      state = MY_LEX_START;             // Try again
 
1043
      break;
 
1044
    case MY_LEX_LONG_COMMENT:           /* Long C comment? */
 
1045
      if (lip->yyPeek() != '*')
 
1046
      {
 
1047
        state=MY_LEX_CHAR;              // Probable division
 
1048
        break;
 
1049
      }
 
1050
      lex->select_lex.options|= OPTION_FOUND_COMMENT;
 
1051
      /* Reject '/' '*', since we might need to turn off the echo */
 
1052
      lip->yyUnget();
 
1053
 
 
1054
      if (lip->yyPeekn(2) == '!')
 
1055
      {
 
1056
        lip->in_comment= DISCARD_COMMENT;
 
1057
        /* Accept '/' '*' '!', but do not keep this marker. */
 
1058
        lip->set_echo(false);
 
1059
        lip->yySkip();
 
1060
        lip->yySkip();
 
1061
        lip->yySkip();
 
1062
 
 
1063
        /*
 
1064
          The special comment format is very strict:
 
1065
          '/' '*' '!', followed by digits ended by a non-digit.
 
1066
          There must be at least 5 digits for it to count
 
1067
        */
 
1068
        const int MAX_VERSION_SIZE= 16;
 
1069
        char version_str[MAX_VERSION_SIZE];
 
1070
 
 
1071
        int pos= 0;
 
1072
        do
 
1073
        {
 
1074
          version_str[pos]= lip->yyPeekn(pos);
 
1075
          pos++;
 
1076
        } while ((pos < MAX_VERSION_SIZE-1) && isdigit(version_str[pos-1]));
 
1077
        version_str[pos]= 0;
 
1078
 
 
1079
        /* To keep some semblance of compatibility, we impose a 5 digit floor */
 
1080
        if (pos > 4)
 
1081
        {
 
1082
          uint64_t version;
 
1083
          version=strtoll(version_str, NULL, 10);
 
1084
 
 
1085
          /* Accept 'M' 'm' 'm' 'd' 'd' */
 
1086
          lip->yySkipn(pos-1);
 
1087
 
 
1088
          if (version <= DRIZZLE_VERSION_ID)
 
1089
          {
 
1090
            /* Expand the content of the special comment as real code */
 
1091
            lip->set_echo(true);
 
1092
            state=MY_LEX_START;
 
1093
            break;
 
1094
          }
 
1095
        }
 
1096
        else
 
1097
        {
 
1098
          state=MY_LEX_START;
 
1099
          lip->set_echo(true);
 
1100
          break;
 
1101
        }
 
1102
      }
 
1103
      else
 
1104
      {
 
1105
        lip->in_comment= PRESERVE_COMMENT;
 
1106
        lip->yySkip();                  // Accept /
 
1107
        lip->yySkip();                  // Accept *
 
1108
      }
 
1109
      /*
 
1110
        Discard:
 
1111
        - regular '/' '*' comments,
 
1112
        - special comments '/' '*' '!' for a future version,
 
1113
        by scanning until we find a closing '*' '/' marker.
 
1114
        Note: There is no such thing as nesting comments,
 
1115
        the first '*' '/' sequence seen will mark the end.
 
1116
      */
 
1117
      comment_closed= false;
 
1118
      while (! lip->eof())
 
1119
      {
 
1120
        c= lip->yyGet();
 
1121
        if (c == '*')
 
1122
        {
 
1123
          if (lip->yyPeek() == '/')
 
1124
          {
 
1125
            lip->yySkip();
 
1126
            comment_closed= true;
 
1127
            state = MY_LEX_START;
 
1128
            break;
 
1129
          }
 
1130
        }
 
1131
        else if (c == '\n')
 
1132
          lip->yylineno++;
 
1133
      }
 
1134
      /* Unbalanced comments with a missing '*' '/' are a syntax error */
 
1135
      if (! comment_closed)
 
1136
        return (ABORT_SYM);
 
1137
      state = MY_LEX_START;             // Try again
 
1138
      lip->in_comment= NO_COMMENT;
 
1139
      lip->set_echo(true);
 
1140
      break;
 
1141
    case MY_LEX_END_LONG_COMMENT:
 
1142
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
 
1143
      {
 
1144
        /* Reject '*' '/' */
 
1145
        lip->yyUnget();
 
1146
        /* Accept '*' '/', with the proper echo */
 
1147
        lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
 
1148
        lip->yySkipn(2);
 
1149
        /* And start recording the tokens again */
 
1150
        lip->set_echo(true);
 
1151
        lip->in_comment=NO_COMMENT;
 
1152
        state=MY_LEX_START;
 
1153
      }
 
1154
      else
 
1155
        state=MY_LEX_CHAR;              // Return '*'
 
1156
      break;
 
1157
    case MY_LEX_SET_VAR:                // Check if ':='
 
1158
      if (lip->yyPeek() != '=')
 
1159
      {
 
1160
        state=MY_LEX_CHAR;              // Return ':'
 
1161
        break;
 
1162
      }
 
1163
      lip->yySkip();
 
1164
      return (SET_VAR);
 
1165
    case MY_LEX_SEMICOLON:                      // optional line terminator
 
1166
      if (lip->yyPeek())
 
1167
      {
 
1168
        state= MY_LEX_CHAR;             // Return ';'
 
1169
        break;
 
1170
      }
 
1171
      lip->next_state=MY_LEX_END;       // Mark for next loop
 
1172
      return(END_OF_INPUT);
 
1173
    case MY_LEX_EOL:
 
1174
      if (lip->eof())
 
1175
      {
 
1176
        lip->yyUnget();                 // Reject the last '\0'
 
1177
        lip->set_echo(false);
 
1178
        lip->yySkip();
 
1179
        lip->set_echo(true);
 
1180
        /* Unbalanced comments with a missing '*' '/' are a syntax error */
 
1181
        if (lip->in_comment != NO_COMMENT)
 
1182
          return (ABORT_SYM);
 
1183
        lip->next_state=MY_LEX_END;     // Mark for next loop
 
1184
        return(END_OF_INPUT);
 
1185
      }
 
1186
      state=MY_LEX_CHAR;
 
1187
      break;
 
1188
    case MY_LEX_END:
 
1189
      lip->next_state=MY_LEX_END;
 
1190
      return false;                     // We found end of input last time
 
1191
 
 
1192
      /* Actually real shouldn't start with . but allow them anyhow */
 
1193
    case MY_LEX_REAL_OR_POINT:
 
1194
      if (my_isdigit(cs,lip->yyPeek()))
 
1195
        state= MY_LEX_REAL;             // Real
 
1196
      else
 
1197
      {
 
1198
        state= MY_LEX_IDENT_SEP;        // return '.'
 
1199
        lip->yyUnget();                 // Put back '.'
 
1200
      }
 
1201
      break;
 
1202
    case MY_LEX_USER_END:               // end '@' of user@hostname
 
1203
      switch (state_map[(uint8_t)lip->yyPeek()]) {
 
1204
      case MY_LEX_STRING:
 
1205
      case MY_LEX_USER_VARIABLE_DELIMITER:
 
1206
      case MY_LEX_STRING_OR_DELIMITER:
 
1207
        break;
 
1208
      case MY_LEX_USER_END:
 
1209
        lip->next_state=MY_LEX_SYSTEM_VAR;
 
1210
        break;
 
1211
      default:
 
1212
        lip->next_state=MY_LEX_HOSTNAME;
 
1213
        break;
 
1214
      }
 
1215
      yylval->lex_str.str=(char*) lip->get_ptr();
 
1216
      yylval->lex_str.length=1;
 
1217
      return((int) '@');
 
1218
    case MY_LEX_HOSTNAME:               // end '@' of user@hostname
 
1219
      for (c=lip->yyGet() ;
 
1220
           my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
 
1221
           c= lip->yyGet()) ;
 
1222
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
 
1223
      return(LEX_HOSTNAME);
 
1224
    case MY_LEX_SYSTEM_VAR:
 
1225
      yylval->lex_str.str=(char*) lip->get_ptr();
 
1226
      yylval->lex_str.length=1;
 
1227
      lip->yySkip();                                    // Skip '@'
 
1228
      lip->next_state= (state_map[(uint8_t)lip->yyPeek()] ==
 
1229
                        MY_LEX_USER_VARIABLE_DELIMITER ?
 
1230
                        MY_LEX_OPERATOR_OR_IDENT :
 
1231
                        MY_LEX_IDENT_OR_KEYWORD);
 
1232
      return((int) '@');
 
1233
    case MY_LEX_IDENT_OR_KEYWORD:
 
1234
      /*
 
1235
        We come here when we have found two '@' in a row.
 
1236
        We should now be able to handle:
 
1237
        [(global | local | session) .]variable_name
 
1238
      */
 
1239
 
 
1240
      for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
 
1241
      /* If there were non-ASCII characters, mark that we must convert */
 
1242
      result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
 
1243
 
 
1244
      if (c == '.')
 
1245
        lip->next_state=MY_LEX_IDENT_SEP;
 
1246
      length= lip->yyLength();
 
1247
      if (length == 0)
 
1248
        return(ABORT_SYM);              // Names must be nonempty.
 
1249
      if ((tokval= find_keyword(lip, length,0)))
 
1250
      {
 
1251
        lip->yyUnget();                         // Put back 'c'
 
1252
        return(tokval);                         // Was keyword
 
1253
      }
 
1254
      yylval->lex_str=get_token(lip, 0, length);
 
1255
 
 
1256
      lip->body_utf8_append(lip->m_cpp_text_start);
 
1257
 
 
1258
      lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
 
1259
 
 
1260
      return(result_state);
 
1261
    }
 
1262
  }
 
1263
}
 
1264
 
 
1265
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
 
1266
{
 
1267
  /*
 
1268
    TODO:
 
1269
    This code assumes that there are no multi-bytes characters
 
1270
    that can be considered white-space.
 
1271
  */
 
1272
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
 
1273
  {
 
1274
    str->length--;
 
1275
    str->str++;
 
1276
  }
 
1277
 
 
1278
  /*
 
1279
    FIXME:
 
1280
    Also, parsing backward is not safe with multi bytes characters
 
1281
  */
 
1282
  while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
 
1283
  {
 
1284
    str->length--;
 
1285
  }
 
1286
}
 
1287
 
 
1288
/*
 
1289
  Select_Lex structures initialisations
 
1290
*/
 
1291
void Select_Lex_Node::init_query()
 
1292
{
 
1293
  options= 0;
 
1294
  linkage= UNSPECIFIED_TYPE;
 
1295
  no_error= no_table_names_allowed= 0;
 
1296
  uncacheable= 0;
 
1297
}
 
1298
 
 
1299
void Select_Lex_Node::init_select()
 
1300
{
 
1301
}
 
1302
 
 
1303
void Select_Lex_Unit::init_query()
 
1304
{
 
1305
  Select_Lex_Node::init_query();
 
1306
  linkage= GLOBAL_OPTIONS_TYPE;
 
1307
  global_parameters= first_select();
 
1308
  select_limit_cnt= HA_POS_ERROR;
 
1309
  offset_limit_cnt= 0;
 
1310
  union_distinct= 0;
 
1311
  prepared= optimized= executed= 0;
 
1312
  item= 0;
 
1313
  union_result= 0;
 
1314
  table= 0;
 
1315
  fake_select_lex= 0;
 
1316
  cleaned= 0;
 
1317
  item_list.empty();
 
1318
  describe= 0;
 
1319
  found_rows_for_union= 0;
 
1320
}
 
1321
 
 
1322
void Select_Lex::init_query()
 
1323
{
 
1324
  Select_Lex_Node::init_query();
 
1325
  table_list.empty();
 
1326
  top_join_list.empty();
 
1327
  join_list= &top_join_list;
 
1328
  embedding= leaf_tables= 0;
 
1329
  item_list.empty();
 
1330
  join= 0;
 
1331
  having= where= 0;
 
1332
  olap= UNSPECIFIED_OLAP_TYPE;
 
1333
  having_fix_field= 0;
 
1334
  context.select_lex= this;
 
1335
  context.init();
 
1336
  /*
 
1337
    Add the name resolution context of the current (sub)query to the
 
1338
    stack of contexts for the whole query.
 
1339
    TODO:
 
1340
    push_context may return an error if there is no memory for a new
 
1341
    element in the stack, however this method has no return value,
 
1342
    thus push_context should be moved to a place where query
 
1343
    initialization is checked for failure.
 
1344
  */
 
1345
  parent_lex->push_context(&context);
 
1346
  cond_count= between_count= with_wild= 0;
 
1347
  max_equal_elems= 0;
 
1348
  ref_pointer_array= 0;
 
1349
  select_n_where_fields= 0;
 
1350
  select_n_having_items= 0;
 
1351
  subquery_in_having= explicit_limit= 0;
 
1352
  is_item_list_lookup= 0;
 
1353
  parsing_place= NO_MATTER;
 
1354
  exclude_from_table_unique_test= false;
 
1355
  nest_level= 0;
 
1356
  link_next= 0;
 
1357
}
 
1358
 
 
1359
void Select_Lex::init_select()
 
1360
{
 
1361
  sj_nests.empty();
 
1362
  group_list.empty();
 
1363
  db= 0;
 
1364
  having= 0;
 
1365
  table_join_options= 0;
 
1366
  in_sum_expr= with_wild= 0;
 
1367
  options= 0;
 
1368
  braces= 0;
 
1369
  interval_list.empty();
 
1370
  inner_sum_func_list= 0;
 
1371
  linkage= UNSPECIFIED_TYPE;
 
1372
  order_list.elements= 0;
 
1373
  order_list.first= 0;
 
1374
  order_list.next= (unsigned char**) &order_list.first;
 
1375
  /* Set limit and offset to default values */
 
1376
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
 
1377
  offset_limit= 0;      /* denotes the default offset = 0 */
 
1378
  with_sum_func= 0;
 
1379
  is_correlated= 0;
 
1380
  cur_pos_in_select_list= UNDEF_POS;
 
1381
  non_agg_fields.empty();
 
1382
  cond_value= having_value= Item::COND_UNDEF;
 
1383
  inner_refs_list.empty();
 
1384
  full_group_by_flag.reset();
 
1385
}
 
1386
 
 
1387
/*
 
1388
  Select_Lex structures linking
 
1389
*/
 
1390
 
 
1391
/* include on level down */
 
1392
void Select_Lex_Node::include_down(Select_Lex_Node *upper)
 
1393
{
 
1394
  if ((next= upper->slave))
 
1395
    next->prev= &next;
 
1396
  prev= &upper->slave;
 
1397
  upper->slave= this;
 
1398
  master= upper;
 
1399
  slave= 0;
 
1400
}
 
1401
 
 
1402
/*
 
1403
  include on level down (but do not link)
 
1404
 
 
1405
  SYNOPSYS
 
1406
    Select_Lex_Node::include_standalone()
 
1407
    upper - reference on node underr which this node should be included
 
1408
    ref - references on reference on this node
 
1409
*/
 
1410
void Select_Lex_Node::include_standalone(Select_Lex_Node *upper,
 
1411
                                            Select_Lex_Node **ref)
 
1412
{
 
1413
  next= 0;
 
1414
  prev= ref;
 
1415
  master= upper;
 
1416
  slave= 0;
 
1417
}
 
1418
 
 
1419
/* include neighbour (on same level) */
 
1420
void Select_Lex_Node::include_neighbour(Select_Lex_Node *before)
 
1421
{
 
1422
  if ((next= before->next))
 
1423
    next->prev= &next;
 
1424
  prev= &before->next;
 
1425
  before->next= this;
 
1426
  master= before->master;
 
1427
  slave= 0;
 
1428
}
 
1429
 
 
1430
/* including in global Select_Lex list */
 
1431
void Select_Lex_Node::include_global(Select_Lex_Node **plink)
 
1432
{
 
1433
  if ((link_next= *plink))
 
1434
    link_next->link_prev= &link_next;
 
1435
  link_prev= plink;
 
1436
  *plink= this;
 
1437
}
 
1438
 
 
1439
//excluding from global list (internal function)
 
1440
void Select_Lex_Node::fast_exclude()
 
1441
{
 
1442
  if (link_prev)
 
1443
  {
 
1444
    if ((*link_prev= link_next))
 
1445
      link_next->link_prev= link_prev;
 
1446
  }
 
1447
  // Remove slave structure
 
1448
  for (; slave; slave= slave->next)
 
1449
    slave->fast_exclude();
 
1450
 
 
1451
}
 
1452
 
 
1453
/*
 
1454
  excluding select_lex structure (except first (first select can't be
 
1455
  deleted, because it is most upper select))
 
1456
*/
 
1457
void Select_Lex_Node::exclude()
 
1458
{
 
1459
  //exclude from global list
 
1460
  fast_exclude();
 
1461
  //exclude from other structures
 
1462
  if ((*prev= next))
 
1463
    next->prev= prev;
 
1464
  /*
 
1465
     We do not need following statements, because prev pointer of first
 
1466
     list element point to master->slave
 
1467
     if (master->slave == this)
 
1468
       master->slave= next;
 
1469
  */
 
1470
}
 
1471
 
 
1472
 
 
1473
/*
 
1474
  Exclude level of current unit from tree of SELECTs
 
1475
 
 
1476
  SYNOPSYS
 
1477
    Select_Lex_Unit::exclude_level()
 
1478
 
 
1479
  NOTE: units which belong to current will be brought up on level of
 
1480
  currernt unit
 
1481
*/
 
1482
void Select_Lex_Unit::exclude_level()
 
1483
{
 
1484
  Select_Lex_Unit *units= 0, **units_last= &units;
 
1485
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
1486
  {
 
1487
    // unlink current level from global SELECTs list
 
1488
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
 
1489
      sl->link_next->link_prev= sl->link_prev;
 
1490
 
 
1491
    // bring up underlay levels
 
1492
    Select_Lex_Unit **last= 0;
 
1493
    for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
 
1494
    {
 
1495
      u->master= master;
 
1496
      last= (Select_Lex_Unit**)&(u->next);
 
1497
    }
 
1498
    if (last)
 
1499
    {
 
1500
      (*units_last)= sl->first_inner_unit();
 
1501
      units_last= last;
 
1502
    }
 
1503
  }
 
1504
  if (units)
 
1505
  {
 
1506
    // include brought up levels in place of current
 
1507
    (*prev)= units;
 
1508
    (*units_last)= (Select_Lex_Unit*)next;
 
1509
    if (next)
 
1510
      next->prev= (Select_Lex_Node**)units_last;
 
1511
    units->prev= prev;
 
1512
  }
 
1513
  else
 
1514
  {
 
1515
    // exclude currect unit from list of nodes
 
1516
    (*prev)= next;
 
1517
    if (next)
 
1518
      next->prev= prev;
 
1519
  }
 
1520
}
 
1521
 
 
1522
/*
 
1523
  Exclude subtree of current unit from tree of SELECTs
 
1524
*/
 
1525
void Select_Lex_Unit::exclude_tree()
 
1526
{
 
1527
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
1528
  {
 
1529
    // unlink current level from global SELECTs list
 
1530
    if (sl->link_prev && (*sl->link_prev= sl->link_next))
 
1531
      sl->link_next->link_prev= sl->link_prev;
 
1532
 
 
1533
    // unlink underlay levels
 
1534
    for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
 
1535
    {
 
1536
      u->exclude_level();
 
1537
    }
 
1538
  }
 
1539
  // exclude currect unit from list of nodes
 
1540
  (*prev)= next;
 
1541
  if (next)
 
1542
    next->prev= prev;
 
1543
}
 
1544
 
 
1545
/**
 
1546
 * Mark all Select_Lex struct from this to 'last' as dependent
 
1547
 *
 
1548
 * @param Pointer to last Select_Lex struct, before wich all
 
1549
 *        Select_Lex have to be marked as dependent
 
1550
 * @note 'last' should be reachable from this Select_Lex_Node
 
1551
 */
 
1552
void Select_Lex::mark_as_dependent(Select_Lex *last)
 
1553
{
 
1554
  /*
 
1555
    Mark all selects from resolved to 1 before select where was
 
1556
    found table as depended (of select where was found table)
 
1557
  */
 
1558
  for (Select_Lex *s= this;
 
1559
       s && s != last;
 
1560
       s= s->outer_select())
 
1561
  {
 
1562
    if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
 
1563
    {
 
1564
      // Select is dependent of outer select
 
1565
      s->uncacheable= (s->uncacheable & ~UNCACHEABLE_UNITED) |
 
1566
                       UNCACHEABLE_DEPENDENT;
 
1567
      Select_Lex_Unit *munit= s->master_unit();
 
1568
      munit->uncacheable= (munit->uncacheable & ~UNCACHEABLE_UNITED) |
 
1569
                       UNCACHEABLE_DEPENDENT;
 
1570
      for (Select_Lex *sl= munit->first_select(); sl ; sl= sl->next_select())
 
1571
      {
 
1572
        if (sl != s &&
 
1573
            !(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
 
1574
          sl->uncacheable|= UNCACHEABLE_UNITED;
 
1575
      }
 
1576
    }
 
1577
    s->is_correlated= true;
 
1578
    Item_subselect *subquery_predicate= s->master_unit()->item;
 
1579
    if (subquery_predicate)
 
1580
      subquery_predicate->is_correlated= true;
 
1581
  }
 
1582
}
 
1583
 
 
1584
bool Select_Lex_Node::set_braces(bool)
 
1585
{ return true; }
 
1586
 
 
1587
bool Select_Lex_Node::inc_in_sum_expr()
 
1588
{ return true; }
 
1589
 
 
1590
uint32_t Select_Lex_Node::get_in_sum_expr() 
 
1591
{ return 0; }
 
1592
 
 
1593
TableList* Select_Lex_Node::get_table_list()
 
1594
{ return NULL; }
 
1595
 
 
1596
List<Item>* Select_Lex_Node::get_item_list()
 
1597
{ return NULL; }
 
1598
 
 
1599
TableList *Select_Lex_Node::add_table_to_list (Session *, Table_ident *, LEX_STRING *, uint32_t,
 
1600
                                                  thr_lock_type, List<Index_hint> *, LEX_STRING *)
 
1601
{
 
1602
  return 0;
 
1603
}
 
1604
 
 
1605
uint32_t Select_Lex_Node::get_table_join_options()
 
1606
{
 
1607
  return 0;
 
1608
}
 
1609
 
 
1610
/*
 
1611
  prohibit using LIMIT clause
 
1612
*/
 
1613
bool Select_Lex::test_limit()
 
1614
{
 
1615
  if (select_limit != 0)
 
1616
  {
 
1617
    my_error(ER_NOT_SUPPORTED_YET, MYF(0),
 
1618
             "LIMIT & IN/ALL/ANY/SOME subquery");
 
1619
    return true;
 
1620
  }
 
1621
  return false;
 
1622
}
 
1623
 
 
1624
Select_Lex_Unit* Select_Lex_Unit::master_unit()
 
1625
{
 
1626
  return this;
 
1627
}
 
1628
 
 
1629
Select_Lex* Select_Lex_Unit::outer_select()
 
1630
{
 
1631
  return (Select_Lex*) master;
 
1632
}
 
1633
 
 
1634
bool Select_Lex::add_order_to_list(Session *session, Item *item, bool asc)
 
1635
{
 
1636
  return add_to_list(session, order_list, item, asc);
 
1637
}
 
1638
 
 
1639
bool Select_Lex::add_item_to_list(Session *, Item *item)
 
1640
{
 
1641
  return(item_list.push_back(item));
 
1642
}
 
1643
 
 
1644
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
 
1645
{
 
1646
  return add_to_list(session, group_list, item, asc);
 
1647
}
 
1648
 
 
1649
Select_Lex_Unit* Select_Lex::master_unit()
 
1650
{
 
1651
  return (Select_Lex_Unit*) master;
 
1652
}
 
1653
 
 
1654
Select_Lex* Select_Lex::outer_select()
 
1655
{
 
1656
  return (Select_Lex*) master->get_master();
 
1657
}
 
1658
 
 
1659
bool Select_Lex::set_braces(bool value)
 
1660
{
 
1661
  braces= value;
 
1662
  return false;
 
1663
}
 
1664
 
 
1665
bool Select_Lex::inc_in_sum_expr()
 
1666
{
 
1667
  in_sum_expr++;
 
1668
  return false;
 
1669
}
 
1670
 
 
1671
uint32_t Select_Lex::get_in_sum_expr()
 
1672
{
 
1673
  return in_sum_expr;
 
1674
}
 
1675
 
 
1676
TableList* Select_Lex::get_table_list()
 
1677
{
 
1678
  return (TableList*) table_list.first;
 
1679
}
 
1680
 
 
1681
List<Item>* Select_Lex::get_item_list()
 
1682
{
 
1683
  return &item_list;
 
1684
}
 
1685
 
 
1686
uint32_t Select_Lex::get_table_join_options()
 
1687
{
 
1688
  return table_join_options;
 
1689
}
 
1690
 
 
1691
bool Select_Lex::setup_ref_array(Session *session, uint32_t order_group_num)
 
1692
{
 
1693
  if (ref_pointer_array)
 
1694
    return false;
 
1695
 
 
1696
  return (ref_pointer_array=
 
1697
          (Item **)session->alloc(sizeof(Item*) * (n_child_sum_items +
 
1698
                                                 item_list.elements +
 
1699
                                                 select_n_having_items +
 
1700
                                                 select_n_where_fields +
 
1701
                                                 order_group_num)*5)) == 0;
 
1702
}
 
1703
 
 
1704
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
 
1705
{
 
1706
  bool union_all= !union_distinct;
 
1707
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
 
1708
  {
 
1709
    if (sl != first_select())
 
1710
    {
 
1711
      str->append(STRING_WITH_LEN(" union "));
 
1712
      if (union_all)
 
1713
        str->append(STRING_WITH_LEN("all "));
 
1714
      else if (union_distinct == sl)
 
1715
        union_all= true;
 
1716
    }
 
1717
    if (sl->braces)
 
1718
      str->append('(');
 
1719
    sl->print(session, str, query_type);
 
1720
    if (sl->braces)
 
1721
      str->append(')');
 
1722
  }
 
1723
  if (fake_select_lex == global_parameters)
 
1724
  {
 
1725
    if (fake_select_lex->order_list.elements)
 
1726
    {
 
1727
      str->append(STRING_WITH_LEN(" order by "));
 
1728
      fake_select_lex->print_order(
 
1729
        str,
 
1730
        (order_st *) fake_select_lex->order_list.first,
 
1731
        query_type);
 
1732
    }
 
1733
    fake_select_lex->print_limit(session, str, query_type);
 
1734
  }
 
1735
}
 
1736
 
 
1737
void Select_Lex::print_order(String *str,
 
1738
                                order_st *order,
 
1739
                                enum_query_type query_type)
 
1740
{
 
1741
  for (; order; order= order->next)
 
1742
  {
 
1743
    if (order->counter_used)
 
1744
    {
 
1745
      char buffer[20];
 
1746
      uint32_t length= snprintf(buffer, 20, "%d", order->counter);
 
1747
      str->append(buffer, length);
 
1748
    }
 
1749
    else
 
1750
      (*order->item)->print(str, query_type);
 
1751
    if (!order->asc)
 
1752
      str->append(STRING_WITH_LEN(" desc"));
 
1753
    if (order->next)
 
1754
      str->append(',');
 
1755
  }
 
1756
}
 
1757
 
 
1758
void Select_Lex::print_limit(Session *, String *str,
 
1759
                                enum_query_type query_type)
 
1760
{
 
1761
  Select_Lex_Unit *unit= master_unit();
 
1762
  Item_subselect *item= unit->item;
 
1763
 
 
1764
  if (item && unit->global_parameters == this)
 
1765
  {
 
1766
    Item_subselect::subs_type subs_type= item->substype();
 
1767
    if (subs_type == Item_subselect::EXISTS_SUBS ||
 
1768
        subs_type == Item_subselect::IN_SUBS ||
 
1769
        subs_type == Item_subselect::ALL_SUBS)
 
1770
    {
 
1771
      assert(!item->fixed ||
 
1772
                  /*
 
1773
                    If not using materialization both:
 
1774
                    select_limit == 1, and there should be no offset_limit.
 
1775
                  */
 
1776
                  (((subs_type == Item_subselect::IN_SUBS) &&
 
1777
                    ((Item_in_subselect*)item)->exec_method ==
 
1778
                    Item_in_subselect::MATERIALIZATION) ?
 
1779
                   true :
 
1780
                   (select_limit->val_int() == 1L) &&
 
1781
                   offset_limit == 0));
 
1782
      return;
 
1783
    }
 
1784
  }
 
1785
  if (explicit_limit)
 
1786
  {
 
1787
    str->append(STRING_WITH_LEN(" limit "));
 
1788
    if (offset_limit)
 
1789
    {
 
1790
      offset_limit->print(str, query_type);
 
1791
      str->append(',');
 
1792
    }
 
1793
    select_limit->print(str, query_type);
 
1794
  }
 
1795
}
 
1796
 
 
1797
/**
 
1798
  @brief Restore the LEX and Session in case of a parse error.
 
1799
 
 
1800
  This is a clean up call that is invoked by the Bison generated
 
1801
  parser before returning an error from DRIZZLEparse. If your
 
1802
  semantic actions manipulate with the global thread state (which
 
1803
  is a very bad practice and should not normally be employed) and
 
1804
  need a clean-up in case of error, and you can not use %destructor
 
1805
  rule in the grammar file itself, this function should be used
 
1806
  to implement the clean up.
 
1807
*/
 
1808
void LEX::cleanup_lex_after_parse_error(Session *)
 
1809
{
 
1810
}
 
1811
 
 
1812
/*
 
1813
  Initialize (or reset) Query_tables_list object.
 
1814
 
 
1815
  SYNOPSIS
 
1816
    reset_query_tables_list()
 
1817
      init  true  - we should perform full initialization of object with
 
1818
                    allocating needed memory
 
1819
            false - object is already initialized so we should only reset
 
1820
                    its state so it can be used for parsing/processing
 
1821
                    of new statement
 
1822
 
 
1823
  DESCRIPTION
 
1824
    This method initializes Query_tables_list so it can be used as part
 
1825
    of LEX object for parsing/processing of statement. One can also use
 
1826
    this method to reset state of already initialized Query_tables_list
 
1827
    so it can be used for processing of new statement.
 
1828
*/
 
1829
void Query_tables_list::reset_query_tables_list(bool init)
 
1830
{
 
1831
  if (!init && query_tables)
 
1832
  {
 
1833
    TableList *table= query_tables;
 
1834
    for (;;)
 
1835
    {
 
1836
      if (query_tables_last == &table->next_global ||
 
1837
          !(table= table->next_global))
 
1838
        break;
 
1839
    }
 
1840
  }
 
1841
  query_tables= 0;
 
1842
  query_tables_last= &query_tables;
 
1843
  query_tables_own_last= 0;
 
1844
}
 
1845
 
 
1846
/*
 
1847
  Initialize LEX object.
 
1848
 
 
1849
  SYNOPSIS
 
1850
    LEX::LEX()
 
1851
 
 
1852
  NOTE
 
1853
    LEX object initialized with this constructor can be used as part of
 
1854
    Session object for which one can safely call open_tables(), lock_tables()
 
1855
    and close_thread_tables() functions. But it is not yet ready for
 
1856
    statement parsing. On should use lex_start() function to prepare LEX
 
1857
    for this.
 
1858
*/
 
1859
LEX::LEX()
 
1860
  :result(0), yacc_yyss(0), yacc_yyvs(0),
 
1861
   sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
 
1862
{
 
1863
  reset_query_tables_list(true);
 
1864
  statement= NULL;
 
1865
}
 
1866
 
 
1867
/*
 
1868
  Detect that we need only table structure of derived table/view
 
1869
 
 
1870
  SYNOPSIS
 
1871
    only_view_structure()
 
1872
 
 
1873
  RETURN
 
1874
    true yes, we need only structure
 
1875
    false no, we need data
 
1876
*/
 
1877
bool LEX::only_view_structure()
 
1878
{
 
1879
  if (sql_command == SQLCOM_SHOW_CREATE)
 
1880
    return true;
 
1881
 
 
1882
  return false;
 
1883
}
 
1884
 
 
1885
/*
 
1886
  Should Items_ident be printed correctly
 
1887
 
 
1888
  SYNOPSIS
 
1889
    need_correct_ident()
 
1890
 
 
1891
  RETURN
 
1892
    true yes, we need only structure
 
1893
    false no, we need data
 
1894
*/
 
1895
bool LEX::need_correct_ident()
 
1896
{
 
1897
  if (sql_command== SQLCOM_SHOW_CREATE)
 
1898
    return true;
 
1899
 
 
1900
  return false;
 
1901
}
 
1902
 
 
1903
/**
 
1904
  This method should be called only during parsing.
 
1905
  It is aware of compound statements (stored routine bodies)
 
1906
  and will initialize the destination with the default
 
1907
  database of the stored routine, rather than the default
 
1908
  database of the connection it is parsed in.
 
1909
  E.g. if one has no current database selected, or current database
 
1910
  set to 'bar' and then issues:
 
1911
 
 
1912
  CREATE PROCEDURE foo.p1() BEGIN SELECT * FROM t1 END//
 
1913
 
 
1914
  t1 is meant to refer to foo.t1, not to bar.t1.
 
1915
 
 
1916
  This method is needed to support this rule.
 
1917
 
 
1918
  @return true in case of error (parsing should be aborted, false in
 
1919
  case of success
 
1920
*/
 
1921
bool LEX::copy_db_to(char **p_db, size_t *p_db_length) const
 
1922
{
 
1923
  return session->copy_db_to(p_db, p_db_length);
 
1924
}
 
1925
 
 
1926
/*
 
1927
  initialize limit counters
 
1928
 
 
1929
  SYNOPSIS
 
1930
    Select_Lex_Unit::set_limit()
 
1931
    values      - Select_Lex with initial values for counters
 
1932
*/
 
1933
void Select_Lex_Unit::set_limit(Select_Lex *sl)
 
1934
{
 
1935
  ha_rows select_limit_val;
 
1936
  uint64_t val;
 
1937
 
 
1938
  val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
 
1939
  select_limit_val= (ha_rows)val;
 
1940
  /*
 
1941
    Check for overflow : ha_rows can be smaller then uint64_t if
 
1942
    BIG_TABLES is off.
 
1943
    */
 
1944
  if (val != (uint64_t)select_limit_val)
 
1945
    select_limit_val= HA_POS_ERROR;
 
1946
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
 
1947
                                                 0UL);
 
1948
  select_limit_cnt= select_limit_val + offset_limit_cnt;
 
1949
  if (select_limit_cnt < select_limit_val)
 
1950
    select_limit_cnt= HA_POS_ERROR;             // no limit
 
1951
}
 
1952
 
 
1953
/*
 
1954
  Unlink the first table from the global table list and the first table from
 
1955
  outer select (lex->select_lex) local list
 
1956
 
 
1957
  SYNOPSIS
 
1958
    unlink_first_table()
 
1959
    link_to_local       Set to 1 if caller should link this table to local list
 
1960
 
 
1961
  NOTES
 
1962
    We assume that first tables in both lists is the same table or the local
 
1963
    list is empty.
 
1964
 
 
1965
  RETURN
 
1966
    0   If 'query_tables' == 0
 
1967
    unlinked table
 
1968
      In this case link_to_local is set.
 
1969
 
 
1970
*/
 
1971
TableList *LEX::unlink_first_table(bool *link_to_local)
 
1972
{
 
1973
  TableList *first;
 
1974
  if ((first= query_tables))
 
1975
  {
 
1976
    /*
 
1977
      Exclude from global table list
 
1978
    */
 
1979
    if ((query_tables= query_tables->next_global))
 
1980
      query_tables->prev_global= &query_tables;
 
1981
    else
 
1982
      query_tables_last= &query_tables;
 
1983
    first->next_global= 0;
 
1984
 
 
1985
    /*
 
1986
      and from local list if it is not empty
 
1987
    */
 
1988
    if ((*link_to_local= test(select_lex.table_list.first)))
 
1989
    {
 
1990
      select_lex.context.table_list=
 
1991
        select_lex.context.first_name_resolution_table= first->next_local;
 
1992
      select_lex.table_list.first= (unsigned char*) (first->next_local);
 
1993
      select_lex.table_list.elements--; //safety
 
1994
      first->next_local= 0;
 
1995
      /*
 
1996
        Ensure that the global list has the same first table as the local
 
1997
        list.
 
1998
      */
 
1999
      first_lists_tables_same();
 
2000
    }
 
2001
  }
 
2002
  return first;
 
2003
}
 
2004
 
 
2005
/*
 
2006
  Bring first local table of first most outer select to first place in global
 
2007
  table list
 
2008
 
 
2009
  SYNOPSYS
 
2010
     LEX::first_lists_tables_same()
 
2011
 
 
2012
  NOTES
 
2013
    In many cases (for example, usual INSERT/DELETE/...) the first table of
 
2014
    main Select_Lex have special meaning => check that it is the first table
 
2015
    in global list and re-link to be first in the global list if it is
 
2016
    necessary.  We need such re-linking only for queries with sub-queries in
 
2017
    the select list, as only in this case tables of sub-queries will go to
 
2018
    the global list first.
 
2019
*/
 
2020
void LEX::first_lists_tables_same()
 
2021
{
 
2022
  TableList *first_table= (TableList*) select_lex.table_list.first;
 
2023
  if (query_tables != first_table && first_table != 0)
 
2024
  {
 
2025
    TableList *next;
 
2026
    if (query_tables_last == &first_table->next_global)
 
2027
      query_tables_last= first_table->prev_global;
 
2028
 
 
2029
    if ((next= *first_table->prev_global= first_table->next_global))
 
2030
      next->prev_global= first_table->prev_global;
 
2031
    /* include in new place */
 
2032
    first_table->next_global= query_tables;
 
2033
    /*
 
2034
       We are sure that query_tables is not 0, because first_table was not
 
2035
       first table in the global list => we can use
 
2036
       query_tables->prev_global without check of query_tables
 
2037
    */
 
2038
    query_tables->prev_global= &first_table->next_global;
 
2039
    first_table->prev_global= &query_tables;
 
2040
    query_tables= first_table;
 
2041
  }
 
2042
}
 
2043
 
 
2044
/*
 
2045
  Link table back that was unlinked with unlink_first_table()
 
2046
 
 
2047
  SYNOPSIS
 
2048
    link_first_table_back()
 
2049
    link_to_local       do we need link this table to local
 
2050
 
 
2051
  RETURN
 
2052
    global list
 
2053
*/
 
2054
void LEX::link_first_table_back(TableList *first, bool link_to_local)
 
2055
{
 
2056
  if (first)
 
2057
  {
 
2058
    if ((first->next_global= query_tables))
 
2059
      query_tables->prev_global= &first->next_global;
 
2060
    else
 
2061
      query_tables_last= &first->next_global;
 
2062
    query_tables= first;
 
2063
 
 
2064
    if (link_to_local)
 
2065
    {
 
2066
      first->next_local= (TableList*) select_lex.table_list.first;
 
2067
      select_lex.context.table_list= first;
 
2068
      select_lex.table_list.first= (unsigned char*) first;
 
2069
      select_lex.table_list.elements++; //safety
 
2070
    }
 
2071
  }
 
2072
}
 
2073
 
 
2074
/*
 
2075
  cleanup lex for case when we open table by table for processing
 
2076
 
 
2077
  SYNOPSIS
 
2078
    LEX::cleanup_after_one_table_open()
 
2079
 
 
2080
  NOTE
 
2081
    This method is mostly responsible for cleaning up of selects lists and
 
2082
    derived tables state. To rollback changes in Query_tables_list one has
 
2083
    to call Query_tables_list::reset_query_tables_list(false).
 
2084
*/
 
2085
void LEX::cleanup_after_one_table_open()
 
2086
{
 
2087
  /*
 
2088
    session->lex->derived_tables & additional units may be set if we open
 
2089
    a view. It is necessary to clear session->lex->derived_tables flag
 
2090
    to prevent processing of derived tables during next openTablesLock
 
2091
    if next table is a real table and cleanup & remove underlying units
 
2092
    NOTE: all units will be connected to session->lex->select_lex, because we
 
2093
    have not UNION on most upper level.
 
2094
    */
 
2095
  if (all_selects_list != &select_lex)
 
2096
  {
 
2097
    derived_tables= 0;
 
2098
    /* cleunup underlying units (units of VIEW) */
 
2099
    for (Select_Lex_Unit *un= select_lex.first_inner_unit();
 
2100
         un;
 
2101
         un= un->next_unit())
 
2102
      un->cleanup();
 
2103
    /* reduce all selects list to default state */
 
2104
    all_selects_list= &select_lex;
 
2105
    /* remove underlying units (units of VIEW) subtree */
 
2106
    select_lex.cut_subtree();
 
2107
  }
 
2108
}
 
2109
 
 
2110
/*
 
2111
  There are Select_Lex::add_table_to_list &
 
2112
  Select_Lex::set_lock_for_tables are in sql_parse.cc
 
2113
 
 
2114
  Select_Lex::print is in sql_select.cc
 
2115
 
 
2116
  Select_Lex_Unit::prepare, Select_Lex_Unit::exec,
 
2117
  Select_Lex_Unit::cleanup, Select_Lex_Unit::reinit_exec_mechanism,
 
2118
  Select_Lex_Unit::change_result
 
2119
  are in sql_union.cc
 
2120
*/
 
2121
 
 
2122
/*
 
2123
  Sets the kind of hints to be added by the calls to add_index_hint().
 
2124
 
 
2125
  SYNOPSIS
 
2126
    set_index_hint_type()
 
2127
      type_arg     The kind of hints to be added from now on.
 
2128
      clause       The clause to use for hints to be added from now on.
 
2129
 
 
2130
  DESCRIPTION
 
2131
    Used in filling up the tagged hints list.
 
2132
    This list is filled by first setting the kind of the hint as a
 
2133
    context variable and then adding hints of the current kind.
 
2134
    Then the context variable index_hint_type can be reset to the
 
2135
    next hint type.
 
2136
*/
 
2137
void Select_Lex::set_index_hint_type(enum index_hint_type type_arg, index_clause_map clause)
 
2138
{
 
2139
  current_index_hint_type= type_arg;
 
2140
  current_index_hint_clause= clause;
 
2141
}
 
2142
 
 
2143
/*
 
2144
  Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
 
2145
 
 
2146
  SYNOPSIS
 
2147
    alloc_index_hints()
 
2148
      session         current thread.
 
2149
*/
 
2150
void Select_Lex::alloc_index_hints (Session *session)
 
2151
{
 
2152
  index_hints= new (session->mem_root) List<Index_hint>();
 
2153
}
 
2154
 
 
2155
/*
 
2156
  adds an element to the array storing index usage hints
 
2157
  (ADD/FORCE/IGNORE INDEX).
 
2158
 
 
2159
  SYNOPSIS
 
2160
    add_index_hint()
 
2161
      session         current thread.
 
2162
      str         name of the index.
 
2163
      length      number of characters in str.
 
2164
 
 
2165
  RETURN VALUE
 
2166
    0 on success, non-zero otherwise
 
2167
*/
 
2168
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
 
2169
{
 
2170
  return index_hints->push_front (new (session->mem_root)
 
2171
                                 Index_hint(current_index_hint_type,
 
2172
                                            current_index_hint_clause,
 
2173
                                            str, length));
 
2174
}
 
2175
 
 
2176
} /* namespace drizzled */