~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

edit

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
/* drop and alter of tables */
17
17
 
18
 
#include <config.h>
 
18
#include "config.h"
19
19
#include <plugin/myisam/myisam.h>
20
20
#include <drizzled/show.h>
21
21
#include <drizzled/error.h>
26
26
#include <drizzled/sql_lex.h>
27
27
#include <drizzled/session.h>
28
28
#include <drizzled/sql_base.h>
29
 
#include <drizzled/strfunc.h>
 
29
#include "drizzled/strfunc.h"
 
30
#include <drizzled/db.h>
30
31
#include <drizzled/lock.h>
31
32
#include <drizzled/unireg.h>
32
33
#include <drizzled/item/int.h>
33
34
#include <drizzled/item/empty_string.h>
34
35
#include <drizzled/transaction_services.h>
35
 
#include <drizzled/transaction_services.h>
 
36
#include "drizzled/transaction_services.h"
36
37
#include <drizzled/table_proto.h>
37
38
#include <drizzled/plugin/client.h>
38
39
#include <drizzled/identifier.h>
39
 
#include <drizzled/internal/m_string.h>
40
 
#include <drizzled/global_charset_info.h>
41
 
#include <drizzled/charset.h>
42
 
 
43
 
#include <drizzled/definition/cache.h>
44
 
 
45
 
#include <drizzled/statement/alter_table.h>
46
 
#include <drizzled/sql_table.h>
47
 
#include <drizzled/pthread_globals.h>
48
 
#include <drizzled/typelib.h>
49
 
#include <drizzled/plugin/storage_engine.h>
 
40
#include "drizzled/internal/m_string.h"
 
41
#include "drizzled/global_charset_info.h"
 
42
#include "drizzled/charset.h"
 
43
 
 
44
#include "drizzled/definition/cache.h"
 
45
 
 
46
 
 
47
#include "drizzled/statement/alter_table.h"
 
48
#include "drizzled/sql_table.h"
 
49
#include "drizzled/pthread_globals.h"
50
50
 
51
51
#include <algorithm>
52
52
#include <sstream>
58
58
namespace drizzled
59
59
{
60
60
 
 
61
extern pid_t current_pid;
 
62
 
61
63
bool is_primary_key(KeyInfo *key_info)
62
64
{
63
65
  static const char * primary_key_name="PRIMARY";
108
110
void write_bin_log(Session *session, const std::string &query)
109
111
{
110
112
  TransactionServices &transaction_services= TransactionServices::singleton();
111
 
  transaction_services.rawStatement(*session, query);
 
113
  transaction_services.rawStatement(session, query);
112
114
}
113
115
 
114
116
/*
142
144
                   bool drop_temporary)
143
145
{
144
146
  TableList *table;
145
 
  util::string::vector wrong_tables;
 
147
  String wrong_tables;
146
148
  int error= 0;
147
149
  bool foreign_key_error= false;
148
150
 
198
200
      }
199
201
      identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
200
202
 
201
 
      message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier, true);
202
 
 
203
203
      if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
204
      {
205
205
        // Table was not found on disk and table can't be created from engine
206
206
        if (if_exists)
207
 
        {
208
207
          push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
209
208
                              ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
210
209
                              table->getTableName());
211
 
        }
212
210
        else
213
211
        {
214
212
          error= 1;
221
219
        /* Generate transaction event ONLY when we successfully drop */ 
222
220
        if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
223
221
        {
224
 
          if (message) // If we have no definition, we don't know if the table should have been replicated
225
 
          {
226
 
            TransactionServices &transaction_services= TransactionServices::singleton();
227
 
            transaction_services.dropTable(*session, identifier, *message, if_exists);
228
 
          }
 
222
          TransactionServices &transaction_services= TransactionServices::singleton();
 
223
          transaction_services.dropTable(session, identifier, if_exists);
229
224
        }
230
225
        else
231
226
        {
246
241
 
247
242
      if (error)
248
243
      {
249
 
        wrong_tables.push_back(table->getTableName());
 
244
        if (wrong_tables.length())
 
245
          wrong_tables.append(',');
 
246
        wrong_tables.append(String(table->getTableName(), system_charset_info));
250
247
      }
251
248
    }
252
249
 
254
251
 
255
252
  } while (0);
256
253
 
257
 
  if (wrong_tables.size())
 
254
  if (wrong_tables.length())
258
255
  {
259
256
    if (not foreign_key_error)
260
257
    {
261
 
      std::string table_error;
262
 
 
263
 
      for (util::string::vector::iterator iter= wrong_tables.begin();
264
 
           iter != wrong_tables.end();
265
 
           iter++)
266
 
      {
267
 
        table_error+= *iter;
268
 
        table_error+= ',';
269
 
      }
270
 
      table_error.resize(table_error.size() -1);
271
 
 
272
258
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
273
 
                      table_error.c_str());
 
259
                      wrong_tables.c_ptr());
274
260
    }
