~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_lex.cc

  • Committer: patrick crews
  • Date: 2011-06-08 03:02:27 UTC
  • mto: This revision was merged to the branch mainline in revision 2329.
  • Revision ID: gleebix@gmail.com-20110608030227-updkyv2652zvfajc
Initial voodoo worked to give us a crashme mode.  Need docs still

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* A lexical scanner on a temporary buffer with a yacc interface */
18
18
 
19
 
#include "config.h"
 
19
#include <config.h>
 
20
 
20
21
#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"
 
22
 
 
23
#include <drizzled/sql_reserved_words.h>
 
24
 
 
25
#include <drizzled/configmake.h>
 
26
#include <drizzled/item/num.h>
 
27
#include <drizzled/error.h>
 
28
#include <drizzled/session.h>
 
29
#include <drizzled/sql_base.h>
 
30
#include <drizzled/lookup_symbol.h>
 
31
#include <drizzled/index_hint.h>
 
32
#include <drizzled/select_result.h>
 
33
#include <drizzled/item/subselect.h>
 
34
#include <drizzled/statement.h>
 
35
#include <drizzled/sql_lex.h>
 
36
#include <drizzled/plugin.h>
28
37
 
29
38
#include <cstdio>
30
39
#include <ctype.h>
31
40
 
 
41
#include <drizzled/message/alter_table.pb.h>
 
42
 
 
43
union ParserType;
 
44
 
32
45
using namespace std;
33
46
 
34
47
/* Stay outside of the namespace because otherwise bison goes nuts */
35
 
int DRIZZLElex(void *arg, void *yysession);
 
48
int base_sql_lex(ParserType *arg, drizzled::Session *yysession);
36
49
 
