~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_lex.cc

  • Committer: Monty Taylor
  • Date: 2008-07-15 21:40:58 UTC
  • mfrom: (77.1.113 codestyle32)
  • mto: This revision was merged to the branch mainline in revision 176.
  • Revision ID: mordred@camelot-20080715214058-rm3phulldos9xehv
Merged from codestyle.

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;
331
336
  lex->reset_query_tables_list(false);
332
337
  lex->expr_allows_subselect= true;
333
338
  lex->use_only_table_context= false;
334
 
  lex->parse_vcol_expr= false;
335
339
 
336
340
  lex->name.str= 0;
337
341
  lex->name.length= 0;
340
344
  lex->in_sum_func= NULL;
341
345
  /*
342
346
    ok, there must be a better solution for this, long-term
343
 
    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
344
348
    some reason made the values zero, even if they were set
345
349
  */
346
350
  lex->server_options.server_name= 0;
350
354
  lex->server_options.username= 0;
351
355
  lex->server_options.password= 0;
352
356
  lex->server_options.scheme= 0;
 
357
  lex->server_options.socket= 0;
353
358
  lex->server_options.owner= 0;
354
359
  lex->server_options.port= -1;
355
360
 
361
366
{
362
367
  if (lex->yacc_yyss)
363
368
  {
364
 
    free(lex->yacc_yyss);
365
 
    free(lex->yacc_yyvs);
 
369
    my_free(lex->yacc_yyss, MYF(0));
 
370
    my_free(lex->yacc_yyvs, MYF(0));
366
371
    lex->yacc_yyss= 0;
367
372
    lex->yacc_yyvs= 0;
368
373
  }
372
377
                     lex->plugins.elements);
373
378
  reset_dynamic(&lex->plugins);
374
379
 
375
 
  delete lex->result;
376
 
  lex->result= 0;
377
 
 
378
380
  return;
379
381
}
380
382
 
381
383
 
