~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Andrew Hutchings
  • Date: 2011-01-28 21:33:48 UTC
  • mto: (2126.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2127.
  • Revision ID: andrew@linuxjedi.co.uk-20110128213348-ypi381xo47o80ypo
Backport fix for http://bugs.mysql.com/bug.php?id=57034

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
   along with this program; if not, write to the Free Software
14
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
 
#include <config.h>
 
16
#include "config.h"
17
17
 
18
18
#define DRIZZLE_LEX 1
19
19
 
20
 
#include <drizzled/item/num.h>
21
 
#include <drizzled/abort_exception.h>
 
20
#include "drizzled/item/num.h"
 
21
#include "drizzled/abort_exception.h"
22
22
#include <drizzled/my_hash.h>
23
23
#include <drizzled/error.h>
24
24
#include <drizzled/nested_join.h>
25
25
#include <drizzled/query_id.h>
26
 
#include <drizzled/transaction_services.h>
 
26
#include "drizzled/transaction_services.h"
27
27
#include <drizzled/sql_parse.h>
28
28
#include <drizzled/data_home.h>
29
29
#include <drizzled/sql_base.h>
30
30
#include <drizzled/show.h>
 
31
#include <drizzled/db.h>
31
32
#include <drizzled/function/time/unix_timestamp.h>
32
33
#include <drizzled/function/get_system_var.h>
33
34
#include <drizzled/item/cmpfunc.h>
34
35
#include <drizzled/item/null.h>
35
36
#include <drizzled/session.h>
36
 
#include <drizzled/session/cache.h>
37
37
#include <drizzled/sql_load.h>
38
38
#include <drizzled/lock.h>
39
39
#include <drizzled/select_send.h>
40
40
#include <drizzled/plugin/client.h>
41
41
#include <drizzled/statement.h>
42
42
#include <drizzled/statement/alter_table.h>
43
 
#include <drizzled/probes.h>
44
 
#include <drizzled/global_charset_info.h>
45
 
 
46
 
#include <drizzled/plugin/logging.h>
47
 
#include <drizzled/plugin/query_rewrite.h>
48
 
#include <drizzled/plugin/query_cache.h>
49
 
#include <drizzled/plugin/authorization.h>
50
 
#include <drizzled/optimizer/explain_plan.h>
51
 
#include <drizzled/pthread_globals.h>
52
 
#include <drizzled/plugin/event_observer.h>
53
 
#include <drizzled/visibility.h>
54
 
 
55
 
#include <drizzled/schema.h>
 
43
#include "drizzled/probes.h"
 
44
#include "drizzled/session/cache.h"
 
45
#include "drizzled/global_charset_info.h"
 
46
 
 
47
#include "drizzled/plugin/logging.h"
 
48
#include "drizzled/plugin/query_rewrite.h"
 
49
#include "drizzled/plugin/query_cache.h"
 
50
#include "drizzled/plugin/authorization.h"
 
51
#include "drizzled/optimizer/explain_plan.h"
 
52
#include "drizzled/pthread_globals.h"
 
53
#include "drizzled/plugin/event_observer.h"
56
54
 
57
55
#include <limits.h>
58
56
 
59
57
#include <bitset>
60
58
#include <algorithm>
61
59
#include <boost/date_time.hpp>
62
 
#include <drizzled/internal/my_sys.h>
 
60
#include "drizzled/internal/my_sys.h"
63
61
 
64
62
using namespace std;
65
63
 
66
 
extern int base_sql_parse(drizzled::Session *session); // from sql_yacc.cc
 
64
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
67
65
 
68
66
namespace drizzled
69
67
{
70
68
 
71
69
/* Prototypes */
72
 
bool my_yyoverflow(short **a, ParserType **b, ulong *yystacksize);
 
70
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
73
71
static bool parse_sql(Session *session, Lex_input_stream *lip);
74
72
void parse(Session *session, const char *inBuf, uint32_t length);
75
73
 
81
79
extern size_t my_thread_stack_size;
82
80
extern const CHARSET_INFO *character_set_filesystem;
83
81
 
84
 
namespace
85
 
{
86
 
 
87
 
static const std::string command_name[COM_END+1]={
88
 
  "Sleep",
89
 
  "Quit",
90
 
  "Init DB",
91
 
  "Query",
92
 
  "Shutdown",
93
 
  "Connect",
94
 
  "Ping",
95
 
  "Error"  // Last command number
 
82
const LEX_STRING command_name[COM_END+1]={
 
83
  { C_STRING_WITH_LEN("Sleep") },
 
84
  { C_STRING_WITH_LEN("Quit") },
 
85
  { C_STRING_WITH_LEN("Init DB") },
 
86
  { C_STRING_WITH_LEN("Query") },
 
87
  { C_STRING_WITH_LEN("Shutdown") },
 
88
  { C_STRING_WITH_LEN("Connect") },
 
89
  { C_STRING_WITH_LEN("Ping") },
 
90
  { C_STRING_WITH_LEN("Error") }  // Last command number
96
91
};
97
92
 
98
 
}
99
 
 
100
93
const char *xa_state_names[]={
101
94
  "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED"
102
95
};
115
108
*/
116
109
bitset<CF_BIT_SIZE> sql_command_flags[SQLCOM_END+1];
117
110
 
118
 
const std::string &getCommandName(const enum_server_command& command)
119
 
{
120
 
  return command_name[command];
121
 
}
122
 
 
123
111
void init_update_queries(void)
124
112
{
125
113
  uint32_t x;
168
156
                         can be zero.
169
157
 
170
158
  @todo
171
 
    set session->getLex()->sql_command to SQLCOM_END here.
 
159
    set session->lex->sql_command to SQLCOM_END here.
172
160
  @todo
173
161
    The following has to be changed to an 8 byte integer
174
162
 
187
175
  DRIZZLE_COMMAND_START(session->thread_id, command);
188
176
 
189
177
  session->command= command;
190
 
  session->getLex()->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
 
178
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
191
179
  session->set_time();
192
180
  session->setQueryId(query_id.value());
193
181
 
201
189
    query_id.next();
202
190
  }
203
191
 
204
 
  /* @todo set session->getLex()->sql_command to SQLCOM_END here */
 
192
  /* @todo set session->lex->sql_command to SQLCOM_END here */
205
193
 
206
194
  plugin::Logging::preDo(session);
207
195
  if (unlikely(plugin::EventObserver::beforeStatement(*session)))
224
212
 
225
213
    identifier::Schema identifier(tmp);
226
214
 
227
 
    if (not schema::change(*session, identifier))
 
215
    if (not change_db(session, identifier))
228
216
    {
229
217
      session->my_ok();
230
218
    }
446
434
static int execute_command(Session *session)
447
435
{
448
436
  bool res= false;
449
 
 
 
437
  LEX  *lex= session->lex;
450
438
  /* first Select_Lex (have special meaning for many of non-SELECTcommands) */
451
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
452
 
 
 
439
  Select_Lex *select_lex= &lex->select_lex;
453
440
  /* list of all tables in query */
454
441
  TableList *all_tables;
455
442
 
468
455
    assert(first_table == all_tables);
469
456
    assert(first_table == all_tables && first_table != 0);
470
457
  */
471
 
  session->getLex()->first_lists_tables_same();
472
 
 
 
458
  lex->first_lists_tables_same();
473
459
  /* should be assigned after making first tables same */
474
 
  all_tables= session->getLex()->query_tables;
475
 
 
 
460
  all_tables= lex->query_tables;
476
461
  /* set context for commands which do not use setup_tables */
477
 
  select_lex->context.resolve_in_table_list_only((TableList*)select_lex->table_list.first);
 
462
  select_lex->
 
463
    context.resolve_in_table_list_only((TableList*)select_lex->
 
464
                                       table_list.first);
478
465
 
479
466
  /*
480
467
    Reset warning count for each query that uses tables
483
470
    variables, but for now this is probably good enough.
484
471
    Don't reset warnings when executing a stored routine.
485
472
  */
486
 
  if (all_tables || ! session->getLex()->is_single_level_stmt())
 
473
  if (all_tables || ! lex->is_single_level_stmt())
487
474
  {
488
475
    drizzle_reset_errors(session, 0);
489
476
  }
490
477
 
491
478
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
492
479
 
493
 
  if (! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
494
 
      && ! session->inTransaction()
495
 
      && session->getLex()->statement->isTransactional())
496
 
  {
497
 
    if (session->startTransaction() == false)
498
 
    {
499
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
500
 
      return true;
501
 
    }
502
 
  }
503
 
 
504
480
  /* now we are ready to execute the statement */
505
 
  res= session->getLex()->statement->execute();
 
481
  res= lex->statement->execute();
506
482
  session->set_proc_info("query end");
507
483
  /*
508
484
    The return value for ROW_COUNT() is "implementation dependent" if the
510
486
    wants. We also keep the last value in case of SQLCOM_CALL or
511
487
    SQLCOM_EXECUTE.
512
488
  */
513
 
  if (! (sql_command_flags[session->getLex()->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
 
489
  if (! (sql_command_flags[lex->sql_command].test(CF_BIT_HAS_ROW_COUNT)))
514
490
  {
515
491
    session->row_count_func= -1;
516
492
  }
519
495
}
520
496
bool execute_sqlcom_select(Session *session, TableList *all_tables)
521
497
{
522
 
  LEX   *lex= session->getLex();
 
498
  LEX   *lex= session->lex;
523
499
  select_result *result=lex->result;
524
500
  bool res= false;
525
501
  /* assign global limit variable if limit is not given */
529
505
      param->select_limit=
530
506
        new Item_int((uint64_t) session->variables.select_limit);
531
507
  }
532
 
 
533
 
  if (all_tables
534
 
      && ! (session->server_status & SERVER_STATUS_AUTOCOMMIT)
535
 
      && ! session->inTransaction()
536
 
      && ! lex->statement->isShow())
537
 
  {
538
 
    if (session->startTransaction() == false)
539
 
    {
540
 
      my_error(drizzled::ER_UNKNOWN_ERROR, MYF(0));
541
 
      return true;
542
 
    }
543
 
  }
544
 
 
545
508
  if (not (res= session->openTablesLock(all_tables)))
546
509
  {
547
510
    if (lex->describe)
556
519
        return true;
557
520
      session->send_explain_fields(result);
558
521
      optimizer::ExplainPlan planner;
559
 
      res= planner.explainUnion(session, &session->getLex()->unit, result);
 
522
      res= planner.explainUnion(session, &session->lex->unit, result);
560
523
      if (lex->describe & DESCRIBE_EXTENDED)
561
524
      {
562
525
        char buff[1024];
563
526
        String str(buff,(uint32_t) sizeof(buff), system_charset_info);
564
527
        str.length(0);
565
 
        session->getLex()->unit.print(&str, QT_ORDINARY);
 
528
        session->lex->unit.print(&str, QT_ORDINARY);
566
529
        str.append('\0');
567
530
        push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
568
531
                     ER_YES, str.ptr());
571
534
        result->abort();
572
535
      else
573
536
        result->send_eof();
574
 
 
575
537
      delete result;
576
538
    }
577
539
    else
596
558
#define MY_YACC_INIT 1000                       // Start with big alloc
597
559
#define MY_YACC_MAX  32000                      // Because of 'short'
598
560
 
599
 
bool my_yyoverflow(short **yyss, ParserType **yyvs, ulong *yystacksize)
 
561
bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
600
562
{
601
 
  LEX   *lex= current_session->getLex();
 
563
  LEX   *lex= current_session->lex;
602
564
  ulong old_info=0;
603
565
  if ((uint32_t) *yystacksize >= MY_YACC_MAX)
604
566
    return 1;
621
583
    memcpy(lex->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
622
584
  }
623
585
  *yyss=(short*) lex->yacc_yyss;
624
 
  *yyvs=(ParserType*) lex->yacc_yyvs;
 
586
  *yyvs=(YYSTYPE*) lex->yacc_yyvs;
625
587
  return 0;
626
588
}
627
589
 
723
685
  @param var_name               Variable name
724
686
*/
725
687
 
726
 
void create_select_for_variable(Session *session, const char *var_name)
 
688
void create_select_for_variable(const char *var_name)
727
689
{
 
690
  Session *session;
728
691
  LEX *lex;
729
692
  LEX_STRING tmp, null_lex_string;
730
693
  Item *var;
731
694
  char buff[MAX_SYS_VAR_LENGTH*2+4+8];
732
695
  char *end= buff;
733
696
 
734
 
  lex= session->getLex();
 
697
  session= current_session;
 
698
  lex= session->lex;
735
699
  init_select(lex);
736
700
  lex->sql_command= SQLCOM_SELECT;
737
701
  tmp.str= (char*) var_name;
747
711
    var->set_name(buff, end-buff, system_charset_info);
748
712
    session->add_item_to_list(var);
749
713
  }
 
714
  return;
750
715
}
751
716
 
752
717
 
760
725
 
761
726
void parse(Session *session, const char *inBuf, uint32_t length)
762
727
{
763
 
  session->getLex()->start(session);
 
728
  session->lex->start(session);
764
729
 
765
730
  session->reset_for_next_command();
766
731
  /* Check if the Query is Cached if and return true if yes
776
741
  {
777
742
    return;
778
743
  }
779
 
  LEX *lex= session->getLex();
 
744
  LEX *lex= session->lex;
780
745
  Lex_input_stream lip(session, inBuf, length);
781
746
  bool err= parse_sql(session, &lip);
782
747
  if (!err)
833
798
                       List<String> *interval_list, const CHARSET_INFO * const cs)
834
799
{
835
800
  register CreateField *new_field;
836
 
  LEX  *lex= session->getLex();
 
801
  LEX  *lex= session->lex;
837
802
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
838
803
 
839
804
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
847
812
                      &default_key_create_info,
848
813
                      0, lex->col_list);
849
814
    statement->alter_info.key_list.push_back(key);
850
 
    lex->col_list.clear();
 
815
    lex->col_list.empty();
851
816
  }
852
817
  if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
853
818
  {
857
822
                 &default_key_create_info, 0,
858
823
                 lex->col_list);
859
824
    statement->alter_info.key_list.push_back(key);
860
 
    lex->col_list.clear();
 
825
    lex->col_list.empty();
861
826
  }
862
827
 
863
828
  if (default_value)
911
876
}
912
877
 
913
878
 
 
879
/** Store position for column in ALTER TABLE .. ADD column. */
 
880
 
 
881
void store_position_for_column(const char *name)
 
882
{
 
883
  current_session->lex->last_field->after=const_cast<char*> (name);
 
884
}
 
885
 
914
886
/**
915
887
  Add a table to list of used tables.
916
888
 
941
913
  TableList *ptr;
942
914
  TableList *previous_table_ref; /* The table preceding the current one. */
943
915
  char *alias_str;
944
 
  LEX *lex= session->getLex();
 
916
  LEX *lex= session->lex;
945
917
 
946
918
  if (!table)
947
919
    return NULL;                                // End of memory
958
930
    my_casedn_str(files_charset_info, table->db.str);
959
931
 
960
932
    identifier::Schema schema_identifier(string(table->db.str));
961
 
    if (not schema::check(*session, schema_identifier))
 
933
    if (not check_db_name(session, schema_identifier))
962
934
    {
963
935
 
964
936
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
974
946
                 ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
975
947
      return NULL;
976
948
    }
977
 
    if (!(alias_str= (char*) session->getMemRoot()->duplicate(alias_str,table->table.length+1)))
 
949
    if (!(alias_str= (char*) session->memdup(alias_str,table->table.length+1)))
978
950
      return NULL;
979
951
  }
980
952
  if (!(ptr = (TableList *) session->calloc(sizeof(TableList))))
1075
1047
bool Select_Lex::init_nested_join(Session *session)
1076
1048
{
1077
1049
  TableList *ptr;
1078
 
  NestedJoin *nested_join;
 
1050
  nested_join_st *nested_join;
1079
1051
 
1080
1052
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1081
 
                                       sizeof(NestedJoin))))
 
1053
                                       sizeof(nested_join_st))))