37
50
namespace drizzled
38
51
{
39
52
 
40
 
static int lex_one_token(void *arg, void *yysession);
 
53
static int lex_one_token(ParserType *arg, drizzled::Session *yysession);
41
54
 
42
55
/**
43
56
  save order by and tables in own lists.
45
58
static bool add_to_list(Session *session, SQL_LIST &list, Item *item, bool asc)
46
59
{
47
60
  Order *order;
48
 
  if (!(order = (Order *) session->alloc(sizeof(Order))))
49
 
    return(1);
 
61
 
 
62
  if (!(order = (Order *) session->getMemRoot()->allocate(sizeof(Order))))
 
63
    return true;
 
64
 
50
65
  order->item_ptr= item;
51
66
  order->item= &order->item_ptr;
52
67
  order->asc = asc;
53
68
  order->free_me=0;
54
69
  order->used=0;
55
70
  order->counter_used= 0;
56
 
  list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
57
 
  return(0);
 
71
  list.link_in_list((unsigned char*) order, (unsigned char**) &order->next);
 
72
 
 
73
  return false;
58
74
}
59
75
 
60
76
/**
64
80
 
65
81
Lex_input_stream::Lex_input_stream(Session *session,
66
82
                                   const char* buffer,
67
 
                                   unsigned int length)
68
 
: m_session(session),
 
83
                                   unsigned int length) :
 
84
  m_session(session),
69
85
  yylineno(1),
70
86
  yytoklen(0),
71
87
  yylval(NULL),
88
104
  ignore_space(1),
89
105
  in_comment(NO_COMMENT)
90
106
{
91
 
  m_cpp_buf= (char*) session->alloc(length + 1);
 
107
  m_cpp_buf= (char*) session->getMemRoot()->allocate(length + 1);
92
108
  m_cpp_ptr= m_cpp_buf;
93
109
}
94
110
 
95
 
Lex_input_stream::~Lex_input_stream()
96
 
{}
97
 
 
98
 
/**
99
 
  The operation is called from the parser in order to
100
 
  1) designate the intention to have utf8 body;
101
 
  1) Indicate to the lexer that we will need a utf8 representation of this
102
 
     statement;
103
 
  2) Determine the beginning of the body.
104
 
 
105
 
  @param session        Thread context.
106
 
  @param begin_ptr  Pointer to the start of the body in the pre-processed
107
 
                    buffer.
108
 
*/
109
 
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
110
 
{
111
 
  assert(begin_ptr);
112
 
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
113
 
 
114
 
  uint32_t body_utf8_length=
115
 
    (m_buf_length / default_charset_info->mbminlen) *
116
 
    my_charset_utf8_bin.mbmaxlen;
117
 
 
118
 
  m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
119
 
  m_body_utf8_ptr= m_body_utf8;
120
 
  *m_body_utf8_ptr= 0;
121
 
 
122
 
  m_cpp_utf8_processed_ptr= begin_ptr;
123
 
}
124
 
 
125
111
/**
126
112
  @brief The operation appends unprocessed part of pre-processed buffer till
127
113
  the given pointer (ptr) and sets m_cpp_utf8_processed_ptr to end_ptr.
213
199
 
214
200
void lex_start(Session *session)
215
201
{
216
 
  LEX *lex= session->lex;
 
202
  LEX *lex= &session->lex();
217
203
 
218
204
  lex->session= lex->unit.session= session;
219
205
 
220
 
  lex->context_stack.empty();
 
206
  lex->context_stack.clear();
221
207
  lex->unit.init_query();
222
208
  lex->unit.init_select();
223
209
  /* 'parent_lex' is used in init_query() so it must be before it. */
224
210
  lex->select_lex.parent_lex= lex;
225
211
  lex->select_lex.init_query();
226
 
  lex->value_list.empty();
227
 
  lex->update_list.empty();
228
 
  lex->auxiliary_table_list.empty();
 
212
  lex->value_list.clear();
 
213
  lex->update_list.clear();
 
214
  lex->auxiliary_table_list.clear();
229
215
  lex->unit.next= lex->unit.master=
230
216
    lex->unit.link_next= lex->unit.return_to= 0;
231
217
  lex->unit.prev= lex->unit.link_prev= 0;
237
223
  lex->select_lex.link_prev= (Select_Lex_Node**)&(lex->all_selects_list);
238
224
  lex->select_lex.options= 0;
239
225
  lex->select_lex.init_order();
240
 
  lex->select_lex.group_list.empty();
 
226
  lex->select_lex.group_list.clear();
241
227
  lex->describe= 0;
242
228
  lex->derived_tables= 0;
243
229
  lex->lock_option= TL_READ;
244
230
  lex->leaf_tables_insert= 0;
 
231
  lex->var_list.clear();
245
232
  lex->select_lex.select_number= 1;
246
233
  lex->length=0;
247
234
  lex->select_lex.in_sum_expr=0;
248
 
  lex->select_lex.group_list.empty();
249
 
  lex->select_lex.order_list.empty();
 
235
  lex->select_lex.group_list.clear();
 
236
  lex->select_lex.order_list.clear();
250
237
  lex->sql_command= SQLCOM_END;
251
238
  lex->duplicates= DUP_ERROR;
252
239
  lex->ignore= 0;
261
248
  lex->nest_level=0 ;
262
249
  lex->allow_sum_func= 0;
263
250
  lex->in_sum_func= NULL;
 
251
  lex->type= 0;
264
252
 
265
253
  lex->is_lex_started= true;
266
254
  lex->statement= NULL;
267
 
  
 
255
 
268
256
  lex->is_cross= false;
269
 
 
270
257
  lex->reset();
271
258
}
272
259
 
280
267
    yacc_yyvs= 0;
281
268
  }
282
269
 
283
 
  delete result;
 
270
  safe_delete(result);
 
271
  safe_delete(_create_table);
 
272
  safe_delete(_alter_table);
 
273
  _create_table= NULL;
 
274
  _alter_table= NULL;
 
275
  _create_field= NULL;
284
276
 
285
277
  result= 0;
286
278
  setCacheable(true);
287
279
 
288
 
  delete statement;
289
 
  statement= NULL;
 
280
  safe_delete(statement);
290
281
}
291
282
 
292
283
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
312
303
  return 0;