382
 
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)
383
385
{
384
386
  const char *tok= lip->get_tok_start();
385
387
 
408
410
    1         name isn't a keyword
409
411
*/
410
412
 
411
 
bool is_keyword(const char *name, uint32_t len)
 
413
bool is_keyword(const char *name, uint len)
412
414
{
413
415
  assert(len != 0);
414
416
  return get_hash_symbol(name,len,0)!=0;
422
424
 
423
425
/* make a copy of token before ptr and set yytoklen */
424
426
 
425
 
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)
426
428
{
427
429
  LEX_STRING tmp;
428
430
  lip->yyUnget();                       // ptr points now after last token char
443
445
*/
444
446
 
445
447
static LEX_STRING get_quoted_token(Lex_input_stream *lip,
446
 
                                   uint32_t skip,
447
 
                                   uint32_t length, char quote)
 
448
                                   uint skip,
 
449
                                   uint length, char quote)
448
450
{
449
451
  LEX_STRING tmp;
450
452
  const char *from, *end;
479
481
 
480
482
static char *get_text(Lex_input_stream *lip, int pre_skip, int post_skip)
481
483
{
482
 
  register unsigned char c,sep;
483
 
  uint32_t found_escape=0;
484
 
  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();
485
487
 
486
488
  lip->tok_bitmap= 0;
487
489
  sep= lip->yyGetLast();                        // String should end with this
557
559
              continue;
558
560
          }
559
561
#endif
560
 
          if (*str == '\\' && str+1 != end)
 
562
          if (!(lip->m_thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
 
563
              *str == '\\' && str+1 != end)
561
564
          {
562
565
            switch(*++str) {
563
566
            case 'n':
605
608
/*
606
609
** Calc type of integer; long integer, int64_t integer or real.
607
610
** Returns smallest type that match the string.
608
 
** When using uint64_t values the result is converted to a real
 
611
** When using unsigned long long values the result is converted to a real
609
612
** because else they will be unexpected sign changes because all calculation
610
613
** is done with int64_t or double.
611
614
*/
612
615
 
613
616
static const char *long_str="2147483647";
614
 
static const uint32_t long_len=10;
 
617
static const uint long_len=10;
615
618
static const char *signed_long_str="-2147483648";
616
619
static const char *int64_t_str="9223372036854775807";
617
 
static const uint32_t int64_t_len=19;
 
620
static const uint int64_t_len=19;
618
621
static const char *signed_int64_t_str="-9223372036854775808";
619
 
static const uint32_t signed_int64_t_len=19;
 
622
static const uint signed_int64_t_len=19;
620
623
static const char *unsigned_int64_t_str="18446744073709551615";
621
 
static const uint32_t unsigned_int64_t_len=20;
 
624
static const uint unsigned_int64_t_len=20;
622
625
 
623
 
static inline uint32_t int_token(const char *str,uint32_t length)
 
626
static inline uint int_token(const char *str,uint length)
624
627
{
625
628
  if (length < long_len)                        // quick normal case
626
629
    return NUM;
642
645
  if (length < long_len)
643
646
    return NUM;
644
647
 
645
 
  uint32_t smaller,bigger;
 
648
  uint smaller,bigger;
646
649
  const char *cmp;
647
650
  if (neg)
648
651
  {
689
692
    }
690
693
  }
691
694
  while (*cmp && *cmp++ == *str++) ;
692
 
  return ((unsigned char) str[-1] <= (unsigned char) cmp[-1]) ? smaller : bigger;
 
695
  return ((uchar) str[-1] <= (uchar) cmp[-1]) ? smaller : bigger;
693
696
}
694
697
 
695
698
 
726
729
  switch(token) {
727
730
  case WITH:
728
731
    /*
729
 
      Parsing 'WITH' 'ROLLUP' requires 2 look ups,
 
732
      Parsing 'WITH' 'ROLLUP' or 'WITH' 'CUBE' requires 2 look ups,
730
733
      which makes the grammar LALR(2).
731
734
      Replace by a single 'WITH_ROLLUP' or 'WITH_CUBE' token,
732
735
      to transform the grammar into a LALR(1) grammar,
733
736
      which sql_yacc.yy can process.
734
737
    */
735
738
    token= lex_one_token(arg, yythd);
736
 
    if (token == ROLLUP_SYM)
737
 
    {
 
739
    switch(token) {
 
740
    case CUBE_SYM:
 
741
      return WITH_CUBE_SYM;
 
742
    case ROLLUP_SYM:
738
743
      return WITH_ROLLUP_SYM;
739
 
    }
740
 
    else
741
 
    {
 
744
    default:
742
745
      /*
743
746
        Save the token following 'WITH'
744
747
      */
766
769
  Lex_input_stream *lip= thd->m_lip;
767
770
  LEX *lex= thd->lex;
768
771
  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;
 
772
  CHARSET_INFO *cs= thd->charset();
 
773
  uchar *state_map= cs->state_map;
 
774
  uchar *ident_map= cs->ident_map;
772
775
 
773
776
  lip->yylval=yylval;                   // The global state
774
777
 
827
830
        */
828
831
        lip->restart_token();
829
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
      }
830
844
 
831
845
      return((int) c);
832
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
 
833
864
    case MY_LEX_IDENT_OR_HEX:
834
865
      if (lip->yyPeek() == '\'')
835
866
      {                                 // Found x'hex-number'
912
943
 
913
944
      if (yylval->lex_str.str[0] == '_')
914
945
      {
915
 
        const CHARSET_INFO * const cs= get_charset_by_csname(yylval->lex_str.str + 1,
916
 
                                                             MY_CS_PRIMARY, MYF(0));
 
946
        CHARSET_INFO *cs= get_charset_by_csname(yylval->lex_str.str + 1,
 
947
                                                MY_CS_PRIMARY, MYF(0));
917
948
        if (cs)
918
949
        {
919
950
          yylval->charset= cs;
1037
1068
 
1038
1069
    case MY_LEX_USER_VARIABLE_DELIMITER:        // Found quote char
1039
1070
    {
1040
 
      uint32_t double_quotes= 0;
 
1071
      uint double_quotes= 0;
1041
1072
      char quote_char= c;                       // Used char
1042
1073
      while ((c=lip->yyGet()))
1043
1074
      {
1247
1278
          /* Accept 'M' 'm' 'm' 'd' 'd' */
1248
1279
          lip->yySkipn(5);
1249
1280
 
1250
 
          if (version <= DRIZZLE_VERSION_ID)
 
1281
          if (version <= MYSQL_VERSION_ID)
1251
1282
          {
1252
1283
            /* Expand the content of the special comment as real code */
1253
1284
            lip->set_echo(true);
1327
1358
    case MY_LEX_SEMICOLON:                      // optional line terminator
1328
1359
      if (lip->yyPeek())
1329
1360
      {
1330
 
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS))
 
1361
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS) && 
 
1362
            !lip->stmt_prepare_mode)
1331
1363
        {
1332
1364
          lip->found_semicolon= lip->get_ptr();
1333
1365
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
1476
1508
}
1477
1509
 
1478
1510
 
1479
 
void trim_whitespace(const CHARSET_INFO * const cs, LEX_STRING *str)
 
1511
void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str)
1480
1512
{
1481
1513
  /*
1482
1514
    TODO:
1545
1577
  embedding= leaf_tables= 0;
1546
1578
  item_list.empty();
1547
1579
  join= 0;
1548
 
  having= where= 0;
 
1580
  having= prep_having= where= prep_where= 0;
1549
1581
  olap= UNSPECIFIED_OLAP_TYPE;
1550
1582
  having_fix_field= 0;
1551
1583
  context.select_lex= this;
1568
1600
  select_n_having_items= 0;
1569
1601
  subquery_in_having= explicit_limit= 0;
1570
1602
  is_item_list_lookup= 0;
 
1603
  first_execution= 1;
 
1604
  first_cond_optimization= 1;
1571
1605
  parsing_place= NO_MATTER;
1572
 
  exclude_from_table_unique_test= false;
 
1606
  exclude_from_table_unique_test= no_wrap_view_item= false;
1573
1607
  nest_level= 0;
1574
1608
  link_next= 0;
1575
1609
}
1592
1626
  linkage= UNSPECIFIED_TYPE;
1593
1627
  order_list.elements= 0;
1594
1628
  order_list.first= 0;
1595
 
  order_list.next= (unsigned char**) &order_list.first;
 
1629
  order_list.next= (uchar**) &order_list.first;
1596
1630
  /* Set limit and offset to default values */
1597
1631
  select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
1598
1632
  offset_limit= 0;      /* denotes the default offset = 0 */
1812
1846
  }
1813
1847
}
1814
1848
 
1815
 
bool st_select_lex_node::set_braces(bool value __attribute__((unused)))
 
1849
bool st_select_lex_node::set_braces(bool value __attribute__((__unused__)))
1816
1850
{ return 1; }
1817
1851
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; }
 
1852
uint st_select_lex_node::get_in_sum_expr()           { return 0; }
 
1853
TABLE_LIST* st_select_lex_node::get_table_list()     { return 0; }
1820
1854
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)))
 
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__)))
1828
1862
{
1829
1863
  return 0;
1830
1864
}
1831
 