1082
1054
    return true;
1083
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
 
1055
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1084
1056
  nested_join= ptr->getNestedJoin();
1085
1057
  join_list->push_front(ptr);
1086
1058
  ptr->setEmbedding(embedding);
1088
1060
  ptr->alias= (char*) "(nested_join)";
1089
1061
  embedding= ptr;
1090
1062
  join_list= &nested_join->join_list;
1091
 
  join_list->clear();
 
1063
  join_list->empty();
1092
1064
  return false;
1093
1065
}
1094
1066
 
1110
1082
TableList *Select_Lex::end_nested_join(Session *)
1111
1083
{
1112
1084
  TableList *ptr;
1113
 
  NestedJoin *nested_join;
 
1085
  nested_join_st *nested_join;
1114
1086
 
1115
1087
  assert(embedding);
1116
1088
  ptr= embedding;
1151
1123
TableList *Select_Lex::nest_last_join(Session *session)
1152
1124
{
1153
1125
  TableList *ptr;
1154
 
  NestedJoin *nested_join;
 
1126
  nested_join_st *nested_join;
1155
1127
  List<TableList> *embedded_list;
1156
1128
 
1157
1129
  if (!(ptr= (TableList*) session->calloc(ALIGN_SIZE(sizeof(TableList))+
1158
 
                                          sizeof(NestedJoin))))
 
1130
                                          sizeof(nested_join_st))))