313
304
}
314
305
 
315
 
bool is_lex_native_function(const LEX_STRING *name)
316
 
{
317
 
  assert(name != NULL);
318
 
  return (lookup_symbol(name->str, name->length, 1) != 0);
319
 
}
320
 
 
321
306
/* make a copy of token before ptr and set yytoklen */
322
307
static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
323
308
{
347
332
  char *to;
348
333
  lip->yyUnget();                       // ptr points now after last token char
349
334
  tmp.length= lip->yytoklen=length;
350
 
  tmp.str=(char*) lip->m_session->alloc(tmp.length+1);
 
335
  tmp.str=(char*) lip->m_session->getMemRoot()->allocate(tmp.length+1);
351
336
  from= lip->get_tok_start() + skip;
352
337
  to= tmp.str;
353
338
  end= to+length;
374
359
*/
375
360
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
376
361
{
377
 
  register unsigned char c,sep;
 
362
  unsigned char c,sep;
378
363
  bool found_escape= false;
379
 
  const CHARSET_INFO * const cs= lip->m_session->charset();
 
364
  const charset_info_st * const cs= lip->m_session->charset();
380
365
 
381
366
  lip->tok_bitmap= 0;
382
367
  sep= lip->yyGetLast();                        // String should end with this
388
373
      if (use_mb(cs))
389
374
      {
390
375
        int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
391
 
        if (l != 0) 
 
376
        if (l != 0)
392
377
        {
393
378
          lip->skip_binary(l-1);
394
379
          continue;
423
408
      end-= post_skip;
424
409
      assert(end >= str);
425
410
 
426
 
      if (!(start= (char*) lip->m_session->alloc((uint32_t) (end-str)+1)))
 
411
      if (!(start= (char*) lip->m_session->getMemRoot()->allocate((uint32_t) (end-str)+1)))
427
412
        return (char*) "";              // memory::SqlAlloc has set error flag
428
413
 
429
414
      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
589
574
 
590
575
} /* namespace drizzled */
591
576
/*
592
 
  DRIZZLElex remember the following states from the following DRIZZLElex()
 
577
  base_sql_lex remember the following states from the following sql_baselex()
593
578
 
594
579
  - MY_LEX_EOQ                  Found end of query
595
580
  - MY_LEX_OPERATOR_OR_IDENT    Last state was an ident, text or number
596
581
                                (which can't be followed by a signed number)
597
582
*/
598
 
int DRIZZLElex(void *arg, void *yysession)
 
583
int base_sql_lex(union ParserType *yylval, drizzled::Session *session)
599
584
{
600
 
  drizzled::Session *session= (drizzled::Session *)yysession;
601
585
  drizzled::Lex_input_stream *lip= session->m_lip;
602
 
  YYSTYPE *yylval=(YYSTYPE*) arg;
603
586
  int token;
604
587
 
605
588
  if (lip->lookahead_token != END_OF_INPUT)
615
598
    return token;
616
599
  }
617
600
 
618
 
  token= drizzled::lex_one_token(arg, yysession);
 
601
  token= drizzled::lex_one_token(yylval, session);
619
602
 
620
603
  switch(token) {
621
604
  case WITH:
626
609
      to transform the grammar into a LALR(1) grammar,
627
610
      which sql_yacc.yy can process.
628
611
    */
629
 
    token= drizzled::lex_one_token(arg, yysession);
 
612
    token= drizzled::lex_one_token(yylval, session);
630
613
    if (token == ROLLUP_SYM)
631
614
    {
632
615
      return WITH_ROLLUP_SYM;
651
634
namespace drizzled
652
635
{
653
636
 
654
 
int lex_one_token(void *arg, void *yysession)
 
637
int lex_one_token(ParserType *yylval, drizzled::Session *session)
655
638
{
656
 
  register unsigned char c= 0; /* Just set to shutup GCC */
 
639
  unsigned char c= 0; /* Just set to shutup GCC */
657
640
  bool comment_closed;
658
641
  int   tokval, result_state;
659
642
  unsigned int length;
660
643
  enum my_lex_states state;
661
 
  Session *session= (Session *)yysession;
662
644
  Lex_input_stream *lip= session->m_lip;
663
 
  LEX *lex= session->lex;
664
 
  YYSTYPE *yylval=(YYSTYPE*) arg;
665
 
  const CHARSET_INFO * const cs= session->charset();
 
645
  LEX *lex= &session->lex();
 
646
  const charset_info_st * const cs= session->charset();
666
647
  unsigned char *state_map= cs->state_map;
667
648
  unsigned char *ident_map= cs->ident_map;
668
649
 
1052
1033
      lip->yyUnget();                   // Safety against eof
1053
1034
      state = MY_LEX_START;             // Try again
1054
1035
      break;
 
1036
 
1055
1037
    case MY_LEX_LONG_COMMENT:           /* Long C comment? */
1056
1038
      if (lip->yyPeek() != '*')
1057
1039
      {
1149
1131
      lip->in_comment= NO_COMMENT;
1150
1132
      lip->set_echo(true);
1151
1133
      break;
 
1134
 
1152
1135
    case MY_LEX_END_LONG_COMMENT:
1153
1136
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
1154
1137
      {
1165
1148
      else
1166
1149
        state=MY_LEX_CHAR;              // Return '*'
1167
1150
      break;
 
1151
 
1168
1152
    case MY_LEX_SET_VAR:                // Check if ':='
1169
1153
      if (lip->yyPeek() != '=')
1170
1154
      {
1173
1157
      }
1174
1158
      lip->yySkip();
1175
1159
      return (SET_VAR);
 
1160
 
1176
1161
    case MY_LEX_SEMICOLON:                      // optional line terminator
1177
1162
      if (lip->yyPeek())
1178
1163
      {
1181
1166
      }
1182
1167
      lip->next_state=MY_LEX_END;       // Mark for next loop
1183
1168
      return(END_OF_INPUT);
 
1169
 
1184
1170
    case MY_LEX_EOL:
1185
1171
      if (lip->eof())
1186
1172
      {
1196
1182
      }
1197
1183
      state=MY_LEX_CHAR;
1198
1184
      break;
 
1185
 
1199
1186
    case MY_LEX_END:
1200
1187
      lip->next_state=MY_LEX_END;
1201
1188
      return false;                     // We found end of input last time
1202
1189
 
1203
1190
      /* Actually real shouldn't start with . but allow them anyhow */
 
1191
 
1204
1192
    case MY_LEX_REAL_OR_POINT:
1205
1193
      if (my_isdigit(cs,lip->yyPeek()))
1206
1194
        state= MY_LEX_REAL;             // Real
1210
1198
        lip->yyUnget();                 // Put back '.'
1211
1199
      }
1212
1200
      break;
 
1201
 
1213
1202
    case MY_LEX_USER_END:               // end '@' of user@hostname
1214
1203
      switch (state_map[(uint8_t)lip->yyPeek()]) {
1215
1204
      case MY_LEX_STRING:
1226
1215
      yylval->lex_str.str=(char*) lip->get_ptr();
1227
1216
      yylval->lex_str.length=1;
1228
1217
      return((int) '@');
 
1218
 
1229
1219
    case MY_LEX_HOSTNAME:               // end '@' of user@hostname
1230
1220
      for (c=lip->yyGet() ;
1231
1221
           my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
1232
1222
           c= lip->yyGet()) ;
1233
1223
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1234
1224
      return(LEX_HOSTNAME);
 
1225
 
1235
1226
    case MY_LEX_SYSTEM_VAR:
1236
1227
      yylval->lex_str.str=(char*) lip->get_ptr();
1237
1228
      yylval->lex_str.length=1;
1241
1232
                        MY_LEX_OPERATOR_OR_IDENT :
1242
1233
                        MY_LEX_IDENT_OR_KEYWORD);
1243
1234
      return((int) '@');
 
1235
 
1244
1236
    case MY_LEX_IDENT_OR_KEYWORD:
1245
1237
      /*
1246
1238
        We come here when we have found two '@' in a row.
1254
1246
 
1255
1247
      if (c == '.')
1256
1248
        lip->next_state=MY_LEX_IDENT_SEP;
 
1249
 
1257
1250
      length= lip->yyLength();
1258
1251
      if (length == 0)
1259
1252
        return(ABORT_SYM);              // Names must be nonempty.
 
1253
 
1260
1254
      if ((tokval= find_keyword(lip, length,0)))
1261
1255
      {
1262
1256
        lip->yyUnget();                         // Put back 'c'
1273
1267
  }
1274
1268
}
1275
1269
 
1276
 
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
1277
 
{
1278
 
  /*
1279
 
    TODO:
1280
 
    This code assumes that there are no multi-bytes characters
1281
 
    that can be considered white-space.
1282
 
  */
1283
 
  while ((str->length > 0) && (my_isspace(cs, str->str[0])))
1284
 
  {
1285
 
    str->length--;
1286
 
    str->str++;
1287
 
  }
1288
 
 
1289
 
  /*
1290
 
    FIXME:
1291
 
    Also, parsing backward is not safe with multi bytes characters
1292
 
  */
1293
 
  while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
1294
 
  {
1295
 
    str->length--;
1296
 
  }
1297
 
}
1298
 
 
1299
1270
/*
1300
1271
  Select_Lex structures initialisations
1301
1272
*/
1325
1296
  table= 0;
1326
1297
  fake_select_lex= 0;
1327
1298
  cleaned= 0;
1328
 
  item_list.empty();
 
1299
  item_list.clear();
1329
1300
  describe= 0;
1330
1301
  found_rows_for_union= 0;
1331
1302
}
1333
1304
void Select_Lex::init_query()
1334
1305
{
1335
1306
  Select_Lex_Node::init_query();
1336
 
  table_list.empty();
1337
 
  top_join_list.empty();
 
1307
  table_list.clear();
 
1308
  top_join_list.clear();
1338
1309
  join_list= &top_join_list;
1339
1310
  embedding= leaf_tables= 0;
1340
 
  item_list.empty();
 
1311
  item_list.clear();
1341
1312
  join= 0;
1342
1313
  having= where= 0;
1343
1314
  olap= UNSPECIFIED_OLAP_TYPE;
1369
1340
 
1370
1341
void Select_Lex::init_select()
1371
1342
{
1372
 
  sj_nests.empty();
1373
 
  group_list.empty();
 
1343
  sj_nests.clear();
 
1344
  group_list.clear();
1374
1345
  db= 0;
1375
1346
  having= 0;
1376
1347
  in_sum_expr= with_wild= 0;
1377
1348
  options= 0;
1378
1349
  braces= 0;
1379
 
  interval_list.empty();
 
1350
  interval_list.clear();
1380
1351
  inner_sum_func_list= 0;
1381
1352
  linkage= UNSPECIFIED_TYPE;
1382
1353
  order_list.elements= 0;
1386
1357
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1387
1358
  offset_limit= 0;      /* denotes the default offset = 0 */
1388
1359
  with_sum_func= 0;
 
1360
  is_cross= false;
1389
1361
  is_correlated= 0;
1390
1362
  cur_pos_in_select_list= UNDEF_POS;
1391
 
  non_agg_fields.empty();
 
1363
  non_agg_fields.clear();
1392
1364
  cond_value= having_value= Item::COND_UNDEF;
1393
 
  inner_refs_list.empty();
 
1365
  inner_refs_list.clear();
1394
1366
  full_group_by_flag.reset();
1395
1367
}
1396
1368
 
1597
1569
bool Select_Lex_Node::inc_in_sum_expr()
1598
1570
{ return true; }
1599
1571
 
1600
 
uint32_t Select_Lex_Node::get_in_sum_expr() 
 
1572
uint32_t Select_Lex_Node::get_in_sum_expr()
1601
1573
{ return 0; }
1602
1574
 
1603
1575
TableList* Select_Lex_Node::get_table_list()
1606
1578
List<Item>* Select_Lex_Node::get_item_list()
1607
1579
{ return NULL; }
1608
1580
 
1609
 
TableList *Select_Lex_Node::add_table_to_list(Session *, 
1610
 
                                              Table_ident *, 
1611
 
                                              LEX_STRING *, 
 
1581
TableList *Select_Lex_Node::add_table_to_list(Session *,
 
1582
                                              Table_ident *,
 
1583
                                              LEX_STRING *,
1612
1584
                                              const bitset<NUM_OF_TABLE_OPTIONS>&,
1613
 
                                              thr_lock_type, 
1614
 
                                              List<Index_hint> *, 
 
1585
                                              thr_lock_type,
 
1586
                                              List<Index_hint> *,
1615
1587
                                              LEX_STRING *)
1616
1588
{
1617
1589
  return 0;
1649
1621
 
1650
1622
bool Select_Lex::add_item_to_list(Session *, Item *item)
1651
1623
{
1652
 
  return(item_list.push_back(item));
 
1624
        item_list.push_back(item);
 
1625
  return false;
1653
1626
}
1654
1627
 
1655
1628
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
1701
1674
    return false;
1702
1675
 
1703
1676
  return (ref_pointer_array=
1704
 
          (Item **)session->alloc(sizeof(Item*) * (n_child_sum_items +
1705
 
                                                 item_list.elements +
 
1677
          (Item **)session->getMemRoot()->allocate(sizeof(Item*) * (n_child_sum_items +
 
1678
                                                 item_list.size() +
1706
1679
                                                 select_n_having_items +
1707
1680
                                                 select_n_where_fields +
1708
1681
                                                 order_group_num)*5)) == 0;
1709
1682
}
1710
1683
 
1711
 
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
 
1684
void Select_Lex_Unit::print(String *str)
1712
1685
{
1713
1686
  bool union_all= !union_distinct;
1714
1687
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1723
1696
    }
1724
1697
    if (sl->braces)
1725
1698
      str->append('(');
1726
 
    sl->print(session, str, query_type);
 
1699
    sl->print(session, str);
1727
1700
    if (sl->braces)
1728
1701
      str->append(')');
1729
1702
  }
1734
1707
      str->append(STRING_WITH_LEN(" order by "));
1735
1708
      fake_select_lex->print_order(
1736
1709
        str,
1737
 
        (Order *) fake_select_lex->order_list.first,
1738
 
        query_type);
 
1710
        (Order *) fake_select_lex->order_list.first);
1739
1711
    }
1740
 
    fake_select_lex->print_limit(session, str, query_type);
 
1712
    fake_select_lex->print_limit(session, str);
1741
1713
  }
1742
1714
}
1743
1715
 
1744
1716
void Select_Lex::print_order(String *str,
1745
 
                                Order *order,
1746
 
                                enum_query_type query_type)
 
1717
                             Order *order)
1747
1718
{
1748
1719
  for (; order; order= order->next)
1749
1720
  {
1754
1725
      str->append(buffer, length);
1755
1726
    }
1756
1727
    else
1757
 
      (*order->item)->print(str, query_type);
 
1728
      (*order->item)->print(str);
1758
1729
    if (!order->asc)
1759
1730
      str->append(STRING_WITH_LEN(" desc"));
1760
1731
    if (order->next)
1762
1733
  }
1763
1734
}
1764
1735
 
1765
 
void Select_Lex::print_limit(Session *, String *str,
1766
 
                                enum_query_type query_type)
 
1736
void Select_Lex::print_limit(Session *, String *str)
1767
1737
{
1768
1738
  Select_Lex_Unit *unit= master_unit();
1769
1739
  Item_subselect *item= unit->item;
1794
1764
    str->append(STRING_WITH_LEN(" limit "));
1795
1765
    if (offset_limit)
1796
1766
    {
1797
 
      offset_limit->print(str, query_type);
 
1767
      offset_limit->print(str);
1798
1768
      str->append(',');
1799
1769
    }
1800
 
    select_limit->print(str, query_type);
 
1770
    select_limit->print(str);
1801
1771
  }
1802
1772
}
1803
1773
 
1804
 
/**
1805
 
  @brief Restore the LEX and Session in case of a parse error.
1806
 
 
1807
 
  This is a clean up call that is invoked by the Bison generated
1808
 
  parser before returning an error from DRIZZLEparse. If your
1809
 
  semantic actions manipulate with the global thread state (which
1810
 
  is a very bad practice and should not normally be employed) and
1811
 
  need a clean-up in case of error, and you can not use %destructor
1812
 
  rule in the grammar file itself, this function should be used
1813
 
  to implement the clean up.
1814
 
*/
1815
 
void LEX::cleanup_lex_after_parse_error(Session *)
 
1774
LEX::~LEX()
1816
1775
{
 
1776
  delete _create_table;
 
1777
  delete _alter_table;
1817
1778
}
1818
1779
 
1819
1780
/*
1863
1824
    statement parsing. On should use lex_start() function to prepare LEX
1864
1825
    for this.
1865
1826
*/
1866
 
LEX::LEX()
1867
 
  :
1868
 
    result(0), 
1869
 
    yacc_yyss(0), 
 
1827
LEX::LEX() :
 
1828
    result(0),
 
1829
    yacc_yyss(0),
1870
1830
    yacc_yyvs(0),
 
1831
    session(NULL),
1871
1832
    charset(NULL),
1872
 
    sql_command(SQLCOM_END), 
1873
 
    option_type(OPT_DEFAULT), 
 
1833
    var_list(),
 
1834
    sql_command(SQLCOM_END),
 
1835
    statement(NULL),
 
1836
    option_type(OPT_DEFAULT),
1874
1837
    is_lex_started(0),
1875
1838
    cacheable(true),
1876
 
    sum_expr_used(false)
 
1839
    sum_expr_used(false),
 
1840
    _create_table(NULL),
 
1841
    _alter_table(NULL),
 
1842
    _create_field(NULL),
 
1843
    _exists(false)
1877
1844
{
1878
1845
  reset_query_tables_list(true);
1879
 
  statement= NULL;
1880
1846
}
1881
1847
 
1882
1848
/**
2064
2030
void LEX::cleanup_after_one_table_open()
2065
2031
{
2066
2032
  /*
2067
 
    session->lex->derived_tables & additional units may be set if we open
2068
 
    a view. It is necessary to clear session->lex->derived_tables flag
 
2033
    session->lex().derived_tables & additional units may be set if we open
 
2034
    a view. It is necessary to clear session->lex().derived_tables flag
2069
2035
    to prevent processing of derived tables during next openTablesLock
2070
2036
    if next table is a real table and cleanup & remove underlying units
2071
 
    NOTE: all units will be connected to session->lex->select_lex, because we
 
2037
    NOTE: all units will be connected to session->lex().select_lex, because we
2072
2038
    have not UNION on most upper level.
2073
2039
    */
2074
2040
  if (all_selects_list != &select_lex)
2144
2110
  RETURN VALUE
2145
2111
    0 on success, non-zero otherwise
2146
2112
*/
2147
 
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
2148
 
{
2149
 
  return index_hints->push_front (new (session->mem_root)
2150
 
                                 Index_hint(current_index_hint_type,
2151
 
                                            current_index_hint_clause,
2152
 
                                            str, length));
 
2113
void Select_Lex::add_index_hint(Session *session, char *str, uint32_t length)
 
2114
{
 
2115
  index_hints->push_front(new (session->mem_root) Index_hint(current_index_hint_type, current_index_hint_clause, str, length));
 
2116
}
 
2117
 
 
2118
message::AlterTable *LEX::alter_table()
 
2119
{
 
2120
  if (not _alter_table)
 
2121
    _alter_table= new message::AlterTable;
 
2122
 
 
2123
  return _alter_table;
2153
2124
}
2154
2125
 
2155
2126
} /* namespace drizzled */