1
/* Copyright (C) 2000-2006 MySQL AB
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.
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.
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 */
17
/* A lexical scanner on a temporary buffer with a yacc interface */
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"
33
/* Stay outside of the namespace because otherwise bison goes nuts */
34
int DRIZZLElex(void *arg, void *yysession);
39
static int lex_one_token(void *arg, void *yysession);
42
save order by and tables in own lists.
44
static bool add_to_list(Session *session, SQL_LIST &list, Item *item, bool asc)
47
if (!(order = (order_st *) session->alloc(sizeof(order_st))))
49
order->item_ptr= item;
50
order->item= &order->item_ptr;
54
order->counter_used= 0;
55
list.link_in_list((unsigned char*) order,(unsigned char**) &order->next);
60
LEX_STRING constant for null-string to be used in parser and other places.
62
const LEX_STRING null_lex_str= {NULL, 0};
64
Lex_input_stream::Lex_input_stream(Session *session,
71
lookahead_token(END_OF_INPUT),
72
lookahead_yylval(NULL),
76
m_end_of_query(buffer + length),
77
m_tok_start_prev(NULL),
81
m_cpp_tok_start(NULL),
82
m_cpp_tok_start_prev(NULL),
85
m_cpp_utf8_processed_ptr(NULL),
86
next_state(MY_LEX_START),
88
in_comment(NO_COMMENT)
90
m_cpp_buf= (char*) session->alloc(length + 1);
94
Lex_input_stream::~Lex_input_stream()
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
102
2) Determine the beginning of the body.
104
@param session Thread context.
105
@param begin_ptr Pointer to the start of the body in the pre-processed
108
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
111
assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
113
uint32_t body_utf8_length=
114
(m_buf_length / default_charset_info->mbminlen) *
115
my_charset_utf8_bin.mbmaxlen;
117
m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
118
m_body_utf8_ptr= m_body_utf8;
121
m_cpp_utf8_processed_ptr= begin_ptr;
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.
128
The idea is that some tokens in the pre-processed buffer (like character
129
set introducers) should be skipped.
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'...">)
137
@param ptr Pointer in the pre-processed buffer, which specifies the
138
end of the chunk, which should be appended to the utf8
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
144
void Lex_input_stream::body_utf8_append(const char *ptr,
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);
153
if (m_cpp_utf8_processed_ptr >= ptr)
156
int bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;
158
memcpy(m_body_utf8_ptr, m_cpp_utf8_processed_ptr, bytes_to_copy);
159
m_body_utf8_ptr += bytes_to_copy;
162
m_cpp_utf8_processed_ptr= end_ptr;
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.
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.
172
void Lex_input_stream::body_utf8_append(const char *ptr)
174
body_utf8_append(ptr, ptr);
178
The operation converts the specified text literal to the utf8 and appends
179
the result to the utf8-body.
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
188
void Lex_input_stream::body_utf8_append_literal(const LEX_STRING *txt,
191
if (!m_cpp_utf8_processed_ptr)
194
/* NOTE: utf_txt.length is in bytes, not in symbols. */
196
memcpy(m_body_utf8_ptr, txt->str, txt->length);
197
m_body_utf8_ptr += txt->length;
200
m_cpp_utf8_processed_ptr= end_ptr;
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)
208
void lex_start(Session *session)
210
LEX *lex= session->lex;
212
lex->session= lex->unit.session= session;
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();
236
lex->derived_tables= 0;
237
lex->lock_option= TL_READ;
238
lex->leaf_tables_insert= 0;
239
lex->select_lex.select_number= 1;
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;
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;
256
lex->allow_sum_func= 0;
257
lex->in_sum_func= NULL;
259
lex->is_lex_started= true;
260
lex->statement= NULL;
263
void lex_end(LEX *lex)
267
free(lex->yacc_yyss);
268
free(lex->yacc_yyvs);
278
delete lex->statement;
281
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
283
/* Plenty of memory for the largest lex symbol we have */
285
const char *tok= lip->get_tok_start();
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;
291
const SYMBOL *symbol= lookup_symbol(tok_upper, len, function);
294
lip->yylval->symbol.symbol=symbol;
295
lip->yylval->symbol.str= (char*) tok;
296
lip->yylval->symbol.length=len;
304
bool is_lex_native_function(const LEX_STRING *name)
306
assert(name != NULL);
307
return (lookup_symbol(name->str, name->length, 1) != 0);
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)
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);
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;
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)
330
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
332
uint32_t length, char quote)
335
const char *from, *end;
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;
344
lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
345
lip->m_cpp_text_end= lip->m_cpp_text_start + length;
349
if ((*to++= *from++) == quote)
351
from++; // Skip double quotes
352
lip->m_cpp_text_start++;
355
*to= 0; // End null for safety
361
Return an unescaped text literal without quotes
362
Fix sometimes to do only one scan of the string
364
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
366
register unsigned char c,sep;
367
bool found_escape= false;
368
const CHARSET_INFO * const cs= lip->m_session->charset();
371
sep= lip->yyGetLast(); // String should end with this
379
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
382
lip->skip_binary(l-1);
388
{ // Escaped character
396
if (c == lip->yyGet()) // Check if two separators in a row
398
found_escape= true; // duplicate. Remember for delete
404
/* Found end. Unescape and return string */
405
const char *str, *end;
408
str= lip->get_tok_start();
410
/* Extract the text from the token */
415
if (!(start= (char*) lip->m_session->alloc((uint32_t) (end-str)+1)))
416
return (char*) ""; // memory::SqlAlloc has set error flag
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;
423
lip->yytoklen= (uint32_t) (end-str);
424
memcpy(start, str, lip->yytoklen);
425
start[lip->yytoklen]= 0;
431
for (to= start; str != end; str++)
435
int l= my_ismbchar(cs, str, end);
444
if (*str == '\\' && (str + 1) != end)
460
*to++= 0; // Ascii null
462
case 'Z': // ^Z must be escaped on Win32
467
*to++= '\\'; // remember prefix for wildcard
474
else if (*str == sep)
475
*to++= *str++; // Two ' or "
480
lip->yytoklen= (uint32_t) (to - start);
485
return 0; // unexpected end of query
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.
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;
507
static inline uint32_t int_token(const char *str,uint32_t length)
509
if (length < long_len) // quick normal case
513
if (*str == '+') // Remove sign and pre-zeros
517
else if (*str == '-')
522
while (*str == '0' && length)
526
if (length < long_len)
529
uint32_t smaller,bigger;
533
if (length == long_len)
535
cmp= signed_long_str+1;
536
smaller=NUM; // If <= signed_long_str
537
bigger=LONG_NUM; // If >= signed_long_str
539
else if (length < signed_int64_t_len)
541
else if (length > signed_int64_t_len)
545
cmp=signed_int64_t_str+1;
546
smaller=LONG_NUM; // If <= signed_int64_t_str
552
if (length == long_len)
558
else if (length < int64_t_len)
560
else if (length > int64_t_len)
562
if (length > unsigned_int64_t_len)
564
cmp=unsigned_int64_t_str;
565
smaller=ULONGLONG_NUM;
572
bigger= ULONGLONG_NUM;
575
while (*cmp && *cmp++ == *str++) ;
576
return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
579
} /* namespace drizzled */
581
DRIZZLElex remember the following states from the following DRIZZLElex()
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)
587
int DRIZZLElex(void *arg, void *yysession)
589
drizzled::Session *session= (drizzled::Session *)yysession;
590
drizzled::Lex_input_stream *lip= session->m_lip;
591
YYSTYPE *yylval=(YYSTYPE*) arg;
594
if (lip->lookahead_token != END_OF_INPUT)
597
The next token was already parsed in advance,
600
token= lip->lookahead_token;
601
lip->lookahead_token= END_OF_INPUT;
602
*yylval= *(lip->lookahead_yylval);
603
lip->lookahead_yylval= NULL;
607
token= drizzled::lex_one_token(arg, yysession);
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.
618
token= drizzled::lex_one_token(arg, yysession);
619
if (token == ROLLUP_SYM)
621
return WITH_ROLLUP_SYM;
626
Save the token following 'WITH'
628
lip->lookahead_yylval= lip->yylval;
630
lip->lookahead_token= token;
643
int lex_one_token(void *arg, void *yysession)
645
register unsigned char c= 0; /* Just set to shutup GCC */
647
int tokval, result_state;
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;
658
lip->yylval=yylval; // The global state
661
state=lip->next_state;
662
lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
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)
677
/* Start of real token */
678
lip->restart_token();
680
state= (enum my_lex_states) state_map[c];
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;
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))))
695
state=MY_LEX_COMMENT;
700
lip->next_state= MY_LEX_START; // Allow signed numbers
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.
713
lip->restart_token();
718
case MY_LEX_IDENT_OR_HEX:
719
if (lip->yyPeek() == '\'')
720
{ // Found x'hex-number'
721
state= MY_LEX_HEX_NUMBER;
724
case MY_LEX_IDENT_OR_BIN:
725
if (lip->yyPeek() == '\'')
726
{ // Found b'bin-number'
727
state= MY_LEX_BIN_NUMBER;
734
result_state= IDENT_QUOTED;
735
if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
737
int l = my_ismbchar(cs,
739
lip->get_end_of_query());
744
lip->skip_binary(l - 1);
746
while (ident_map[c=lip->yyGet()])
748
if (my_mbcharlen(cs, c) > 1)
750
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
753
lip->skip_binary(l-1);
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;
763
length= lip->yyLength();
764
start= lip->get_ptr();
765
if (lip->ignore_space)
768
If we find a space then this can't be an identifier. We notice this
769
below by checking start != lex->ptr.
771
for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
773
if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
774
lip->next_state=MY_LEX_IDENT_SEP;
776
{ // '(' must follow directly if function
778
if ((tokval = find_keyword(lip, length, c == '(')))
780
lip->next_state= MY_LEX_START; // Allow signed numbers
781
return(tokval); // Was keyword
783
lip->yySkip(); // next state does a unget
785
yylval->lex_str=get_token(lip, 0, length);
787
lip->body_utf8_append(lip->m_cpp_text_start);
789
lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
791
return(result_state); // IDENT or IDENT_QUOTED
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;
802
case MY_LEX_NUMBER_IDENT: // number or ident which num-start
803
if (lip->yyGetLast() == '0')
808
while (my_isxdigit(cs,(c = lip->yyGet()))) ;
809
if ((lip->yyLength() >= 3) && !ident_map[c])
812
yylval->lex_str=get_token(lip, 2, lip->yyLength()-2);
816
state= MY_LEX_IDENT_START;
821
while ((c= lip->yyGet()) == '0' || c == '1') {};
822
if ((lip->yyLength() >= 3) && !ident_map[c])
825
yylval->lex_str= get_token(lip, 2, lip->yyLength()-2);
829
state= MY_LEX_IDENT_START;
835
while (my_isdigit(cs, (c = lip->yyGet()))) ;
837
{ // Can't be identifier
838
state=MY_LEX_INT_OR_REAL;
841
if (c == 'e' || c == 'E')
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 == '-')
847
if (my_isdigit(cs,lip->yyPeek())) // Number must have digit after sign
850
while (my_isdigit(cs,lip->yyGet())) ;
851
yylval->lex_str=get_token(lip, 0, lip->yyLength());
858
case MY_LEX_IDENT_START: // We come here after '.'
862
result_state= IDENT_QUOTED;
863
while (ident_map[c=lip->yyGet()])
865
if (my_mbcharlen(cs, c) > 1)
867
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
870
lip->skip_binary(l-1);
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;
880
if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
881
lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
883
yylval->lex_str= get_token(lip, 0, lip->yyLength());
885
lip->body_utf8_append(lip->m_cpp_text_start);
887
lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
889
return(result_state);
891
case MY_LEX_USER_VARIABLE_DELIMITER: // Found quote char
893
uint32_t double_quotes= 0;
894
char quote_char= c; // Used char
895
while ((c=lip->yyGet()))
898
if ((var_length= my_mbcharlen(cs, c)) == 1)
902
if (lip->yyPeek() != quote_char)
909
else if (var_length < 1)
911
lip->skip_binary(var_length-1);
914
yylval->lex_str=get_quoted_token(lip, 1, lip->yyLength() - double_quotes -1, quote_char);
916
yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
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);
924
case MY_LEX_INT_OR_REAL: // Complete int or incomplete real
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);
931
case MY_LEX_REAL: // Incomplete real number
932
while (my_isdigit(cs,c = lip->yyGet())) ;
934
if (c == 'e' || c == 'E')
937
if (c == '-' || c == '+')
938
c = lip->yyGet(); // Skip sign
939
if (!my_isdigit(cs,c))
940
{ // No digit after sign
944
while (my_isdigit(cs,lip->yyGet())) ;
945
yylval->lex_str=get_token(lip, 0, lip->yyLength());
948
yylval->lex_str=get_token(lip, 0, lip->yyLength());
951
case MY_LEX_HEX_NUMBER: // Found x'hexstring'
952
lip->yySkip(); // Accept opening '
953
while (my_isxdigit(cs, (c= lip->yyGet()))) ;
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,
962
length-3); // don't count x' and last '
965
case MY_LEX_BIN_NUMBER: // Found b'bin-string'
966
lip->yySkip(); // Accept opening '
967
while ((c= lip->yyGet()) == '0' || c == '1') {};
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,
974
length-3); // don't count b' and last '
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)
981
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
983
lip->next_state= MY_LEX_START; // Allow signed numbers
986
state = MY_LEX_CHAR; // Something fishy found
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)
994
if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP)
997
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
999
lip->next_state= MY_LEX_START; // Found long op
1002
state = MY_LEX_CHAR; // Something fishy found
1006
if (c != lip->yyPeek())
1012
tokval = find_keyword(lip,2,0); // Is a bool operator
1013
lip->next_state= MY_LEX_START; // Allow signed numbers
1016
case MY_LEX_STRING_OR_DELIMITER:
1019
state= MY_LEX_USER_VARIABLE_DELIMITER;
1022
/* " used for strings */
1023
case MY_LEX_STRING: // Incomplete text string
1024
if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
1026
state= MY_LEX_CHAR; // Read char by char
1029
yylval->lex_str.length=lip->yytoklen;
1031
lip->body_utf8_append(lip->m_cpp_text_start);
1033
lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1035
lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
1036
return(TEXT_STRING);
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
1044
case MY_LEX_LONG_COMMENT: /* Long C comment? */
1045
if (lip->yyPeek() != '*')
1047
state=MY_LEX_CHAR; // Probable division
1050
lex->select_lex.options|= OPTION_FOUND_COMMENT;
1051
/* Reject '/' '*', since we might need to turn off the echo */
1054
if (lip->yyPeekn(2) == '!')
1056
lip->in_comment= DISCARD_COMMENT;
1057
/* Accept '/' '*' '!', but do not keep this marker. */
1058
lip->set_echo(false);
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
1068
const int MAX_VERSION_SIZE= 16;
1069
char version_str[MAX_VERSION_SIZE];
1074
version_str[pos]= lip->yyPeekn(pos);
1076
} while ((pos < MAX_VERSION_SIZE-1) && isdigit(version_str[pos-1]));
1077
version_str[pos]= 0;
1079
/* To keep some semblance of compatibility, we impose a 5 digit floor */
1083
version=strtoll(version_str, NULL, 10);
1085
/* Accept 'M' 'm' 'm' 'd' 'd' */
1086
lip->yySkipn(pos-1);
1088
if (version <= DRIZZLE_VERSION_ID)
1090
/* Expand the content of the special comment as real code */
1091
lip->set_echo(true);
1099
lip->set_echo(true);
1105
lip->in_comment= PRESERVE_COMMENT;
1106
lip->yySkip(); // Accept /
1107
lip->yySkip(); // Accept *
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.
1117
comment_closed= false;
1118
while (! lip->eof())
1123
if (lip->yyPeek() == '/')
1126
comment_closed= true;
1127
state = MY_LEX_START;
1134
/* Unbalanced comments with a missing '*' '/' are a syntax error */
1135
if (! comment_closed)
1137
state = MY_LEX_START; // Try again
1138
lip->in_comment= NO_COMMENT;
1139
lip->set_echo(true);
1141
case MY_LEX_END_LONG_COMMENT:
1142
if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
1144
/* Reject '*' '/' */
1146
/* Accept '*' '/', with the proper echo */
1147
lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
1149
/* And start recording the tokens again */
1150
lip->set_echo(true);
1151
lip->in_comment=NO_COMMENT;
1155
state=MY_LEX_CHAR; // Return '*'
1157
case MY_LEX_SET_VAR: // Check if ':='
1158
if (lip->yyPeek() != '=')
1160
state=MY_LEX_CHAR; // Return ':'
1165
case MY_LEX_SEMICOLON: // optional line terminator
1168
state= MY_LEX_CHAR; // Return ';'
1171
lip->next_state=MY_LEX_END; // Mark for next loop
1172
return(END_OF_INPUT);
1176
lip->yyUnget(); // Reject the last '\0'
1177
lip->set_echo(false);
1179
lip->set_echo(true);
1180
/* Unbalanced comments with a missing '*' '/' are a syntax error */
1181
if (lip->in_comment != NO_COMMENT)
1183
lip->next_state=MY_LEX_END; // Mark for next loop
1184
return(END_OF_INPUT);
1189
lip->next_state=MY_LEX_END;
1190
return false; // We found end of input last time
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
1198
state= MY_LEX_IDENT_SEP; // return '.'
1199
lip->yyUnget(); // Put back '.'
1202
case MY_LEX_USER_END: // end '@' of user@hostname
1203
switch (state_map[(uint8_t)lip->yyPeek()]) {
1205
case MY_LEX_USER_VARIABLE_DELIMITER:
1206
case MY_LEX_STRING_OR_DELIMITER:
1208
case MY_LEX_USER_END:
1209
lip->next_state=MY_LEX_SYSTEM_VAR;
1212
lip->next_state=MY_LEX_HOSTNAME;
1215
yylval->lex_str.str=(char*) lip->get_ptr();
1216
yylval->lex_str.length=1;
1218
case MY_LEX_HOSTNAME: // end '@' of user@hostname
1219
for (c=lip->yyGet() ;
1220
my_isalnum(cs,c) || c == '.' || c == '_' || c == '$';
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);
1233
case MY_LEX_IDENT_OR_KEYWORD:
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
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;
1245
lip->next_state=MY_LEX_IDENT_SEP;
1246
length= lip->yyLength();
1248
return(ABORT_SYM); // Names must be nonempty.
1249
if ((tokval= find_keyword(lip, length,0)))
1251
lip->yyUnget(); // Put back 'c'
1252
return(tokval); // Was keyword
1254
yylval->lex_str=get_token(lip, 0, length);
1256
lip->body_utf8_append(lip->m_cpp_text_start);
1258
lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
1260
return(result_state);
1265
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
1269
This code assumes that there are no multi-bytes characters
1270
that can be considered white-space.
1272
while ((str->length > 0) && (my_isspace(cs, str->str[0])))
1280
Also, parsing backward is not safe with multi bytes characters
1282
while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
1289
Select_Lex structures initialisations
1291
void Select_Lex_Node::init_query()
1294
linkage= UNSPECIFIED_TYPE;
1295
no_error= no_table_names_allowed= 0;
1299
void Select_Lex_Node::init_select()
1303
void Select_Lex_Unit::init_query()
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;
1311
prepared= optimized= executed= 0;
1319
found_rows_for_union= 0;
1322
void Select_Lex::init_query()
1324
Select_Lex_Node::init_query();
1326
top_join_list.empty();
1327
join_list= &top_join_list;
1328
embedding= leaf_tables= 0;
1332
olap= UNSPECIFIED_OLAP_TYPE;
1333
having_fix_field= 0;
1334
context.select_lex= this;
1337
Add the name resolution context of the current (sub)query to the
1338
stack of contexts for the whole query.
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.
1345
parent_lex->push_context(&context);
1346
cond_count= between_count= with_wild= 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;
1359
void Select_Lex::init_select()
1365
table_join_options= 0;
1366
in_sum_expr= with_wild= 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 */
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();
1388
Select_Lex structures linking
1391
/* include on level down */
1392
void Select_Lex_Node::include_down(Select_Lex_Node *upper)
1394
if ((next= upper->slave))
1396
prev= &upper->slave;
1403
include on level down (but do not link)
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
1410
void Select_Lex_Node::include_standalone(Select_Lex_Node *upper,
1411
Select_Lex_Node **ref)
1419
/* include neighbour (on same level) */
1420
void Select_Lex_Node::include_neighbour(Select_Lex_Node *before)
1422
if ((next= before->next))
1424
prev= &before->next;
1426
master= before->master;
1430
/* including in global Select_Lex list */
1431
void Select_Lex_Node::include_global(Select_Lex_Node **plink)
1433
if ((link_next= *plink))
1434
link_next->link_prev= &link_next;
1439
//excluding from global list (internal function)
1440
void Select_Lex_Node::fast_exclude()
1444
if ((*link_prev= link_next))
1445
link_next->link_prev= link_prev;
1447
// Remove slave structure
1448
for (; slave; slave= slave->next)
1449
slave->fast_exclude();
1454
excluding select_lex structure (except first (first select can't be
1455
deleted, because it is most upper select))
1457
void Select_Lex_Node::exclude()
1459
//exclude from global list
1461
//exclude from other structures
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;
1474
Exclude level of current unit from tree of SELECTs
1477
Select_Lex_Unit::exclude_level()
1479
NOTE: units which belong to current will be brought up on level of
1482
void Select_Lex_Unit::exclude_level()
1484
Select_Lex_Unit *units= 0, **units_last= &units;
1485
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
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;
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())
1496
last= (Select_Lex_Unit**)&(u->next);
1500
(*units_last)= sl->first_inner_unit();
1506
// include brought up levels in place of current
1508
(*units_last)= (Select_Lex_Unit*)next;
1510
next->prev= (Select_Lex_Node**)units_last;
1515
// exclude currect unit from list of nodes
1523
Exclude subtree of current unit from tree of SELECTs
1525
void Select_Lex_Unit::exclude_tree()
1527
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
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;
1533
// unlink underlay levels
1534
for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
1539
// exclude currect unit from list of nodes
1546
* Mark all Select_Lex struct from this to 'last' as dependent
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
1552
void Select_Lex::mark_as_dependent(Select_Lex *last)
1555
Mark all selects from resolved to 1 before select where was
1556
found table as depended (of select where was found table)
1558
for (Select_Lex *s= this;
1560
s= s->outer_select())
1562
if (!(s->uncacheable & UNCACHEABLE_DEPENDENT))
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())
1573
!(sl->uncacheable & (UNCACHEABLE_DEPENDENT | UNCACHEABLE_UNITED)))
1574
sl->uncacheable|= UNCACHEABLE_UNITED;
1577
s->is_correlated= true;
1578
Item_subselect *subquery_predicate= s->master_unit()->item;
1579
if (subquery_predicate)
1580
subquery_predicate->is_correlated= true;
1584
bool Select_Lex_Node::set_braces(bool)
1587
bool Select_Lex_Node::inc_in_sum_expr()
1590
uint32_t Select_Lex_Node::get_in_sum_expr()
1593
TableList* Select_Lex_Node::get_table_list()
1596
List<Item>* Select_Lex_Node::get_item_list()
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 *)
1605
uint32_t Select_Lex_Node::get_table_join_options()
1611
prohibit using LIMIT clause
1613
bool Select_Lex::test_limit()
1615
if (select_limit != 0)
1617
my_error(ER_NOT_SUPPORTED_YET, MYF(0),
1618
"LIMIT & IN/ALL/ANY/SOME subquery");
1624
Select_Lex_Unit* Select_Lex_Unit::master_unit()
1629
Select_Lex* Select_Lex_Unit::outer_select()
1631
return (Select_Lex*) master;
1634
bool Select_Lex::add_order_to_list(Session *session, Item *item, bool asc)
1636
return add_to_list(session, order_list, item, asc);
1639
bool Select_Lex::add_item_to_list(Session *, Item *item)
1641
return(item_list.push_back(item));
1644
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
1646
return add_to_list(session, group_list, item, asc);
1649
Select_Lex_Unit* Select_Lex::master_unit()
1651
return (Select_Lex_Unit*) master;
1654
Select_Lex* Select_Lex::outer_select()
1656
return (Select_Lex*) master->get_master();
1659
bool Select_Lex::set_braces(bool value)
1665
bool Select_Lex::inc_in_sum_expr()
1671
uint32_t Select_Lex::get_in_sum_expr()
1676
TableList* Select_Lex::get_table_list()
1678
return (TableList*) table_list.first;
1681
List<Item>* Select_Lex::get_item_list()
1686
uint32_t Select_Lex::get_table_join_options()
1688
return table_join_options;
1691
bool Select_Lex::setup_ref_array(Session *session, uint32_t order_group_num)
1693
if (ref_pointer_array)
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;
1704
void Select_Lex_Unit::print(String *str, enum_query_type query_type)
1706
bool union_all= !union_distinct;
1707
for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
1709
if (sl != first_select())
1711
str->append(STRING_WITH_LEN(" union "));
1713
str->append(STRING_WITH_LEN("all "));
1714
else if (union_distinct == sl)
1719
sl->print(session, str, query_type);
1723
if (fake_select_lex == global_parameters)
1725
if (fake_select_lex->order_list.elements)
1727
str->append(STRING_WITH_LEN(" order by "));
1728
fake_select_lex->print_order(
1730
(order_st *) fake_select_lex->order_list.first,
1733
fake_select_lex->print_limit(session, str, query_type);
1737
void Select_Lex::print_order(String *str,
1739
enum_query_type query_type)
1741
for (; order; order= order->next)
1743
if (order->counter_used)
1746
uint32_t length= snprintf(buffer, 20, "%d", order->counter);
1747
str->append(buffer, length);
1750
(*order->item)->print(str, query_type);
1752
str->append(STRING_WITH_LEN(" desc"));
1758
void Select_Lex::print_limit(Session *, String *str,
1759
enum_query_type query_type)
1761
Select_Lex_Unit *unit= master_unit();
1762
Item_subselect *item= unit->item;
1764
if (item && unit->global_parameters == this)
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)
1771
assert(!item->fixed ||
1773
If not using materialization both:
1774
select_limit == 1, and there should be no offset_limit.
1776
(((subs_type == Item_subselect::IN_SUBS) &&
1777
((Item_in_subselect*)item)->exec_method ==
1778
Item_in_subselect::MATERIALIZATION) ?
1780
(select_limit->val_int() == 1L) &&
1781
offset_limit == 0));
1787
str->append(STRING_WITH_LEN(" limit "));
1790
offset_limit->print(str, query_type);
1793
select_limit->print(str, query_type);
1798
@brief Restore the LEX and Session in case of a parse error.
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.
1808
void LEX::cleanup_lex_after_parse_error(Session *)
1813
Initialize (or reset) Query_tables_list object.
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
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.
1829
void Query_tables_list::reset_query_tables_list(bool init)
1831
if (!init && query_tables)
1833
TableList *table= query_tables;
1836
if (query_tables_last == &table->next_global ||
1837
!(table= table->next_global))
1842
query_tables_last= &query_tables;
1843
query_tables_own_last= 0;
1847
Initialize LEX object.
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
1860
:result(0), yacc_yyss(0), yacc_yyvs(0),
1861
sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
1863
reset_query_tables_list(true);
1868
Detect that we need only table structure of derived table/view
1871
only_view_structure()
1874
true yes, we need only structure
1875
false no, we need data
1877
bool LEX::only_view_structure()
1879
if (sql_command == SQLCOM_SHOW_CREATE)
1886
Should Items_ident be printed correctly
1889
need_correct_ident()
1892
true yes, we need only structure
1893
false no, we need data
1895
bool LEX::need_correct_ident()
1897
if (sql_command== SQLCOM_SHOW_CREATE)
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:
1912
CREATE PROCEDURE foo.p1() BEGIN SELECT * FROM t1 END//
1914
t1 is meant to refer to foo.t1, not to bar.t1.
1916
This method is needed to support this rule.
1918
@return true in case of error (parsing should be aborted, false in
1921
bool LEX::copy_db_to(char **p_db, size_t *p_db_length) const
1923
return session->copy_db_to(p_db, p_db_length);
1927
initialize limit counters
1930
Select_Lex_Unit::set_limit()
1931
values - Select_Lex with initial values for counters
1933
void Select_Lex_Unit::set_limit(Select_Lex *sl)
1935
ha_rows select_limit_val;
1938
val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
1939
select_limit_val= (ha_rows)val;
1941
Check for overflow : ha_rows can be smaller then uint64_t if
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() :
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
1954
Unlink the first table from the global table list and the first table from
1955
outer select (lex->select_lex) local list
1958
unlink_first_table()
1959
link_to_local Set to 1 if caller should link this table to local list
1962
We assume that first tables in both lists is the same table or the local
1966
0 If 'query_tables' == 0
1968
In this case link_to_local is set.
1971
TableList *LEX::unlink_first_table(bool *link_to_local)
1974
if ((first= query_tables))
1977
Exclude from global table list
1979
if ((query_tables= query_tables->next_global))
1980
query_tables->prev_global= &query_tables;
1982
query_tables_last= &query_tables;
1983
first->next_global= 0;
1986
and from local list if it is not empty
1988
if ((*link_to_local= test(select_lex.table_list.first)))
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;
1996
Ensure that the global list has the same first table as the local
1999
first_lists_tables_same();
2006
Bring first local table of first most outer select to first place in global
2010
LEX::first_lists_tables_same()
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.
2020
void LEX::first_lists_tables_same()
2022
TableList *first_table= (TableList*) select_lex.table_list.first;
2023
if (query_tables != first_table && first_table != 0)
2026
if (query_tables_last == &first_table->next_global)
2027
query_tables_last= first_table->prev_global;
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;
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
2038
query_tables->prev_global= &first_table->next_global;
2039
first_table->prev_global= &query_tables;
2040
query_tables= first_table;
2045
Link table back that was unlinked with unlink_first_table()
2048
link_first_table_back()
2049
link_to_local do we need link this table to local
2054
void LEX::link_first_table_back(TableList *first, bool link_to_local)
2058
if ((first->next_global= query_tables))
2059
query_tables->prev_global= &first->next_global;
2061
query_tables_last= &first->next_global;
2062
query_tables= first;
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
2075
cleanup lex for case when we open table by table for processing
2078
LEX::cleanup_after_one_table_open()
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).
2085
void LEX::cleanup_after_one_table_open()
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.
2095
if (all_selects_list != &select_lex)
2098
/* cleunup underlying units (units of VIEW) */
2099
for (Select_Lex_Unit *un= select_lex.first_inner_unit();
2101
un= un->next_unit())
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();
2111
There are Select_Lex::add_table_to_list &
2112
Select_Lex::set_lock_for_tables are in sql_parse.cc
2114
Select_Lex::print is in sql_select.cc
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
2123
Sets the kind of hints to be added by the calls to add_index_hint().
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.
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
2137
void Select_Lex::set_index_hint_type(enum index_hint_type type_arg, index_clause_map clause)
2139
current_index_hint_type= type_arg;
2140
current_index_hint_clause= clause;
2144
Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
2148
session current thread.
2150
void Select_Lex::alloc_index_hints (Session *session)
2152
index_hints= new (session->mem_root) List<Index_hint>();
2156
adds an element to the array storing index usage hints
2157
(ADD/FORCE/IGNORE INDEX).
2161
session current thread.
2162
str name of the index.
2163
length number of characters in str.
2166
0 on success, non-zero otherwise
2168
bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
2170
return index_hints->push_front (new (session->mem_root)
2171
Index_hint(current_index_hint_type,
2172
current_index_hint_clause,
2176
} /* namespace drizzled */