uint32_t st_select_lex_node::get_table_join_options()
 
1865
ulong st_select_lex_node::get_table_join_options()
1832
1866
{
1833
1867
  return 0;
1834
1868
}
1866
1900
}
1867
1901
 
1868
1902
 
1869
 
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__)),
1870
1904
                                     Item *item)
1871
1905
{
1872
1906
  return(item_list.push_back(item));
1905
1939
}
1906
1940
 
1907
1941
 
1908
 
uint32_t st_select_lex::get_in_sum_expr()
 
1942
uint st_select_lex::get_in_sum_expr()
1909
1943
{
1910
1944
  return in_sum_expr;
1911
1945
}
1912
1946
 
1913
1947
 
1914
 
TableList* st_select_lex::get_table_list()
 
1948
TABLE_LIST* st_select_lex::get_table_list()
1915
1949
{
1916
 
  return (TableList*) table_list.first;
 
1950
  return (TABLE_LIST*) table_list.first;
1917
1951
}
1918
1952
 
1919
1953
List<Item>* st_select_lex::get_item_list()
1921
1955
  return &item_list;
1922
1956
}
1923
1957
 
1924
 
uint32_t st_select_lex::get_table_join_options()
 
1958
ulong st_select_lex::get_table_join_options()
1925
1959
{
1926
1960
  return table_join_options;
1927
1961
}
1928
1962
 
