17
17
/* A lexical scanner on a temporary buffer with a yacc interface */
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"
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>
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>
32
45
using namespace std;
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);
40
static int lex_one_token(void *arg, void *yysession);
53
static int lex_one_token(ParserType *arg, drizzled::Session *yysession);
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)
48
if (!(order = (Order *) session->alloc(sizeof(Order))))
62
if (!(order = (Order *) session->getMemRoot()->allocate(sizeof(Order))))
50
65
order->item_ptr= item;
51
66
order->item= &order->item_ptr;
55
70
order->counter_used= 0;
56
list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
71
list.link_in_list((unsigned char*) order, (unsigned char**) &order->next);
89
105
in_comment(NO_COMMENT)
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;
95
Lex_input_stream::~Lex_input_stream()
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
103
2) Determine the beginning of the body.
105
@param session Thread context.
106
@param begin_ptr Pointer to the start of the body in the pre-processed
109
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
112
assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
114
uint32_t body_utf8_length=
115
(m_buf_length / default_charset_info->mbminlen) *
116
my_charset_utf8_bin.mbmaxlen;
118
m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
119
m_body_utf8_ptr= m_body_utf8;
122
m_cpp_utf8_processed_ptr= begin_ptr;
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.
214
200
void lex_start(Session *session)
216
LEX *lex= session->lex;
202
LEX *lex= &session->lex();
218
204
lex->session= lex->unit.session= session;
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;
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;
315
bool is_lex_native_function(const LEX_STRING *name)
317
assert(name != NULL);
318
return (lookup_symbol(name->str, name->length, 1) != 0);
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)
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;
375
360
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
377
register 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();
381
366
lip->tok_bitmap= 0;
382
367
sep= lip->yyGetLast(); // String should end with this
424
409
assert(end >= str);
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
429
414
lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
590
575
} /* namespace drizzled */
592
DRIZZLElex remember the following states from the following DRIZZLElex()
577
base_sql_lex remember the following states from the following sql_baselex()
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)
598
int DRIZZLElex(void *arg, void *yysession)
583
int base_sql_lex(union ParserType *yylval, drizzled::Session *session)
600
drizzled::Session *session= (drizzled::Session *)yysession;
601
585
drizzled::Lex_input_stream *lip= session->m_lip;
602
YYSTYPE *yylval=(YYSTYPE*) arg;
605
588
if (lip->lookahead_token != END_OF_INPUT)
626
609
to transform the grammar into a LALR(1) grammar,
627
610
which sql_yacc.yy can process.
629
token= drizzled::lex_one_token(arg, yysession);
612
token= drizzled::lex_one_token(yylval, session);
630
613
if (token == ROLLUP_SYM)
632
615
return WITH_ROLLUP_SYM;
651
634
namespace drizzled
654
int lex_one_token(void *arg, void *yysession)
637
int lex_one_token(ParserType *yylval, drizzled::Session *session)
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;
1197
1183
state=MY_LEX_CHAR;
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
1203
1190
/* Actually real shouldn't start with . but allow them anyhow */
1204
1192
case MY_LEX_REAL_OR_POINT:
1205
1193
if (my_isdigit(cs,lip->yyPeek()))
1206
1194
state= MY_LEX_REAL; // Real
1226
1215
yylval->lex_str.str=(char*) lip->get_ptr();
1227
1216
yylval->lex_str.length=1;
1228
1217
return((int) '@');
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);
1235
1226
case MY_LEX_SYSTEM_VAR:
1236
1227
yylval->lex_str.str=(char*) lip->get_ptr();
1237
1228
yylval->lex_str.length=1;
1256
1248
lip->next_state=MY_LEX_IDENT_SEP;
1257
1250
length= lip->yyLength();
1258
1251
if (length == 0)
1259
1252
return(ABORT_SYM); // Names must be nonempty.
1260
1254
if ((tokval= find_keyword(lip, length,0)))
1262
1256
lip->yyUnget(); // Put back 'c'
1276
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
1280
This code assumes that there are no multi-bytes characters
1281
that can be considered white-space.
1283
while ((str->length > 0) && (my_isspace(cs, str->str[0])))
1291
Also, parsing backward is not safe with multi bytes characters
1293
while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
1300
1271
Select_Lex structures initialisations
1333
1304
void Select_Lex::init_query()
1335
1306
Select_Lex_Node::init_query();
1337
top_join_list.empty();
1308
top_join_list.clear();
1338
1309
join_list= &top_join_list;
1339
1310
embedding= leaf_tables= 0;
1342
1313
having= where= 0;
1343
1314
olap= UNSPECIFIED_OLAP_TYPE;
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;
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();
1606
1578
List<Item>* Select_Lex_Node::get_item_list()
1607
1579
{ return NULL; }
1609
TableList *Select_Lex_Node::add_table_to_list(Session *,
1581
TableList *Select_Lex_Node::add_table_to_list(Session *,
1612
1584
const bitset<NUM_OF_TABLE_OPTIONS>&,
1650
1622
bool Select_Lex::add_item_to_list(Session *, Item *item)
1652
return(item_list.push_back(item));
1624
item_list.push_back(item);
1655
1628
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
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 +
1706
1679
select_n_having_items +
1707
1680
select_n_where_fields +
1708
1681
order_group_num)*5)) == 0;
1711
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
1684
void Select_Lex_Unit::print(String *str)
1713
1686
bool union_all= !union_distinct;
1714
1687
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1734
1707
str->append(STRING_WITH_LEN(" order by "));
1735
1708
fake_select_lex->print_order(
1737
(Order *) fake_select_lex->order_list.first,
1710
(Order *) fake_select_lex->order_list.first);
1740
fake_select_lex->print_limit(session, str, query_type);
1712
fake_select_lex->print_limit(session, str);
1744
1716
void Select_Lex::print_order(String *str,
1746
enum_query_type query_type)
1748
1719
for (; order; order= order->next)
1754
1725
str->append(buffer, length);
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)
1765
void Select_Lex::print_limit(Session *, String *str,
1766
enum_query_type query_type)
1736
void Select_Lex::print_limit(Session *, String *str)
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)
1797
offset_limit->print(str, query_type);
1767
offset_limit->print(str);
1798
1768
str->append(',');
1800
select_limit->print(str, query_type);
1770
select_limit->print(str);
1805
@brief Restore the LEX and Session in case of a parse error.
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.
1815
void LEX::cleanup_lex_after_parse_error(Session *)
1776
delete _create_table;
1777
delete _alter_table;
1863
1824
statement parsing. On should use lex_start() function to prepare LEX
1872
sql_command(SQLCOM_END),
1873
option_type(OPT_DEFAULT),
1834
sql_command(SQLCOM_END),
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),
1842
_create_field(NULL),
1878
1845
reset_query_tables_list(true);
2064
2030
void LEX::cleanup_after_one_table_open()
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.
2074
2040
if (all_selects_list != &select_lex)
2145
2111
0 on success, non-zero otherwise
2147
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
2149
return index_hints->push_front (new (session->mem_root)
2150
Index_hint(current_index_hint_type,
2151
current_index_hint_clause,
2113
void Select_Lex::add_index_hint(Session *session, char *str, uint32_t length)
2115
index_hints->push_front(new (session->mem_root) Index_hint(current_index_hint_type, current_index_hint_clause, str, length));
2118
message::AlterTable *LEX::alter_table()
2120
if (not _alter_table)
2121
_alter_table= new message::AlterTable;
2123
return _alter_table;
2155
2126
} /* namespace drizzled */