32
32
static int lex_one_token(void *arg, void *yysession);
36
35
We are using pointer to this variable for distinguishing between assignment
37
36
to NEW row field (when parsing trigger definition) and structured variable.
40
38
sys_var *trg_new_row_fake_var= (sys_var*) 0x01;
45
43
const LEX_STRING null_lex_str= {NULL, 0};
48
st_parsing_options::reset()
50
allows_select_procedure= true;
53
45
Lex_input_stream::Lex_input_stream(Session *session,
54
46
const char* buffer,
55
47
unsigned int length)
162
152
@param ptr Pointer in the pre-processed buffer, which specifies the end
163
153
of the chunk, which should be appended to the utf8 body.
166
155
void Lex_input_stream::body_utf8_append(const char *ptr)
168
157
body_utf8_append(ptr, ptr);
212
200
m_cpp_utf8_processed_ptr= end_ptr;
217
204
This is called before every query that is to be parsed.
218
205
Because of this, it's critical to not do too much things here.
219
206
(We already do too much here)
222
208
void lex_start(Session *session)
224
210
LEX *lex= session->lex;
248
234
lex->select_lex.init_order();
249
235
lex->select_lex.group_list.empty();
250
236
lex->describe= 0;
251
lex->subqueries= false;
252
237
lex->derived_tables= 0;
253
238
lex->lock_option= TL_READ;
254
239
lex->leaf_tables_insert= 0;
255
lex->parsing_options.reset();
256
240
lex->select_lex.select_number= 1;
258
242
lex->select_lex.in_sum_expr=0;
342
323
get_quoted_token yet. But it should be fixed in the
343
324
future to operate multichar strings (like ucs2)
346
326
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
348
328
uint32_t length, char quote)
377
357
Return an unescaped text literal without quotes
378
358
Fix sometimes to do only one scan of the string
381
360
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
383
362
register unsigned char c,sep;
384
uint32_t found_escape=0;
363
bool found_escape= false;
385
364
const CHARSET_INFO * const cs= lip->m_session->charset();
387
366
lip->tok_bitmap= 0;
392
371
lip->tok_bitmap|= c;
399
lip->get_end_of_query()))) {
400
lip->skip_binary(l-1);
376
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
379
lip->skip_binary(l-1);
406
386
{ // Escaped character
412
392
else if (c == sep)
414
394
if (c == lip->yyGet()) // Check if two separators in a row
416
found_escape=1; // duplicate. Remember for delete
396
found_escape= true; // duplicate. Remember for delete
426
406
str= lip->get_tok_start();
427
407
end= lip->get_ptr();
428
408
/* Extract the text from the token */
431
411
assert(end >= str);
433
413
if (!(start= (char*) lip->m_session->alloc((uint32_t) (end-str)+1)))
434
return (char*) ""; // Sql_alloc has set error flag
414
return (char*) ""; // Sql_alloc has set error flag
436
416
lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
437
417
lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;
441
lip->yytoklen=(uint32_t) (end-str);
442
memcpy(start,str,lip->yytoklen);
443
start[lip->yytoklen]=0;
421
lip->yytoklen= (uint32_t) (end-str);
422
memcpy(start, str, lip->yytoklen);
423
start[lip->yytoklen]= 0;
449
for (to=start ; str != end ; str++)
429
for (to= start; str != end; str++)
454
(l = my_ismbchar(cs, str, end))) {
434
int l= my_ismbchar(cs, str, end);
461
if (*str == '\\' && str+1 != end)
477
*to++= 0; // Ascii null
479
case 'Z': // ^Z must be escaped on Win32
484
*to++= '\\'; // remember prefix for wildcard
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
491
else if (*str == sep)
492
*to++= *str++; // Two ' or "
497
lip->yytoklen=(uint32_t) (to-start);
474
else if (*str == sep)
475
*to++= *str++; // Two ' or "
480
lip->yytoklen= (uint32_t) (to - start);
511
494
** is done with int64_t or double.
514
static const char *long_str="2147483647";
515
static const uint32_t long_len=10;
516
static const char *signed_long_str="-2147483648";
517
static const char *int64_t_str="9223372036854775807";
518
static const uint32_t int64_t_len=19;
519
static const char *signed_int64_t_str="-9223372036854775808";
520
static const uint32_t signed_int64_t_len=19;
521
static const char *unsigned_int64_t_str="18446744073709551615";
522
static const uint32_t unsigned_int64_t_len=20;
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;
524
507
static inline uint32_t int_token(const char *str,uint32_t length)
601
583
- MY_LEX_OPERATOR_OR_IDENT Last state was an ident, text or number
602
584
(which can't be followed by a signed number)
605
586
int DRIZZLElex(void *arg, void *yysession)
607
588
Session *session= (Session *)yysession;
697
678
case MY_LEX_ESCAPE:
698
679
if (lip->yyGet() == 'N')
699
680
{ // Allow \N as shortcut for NULL
700
yylval->lex_str.str=(char*) "\\N";
701
yylval->lex_str.length=2;
681
yylval->lex_str.str=(char*) "\\N";
682
yylval->lex_str.length=2;
704
685
case MY_LEX_CHAR: // Unknown or single char token
705
686
case MY_LEX_SKIP: // This should not happen
733
714
case MY_LEX_IDENT_OR_HEX:
734
715
if (lip->yyPeek() == '\'')
735
716
{ // Found x'hex-number'
736
state= MY_LEX_HEX_NUMBER;
717
state= MY_LEX_HEX_NUMBER;
739
720
case MY_LEX_IDENT_OR_BIN:
740
721
if (lip->yyPeek() == '\'')
747
728
#if defined(USE_MB) && defined(USE_MB_IDENT)
750
result_state= IDENT_QUOTED;
731
result_state= IDENT_QUOTED;
751
732
if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
753
734
int l = my_ismbchar(cs,
764
745
if (my_mbcharlen(cs, c) > 1)
767
if ((l = my_ismbchar(cs,
769
lip->get_end_of_query())) == 0)
747
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
771
750
lip->skip_binary(l-1);
790
769
for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
792
771
if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
793
lip->next_state=MY_LEX_IDENT_SEP;
772
lip->next_state=MY_LEX_IDENT_SEP;
795
774
{ // '(' must follow directly if function
797
if ((tokval = find_keyword(lip, length, c == '(')))
799
lip->next_state= MY_LEX_START; // Allow signed numbers
800
return(tokval); // Was keyword
776
if ((tokval = find_keyword(lip, length, c == '(')))
778
lip->next_state= MY_LEX_START; // Allow signed numbers
779
return(tokval); // Was keyword
802
781
lip->yySkip(); // next state does a unget
804
783
yylval->lex_str=get_token(lip, 0, length);
816
795
c= lip->yyGet(); // should be '.'
817
796
lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
818
797
if (!ident_map[(uint8_t)lip->yyPeek()]) // Probably ` or "
819
lip->next_state= MY_LEX_START;
798
lip->next_state= MY_LEX_START;
822
801
case MY_LEX_NUMBER_IDENT: // number or ident which num-start
855
834
while (my_isdigit(cs, (c = lip->yyGet()))) ;
856
835
if (!ident_map[c])
857
836
{ // Can't be identifier
858
state=MY_LEX_INT_OR_REAL;
837
state=MY_LEX_INT_OR_REAL;
861
840
if (c == 'e' || c == 'E')
863
// The following test is written this way to allow numbers of type 1e1
842
// The following test is written this way to allow numbers of type 1e1
864
843
if (my_isdigit(cs,lip->yyPeek()) ||
865
844
(c=(lip->yyGet())) == '+' || c == '-')
867
846
if (my_isdigit(cs,lip->yyPeek())) // Number must have digit after sign
870
849
while (my_isdigit(cs,lip->yyGet())) ;
871
850
yylval->lex_str=get_token(lip, 0, lip->yyLength());
880
859
#if defined(USE_MB) && defined(USE_MB_IDENT)
883
result_state= IDENT_QUOTED;
862
result_state= IDENT_QUOTED;
884
863
while (ident_map[c=lip->yyGet()])
886
865
if (my_mbcharlen(cs, c) > 1)
889
if ((l = my_ismbchar(cs,
891
lip->get_end_of_query())) == 0)
867
int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
893
870
lip->skip_binary(l-1);
902
879
result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
904
881
if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
905
lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
882
lip->next_state=MY_LEX_IDENT_SEP;// Next is '.'
907
884
yylval->lex_str= get_token(lip, 0, lip->yyLength());
919
896
char quote_char= c; // Used char
920
897
while ((c=lip->yyGet()))
923
if ((var_length= my_mbcharlen(cs, c)) == 1)
927
if (lip->yyPeek() != quote_char)
900
if ((var_length= my_mbcharlen(cs, c)) == 1)
904
if (lip->yyPeek() != quote_char)
935
else if (var_length < 1)
912
else if (var_length < 1)
937
914
lip->skip_binary(var_length-1);
940
917
if (double_quotes)
941
yylval->lex_str=get_quoted_token(lip, 1,
942
lip->yyLength() - double_quotes -1,
918
yylval->lex_str=get_quoted_token(lip, 1, lip->yyLength() - double_quotes -1, quote_char);
945
920
yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
946
921
if (c == quote_char)
947
922
lip->yySkip(); // Skip end `
948
923
lip->next_state= MY_LEX_START;
950
924
lip->body_utf8_append(lip->m_cpp_text_start);
952
lip->body_utf8_append_literal(session, &yylval->lex_str, cs,
953
lip->m_cpp_text_end);
925
lip->body_utf8_append_literal(session, &yylval->lex_str, cs, lip->m_cpp_text_end);
955
926
return(IDENT_QUOTED);
957
928
case MY_LEX_INT_OR_REAL: // Complete int or incomplete real
959
930
{ // Found complete integer number.
960
931
yylval->lex_str=get_token(lip, 0, lip->yyLength());
961
return int_token(yylval->lex_str.str,yylval->lex_str.length);
932
return int_token(yylval->lex_str.str,yylval->lex_str.length);
964
935
case MY_LEX_REAL: // Incomplete real number
967
938
if (c == 'e' || c == 'E')
969
940
c = lip->yyGet();
970
if (c == '-' || c == '+')
971
c = lip->yyGet(); // Skip sign
972
if (!my_isdigit(cs,c))
973
{ // No digit after sign
941
if (c == '-' || c == '+')
942
c = lip->yyGet(); // Skip sign
943
if (!my_isdigit(cs,c))
944
{ // No digit after sign
977
948
while (my_isdigit(cs,lip->yyGet())) ;
978
949
yylval->lex_str=get_token(lip, 0, lip->yyLength());
981
952
yylval->lex_str=get_token(lip, 0, lip->yyLength());
982
953
return(DECIMAL_NUM);
1014
985
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1016
lip->next_state= MY_LEX_START; // Allow signed numbers
987
lip->next_state= MY_LEX_START; // Allow signed numbers
1019
990
state = MY_LEX_CHAR; // Something fishy found
1030
1001
if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
1032
lip->next_state= MY_LEX_START; // Found long op
1003
lip->next_state= MY_LEX_START; // Found long op
1035
1006
state = MY_LEX_CHAR; // Something fishy found
1056
1027
case MY_LEX_STRING: // Incomplete text string
1057
1028
if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
1059
state= MY_LEX_CHAR; // Read char by char
1030
state= MY_LEX_CHAR; // Read char by char
1062
1033
yylval->lex_str.length=lip->yytoklen;
1081
1052
case MY_LEX_LONG_COMMENT: /* Long C comment? */
1082
1053
if (lip->yyPeek() != '*')
1084
state=MY_LEX_CHAR; // Probable division
1055
state=MY_LEX_CHAR; // Probable division
1087
1058
lex->select_lex.options|= OPTION_FOUND_COMMENT;
1088
1059
/* Reject '/' '*', since we might need to turn off the echo */
1189
1160
state=MY_LEX_START;
1192
state=MY_LEX_CHAR; // Return '*'
1163
state=MY_LEX_CHAR; // Return '*'
1194
1165
case MY_LEX_SET_VAR: // Check if ':='
1195
1166
if (lip->yyPeek() != '=')
1197
state=MY_LEX_CHAR; // Return ':'
1168
state=MY_LEX_CHAR; // Return ':'
1201
1172
return (SET_VAR);
1237
1208
/* Actually real shouldn't start with . but allow them anyhow */
1238
1209
case MY_LEX_REAL_OR_POINT:
1239
1210
if (my_isdigit(cs,lip->yyPeek()))
1240
state = MY_LEX_REAL; // Real
1211
state= MY_LEX_REAL; // Real
1243
state= MY_LEX_IDENT_SEP; // return '.'
1214
state= MY_LEX_IDENT_SEP; // return '.'
1244
1215
lip->yyUnget(); // Put back '.'
1249
1220
case MY_LEX_STRING:
1250
1221
case MY_LEX_USER_VARIABLE_DELIMITER:
1251
1222
case MY_LEX_STRING_OR_DELIMITER:
1253
1224
case MY_LEX_USER_END:
1254
lip->next_state=MY_LEX_SYSTEM_VAR;
1225
lip->next_state=MY_LEX_SYSTEM_VAR;
1257
lip->next_state=MY_LEX_HOSTNAME;
1228
lip->next_state=MY_LEX_HOSTNAME;
1260
1231
yylval->lex_str.str=(char*) lip->get_ptr();
1261
1232
yylval->lex_str.length=1;
1262
1233
return((int) '@');
1263
1234
case MY_LEX_HOSTNAME: // end '@' of user@hostname
1264
1235
for (c=lip->yyGet() ;
1265
my_isalnum(cs,c) || c == '.' || c == '_' || c == '$';
1236
my_isalnum(cs,c) || c == '.' || c == '_' || c == '$';
1266
1237
c= lip->yyGet()) ;
1267
1238
yylval->lex_str=get_token(lip, 0, lip->yyLength());
1268
1239
return(LEX_HOSTNAME);
1277
1248
return((int) '@');
1278
1249
case MY_LEX_IDENT_OR_KEYWORD:
1280
We come here when we have found two '@' in a row.
1281
We should now be able to handle:
1282
[(global | local | session) .]variable_name
1251
We come here when we have found two '@' in a row.
1252
We should now be able to handle:
1253
[(global | local | session) .]variable_name
1285
1256
for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
1287
1258
result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
1290
lip->next_state=MY_LEX_IDENT_SEP;
1261
lip->next_state=MY_LEX_IDENT_SEP;
1291
1262
length= lip->yyLength();
1292
1263
if (length == 0)
1293
1264
return(ABORT_SYM); // Names must be nonempty.
1294
1265
if ((tokval= find_keyword(lip, length,0)))
1296
1267
lip->yyUnget(); // Put back 'c'
1297
return(tokval); // Was keyword
1268
return(tokval); // Was keyword
1299
1270
yylval->lex_str=get_token(lip, 0, length);
1321
1291
@return You need to use check the error in Session for out
1322
1292
of memory condition after calling this function.
1325
1294
Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root)
1326
1295
:drop_list(rhs.drop_list, mem_root),
1327
1296
alter_list(rhs.alter_list, mem_root),
1639
1599
next->prev= prev;
1644
Select_Lex_Node::mark_as_dependent mark all Select_Lex struct from
1645
this to 'last' as dependent
1648
last - pointer to last Select_Lex struct, before wich all
1649
Select_Lex have to be marked as dependent
1652
'last' should be reachable from this Select_Lex_Node
1603
* Mark all Select_Lex struct from this to 'last' as dependent
1605
* @param Pointer to last Select_Lex struct, before wich all
1606
* Select_Lex have to be marked as dependent
1607
* @note 'last' should be reachable from this Select_Lex_Node
1655
1609
void Select_Lex::mark_as_dependent(Select_Lex *last)
1728
1681
Select_Lex_Unit* Select_Lex_Unit::master_unit()
1734
1686
Select_Lex* Select_Lex_Unit::outer_select()
1736
1688
return (Select_Lex*) master;
1740
1691
bool Select_Lex::add_order_to_list(Session *session, Item *item, bool asc)
1742
1693
return add_to_list(session, order_list, item, asc);
1746
1696
bool Select_Lex::add_item_to_list(Session *, Item *item)
1748
1698
return(item_list.push_back(item));
1752
1701
bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
1754
1703
return add_to_list(session, group_list, item, asc);
1758
1706
Select_Lex_Unit* Select_Lex::master_unit()
1760
1708
return (Select_Lex_Unit*) master;
1764
1711
Select_Lex* Select_Lex::outer_select()
1766
1713
return (Select_Lex*) master->get_master();
1770
1716
bool Select_Lex::set_braces(bool value)
1778
1722
bool Select_Lex::inc_in_sum_expr()
1786
1728
uint32_t Select_Lex::get_in_sum_expr()
1788
1730
return in_sum_expr;
1792
1733
TableList* Select_Lex::get_table_list()
1794
1735
return (TableList*) table_list.first;
1947
1883
this method to reset state of already initialized Query_tables_list
1948
1884
so it can be used for processing of new statement.
1951
1886
void Query_tables_list::reset_query_tables_list(bool init)
1953
1888
if (!init && query_tables)
1979
1913
statement parsing. On should use lex_start() function to prepare LEX
1984
1917
:result(0), yacc_yyss(0), yacc_yyvs(0),
1985
1918
sql_command(SQLCOM_END), option_type(OPT_DEFAULT), is_lex_started(0)
2054
1982
@return true in case of error (parsing should be aborted, false in
2055
1983
case of success
2059
LEX::copy_db_to(char **p_db, size_t *p_db_length) const
1985
bool LEX::copy_db_to(char **p_db, size_t *p_db_length) const
2061
1987
return session->copy_db_to(p_db, p_db_length);
2283
2198
Then the context variable index_hint_type can be reset to the
2284
2199
next hint type.
2286
void Select_Lex::set_index_hint_type(enum index_hint_type type_arg,
2287
index_clause_map clause)
2201
void Select_Lex::set_index_hint_type(enum index_hint_type type_arg, index_clause_map clause)
2289
2203
current_index_hint_type= type_arg;
2290
2204
current_index_hint_clause= clause;
2295
2208
Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).