275
261
    else
276
262
    {
557
543
  int           timestamps= 0, timestamps_with_niladic= 0;
558
544
  int           dup_no;
559
545
  int           select_field_pos,auto_increment=0;
560
 
  List<CreateField>::iterator it(alter_info->create_list.begin());
561
 
  List<CreateField>::iterator it2(alter_info->create_list.begin());
 
546
  List_iterator<CreateField> it(alter_info->create_list);
 
547
  List_iterator<CreateField> it2(alter_info->create_list);
562
548
  uint32_t total_uneven_bit_length= 0;
563
549
 
564
550
  plugin::StorageEngine *engine= plugin::StorageEngine::findByName(create_proto.engine().name());
652
638
        interval= sql_field->interval= typelib(session->mem_root,
653
639
                                               sql_field->interval_list);
654
640
 
655
 
        List<String>::iterator int_it(sql_field->interval_list.begin());
 
641
        List_iterator<String> int_it(sql_field->interval_list);
656
642
        String conv, *tmp;
657
643
        char comma_buf[4];
658
644
        int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
678
664
          interval->type_lengths[i]= lengthsp;
679
665
          ((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
680
666
        }
681
 
        sql_field->interval_list.clear(); // Don't need interval_list anymore
 
667
        sql_field->interval_list.empty(); // Don't need interval_list anymore
682
668
      }
683
669
 
684
670
      /* DRIZZLE_TYPE_ENUM */
701
687
          else /* not NULL */
702
688
          {
703
689
            def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
704
 
            if (interval->find_type2(def->ptr(), def->length(), cs) == 0) /* not found */
 
690
            if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
705
691
            {
706
692
              my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
707
693
              return(true);
782
768
      (*db_options)|= HA_OPTION_PACK_RECORD;
783
769
    }
784
770
 
785
 
    it2= alter_info->create_list.begin();
 
771
    it2.rewind();
786
772
  }
787
773
 
788
774
  /* record_offset will be increased with 'length-of-null-bits' later */
789
775
  record_offset= 0;
790
776
  null_fields+= total_uneven_bit_length;
791
777
 
792
 
  it= alter_info->create_list.begin();
 
778
  it.rewind();
793
779
  while ((sql_field=it++))
794
780
  {
795
781
    assert(sql_field->charset != 0);
829
815
 
830
816
  /* Create keys */
831
817
 
832
 
  List<Key>::iterator key_iterator(alter_info->key_list.begin());
833
 
  List<Key>::iterator key_iterator2(alter_info->key_list.begin());
 
818
  List_iterator<Key> key_iterator(alter_info->key_list);
 
819
  List_iterator<Key> key_iterator2(alter_info->key_list);
834
820
  uint32_t key_parts=0, fk_key_count=0;
835
821
  bool primary_key=0,unique_key=0;
836
822
  Key *key, *key2;
880
866
    }
881
867
    if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
882
868
      return(true);
883
 
    key_iterator2= alter_info->key_list.begin();
 
869
    key_iterator2.rewind ();
884
870
    if (key->type != Key::FOREIGN_KEY)
885
871
    {
886
872
      while ((key2 = key_iterator2++) != key)
933
919
  if (!*key_info_buffer || ! key_part_info)
934
920
    return(true);                               // Out of memory
935
921
 
936
 
  key_iterator= alter_info->key_list.begin();
 
922
  key_iterator.rewind();
937
923
  key_number=0;
938
924
  for (; (key=key_iterator++) ; key_number++)
939
925
  {
992
978
 
993
979
    message::Table::Field *protofield= NULL;
994
980
 
995
 
    List<Key_part_spec>::iterator cols(key->columns.begin());
996
 
    List<Key_part_spec>::iterator cols2(key->columns.begin());
 
981
    List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
997
982
    for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
998
983
    {
999
984
      uint32_t length;
1000
985
      Key_part_spec *dup_column;
1001
986
      int proto_field_nr= 0;
1002
987
 
1003
 
      it= alter_info->create_list.begin();
 
988
      it.rewind();
1004
989
      field=0;
1005
990
      while ((sql_field=it++) && ++proto_field_nr &&
1006
991
             my_strcasecmp(system_charset_info,
1027
1012
          return(true);
1028
1013
        }
1029
1014
      }
1030
 
      cols2= key->columns.begin();
 
1015
      cols2.rewind();
1031
1016
 
1032
1017
      if (create_proto.field_size() > 0)
1033
1018
        protofield= create_proto.mutable_field(proto_field_nr - 1);
1240
1225
                     (qsort_cmp) sort_keys);
1241
1226
 
1242
1227
  /* Check fields. */
1243
 
  it= alter_info->create_list.begin();
 
1228
  it.rewind();
1244
1229
  while ((sql_field=it++))
1245
1230
  {
1246
1231
    Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1247
1232
 
1248
1233
    if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1249
1234
        !sql_field->def &&
1250
 
        (sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP  or sql_field->sql_type == DRIZZLE_TYPE_MICROTIME) &&
 
1235
        sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1251
1236
        (sql_field->flags & NOT_NULL_FLAG) &&
1252
1237
        (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1253
1238
    {
1346
1331
        return error;
1347
1332
      }
1348
1333
 
1349
 
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1334
      std::string path;
 
1335
      identifier.getSQLPath(path);
 
1336
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1350
1337
 
1351
1338
      return error;
1352
1339
    }
1366
1353
      */
1367
1354
      if (definition::Cache::singleton().find(identifier.getKey()))
1368
1355
      {
1369
 
        my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1356
        std::string path;
 
1357
        identifier.getSQLPath(path);
 
1358
        my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1370
1359
 
1371
1360
        return error;
1372
1361
      }
1405
1394
  if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1406
1395
  {
1407
1396
    TransactionServices &transaction_services= TransactionServices::singleton();
1408
 
    transaction_services.createTable(*session, table_proto);
 
1397
    transaction_services.createTable(session, table_proto);
1409
1398
  }
1410
1399
 
1411
1400
  return false;
1469
1458
 
1470
1459
  /* Build a Table object to pass down to the engine, and the do the actual create. */
1471
1460
  if (not prepare_create_table(session, create_info, table_proto, alter_info,
1472
 
                               internal_tmp_table,
1473
 
                               &db_options,
1474
 
                               &key_info_buffer, &key_count,
1475
 
                               select_field_count))
 
1461
                                     internal_tmp_table,
 
1462
                                     &db_options,
 
1463
                                     &key_info_buffer, &key_count,
 
1464
                                     select_field_count))
1476
1465
  {
1477
1466
    boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1478
1467
    error= locked_create_event(session,
1522
1511
    }
1523
1512
    else
1524
1513
    {
1525
 
      my_error(ER_TABLE_EXISTS_ERROR, identifier);
 
1514
      std::string path;
 
1515
      identifier.getSQLPath(path);
 
1516
      my_error(ER_TABLE_EXISTS_ERROR, MYF(0), path.c_str());
1526
1517
      result= true;
1527
1518
    }
1528
1519
  }
1768
1759
                                                            HA_CHECK_OPT *))
