00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #define DRIZZLE_LEX 1
00022
00023 #include <drizzled/sql_reserved_words.h>
00024
00025 #include <drizzled/configmake.h>
00026 #include <drizzled/item/num.h>
00027 #include <drizzled/error.h>
00028 #include <drizzled/session.h>
00029 #include <drizzled/sql_base.h>
00030 #include <drizzled/lookup_symbol.h>
00031 #include <drizzled/index_hint.h>
00032 #include <drizzled/select_result.h>
00033 #include <drizzled/item/subselect.h>
00034 #include <drizzled/statement.h>
00035 #include <drizzled/sql_lex.h>
00036
00037 #include <cstdio>
00038 #include <ctype.h>
00039
00040 union ParserType;
00041
00042 using namespace std;
00043
00044
00045 int base_sql_lex(ParserType *arg, drizzled::Session *yysession);
00046
00047 namespace drizzled
00048 {
00049
00050 static int lex_one_token(ParserType *arg, drizzled::Session *yysession);
00051
00055 static bool add_to_list(Session *session, SQL_LIST &list, Item *item, bool asc)
00056 {
00057 Order *order;
00058
00059 if (!(order = (Order *) session->getMemRoot()->allocate(sizeof(Order))))
00060 return true;
00061
00062 order->item_ptr= item;
00063 order->item= &order->item_ptr;
00064 order->asc = asc;
00065 order->free_me=0;
00066 order->used=0;
00067 order->counter_used= 0;
00068 list.link_in_list((unsigned char*) order, (unsigned char**) &order->next);
00069
00070 return false;
00071 }
00072
00076 const LEX_STRING null_lex_str= {NULL, 0};
00077
00078 Lex_input_stream::Lex_input_stream(Session *session,
00079 const char* buffer,
00080 unsigned int length) :
00081 m_session(session),
00082 yylineno(1),
00083 yytoklen(0),
00084 yylval(NULL),
00085 lookahead_token(END_OF_INPUT),
00086 lookahead_yylval(NULL),
00087 m_ptr(buffer),
00088 m_tok_start(NULL),
00089 m_tok_end(NULL),
00090 m_end_of_query(buffer + length),
00091 m_tok_start_prev(NULL),
00092 m_buf(buffer),
00093 m_buf_length(length),
00094 m_echo(true),
00095 m_cpp_tok_start(NULL),
00096 m_cpp_tok_start_prev(NULL),
00097 m_cpp_tok_end(NULL),
00098 m_body_utf8(NULL),
00099 m_cpp_utf8_processed_ptr(NULL),
00100 next_state(MY_LEX_START),
00101 ignore_space(1),
00102 in_comment(NO_COMMENT)
00103 {
00104 m_cpp_buf= (char*) session->getMemRoot()->allocate(length + 1);
00105 m_cpp_ptr= m_cpp_buf;
00106 }
00107
00108 Lex_input_stream::~Lex_input_stream()
00109 {}
00110
00122 void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
00123 {
00124 assert(begin_ptr);
00125 assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
00126
00127 uint32_t body_utf8_length=
00128 (m_buf_length / default_charset_info->mbminlen) *
00129 my_charset_utf8_bin.mbmaxlen;
00130
00131 m_body_utf8= (char *) session->getMemRoot()->allocate(body_utf8_length + 1);
00132 m_body_utf8_ptr= m_body_utf8;
00133 *m_body_utf8_ptr= 0;
00134
00135 m_cpp_utf8_processed_ptr= begin_ptr;
00136 }
00137
00158 void Lex_input_stream::body_utf8_append(const char *ptr,
00159 const char *end_ptr)
00160 {
00161 assert(m_cpp_buf <= ptr && ptr <= m_cpp_buf + m_buf_length);
00162 assert(m_cpp_buf <= end_ptr && end_ptr <= m_cpp_buf + m_buf_length);
00163
00164 if (!m_body_utf8)
00165 return;
00166
00167 if (m_cpp_utf8_processed_ptr >= ptr)
00168 return;
00169
00170 int bytes_to_copy= ptr - m_cpp_utf8_processed_ptr;
00171
00172 memcpy(m_body_utf8_ptr, m_cpp_utf8_processed_ptr, bytes_to_copy);
00173 m_body_utf8_ptr += bytes_to_copy;
00174 *m_body_utf8_ptr= 0;
00175
00176 m_cpp_utf8_processed_ptr= end_ptr;
00177 }
00178
00186 void Lex_input_stream::body_utf8_append(const char *ptr)
00187 {
00188 body_utf8_append(ptr, ptr);
00189 }
00190
00202 void Lex_input_stream::body_utf8_append_literal(const LEX_STRING *txt,
00203 const char *end_ptr)
00204 {
00205 if (!m_cpp_utf8_processed_ptr)
00206 return;
00207
00208
00209
00210 memcpy(m_body_utf8_ptr, txt->str, txt->length);
00211 m_body_utf8_ptr += txt->length;
00212 *m_body_utf8_ptr= 0;
00213
00214 m_cpp_utf8_processed_ptr= end_ptr;
00215 }
00216
00217
00218
00219
00220
00221
00222 void LEX::start(Session *arg)
00223 {
00224 lex_start(arg);
00225 }
00226
00227 void lex_start(Session *session)
00228 {
00229 LEX *lex= &session->lex();
00230
00231 lex->session= lex->unit.session= session;
00232
00233 lex->context_stack.clear();
00234 lex->unit.init_query();
00235 lex->unit.init_select();
00236
00237 lex->select_lex.parent_lex= lex;
00238 lex->select_lex.init_query();
00239 lex->value_list.clear();
00240 lex->update_list.clear();
00241 lex->auxiliary_table_list.clear();
00242 lex->unit.next= lex->unit.master=
00243 lex->unit.link_next= lex->unit.return_to= 0;
00244 lex->unit.prev= lex->unit.link_prev= 0;
00245 lex->unit.slave= lex->unit.global_parameters= lex->current_select=
00246 lex->all_selects_list= &lex->select_lex;
00247 lex->select_lex.master= &lex->unit;
00248 lex->select_lex.prev= &lex->unit.slave;
00249 lex->select_lex.link_next= lex->select_lex.slave= lex->select_lex.next= 0;
00250 lex->select_lex.link_prev= (Select_Lex_Node**)&(lex->all_selects_list);
00251 lex->select_lex.options= 0;
00252 lex->select_lex.init_order();
00253 lex->select_lex.group_list.clear();
00254 lex->describe= 0;
00255 lex->derived_tables= 0;
00256 lex->lock_option= TL_READ;
00257 lex->leaf_tables_insert= 0;
00258 lex->var_list.clear();
00259 lex->select_lex.select_number= 1;
00260 lex->length=0;
00261 lex->select_lex.in_sum_expr=0;
00262 lex->select_lex.group_list.clear();
00263 lex->select_lex.order_list.clear();
00264 lex->sql_command= SQLCOM_END;
00265 lex->duplicates= DUP_ERROR;
00266 lex->ignore= 0;
00267 lex->escape_used= false;
00268 lex->query_tables= 0;
00269 lex->reset_query_tables_list(false);
00270 lex->expr_allows_subselect= true;
00271 lex->use_only_table_context= false;
00272
00273 lex->name.str= 0;
00274 lex->name.length= 0;
00275 lex->nest_level=0 ;
00276 lex->allow_sum_func= 0;
00277 lex->in_sum_func= NULL;
00278 lex->type= 0;
00279
00280 lex->is_lex_started= true;
00281 lex->statement= NULL;
00282
00283 lex->is_cross= false;
00284 lex->reset();
00285 }
00286
00287 void LEX::end()
00288 {
00289 if (yacc_yyss)
00290 {
00291 free(yacc_yyss);
00292 free(yacc_yyvs);
00293 yacc_yyss= 0;
00294 yacc_yyvs= 0;
00295 }
00296
00297 safe_delete(result);
00298 safe_delete(_create_table);
00299 _create_table= NULL;
00300 _create_field= NULL;
00301
00302 result= 0;
00303 setCacheable(true);
00304
00305 safe_delete(statement);
00306 }
00307
00308 static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
00309 {
00310
00311 char tok_upper[64];
00312 const char *tok= lip->get_tok_start();
00313 uint32_t tok_pos= 0;
00314 for (;tok_pos<len && tok_pos<63;tok_pos++)
00315 tok_upper[tok_pos]=my_toupper(system_charset_info, tok[tok_pos]);
00316 tok_upper[tok_pos]=0;
00317
00318 const SYMBOL *symbol= lookup_symbol(tok_upper, len, function);
00319 if (symbol)
00320 {
00321 lip->yylval->symbol.symbol=symbol;
00322 lip->yylval->symbol.str= (char*) tok;
00323 lip->yylval->symbol.length=len;
00324
00325 return symbol->tok;
00326 }
00327
00328 return 0;
00329 }
00330
00331 bool is_lex_native_function(const LEX_STRING *name)
00332 {
00333 assert(name != NULL);
00334 return (lookup_symbol(name->str, name->length, 1) != 0);
00335 }
00336
00337
00338 static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
00339 {
00340 LEX_STRING tmp;
00341 lip->yyUnget();
00342 tmp.length=lip->yytoklen=length;
00343 tmp.str= lip->m_session->strmake(lip->get_tok_start() + skip, tmp.length);
00344
00345 lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
00346 lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;
00347
00348 return tmp;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357 static LEX_STRING get_quoted_token(Lex_input_stream *lip,
00358 uint32_t skip,
00359 uint32_t length, char quote)
00360 {
00361 LEX_STRING tmp;
00362 const char *from, *end;
00363 char *to;
00364 lip->yyUnget();
00365 tmp.length= lip->yytoklen=length;
00366 tmp.str=(char*) lip->m_session->getMemRoot()->allocate(tmp.length+1);
00367 from= lip->get_tok_start() + skip;
00368 to= tmp.str;
00369 end= to+length;
00370
00371 lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
00372 lip->m_cpp_text_end= lip->m_cpp_text_start + length;
00373
00374 for ( ; to != end; )
00375 {
00376 if ((*to++= *from++) == quote)
00377 {
00378 from++;
00379 lip->m_cpp_text_start++;
00380 }
00381 }
00382 *to= 0;
00383 return tmp;
00384 }
00385
00386
00387
00388
00389
00390
00391 static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
00392 {
00393 unsigned char c,sep;
00394 bool found_escape= false;
00395 const CHARSET_INFO * const cs= lip->m_session->charset();
00396
00397 lip->tok_bitmap= 0;
00398 sep= lip->yyGetLast();
00399 while (! lip->eof())
00400 {
00401 c= lip->yyGet();
00402 lip->tok_bitmap|= c;
00403 {
00404 if (use_mb(cs))
00405 {
00406 int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
00407 if (l != 0)
00408 {
00409 lip->skip_binary(l-1);
00410 continue;
00411 }
00412 }
00413 }
00414 if (c == '\\')
00415 {
00416 found_escape= true;
00417 if (lip->eof())
00418 return 0;
00419 lip->yySkip();
00420 }
00421 else if (c == sep)
00422 {
00423 if (c == lip->yyGet())
00424 {
00425 found_escape= true;
00426 continue;
00427 }
00428 else
00429 lip->yyUnget();
00430
00431
00432 const char *str, *end;
00433 char *start;
00434
00435 str= lip->get_tok_start();
00436 end= lip->get_ptr();
00437
00438 str+= pre_skip;
00439 end-= post_skip;
00440 assert(end >= str);
00441
00442 if (!(start= (char*) lip->m_session->getMemRoot()->allocate((uint32_t) (end-str)+1)))
00443 return (char*) "";
00444
00445 lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
00446 lip->m_cpp_text_end= lip->get_cpp_ptr() - post_skip;
00447
00448 if (! found_escape)
00449 {
00450 lip->yytoklen= (uint32_t) (end-str);
00451 memcpy(start, str, lip->yytoklen);
00452 start[lip->yytoklen]= 0;
00453 }
00454 else
00455 {
00456 char *to;
00457
00458 for (to= start; str != end; str++)
00459 {
00460 if (use_mb(cs))
00461 {
00462 int l= my_ismbchar(cs, str, end);
00463 if (l != 0)
00464 {
00465 while (l--)
00466 *to++= *str++;
00467 str--;
00468 continue;
00469 }
00470 }
00471 if (*str == '\\' && (str + 1) != end)
00472 {
00473 switch (*++str) {
00474 case 'n':
00475 *to++= '\n';
00476 break;
00477 case 't':
00478 *to++= '\t';
00479 break;
00480 case 'r':
00481 *to++= '\r';
00482 break;
00483 case 'b':
00484 *to++= '\b';
00485 break;
00486 case '0':
00487 *to++= 0;
00488 break;
00489 case 'Z':
00490 *to++= '\032';
00491 break;
00492 case '_':
00493 case '%':
00494 *to++= '\\';
00495
00496 default:
00497 *to++= *str;
00498 break;
00499 }
00500 }
00501 else if (*str == sep)
00502 *to++= *str++;
00503 else
00504 *to++ = *str;
00505 }
00506 *to= 0;
00507 lip->yytoklen= (uint32_t) (to - start);
00508 }
00509 return start;
00510 }
00511 }
00512 return 0;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 static const char *long_str= "2147483647";
00525 static const uint32_t long_len= 10;
00526 static const char *signed_long_str= "-2147483648";
00527 static const char *int64_t_str= "9223372036854775807";
00528 static const uint32_t int64_t_len= 19;
00529 static const char *signed_int64_t_str= "-9223372036854775808";
00530 static const uint32_t signed_int64_t_len= 19;
00531 static const char *unsigned_int64_t_str= "18446744073709551615";
00532 static const uint32_t unsigned_int64_t_len= 20;
00533
00534 static inline uint32_t int_token(const char *str,uint32_t length)
00535 {
00536 if (length < long_len)
00537 return NUM;
00538 bool neg=0;
00539
00540 if (*str == '+')
00541 {
00542 str++; length--;
00543 }
00544 else if (*str == '-')
00545 {
00546 str++; length--;
00547 neg=1;
00548 }
00549 while (*str == '0' && length)
00550 {
00551 str++; length --;
00552 }
00553 if (length < long_len)
00554 return NUM;
00555
00556 uint32_t smaller,bigger;
00557 const char *cmp;
00558 if (neg)
00559 {
00560 if (length == long_len)
00561 {
00562 cmp= signed_long_str+1;
00563 smaller=NUM;
00564 bigger=LONG_NUM;
00565 }
00566 else if (length < signed_int64_t_len)
00567 return LONG_NUM;
00568 else if (length > signed_int64_t_len)
00569 return DECIMAL_NUM;
00570 else
00571 {
00572 cmp=signed_int64_t_str+1;
00573 smaller=LONG_NUM;
00574 bigger=DECIMAL_NUM;
00575 }
00576 }
00577 else
00578 {
00579 if (length == long_len)
00580 {
00581 cmp= long_str;
00582 smaller=NUM;
00583 bigger=LONG_NUM;
00584 }
00585 else if (length < int64_t_len)
00586 return LONG_NUM;
00587 else if (length > int64_t_len)
00588 {
00589 if (length > unsigned_int64_t_len)
00590 return DECIMAL_NUM;
00591 cmp=unsigned_int64_t_str;
00592 smaller=ULONGLONG_NUM;
00593 bigger=DECIMAL_NUM;
00594 }
00595 else
00596 {
00597 cmp=int64_t_str;
00598 smaller=LONG_NUM;
00599 bigger= ULONGLONG_NUM;
00600 }
00601 }
00602 while (*cmp && *cmp++ == *str++) ;
00603 return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
00604 }
00605
00606 }
00607
00608
00609
00610
00611
00612
00613
00614 int base_sql_lex(union ParserType *yylval, drizzled::Session *session)
00615 {
00616 drizzled::Lex_input_stream *lip= session->m_lip;
00617 int token;
00618
00619 if (lip->lookahead_token != END_OF_INPUT)
00620 {
00621
00622
00623
00624
00625 token= lip->lookahead_token;
00626 lip->lookahead_token= END_OF_INPUT;
00627 *yylval= *(lip->lookahead_yylval);
00628 lip->lookahead_yylval= NULL;
00629 return token;
00630 }
00631
00632 token= drizzled::lex_one_token(yylval, session);
00633
00634 switch(token) {
00635 case WITH:
00636
00637
00638
00639
00640
00641
00642
00643 token= drizzled::lex_one_token(yylval, session);
00644 if (token == ROLLUP_SYM)
00645 {
00646 return WITH_ROLLUP_SYM;
00647 }
00648 else
00649 {
00650
00651
00652
00653 lip->lookahead_yylval= lip->yylval;
00654 lip->yylval= NULL;
00655 lip->lookahead_token= token;
00656 return WITH;
00657 }
00658 default:
00659 break;
00660 }
00661
00662 return token;
00663 }
00664
00665 namespace drizzled
00666 {
00667
00668 int lex_one_token(ParserType *yylval, drizzled::Session *session)
00669 {
00670 unsigned char c= 0;
00671 bool comment_closed;
00672 int tokval, result_state;
00673 unsigned int length;
00674 enum my_lex_states state;
00675 Lex_input_stream *lip= session->m_lip;
00676 LEX *lex= &session->lex();
00677 const CHARSET_INFO * const cs= session->charset();
00678 unsigned char *state_map= cs->state_map;
00679 unsigned char *ident_map= cs->ident_map;
00680
00681 lip->yylval=yylval;
00682
00683 lip->start_token();
00684 state=lip->next_state;
00685 lip->next_state=MY_LEX_OPERATOR_OR_IDENT;
00686 for (;;)
00687 {
00688 switch (state) {
00689 case MY_LEX_OPERATOR_OR_IDENT:
00690 case MY_LEX_START:
00691
00692 while(state_map[c= lip->yyPeek()] == MY_LEX_SKIP)
00693 {
00694 if (c == '\n')
00695 lip->yylineno++;
00696
00697 lip->yySkip();
00698 }
00699
00700
00701 lip->restart_token();
00702 c= lip->yyGet();
00703 state= (enum my_lex_states) state_map[c];
00704 break;
00705 case MY_LEX_ESCAPE:
00706 if (lip->yyGet() == 'N')
00707 {
00708 yylval->lex_str.str=(char*) "\\N";
00709 yylval->lex_str.length=2;
00710 return NULL_SYM;
00711 }
00712 case MY_LEX_CHAR:
00713 case MY_LEX_SKIP:
00714 if (c == '-' && lip->yyPeek() == '-' &&
00715 (my_isspace(cs,lip->yyPeekn(1)) ||
00716 my_iscntrl(cs,lip->yyPeekn(1))))
00717 {
00718 state=MY_LEX_COMMENT;
00719 break;
00720 }
00721
00722 if (c != ')')
00723 lip->next_state= MY_LEX_START;
00724
00725 if (c == ',')
00726 {
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 lip->restart_token();
00737 }
00738
00739 return((int) c);
00740
00741 case MY_LEX_IDENT_OR_HEX:
00742 if (lip->yyPeek() == '\'')
00743 {
00744 state= MY_LEX_HEX_NUMBER;
00745 break;
00746 }
00747 case MY_LEX_IDENT_OR_BIN:
00748 if (lip->yyPeek() == '\'')
00749 {
00750 state= MY_LEX_BIN_NUMBER;
00751 break;
00752 }
00753 case MY_LEX_IDENT:
00754 const char *start;
00755 if (use_mb(cs))
00756 {
00757 result_state= IDENT_QUOTED;
00758 if (my_mbcharlen(cs, lip->yyGetLast()) > 1)
00759 {
00760 int l = my_ismbchar(cs,
00761 lip->get_ptr() -1,
00762 lip->get_end_of_query());
00763 if (l == 0) {
00764 state = MY_LEX_CHAR;
00765 continue;
00766 }
00767 lip->skip_binary(l - 1);
00768 }
00769 while (ident_map[c=lip->yyGet()])
00770 {
00771 if (my_mbcharlen(cs, c) > 1)
00772 {
00773 int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
00774 if (l == 0)
00775 break;
00776 lip->skip_binary(l-1);
00777 }
00778 }
00779 }
00780 else
00781 {
00782 for (result_state= c; ident_map[c= lip->yyGet()]; result_state|= c) {};
00783
00784 result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
00785 }
00786 length= lip->yyLength();
00787 start= lip->get_ptr();
00788 if (lip->ignore_space)
00789 {
00790
00791
00792
00793
00794 for (; state_map[c] == MY_LEX_SKIP ; c= lip->yyGet()) {};
00795 }
00796 if (start == lip->get_ptr() && c == '.' && ident_map[(uint8_t)lip->yyPeek()])
00797 lip->next_state=MY_LEX_IDENT_SEP;
00798 else
00799 {
00800 lip->yyUnget();
00801 if ((tokval = find_keyword(lip, length, c == '(')))
00802 {
00803 lip->next_state= MY_LEX_START;
00804 return(tokval);
00805 }
00806 lip->yySkip();
00807 }
00808 yylval->lex_str=get_token(lip, 0, length);
00809
00810 lip->body_utf8_append(lip->m_cpp_text_start);
00811
00812 lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
00813
00814 return(result_state);
00815
00816 case MY_LEX_IDENT_SEP:
00817 yylval->lex_str.str= (char*) lip->get_ptr();
00818 yylval->lex_str.length= 1;
00819 c= lip->yyGet();
00820 lip->next_state= MY_LEX_IDENT_START;
00821 if (!ident_map[(uint8_t)lip->yyPeek()])
00822 lip->next_state= MY_LEX_START;
00823 return((int) c);
00824
00825 case MY_LEX_NUMBER_IDENT:
00826 if (lip->yyGetLast() == '0')
00827 {
00828 c= lip->yyGet();
00829 if (c == 'x')
00830 {
00831 while (my_isxdigit(cs,(c = lip->yyGet()))) ;
00832 if ((lip->yyLength() >= 3) && !ident_map[c])
00833 {
00834
00835 yylval->lex_str=get_token(lip, 2, lip->yyLength()-2);
00836 return (HEX_NUM);
00837 }
00838 lip->yyUnget();
00839 state= MY_LEX_IDENT_START;
00840 break;
00841 }
00842 else if (c == 'b')
00843 {
00844 while ((c= lip->yyGet()) == '0' || c == '1') {};
00845 if ((lip->yyLength() >= 3) && !ident_map[c])
00846 {
00847
00848 yylval->lex_str= get_token(lip, 2, lip->yyLength()-2);
00849 return (BIN_NUM);
00850 }
00851 lip->yyUnget();
00852 state= MY_LEX_IDENT_START;
00853 break;
00854 }
00855 lip->yyUnget();
00856 }
00857
00858 while (my_isdigit(cs, (c = lip->yyGet()))) ;
00859 if (!ident_map[c])
00860 {
00861 state=MY_LEX_INT_OR_REAL;
00862 break;
00863 }
00864 if (c == 'e' || c == 'E')
00865 {
00866
00867 if (my_isdigit(cs,lip->yyPeek()) ||
00868 (c=(lip->yyGet())) == '+' || c == '-')
00869 {
00870 if (my_isdigit(cs,lip->yyPeek()))
00871 {
00872 lip->yySkip();
00873 while (my_isdigit(cs,lip->yyGet())) ;
00874 yylval->lex_str=get_token(lip, 0, lip->yyLength());
00875 return(FLOAT_NUM);
00876 }
00877 }
00878 lip->yyUnget();
00879 }
00880
00881 case MY_LEX_IDENT_START:
00882 result_state= IDENT;
00883 if (use_mb(cs))
00884 {
00885 result_state= IDENT_QUOTED;
00886 while (ident_map[c=lip->yyGet()])
00887 {
00888 if (my_mbcharlen(cs, c) > 1)
00889 {
00890 int l= my_ismbchar(cs, lip->get_ptr() -1, lip->get_end_of_query());
00891 if (l == 0)
00892 break;
00893 lip->skip_binary(l-1);
00894 }
00895 }
00896 }
00897 else
00898 {
00899 for (result_state=0; ident_map[c= lip->yyGet()]; result_state|= c) {};
00900
00901 result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
00902 }
00903 if (c == '.' && ident_map[(uint8_t)lip->yyPeek()])
00904 lip->next_state=MY_LEX_IDENT_SEP;
00905
00906 yylval->lex_str= get_token(lip, 0, lip->yyLength());
00907
00908 lip->body_utf8_append(lip->m_cpp_text_start);
00909
00910 lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
00911
00912 return(result_state);
00913
00914 case MY_LEX_USER_VARIABLE_DELIMITER:
00915 {
00916 uint32_t double_quotes= 0;
00917 char quote_char= c;
00918 while ((c=lip->yyGet()))
00919 {
00920 int var_length;
00921 if ((var_length= my_mbcharlen(cs, c)) == 1)
00922 {
00923 if (c == quote_char)
00924 {
00925 if (lip->yyPeek() != quote_char)
00926 break;
00927 c=lip->yyGet();
00928 double_quotes++;
00929 continue;
00930 }
00931 }
00932 else if (var_length < 1)
00933 break;
00934 lip->skip_binary(var_length-1);
00935 }
00936 if (double_quotes)
00937 yylval->lex_str=get_quoted_token(lip, 1, lip->yyLength() - double_quotes -1, quote_char);
00938 else
00939 yylval->lex_str=get_token(lip, 1, lip->yyLength() -1);
00940 if (c == quote_char)
00941 lip->yySkip();
00942 lip->next_state= MY_LEX_START;
00943 lip->body_utf8_append(lip->m_cpp_text_start);
00944 lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
00945 return(IDENT_QUOTED);
00946 }
00947 case MY_LEX_INT_OR_REAL:
00948 if (c != '.')
00949 {
00950 yylval->lex_str=get_token(lip, 0, lip->yyLength());
00951 return int_token(yylval->lex_str.str,yylval->lex_str.length);
00952 }
00953
00954 case MY_LEX_REAL:
00955 while (my_isdigit(cs,c = lip->yyGet())) ;
00956
00957 if (c == 'e' || c == 'E')
00958 {
00959 c = lip->yyGet();
00960 if (c == '-' || c == '+')
00961 c = lip->yyGet();
00962 if (!my_isdigit(cs,c))
00963 {
00964 state= MY_LEX_CHAR;
00965 break;
00966 }
00967 while (my_isdigit(cs,lip->yyGet())) ;
00968 yylval->lex_str=get_token(lip, 0, lip->yyLength());
00969 return(FLOAT_NUM);
00970 }
00971 yylval->lex_str=get_token(lip, 0, lip->yyLength());
00972 return(DECIMAL_NUM);
00973
00974 case MY_LEX_HEX_NUMBER:
00975 lip->yySkip();
00976 while (my_isxdigit(cs, (c= lip->yyGet()))) ;
00977 if (c != '\'')
00978 return(ABORT_SYM);
00979 lip->yySkip();
00980 length= lip->yyLength();
00981 if ((length % 2) == 0)
00982 return(ABORT_SYM);
00983 yylval->lex_str=get_token(lip,
00984 2,
00985 length-3);
00986 return (HEX_NUM);
00987
00988 case MY_LEX_BIN_NUMBER:
00989 lip->yySkip();
00990 while ((c= lip->yyGet()) == '0' || c == '1') {};
00991 if (c != '\'')
00992 return(ABORT_SYM);
00993 lip->yySkip();
00994 length= lip->yyLength();
00995 yylval->lex_str= get_token(lip,
00996 2,
00997 length-3);
00998 return (BIN_NUM);
00999
01000 case MY_LEX_CMP_OP:
01001 if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
01002 state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
01003 lip->yySkip();
01004 if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
01005 {
01006 lip->next_state= MY_LEX_START;
01007 return(tokval);
01008 }
01009 state = MY_LEX_CHAR;
01010 break;
01011
01012 case MY_LEX_LONG_CMP_OP:
01013 if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP ||
01014 state_map[(uint8_t)lip->yyPeek()] == MY_LEX_LONG_CMP_OP)
01015 {
01016 lip->yySkip();
01017 if (state_map[(uint8_t)lip->yyPeek()] == MY_LEX_CMP_OP)
01018 lip->yySkip();
01019 }
01020 if ((tokval = find_keyword(lip, lip->yyLength() + 1, 0)))
01021 {
01022 lip->next_state= MY_LEX_START;
01023 return(tokval);
01024 }
01025 state = MY_LEX_CHAR;
01026 break;
01027
01028 case MY_LEX_BOOL:
01029 if (c != lip->yyPeek())
01030 {
01031 state=MY_LEX_CHAR;
01032 break;
01033 }
01034 lip->yySkip();
01035 tokval = find_keyword(lip,2,0);
01036 lip->next_state= MY_LEX_START;
01037 return(tokval);
01038
01039 case MY_LEX_STRING_OR_DELIMITER:
01040 if (0)
01041 {
01042 state= MY_LEX_USER_VARIABLE_DELIMITER;
01043 break;
01044 }
01045
01046 case MY_LEX_STRING:
01047 if (!(yylval->lex_str.str = get_text(lip, 1, 1)))
01048 {
01049 state= MY_LEX_CHAR;
01050 break;
01051 }
01052 yylval->lex_str.length=lip->yytoklen;
01053
01054 lip->body_utf8_append(lip->m_cpp_text_start);
01055
01056 lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
01057
01058 lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
01059 return(TEXT_STRING);
01060
01061 case MY_LEX_COMMENT:
01062 lex->select_lex.options|= OPTION_FOUND_COMMENT;
01063 while ((c = lip->yyGet()) != '\n' && c) ;
01064 lip->yyUnget();
01065 state = MY_LEX_START;
01066 break;
01067
01068 case MY_LEX_LONG_COMMENT:
01069 if (lip->yyPeek() != '*')
01070 {
01071 state=MY_LEX_CHAR;
01072 break;
01073 }
01074 lex->select_lex.options|= OPTION_FOUND_COMMENT;
01075
01076 lip->yyUnget();
01077
01078 if (lip->yyPeekn(2) == '!')
01079 {
01080 lip->in_comment= DISCARD_COMMENT;
01081
01082 lip->set_echo(false);
01083 lip->yySkip();
01084 lip->yySkip();
01085 lip->yySkip();
01086
01087
01088
01089
01090
01091
01092 const int MAX_VERSION_SIZE= 16;
01093 char version_str[MAX_VERSION_SIZE];
01094
01095 int pos= 0;
01096 do
01097 {
01098 version_str[pos]= lip->yyPeekn(pos);
01099 pos++;
01100 } while ((pos < MAX_VERSION_SIZE-1) && isdigit(version_str[pos-1]));
01101 version_str[pos]= 0;
01102
01103
01104 if (pos > 4)
01105 {
01106 uint64_t version;
01107 version=strtoll(version_str, NULL, 10);
01108
01109
01110 lip->yySkipn(pos-1);
01111
01112 if (version <= DRIZZLE_VERSION_ID)
01113 {
01114
01115 lip->set_echo(true);
01116 state=MY_LEX_START;
01117 break;
01118 }
01119 }
01120 else
01121 {
01122 state=MY_LEX_START;
01123 lip->set_echo(true);
01124 break;
01125 }
01126 }
01127 else
01128 {
01129 lip->in_comment= PRESERVE_COMMENT;
01130 lip->yySkip();
01131 lip->yySkip();
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141 comment_closed= false;
01142 while (! lip->eof())
01143 {
01144 c= lip->yyGet();
01145 if (c == '*')
01146 {
01147 if (lip->yyPeek() == '/')
01148 {
01149 lip->yySkip();
01150 comment_closed= true;
01151 state = MY_LEX_START;
01152 break;
01153 }
01154 }
01155 else if (c == '\n')
01156 lip->yylineno++;
01157 }
01158
01159 if (! comment_closed)
01160 return (ABORT_SYM);
01161 state = MY_LEX_START;
01162 lip->in_comment= NO_COMMENT;
01163 lip->set_echo(true);
01164 break;
01165
01166 case MY_LEX_END_LONG_COMMENT:
01167 if ((lip->in_comment != NO_COMMENT) && lip->yyPeek() == '/')
01168 {
01169
01170 lip->yyUnget();
01171
01172 lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
01173 lip->yySkipn(2);
01174
01175 lip->set_echo(true);
01176 lip->in_comment=NO_COMMENT;
01177 state=MY_LEX_START;
01178 }
01179 else
01180 state=MY_LEX_CHAR;
01181 break;
01182
01183 case MY_LEX_SET_VAR:
01184 if (lip->yyPeek() != '=')
01185 {
01186 state=MY_LEX_CHAR;
01187 break;
01188 }
01189 lip->yySkip();
01190 return (SET_VAR);
01191
01192 case MY_LEX_SEMICOLON:
01193 if (lip->yyPeek())
01194 {
01195 state= MY_LEX_CHAR;
01196 break;
01197 }
01198 lip->next_state=MY_LEX_END;
01199 return(END_OF_INPUT);
01200
01201 case MY_LEX_EOL:
01202 if (lip->eof())
01203 {
01204 lip->yyUnget();
01205 lip->set_echo(false);
01206 lip->yySkip();
01207 lip->set_echo(true);
01208
01209 if (lip->in_comment != NO_COMMENT)
01210 return (ABORT_SYM);
01211 lip->next_state=MY_LEX_END;
01212 return(END_OF_INPUT);
01213 }
01214 state=MY_LEX_CHAR;
01215 break;
01216
01217 case MY_LEX_END:
01218 lip->next_state=MY_LEX_END;
01219 return false;
01220
01221
01222
01223 case MY_LEX_REAL_OR_POINT:
01224 if (my_isdigit(cs,lip->yyPeek()))
01225 state= MY_LEX_REAL;
01226 else
01227 {
01228 state= MY_LEX_IDENT_SEP;
01229 lip->yyUnget();
01230 }
01231 break;
01232
01233 case MY_LEX_USER_END:
01234 switch (state_map[(uint8_t)lip->yyPeek()]) {
01235 case MY_LEX_STRING:
01236 case MY_LEX_USER_VARIABLE_DELIMITER:
01237 case MY_LEX_STRING_OR_DELIMITER:
01238 break;
01239 case MY_LEX_USER_END:
01240 lip->next_state=MY_LEX_SYSTEM_VAR;
01241 break;
01242 default:
01243 lip->next_state=MY_LEX_HOSTNAME;
01244 break;
01245 }
01246 yylval->lex_str.str=(char*) lip->get_ptr();
01247 yylval->lex_str.length=1;
01248 return((int) '@');
01249
01250 case MY_LEX_HOSTNAME:
01251 for (c=lip->yyGet() ;
01252 my_isalnum(cs,c) || c == '.' || c == '_' || c == '$';
01253 c= lip->yyGet()) ;
01254 yylval->lex_str=get_token(lip, 0, lip->yyLength());
01255 return(LEX_HOSTNAME);
01256
01257 case MY_LEX_SYSTEM_VAR:
01258 yylval->lex_str.str=(char*) lip->get_ptr();
01259 yylval->lex_str.length=1;
01260 lip->yySkip();
01261 lip->next_state= (state_map[(uint8_t)lip->yyPeek()] ==
01262 MY_LEX_USER_VARIABLE_DELIMITER ?
01263 MY_LEX_OPERATOR_OR_IDENT :
01264 MY_LEX_IDENT_OR_KEYWORD);
01265 return((int) '@');
01266
01267 case MY_LEX_IDENT_OR_KEYWORD:
01268
01269
01270
01271
01272
01273
01274 for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
01275
01276 result_state= result_state & 0x80 ? IDENT_QUOTED : IDENT;
01277
01278 if (c == '.')
01279 lip->next_state=MY_LEX_IDENT_SEP;
01280
01281 length= lip->yyLength();
01282 if (length == 0)
01283 return(ABORT_SYM);
01284
01285 if ((tokval= find_keyword(lip, length,0)))
01286 {
01287 lip->yyUnget();
01288 return(tokval);
01289 }
01290 yylval->lex_str=get_token(lip, 0, length);
01291
01292 lip->body_utf8_append(lip->m_cpp_text_start);
01293
01294 lip->body_utf8_append_literal(&yylval->lex_str, lip->m_cpp_text_end);
01295
01296 return(result_state);
01297 }
01298 }
01299 }
01300
01301 void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
01302 {
01303
01304
01305
01306
01307
01308 while ((str->length > 0) && (my_isspace(cs, str->str[0])))
01309 {
01310 str->length--;
01311 str->str++;
01312 }
01313
01314
01315
01316
01317
01318 while ((str->length > 0) && (my_isspace(cs, str->str[str->length-1])))
01319 {
01320 str->length--;
01321 }
01322 }
01323
01324
01325
01326
01327 void Select_Lex_Node::init_query()
01328 {
01329 options= 0;
01330 linkage= UNSPECIFIED_TYPE;
01331 no_error= no_table_names_allowed= 0;
01332 uncacheable.reset();
01333 }
01334
01335 void Select_Lex_Node::init_select()
01336 {
01337 }
01338
01339 void Select_Lex_Unit::init_query()
01340 {
01341 Select_Lex_Node::init_query();
01342 linkage= GLOBAL_OPTIONS_TYPE;
01343 global_parameters= first_select();
01344 select_limit_cnt= HA_POS_ERROR;
01345 offset_limit_cnt= 0;
01346 union_distinct= 0;
01347 prepared= optimized= executed= 0;
01348 item= 0;
01349 union_result= 0;
01350 table= 0;
01351 fake_select_lex= 0;
01352 cleaned= 0;
01353 item_list.clear();
01354 describe= 0;
01355 found_rows_for_union= 0;
01356 }
01357
01358 void Select_Lex::init_query()
01359 {
01360 Select_Lex_Node::init_query();
01361 table_list.clear();
01362 top_join_list.clear();
01363 join_list= &top_join_list;
01364 embedding= leaf_tables= 0;
01365 item_list.clear();
01366 join= 0;
01367 having= where= 0;
01368 olap= UNSPECIFIED_OLAP_TYPE;
01369 having_fix_field= 0;
01370 context.select_lex= this;
01371 context.init();
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 parent_lex->push_context(&context);
01382 cond_count= between_count= with_wild= 0;
01383 max_equal_elems= 0;
01384 ref_pointer_array= 0;
01385 select_n_where_fields= 0;
01386 select_n_having_items= 0;
01387 subquery_in_having= explicit_limit= 0;
01388 is_item_list_lookup= 0;
01389 parsing_place= NO_MATTER;
01390 exclude_from_table_unique_test= false;
01391 nest_level= 0;
01392 link_next= 0;
01393 }
01394
01395 void Select_Lex::init_select()
01396 {
01397 sj_nests.clear();
01398 group_list.clear();
01399 db= 0;
01400 having= 0;
01401 in_sum_expr= with_wild= 0;
01402 options= 0;
01403 braces= 0;
01404 interval_list.clear();
01405 inner_sum_func_list= 0;
01406 linkage= UNSPECIFIED_TYPE;
01407 order_list.elements= 0;
01408 order_list.first= 0;
01409 order_list.next= (unsigned char**) &order_list.first;
01410
01411 select_limit= 0;
01412 offset_limit= 0;
01413 with_sum_func= 0;
01414 is_cross= false;
01415 is_correlated= 0;
01416 cur_pos_in_select_list= UNDEF_POS;
01417 non_agg_fields.clear();
01418 cond_value= having_value= Item::COND_UNDEF;
01419 inner_refs_list.clear();
01420 full_group_by_flag.reset();
01421 }
01422
01423
01424
01425
01426
01427
01428 void Select_Lex_Node::include_down(Select_Lex_Node *upper)
01429 {
01430 if ((next= upper->slave))
01431 next->prev= &next;
01432 prev= &upper->slave;
01433 upper->slave= this;
01434 master= upper;
01435 slave= 0;
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 void Select_Lex_Node::include_standalone(Select_Lex_Node *upper,
01447 Select_Lex_Node **ref)
01448 {
01449 next= 0;
01450 prev= ref;
01451 master= upper;
01452 slave= 0;
01453 }
01454
01455
01456 void Select_Lex_Node::include_neighbour(Select_Lex_Node *before)
01457 {
01458 if ((next= before->next))
01459 next->prev= &next;
01460 prev= &before->next;
01461 before->next= this;
01462 master= before->master;
01463 slave= 0;
01464 }
01465
01466
01467 void Select_Lex_Node::include_global(Select_Lex_Node **plink)
01468 {
01469 if ((link_next= *plink))
01470 link_next->link_prev= &link_next;
01471 link_prev= plink;
01472 *plink= this;
01473 }
01474
01475
01476 void Select_Lex_Node::fast_exclude()
01477 {
01478 if (link_prev)
01479 {
01480 if ((*link_prev= link_next))
01481 link_next->link_prev= link_prev;
01482 }
01483
01484 for (; slave; slave= slave->next)
01485 slave->fast_exclude();
01486
01487 }
01488
01489
01490
01491
01492
01493 void Select_Lex_Node::exclude()
01494 {
01495
01496 fast_exclude();
01497
01498 if ((*prev= next))
01499 next->prev= prev;
01500
01501
01502
01503
01504
01505
01506 }
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 void Select_Lex_Unit::exclude_level()
01519 {
01520 Select_Lex_Unit *units= 0, **units_last= &units;
01521 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
01522 {
01523
01524 if (sl->link_prev && (*sl->link_prev= sl->link_next))
01525 sl->link_next->link_prev= sl->link_prev;
01526
01527
01528 Select_Lex_Unit **last= 0;
01529 for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
01530 {
01531 u->master= master;
01532 last= (Select_Lex_Unit**)&(u->next);
01533 }
01534 if (last)
01535 {
01536 (*units_last)= sl->first_inner_unit();
01537 units_last= last;
01538 }
01539 }
01540 if (units)
01541 {
01542
01543 (*prev)= units;
01544 (*units_last)= (Select_Lex_Unit*)next;
01545 if (next)
01546 next->prev= (Select_Lex_Node**)units_last;
01547 units->prev= prev;
01548 }
01549 else
01550 {
01551
01552 (*prev)= next;
01553 if (next)
01554 next->prev= prev;
01555 }
01556 }
01557
01558
01559
01560
01561 void Select_Lex_Unit::exclude_tree()
01562 {
01563 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
01564 {
01565
01566 if (sl->link_prev && (*sl->link_prev= sl->link_next))
01567 sl->link_next->link_prev= sl->link_prev;
01568
01569
01570 for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
01571 {
01572 u->exclude_level();
01573 }
01574 }
01575
01576 (*prev)= next;
01577 if (next)
01578 next->prev= prev;
01579 }
01580
01588 void Select_Lex::mark_as_dependent(Select_Lex *last)
01589 {
01590
01591
01592
01593
01594 for (Select_Lex *s= this;
01595 s && s != last;
01596 s= s->outer_select())
01597 {
01598 if (! (s->uncacheable.test(UNCACHEABLE_DEPENDENT)))
01599 {
01600
01601 s->uncacheable.set(UNCACHEABLE_DEPENDENT);
01602 s->uncacheable.set(UNCACHEABLE_UNITED);
01603 Select_Lex_Unit *munit= s->master_unit();
01604 munit->uncacheable.set(UNCACHEABLE_UNITED);
01605 munit->uncacheable.set(UNCACHEABLE_DEPENDENT);
01606 for (Select_Lex *sl= munit->first_select(); sl ; sl= sl->next_select())
01607 {
01608 if (sl != s &&
01609 ! (sl->uncacheable.test(UNCACHEABLE_DEPENDENT) && sl->uncacheable.test(UNCACHEABLE_UNITED)))
01610 sl->uncacheable.set(UNCACHEABLE_UNITED);
01611 }
01612 }
01613 s->is_correlated= true;
01614 Item_subselect *subquery_predicate= s->master_unit()->item;
01615 if (subquery_predicate)
01616 subquery_predicate->is_correlated= true;
01617 }
01618 }
01619
01620 bool Select_Lex_Node::set_braces(bool)
01621 { return true; }
01622
01623 bool Select_Lex_Node::inc_in_sum_expr()
01624 { return true; }
01625
01626 uint32_t Select_Lex_Node::get_in_sum_expr()
01627 { return 0; }
01628
01629 TableList* Select_Lex_Node::get_table_list()
01630 { return NULL; }
01631
01632 List<Item>* Select_Lex_Node::get_item_list()
01633 { return NULL; }
01634
01635 TableList *Select_Lex_Node::add_table_to_list(Session *,
01636 Table_ident *,
01637 LEX_STRING *,
01638 const bitset<NUM_OF_TABLE_OPTIONS>&,
01639 thr_lock_type,
01640 List<Index_hint> *,
01641 LEX_STRING *)
01642 {
01643 return 0;
01644 }
01645
01646
01647
01648
01649
01650 bool Select_Lex::test_limit()
01651 {
01652 if (select_limit != 0)
01653 {
01654 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
01655 "LIMIT & IN/ALL/ANY/SOME subquery");
01656 return true;
01657 }
01658 return false;
01659 }
01660
01661 Select_Lex_Unit* Select_Lex_Unit::master_unit()
01662 {
01663 return this;
01664 }
01665
01666 Select_Lex* Select_Lex_Unit::outer_select()
01667 {
01668 return (Select_Lex*) master;
01669 }
01670
01671 bool Select_Lex::add_order_to_list(Session *session, Item *item, bool asc)
01672 {
01673 return add_to_list(session, order_list, item, asc);
01674 }
01675
01676 bool Select_Lex::add_item_to_list(Session *, Item *item)
01677 {
01678 return(item_list.push_back(item));
01679 }
01680
01681 bool Select_Lex::add_group_to_list(Session *session, Item *item, bool asc)
01682 {
01683 return add_to_list(session, group_list, item, asc);
01684 }
01685
01686 Select_Lex_Unit* Select_Lex::master_unit()
01687 {
01688 return (Select_Lex_Unit*) master;
01689 }
01690
01691 Select_Lex* Select_Lex::outer_select()
01692 {
01693 return (Select_Lex*) master->get_master();
01694 }
01695
01696 bool Select_Lex::set_braces(bool value)
01697 {
01698 braces= value;
01699 return false;
01700 }
01701
01702 bool Select_Lex::inc_in_sum_expr()
01703 {
01704 in_sum_expr++;
01705 return false;
01706 }
01707
01708 uint32_t Select_Lex::get_in_sum_expr()
01709 {
01710 return in_sum_expr;
01711 }
01712
01713 TableList* Select_Lex::get_table_list()
01714 {
01715 return (TableList*) table_list.first;
01716 }
01717
01718 List<Item>* Select_Lex::get_item_list()
01719 {
01720 return &item_list;
01721 }
01722
01723
01724 bool Select_Lex::setup_ref_array(Session *session, uint32_t order_group_num)
01725 {
01726 if (ref_pointer_array)
01727 return false;
01728
01729 return (ref_pointer_array=
01730 (Item **)session->getMemRoot()->allocate(sizeof(Item*) * (n_child_sum_items +
01731 item_list.size() +
01732 select_n_having_items +
01733 select_n_where_fields +
01734 order_group_num)*5)) == 0;
01735 }
01736
01737 void Select_Lex_Unit::print(String *str)
01738 {
01739 bool union_all= !union_distinct;
01740 for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
01741 {
01742 if (sl != first_select())
01743 {
01744 str->append(STRING_WITH_LEN(" union "));
01745 if (union_all)
01746 str->append(STRING_WITH_LEN("all "));
01747 else if (union_distinct == sl)
01748 union_all= true;
01749 }
01750 if (sl->braces)
01751 str->append('(');
01752 sl->print(session, str);
01753 if (sl->braces)
01754 str->append(')');
01755 }
01756 if (fake_select_lex == global_parameters)
01757 {
01758 if (fake_select_lex->order_list.elements)
01759 {
01760 str->append(STRING_WITH_LEN(" order by "));
01761 fake_select_lex->print_order(
01762 str,
01763 (Order *) fake_select_lex->order_list.first);
01764 }
01765 fake_select_lex->print_limit(session, str);
01766 }
01767 }
01768
01769 void Select_Lex::print_order(String *str,
01770 Order *order)
01771 {
01772 for (; order; order= order->next)
01773 {
01774 if (order->counter_used)
01775 {
01776 char buffer[20];
01777 uint32_t length= snprintf(buffer, 20, "%d", order->counter);
01778 str->append(buffer, length);
01779 }
01780 else
01781 (*order->item)->print(str);
01782 if (!order->asc)
01783 str->append(STRING_WITH_LEN(" desc"));
01784 if (order->next)
01785 str->append(',');
01786 }
01787 }
01788
01789 void Select_Lex::print_limit(Session *, String *str)
01790 {
01791 Select_Lex_Unit *unit= master_unit();
01792 Item_subselect *item= unit->item;
01793
01794 if (item && unit->global_parameters == this)
01795 {
01796 Item_subselect::subs_type subs_type= item->substype();
01797 if (subs_type == Item_subselect::EXISTS_SUBS ||
01798 subs_type == Item_subselect::IN_SUBS ||
01799 subs_type == Item_subselect::ALL_SUBS)
01800 {
01801 assert(!item->fixed ||
01802
01803
01804
01805
01806 (((subs_type == Item_subselect::IN_SUBS) &&
01807 ((Item_in_subselect*)item)->exec_method ==
01808 Item_in_subselect::MATERIALIZATION) ?
01809 true :
01810 (select_limit->val_int() == 1L) &&
01811 offset_limit == 0));
01812 return;
01813 }
01814 }
01815 if (explicit_limit)
01816 {
01817 str->append(STRING_WITH_LEN(" limit "));
01818 if (offset_limit)
01819 {
01820 offset_limit->print(str);
01821 str->append(',');
01822 }
01823 select_limit->print(str);
01824 }
01825 }
01826
01827 LEX::~LEX()
01828 {
01829 delete _create_table;
01830 }
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849 void Query_tables_list::reset_query_tables_list(bool init)
01850 {
01851 if (!init && query_tables)
01852 {
01853 TableList *table= query_tables;
01854 for (;;)
01855 {
01856 if (query_tables_last == &table->next_global ||
01857 !(table= table->next_global))
01858 break;
01859 }
01860 }
01861 query_tables= 0;
01862 query_tables_last= &query_tables;
01863 query_tables_own_last= 0;
01864 }
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879 LEX::LEX() :
01880 result(0),
01881 yacc_yyss(0),
01882 yacc_yyvs(0),
01883 session(NULL),
01884 charset(NULL),
01885 var_list(),
01886 sql_command(SQLCOM_END),
01887 statement(NULL),
01888 option_type(OPT_DEFAULT),
01889 is_lex_started(0),
01890 cacheable(true),
01891 sum_expr_used(false),
01892 _create_table(NULL),
01893 _create_field(NULL),
01894 _exists(false)
01895 {
01896 reset_query_tables_list(true);
01897 }
01898
01917 bool LEX::copy_db_to(char **p_db, size_t *p_db_length) const
01918 {
01919 return session->copy_db_to(p_db, p_db_length);
01920 }
01921
01922
01923
01924
01925
01926
01927
01928
01929 void Select_Lex_Unit::set_limit(Select_Lex *sl)
01930 {
01931 ha_rows select_limit_val;
01932 uint64_t val;
01933
01934 val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
01935 select_limit_val= (ha_rows)val;
01936
01937
01938
01939
01940 if (val != (uint64_t)select_limit_val)
01941 select_limit_val= HA_POS_ERROR;
01942 offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
01943 0UL);
01944 select_limit_cnt= select_limit_val + offset_limit_cnt;
01945 if (select_limit_cnt < select_limit_val)
01946 select_limit_cnt= HA_POS_ERROR;
01947 }
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966
01967 TableList *LEX::unlink_first_table(bool *link_to_local)
01968 {
01969 TableList *first;
01970 if ((first= query_tables))
01971 {
01972
01973
01974
01975 if ((query_tables= query_tables->next_global))
01976 query_tables->prev_global= &query_tables;
01977 else
01978 query_tables_last= &query_tables;
01979 first->next_global= 0;
01980
01981
01982
01983
01984 if ((*link_to_local= test(select_lex.table_list.first)))
01985 {
01986 select_lex.context.table_list=
01987 select_lex.context.first_name_resolution_table= first->next_local;
01988 select_lex.table_list.first= (unsigned char*) (first->next_local);
01989 select_lex.table_list.elements--;
01990 first->next_local= 0;
01991
01992
01993
01994
01995 first_lists_tables_same();
01996 }
01997 }
01998 return first;
01999 }
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016 void LEX::first_lists_tables_same()
02017 {
02018 TableList *first_table= (TableList*) select_lex.table_list.first;
02019 if (query_tables != first_table && first_table != 0)
02020 {
02021 TableList *next;
02022 if (query_tables_last == &first_table->next_global)
02023 query_tables_last= first_table->prev_global;
02024
02025 if ((next= *first_table->prev_global= first_table->next_global))
02026 next->prev_global= first_table->prev_global;
02027
02028 first_table->next_global= query_tables;
02029
02030
02031
02032
02033
02034 query_tables->prev_global= &first_table->next_global;
02035 first_table->prev_global= &query_tables;
02036 query_tables= first_table;
02037 }
02038 }
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050 void LEX::link_first_table_back(TableList *first, bool link_to_local)
02051 {
02052 if (first)
02053 {
02054 if ((first->next_global= query_tables))
02055 query_tables->prev_global= &first->next_global;
02056 else
02057 query_tables_last= &first->next_global;
02058 query_tables= first;
02059
02060 if (link_to_local)
02061 {
02062 first->next_local= (TableList*) select_lex.table_list.first;
02063 select_lex.context.table_list= first;
02064 select_lex.table_list.first= (unsigned char*) first;
02065 select_lex.table_list.elements++;
02066 }
02067 }
02068 }
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081 void LEX::cleanup_after_one_table_open()
02082 {
02083
02084
02085
02086
02087
02088
02089
02090
02091 if (all_selects_list != &select_lex)
02092 {
02093 derived_tables= 0;
02094
02095 for (Select_Lex_Unit *un= select_lex.first_inner_unit();
02096 un;
02097 un= un->next_unit())
02098 un->cleanup();
02099
02100 all_selects_list= &select_lex;
02101
02102 select_lex.cut_subtree();
02103 }
02104 }
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133 void Select_Lex::set_index_hint_type(enum index_hint_type type_arg, index_clause_map clause)
02134 {
02135 current_index_hint_type= type_arg;
02136 current_index_hint_clause= clause;
02137 }
02138
02139
02140
02141
02142
02143
02144
02145
02146 void Select_Lex::alloc_index_hints (Session *session)
02147 {
02148 index_hints= new (session->mem_root) List<Index_hint>();
02149 }
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164 bool Select_Lex::add_index_hint (Session *session, char *str, uint32_t length)
02165 {
02166 return index_hints->push_front (new (session->mem_root)
02167 Index_hint(current_index_hint_type,
02168 current_index_hint_clause,
02169 str, length));
02170 }
02171
02172 bool check_for_sql_keyword(drizzled::lex_string_t const& string)
02173 {
02174 if (sql_reserved_words::in_word_set(string.str, string.length))
02175 return true;
02176
02177 return false;
02178 }
02179
02180 bool check_for_sql_keyword(drizzled::st_lex_symbol const& string)
02181 {
02182 if (sql_reserved_words::in_word_set(string.str, string.length))
02183 return true;
02184
02185 return false;
02186 }
02187
02188
02189 }