~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_lex.cc

  • Committer: Lee Bieber
  • Date: 2011-03-29 22:31:41 UTC
  • mfrom: (2257.1.3 build)
  • Revision ID: kalebral@gmail.com-20110329223141-yxc22h3l2he58sk0
Merge Andrew - 743842: Build failure using GCC 4.6
Merge Stewart - 738022: CachedDirectory silently fails to add entries if stat() fails
Merge Olaf - Common fwd: add copyright, add more declaration

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
21
#define DRIZZLE_LEX 1
22
22
 
23
 
#include "drizzled/sql_reserved_words.h"
 
23
#include <drizzled/sql_reserved_words.h>
24
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"
 
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>
32
37
 
33
38
#include <cstdio>
34
39
#include <ctype.h>
35
40
 
 
41
#include <drizzled/message/alter_table.pb.h>
 
42
 
 
43
union ParserType;
 
44
 
36
45
using namespace std;
37
46
 
38
47
/* Stay outside of the namespace because otherwise bison goes nuts */
39
 
int DRIZZLElex(void *arg, void *yysession);
 
48
int base_sql_lex(ParserType *arg, drizzled::Session *yysession);
40
49
 
41
50
namespace drizzled
42
51
{
43
52
 
44
 
static int lex_one_token(void *arg, void *yysession);
 
53
static int lex_one_token(ParserType *arg, drizzled::Session *yysession);
45
54
 
46
55
/**
47
56
  save order by and tables in own lists.
220
229
 
221
230
void lex_start(Session *session)
222
231
{
223
 
  LEX *lex= session->lex;
 
232
  LEX *lex= &session->lex();
224
233
 
225
234
  lex->session= lex->unit.session= session;
226
235
 
227
 
  lex->context_stack.empty();
 
236
  lex->context_stack.clear();
228
237
  lex->unit.init_query();
229
238
  lex->unit.init_select();
230
239
  /* 'parent_lex' is used in init_query() so it must be before it. */
231
240
  lex->select_lex.parent_lex= lex;
232
241
  lex->select_lex.init_query();
233
 
  lex->value_list.empty();
234
 
  lex->update_list.empty();
235
 
  lex->auxiliary_table_list.empty();
 
242
  lex->value_list.clear();
 
243
  lex->update_list.clear();
 
244
  lex->auxiliary_table_list.clear();
236
245
  lex->unit.next= lex->unit.master=
237
246
    lex->unit.link_next= lex->unit.return_to= 0;
238
247
  lex->unit.prev= lex->unit.link_prev= 0;
244
253
  lex->select_lex.link_prev= (Select_Lex_Node**)&(lex->all_selects_list);
245
254
  lex->select_lex.options= 0;
246
255
  lex->select_lex.init_order();
247
 
  lex->select_lex.group_list.empty();
 
256
  lex->select_lex.group_list.clear();
248
257
  lex->describe= 0;
249
258
  lex->derived_tables= 0;
250
259
  lex->lock_option= TL_READ;
253
262
  lex->select_lex.select_number= 1;
254
263
  lex->length=0;
255
264
  lex->select_lex.in_sum_expr=0;
256
 
  lex->select_lex.group_list.empty();
257
 
  lex->select_lex.order_list.empty();
 
265
  lex->select_lex.group_list.clear();
 
266
  lex->select_lex.order_list.clear();
258
267
  lex->sql_command= SQLCOM_END;
259
268
  lex->duplicates= DUP_ERROR;
260
269
  lex->ignore= 0;
273
282
 
274
283
  lex->is_lex_started= true;
275
284
  lex->statement= NULL;
276
 
  
 
285
 
277
286
  lex->is_cross= false;
278
287
  lex->reset();
279
288
}
288
297
    yacc_yyvs= 0;
289
298
  }
290
299
 
291
 
  delete result;
292
 
  delete _create_table;
 
300
  safe_delete(result);
 
301
  safe_delete(_create_table);
 
302
  safe_delete(_alter_table);
293
303
  _create_table= NULL;
 
304
  _alter_table= NULL;
294
305
  _create_field= NULL;
295
306
 
296
307
  result= 0;
297
308
  setCacheable(true);
298
309
 
299
 
  delete statement;
300
 
  statement= NULL;
 
310
  safe_delete(statement);
301
311
}
302
312
 
