~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_lex.cc

  • Committer: Jay Pipes
  • Date: 2008-07-21 17:52:33 UTC
  • mto: (201.2.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 204.
  • Revision ID: jay@mysql.com-20080721175233-mtyz298j8xl3v63y
cleanup of FAQ file

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* A lexical scanner on a temporary buffer with a yacc interface */
18
18
 
19
 
#define DRIZZLE_LEX 1
20
 
#include <drizzled/server_includes.h>
 
19
#define MYSQL_LEX 1
 
20
#include "mysql_priv.h"
 
21
#include "item_create.h"
 
22
#include <m_ctype.h>
 
23
#include <hash.h>
21
24
 
22
25
static int lex_one_token(void *arg, void *yythd);
23
26
 
42
45
  used when comparing keywords
43
46
*/
44
47
 
45
 
static unsigned char to_upper_lex[]=
 
48
static uchar to_upper_lex[]=
46
49
{
47
50
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
48
51
   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
74
77
  "FORCE INDEX"
75
78
};
76
79
 
77
 
inline int lex_casecmp(const char *s, const char *t, uint32_t len)
 
80
inline int lex_casecmp(const char *s, const char *t, uint len)
78
81
{
79
82
  while (len-- != 0 &&
80
 
         to_upper_lex[(unsigned char) *s++] == to_upper_lex[(unsigned char) *t++]) ;
 
83
         to_upper_lex[(uchar) *s++] == to_upper_lex[(uchar) *t++]) ;
81
84
  return (int) len+1;
82
85
}
83
86
 
86
89
 
87
90
void lex_init(void)
88
91
{
89
 
  uint32_t i;
 
92
  uint i;
90
93
  for (i=0 ; i < array_elements(symbols) ; i++)
91
 
    symbols[i].length=(unsigned char) strlen(symbols[i].name);
 
94
    symbols[i].length=(uchar) strlen(symbols[i].name);
92
95
  for (i=0 ; i < array_elements(sql_functions) ; i++)
93
 
    sql_functions[i].length=(unsigned char) strlen(sql_functions[i].name);
 
96
    sql_functions[i].length=(uchar) strlen(sql_functions[i].name);
94
97
 
95
98
  return;
96
99
}
163
166
  assert(begin_ptr);
164
167
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
165
168
 
166
 
  uint32_t body_utf8_length=
 
169
  uint body_utf8_length=
167
170
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
168
171
    my_charset_utf8_bin.mbmaxlen;
169
172
 
243
246
 
244
247
void Lex_input_stream::body_utf8_append_literal(THD *thd,
245
248
                                                const LEX_STRING *txt,
246
 
                                                const CHARSET_INFO * const txt_cs,
 
249
                                                CHARSET_INFO *txt_cs,
247
250
                                                const char *end_ptr)
248
251
{
249
252
  if (!m_cpp_utf8_processed_ptr)
331
334
  lex->reset_query_tables_list(false);
332
335
  lex->expr_allows_subselect= true;
333
336
  lex->use_only_table_context= false;
334
 
  lex->parse_vcol_expr= false;
335
337
 
336
338
  lex->name.str= 0;
337
339
  lex->name.length= 0;
340
342
  lex->in_sum_func= NULL;
341
343
  /*
342
344
    ok, there must be a better solution for this, long-term
343
 
    I tried "memset" in the sql_yacc.yy code, but that for
 
345
    I tried "bzero" in the sql_yacc.yy code, but that for
344
346
    some reason made the values zero, even if they were set
345
347
  */
346
348
  lex->server_options.server_name= 0;
361
363
{
362
364
  if (lex->yacc_yyss)
363
365
  {
364
 
    free(lex->yacc_yyss);
365
 
    free(lex->yacc_yyvs);
 
366
    my_free(lex->yacc_yyss, MYF(0));
 
367
    my_free(lex->yacc_yyvs, MYF(0));
366
368
    lex->yacc_yyss= 0;
367
369
    lex->yacc_yyvs= 0;
368
370
  }
372
374
                     lex->plugins.elements);
373
375
  reset_dynamic(&lex->plugins);
374
376
 
375
 
  delete lex->result;
376
 
  lex->result= 0;
377
 
 
378
377
  return;
379
378
}
380
379
 
381
380
 
382
 
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
 