1769
1760
{
1770
1761
  TableList *table;
1771
 
  Select_Lex *select= &session->getLex()->select_lex;
 
1762
  Select_Lex *select= &session->lex->select_lex;
1772
1763
  List<Item> field_list;
1773
1764
  Item *item;
 
1765
  LEX *lex= session->lex;
1774
1766
  int result_code= 0;
1775
1767
  TransactionServices &transaction_services= TransactionServices::singleton();
1776
1768
  const CHARSET_INFO * const cs= system_charset_info;
1777
1769
 
1778
1770
  if (! session->endActiveTransaction())
1779
1771
    return 1;
1780
 
 
1781
1772
  field_list.push_back(item = new Item_empty_string("Table",
1782
1773
                                                    NAME_CHAR_LEN * 2,
1783
1774
                                                    cs));
1793
1784
 
1794
1785
  for (table= tables; table; table= table->next_local)
1795
1786
  {
1796
 
    identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1797
 
    std::string table_name;
 
1787
    char table_name[NAME_LEN*2+2];
1798
1788
    bool fatal_error=0;
1799
1789
 
1800
 
    table_identifier.getSQLPath(table_name);
1801
 
 
 
1790
    snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1802
1791
    table->lock_type= lock_type;
1803
1792
    /* open only one table from local list of command */
1804
1793
    {
1813
1802
        so it have to be prepared.
1814
1803
        @todo Investigate if we can put extra tables into argument instead of using lex->query_tables
1815
1804
      */
1816
 
      session->getLex()->query_tables= table;
1817
 
      session->getLex()->query_tables_last= &table->next_global;
1818
 
      session->getLex()->query_tables_own_last= 0;
 
1805
      lex->query_tables= table;
 
1806
      lex->query_tables_last= &table->next_global;
 
1807
      lex->query_tables_own_last= 0;
1819
1808
      session->no_warnings_for_error= 0;
1820
1809
 
1821
1810
      session->openTablesLock(table);
1845
1834
    {
1846
1835
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1847
1836
      uint32_t length;
1848
 
      session->getClient()->store(table_name.c_str());
 
1837
      session->getClient()->store(table_name);
1849
1838
      session->getClient()->store(operator_name);
1850
1839
      session->getClient()->store(STRING_WITH_LEN("error"));
1851
1840
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1852
 
                       table_name.c_str());
 
1841
                       table_name);
1853
1842
      session->getClient()->store(buff, length);
1854
 
      transaction_services.autocommitOrRollback(*session, false);
 
1843
      transaction_services.autocommitOrRollback(session, false);
1855
1844
      session->endTransaction(COMMIT);
1856
1845
      session->close_thread_tables();
1857
 
      session->getLex()->reset_query_tables_list(false);
 
1846
      lex->reset_query_tables_list(false);
1858
1847
      table->table=0;                           // For query cache
1859
1848
      if (session->getClient()->flush())
1860
1849
        goto err;
1880
1869
 
1881
1870
send_result:
1882
1871
 
1883
 
    session->getLex()->cleanup_after_one_table_open();
 
1872
    lex->cleanup_after_one_table_open();
1884
1873
    session->clear_error();  // these errors shouldn't get client
1885
1874
    {
1886
 
      List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
 
1875
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1887
1876
      DRIZZLE_ERROR *err;
1888
1877
      while ((err= it++))
1889
1878
      {
1890
 
        session->getClient()->store(table_name.c_str());
 
1879
        session->getClient()->store(table_name);
1891
1880
        session->getClient()->store(operator_name);
1892
1881
        session->getClient()->store(warning_level_names[err->level].str,
1893
1882
                               warning_level_names[err->level].length);
1897
1886
      }
1898
1887
      drizzle_reset_errors(session, true);
1899
1888
    }
1900
 
    session->getClient()->store(table_name.c_str());
 
1889
    session->getClient()->store(table_name);
1901
1890
    session->getClient()->store(operator_name);
1902
1891
 
1903
1892
    switch (result_code) {
1975
1964
        }
1976
1965
      }
1977
1966
    }