1929
1963
 
1930
 
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)
1931
1965
{
1932
1966
  if (ref_pointer_array)
1933
1967
    return 0;
1934
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;
1935
1974
  return (ref_pointer_array=
1936
 
          (Item **)thd->alloc(sizeof(Item*) * (n_child_sum_items +
 
1975
          (Item **)arena->alloc(sizeof(Item*) * (n_child_sum_items +
1937
1976
                                                 item_list.elements +
1938
1977
                                                 select_n_having_items +
1939
1978
                                                 select_n_where_fields +
1967
2006
      str->append(STRING_WITH_LEN(" order by "));
1968
2007
      fake_select_lex->print_order(
1969
2008
        str,
1970
 
        (order_st *) fake_select_lex->order_list.first,
 
2009
        (ORDER *) fake_select_lex->order_list.first,
1971
2010
        query_type);
1972
2011
    }
1973
2012
    fake_select_lex->print_limit(thd, str, query_type);
1976
2015
 
1977
2016
 
1978
2017
void st_select_lex::print_order(String *str,
1979
 
                                order_st *order,
 
2018
                                ORDER *order,
1980
2019
                                enum_query_type query_type)
1981
2020
{
1982
2021
  for (; order; order= order->next)
1984
2023
    if (order->counter_used)
1985
2024
    {
1986
2025
      char buffer[20];
1987
 
      uint32_t length= snprintf(buffer, 20, "%d", order->counter);
 
2026
      uint length= snprintf(buffer, 20, "%d", order->counter);
1988
2027
      str->append(buffer, length);
1989
2028
    }
1990
2029
    else
1997
2036
}
1998
2037
 
1999
2038
 
2000
 
void st_select_lex::print_limit(THD *thd __attribute__((unused)),
 
2039
void st_select_lex::print_limit(THD *thd __attribute__((__unused__)),
2001
2040
                                String *str,
2002
2041
                                enum_query_type query_type)
2003
2042
{
2020
2059
                    ((Item_in_subselect*)item)->exec_method ==
2021
2060
                    Item_in_subselect::MATERIALIZATION) ?
2022
2061
                   true :
2023
 
                   (select_limit->val_int() == 1L) &&
 
2062
                   (select_limit->val_int() == 1LL) &&
2024
2063
                   offset_limit == 0));
2025
2064
      return;
2026
2065
    }
2049
2088
  to implement the clean up.
2050
2089
*/
2051
2090
 
2052
 
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__)))
2053
2092
{
2054
2093
}
2055
2094
 