381
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
383
382
{
384
383
  const char *tok= lip->get_tok_start();
385
384
 
408
407
    1         name isn't a keyword
409
408
*/
410
409
 
411
 
bool is_keyword(const char *name, uint32_t len)
 
410
bool is_keyword(const char *name, uint len)
412
411
{
413
412
  assert(len != 0);
414
413
  return get_hash_symbol(name,len,0)!=0;
422
421
 
423
422
/* make a copy of token before ptr and set yytoklen */
424
423
 
425
 
static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
 
424
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
426
425
{
427
426
  LEX_STRING tmp;
428
427
  lip->yyUnget();                       // ptr points now after last token char
443
442
*/
444
443
 
445
444
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
446
 
                                   uint32_t skip,
447
 
                                   uint32_t length, char quote)
 
445
                                   uint skip,
 
446
                                   uint length, char quote)
448
447
{
449
448
  LEX_STRING tmp;
450
449
  const char *from, *end;
479
478
 
480
479
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
481
480
{
482
 
  register unsigned char c,sep;
483
 
  uint32_t found_escape=0;
484
 
  const CHARSET_INFO * const cs= lip->m_thd->charset();
 
481
  register uchar c,sep;
 
482
  uint found_escape=0;
 
483
  CHARSET_INFO *cs= lip->m_thd->charset();
485
484
 
486
485
  lip->tok_bitmap= 0;
487
486
  sep= lip->yyGetLast();                        // String should end with this
557
556
              continue;
558
557
          }
559
558
#endif
560
 
          if (*str == '\\' && str+1 != end)
 
559
          if (!(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
560
              *str == '\\' && str+1 != end)
561
561
          {
562
562
            switch(*++str) {
563
563
            case 'n':
605
605
/*
606
606
** Calc type of integer; long integer, int64_t integer or real.
607
607
** Returns smallest type that match the string.
608
 
** When using uint64_t values the result is converted to a real
 
608
** When using unsigned long long values the result is converted to a real
609
609
** because else they will be unexpected sign changes because all calculation
610
610
** is done with int64_t or double.
611
611
*/
612
612
 
613
613
static const char *long_str="2147483647";
614
 
static const uint32_t long_len=10;
 
614
static const uint long_len=10;
615
615
static const char *signed_long_str="-2147483648";
616
616
static const char *int64_t_str="9223372036854775807";
617
 
static const uint32_t int64_t_len=19;
 
617
static const uint int64_t_len=19;
618
618
static const char *signed_int64_t_str="-9223372036854775808";
619
 
static const uint32_t signed_int64_t_len=19;
 
619
static const uint signed_int64_t_len=19;
620
620
static const char *unsigned_int64_t_str="18446744073709551615";
621
 
static const uint32_t unsigned_int64_t_len=20;
 
621
static const uint unsigned_int64_t_len=20;
622
622
 
623
 
static inline uint32_t int_token(const char *str,uint32_t length)
 
623
static inline uint int_token(const char *str,uint length)
624
624
{
625
625
  if (length < long_len)                        // quick normal case
626
626
    return NUM;
642
642
  if (length < long_len)
643
643
    return NUM;
644
644
 
645
 
  uint32_t smaller,bigger;
 
645
  uint smaller,bigger;
646
646
  const char *cmp;
647
647
  if (neg)
648
648
  {
689
689
    }
690
690
  }
691
691
  while (*cmp && *cmp++ == *str++) ;
692
 
  return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
 
692
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
693
693
}
694
694
 
695
695
 
726
726
  switch(token) {
727
727
  case WITH:
728
728
    /*
729
 
      Parsing 'WITH' 'ROLLUP' requires 2 look ups,
 
729
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
730
730
      which makes the grammar LALR(2).
731
731
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
732
732
      to transform the grammar into a LALR(1) grammar,
733
733
      which sql_yacc.yy can process.
734
734
    */
735
735
    token= lex_one_token(arg, yythd);
736
 
    if (token == ROLLUP_SYM)
737
 
    {
 
736
    switch(token) {
 
737
    case CUBE_SYM:
 
738
      return WITH_CUBE_SYM;
 
739
    case ROLLUP_SYM:
738
740
      return WITH_ROLLUP_SYM;
739
 
    }
740
 
    else
741
 
    {
 
741
    default:
742
742
      /*
743
743
        Save the token following 'WITH'
744
744
      */
766
766
  Lex_input_stream *lip= thd->m_lip;
767
767
  LEX *lex= thd->lex;
768
768
  YYSTYPE *yylval=(YYSTYPE*) arg;
769
 
  const CHARSET_INFO * const cs= thd->charset();
770
 
  unsigned char *state_map= cs->state_map;
771
 
  unsigned char *ident_map= cs->ident_map;
 
769
  CHARSET_INFO *cs= thd->charset();
 
770
  uchar *state_map= cs->state_map;
 
771
  uchar *ident_map= cs->ident_map;
772
772
 
773
773
  lip->yylval=yylval;                   // The global state
774
774
 
830
830
 
831
831
      return((int) c);
832
832
 
 
833
    case MY_LEX_IDENT_OR_NCHAR:
 
834
      if (lip->yyPeek() != '\'')
 
835
      {
 
836
        state= MY_LEX_IDENT;
 
837
        break;
 
838
      }
 
839
      /* Found N'string' */
 
840
      lip->yySkip();                         // Skip '
 
841
      if (!(yylval->lex_str.str = get_text(lip, 2, 1)))
 
842
      {
 
843
        state= MY_LEX_CHAR;             // Read char by char
 
844
        break;
 
845
      }
 
846
      yylval->lex_str.length= lip->yytoklen;
 
847
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
 
848
      return(NCHAR_STRING);
 
849
 
833
850
    case MY_LEX_IDENT_OR_HEX:
834
851
      if (lip->yyPeek() == '\'')
835
852
      {                                 // Found x'hex-number'
912
929
 
913
930
      if (yylval->lex_str.str[0] == '_')
914
931
      {
915
 
        const CHARSET_INFO * const cs= get_charset_by_csname(yylval->lex_str.str + 1,
916
 
                                                             MY_CS_PRIMARY, MYF(0));
 
932
        CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1,
 
933
                                                MY_CS_PRIMARY, MYF(0));
917
934
        if (cs)
918
935
        {
919
936
          yylval->charset= cs;
1037
1054
 
1038
1055
    case MY_LEX_USER_VARIABLE_DELIMITER:        // Found quote char
1039
1056
    {
1040
 
      uint32_t double_quotes= 0;
 
1057
      uint double_quotes= 0;
1041
1058
      char quote_char= c;                       // Used char
1042
1059
      while ((c=lip->yyGet()))
1043
1060
      {
1247
1264
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1248
1265
          lip->yySkipn(5);
1249
1266
 
1250
 
          if (version <= DRIZZLE_VERSION_ID)
 
1267
          if (version <= MYSQL_VERSION_ID)
1251
1268
          {
1252
1269
            /* Expand the content of the special comment as real code */
1253
1270
            lip->set_echo(true);
1476
1493
}
1477
1494
 
1478
1495
 
1479
 
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
 
1496
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
1480
1497
{
1481
1498
  /*
1482
1499
    TODO:
1568
1585
  select_n_having_items= 0;
1569
1586
  subquery_in_having= explicit_limit= 0;
1570
1587
  is_item_list_lookup= 0;
 
1588
  first_execution= 1;
 
1589
  first_cond_optimization= 1;
1571
1590
  parsing_place= NO_MATTER;
1572
1591
  exclude_from_table_unique_test= false;
1573
1592
  nest_level= 0;
1592
1611
  linkage= UNSPECIFIED_TYPE;
1593
1612
  order_list.elements= 0;
1594
1613
  order_list.first= 0;
1595
 
  order_list.next= (unsigned char**) &order_list.first;
 
1614
  order_list.next= (uchar**) &order_list.first;
1596
1615
  /* Set limit and offset to default values */
1597
1616
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1598
1617
  offset_limit= 0;      /* denotes the default offset = 0 */
1812
1831
  }
1813
1832
}
1814
1833
 
1815
 
bool st_select_lex_node::set_braces(bool value __attribute__((unused)))
 
1834
bool st_select_lex_node::set_braces(bool value __attribute__((__unused__)))
1816
1835
{ return 1; }
1817
1836
bool st_select_lex_node::inc_in_sum_expr()           { return 1; }
1818
 
uint32_t st_select_lex_node::get_in_sum_expr()           { return 0; }
1819
 
TableList* st_select_lex_node::get_table_list()     { return 0; }
 
1837
uint st_select_lex_node::get_in_sum_expr()           { return 0; }
 
1838
TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
1820
1839
List<Item>* st_select_lex_node::get_item_list()      { return 0; }
1821
 
TableList *st_select_lex_node::add_table_to_list (THD *thd __attribute__((unused)),
1822
 
                                                   Table_ident *table __attribute__((unused)),
1823
 
                                                  LEX_STRING *alias __attribute__((unused)),
1824
 
                                                  uint32_t table_join_options __attribute__((unused)),
1825
 
                                                  thr_lock_type flags __attribute__((unused)),
1826
 
                                                  List<Index_hint> *hints __attribute__((unused)),
1827
 
                                                  LEX_STRING *option __attribute__((unused)))
 
1840
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd __attribute__((__unused__)),
 
1841
                                                   Table_ident *table __attribute__((__unused__)),
 
1842
                                                  LEX_STRING *alias __attribute__((__unused__)),
 
1843
                                                  ulong table_join_options __attribute__((__unused__)),
 
1844
                                                  thr_lock_type flags __attribute__((__unused__)),
 
1845
                                                  List<Index_hint> *hints __attribute__((__unused__)),
 
1846
                                                  LEX_STRING *option __attribute__((__unused__)))
1828
1847
{
1829
1848
  return 0;
1830
1849
}
1831
 
uint32_t st_select_lex_node::get_table_join_options()
 
1850
ulong st_select_lex_node::get_table_join_options()
1832
1851
{
1833
1852
  return 0;
1834
1853
}
1866
1885
}
1867
1886
 
1868
1887
 
1869
 
bool st_select_lex::add_item_to_list(THD *thd __attribute__((unused)),
 
1888
bool st_select_lex::add_item_to_list(THD *thd __attribute__((__unused__)),
1870
1889
                                     Item *item)
1871
1890
{
1872
1891
  return(item_list.push_back(item));
1905
1924
}
1906
1925
 
1907
1926
 
1908
 
uint32_t st_select_lex::get_in_sum_expr()
 
1927
uint st_select_lex::get_in_sum_expr()
1909
1928
{
1910
1929
  return in_sum_expr;
1911
1930
}
1912
1931
 
1913
1932
 
1914
 
TableList* st_select_lex::get_table_list()
 
1933
TABLE_LIST* st_select_lex::get_table_list()
1915
1934
{
1916
 
  return (TableList*) table_list.first;
 
1935
  return (TABLE_LIST*) table_list.first;
1917
1936
}
1918
1937
 
1919
1938
List<Item>* st_select_lex::get_item_list()
1921
1940
  return &item_list;
1922
1941
}
1923
1942
 
1924
 
uint32_t st_select_lex::get_table_join_options()
 
1943
ulong st_select_lex::get_table_join_options()
1925
1944
{
1926
1945
  return table_join_options;
1927
1946
}
1928
1947
 
1929
1948
 
1930
 
bool st_select_lex::setup_ref_array(THD *thd, uint32_t order_group_num)
 
1949
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
1931
1950
{
1932
1951
  if (ref_pointer_array)
1933
1952
    return 0;
1934
1953
 
 
1954
  /*
 
1955
    We have to create array in prepared statement memory if it is
 
1956
    prepared statement
 
1957
  */
 
1958
  Query_arena *arena= thd->stmt_arena;
1935
1959
  return (ref_pointer_array=
1936
 
          (Item **)thd->alloc(sizeof(Item*) * (n_child_sum_items +
 
1960
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
1937
1961
                                                 item_list.elements +
1938
1962
                                                 select_n_having_items +
1939
1963
                                                 select_n_where_fields +
1967
1991
      str->append(STRING_WITH_LEN(" order by "));
1968
1992
      fake_select_lex->print_order(
1969
1993
        str,
1970
 
        (order_st *) fake_select_lex->order_list.first,
 
1994
        (ORDER *) fake_select_lex->order_list.first,
1971
1995
        query_type);
1972
1996
    }
1973
1997
    fake_select_lex->print_limit(thd, str, query_type);
1976
2000
 
1977
2001
 
1978
2002
void st_select_lex::print_order(String *str,
1979
 
                                order_st *order,
 
2003
                                ORDER *order,
1980
2004
                                enum_query_type query_type)
1981
2005
{
1982
2006
  for (; order; order= order->next)
1984
2008
    if (order->counter_used)
1985
2009
    {
1986
2010
      char buffer[20];
1987
 
      uint32_t length= snprintf(buffer, 20, "%d", order->counter);
 
2011
      uint length= snprintf(buffer, 20, "%d", order->counter);
1988
2012
      str->append(buffer, length);
1989
2013
    }
1990
2014
    else
1997
2021
}
1998
2022
 
1999
2023
 
2000
 
void st_select_lex::print_limit(THD *thd __attribute__((unused)),
 
2024
void st_select_lex::print_limit(THD *thd __attribute__((__unused__)),
2001
2025
                                String *str,
2002
2026
                                enum_query_type query_type)
2003
2027
{
2020
2044
                    ((Item_in_subselect*)item)->exec_method ==
2021
2045
                    Item_in_subselect::MATERIALIZATION) ?
2022
2046
                   true :
2023
 
                   (select_limit->val_int() == 1L) &&
 
2047
                   (select_limit->val_int() == 1LL) &&
2024
2048
                   offset_limit == 0));
2025
2049
      return;
2026
2050
    }
2049
2073
  to implement the clean up.
2050
2074
*/
2051
2075
 
2052
 
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((unused)))
 
2076
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((__unused__)))
2053
2077
{
2054
2078
}
2055
2079
 
2075
2099
{
2076
2100
  if (!init && query_tables)
2077
2101
  {
2078
 
    TableList *table= query_tables;
 
2102
    TABLE_LIST *table= query_tables;
2079
2103
    for (;;)
2080
2104
    {
2081
2105
      if (query_tables_last == &table->next_global ||
2363
2387
    select_limit_val= HA_POS_ERROR;
2364
2388
#endif
2365
2389
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
2366
 
                                                 0UL);
 
2390
                                                 0ULL);
2367
2391
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2368
2392
  if (select_limit_cnt < select_limit_val)
2369
2393
    select_limit_cnt= HA_POS_ERROR;             // no limit
2388
2412
      In this case link_to_local is set.
2389
2413
 
2390
2414
*/
2391
 
TableList *st_lex::unlink_first_table(bool *link_to_local)
 
2415
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
2392
2416
{
2393
 
  TableList *first;
 
2417
  TABLE_LIST *first;
2394
2418
  if ((first= query_tables))
2395
2419
  {
2396
2420
    /*
2409
2433
    {
2410
2434
      select_lex.context.table_list= 
2411
2435
        select_lex.context.first_name_resolution_table= first->next_local;
2412
 
      select_lex.table_list.first= (unsigned char*) (first->next_local);
 
2436
      select_lex.table_list.first= (uchar*) (first->next_local);
2413
2437
      select_lex.table_list.elements--; //safety
2414
2438
      first->next_local= 0;
2415
2439
      /*
2441
2465
 
2442
2466
void st_lex::first_lists_tables_same()
2443
2467
{
2444
 
  TableList *first_table= (TableList*) select_lex.table_list.first;
 
2468
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
2445
2469
  if (query_tables != first_table && first_table != 0)
2446
2470
  {
2447
 
    TableList *next;
 
2471
    TABLE_LIST *next;
2448
2472
    if (query_tables_last == &first_table->next_global)
2449
2473
      query_tables_last= first_table->prev_global;
2450
2474
 
2475
2499
    global list
2476
2500
*/
2477
2501
 
2478
 
void st_lex::link_first_table_back(TableList *first,
 
2502
void st_lex::link_first_table_back(TABLE_LIST *first,
2479
2503
                                   bool link_to_local)
2480
2504
{
2481
2505
  if (first)
2488
2512
 
2489
2513
    if (link_to_local)
2490
2514
    {
2491
 
      first->next_local= (TableList*) select_lex.table_list.first;
 
2515
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
2492
2516
      select_lex.context.table_list= first;
2493
 
      select_lex.table_list.first= (unsigned char*) first;
 
2517
      select_lex.table_list.first= (uchar*) first;
2494
2518
      select_lex.table_list.elements++; //safety
2495
2519
    }
2496
2520
  }
2545
2569
      backup  Pointer to Query_tables_list instance to be used for backup
2546
2570
*/
2547
2571
 
2548
 
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
 
2572
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
2549
2573
{
2550
2574
}
2551
2575
 
2558
2582
      backup  Pointer to Query_tables_list instance used for backup
2559
2583
*/
2560
2584
 
2561
 
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
 
2585
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
2562
2586
{
2563
2587
}
2564
2588
 
2598
2622
 
2599
2623
*/
2600
2624
 
2601
 
static void fix_prepare_info_in_table_list(THD *thd, TableList *tbl)
 
2625
static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
2602
2626
{
2603
2627
  for (; tbl; tbl= tbl->next_local)
2604
2628
  {
2675
2699
  RETURN VALUE
2676
2700
    0 on success, non-zero otherwise
2677
2701
*/
2678
 
bool st_select_lex::add_index_hint (THD *thd, char *str, uint32_t length)
 
2702
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
2679
2703
{
2680
2704
  return index_hints->push_front (new (thd->mem_root) 
2681
2705
                                 Index_hint(current_index_hint_type,