~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_parse.cc

  • Committer: Stewart Smith
  • Date: 2009-12-02 06:01:21 UTC
  • mto: (1237.1.2 push)
  • mto: This revision was merged to the branch mainline in revision 1238.
  • Revision ID: stewart@flamingspork.com-20091202060121-68gyfqifqcjcmi2v
my_end() no longer requires an argument (we removed them all)

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
 
#include "config.h"
17
 
 
18
16
#define DRIZZLE_LEX 1
19
 
 
20
 
#include <drizzled/my_hash.h>
 
17
#include <drizzled/server_includes.h>
 
18
#include <mysys/hash.h>
 
19
#include <drizzled/db.h>
21
20
#include <drizzled/error.h>
22
21
#include <drizzled/nested_join.h>
23
22
#include <drizzled/query_id.h>
24
 
#include "drizzled/transaction_services.h"
25
23
#include <drizzled/sql_parse.h>
26
24
#include <drizzled/data_home.h>
27
25
#include <drizzled/sql_base.h>
28
26
#include <drizzled/show.h>
29
 
#include <drizzled/db.h>
 
27
#include <drizzled/plugin/info_schema_table.h>
30
28
#include <drizzled/function/time/unix_timestamp.h>
31
29
#include <drizzled/function/get_system_var.h>
32
30
#include <drizzled/item/cmpfunc.h>
39
37
#include <drizzled/statement.h>
40
38
#include <drizzled/statement/alter_table.h>
41
39
#include "drizzled/probes.h"
42
 
#include "drizzled/session_list.h"
43
 
#include "drizzled/global_charset_info.h"
44
40
 
45
41
#include "drizzled/plugin/logging.h"
46
 
#include "drizzled/plugin/query_rewrite.h"
47
 
#include "drizzled/plugin/authorization.h"
48
 
#include "drizzled/optimizer/explain_plan.h"
49
 
#include "drizzled/pthread_globals.h"
50
 
 
51
 
#include <limits.h>
 
42
#include "drizzled/plugin/info_schema_table.h"
52
43
 
53
44
#include <bitset>
54
45
#include <algorithm>
55
46
 
56
 
#include "drizzled/internal/my_sys.h"
57
 
 
 
47
using namespace drizzled;
58
48
using namespace std;
59
49
 
60
 
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
61
 
 
62
 
namespace drizzled
63
 
{
64
 
 
65
50
/* Prototypes */
66
51
bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
67
52
static bool parse_sql(Session *session, Lex_input_stream *lip);
68
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length);
 
53
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
54
                 const char ** found_semicolon);
69
55
 
70
56
/**
71
57
  @defgroup Runtime_Environment Runtime Environment
129
115
  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
130
116
  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT;
131
117
 
 
118
  sql_command_flags[SQLCOM_SHOW_STATUS]=      CF_STATUS_COMMAND;
 
119
  sql_command_flags[SQLCOM_SHOW_DATABASES]=   CF_STATUS_COMMAND;
 
120
  sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND;
 
121
  sql_command_flags[SQLCOM_SHOW_FIELDS]=      CF_STATUS_COMMAND;
 
122
  sql_command_flags[SQLCOM_SHOW_KEYS]=        CF_STATUS_COMMAND;
 
123
  sql_command_flags[SQLCOM_SHOW_VARIABLES]=   CF_STATUS_COMMAND;
132
124
  sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
133
125
  sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
 
126
  sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
 
127
  sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
134
128
  sql_command_flags[SQLCOM_SHOW_CREATE_DB]=  CF_STATUS_COMMAND;
135
129
  sql_command_flags[SQLCOM_SHOW_CREATE]=  CF_STATUS_COMMAND;
136
130
 
 
131
   sql_command_flags[SQLCOM_SHOW_TABLES]=       (CF_STATUS_COMMAND |
 
132
                                               CF_SHOW_TABLE_COMMAND);
 
133
  sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
 
134
                                                CF_SHOW_TABLE_COMMAND);
137
135
  /*
138
136
    The following admin table operations are allowed
139
137
    on log tables.
174
172
  session->command= command;
175
173
  session->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
176
174
  session->set_time();
177
 
  session->setQueryId(query_id.value());
 
175
  session->query_id= query_id.value();
178
176
 
179
177
  switch( command ) {
180
178
  /* Ignore these statements. */
