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