~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_lex.cc

  • Committer: Monty Taylor
  • Date: 2008-10-22 01:52:54 UTC
  • Revision ID: monty@inaugust.com-20081022015254-65qfk9f2v0b8jlk3
Moved drizzle_com to drizzled/drizzle_common. Started splitting it up.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#define DRIZZLE_LEX 1
20
20
#include <drizzled/server_includes.h>
21
21
 
22
 
static int lex_one_token(void *arg, void *yythd);
 
22
static int lex_one_token(void *arg, void *yysession);
23
23
 
24
24
/*
25
25
  We are using pointer to this variable for distinguishing between assignment
33
33
*/
34
34
const LEX_STRING null_lex_str= {NULL, 0};
35
35
 
36
 
/* Longest standard keyword name */
37
 
 
38
 
#define TOCK_NAME_LENGTH 24
39
36
 
40
37
/*
41
38
  The following data is based on the latin1 character set, and is only
111
108
  allows_derived= true;
112
109
}
113
110
 
114
 
Lex_input_stream::Lex_input_stream(THD *thd,
 
111
Lex_input_stream::Lex_input_stream(Session *session,
115
112
                                   const char* buffer,
116
113
                                   unsigned int length)
117
 
: m_thd(thd),
 
114
: m_session(session),
118
115
  yylineno(1),
119
116
  yytoklen(0),
120
117
  yylval(NULL),
139
136
  in_comment(NO_COMMENT),
140
137
  m_underscore_cs(NULL)
141
138
{
142
 
  m_cpp_buf= (char*) thd->alloc(length + 1);
 
139
  m_cpp_buf= (char*) session->alloc(length + 1);
143
140
  m_cpp_ptr= m_cpp_buf;
144
141
}
145
142
 
153
150
     statement;
154
151
  2) Determine the beginning of the body.
155
152
 
156
 
  @param thd        Thread context.
 
153
  @param session        Thread context.
157
154
  @param begin_ptr  Pointer to the start of the body in the pre-processed
158
155
                    buffer.
159
156
*/
160
157
 
161
 
void Lex_input_stream::body_utf8_start(THD *thd, const char *begin_ptr)
 
