Drizzled Public API Documentation

sql_lex.cc
00001 /* Copyright (C) 2000-2006 MySQL AB
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00015 
00016 
00017 /* A lexical scanner on a temporary buffer with a yacc interface */
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 /* Stay outside of the namespace because otherwise bison goes nuts */
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   /* NOTE: utf_txt.length is in bytes, not in symbols. */
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   This is called before every query that is to be parsed.
00179   Because of this, it's critical to not do too much things here.
00180   (We already do too much here)
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   /* 'parent_lex' is used in init_query() so it must be before it. */
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   /* Plenty of memory for the largest lex symbol we have */
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 /* make a copy of token before ptr and set yytoklen */
00293 static lex_string_t get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
00294 {
00295   lip->yyUnget();                       // ptr points now after last token char
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  todo:
00306    There are no dangerous charsets in mysql for function
00307    get_quoted_token yet. But it should be fixed in the
00308    future to operate multichar strings (like ucs2)
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();                       // ptr points now after last token char
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++;         // Skip double quotes
00330       lip->m_cpp_text_start++;
00331     }
00332   }
00333   *to= 0;         // End null for safety
00334   return tmp;
00335 }
00336 
00337 
00338 /*
00339   Return an unescaped text literal without quotes
00340   Fix sometimes to do only one scan of the string
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();                        // String should end with this
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     {         // Escaped character
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())            // Check if two separators in a row
00374       {
00375         found_escape= true;                 // duplicate. Remember for delete
00376         continue;
00377       }
00378       else
00379         lip->yyUnget();
00380 
00381       /* Found end. Unescape and return string */
00382       const char* str= lip->get_tok_start();
00383       const char* end= lip->get_ptr();
00384       /* Extract the text from the token */
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;     // Ascii null
00434               break;
00435             case 'Z':     // ^Z must be escaped on Win32
00436               *to++= '\032';
00437               break;
00438             case '_':
00439             case '%':
00440               *to++= '\\';    // remember prefix for wildcard
00441               /* Fall through */
00442             default:
00443               *to++= *str;
00444               break;
00445             }
00446           }
00447           else if (*str == sep)
00448             *to++= *str++;    // Two ' or "
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;         // unexpected end of query
00459 }
00460 
00461 
00462 /*
00463 ** Calc type of integer; long integer, int64_t integer or real.
00464 ** Returns smallest type that match the string.
00465 ** When using uint64_t values the result is converted to a real
00466 ** because else they will be unexpected sign changes because all calculation
00467 ** is done with int64_t or double.
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)      // quick normal case
00483     return NUM;
00484   bool neg=0;
00485 
00486   if (*str == '+')        // Remove sign and pre-zeros
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;        // If <= signed_long_str
00510       bigger=LONG_NUM;        // If >= signed_long_str
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;       // If <= signed_int64_t_str
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 } /* namespace drizzled */
00553 /*
00554   base_sql_lex remember the following states from the following sql_baselex()
00555 
00556   - MY_LEX_EOQ      Found end of query
00557   - MY_LEX_OPERATOR_OR_IDENT  Last state was an ident, text or number
00558         (which can't be followed by a signed number)
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       The next token was already parsed in advance,
00569       return it.
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       Parsing 'WITH' 'ROLLUP' requires 2 look ups,
00584       which makes the grammar LALR(2).
00585       Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
00586       to transform the grammar into a LALR(1) grammar,
00587       which sql_yacc.yy can process.
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         Save the token following 'WITH'
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; /* Just set to shutup GCC */
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;     // The global state
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:  // Next is operator or keyword
00636     case MY_LEX_START:      // Start of token
00637       // Skip starting whitespace
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       /* Start of real token */
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       {         // Allow \N as shortcut for NULL
00654         yylval->lex_str.assign("\\N", 2);
00655         return NULL_SYM;
00656       }
00657     case MY_LEX_CHAR:     // Unknown or single char token
00658     case MY_LEX_SKIP:     // This should not happen
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;  // Allow signed numbers
00669 
00670       if (c == ',')
00671       {
00672         /*
00673           Warning:
00674           This is a work around, to make the "remember_name" rule in
00675           sql/sql_yacc.yy work properly.
00676           The problem is that, when parsing "select expr1, expr2",
00677           the code generated by bison executes the *pre* action
00678           remember_name (see select_item) *before* actually parsing the
00679           first token of expr2.
00680         */
00681         lip->restart_token();
00682       }
00683 
00684       return((int) c);
00685 
00686     case MY_LEX_IDENT_OR_HEX:
00687       if (lip->yyPeek() == '\'')
00688       {         // Found x'hex-number'
00689         state= MY_LEX_HEX_NUMBER;
00690         break;
00691       }
00692     case MY_LEX_IDENT_OR_BIN:
00693       if (lip->yyPeek() == '\'')
00694       {                                 // Found b'bin-number'
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         /* If there were non-ASCII characters, mark that we must convert */
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           If we find a space then this can't be an identifier. We notice this
00737           below by checking start != lex->ptr.
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       {         // '(' must follow directly if function
00745         lip->yyUnget();
00746         if ((tokval = find_keyword(lip, length, c == '(')))
00747         {
00748           lip->next_state= MY_LEX_START;  // Allow signed numbers
00749           return(tokval);   // Was keyword
00750         }
00751         lip->yySkip();                  // next state does a unget
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);     // IDENT or IDENT_QUOTED
00760 
00761     case MY_LEX_IDENT_SEP:    // Found ident and now '.'
00762       yylval->lex_str.assign(lip->get_ptr(), 1);
00763       c= lip->yyGet();                  // should be '.'
00764       lip->next_state= MY_LEX_IDENT_START;// Next is an ident (not a keyword)
00765       if (!ident_map[(uint8_t)lip->yyPeek()])            // Probably ` or "
00766         lip->next_state= MY_LEX_START;
00767       return((int) c);
00768 
00769     case MY_LEX_NUMBER_IDENT:   // number or ident which num-start
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             /* skip '0x' */
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             /* Skip '0b' */
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       {         // Can't be identifier
00805         state=MY_LEX_INT_OR_REAL;
00806         break;
00807       }
00808       if (c == 'e' || c == 'E')
00809       {
00810         // The following test is written this way to allow numbers of type 1e1
00811         if (cs->isdigit(lip->yyPeek()) ||
00812             (c=(lip->yyGet())) == '+' || c == '-')
00813         {       // Allow 1E+10
00814           if (cs->isdigit(lip->yyPeek()))     // Number must have digit after sign
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       // fall through
00825     case MY_LEX_IDENT_START:      // We come here after '.'
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         /* If there were non-ASCII characters, mark that we must convert */
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;// Next is '.'
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:  // Found quote char
00858     {
00859       uint32_t double_quotes= 0;
00860       char quote_char= c;                       // Used char
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;        // Error
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();                  // Skip end `
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:    // Complete int or incomplete real
00890       if (c != '.')
00891       {         // Found complete integer number.
00892         yylval->lex_str=get_token(lip, 0, lip->yyLength());
00893         return int_token(yylval->lex_str.data(), yylval->lex_str.size());
00894       }
00895       // fall through
00896     case MY_LEX_REAL:     // Incomplete real number
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();                     // Skip sign
00904         if (!cs->isdigit(c))
00905         {       // No digit after sign
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:   // Found x'hexstring'
00917       lip->yySkip();                    // Accept opening '
00918       while (cs->isxdigit((c= lip->yyGet()))) ;
00919       if (c != '\'')
00920         return(ABORT_SYM);              // Illegal hex constant
00921       lip->yySkip();                    // Accept closing '
00922       length= lip->yyLength();          // Length of hexnum+3
00923       if (length % 2 == 0)
00924         return ABORT_SYM;               // odd number of hex digits
00925       yylval->lex_str=get_token(lip,
00926                                 2,          // skip x'
00927                                 length-3);  // don't count x' and last '
00928       return (HEX_NUM);
00929 
00930     case MY_LEX_BIN_NUMBER:           // Found b'bin-string'
00931       lip->yySkip();                  // Accept opening '
00932       while ((c= lip->yyGet()) == '0' || c == '1') {};
00933       if (c != '\'')
00934         return(ABORT_SYM);            // Illegal hex constant
00935       lip->yySkip();                  // Accept closing '
00936       length= lip->yyLength();        // Length of bin-num + 3
00937       yylval->lex_str= get_token(lip,
00938                                  2,         // skip b'
00939                                  length-3); // don't count b' and last '
00940       return (BIN_NUM);
00941 
00942     case MY_LEX_CMP_OP:     // Incomplete comparison operator
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;  // Allow signed numbers
00949         return(tokval);
00950       }
00951       state = MY_LEX_CHAR;    // Something fishy found
00952       break;
00953 
00954     case MY_LEX_LONG_CMP_OP:    // Incomplete comparison operator
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;  // Found long op
00965         return(tokval);
00966       }
00967       state = MY_LEX_CHAR;    // Something fishy found
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); // Is a bool operator
00978       lip->next_state= MY_LEX_START;  // Allow signed numbers
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       /* " used for strings */
00988     case MY_LEX_STRING:     // Incomplete text string
00989       if (!(yylval->lex_str.str_ = get_text(lip, 1, 1)))
00990       {
00991         state= MY_LEX_CHAR;   // Read char by 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:      //  Comment
01003       lex->select_lex.options|= OPTION_FOUND_COMMENT;
01004       while ((c = lip->yyGet()) != '\n' && c) ;
01005       lip->yyUnget();                   // Safety against eof
01006       state = MY_LEX_START;   // Try again
01007       break;
01008 
01009     case MY_LEX_LONG_COMMENT:   /* Long C comment? */
01010       if (lip->yyPeek() != '*')
01011       {
01012         state=MY_LEX_CHAR;    // Probable division
01013         break;
01014       }
01015       lex->select_lex.options|= OPTION_FOUND_COMMENT;
01016       /* Reject '/' '*', since we might need to turn off the echo */
01017       lip->yyUnget();
01018 
01019       if (lip->yyPeekn(2) == '!')
01020       {
01021         lip->in_comment= DISCARD_COMMENT;
01022         /* Accept '/' '*' '!', but do not keep this marker. */
01023         lip->set_echo(false);
01024         lip->yySkip();
01025         lip->yySkip();
01026         lip->yySkip();
01027 
01028         /*
01029           The special comment format is very strict:
01030           '/' '*' '!', followed by digits ended by a non-digit.
01031           There must be at least 5 digits for it to count
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         /* To keep some semblance of compatibility, we impose a 5 digit floor */
01045         if (pos > 4)
01046         {
01047           uint64_t version;
01048           version=strtoll(version_str, NULL, 10);
01049 
01050           /* Accept 'M' 'm' 'm' 'd' 'd' */
01051           lip->yySkipn(pos-1);
01052 
01053           if (version <= DRIZZLE_VERSION_ID)
01054           {
01055             /* Expand the content of the special comment as real code */
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();                  // Accept /
01072         lip->yySkip();                  // Accept *
01073       }
01074       /*
01075         Discard:
01076         - regular '/' '*' comments,
01077         - special comments '/' '*' '!' for a future version,
01078         by scanning until we find a closing '*' '/' marker.
01079         Note: There is no such thing as nesting comments,
01080         the first '*' '/' sequence seen will mark the end.
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       /* Unbalanced comments with a missing '*' '/' are a syntax error */
01100       if (! comment_closed)
01101         return (ABORT_SYM);
01102       state = MY_LEX_START;             // Try again
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         /* Reject '*' '/' */
01111         lip->yyUnget();
01112         /* Accept '*' '/', with the proper echo */
01113         lip->set_echo(lip->in_comment == PRESERVE_COMMENT);
01114         lip->yySkipn(2);
01115         /* And start recording the tokens again */
01116         lip->set_echo(true);
01117         lip->in_comment=NO_COMMENT;
01118         state=MY_LEX_START;
01119       }
01120       else
01121         state=MY_LEX_CHAR;    // Return '*'
01122       break;
01123 
01124     case MY_LEX_SET_VAR:    // Check if ':='
01125       if (lip->yyPeek() != '=')
01126       {
01127         state=MY_LEX_CHAR;    // Return ':'
01128         break;
01129       }
01130       lip->yySkip();
01131       return (SET_VAR);
01132 
01133     case MY_LEX_SEMICOLON:      // optional line terminator
01134       if (lip->yyPeek())
01135       {
01136         state= MY_LEX_CHAR;   // Return ';'
01137         break;
01138       }
01139       lip->next_state=MY_LEX_END;       // Mark for next loop
01140       return(END_OF_INPUT);
01141 
01142     case MY_LEX_EOL:
01143       if (lip->eof())
01144       {
01145         lip->yyUnget();                 // Reject the last '\0'
01146         lip->set_echo(false);
01147         lip->yySkip();
01148         lip->set_echo(true);
01149         /* Unbalanced comments with a missing '*' '/' are a syntax error */
01150         if (lip->in_comment != NO_COMMENT)
01151           return (ABORT_SYM);
01152         lip->next_state=MY_LEX_END;     // Mark for next loop
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;     // We found end of input last time
01161 
01162       /* Actually real shouldn't start with . but allow them anyhow */
01163 
01164     case MY_LEX_REAL_OR_POINT:
01165       if (cs->isdigit(lip->yyPeek()))
01166         state= MY_LEX_REAL;   // Real
01167       else
01168       {
01169         state= MY_LEX_IDENT_SEP;  // return '.'
01170         lip->yyUnget();                 // Put back '.'
01171       }
01172       break;
01173 
01174     case MY_LEX_USER_END:   // end '@' of user@hostname
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:   // end '@' of user@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();                                    // Skip '@'
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         We come here when we have found two '@' in a row.
01209         We should now be able to handle:
01210         [(global | local | session) .]variable_name
01211       */
01212 
01213       for (result_state= 0; ident_map[c= lip->yyGet()]; result_state|= c) {};
01214       /* If there were non-ASCII characters, mark that we must convert */
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);              // Names must be nonempty.
01223 
01224       if ((tokval= find_keyword(lip, length,0)))
01225       {
01226         lip->yyUnget();                         // Put back 'c'
01227         return(tokval);       // Was keyword
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   Select_Lex structures initialisations
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     Add the name resolution context of the current (sub)query to the
01289     stack of contexts for the whole query.
01290     TODO:
01291     push_context may return an error if there is no memory for a new
01292     element in the stack, however this method has no return value,
01293     thus push_context should be moved to a place where query
01294     initialization is checked for failure.
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   /* Set limit and offset to default values */
01326   select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
01327   offset_limit= 0;      /* denotes the default offset = 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   Select_Lex structures linking
01340 */
01341 
01342 /* include on level down */
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   include on level down (but do not link)
01355 
01356   SYNOPSYS
01357     Select_Lex_Node::include_standalone()
01358     upper - reference on node underr which this node should be included
01359     ref - references on reference on this node
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 /* include neighbour (on same level) */
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 /* including in global Select_Lex list */
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 //excluding from global list (internal function)
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   // Remove slave structure
01399   for (; slave; slave= slave->next)
01400     slave->fast_exclude();
01401 
01402 }
01403 
01404 /*
01405   excluding select_lex structure (except first (first select can't be
01406   deleted, because it is most upper select))
01407 */
01408 void Select_Lex_Node::exclude()
01409 {
01410   //exclude from global list
01411   fast_exclude();
01412   //exclude from other structures
01413   if ((*prev= next))
01414     next->prev= prev;
01415   /*
01416      We do not need following statements, because prev pointer of first
01417      list element point to master->slave
01418      if (master->slave == this)
01419        master->slave= next;
01420   */
01421 }
01422 
01423 
01424 /*
01425   Exclude level of current unit from tree of SELECTs
01426 
01427   SYNOPSYS
01428     Select_Lex_Unit::exclude_level()
01429 
01430   NOTE: units which belong to current will be brought up on level of
01431   currernt unit
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     // unlink current level from global SELECTs list
01439     if (sl->link_prev && (*sl->link_prev= sl->link_next))
01440       sl->link_next->link_prev= sl->link_prev;
01441 
01442     // bring up underlay levels
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     // include brought up levels in place of current
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     // exclude currect unit from list of nodes
01467     (*prev)= next;
01468     if (next)
01469       next->prev= prev;
01470   }
01471 }
01472 
01473 /*
01474   Exclude subtree of current unit from tree of SELECTs
01475 */
01476 void Select_Lex_Unit::exclude_tree()
01477 {
01478   for (Select_Lex *sl= first_select(); sl; sl= sl->next_select())
01479   {
01480     // unlink current level from global SELECTs list
01481     if (sl->link_prev && (*sl->link_prev= sl->link_next))
01482       sl->link_next->link_prev= sl->link_prev;
01483 
01484     // unlink underlay levels
01485     for (Select_Lex_Unit *u= sl->first_inner_unit(); u; u= u->next_unit())
01486     {
01487       u->exclude_level();
01488     }
01489   }
01490   // exclude currect unit from list of nodes
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     Mark all selects from resolved to 1 before select where was
01507     found table as depended (of select where was found table)
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       // Select is dependent of outer select
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   prohibit using LIMIT clause
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                     If not using materialization both:
01711                     select_limit == 1, and there should be no offset_limit.
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   Initialize (or reset) Query_tables_list object.
01742 
01743   SYNOPSIS
01744     reset_query_tables_list()
01745       init  true  - we should perform full initialization of object with
01746                     allocating needed memory
01747             false - object is already initialized so we should only reset
01748                     its state so it can be used for parsing/processing
01749                     of new statement
01750 
01751   DESCRIPTION
01752     This method initializes Query_tables_list so it can be used as part
01753     of LEX object for parsing/processing of statement. One can also use
01754     this method to reset state of already initialized Query_tables_list
01755     so it can be used for processing of new statement.
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   Initialize LEX object.
01776 
01777   SYNOPSIS
01778     LEX::LEX()
01779 
01780   NOTE
01781     LEX object initialized with this constructor can be used as part of
01782     Session object for which one can safely call open_tables(), lock_tables()
01783     and close_thread_tables() functions. But it is not yet ready for
01784     statement parsing. On should use lex_start() function to prepare LEX
01785     for this.
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   initialize limit counters
01810 
01811   SYNOPSIS
01812     Select_Lex_Unit::set_limit()
01813     values  - Select_Lex with initial values for counters
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     Check for overflow : ha_rows can be smaller then uint64_t if
01824     BIG_TABLES is off.
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;   // no limit
01833 }
01834 
01835 /*
01836   Unlink the first table from the global table list and the first table from
01837   outer select (lex->select_lex) local list
01838 
01839   SYNOPSIS
01840     unlink_first_table()
01841     link_to_local Set to 1 if caller should link this table to local list
01842 
01843   NOTES
01844     We assume that first tables in both lists is the same table or the local
01845     list is empty.
01846 
01847   RETURN
01848     0 If 'query_tables' == 0
01849     unlinked table
01850       In this case link_to_local is set.
01851 
01852 */
01853 TableList *LEX::unlink_first_table(bool *link_to_local)
01854 {
01855   TableList *first;
01856   if ((first= query_tables))
01857   {
01858     /*
01859       Exclude from global table list
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       and from local list if it is not empty
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--; //safety
01876       first->next_local= 0;
01877       /*
01878         Ensure that the global list has the same first table as the local
01879         list.
01880       */
01881       first_lists_tables_same();
01882     }
01883   }
01884   return first;
01885 }
01886 
01887 /*
01888   Bring first local table of first most outer select to first place in global
01889   table list
01890 
01891   SYNOPSYS
01892      LEX::first_lists_tables_same()
01893 
01894   NOTES
01895     In many cases (for example, usual INSERT/DELETE/...) the first table of
01896     main Select_Lex have special meaning => check that it is the first table
01897     in global list and re-link to be first in the global list if it is
01898     necessary.  We need such re-linking only for queries with sub-queries in
01899     the select list, as only in this case tables of sub-queries will go to
01900     the global list first.
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     /* include in new place */
01914     first_table->next_global= query_tables;
01915     /*
01916        We are sure that query_tables is not 0, because first_table was not
01917        first table in the global list => we can use
01918        query_tables->prev_global without check of query_tables
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   Link table back that was unlinked with unlink_first_table()
01928 
01929   SYNOPSIS
01930     link_first_table_back()
01931     link_to_local do we need link this table to local
01932 
01933   RETURN
01934     global list
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++; //safety
01952     }
01953   }
01954 }
01955 
01956 /*
01957   cleanup lex for case when we open table by table for processing
01958 
01959   SYNOPSIS
01960     LEX::cleanup_after_one_table_open()
01961 
01962   NOTE
01963     This method is mostly responsible for cleaning up of selects lists and
01964     derived tables state. To rollback changes in Query_tables_list one has
01965     to call Query_tables_list::reset_query_tables_list(false).
01966 */
01967 void LEX::cleanup_after_one_table_open()
01968 {
01969   /*
01970     session->lex().derived_tables & additional units may be set if we open
01971     a view. It is necessary to clear session->lex().derived_tables flag
01972     to prevent processing of derived tables during next openTablesLock
01973     if next table is a real table and cleanup & remove underlying units
01974     NOTE: all units will be connected to session->lex().select_lex, because we
01975     have not UNION on most upper level.
01976     */
01977   if (all_selects_list != &select_lex)
01978   {
01979     derived_tables= 0;
01980     /* cleunup underlying units (units of VIEW) */
01981     for (Select_Lex_Unit *un= select_lex.first_inner_unit();
01982          un;
01983          un= un->next_unit())
01984       un->cleanup();
01985     /* reduce all selects list to default state */
01986     all_selects_list= &select_lex;
01987     /* remove underlying units (units of VIEW) subtree */
01988     select_lex.cut_subtree();
01989   }
01990 }
01991 
01992 /*
01993   There are Select_Lex::add_table_to_list &
01994   Select_Lex::set_lock_for_tables are in sql_parse.cc
01995 
01996   Select_Lex::print is in sql_select.cc
01997 
01998   Select_Lex_Unit::prepare, Select_Lex_Unit::exec,
01999   Select_Lex_Unit::cleanup, Select_Lex_Unit::reinit_exec_mechanism,
02000   Select_Lex_Unit::change_result
02001   are in sql_union.cc
02002 */
02003 
02004 /*
02005   Sets the kind of hints to be added by the calls to add_index_hint().
02006 
02007   SYNOPSIS
02008     set_index_hint_type()
02009       type_arg     The kind of hints to be added from now on.
02010       clause       The clause to use for hints to be added from now on.
02011 
02012   DESCRIPTION
02013     Used in filling up the tagged hints list.
02014     This list is filled by first setting the kind of the hint as a
02015     context variable and then adding hints of the current kind.
02016     Then the context variable index_hint_type can be reset to the
02017     next hint type.
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   Makes an array to store index usage hints (ADD/FORCE/IGNORE INDEX).
02027 
02028   SYNOPSIS
02029     alloc_index_hints()
02030       session         current thread.
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   adds an element to the array storing index usage hints
02039   (ADD/FORCE/IGNORE INDEX).
02040 
02041   SYNOPSIS
02042     add_index_hint()
02043       session         current thread.
02044       str         name of the index.
02045       length      number of characters in str.
02046 
02047   RETURN VALUE
02048     0 on success, non-zero otherwise
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 } /* namespace drizzled */