303
313
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
385
395
*/
386
396
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
387
397
{
388
 
  register unsigned char c,sep;
 
398
  unsigned char c,sep;
389
399
  bool found_escape= false;
390
 
  const CHARSET_INFO * const cs= lip->m_session->charset();
 
400
  const charset_info_st * const cs= lip->m_session->charset();
391
401
 
392
402
  lip->tok_bitmap= 0;
393
403
  sep= lip->yyGetLast();                        // String should end with this
399
409
      if (use_mb(cs))
400
410
      {
401
411
        int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
402
 
        if (l != 0) 
 
412
        if (l != 0)
403
413
        {
404
414
          lip->skip_binary(l-1);
405
415
          continue;
600
610
 
601
611
} /* namespace drizzled */
602
612
/*
603
 
  DRIZZLElex remember the following states from the following DRIZZLElex()
 
613
  base_sql_lex remember the following states from the following sql_baselex()
604
614
 
605
615
  - MY_LEX_EOQ                  Found end of query
606
616
  - MY_LEX_OPERATOR_OR_IDENT    Last state was an ident, text or number
607
617
                                (which can't be followed by a signed number)
608
618
*/
609
 
int DRIZZLElex(void *arg, void *yysession)
 
619
int base_sql_lex(union ParserType *yylval, drizzled::Session *session)
610
620
{
611
 
  drizzled::Session *session= (drizzled::Session *)yysession;
612
621
  drizzled::Lex_input_stream *lip= session->m_lip;
613
 
  YYSTYPE *yylval=(YYSTYPE*) arg;
614
622
  int token;
615
623
 
616
624
  if (lip->lookahead_token != END_OF_INPUT)
626
634
    return token;
627
635
  }
628
636
 
629
 
  token= drizzled::lex_one_token(arg, yysession);
 
637
  token= drizzled::lex_one_token(yylval, session);
630
638
 
631
639
  switch(token) {
632
640
  case WITH:
637
645
      to transform the grammar into a LALR(1) grammar,
638
646
      which sql_yacc.yy can process.
639
647
    */
640
 
    token= drizzled::lex_one_token(arg, yysession);
 
648
    token= drizzled::lex_one_token(yylval, session);
641
649
    if (token == ROLLUP_SYM)
642
650
    {
643
651
      return WITH_ROLLUP_SYM;
662
670
namespace drizzled
663
671
{
664
672
 
665
 
int lex_one_token(void *arg, void *yysession)
 
673
int lex_one_token(ParserType *yylval, drizzled::Session *session)
666
674
{
667
 
  register unsigned char c= 0; /* Just set to shutup GCC */
 
675
  unsigned char c= 0; /* Just set to shutup GCC */
668
676
  bool comment_closed;
669
677
  int   tokval, result_state;
670
678
  unsigned int length;
671
679
  enum my_lex_states state;
672
 
  Session *session= (Session *)yysession;
673
680
  Lex_input_stream *lip= session->m_lip;
674
 
  LEX *lex= session->lex;
675
 
  YYSTYPE *yylval=(YYSTYPE*) arg;
676
 
  const CHARSET_INFO * const cs= session->charset();
 
681
  LEX *lex= &session->lex();
 
682
  const charset_info_st * const cs= session->charset();
677
683
  unsigned char *state_map= cs->state_map;
678
684
  unsigned char *ident_map= cs->ident_map;
679
685
 
1063
1069
      lip->yyUnget();                   // Safety against eof
1064
1070
      state = MY_LEX_START;             // Try again
1065
1071
      break;
 
1072
 
1066
1073
    case MY_LEX_LONG_COMMENT:           /* Long C comment? */
1067
1074
      if (lip->yyPeek() != '*')
1068
1075
      {
1160
1167
      lip->in_comment= NO_COMMENT;
1161
1168
      lip->set_echo(true);
1162
1169
      break;
 
1170
 
1163
1171
    case MY_LEX_END_LONG_COMMENT:
1164
1172
      if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
1165
1173
      {
1176
1184
      else
1177
1185
        state=MY_LEX_CHAR;              // Return '*'
1178
1186
      break;
 
1187
 
1179
1188
    case MY_LEX_SET_VAR:                // Check if ':='
1180
1189
      if (lip->yyPeek() != '=')
1181
1190
      {
1184
1193
      }
1185
1194
      lip->yySkip();
1186
1195
      return (SET_VAR);
 
1196
 
1187
1197
    case MY_LEX_SEMICOLON:                      // optional line terminator
1188
1198
      if (lip->yyPeek())
1189
1199
      {
1192
1202
      }
1193
1203
      lip->next_state=MY_LEX_END;       // Mark for next loop
1194
1204
      return(END_OF_INPUT);
 
1205
 
1195
1206
    case MY_LEX_EOL:
1196
1207
      if (lip->eof())
1197
1208
      {
1207
1218
      }
1208
1219
      state=MY_LEX_CHAR;
1209
1220
      break;
 
1221
 
1210
1222
    case MY_LEX_END:
1211
1223
      lip->next_state=MY_LEX_END;
1212
1224
      return false;                     // We found end of input last time
1213
1225
 
1214
1226
      /* Actually real shouldn't start with . but allow them anyhow */
 
1227
 
1215
1228
    case MY_LEX_REAL_OR_POINT:
1216
1229
      if (my_isdigit(cs,lip->yyPeek()))
1217
1230
        state= MY_LEX_REAL;             // Real
1221
1234
        lip->yyUnget();                 // Put back '.'
1222
1235
      }
1223
1236
      break;
 
1237
 
1224
1238
    case MY_LEX_USER_END:               // end '@' of user@hostname
1225
1239
      switch (state_map[(uint8_t)lip->yyPeek()]) {
1226
1240
      case MY_LEX_STRING:
1237
1251
      yylval->lex_str.str=(char*) lip->get_ptr();
1238
1252
      yylval->lex_str.length=1;
1239
1253
      return((int) '@');
 
1254
 
1240
1255
    case MY_LEX_HOSTNAME:               // end '@' of user@hostname
1241
1256
      for (c=lip->yyGet() ;
1242
1257
           my_isalnum(cs,c) || c == '.' || c == '_' ||  c == '$';
1243
1258
           c= lip->yyGet()) ;
1244
1259
      yylval->lex_str=get_token(lip, 0, lip->yyLength());
1245
1260
      return(LEX_HOSTNAME);
 
1261
 
1246
1262
    case MY_LEX_SYSTEM_VAR:
1247
1263
      yylval->lex_str.str=(char*) lip->get_ptr();
1248
1264
      yylval->lex_str.length=1;
1252
1268
                        MY_LEX_OPERATOR_OR_IDENT :
1253
1269
                        MY_LEX_IDENT_OR_KEYWORD);
1254
1270
      return((int) '@');
 
1271
 
1255
1272
    case MY_LEX_IDENT_OR_KEYWORD:
1256
1273
      /*
1257
1274
        We come here when we have found two '@' in a row.
1265
1282
 
1266
1283
      if (c == '.')
1267
1284
        lip->next_state=MY_LEX_IDENT_SEP;
 
1285
 
1268
1286
      length= lip->yyLength();
1269
1287
      if (length == 0)
1270
1288
        return(ABORT_SYM);              // Names must be nonempty.
 
1289
 
1271
1290
      if ((tokval= find_keyword(lip, length,0)))
1272
1291
      {
1273
1292
        lip->yyUnget();                         // Put back 'c'
1284
1303
  }
1285
1304
}
1286
1305
 
1287
 
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
 
1306
void trim_whitespace(const charset_info_st * const cs, LEX_STRING *str)
1288
1307
{
1289
1308
  /*
1290
1309
    TODO:
1336
1355
  table= 0;
1337
1356
  fake_select_lex= 0;
1338
1357
  cleaned= 0;
1339
 
  item_list.empty();
 
1358
  item_list.clear();
1340
1359
  describe= 0;
1341
1360
  found_rows_for_union= 0;
1342
1361
}
1344
1363
void Select_Lex::init_query()
1345
1364
{
1346
1365
  Select_Lex_Node::init_query();
1347
 
  table_list.empty();
1348
 
  top_join_list.empty();
 
1366
  table_list.clear();
 
1367
  top_join_list.clear();
1349
1368
  join_list= &top_join_list;
1350
1369
  embedding= leaf_tables= 0;
1351
 
  item_list.empty();
 
1370
  item_list.clear();
1352
1371
  join= 0;
1353
1372
  having= where= 0;
1354
1373
  olap= UNSPECIFIED_OLAP_TYPE;
1380
1399
 
1381
1400
void Select_Lex::init_select()
1382
1401
{
1383
 
  sj_nests.empty();
1384
 
  group_list.empty();
 
1402
  sj_nests.clear();
 
1403
  group_list.clear();
1385
1404
  db= 0;
1386
1405
  having= 0;
1387
1406
  in_sum_expr= with_wild= 0;
1388
1407
  options= 0;
1389
1408
  braces= 0;
1390
 
  interval_list.empty();
 
1409
  interval_list.clear();
1391
1410
  inner_sum_func_list= 0;
1392
1411
  linkage= UNSPECIFIED_TYPE;
1393
1412
  order_list.elements= 0;
1400
1419
  is_cross= false;
1401
1420
  is_correlated= 0;
1402
1421
  cur_pos_in_select_list= UNDEF_POS;
1403
 
  non_agg_fields.empty();
 
1422
  non_agg_fields.clear();
1404
1423
  cond_value= having_value= Item::COND_UNDEF;
1405
 
  inner_refs_list.empty();
 
1424
  inner_refs_list.clear();
1406
1425
  full_group_by_flag.reset();
1407
1426
}
1408
1427
 
1609
1628
bool Select_Lex_Node::inc_in_sum_expr()
1610
1629
{ return true; }
1611
1630
 
1612
 
uint32_t Select_Lex_Node::get_in_sum_expr() 
 
1631
uint32_t Select_Lex_Node::get_in_sum_expr()
1613
1632
{ return 0; }
1614
1633
 
1615
1634
TableList* Select_Lex_Node::get_table_list()
1618
1637
List<Item>* Select_Lex_Node::get_item_list()
1619
1638
{ return NULL; }
1620
1639
 
1621
 
TableList *Select_Lex_Node::add_table_to_list(Session *, 
1622
 
                                              Table_ident *, 
1623
 
                                              LEX_STRING *, 
 
1640
TableList *Select_Lex_Node::add_table_to_list(Session *,
 
1641
                                              Table_ident *,
 
1642
                                              LEX_STRING *,
1624
1643
                                              const bitset<NUM_OF_TABLE_OPTIONS>&,
1625
 
                                              thr_lock_type, 
1626
 
                                              List<Index_hint> *, 
 
1644
                                              thr_lock_type,
 
1645
                                              List<Index_hint> *,
1627
1646
                                              LEX_STRING *)
1628
1647
{
1629
1648
  return 0;
1661
1680
 
1662
1681
bool Select_Lex::add_item_to_list(Session *, Item *item)
1663
1682
{
1664
 
  return(item_list.push_back(item));
 
1683
        item_list.push_back(item);
 
1684
  return false;
1665
1685
}
1666
1686
 
1667
1687
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
1714
1734
 
1715
1735
  return (ref_pointer_array=
1716
1736
          (Item **)session->getMemRoot()->allocate(sizeof(Item*) * (n_child_sum_items +
1717
 
                                                 item_list.elements +
 
1737
                                                 item_list.size() +
1718
1738
                                                 select_n_having_items +
1719
1739
                                                 select_n_where_fields +
1720
1740
                                                 order_group_num)*5)) == 0;
1721
1741
}
1722
1742
 
1723
 
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
 
1743
void Select_Lex_Unit::print(String *str)
1724
1744
{
1725
1745
  bool union_all= !union_distinct;
1726
1746
  for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1735
1755
    }
1736
1756
    if (sl->braces)
1737
1757
      str->append('(');
1738
 
    sl->print(session, str, query_type);
 
1758
    sl->print(session, str);
1739
1759
    if (sl->braces)
1740
1760
      str->append(')');
1741
1761
  }
1746
1766
      str->append(STRING_WITH_LEN(" order by "));
1747
1767
      fake_select_lex->print_order(
1748
1768
        str,
1749
 
        (Order *) fake_select_lex->order_list.first,
1750
 
        query_type);
 
1769
        (Order *) fake_select_lex->order_list.first);
1751
1770
    }
1752
 
    fake_select_lex->print_limit(session, str, query_type);
 
1771
    fake_select_lex->print_limit(session, str);
1753
1772
  }
1754
1773
}
1755
1774
 
1756
1775
void Select_Lex::print_order(String *str,
1757
 
                                Order *order,
1758
 
                                enum_query_type query_type)
 
1776
                             Order *order)
1759
1777
{
1760
1778
  for (; order; order= order->next)
1761
1779
  {
1766
1784
      str->append(buffer, length);
1767
1785
    }
1768
1786
    else
1769
 
      (*order->item)->print(str, query_type);
 
1787
      (*order->item)->print(str);
1770
1788
    if (!order->asc)
1771
1789
      str->append(STRING_WITH_LEN(" desc"));
1772
1790
    if (order->next)
1774
1792
  }
1775
1793
}
1776
1794
 
1777
 
void Select_Lex::print_limit(Session *, String *str,
1778
 
                                enum_query_type query_type)
 
1795
void Select_Lex::print_limit(Session *, String *str)
1779
1796
{
1780
1797
  Select_Lex_Unit *unit= master_unit();
1781
1798
  Item_subselect *item= unit->item;
1806
1823
    str->append(STRING_WITH_LEN(" limit "));
1807
1824
    if (offset_limit)
1808
1825
    {
1809
 
      offset_limit->print(str, query_type);
 
1826
      offset_limit->print(str);
1810
1827
      str->append(',');
1811
1828
    }
1812
 
    select_limit->print(str, query_type);
 
1829
    select_limit->print(str);
1813
1830
  }
1814
1831
}
1815
1832
 
1816
1833
LEX::~LEX()
1817
1834
{
1818
1835
  delete _create_table;
 
1836
  delete _alter_table;
1819
1837
}
1820
1838
 
1821
1839
/*
1866
1884
    for this.
1867
1885
*/
1868
1886
LEX::LEX() :
1869
 
    result(0), 
1870
 
    yacc_yyss(0), 
 
1887
    result(0),
 
1888
    yacc_yyss(0),
1871
1889
    yacc_yyvs(0),
1872
1890
    session(NULL),
1873
1891
    charset(NULL),
1874
1892
    var_list(),
1875
 
    sql_command(SQLCOM_END), 
 
1893
    sql_command(SQLCOM_END),
1876
1894
    statement(NULL),
1877
 
    option_type(OPT_DEFAULT), 
 
1895
    option_type(OPT_DEFAULT),
1878
1896
    is_lex_started(0),
1879
1897
    cacheable(true),
1880
1898
    sum_expr_used(false),
1881
1899
    _create_table(NULL),
 
1900
    _alter_table(NULL),
1882
1901
    _create_field(NULL),
1883
1902
    _exists(false)
1884
1903
{
2070
2089
void LEX::cleanup_after_one_table_open()
2071
2090
{
2072
2091
  /*
2073
 
    session->lex->derived_tables & additional units may be set if we open
2074
 
    a view. It is necessary to clear session->lex->derived_tables flag
 
2092
    session->lex().derived_tables & additional units may be set if we open
 
2093
    a view. It is necessary to clear session->lex().derived_tables flag
2075
2094
    to prevent processing of derived tables during next openTablesLock
2076
2095
    if next table is a real table and cleanup & remove underlying units
2077
 
    NOTE: all units will be connected to session->lex->select_lex, because we
 
2096
    NOTE: all units will be connected to session->lex().select_lex, because we
2078
2097
    have not UNION on most upper level.
2079
2098
    */
2080
2099
  if (all_selects_list != &select_lex)
2150
2169
  RETURN VALUE
2151
2170
    0 on success, non-zero otherwise
2152
2171
*/
2153
 
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
 
2172
void Select_Lex::add_index_hint(Session *session, char *str, uint32_t length)
2154
2173
{
2155
 
  return index_hints->push_front (new (session->mem_root)
2156
 
                                 Index_hint(current_index_hint_type,
2157
 
                                            current_index_hint_clause,
2158
 
                                            str, length));
 
2174
  index_hints->push_front(new (session->mem_root) Index_hint(current_index_hint_type, current_index_hint_clause, str, length));
2159
2175
}
2160
2176
 
2161
2177
bool check_for_sql_keyword(drizzled::lex_string_t const& string)
2162
2178
{
2163
 
  if (sql_reserved_words::in_word_set(string.str, string.length))
2164
 
      return true;
2165
 
 
2166
 
  return false;
 
2179
  return sql_reserved_words::in_word_set(string.str, string.length);
2167
2180
}
2168
2181
 
2169
2182
bool check_for_sql_keyword(drizzled::st_lex_symbol const& string)
2170
2183
{
2171
 
  if (sql_reserved_words::in_word_set(string.str, string.length))
2172
 
      return true;
2173
 
 
2174
 
  return false;
2175
 
}
2176
 
 
 
2184
  return sql_reserved_words::in_word_set(string.str, string.length);
 
2185
}
 
2186
 
 
2187
message::AlterTable *LEX::alter_table()
 
2188
{
 
2189
  if (not _alter_table)
 
2190
    _alter_table= new message::AlterTable;
 
2191
 
 
2192
  return _alter_table;
 
2193
}
2177
2194
 
2178
2195
} /* namespace drizzled */