~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_table.cc

Merge in additional test case fixes.

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";
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
    {
1768
1753
                                                            HA_CHECK_OPT *))
1769
1754
{
1770
1755
  TableList *table;
1771
 
  Select_Lex *select= &session->getLex()->select_lex;
 
1756
  Select_Lex *select= &session->lex->select_lex;
1772
1757
  List<Item> field_list;
1773
1758
  Item *item;
 
1759
  LEX *lex= session->lex;
1774
1760
  int result_code= 0;
1775
1761
  TransactionServices &transaction_services= TransactionServices::singleton();
1776
1762
  const CHARSET_INFO * const cs= system_charset_info;
1777
1763
 
1778
1764
  if (! session->endActiveTransaction())
1779
1765
    return 1;
1780
 
 
1781
1766
  field_list.push_back(item = new Item_empty_string("Table",
1782
1767
                                                    NAME_CHAR_LEN * 2,
1783
1768
                                                    cs));
1793
1778
 
1794
1779
  for (table= tables; table; table= table->next_local)
1795
1780
  {
1796
 
    identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1797
 
    std::string table_name;
 
1781
    char table_name[NAME_LEN*2+2];
1798
1782
    bool fatal_error=0;
1799
1783
 
1800
 
    table_identifier.getSQLPath(table_name);
1801
 
 
 
1784
    snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1802
1785
    table->lock_type= lock_type;
1803
1786
    /* open only one table from local list of command */
1804
1787
    {
1813
1796
        so it have to be prepared.
1814
1797
        @todo Investigate if we can put extra tables into argument instead of using lex->query_tables
1815
1798
      */
1816
 
      session->getLex()->query_tables= table;
1817
 
      session->getLex()->query_tables_last= &table->next_global;
1818
 
      session->getLex()->query_tables_own_last= 0;
 
1799
      lex->query_tables= table;
 
1800
      lex->query_tables_last= &table->next_global;
 
1801
      lex->query_tables_own_last= 0;
1819
1802
      session->no_warnings_for_error= 0;
1820
1803
 
1821
1804
      session->openTablesLock(table);
1845
1828
    {
1846
1829
      char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1847
1830
      uint32_t length;
1848
 
      session->getClient()->store(table_name.c_str());
 
1831
      session->getClient()->store(table_name);
1849
1832
      session->getClient()->store(operator_name);
1850
1833
      session->getClient()->store(STRING_WITH_LEN("error"));
1851
1834
      length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1852
 
                       table_name.c_str());
 
1835
                       table_name);
1853
1836
      session->getClient()->store(buff, length);
1854
1837
      transaction_services.autocommitOrRollback(*session, false);
1855
1838
      session->endTransaction(COMMIT);
1856
1839
      session->close_thread_tables();
1857
 
      session->getLex()->reset_query_tables_list(false);
 
1840
      lex->reset_query_tables_list(false);
1858
1841
      table->table=0;                           // For query cache
1859
1842
      if (session->getClient()->flush())
1860
1843
        goto err;
1880
1863
 
1881
1864
send_result:
1882
1865
 
1883
 
    session->getLex()->cleanup_after_one_table_open();
 
1866
    lex->cleanup_after_one_table_open();
1884
1867
    session->clear_error();  // these errors shouldn't get client
1885
1868
    {
1886
 
      List<DRIZZLE_ERROR>::iterator it(session->warn_list.begin());
 
1869
      List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1887
1870
      DRIZZLE_ERROR *err;
1888
1871
      while ((err= it++))
1889
1872
      {
1890
 
        session->getClient()->store(table_name.c_str());
 
1873
        session->getClient()->store(table_name);
1891
1874
        session->getClient()->store(operator_name);
1892
1875
        session->getClient()->store(warning_level_names[err->level].str,
1893
1876
                               warning_level_names[err->level].length);
1897
1880
      }
1898
1881
      drizzle_reset_errors(session, true);
1899
1882
    }
1900
 
    session->getClient()->store(table_name.c_str());
 
1883
    session->getClient()->store(table_name);
1901
1884
    session->getClient()->store(operator_name);
1902
1885
 
1903
1886
    switch (result_code) {
2020
2003
  // a "new" message and it will not have all of the information that the
2021
2004
  // source table message would have.
2022
2005
  message::Table new_table_message;
 
2006
  drizzled::error_t error;
2023
2007
 
2024
 
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
 
2008
  message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier, error);
2025
2009
 
2026
2010
  if (not source_table_message)
2027
2011
  {