2075
2114
{
2076
2115
  if (!init && query_tables)
2077
2116
  {
2078
 
    TableList *table= query_tables;
 
2117
    TABLE_LIST *table= query_tables;
2079
2118
    for (;;)
2080
2119
    {
2081
2120
      if (query_tables_last == &table->next_global ||
2313
2352
  }
2314
2353
}
2315
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
 
2316
2377
 
2317
2378
/**
2318
2379
  This method should be called only during parsing.
2363
2424
    select_limit_val= HA_POS_ERROR;
2364
2425
#endif
2365
2426
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
2366
 
                                                 0UL);
 
2427
                                                 0ULL);
2367
2428
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2368
2429
  if (select_limit_cnt < select_limit_val)
2369
2430
    select_limit_cnt= HA_POS_ERROR;             // no limit
2388
2449
      In this case link_to_local is set.
2389
2450
 
2390
2451
*/
2391
 
TableList *st_lex::unlink_first_table(bool *link_to_local)
 
2452
TABLE_LIST *st_lex::unlink_first_table(bool *link_to_local)
2392
2453
{
2393
 
  TableList *first;
 
2454
  TABLE_LIST *first;
2394
2455
  if ((first= query_tables))
2395
2456
  {
2396
2457
    /*
2409
2470
    {
2410
2471
      select_lex.context.table_list= 
2411
2472
        select_lex.context.first_name_resolution_table= first->next_local;
2412
 
      select_lex.table_list.first= (unsigned char*) (first->next_local);
 
2473
      select_lex.table_list.first= (uchar*) (first->next_local);
2413
2474
      select_lex.table_list.elements--; //safety
2414
2475
      first->next_local= 0;
2415
2476
      /*
2441
2502
 
2442
2503
void st_lex::first_lists_tables_same()
2443
2504
{
2444
 
  TableList *first_table= (TableList*) select_lex.table_list.first;
 
2505
  TABLE_LIST *first_table= (TABLE_LIST*) select_lex.table_list.first;
2445
2506
  if (query_tables != first_table && first_table != 0)
2446
2507
  {
2447
 
    TableList *next;
 
2508
    TABLE_LIST *next;
2448
2509
    if (query_tables_last == &first_table->next_global)
2449
2510
      query_tables_last= first_table->prev_global;
2450
2511
 
2475
2536
    global list
2476
2537
*/
2477
2538
 
2478
 
void st_lex::link_first_table_back(TableList *first,
 
2539
void st_lex::link_first_table_back(TABLE_LIST *first,
2479
2540
                                   bool link_to_local)
2480
2541
{
2481
2542
  if (first)
2488
2549
 
2489
2550
    if (link_to_local)
2490
2551
    {
2491
 
      first->next_local= (TableList*) select_lex.table_list.first;
 
2552
      first->next_local= (TABLE_LIST*) select_lex.table_list.first;
2492
2553
      select_lex.context.table_list= first;
2493
 
      select_lex.table_list.first= (unsigned char*) first;
 
2554
      select_lex.table_list.first= (uchar*) first;
2494
2555
      select_lex.table_list.elements++; //safety
2495
2556
    }
2496
2557
  }
2545
2606
      backup  Pointer to Query_tables_list instance to be used for backup
2546
2607
*/
2547
2608
 
2548
 
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__)))
2549
2610
{
2550
2611
}
2551
2612
 
2558
2619
      backup  Pointer to Query_tables_list instance used for backup
2559
2620
*/
2560
2621
 
2561
 
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__)))
2562
2623
{
2563
2624
}
2564
2625
 
2598
2659
 
2599
2660
*/
2600
2661
 
2601
 
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)
2602
2663
{
2603
2664
  for (; tbl; tbl= tbl->next_local)
2604
2665
  {
2613
2674
 
2614
2675
 
2615
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
/*
2616
2716
  There are st_select_lex::add_table_to_list &
2617
2717
  st_select_lex::set_lock_for_tables are in sql_parse.cc
2618
2718
 
2675
2775
  RETURN VALUE
2676
2776
    0 on success, non-zero otherwise
2677
2777
*/
2678
 
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)
2679
2779
{
2680
2780
  return index_hints->push_front (new (thd->mem_root) 
2681
2781
                                 Index_hint(current_index_hint_type,