195
193
  switch (command) {
196
194
  case COM_INIT_DB:
197
195
  {
 
196
    LEX_STRING tmp;
198
197
    status_var_increment(session->status_var.com_stat[SQLCOM_CHANGE_DB]);
199
 
    if (packet_length == 0)
200
 
    {
201
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
202
 
      break;
203
 
    }
204
 
 
205
 
    string tmp(packet, packet_length);
206
 
 
207
 
    SchemaIdentifier identifier(tmp);
208
 
 
209
 
    if (not mysql_change_db(session, identifier))
 
198
    tmp.str= packet;
 
199
    tmp.length= packet_length;
 
200
    if (!mysql_change_db(session, &tmp, false))
210
201
    {
211
202
      session->my_ok();
212
203
    }
216
207
  {
217
208
    if (! session->readAndStoreQuery(packet, packet_length))
218
209
      break;                                    // fatal error is set
219
 
    DRIZZLE_QUERY_START(session->query.c_str(),
 
210
    DRIZZLE_QUERY_START(session->query,
220
211
                        session->thread_id,
221
 
                        const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
 
212
                        const_cast<const char *>(session->db ? session->db : ""));
 
213
    const char* end_of_stmt= NULL;
222
214
 
223
 
    plugin::QueryRewriter::rewriteQuery(session->db, session->query);
224
 
    mysql_parse(session, session->query.c_str(), session->query.length());
 
215
    mysql_parse(session, session->query, session->query_length, &end_of_stmt);
225
216
 
226
217
    break;
227
218
  }
253
244
 
254
245
  /* If commit fails, we should be able to reset the OK status. */
255
246
  session->main_da.can_overwrite_status= true;
256
 
  TransactionServices &transaction_services= TransactionServices::singleton();
257
 
  transaction_services.ha_autocommit_or_rollback(session, session->is_error());
 
247
  ha_autocommit_or_rollback(session, session->is_error());
258
248
  session->main_da.can_overwrite_status= false;
259
249
 
260
250
  session->transaction.stmt.reset();
312
302
  session->set_proc_info("cleaning up");
313
303
  session->command= COM_SLEEP;
314
304
  memset(session->process_list_info, 0, PROCESS_LIST_WIDTH);
315
 
  session->query.clear();
 
305
  session->query= 0;
 
306
  session->query_length= 0;
316
307
 
317
308
  session->set_proc_info(NULL);
318
 
  free_root(session->mem_root,MYF(memory::KEEP_PREALLOC));
 
309
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
319
310
 
320
311
  if (DRIZZLE_QUERY_DONE_ENABLED() || DRIZZLE_COMMAND_DONE_ENABLED())
321
312
  {
355
346
    1                 out of memory or SHOW commands are not allowed
356
347
                      in this version of the server.
357
348
*/
358
 
static bool _schema_select(Session *session, Select_Lex *sel,
359
 
                           const string& schema_table_name)
360
 
{
361
 
  LEX_STRING db, table;
362
 
  /*
363
 
     We have to make non const db_name & table_name
364
 
     because of lower_case_table_names
365
 
  */
366
 
  session->make_lex_string(&db, "data_dictionary", sizeof("data_dictionary"), false);
367
 
  session->make_lex_string(&table, schema_table_name, false);
368
 
 
369
 
  if (! sel->add_table_to_list(session, new Table_ident(db, table),
370
 
                               NULL, 0, TL_READ))
371
 
  {
372
 
    return true;
373
 
  }
374
 
  return false;
375
 
}
376
 
 
377
 
int prepare_new_schema_table(Session *session, LEX *lex,
378
 
                             const string& schema_table_name)
 
349
 
 
350
int prepare_schema_table(Session *session, LEX *lex, Table_ident *table_ident,
 
351
                         const string& schema_table_name)
379
352
{
380
353
  Select_Lex *schema_select_lex= NULL;
381
354
 
 
355
 
 
356
  if (schema_table_name.compare("TABLES") == 0 ||
 
357
      schema_table_name.compare("TABLE_NAMES") == 0)
 
358
  {
 
359
    LEX_STRING db;
 
360
    size_t dummy;
 
361
    if (lex->select_lex.db == NULL &&
 
362
        lex->copy_db_to(&lex->select_lex.db, &dummy))
 
363
    {
 
364
      return (1);
 
365
    }
 
366
    schema_select_lex= new Select_Lex();
 
367
    db.str= schema_select_lex->db= lex->select_lex.db;
 
368
    schema_select_lex->table_list.first= NULL;
 
369
    db.length= strlen(db.str);
 
370
 
 
371
    if (check_db_name(&db))
 
372
    {
 
373
      my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
 
374
      return (1);
 
375
    }
 
376
  }
 
377
  else if (schema_table_name.compare("COLUMNS") == 0 ||
 
378
           schema_table_name.compare("STATISTICS") == 0)
 
379
  {
 
380
    assert(table_ident);
 
381
    TableList **query_tables_last= lex->query_tables_last;
 
382
    schema_select_lex= new Select_Lex();
 
383
    /* 'parent_lex' is used in init_query() so it must be before it. */
 
384
    schema_select_lex->parent_lex= lex;
 
385
    schema_select_lex->init_query();
 
386
    if (! schema_select_lex->add_table_to_list(session, table_ident, 0, 0, TL_READ))
 
387
    {
 
388
      return (1);
 
389
    }
 
390
    lex->query_tables_last= query_tables_last;
 
391
  }
 
392
 
382
393
  Select_Lex *select_lex= lex->current_select;
383
394
  assert(select_lex);
384
 
  if (_schema_select(session, select_lex, schema_table_name))
 
395
  if (make_schema_select(session, select_lex, schema_table_name))
385
396
  {
386
397
    return(1);
387
398
  }
432
443
  /* list of all tables in query */
433
444
  TableList *all_tables;
434
445
  /* A peek into the query string */
435
 
  size_t proc_info_len= session->query.length() > PROCESS_LIST_WIDTH ?
436
 
                        PROCESS_LIST_WIDTH : session->query.length();
 
446
  size_t proc_info_len= session->query_length > PROCESS_LIST_WIDTH ?
 
447
                        PROCESS_LIST_WIDTH : session->query_length;
437
448
 
438
 
  memcpy(session->process_list_info, session->query.c_str(), proc_info_len);
 
449
  memcpy(session->process_list_info, session->query, proc_info_len);
439
450
  session->process_list_info[proc_info_len]= '\0';
440
451
 
441
452
  /*
475
486
 
476
487
  status_var_increment(session->status_var.com_stat[lex->sql_command]);
477
488
 
478
 
  assert(session->transaction.stmt.hasModifiedNonTransData() == false);
 
489
  assert(session->transaction.stmt.modified_non_trans_table == false);
479
490
 
480
491
  /* now we are ready to execute the statement */
481
492
  res= lex->statement->execute();
508
519
      param->select_limit=
509
520
        new Item_int((uint64_t) session->variables.select_limit);
510
521
  }
511
 
  if (not (res= session->openTablesLock(all_tables)))
 
522
  if (!(res= session->openTablesLock(all_tables)))
512
523
  {
513
524
    if (lex->describe)
514
525
    {
521
532
      if (!(result= new select_send()))
522
533
        return true;
523
534
      session->send_explain_fields(result);
524
 
      optimizer::ExplainPlan planner;
525
 
      res= planner.explainUnion(session, &session->lex->unit, result);
 
535
      res= mysql_explain_union(session, &session->lex->unit, result);
526
536
      if (lex->describe & DESCRIBE_EXTENDED)
527
537
      {
528
538
        char buff[1024];
697
707
  */
698
708
  if ((var= get_system_var(session, OPT_SESSION, tmp, null_lex_string)))
699
709
  {
700
 
    end+= snprintf(buff, sizeof(buff), "@@session.%s", var_name);
 
710
    end+= sprintf(buff, "@@session.%s", var_name);
701
711
    var->set_name(buff, end-buff, system_charset_info);
702
712
    session->add_item_to_list(var);
703
713
  }
711
721
  @param       session     Current thread
712
722
  @param       inBuf   Begining of the query text
713
723
  @param       length  Length of the query text
 
724
  @param[out]  found_semicolon For multi queries, position of the character of
 
725
                               the next query in the query text.
714
726
*/
715
727
 
716
 
void mysql_parse(Session *session, const char *inBuf, uint32_t length)
 
728
static void mysql_parse(Session *session, const char *inBuf, uint32_t length,
 
729
                 const char ** found_semicolon)
717
730
{
 
731
  /*
 
732
    Warning.
 
733
    The purpose of query_cache_send_result_to_client() is to lookup the
 
734
    query in the query cache first, to avoid parsing and executing it.
 
735
    So, the natural implementation would be to:
 
736
    - first, call query_cache_send_result_to_client,
 
737
    - second, if caching failed, initialise the lexical and syntactic parser.
 
738
    The problem is that the query cache depends on a clean initialization
 
739
    of (among others) lex->safe_to_cache_query and session->server_status,
 
740
    which are reset respectively in
 
741
    - lex_start()
 
742
    - mysql_reset_session_for_next_command()
 
743
    So, initializing the lexical analyser *before* using the query cache
 
744
    is required for the cache to work properly.
 
745
    FIXME: cleanup the dependencies in the code to simplify this.
 
746
  */
718
747
  lex_start(session);
719
748
  session->reset_for_next_command();
720
749
 
721
 
  LEX *lex= session->lex;
722
 
 
723
 
  Lex_input_stream lip(session, inBuf, length);
724
 
 
725
 
  bool err= parse_sql(session, &lip);
726
 
 
727
 
  if (!err)
728
750
  {
 
751
    LEX *lex= session->lex;
 
752
 
 
753
    Lex_input_stream lip(session, inBuf, length);
 
754
 
 
755
    bool err= parse_sql(session, &lip);
 
756
    *found_semicolon= lip.found_semicolon;
 
757
 
 
758
    if (!err)
729
759
    {
730
 
      if (! session->is_error())
731
760
      {
732
 
        DRIZZLE_QUERY_EXEC_START(session->query.c_str(),
733
 
                                 session->thread_id,
734
 
                                 const_cast<const char *>(session->db.empty() ? "" : session->db.c_str()));
735
 
        /* Actually execute the query */
736
 
        mysql_execute_command(session);
737
 
        DRIZZLE_QUERY_EXEC_DONE(0);
 
761
        if (! session->is_error())
 
762
        {
 
763
          /*
 
764
            Binlog logs a string starting from session->query and having length
 
765
            session->query_length; so we set session->query_length correctly (to not
 
766
            log several statements in one event, when we executed only first).
 
767
            We set it to not see the ';' (otherwise it would get into binlog
 
768
            and Query_log_event::print() would give ';;' output).
 
769
            This also helps display only the current query in SHOW
 
770
            PROCESSLIST.
 
771
            Note that we don't need LOCK_thread_count to modify query_length.
 
772
          */
 
773
          if (*found_semicolon &&
 
774
              (session->query_length= (ulong)(*found_semicolon - session->query)))
 
775
            session->query_length--;
 
776
          DRIZZLE_QUERY_EXEC_START(session->query,
 
777
                                   session->thread_id,
 
778
                                   const_cast<const char *>(session->db ? session->db : ""));
 
779
          /* Actually execute the query */
 
780
          mysql_execute_command(session);
 
781
          DRIZZLE_QUERY_EXEC_DONE(0);
 
782
        }
738
783
      }
739
784
    }
740
 
  }
741
 
  else
742
 
  {
743
 
    assert(session->is_error());
744
 
  }
745
 
 
746
 
  lex->unit.cleanup();
747
 
  session->set_proc_info("freeing items");
748
 
  session->end_statement();
749
 
  session->cleanup_after_query();
 
785
    else
 
786
    {
 
787
      assert(session->is_error());
 
788
    }
 
789
    lex->unit.cleanup();
 
790
    session->set_proc_info("freeing items");
 
791
    session->end_statement();
 
792
    session->cleanup_after_query();
 
793
  }
750
794
 
751
795
  return;
752
796
}
771
815
{
772
816
  register CreateField *new_field;
773
817
  LEX  *lex= session->lex;
774
 
  statement::AlterTable *statement= (statement::AlterTable *)lex->statement;
 
818
  drizzled::statement::AlterTable *statement= (drizzled::statement::AlterTable *)lex->statement;
775
819
 
776
820
  if (check_identifier_name(field_name, ER_TOO_LONG_IDENT))
777
821
    return true;
898
942
    return NULL;
899
943
  }
900
944
 
901
 
  if (table->is_derived_table() == false && table->db.str)
 
945
  if (table->is_derived_table() == false && table->db.str &&
 
946
      check_db_name(&table->db))
902
947
  {
903
 
    my_casedn_str(files_charset_info, table->db.str);
904
 
 
905
 
    SchemaIdentifier schema_identifier(string(table->db.str, table->db.length));
906
 
    if (not check_db_name(schema_identifier))
907
 
    {
908
 
 
909
 
      my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
910
 
      return NULL;
911
 
    }
 
948
    my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
 
949
    return NULL;
912
950
  }
913
951
 
914
952
  if (!alias)                                   /* Alias is case sensitive */
942
980
  ptr->table_name=table->table.str;
943
981
  ptr->table_name_length=table->table.length;
944
982
  ptr->lock_type=   lock_type;
 
983
  ptr->updating=    test(table_options & TL_OPTION_UPDATING);
945
984
  ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
946
985
  ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
947
986
  ptr->derived=     table->sel;
 
987
  if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
 
988
                                      INFORMATION_SCHEMA_NAME.c_str()))
 
989
  {
 
990
    plugin::InfoSchemaTable *schema_table= plugin::InfoSchemaTable::getTable(ptr->table_name);
 
991
    if (!schema_table ||
 
992
        (schema_table->isHidden() &&
 
993
         ((sql_command_flags[lex->sql_command].test(CF_BIT_STATUS_COMMAND)) == 0 ||
 
994
          /*
 
995
            this check is used for show columns|keys from I_S hidden table
 
996
          */
 
997
          lex->sql_command == SQLCOM_SHOW_FIELDS ||
 
998
          lex->sql_command == SQLCOM_SHOW_KEYS)))
 
999
    {
 
1000
      my_error(ER_UNKNOWN_TABLE, MYF(0),
 
1001
               ptr->table_name, INFORMATION_SCHEMA_NAME.c_str());
 
1002
      return NULL;
 
1003
    }
 
1004
  }
948
1005
  ptr->select_lex=  lex->current_select;
949
1006
  ptr->index_hints= index_hints_arg;
950
1007
  ptr->option= option ? option->str : 0;
957
1014
         tables=tables->next_local)
958
1015
    {
959
1016
      if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
960
 
          !strcasecmp(ptr->db, tables->db))
 
1017
          !strcmp(ptr->db, tables->db))
961
1018
      {
962
1019
        my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str);
963
1020
        return NULL;
1214
1271
 
1215
1272
void Select_Lex::set_lock_for_tables(thr_lock_type lock_type)
1216
1273
{
 
1274
  bool for_update= lock_type >= TL_READ_NO_INSERT;
 
1275
 
1217
1276
  for (TableList *tables= (TableList*) table_list.first;
1218
1277
       tables;
1219
1278
       tables= tables->next_local)
1220
1279
  {
1221
1280
    tables->lock_type= lock_type;
 
1281
    tables->updating=  for_update;
1222
1282
  }
 
1283
  return;
1223
1284
}
1224
1285
 
1225
1286
 
1230
1291
    This object is created for any union construct containing a union
1231
1292
    operation and also for any single select union construct of the form
1232
1293
    @verbatim
1233
 
    (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
 
1294
    (SELECT ... order_st BY order_list [LIMIT n]) order_st BY ...
1234
1295
    @endvarbatim
1235
1296
    or of the form
1236
1297
    @varbatim
1237
 
    (SELECT ... ORDER BY LIMIT n) ORDER BY ...
 
1298
    (SELECT ... order_st BY LIMIT n) order_st BY ...
1238
1299
    @endvarbatim
1239
1300
 
1240
1301
  @param session_arg               thread handle
1265
1326
  fake_select_lex->select_limit= 0;
1266
1327
 
1267
1328
  fake_select_lex->context.outer_context=first_sl->context.outer_context;
1268
 
  /* allow item list resolving in fake select for ORDER BY */
 
1329
  /* allow item list resolving in fake select for order_st BY */
1269
1330
  fake_select_lex->context.resolve_in_select_list= true;
1270
1331
  fake_select_lex->context.select_lex= fake_select_lex;
1271
1332
 
1273
1334
  {
1274
1335
    /*
1275
1336
      This works only for
1276
 
      (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
1277
 
      (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
 
1337
      (SELECT ... order_st BY list [LIMIT n]) order_st BY order_list [LIMIT m],
 
1338
      (SELECT ... LIMIT n) order_st BY order_list [LIMIT m]
1278
1339
      just before the parser starts processing order_list
1279
1340
    */
1280
1341
    global_parameters= fake_select_lex;
1411
1472
kill_one_thread(Session *, ulong id, bool only_kill_query)
1412
1473
{
1413
1474
  Session *tmp= NULL;
1414
 
  uint32_t error= ER_NO_SUCH_THREAD;
 
1475
  uint32_t error=ER_NO_SUCH_THREAD;
1415
1476
  pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
1416
1477
  
1417
 
  for (SessionList::iterator it= getSessionList().begin(); it != getSessionList().end(); ++it )
 
1478
  for( vector<Session*>::iterator it= session_list.begin(); it != session_list.end(); ++it )
1418
1479
  {
1419
1480
    if ((*it)->thread_id == id)
1420
1481
    {
1426
1487
  pthread_mutex_unlock(&LOCK_thread_count);
1427
1488
  if (tmp)
1428
1489
  {
1429
 
 
1430
 
    if (tmp->isViewable())
1431
 
    {
1432
 
      tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
1433
 
      error= 0;
1434
 
    }
1435
 
 
 
1490
    tmp->awake(only_kill_query ? Session::KILL_QUERY : Session::KILL_CONNECTION);
 
1491
    error=0;
1436
1492
    pthread_mutex_unlock(&tmp->LOCK_delete);
1437
1493
  }
1438
1494
  return(error);
1601
1657
 
1602
1658
bool create_table_precheck(TableIdentifier &identifier)
1603
1659
{
1604
 
  if (not plugin::StorageEngine::canCreateTable(identifier))
1605
 
  {
1606
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", identifier.getSchemaName().c_str());
1607
 
    return true;
1608
 
  }
1609
 
 
1610
 
  if (not plugin::StorageEngine::doesSchemaExist(identifier))
1611
 
  {
1612
 
    my_error(ER_BAD_DB_ERROR, MYF(0), identifier.getSchemaName().c_str());
 
1660
  if (strcmp(identifier.getDBName(), "information_schema") == 0)
 
1661
  {
 
1662
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
1613
1663
    return true;
1614
1664
  }
1615
1665
 
1725
1775
  return true;
1726
1776
}
1727
1777
 
 
1778
extern int DRIZZLEparse(void *session); // from sql_yacc.cc
 
1779
 
1728
1780
 
1729
1781
/**
1730
1782
  This is a wrapper of DRIZZLEparse(). All the code should call parse_sql()
1742
1794
{
1743
1795
  assert(session->m_lip == NULL);
1744
1796
 
1745
 
  DRIZZLE_QUERY_PARSE_START(session->query.c_str());
 
1797
  DRIZZLE_QUERY_PARSE_START(session->query);
1746
1798
 
1747
1799
  /* Set Lex_input_stream. */
1748
1800
 
1770
1822
/**
1771
1823
  @} (end of group Runtime_Environment)
1772
1824
*/
1773
 
 
1774
 
} /* namespace drizzled */