~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_lex.cc

Merged in from trunk.

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
}
136
139
  next_state(MY_LEX_START),
137
140
  found_semicolon(NULL),
138
141
  ignore_space(1),
 
142
  stmt_prepare_mode(false),
139
143
  in_comment(NO_COMMENT),
140
144
  m_underscore_cs(NULL)
141
145
{
163
167
  assert(begin_ptr);
164
168
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
165
169
 
166
 
  uint32_t body_utf8_length=
 
170
  uint body_utf8_length=
167
171
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
168
172
    my_charset_utf8_bin.mbmaxlen;
169
173
 
243
247
 
244
248
void Lex_input_stream::body_utf8_append_literal(THD *thd,
245
249
                                                const LEX_STRING *txt,
246
 
                                                const CHARSET_INFO * const txt_cs,
 
250
                                                CHARSET_INFO *txt_cs,
247
251
                                                const char *end_ptr)
248
252
{
249
253
  if (!m_cpp_utf8_processed_ptr)
295
299
  lex->value_list.empty();
296
300
  lex->update_list.empty();
297
301
  lex->param_list.empty();
 
302
  lex->view_list.empty();
298
303
  lex->auxiliary_table_list.empty();
299
304
  lex->unit.next= lex->unit.master=
300
305
    lex->unit.link_next= lex->unit.return_to= 0;
339
344
  lex->in_sum_func= NULL;
340
345
  /*
341
346
    ok, there must be a better solution for this, long-term
342
 
    I tried "memset" in the sql_yacc.yy code, but that for
 
347
    I tried "bzero" in the sql_yacc.yy code, but that for
343
348
    some reason made the values zero, even if they were set
344
349
  */
345
350
  lex->server_options.server_name= 0;
349
354
  lex->server_options.username= 0;
350
355
  lex->server_options.password= 0;
351
356
  lex->server_options.scheme= 0;
 
357
  lex->server_options.socket= 0;
352
358
  lex->server_options.owner= 0;
353
359
  lex->server_options.port= -1;
354
360
 
360
366
{
361
367
  if (lex->yacc_yyss)
362
368
  {
363
 
    free(lex->yacc_yyss);
364
 
    free(lex->yacc_yyvs);
 
369
    my_free(lex->yacc_yyss, MYF(0));
 
370
    my_free(lex->yacc_yyvs, MYF(0));
365
371
    lex->yacc_yyss= 0;
366
372
    lex->yacc_yyvs= 0;
367
373
  }
371
377
                     lex->plugins.elements);
372
378
  reset_dynamic(&lex->plugins);
373
379
 
374
 
  delete lex->result;
375
 
  lex->result= 0;
376
 
 
377
380
  return;
378
381
}
379
382
 
380
383
 
381
 
static int find_keyword(Lex_input_stream *lip, uint32_t len, bool function)
 
384
static int find_keyword(Lex_input_stream *lip, uint len, bool function)
382
385
{
383
386
  const char *tok= lip->get_tok_start();
384
387
 
407
410
    1         name isn't a keyword
408
411
*/
409
412
 
410
 
bool is_keyword(const char *name, uint32_t len)
 
413
bool is_keyword(const char *name, uint len)
411
414
{
412
415
  assert(len != 0);
413
416
  return get_hash_symbol(name,len,0)!=0;
421
424
 
422
425
/* make a copy of token before ptr and set yytoklen */
423
426
 
424
 
static LEX_STRING get_token(Lex_input_stream *lip, uint32_t skip, uint32_t length)
 
427
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
425
428
{
426
429
  LEX_STRING tmp;
427
430
  lip->yyUnget();                       // ptr points now after last token char
442
445
*/
443
446
 
444
447
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
445
 
                                   uint32_t skip,
446
 
                                   uint32_t length, char quote)
 
448
                                   uint skip,
 
449
                                   uint length, char quote)
447
450
{
448
451
  LEX_STRING tmp;
449
452
  const char *from, *end;
478
481
 
479
482
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
480
483
{
481
 
  register unsigned char c,sep;
482
 
  uint32_t found_escape=0;
483
 
  const CHARSET_INFO * const cs= lip->m_thd->charset();
 
484
  register uchar c,sep;
 
485
  uint found_escape=0;
 
486
  CHARSET_INFO *cs= lip->m_thd->charset();
484
487
 
485
488
  lip->tok_bitmap= 0;
486
489
  sep= lip->yyGetLast();                        // String should end with this
556
559
              continue;
557
560
          }
558
561
#endif
559
 
          if (*str == '\\' && str+1 != end)
 
562
          if (!(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
563
              *str == '\\' && str+1 != end)
560
564
          {
561
565
            switch(*++str) {
562
566
            case 'n':
610
614
*/
611
615
 
612
616
static const char *long_str="2147483647";
613
 
static const uint32_t long_len=10;
 
617
static const uint long_len=10;
614
618
static const char *signed_long_str="-2147483648";
615
619
static const char *int64_t_str="9223372036854775807";
616
 
static const uint32_t int64_t_len=19;
 
620
static const uint int64_t_len=19;
617
621
static const char *signed_int64_t_str="-9223372036854775808";
618
 
static const uint32_t signed_int64_t_len=19;
 
622
static const uint signed_int64_t_len=19;
619
623
static const char *unsigned_int64_t_str="18446744073709551615";
620
 
static const uint32_t unsigned_int64_t_len=20;
 
624
static const uint unsigned_int64_t_len=20;
621
625
 
622
 
static inline uint32_t int_token(const char *str,uint32_t length)
 
626
static inline uint int_token(const char *str,uint length)
623
627
{
624
628
  if (length < long_len)                        // quick normal case
625
629
    return NUM;
641
645
  if (length < long_len)
642
646
    return NUM;
643
647
 
644
 
  uint32_t smaller,bigger;
 
648
  uint smaller,bigger;
645
649
  const char *cmp;
646
650
  if (neg)
647
651
  {
688
692
    }
689
693
  }
690
694
  while (*cmp && *cmp++ == *str++) ;
691
 
  return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
 
695
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
692
696
}
693
697
 
694
698
 
725
729
  switch(token) {
726
730
  case WITH:
727
731
    /*
728
 
      Parsing 'WITH' 'ROLLUP' requires 2 look ups,
 
732
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
729
733
      which makes the grammar LALR(2).
730
734
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
731
735
      to transform the grammar into a LALR(1) grammar,
732
736
      which sql_yacc.yy can process.
733
737
    */
734
738
    token= lex_one_token(arg, yythd);
735
 
    if (token == ROLLUP_SYM)
736
 
    {
 
739
    switch(token) {
 
740
    case CUBE_SYM:
 
741
      return WITH_CUBE_SYM;
 
742
    case ROLLUP_SYM:
737
743
      return WITH_ROLLUP_SYM;
738
 
    }
739
 
    else
740
 
    {
 
744
    default:
741
745
      /*
742
746
        Save the token following 'WITH'
743
747
      */
765
769
  Lex_input_stream *lip= thd->m_lip;
766
770
  LEX *lex= thd->lex;
767
771
  YYSTYPE *yylval=(YYSTYPE*) arg;
768
 
  const CHARSET_INFO * const cs= thd->charset();
769
 
  unsigned char *state_map= cs->state_map;
770
 
  unsigned char *ident_map= cs->ident_map;
 
772
  CHARSET_INFO *cs= thd->charset();
 
773
  uchar *state_map= cs->state_map;
 
774
  uchar *ident_map= cs->ident_map;
771
775
 
772
776
  lip->yylval=yylval;                   // The global state
773
777
 
826
830
        */
827
831
        lip->restart_token();
828
832
      }
 
833
      else
 
834
      {
 
835
        /*
 
836
          Check for a placeholder: it should not precede a possible identifier
 
837
          because of binlogging: when a placeholder is replaced with
 
838
          its value in a query for the binlog, the query must stay
 
839
          grammatically correct.
 
840
        */
 
841
        if (c == '?' && lip->stmt_prepare_mode && !ident_map[(uint8_t)(lip->yyPeek())])
 
842
        return(PARAM_MARKER);
 
843
      }
829
844
 
830
845
      return((int) c);
831
846
 
 
847
    case MY_LEX_IDENT_OR_NCHAR:
 
848
      if (lip->yyPeek() != '\'')
 
849
      {
 
850
        state= MY_LEX_IDENT;
 
851
        break;
 
852
      }
 
853
      /* Found N'string' */
 
854
      lip->yySkip();                         // Skip '
 
855
      if (!(yylval->lex_str.str = get_text(lip, 2, 1)))
 
856
      {
 
857
        state= MY_LEX_CHAR;             // Read char by char
 
858
        break;
 
859
      }
 
860
      yylval->lex_str.length= lip->yytoklen;
 
861
      lex->text_string_is_7bit= (lip->tok_bitmap & 0x80) ? 0 : 1;
 
862
      return(NCHAR_STRING);
 
863
 
832
864
    case MY_LEX_IDENT_OR_HEX:
833
865
      if (lip->yyPeek() == '\'')
834
866
      {                                 // Found x'hex-number'
911
943
 
912
944
      if (yylval->lex_str.str[0] == '_')
913
945
      {
914
 
        const CHARSET_INFO * const cs= get_charset_by_csname(yylval->lex_str.str + 1,
915
 
                                                             MY_CS_PRIMARY, MYF(0));
 
946
        CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1,
 
947
                                                MY_CS_PRIMARY, MYF(0));
916
948
        if (cs)
917
949
        {
918
950
          yylval->charset= cs;
1036
1068
 
1037
1069
    case MY_LEX_USER_VARIABLE_DELIMITER:        // Found quote char
1038
1070
    {
1039
 
      uint32_t double_quotes= 0;
 
1071
      uint double_quotes= 0;
1040
1072
      char quote_char= c;                       // Used char
1041
1073
      while ((c=lip->yyGet()))
1042
1074
      {
1246
1278
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1247
1279
          lip->yySkipn(5);
1248
1280
 
1249
 
          if (version <= DRIZZLE_VERSION_ID)
 
1281
          if (version <= MYSQL_VERSION_ID)
1250
1282
          {
1251
1283
            /* Expand the content of the special comment as real code */
1252
1284
            lip->set_echo(true);
1326
1358
    case MY_LEX_SEMICOLON:                      // optional line terminator
1327
1359
      if (lip->yyPeek())
1328
1360
      {
1329
 
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS))
 
1361
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && 
 
1362
            !lip->stmt_prepare_mode)
1330
1363
        {
1331
1364
          lip->found_semicolon= lip->get_ptr();
1332
1365
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
1475
1508
}
1476
1509
 
1477
1510
 
1478
 
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
 
1511
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
1479
1512
{
1480
1513
  /*
1481
1514
    TODO:
1544
1577
  embedding= leaf_tables= 0;
1545
1578
  item_list.empty();
1546
1579
  join= 0;
1547
 
  having= where= 0;
 
1580
  having= prep_having= where= prep_where= 0;
1548
1581
  olap= UNSPECIFIED_OLAP_TYPE;
1549
1582
  having_fix_field= 0;
1550
1583
  context.select_lex= this;
1567
1600
  select_n_having_items= 0;
1568
1601
  subquery_in_having= explicit_limit= 0;
1569
1602
  is_item_list_lookup= 0;
 
1603
  first_execution= 1;
 
1604
  first_cond_optimization= 1;
1570
1605
  parsing_place= NO_MATTER;
1571
 
  exclude_from_table_unique_test= false;
 
1606
  exclude_from_table_unique_test= no_wrap_view_item= false;
1572
1607
  nest_level= 0;
1573
1608
  link_next= 0;
1574
1609
}
1591
1626
  linkage= UNSPECIFIED_TYPE;
1592
1627
  order_list.elements= 0;
1593
1628
  order_list.first= 0;
1594
 
  order_list.next= (unsigned char**) &order_list.first;
 
1629
  order_list.next= (uchar**) &order_list.first;
1595
1630
  /* Set limit and offset to default values */
1596
1631
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1597
1632
  offset_limit= 0;      /* denotes the default offset = 0 */
1811
1846
  }
1812
1847
}
1813
1848
 
1814
 
bool st_select_lex_node::set_braces(bool value __attribute__((unused)))
 
1849
bool st_select_lex_node::set_braces(bool value __attribute__((__unused__)))
1815
1850
{ return 1; }
1816
1851
bool st_select_lex_node::inc_in_sum_expr()           { return 1; }
1817
 
uint32_t st_select_lex_node::get_in_sum_expr()           { return 0; }
1818
 
TableList* st_select_lex_node::get_table_list()     { return 0; }
 
1852
uint st_select_lex_node::get_in_sum_expr()           { return 0; }
 
1853
TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
1819
1854
List<Item>* st_select_lex_node::get_item_list()      { return 0; }
1820
 
TableList *st_select_lex_node::add_table_to_list (THD *thd __attribute__((unused)),
1821
 
                                                   Table_ident *table __attribute__((unused)),
1822
 
                                                  LEX_STRING *alias __attribute__((unused)),
1823
 
                                                  uint32_t table_join_options __attribute__((unused)),
1824
 
                                                  thr_lock_type flags __attribute__((unused)),
1825
 
                                                  List<Index_hint> *hints __attribute__((unused)),
1826
 
                                                  LEX_STRING *option __attribute__((unused)))
 
1855
TABLE_LIST *st_select_lex_node::add_table_to_list (THD *thd __attribute__((__unused__)),
 
1856
                                                   Table_ident *table __attribute__((__unused__)),
 
1857
                                                  LEX_STRING *alias __attribute__((__unused__)),
 
1858
                                                  ulong table_join_options __attribute__((__unused__)),
 
1859
                                                  thr_lock_type flags __attribute__((__unused__)),
 
1860
                                                  List<Index_hint> *hints __attribute__((__unused__)),
 
1861
                                                  LEX_STRING *option __attribute__((__unused__)))
1827
1862
{
1828
1863
  return 0;
1829
1864
}
1830
 
uint32_t st_select_lex_node::get_table_join_options()
 
1865
ulong st_select_lex_node::get_table_join_options()
1831
1866
{
1832
1867
  return 0;
1833
1868
}
1865
1900
}
1866
1901
 
1867
1902
 
1868
 
bool st_select_lex::add_item_to_list(THD *thd __attribute__((unused)),
 
1903
bool st_select_lex::add_item_to_list(THD *thd __attribute__((__unused__)),
1869
1904
                                     Item *item)
1870
1905
{
1871
1906
  return(item_list.push_back(item));
1904
1939
}
1905
1940
 
1906
1941
 
1907
 
uint32_t st_select_lex::get_in_sum_expr()
 
1942
uint st_select_lex::get_in_sum_expr()
1908
1943
{
1909
1944
  return in_sum_expr;
1910
1945
}
1911
1946
 
1912
1947
 
1913
 
TableList* st_select_lex::get_table_list()
 
1948
TABLE_LIST* st_select_lex::get_table_list()
1914
1949
{
1915
 
  return (TableList*) table_list.first;
 
1950
  return (TABLE_LIST*) table_list.first;
1916
1951
}
1917
1952
 
1918
1953
List<Item>* st_select_lex::get_item_list()
1920
1955
  return &item_list;
1921
1956
}
1922
1957
 
1923
 
uint32_t st_select_lex::get_table_join_options()
 
1958
ulong st_select_lex::get_table_join_options()
1924
1959
{
1925
1960
  return table_join_options;
1926
1961
}
1927
1962
 
1928
1963
 
1929
 
bool st_select_lex::setup_ref_array(THD *thd, uint32_t order_group_num)
 
1964
bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
1930
1965
{
1931
1966
  if (ref_pointer_array)
1932
1967
    return 0;
1933
1968
 
 
1969
  /*
 
1970
    We have to create array in prepared statement memory if it is
 
1971
    prepared statement
 
1972
  */
 
1973
  Query_arena *arena= thd->stmt_arena;
1934
1974
  return (ref_pointer_array=
1935
 
          (Item **)thd->alloc(sizeof(Item*) * (n_child_sum_items +
 
1975
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
1936
1976
                                                 item_list.elements +
1937
1977
                                                 select_n_having_items +
1938
1978
                                                 select_n_where_fields +
1966
2006
      str->append(STRING_WITH_LEN(" order by "));
1967
2007
      fake_select_lex->print_order(
1968
2008
        str,
1969
 
        (order_st *) fake_select_lex->order_list.first,
 
2009
        (ORDER *) fake_select_lex->order_list.first,
1970
2010
        query_type);
1971
2011
    }
1972
2012
    fake_select_lex->print_limit(thd, str, query_type);
1975
2015
 
1976
2016
 
1977
2017
void st_select_lex::print_order(String *str,
1978
 
                                order_st *order,
 
2018
                                ORDER *order,
1979
2019
                                enum_query_type query_type)
1980
2020
{
1981
2021
  for (; order; order= order->next)
1983
2023
    if (order->counter_used)
1984
2024
    {
1985
2025
      char buffer[20];
1986
 
      uint32_t length= snprintf(buffer, 20, "%d", order->counter);
 
2026
      uint length= snprintf(buffer, 20, "%d", order->counter);
1987
2027
      str->append(buffer, length);
1988
2028
    }
1989
2029
    else
1996
2036
}
1997
2037
 
1998
2038
 
1999
 
void st_select_lex::print_limit(THD *thd __attribute__((unused)),
 
2039
void st_select_lex::print_limit(THD *thd __attribute__((__unused__)),
2000
2040
                                String *str,
2001
2041
                                enum_query_type query_type)
2002
2042
{
2019
2059
                    ((Item_in_subselect*)item)->exec_method ==
2020
2060
                    Item_in_subselect::MATERIALIZATION) ?
2021
2061
                   true :
2022
 
                   (select_limit->val_int() == 1L) &&
 
2062
                   (select_limit->val_int() == 1LL) &&
2023
2063
                   offset_limit == 0));
2024
2064
      return;
2025
2065
    }
2048
2088
  to implement the clean up.
2049
2089
*/
2050
2090
 
2051
 
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((unused)))
 
2091
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((__unused__)))
2052
2092
{
2053
2093
}
2054
2094
 
2074
2114
{
2075
2115
  if (!init && query_tables)
2076
2116
  {
2077
 
    TableList *table= query_tables;
 
2117
    TABLE_LIST *table= query_tables;
2078
2118
    for (;;)
2079
2119
    {
2080
2120
      if (query_tables_last == &table->next_global ||
2312
2352
  }
2313
2353
}
2314
2354
 
 
2355
/*
 
2356
  Get effective type of CHECK OPTION for given view
 
2357
 
 
2358
  SYNOPSIS
 
2359
    get_effective_with_check()
 
2360
    view    given view
 
2361
 
 
2362
  NOTE
 
2363
    It have not sense to set CHECK OPTION for SELECT satement or subqueries,
 
2364
    so we do not.
 
2365
 
 
2366
  RETURN
 
2367
    VIEW_CHECK_NONE      no need CHECK OPTION
 
2368
    VIEW_CHECK_LOCAL     CHECK OPTION LOCAL
 
2369
    VIEW_CHECK_CASCADED  CHECK OPTION CASCADED
 
2370
*/
 
2371
 
 
2372
uint8 st_lex::get_effective_with_check(TABLE_LIST *view __attribute__((__unused__)))
 
2373
{
 
2374
  return 0;
 
2375
}
 
2376
 
2315
2377
 
2316
2378
/**
2317
2379
  This method should be called only during parsing.
2362
2424
    select_limit_val= HA_POS_ERROR;
2363
2425
#endif
2364
2426
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
2365
 
                                                 0UL);
 
2427
                                                 0ULL);
2366
2428
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2367
2429
  if (select_limit_cnt < select_limit_val)
2368
2430
    select_limit_cnt= HA_POS_ERROR;             // no limit
2387
2449
      In this case link_to_local is set.
2388
2450
 
2389
2451
*/
2390
 
TableList *st_lex::unlink_first_table(bool *link_to_local)
 
2452
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
2391
2453
{
2392
 
  TableList *first;
 
2454
  TABLE_LIST *first;
2393
2455
  if ((first= query_tables))
2394
2456
  {
2395
2457
    /*
2408
2470
    {
2409
2471
      select_lex.context.table_list= 
2410
2472
        select_lex.context.first_name_resolution_table= first->next_local;
2411
 
      select_lex.table_list.first= (unsigned char*) (first->next_local);
 
2473
      select_lex.table_list.first= (uchar*) (first->next_local);
2412
2474
      select_lex.table_list.elements--; //safety
2413
2475
      first->next_local= 0;
2414
2476
      /*
2440
2502
 
2441
2503
void st_lex::first_lists_tables_same()
2442
2504
{
2443
 
  TableList *first_table= (TableList*) select_lex.table_list.first;
 
2505
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
2444
2506
  if (query_tables != first_table && first_table != 0)
2445
2507
  {
2446
 
    TableList *next;
 
2508
    TABLE_LIST *next;
2447
2509
    if (query_tables_last == &first_table->next_global)
2448
2510
      query_tables_last= first_table->prev_global;
2449
2511
 
2474
2536
    global list
2475
2537
*/
2476
2538
 
2477
 
void st_lex::link_first_table_back(TableList *first,
 
2539
void st_lex::link_first_table_back(TABLE_LIST *first,
2478
2540
                                   bool link_to_local)
2479
2541
{
2480
2542
  if (first)
2487
2549
 
2488
2550
    if (link_to_local)
2489
2551
    {
2490
 
      first->next_local= (TableList*) select_lex.table_list.first;
 
2552
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
2491
2553
      select_lex.context.table_list= first;
2492
 
      select_lex.table_list.first= (unsigned char*) first;
 
2554
      select_lex.table_list.first= (uchar*) first;
2493
2555
      select_lex.table_list.elements++; //safety
2494
2556
    }
2495
2557
  }
2544
2606
      backup  Pointer to Query_tables_list instance to be used for backup
2545
2607
*/
2546
2608
 
2547
 
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
 
2609
void st_lex::reset_n_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
2548
2610
{
2549
2611
}
2550
2612
 
2557
2619
      backup  Pointer to Query_tables_list instance used for backup
2558
2620
*/
2559
2621
 
2560
 
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((unused)))
 
2622
void st_lex::restore_backup_query_tables_list(Query_tables_list *backup __attribute__((__unused__)))
2561
2623
{
2562
2624
}
2563
2625
 
2597
2659
 
2598
2660
*/
2599
2661
 
2600
 
static void fix_prepare_info_in_table_list(THD *thd, TableList *tbl)
 
2662
static void fix_prepare_info_in_table_list(THD *thd, TABLE_LIST *tbl)
2601
2663
{
2602
2664
  for (; tbl; tbl= tbl->next_local)
2603
2665
  {
2612
2674
 
2613
2675
 
2614
2676
/*
 
2677
  Save WHERE/HAVING/ON clauses and replace them with disposable copies
 
2678
 
 
2679
  SYNOPSIS
 
2680
    st_select_lex::fix_prepare_information
 
2681
      thd          thread handler
 
2682
      conds        in/out pointer to WHERE condition to be met at execution
 
2683
      having_conds in/out pointer to HAVING condition to be met at execution
 
2684
  
 
2685
  DESCRIPTION
 
2686
    The passed WHERE and HAVING are to be saved for the future executions.
 
2687
    This function saves it, and returns a copy which can be thrashed during
 
2688
    this execution of the statement. By saving/thrashing here we mean only
 
2689
    AND/OR trees.
 
2690
    The function also calls fix_prepare_info_in_table_list that saves all
 
2691
    ON expressions.    
 
2692
*/
 
2693
 
 
2694
void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
 
2695
                                            Item **having_conds)
 
2696
{
 
2697
  if (thd->stmt_arena->is_conventional() == false && first_execution)
 
2698
  {
 
2699
    first_execution= 0;
 
2700
    if (*conds)
 
2701
    {
 
2702
      prep_where= *conds;
 
2703
      *conds= where= prep_where->copy_andor_structure(thd);
 
2704
    }
 
2705
    if (*having_conds)
 
2706
    {
 
2707
      prep_having= *having_conds;
 
2708
      *having_conds= having= prep_having->copy_andor_structure(thd);
 
2709
    }
 
2710
    fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
 
2711
  }
 
2712
}
 
2713
 
 
2714
 
 
2715
/*
2615
2716
  There are st_select_lex::add_table_to_list &
2616
2717
  st_select_lex::set_lock_for_tables are in sql_parse.cc
2617
2718
 
2674
2775
  RETURN VALUE
2675
2776
    0 on success, non-zero otherwise
2676
2777
*/
2677
 
bool st_select_lex::add_index_hint (THD *thd, char *str, uint32_t length)
 
2778
bool st_select_lex::add_index_hint (THD *thd, char *str, uint length)
2678
2779
{
2679
2780
  return index_hints->push_front (new (thd->mem_root) 
2680
2781
                                 Index_hint(current_index_hint_type,