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