158
void Lex_input_stream::body_utf8_start(Session *session, const char *begin_ptr)
162
159
{
163
160
  assert(begin_ptr);
164
161
  assert(m_cpp_buf <= begin_ptr && begin_ptr <= m_cpp_buf + m_buf_length);
165
162
 
166
163
  uint32_t body_utf8_length=
167
 
    (m_buf_length / thd->variables.character_set_client->mbminlen) *
 
164
    (m_buf_length / session->variables.character_set_client->mbminlen) *
168
165
    my_charset_utf8_bin.mbmaxlen;
169
166
 
170
 
  m_body_utf8= (char *) thd->alloc(body_utf8_length + 1);
 
167
  m_body_utf8= (char *) session->alloc(body_utf8_length + 1);
171
168
  m_body_utf8_ptr= m_body_utf8;
172
169
  *m_body_utf8_ptr= 0;
173
170
 
233
230
  The operation converts the specified text literal to the utf8 and appends
234
231
  the result to the utf8-body.
235
232
 
236
 
  @param thd      Thread context.
 
233
  @param session      Thread context.
237
234
  @param txt      Text literal.
238
235
  @param txt_cs   Character set of the text literal.
239
236
  @param end_ptr  Pointer in the pre-processed buffer, to which
241
238
                  operation.
242
239
*/
243
240
 
244
 
void Lex_input_stream::body_utf8_append_literal(THD *thd,
 
241
void Lex_input_stream::body_utf8_append_literal(Session *session,
245
242
                                                const LEX_STRING *txt,
246
243
                                                const CHARSET_INFO * const txt_cs,
247
244
                                                const char *end_ptr)
253
250
 
254
251
  if (!my_charset_same(txt_cs, &my_charset_utf8_general_ci))
255
252
  {
256
 
    thd->convert_string(&utf_txt,
 
253
    session->convert_string(&utf_txt,
257
254
                        &my_charset_utf8_general_ci,
258
255
                        txt->str, txt->length,
259
256
                        txt_cs);
280
277
  (We already do too much here)
281
278
*/
282
279
 
283
 
void lex_start(THD *thd)
 
280
void lex_start(Session *session)
284
281
{
285
 
  LEX *lex= thd->lex;
 
282
  LEX *lex= session->lex;
286
283
 
287
 
  lex->thd= lex->unit.thd= thd;
 
284
  lex->session= lex->unit.session= session;
288
285
 
289
286
  lex->context_stack.empty();
290
287
  lex->unit.init_query();
331
328
  lex->reset_query_tables_list(false);
332
329
  lex->expr_allows_subselect= true;
333
330
  lex->use_only_table_context= false;
 
331
  lex->parse_vcol_expr= false;
334
332
 
335
333
  lex->name.str= 0;
336
334
  lex->name.length= 0;
426
424
  LEX_STRING tmp;
427
425
  lip->yyUnget();                       // ptr points now after last token char
428
426
  tmp.length=lip->yytoklen=length;
429
 
  tmp.str= lip->m_thd->strmake(lip->get_tok_start() + skip, tmp.length);
 
427
  tmp.str= lip->m_session->strmake(lip->get_tok_start() + skip, tmp.length);
430
428
 
431
429
  lip->m_cpp_text_start= lip->get_cpp_tok_start() + skip;
432
430
  lip->m_cpp_text_end= lip->m_cpp_text_start + tmp.length;
450
448
  char *to;
451
449
  lip->yyUnget();                       // ptr points now after last token char
452
450
  tmp.length= lip->yytoklen=length;
453
 
  tmp.str=(char*) lip->m_thd->alloc(tmp.length+1);
 
451
  tmp.str=(char*) lip->m_session->alloc(tmp.length+1);
454
452
  from= lip->get_tok_start() + skip;
455
453
  to= tmp.str;
456
454
  end= to+length;
480
478
{
481
479
  register unsigned char c,sep;
482
480
  uint32_t found_escape=0;
483
 
  const CHARSET_INFO * const cs= lip->m_thd->charset();
 
481
  const CHARSET_INFO * const cs= lip->m_session->charset();
484
482
 
485
483
  lip->tok_bitmap= 0;
486
484
  sep= lip->yyGetLast();                        // String should end with this
528
526
      end -= post_skip;
529
527
      assert(end >= str);
530
528
 
531
 
      if (!(start= (char*) lip->m_thd->alloc((uint) (end-str)+1)))
 
529
      if (!(start= (char*) lip->m_session->alloc((uint) (end-str)+1)))
532
530
        return (char*) "";              // Sql_alloc has set error flag
533
531
 
534
532
      lip->m_cpp_text_start= lip->get_cpp_tok_start() + pre_skip;
604
602
/*
605
603
** Calc type of integer; long integer, int64_t integer or real.
606
604
** Returns smallest type that match the string.
607
 
** When using unsigned long long values the result is converted to a real
 
605
** When using uint64_t values the result is converted to a real
608
606
** because else they will be unexpected sign changes because all calculation
609
607
** is done with int64_t or double.
610
608
*/
700
698
                                (which can't be followed by a signed number)
701
699
*/
702
700
 
703
 
int MYSQLlex(void *arg, void *yythd)
 
701
int MYSQLlex(void *arg, void *yysession)
704
702
{
705
 
  THD *thd= (THD *)yythd;
706
 
  Lex_input_stream *lip= thd->m_lip;
 
703
  Session *session= (Session *)yysession;
 
704
  Lex_input_stream *lip= session->m_lip;
707
705
  YYSTYPE *yylval=(YYSTYPE*) arg;
708
706
  int token;
709
707
 
720
718
    return token;
721
719
  }
722
720
 
723
 
  token= lex_one_token(arg, yythd);
 
721
  token= lex_one_token(arg, yysession);
724
722
 
725
723
  switch(token) {
726
724
  case WITH:
731
729
      to transform the grammar into a LALR(1) grammar,
732
730
      which sql_yacc.yy can process.
733
731
    */
734
 
    token= lex_one_token(arg, yythd);
 
732
    token= lex_one_token(arg, yysession);
735
733
    if (token == ROLLUP_SYM)
736
734
    {
737
735
      return WITH_ROLLUP_SYM;
754
752
  return token;
755
753
}
756
754
 
757
 
int lex_one_token(void *arg, void *yythd)
 
755
int lex_one_token(void *arg, void *yysession)
758
756
{
759
757
  register unsigned char c= 0; /* Just set to shutup GCC */
760
758
  bool comment_closed;
761
759
  int   tokval, result_state;
762
760
  unsigned int length;
763
761
  enum my_lex_states state;
764
 
  THD *thd= (THD *)yythd;
765
 
  Lex_input_stream *lip= thd->m_lip;
766
 
  LEX *lex= thd->lex;
 
762
  Session *session= (Session *)yysession;
 
763
  Lex_input_stream *lip= session->m_lip;
 
764
  LEX *lex= session->lex;
767
765
  YYSTYPE *yylval=(YYSTYPE*) arg;
768
 
  const CHARSET_INFO * const cs= thd->charset();
 
766
  const CHARSET_INFO * const cs= session->charset();
769
767
  unsigned char *state_map= cs->state_map;
770
768
  unsigned char *ident_map= cs->ident_map;
771
769
 
926
924
 
927
925
      lip->body_utf8_append(lip->m_cpp_text_start);
928
926
 
929
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
 
927
      lip->body_utf8_append_literal(session, &yylval->lex_str, cs,
930
928
                                    lip->m_cpp_text_end);
931
929
 
932
930
      return(result_state);                     // IDENT or IDENT_QUOTED
1029
1027
 
1030
1028
      lip->body_utf8_append(lip->m_cpp_text_start);
1031
1029
 
1032
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
 
1030
      lip->body_utf8_append_literal(session, &yylval->lex_str, cs,
1033
1031
                                    lip->m_cpp_text_end);
1034
1032
 
1035
1033
      return(result_state);
1070
1068
 
1071
1069
      lip->body_utf8_append(lip->m_cpp_text_start);
1072
1070
 
1073
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
 
1071
      lip->body_utf8_append_literal(session, &yylval->lex_str, cs,
1074
1072
                                    lip->m_cpp_text_end);
1075
1073
 
1076
1074
      return(IDENT_QUOTED);
1184
1182
 
1185
1183
      lip->body_utf8_append(lip->m_cpp_text_start);
1186
1184
 
1187
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str,
 
1185
      lip->body_utf8_append_literal(session, &yylval->lex_str,
1188
1186
        lip->m_underscore_cs ? lip->m_underscore_cs : cs,
1189
1187
        lip->m_cpp_text_end);
1190
1188
 
1326
1324
    case MY_LEX_SEMICOLON:                      // optional line terminator
1327
1325
      if (lip->yyPeek())
1328
1326
      {
1329
 
        if ((thd->client_capabilities & CLIENT_MULTI_STATEMENTS))
 
1327
        if ((session->client_capabilities & CLIENT_MULTI_STATEMENTS))
1330
1328
        {
1331
1329
          lip->found_semicolon= lip->get_ptr();
1332
 
          thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
 
1330
          session->server_status|= SERVER_MORE_RESULTS_EXISTS;
1333
1331
          lip->next_state= MY_LEX_END;
1334
1332
          lip->set_echo(true);
1335
1333
          return (END_OF_INPUT);
1424
1422
 
1425
1423
      lip->body_utf8_append(lip->m_cpp_text_start);
1426
1424
 
1427
 
      lip->body_utf8_append_literal(thd, &yylval->lex_str, cs,
 
1425
      lip->body_utf8_append_literal(session, &yylval->lex_str, cs,
1428
1426
                                    lip->m_cpp_text_end);
1429
1427
 
1430
1428
      return(result_state);
1442
1440
  statements and stored procedures and is compensated by always
1443
1441
  supplying a copy of Alter_info to these functions.
1444
1442
 
1445
 
  @return You need to use check the error in THD for out
 
1443
  @return You need to use check the error in Session for out
1446
1444
  of memory condition after calling this function.
1447
1445
*/
1448
1446
 
1817
1815
uint32_t st_select_lex_node::get_in_sum_expr()           { return 0; }
1818
1816
TableList* st_select_lex_node::get_table_list()     { return 0; }
1819
1817
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)),
 
1818
TableList *st_select_lex_node::add_table_to_list (Session *session __attribute__((unused)),
1821
1819
                                                   Table_ident *table __attribute__((unused)),
1822
1820
                                                  LEX_STRING *alias __attribute__((unused)),
1823
1821
                                                  uint32_t table_join_options __attribute__((unused)),
1859
1857
}
1860
1858
 
1861
1859
 
1862
 
bool st_select_lex::add_order_to_list(THD *thd, Item *item, bool asc)
 
1860
bool st_select_lex::add_order_to_list(Session *session, Item *item, bool asc)
1863
1861
{
1864
 
  return add_to_list(thd, order_list, item, asc);
 
1862
  return add_to_list(session, order_list, item, asc);
1865
1863
}
1866
1864
 
1867
1865
 
1868
 
bool st_select_lex::add_item_to_list(THD *thd __attribute__((unused)),
 
1866
bool st_select_lex::add_item_to_list(Session *session __attribute__((unused)),
1869
1867
                                     Item *item)
1870
1868
{
1871
1869
  return(item_list.push_back(item));
1872
1870
}
1873
1871
 
1874
1872
 
1875
 
bool st_select_lex::add_group_to_list(THD *thd, Item *item, bool asc)
 
1873
bool st_select_lex::add_group_to_list(Session *session, Item *item, bool asc)
1876
1874
{
1877
 
  return add_to_list(thd, group_list, item, asc);
 
1875
  return add_to_list(session, group_list, item, asc);
1878
1876
}
1879
1877
 
1880
1878
 
1926
1924
}
1927
1925
 
1928
1926
 
1929
 
bool st_select_lex::setup_ref_array(THD *thd, uint32_t order_group_num)
 
1927
bool st_select_lex::setup_ref_array(Session *session, uint32_t order_group_num)
1930
1928
{
1931
1929
  if (ref_pointer_array)
1932
1930
    return 0;
1933
1931
 
1934
1932
  return (ref_pointer_array=
1935
 
          (Item **)thd->alloc(sizeof(Item*) * (n_child_sum_items +
 
1933
          (Item **)session->alloc(sizeof(Item*) * (n_child_sum_items +
1936
1934
                                                 item_list.elements +
1937
1935
                                                 select_n_having_items +
1938
1936
                                                 select_n_where_fields +
1955
1953
    }
1956
1954
    if (sl->braces)
1957
1955
      str->append('(');
1958
 
    sl->print(thd, str, query_type);
 
1956
    sl->print(session, str, query_type);
1959
1957
    if (sl->braces)
1960
1958
      str->append(')');
1961
1959
  }
1969
1967
        (order_st *) fake_select_lex->order_list.first,
1970
1968
        query_type);
1971
1969
    }
1972
 
    fake_select_lex->print_limit(thd, str, query_type);
 
1970
    fake_select_lex->print_limit(session, str, query_type);
1973
1971
  }
1974
1972
}
1975
1973
 
1996
1994
}
1997
1995
 
1998
1996
 
1999
 
void st_select_lex::print_limit(THD *thd __attribute__((unused)),
 
1997
void st_select_lex::print_limit(Session *session __attribute__((unused)),
2000
1998
                                String *str,
2001
1999
                                enum_query_type query_type)
2002
2000
{
2037
2035
}
2038
2036
 
2039
2037
/**
2040
 
  @brief Restore the LEX and THD in case of a parse error.
 
2038
  @brief Restore the LEX and Session in case of a parse error.
2041
2039
 
2042
2040
  This is a clean up call that is invoked by the Bison generated
2043
2041
  parser before returning an error from MYSQLparse. If your
2048
2046
  to implement the clean up.
2049
2047
*/
2050
2048
 
2051
 
void st_lex::cleanup_lex_after_parse_error(THD *thd __attribute__((unused)))
 
2049
void st_lex::cleanup_lex_after_parse_error(Session *session __attribute__((unused)))
2052
2050
{
2053
2051
}
2054
2052
 
2126
2124
 
2127
2125
  NOTE
2128
2126
    LEX object initialized with this constructor can be used as part of
2129
 
    THD object for which one can safely call open_tables(), lock_tables()
 
2127
    Session object for which one can safely call open_tables(), lock_tables()
2130
2128
    and close_thread_tables() functions. But it is not yet ready for
2131
2129
    statement parsing. On should use lex_start() function to prepare LEX
2132
2130
    for this.
2335
2333
bool
2336
2334
st_lex::copy_db_to(char **p_db, size_t *p_db_length) const
2337
2335
{
2338
 
  return thd->copy_db_to(p_db, p_db_length);
 
2336
  return session->copy_db_to(p_db, p_db_length);
2339
2337
}
2340
2338
 
2341
2339
/*
2353
2351
 
2354
2352
  val= sl->select_limit ? sl->select_limit->val_uint() : HA_POS_ERROR;
2355
2353
  select_limit_val= (ha_rows)val;
2356
 
#ifndef BIG_TABLES
2357
2354
  /* 
2358
2355
    Check for overflow : ha_rows can be smaller then uint64_t if
2359
2356
    BIG_TABLES is off.
2360
2357
    */
2361
2358
  if (val != (uint64_t)select_limit_val)
2362
2359
    select_limit_val= HA_POS_ERROR;
2363
 
#endif
2364
2360
  offset_limit_cnt= (ha_rows)(sl->offset_limit ? sl->offset_limit->val_uint() :
2365
2361
                                                 0UL);
2366
2362
  select_limit_cnt= select_limit_val + offset_limit_cnt;
2512
2508
void st_lex::cleanup_after_one_table_open()
2513
2509
{
2514
2510
  /*
2515
 
    thd->lex->derived_tables & additional units may be set if we open
2516
 
    a view. It is necessary to clear thd->lex->derived_tables flag
 
2511
    session->lex->derived_tables & additional units may be set if we open
 
2512
    a view. It is necessary to clear session->lex->derived_tables flag
2517
2513
    to prevent processing of derived tables during next open_and_lock_tables
2518
2514
    if next table is a real table and cleanup & remove underlying units
2519
 
    NOTE: all units will be connected to thd->lex->select_lex, because we
 
2515
    NOTE: all units will be connected to session->lex->select_lex, because we
2520
2516
    have not UNION on most upper level.
2521
2517
    */
2522
2518
  if (all_selects_list != &select_lex)
2587
2583
 
2588
2584
  SYNOPSIS
2589
2585
    fix_prepare_info_in_table_list()
2590
 
      thd  Thread handle
 
2586
      session  Thread handle
2591
2587
      tbl  List of tables to process
2592
2588
 
2593
2589
  DESCRIPTION
2597
2593
 
2598
2594
*/
2599
2595
 
2600
 
static void fix_prepare_info_in_table_list(THD *thd, TableList *tbl)
 
2596
static void fix_prepare_info_in_table_list(Session *session, TableList *tbl)
2601
2597
{
2602
2598
  for (; tbl; tbl= tbl->next_local)
2603
2599
  {
2604
2600
    if (tbl->on_expr)
2605
2601
    {
2606
2602
      tbl->prep_on_expr= tbl->on_expr;
2607
 
      tbl->on_expr= tbl->on_expr->copy_andor_structure(thd);
 
2603
      tbl->on_expr= tbl->on_expr->copy_andor_structure(session);
2608
2604
    }
2609
 
    fix_prepare_info_in_table_list(thd, tbl->merge_underlying_list);
 
2605
    fix_prepare_info_in_table_list(session, tbl->merge_underlying_list);
2610
2606
  }
2611
2607
}
2612
2608
 
2651
2647
 
2652
2648
  SYNOPSIS
2653
2649
    alloc_index_hints()
2654
 
      thd         current thread.
 
2650
      session         current thread.
2655
2651
*/
2656
2652
 
2657
 
void st_select_lex::alloc_index_hints (THD *thd)
 
2653
void st_select_lex::alloc_index_hints (Session *session)
2658
2654
2659
 
  index_hints= new (thd->mem_root) List<Index_hint>(); 
 
2655
  index_hints= new (session->mem_root) List<Index_hint>(); 
2660
2656
}
2661
2657
 
2662
2658
 
2667
2663
 
2668
2664
  SYNOPSIS
2669
2665
    add_index_hint()
2670
 
      thd         current thread.
 
2666
      session         current thread.
2671
2667
      str         name of the index.
2672
2668
      length      number of characters in str.
2673
2669
 
2674
2670
  RETURN VALUE
2675
2671
    0 on success, non-zero otherwise
2676
2672
*/
2677
 
bool st_select_lex::add_index_hint (THD *thd, char *str, uint32_t length)
 
2673
bool st_select_lex::add_index_hint (Session *session, char *str, uint32_t length)
2678
2674
{
2679
 
  return index_hints->push_front (new (thd->mem_root) 
 
2675
  return index_hints->push_front (new (session->mem_root) 
2680
2676
                                 Index_hint(current_index_hint_type,
2681
2677
                                            current_index_hint_clause,
2682
2678
                                            str, length));