1159
1131
    return NULL;
1160
 
  ptr->setNestedJoin(((NestedJoin*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
 
1132
  ptr->setNestedJoin(((nested_join_st*) ((unsigned char*) ptr + ALIGN_SIZE(sizeof(TableList)))));
1161
1133
  nested_join= ptr->getNestedJoin();
1162
1134
  ptr->setEmbedding(embedding);
1163
1135
  ptr->setJoinList(join_list);
1164
1136
  ptr->alias= (char*) "(nest_last_join)";
1165
1137
  embedded_list= &nested_join->join_list;
1166
 
  embedded_list->clear();
 
1138
  embedded_list->empty();
1167
1139
 
1168
1140
  for (uint32_t i=0; i < 2; i++)
1169
1141
  {
1311
1283
  fake_select_lex->include_standalone(this,
1312
1284
                                      (Select_Lex_Node**)&fake_select_lex);
1313
1285
  fake_select_lex->select_number= INT_MAX;
1314
 
  fake_select_lex->parent_lex= session_arg->getLex(); /* Used in init_query. */
 
1286
  fake_select_lex->parent_lex= session_arg->lex; /* Used in init_query. */
1315
1287
  fake_select_lex->make_empty_select();
1316
1288
  fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
1317
1289
  fake_select_lex->select_limit= 0;
1331
1303
    */
1332
1304
    global_parameters= fake_select_lex;
1333
1305
    fake_select_lex->no_table_names_allowed= 1;
1334
 
    session_arg->getLex()->current_select= fake_select_lex;
 
1306
    session_arg->lex->current_select= fake_select_lex;
1335
1307
  }
1336
 
  session_arg->getLex()->pop_context();
 
1308
  session_arg->lex->pop_context();
1337
1309
  return(0);
1338
1310
}
1339
1311
 
1369
1341
    left_op->first_leaf_for_name_resolution();
1370
1342
  on_context->last_name_resolution_table=
1371
1343
    right_op->last_leaf_for_name_resolution();
1372
 
  return session->getLex()->push_context(on_context);
 
1344
  return session->lex->push_context(on_context);
1373
1345
}
1374
1346
 
1375
1347
 
1459
1431
 
1460
1432
bool check_simple_select(Session::pointer session)
1461
1433
{
1462
 
  if (session->getLex()->current_select != &session->getLex()->select_lex)
 
1434
  LEX *lex= session->lex;
 
1435
  if (lex->current_select != &lex->select_lex)
1463
1436
  {
1464
1437
    char command[80];
1465
1438
    Lex_input_stream *lip= session->m_lip;
1519
1492
bool update_precheck(Session *session, TableList *)
1520
1493
{
1521
1494
  const char *msg= 0;
1522
 
  Select_Lex *select_lex= &session->getLex()->select_lex;
 
1495
  LEX *lex= session->lex;
 
1496
  Select_Lex *select_lex= &lex->select_lex;
1523
1497
 
1524
 
  if (session->getLex()->select_lex.item_list.elements != session->getLex()->value_list.elements)
 
1498
  if (session->lex->select_lex.item_list.elements != session->lex->value_list.elements)
1525
1499
  {
1526
1500
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1527
1501
    return(true);
1528
1502
  }
1529
1503
 
1530
 
  if (session->getLex()->select_lex.table_list.elements > 1)
 
1504
  if (session->lex->select_lex.table_list.elements > 1)
1531
1505
  {
1532
1506
    if (select_lex->order_list.elements)
1533
1507
      msg= "ORDER BY";
1557
1531
 
1558
1532
bool insert_precheck(Session *session, TableList *)
1559
1533
{
 
1534
  LEX *lex= session->lex;
 
1535
 
1560
1536
  /*
1561
1537
    Check that we have modify privileges for the first table and
1562
1538
    select privileges for the rest
1563
1539
  */
1564
 
  if (session->getLex()->update_list.elements != session->getLex()->value_list.elements)
 
1540
  if (lex->update_list.elements != lex->value_list.elements)
1565
1541
  {
1566
1542
    my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
1567
1543
    return(true);
1588
1564
  {
1589
1565
    /* it is NOT(NOT( ... )) */
1590
1566
    Item *arg= ((Item_func *) expr)->arguments()[0];
1591
 
    enum_parsing_place place= session->getLex()->current_select->parsing_place;
 
1567
    enum_parsing_place place= session->lex->current_select->parsing_place;
1592
1568
    if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
1593
1569
      return arg;
1594
1570
    /*
1704
1680
 
1705
1681
  /* Parse the query. */
1706
1682
 
1707
 
  bool parse_status= base_sql_parse(session) != 0;
 
1683
  bool parse_status= DRIZZLEparse(session) != 0;
1708
1684
 
1709
1685
  /* Check that if DRIZZLEparse() failed, session->is_error() is set. */
1710
1686