1978
 
    transaction_services.autocommitOrRollback(*session, false);
 
1967
    transaction_services.autocommitOrRollback(session, false);
1979
1968
    session->endTransaction(COMMIT);
1980
1969
    session->close_thread_tables();
1981
1970
    table->table=0;                             // For query cache
1987
1976
  return(false);
1988
1977
 
1989
1978
err:
1990
 
  transaction_services.autocommitOrRollback(*session, true);
 
1979
  transaction_services.autocommitOrRollback(session, true);
1991
1980
  session->endTransaction(ROLLBACK);
1992
1981
  session->close_thread_tables();                       // Shouldn't be needed
1993
1982
  if (table)
2020
2009
  // a "new" message and it will not have all of the information that the
2021
2010
  // source table message would have.
2022
2011
  message::Table new_table_message;
 
2012
  drizzled::error_t error;
2023
2013
 
2024
 
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
 
2014
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier, error);
2025
2015
 
2026
2016
  if (not source_table_message)
2027
2017
  {
2079
2069
  if (success && not destination_identifier.isTmp())
2080
2070
  {
2081
2071
    TransactionServices &transaction_services= TransactionServices::singleton();
2082
 
    transaction_services.createTable(session, new_table_message);
 
2072
    transaction_services.createTable(&session, new_table_message);
2083
2073
  }
2084
2074
 
2085
2075
  return success;