17
17
/* A lexical scanner on a temporary buffer with a yacc interface */
21
21
#define DRIZZLE_LEX 1
23
#include "drizzled/sql_reserved_words.h"
23
#include <drizzled/sql_reserved_words.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"
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>
41
#include <drizzled/message/alter_table.pb.h>
36
45
using namespace std;
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);
44
static int lex_one_token(void *arg, void *yysession);
53
static int lex_one_token(ParserType *arg, drizzled::Session *yysession);
47
56
save order by and tables in own lists.
221
230
void lex_start(Session *session)
223
LEX *lex= session->lex;
232
LEX *lex= &session->lex();
225
234
lex->session= lex->unit.session= session;
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;
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;
386
396
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
388
register 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();
392
402
lip->tok_bitmap= 0;
393
403
sep= lip->yyGetLast(); // String should end with this
601
611
} /* namespace drizzled */
603
DRIZZLElex remember the following states from the following DRIZZLElex()
613
base_sql_lex remember the following states from the following sql_baselex()
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)
609
int DRIZZLElex(void *arg, void *yysession)
619
int base_sql_lex(union ParserType *yylval, drizzled::Session *session)
611
drizzled::Session *session= (drizzled::Session *)yysession;
612
621
drizzled::Lex_input_stream *lip= session->m_lip;
613
YYSTYPE *yylval=(YYSTYPE*) arg;
616
624
if (lip->lookahead_token != END_OF_INPUT)
637
645
to transform the grammar into a LALR(1) grammar,
638
646
which sql_yacc.yy can process.
640
token= drizzled::lex_one_token(arg, yysession);
648
token= drizzled::lex_one_token(yylval, session);
641
649
if (token == ROLLUP_SYM)
643
651
return WITH_ROLLUP_SYM;
662
670
namespace drizzled
665
int lex_one_token(void *arg, void *yysession)
673
int lex_one_token(ParserType *yylval, drizzled::Session *session)
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;
1208
1219
state=MY_LEX_CHAR;
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
1214
1226
/* Actually real shouldn't start with . but allow them anyhow */
1215
1228
case MY_LEX_REAL_OR_POINT:
1216
1229
if (my_isdigit(cs,lip->yyPeek()))
1217
1230
state= MY_LEX_REAL; // Real
1237
1251
yylval->lex_str.str=(char*) lip->get_ptr();
1238
1252
yylval->lex_str.length=1;
1239
1253
return((int) '@');
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);
1246
1262
case MY_LEX_SYSTEM_VAR:
1247
1263
yylval->lex_str.str=(char*) lip->get_ptr();
1248
1264
yylval->lex_str.length=1;
1267
1284
lip->next_state=MY_LEX_IDENT_SEP;
1268
1286
length= lip->yyLength();
1269
1287
if (length == 0)
1270
1288
return(ABORT_SYM); // Names must be nonempty.
1271
1290
if ((tokval= find_keyword(lip, length,0)))
1273
1292
lip->yyUnget(); // Put back 'c'
1344
1363
void Select_Lex::init_query()
1346
1365
Select_Lex_Node::init_query();
1348
top_join_list.empty();
1367
top_join_list.clear();
1349
1368
join_list= &top_join_list;
1350
1369
embedding= leaf_tables= 0;
1353
1372
having= where= 0;
1354
1373
olap= UNSPECIFIED_OLAP_TYPE;
1618
1637
List<Item>* Select_Lex_Node::get_item_list()
1619
1638
{ return NULL; }
1621
TableList *Select_Lex_Node::add_table_to_list(Session *,
1640
TableList *Select_Lex_Node::add_table_to_list(Session *,
1624
1643
const bitset<NUM_OF_TABLE_OPTIONS>&,
1662
1681
bool Select_Lex::add_item_to_list(Session *, Item *item)
1664
return(item_list.push_back(item));
1683
item_list.push_back(item);
1667
1687
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
1715
1735
return (ref_pointer_array=
1716
1736
(Item **)session->getMemRoot()->allocate(sizeof(Item*) * (n_child_sum_items +
1717
item_list.elements +
1718
1738
select_n_having_items +
1719
1739
select_n_where_fields +
1720
1740
order_group_num)*5)) == 0;
1723
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
1743
void Select_Lex_Unit::print(String *str)
1725
1745
bool union_all= !union_distinct;
1726
1746
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1746
1766
str->append(STRING_WITH_LEN(" order by "));
1747
1767
fake_select_lex->print_order(
1749
(Order *) fake_select_lex->order_list.first,
1769
(Order *) fake_select_lex->order_list.first);
1752
fake_select_lex->print_limit(session, str, query_type);
1771
fake_select_lex->print_limit(session, str);
1756
1775
void Select_Lex::print_order(String *str,
1758
enum_query_type query_type)
1760
1778
for (; order; order= order->next)
1766
1784
str->append(buffer, length);
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)
1777
void Select_Lex::print_limit(Session *, String *str,
1778
enum_query_type query_type)
1795
void Select_Lex::print_limit(Session *, String *str)
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)
1809
offset_limit->print(str, query_type);
1826
offset_limit->print(str);
1810
1827
str->append(',');
1812
select_limit->print(str, query_type);
1829
select_limit->print(str);
1818
1835
delete _create_table;
1836
delete _alter_table;
2070
2089
void LEX::cleanup_after_one_table_open()
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.
2080
2099
if (all_selects_list != &select_lex)
2151
2170
0 on success, non-zero otherwise
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)
2155
return index_hints->push_front (new (session->mem_root)
2156
Index_hint(current_index_hint_type,
2157
current_index_hint_clause,
2174
index_hints->push_front(new (session->mem_root) Index_hint(current_index_hint_type, current_index_hint_clause, str, length));
2161
2177
bool check_for_sql_keyword(drizzled::lex_string_t const& string)
2163
if (sql_reserved_words::in_word_set(string.str, string.length))
2179
return sql_reserved_words::in_word_set(string.str, string.length);
2169
2182
bool check_for_sql_keyword(drizzled::st_lex_symbol const& string)
2171
if (sql_reserved_words::in_word_set(string.str, string.length))
2184
return sql_reserved_words::in_word_set(string.str, string.length);
2187
message::AlterTable *LEX::alter_table()
2189
if (not _alter_table)
2190
_alter_table= new message::AlterTable;
2192
return _alter_table;
2178
2195
} /* namespace drizzled */