16
16
/* drop and alter of tables */
19
19
#include <plugin/myisam/myisam.h>
20
20
#include <drizzled/show.h>
21
21
#include <drizzled/error.h>
22
22
#include <drizzled/gettext.h>
23
23
#include <drizzled/data_home.h>
24
24
#include <drizzled/sql_parse.h>
25
#include <drizzled/my_hash.h>
26
25
#include <drizzled/sql_lex.h>
27
26
#include <drizzled/session.h>
28
27
#include <drizzled/sql_base.h>
29
#include "drizzled/strfunc.h"
30
#include <drizzled/db.h>
31
28
#include <drizzled/lock.h>
32
#include <drizzled/unireg.h>
33
29
#include <drizzled/item/int.h>
34
30
#include <drizzled/item/empty_string.h>
35
31
#include <drizzled/transaction_services.h>
36
#include "drizzled/transaction_services.h"
32
#include <drizzled/transaction_services.h>
37
33
#include <drizzled/table_proto.h>
38
34
#include <drizzled/plugin/client.h>
39
35
#include <drizzled/identifier.h>
40
#include "drizzled/internal/m_string.h"
41
#include "drizzled/global_charset_info.h"
42
#include "drizzled/charset.h"
44
#include "drizzled/definition/cache.h"
47
#include "drizzled/statement/alter_table.h"
48
#include "drizzled/sql_table.h"
49
#include "drizzled/pthread_globals.h"
50
#include "drizzled/plugin/storage_engine.h"
36
#include <drizzled/internal/m_string.h>
37
#include <drizzled/charset.h>
38
#include <drizzled/definition/cache.h>
39
#include <drizzled/system_variables.h>
40
#include <drizzled/statement/alter_table.h>
41
#include <drizzled/sql_table.h>
42
#include <drizzled/pthread_globals.h>
43
#include <drizzled/typelib.h>
44
#include <drizzled/plugin/storage_engine.h>
45
#include <drizzled/diagnostics_area.h>
46
#include <drizzled/open_tables_state.h>
47
#include <drizzled/table/cache.h>
48
#include <drizzled/create_field.h>
52
50
#include <algorithm>
99
query_length Length of query
105
Write the binlog if open, routine used in multiple places in this
109
void write_bin_log(Session *session, const std::string &query)
111
TransactionServices &transaction_services= TransactionServices::singleton();
112
transaction_services.rawStatement(*session, query);
116
92
Execute the drop of a normal or temporary table
143
119
bool drop_temporary)
145
121
TableList *table;
122
util::string::vector wrong_tables;
148
124
bool foreign_key_error= false;
152
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex());
128
boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
154
130
if (not drop_temporary && session->lock_table_names_exclusively(tables))
180
156
if (drop_temporary == false)
183
158
abort_locked_tables(session, tmp_identifier);
184
table::Cache::singleton().removeTable(session, tmp_identifier,
185
RTFC_WAIT_OTHER_THREAD_FLAG |
186
RTFC_CHECK_KILLED_FLAG);
159
table::Cache::removeTable(*session, tmp_identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
188
161
If the table was used in lock tables, remember it so that
189
162
unlock_table_names can free it
191
if ((locked_table= drop_locked_tables(session, tmp_identifier)))
164
Table *locked_table= drop_locked_tables(session, tmp_identifier);
192
166
table->table= locked_table;
194
168
if (session->getKilled())
200
174
identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
176
message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier, true);
202
178
if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
204
180
// Table was not found on disk and table can't be created from engine
206
183
push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
207
184
ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
208
185
table->getTableName());
218
196
/* Generate transaction event ONLY when we successfully drop */
219
197
if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
221
TransactionServices &transaction_services= TransactionServices::singleton();
222
transaction_services.dropTable(*session, identifier, if_exists);
199
if (message) // If we have no definition, we don't know if the table should have been replicated
201
TransactionServices::dropTable(*session, identifier, *message, if_exists);
253
if (wrong_tables.length())
231
if (wrong_tables.size())
255
233
if (not foreign_key_error)
235
std::string table_error;
237
BOOST_FOREACH(util::string::vector::reference iter, wrong_tables)
242
table_error.resize(table_error.size() -1);
257
244
my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
258
wrong_tables.c_ptr());
245
table_error.c_str());
341
const CHARSET_INFO * const cs;
328
const charset_info_st * const cs;
343
330
typelib_set_member(const char* value, unsigned int length,
344
const CHARSET_INFO * const charset)
331
const charset_info_st * const charset)
345
332
: s(value, length),
371
358
static bool check_duplicates_in_interval(const char *set_or_name,
372
359
const char *name, TYPELIB *typelib,
373
const CHARSET_INFO * const cs,
360
const charset_info_st * const cs,
374
361
unsigned int *dup_val_count)
376
363
TYPELIB tmp= *typelib;
385
372
tmp.type_names++;
386
373
tmp.type_lengths++;
388
if (interval_set.find(typelib_set_member(*cur_value, *cur_length, cs)) != interval_set.end())
375
if (interval_set.count(typelib_set_member(*cur_value, *cur_length, cs)))
390
377
my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
391
378
name,*cur_value,set_or_name);
542
529
int timestamps= 0, timestamps_with_niladic= 0;
544
531
int select_field_pos,auto_increment=0;
545
List_iterator<CreateField> it(alter_info->create_list);
546
List_iterator<CreateField> it2(alter_info->create_list);
532
List<CreateField>::iterator it(alter_info->create_list.begin());
533
List<CreateField>::iterator it2(alter_info->create_list.begin());
547
534
uint32_t total_uneven_bit_length= 0;
549
536
plugin::StorageEngine *engine= plugin::StorageEngine::findByName(create_proto.engine().name());
551
select_field_pos= alter_info->create_list.elements - select_field_count;
538
select_field_pos= alter_info->create_list.size() - select_field_count;
552
539
null_fields=blob_columns=0;
553
540
max_key_length= engine->max_key_length();
555
542
for (int32_t field_no=0; (sql_field=it++) ; field_no++)
557
const CHARSET_INFO *save_cs;
544
const charset_info_st *save_cs;
560
547
Initialize length from its original value (number of characters),
613
600
/* Could not convert */
614
601
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
619
606
if (sql_field->sql_type == DRIZZLE_TYPE_ENUM)
622
const CHARSET_INFO * const cs= sql_field->charset;
608
const charset_info_st * const cs= sql_field->charset;
623
609
TYPELIB *interval= sql_field->interval;
634
620
occupied memory at the same time when we free this
635
621
sql_field -- at the end of execution.
637
interval= sql_field->interval= typelib(session->mem_root,
638
sql_field->interval_list);
623
interval= sql_field->interval= typelib(*session->mem_root, sql_field->interval_list);
640
List_iterator<String> int_it(sql_field->interval_list);
625
List<String>::iterator int_it(sql_field->interval_list.begin());
641
626
String conv, *tmp;
642
627
char comma_buf[4];
643
int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf,
644
(unsigned char*) comma_buf +
628
int comma_length= cs->cset->wc_mb(cs, ',', (unsigned char*) comma_buf, (unsigned char*) comma_buf + sizeof(comma_buf));
646
629
assert(comma_length > 0);
648
631
for (uint32_t i= 0; (tmp= int_it++); i++)
650
633
uint32_t lengthsp;
651
if (String::needs_conversion(tmp->length(), tmp->charset(),
634
if (String::needs_conversion(tmp->length(), tmp->charset(), cs))
655
conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
656
interval->type_names[i]= session->mem_root->strmake_root(conv.ptr(), conv.length());
636
conv.copy(tmp->ptr(), tmp->length(), cs);
637
interval->type_names[i]= session->mem.strdup(conv);
657
638
interval->type_lengths[i]= conv.length();
660
641
// Strip trailing spaces.
661
lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
662
interval->type_lengths[i]);
642
lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], interval->type_lengths[i]);
663
643
interval->type_lengths[i]= lengthsp;
664
644
((unsigned char *)interval->type_names[i])[lengthsp]= '\0';
666
sql_field->interval_list.empty(); // Don't need interval_list anymore
646
sql_field->interval_list.clear(); // Don't need interval_list anymore
669
649
/* DRIZZLE_TYPE_ENUM */
675
655
String str, *def= sql_field->def->val_str(&str);
676
656
if (def == NULL) /* SQL "NULL" maps to NULL */
678
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
658
if (sql_field->flags & NOT_NULL_FLAG)
680
660
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
684
664
/* else, the defaults yield the correct length for NULLs. */
686
666
else /* not NULL */
688
668
def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
689
if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
669
if (interval->find_type2(def->ptr(), def->length(), cs) == 0) /* not found */
691
671
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
767
747
(*db_options)|= HA_OPTION_PACK_RECORD;
750
it2= alter_info->create_list.begin();
773
753
/* record_offset will be increased with 'length-of-null-bits' later */
774
754
record_offset= 0;
775
755
null_fields+= total_uneven_bit_length;
757
it= alter_info->create_list.begin();
778
758
while ((sql_field=it++))
780
760
assert(sql_field->charset != 0);
782
762
if (prepare_create_field(sql_field, &blob_columns,
783
763
×tamps, ×tamps_with_niladic))
785
765
sql_field->offset= record_offset;
786
766
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
787
767
auto_increment++;
791
771
my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
792
772
ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
795
775
if (auto_increment > 1)
797
777
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
800
780
if (auto_increment &&
801
781
(engine->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
803
783
my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
804
784
ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
808
788
if (blob_columns && (engine->check_flag(HTON_BIT_NO_BLOBS)))
810
790
my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
815
795
/* Create keys */
817
List_iterator<Key> key_iterator(alter_info->key_list);
818
List_iterator<Key> key_iterator2(alter_info->key_list);
797
List<Key>::iterator key_iterator(alter_info->key_list.begin());
798
List<Key>::iterator key_iterator2(alter_info->key_list.begin());
819
799
uint32_t key_parts=0, fk_key_count=0;
820
800
bool primary_key=0,unique_key=0;
845
825
fk_key->update_opt,
846
826
fk_key->match_opt);
848
if (fk_key->ref_columns.elements &&
849
fk_key->ref_columns.elements != fk_key->columns.elements)
828
if (fk_key->ref_columns.size() &&
829
fk_key->ref_columns.size() != fk_key->columns.size())
851
831
my_error(ER_WRONG_FK_DEF, MYF(0),
852
832
(fk_key->name.str ? fk_key->name.str :
853
833
"foreign key without name"),
854
834
ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
860
840
tmp= engine->max_key_parts();
861
if (key->columns.elements > tmp)
841
if (key->columns.size() > tmp)
863
843
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
866
846
if (check_identifier_name(&key->name, ER_TOO_LONG_IDENT))
868
key_iterator2.rewind ();
848
key_iterator2= alter_info->key_list.begin();
869
849
if (key->type != Key::FOREIGN_KEY)
871
851
while ((key2 = key_iterator2++) != key)
882
862
/* @todo issue warning message */
883
863
/* mark that the generated key should be ignored */
884
864
if (!key2->generated ||
885
(key->generated && key->columns.elements <
886
key2->columns.elements))
865
(key->generated && key->columns.size() <
866
key2->columns.size()))
887
867
key->name.str= ignore_key;
890
870
key2->name.str= ignore_key;
891
key_parts-= key2->columns.elements;
871
key_parts-= key2->columns.size();
898
878
if (key->name.str != ignore_key)
899
key_parts+=key->columns.elements;
879
key_parts+=key->columns.size();
902
882
if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
903
883
is_primary_key_name(key->name.str))
905
885
my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
909
889
tmp= engine->max_keys();
910
890
if (*key_count > tmp)
912
892
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
916
896
(*key_info_buffer)= key_info= (KeyInfo*) memory::sql_calloc(sizeof(KeyInfo) * (*key_count));
917
897
key_part_info=(KeyPartInfo*) memory::sql_calloc(sizeof(KeyPartInfo)*key_parts);
918
if (!*key_info_buffer || ! key_part_info)
919
return(true); // Out of memory
921
key_iterator.rewind();
899
key_iterator= alter_info->key_list.begin();
923
901
for (; (key=key_iterator++) ; key_number++)
949
927
if (key->generated)
950
928
key_info->flags|= HA_GENERATED_KEY;
952
key_info->key_parts=(uint8_t) key->columns.elements;
930
key_info->key_parts=(uint8_t) key->columns.size();
953
931
key_info->key_part=key_part_info;
954
932
key_info->usable_key_parts= key_number;
955
933
key_info->algorithm= key->key_create_info.algorithm;
978
956
message::Table::Field *protofield= NULL;
980
List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
958
List<Key_part_spec>::iterator cols(key->columns.begin());
959
List<Key_part_spec>::iterator cols2(key->columns.begin());
981
960
for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
984
963
Key_part_spec *dup_column;
985
964
int proto_field_nr= 0;
966
it= alter_info->create_list.begin();
989
968
while ((sql_field=it++) && ++proto_field_nr &&
990
969
my_strcasecmp(system_charset_info,
1008
987
my_printf_error(ER_DUP_FIELDNAME,
1009
988
ER(ER_DUP_FIELDNAME),MYF(0),
1010
989
column->field_name.str);
993
cols2= key->columns.begin();
1016
995
if (create_proto.field_size() > 0)
1017
996
protofield= create_proto.mutable_field(proto_field_nr - 1);
1211
1190
(engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1213
1192
my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1217
1196
if (auto_increment > 0)
1219
1198
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1222
1201
/* Sort keys in optimized order */
1223
1202
internal::my_qsort((unsigned char*) *key_info_buffer, *key_count, sizeof(KeyInfo),
1224
1203
(qsort_cmp) sort_keys);
1226
1205
/* Check fields. */
1206
it= alter_info->create_list.begin();
1228
1207
while ((sql_field=it++))
1230
1209
Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
1232
1211
if (session->variables.sql_mode & MODE_NO_ZERO_DATE &&
1233
1212
!sql_field->def &&
1234
sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP &&
1213
(sql_field->sql_type == DRIZZLE_TYPE_TIMESTAMP or sql_field->sql_type == DRIZZLE_TYPE_MICROTIME) &&
1235
1214
(sql_field->flags & NOT_NULL_FLAG) &&
1236
1215
(type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1389
1368
if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1391
TransactionServices &transaction_services= TransactionServices::singleton();
1392
transaction_services.createTable(*session, table_proto);
1370
TransactionServices::createTable(*session, table_proto);
1440
1418
bool error= true;
1442
1420
/* Check for duplicate fields and check type of table to create */
1443
if (not alter_info->create_list.elements)
1421
if (not alter_info->create_list.size())
1445
1423
my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1458
1436
&key_info_buffer, &key_count,
1459
1437
select_field_count))
1461
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1439
boost::mutex::scoped_lock lock(table::Cache::mutex()); /* CREATE TABLE (some confussion on naming, double check) */
1462
1440
error= locked_create_event(session,
1635
1608
const identifier::Table &from,
1636
1609
const identifier::Table &to)
1642
1611
if (not plugin::StorageEngine::doesSchemaExist(to))
1644
1613
my_error(ER_NO_DB_ERROR, MYF(0), to.getSchemaName().c_str());
1648
error= base->renameTable(session, from, to);
1617
int error= base->renameTable(session, from, to);
1650
1618
if (error == HA_ERR_WRONG_COMMAND)
1652
1619
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER Table");
1654
1620
else if (error)
1656
std::string from_path;
1657
std::string to_path;
1659
from.getSQLPath(from_path);
1660
to.getSQLPath(to_path);
1662
const char *from_identifier= from.isTmp() ? "#sql-temporary" : from_path.c_str();
1663
const char *to_identifier= to.isTmp() ? "#sql-temporary" : to_path.c_str();
1665
my_error(ER_ERROR_ON_RENAME, MYF(0), from_identifier, to_identifier, error);
1622
my_error(ER_ERROR_ON_RENAME, MYF(0),
1623
from.isTmp() ? "#sql-temporary" : from.getSQLPath().c_str(),
1624
to.isTmp() ? "#sql-temporary" : to.getSQLPath().c_str(), error);
1668
return error ? true : false;
1692
1650
enum ha_extra_function function)
1695
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle());
1653
safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1697
1655
table->cursor->extra(function);
1698
1656
/* Mark all tables that are in use as 'old' */
1701
1659
/* Wait until all there are no other threads that has this table open */
1702
1660
identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1703
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1661
table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1726
1684
wait_while_table_is_used(this, table, HA_EXTRA_FORCE_REOPEN);
1727
1685
/* Close lock if this is not got with LOCK TABLES */
1686
if (open_tables.lock)
1731
lock= NULL; // Start locked threads
1688
unlockTables(open_tables.lock);
1689
open_tables.lock= NULL; // Start locked threads
1733
1691
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
1734
1692
unlink_open_table(table);
1736
/* When lock on table::Cache::singleton().mutex() is freed other threads can continue */
1694
/* When lock on table::Cache::mutex() is freed other threads can continue */
1737
1695
locking::broadcast_refresh();
1744
1702
(admin operation or network communication failed)
1746
1704
static bool admin_table(Session* session, TableList* tables,
1747
HA_CHECK_OPT* check_opt,
1748
1705
const char *operator_name,
1749
1706
thr_lock_type lock_type,
1750
1707
bool open_for_modify,
1751
int (Cursor::*operator_func)(Session *,
1708
int (Cursor::*operator_func)(Session*))
1754
1710
TableList *table;
1755
Select_Lex *select= &session->lex->select_lex;
1711
Select_Lex *select= &session->lex().select_lex;
1756
1712
List<Item> field_list;
1758
LEX *lex= session->lex;
1759
1714
int result_code= 0;
1760
TransactionServices &transaction_services= TransactionServices::singleton();
1761
const CHARSET_INFO * const cs= system_charset_info;
1715
const charset_info_st * const cs= system_charset_info;
1763
1717
if (! session->endActiveTransaction())
1765
field_list.push_back(item = new Item_empty_string("Table",
1720
field_list.push_back(item = new Item_empty_string("Table", NAME_CHAR_LEN * 2, cs));
1768
1721
item->maybe_null = 1;
1769
1722
field_list.push_back(item = new Item_empty_string("Op", 10, cs));
1770
1723
item->maybe_null = 1;
1772
1725
item->maybe_null = 1;
1773
1726
field_list.push_back(item = new Item_empty_string("Msg_text", 255, cs));
1774
1727
item->maybe_null = 1;
1775
if (session->getClient()->sendFields(&field_list))
1728
session->getClient()->sendFields(field_list);
1778
1730
for (table= tables; table; table= table->next_local)
1780
char table_name[NAME_LEN*2+2];
1732
identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1781
1733
bool fatal_error=0;
1783
snprintf(table_name, sizeof(table_name), "%s.%s", table->getSchemaName(), table->getTableName());
1735
std::string table_name = table_identifier.getSQLPath();
1784
1737
table->lock_type= lock_type;
1785
1738
/* open only one table from local list of command */
1795
1748
so it have to be prepared.
1796
1749
@todo Investigate if we can put extra tables into argument instead of using lex->query_tables
1798
lex->query_tables= table;
1799
lex->query_tables_last= &table->next_global;
1800
lex->query_tables_own_last= 0;
1751
session->lex().query_tables= table;
1752
session->lex().query_tables_last= &table->next_global;
1753
session->lex().query_tables_own_last= 0;
1801
1754
session->no_warnings_for_error= 0;
1803
1756
session->openTablesLock(table);
1817
1770
if (!table->table)
1819
if (!session->warn_list.elements)
1772
if (!session->main_da().m_warn_list.size())
1820
1773
push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1821
1774
ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
1822
1775
result_code= HA_ADMIN_CORRUPT;
1828
1781
char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1829
1782
uint32_t length;
1830
session->getClient()->store(table_name);
1783
session->getClient()->store(table_name.c_str());
1831
1784
session->getClient()->store(operator_name);
1832
1785
session->getClient()->store(STRING_WITH_LEN("error"));
1833
1786
length= snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
1787
table_name.c_str());
1835
1788
session->getClient()->store(buff, length);
1836
transaction_services.autocommitOrRollback(*session, false);
1789
TransactionServices::autocommitOrRollback(*session, false);
1837
1790
session->endTransaction(COMMIT);
1838
1791
session->close_thread_tables();
1839
lex->reset_query_tables_list(false);
1792
session->lex().reset_query_tables_list(false);
1840
1793
table->table=0; // For query cache
1841
1794
if (session->getClient()->flush())
1846
1799
/* Close all instances of the table to allow repair to rename files */
1847
1800
if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1849
table::Cache::singleton().mutex().lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1850
const char *old_message=session->enter_cond(COND_refresh, table::Cache::singleton().mutex(),
1802
table::Cache::mutex().lock(); /* Lock type is TL_WRITE and we lock to repair the table */
1803
const char *old_message=session->enter_cond(COND_refresh, table::Cache::mutex(),
1851
1804
"Waiting to get writelock");
1852
1805
session->abortLock(table->table);
1853
1806
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1854
table::Cache::singleton().removeTable(session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1807
table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1855
1808
session->exit_cond(old_message);
1856
1809
if (session->getKilled())
1858
1811
open_for_modify= 0;
1861
result_code = (table->table->cursor->*operator_func)(session, check_opt);
1814
result_code = (table->table->cursor->*operator_func)(session);
1865
lex->cleanup_after_one_table_open();
1818
session->lex().cleanup_after_one_table_open();
1866
1819
session->clear_error(); // these errors shouldn't get client
1868
List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
1821
BOOST_FOREACH(DRIZZLE_ERROR* err, session->main_da().m_warn_list)
1872
session->getClient()->store(table_name);
1823
session->getClient()->store(table_name.c_str());
1873
1824
session->getClient()->store(operator_name);
1874
session->getClient()->store(warning_level_names[err->level].str,
1875
warning_level_names[err->level].length);
1825
session->getClient()->store(warning_level_names[err->level].str, warning_level_names[err->level].length);
1876
1826
session->getClient()->store(err->msg);
1877
1827
if (session->getClient()->flush())
1880
drizzle_reset_errors(session, true);
1830
drizzle_reset_errors(*session, true);
1882
session->getClient()->store(table_name);
1832
session->getClient()->store(table_name.c_str());
1883
1833
session->getClient()->store(operator_name);
1885
1835
switch (result_code) {
1954
boost::unique_lock<boost::mutex> lock(table::Cache::singleton().mutex());
1955
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1956
table::Cache::singleton().removeTable(session, identifier, RTFC_NO_FLAG);
1904
boost::unique_lock<boost::mutex> lock(table::Cache::mutex());
1905
identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1906
table::Cache::removeTable(*session, identifier, RTFC_NO_FLAG);
1960
transaction_services.autocommitOrRollback(*session, false);
1910
TransactionServices::autocommitOrRollback(*session, false);
1961
1911
session->endTransaction(COMMIT);
1962
1912
session->close_thread_tables();
1963
1913
table->table=0; // For query cache
1983
1933
Altough exclusive name-lock on target table protects us from concurrent
1984
1934
DML and DDL operations on it we still want to wrap .FRM creation and call
1985
1935
to plugin::StorageEngine::createTable() in critical section protected by
1986
table::Cache::singleton().mutex() in order to provide minimal atomicity against operations which
1936
table::Cache::mutex() in order to provide minimal atomicity against operations which
1987
1937
disregard name-locks, like I_S implementation, for example. This is a
1988
1938
temporary and should not be copied. Instead we should fix our code to
1989
1939
always honor name-locks.
1991
Also some engines (e.g. NDB cluster) require that table::Cache::singleton().mutex() should be held
1941
Also some engines (e.g. NDB cluster) require that table::Cache::mutex() should be held
1992
1942
during the call to plugin::StorageEngine::createTable().
1993
1943
See bug #28614 for more info.
1995
1945
static bool create_table_wrapper(Session &session,
1996
1946
const message::Table& create_table_proto,
1997
identifier::Table::const_reference destination_identifier,
1998
identifier::Table::const_reference source_identifier,
1947
const identifier::Table& destination_identifier,
1948
const identifier::Table& source_identifier,
1999
1949
bool is_engine_set)
2001
1951
// We require an additional table message because during parsing we used
2002
1952
// a "new" message and it will not have all of the information that the
2003
1953
// source table message would have.
2004
1954
message::Table new_table_message;
2005
drizzled::error_t error;
2007
message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier, error);
1956
message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
2009
1958
if (not source_table_message)
2062
2011
if (success && not destination_identifier.isTmp())
2064
TransactionServices &transaction_services= TransactionServices::singleton();
2065
transaction_services.createTable(session, new_table_message);
2013
TransactionServices::createTable(session, new_table_message);
2068
2016
return success;
2086
2034
bool create_like_table(Session* session,
2087
identifier::Table::const_reference destination_identifier,
2088
identifier::Table::const_reference source_identifier,
2035
const identifier::Table& destination_identifier,
2036
const identifier::Table& source_identifier,
2089
2037
message::Table &create_table_proto,
2090
2038
bool is_if_not_exists,
2091
2039
bool is_engine_set)
2114
2062
is_engine_set);
2115
2063
if (not was_created) // This is pretty paranoid, but we assume something might not clean up after itself
2117
(void) session->rm_temporary_table(destination_identifier, true);
2065
(void) session->open_tables.rm_temporary_table(destination_identifier, true);
2119
2067
else if (not session->open_temporary_table(destination_identifier))
2121
2069
// We created, but we can't open... also, a hack.
2122
(void) session->rm_temporary_table(destination_identifier, true);
2070
(void) session->open_tables.rm_temporary_table(destination_identifier, true);
2130
2078
else // Standard table which will require locks.
2132
Table *name_lock= 0;
2134
if (session->lock_table_name_if_not_cached(destination_identifier, &name_lock))
2138
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* unlink open tables for create table like*/
2139
session->unlink_open_table(name_lock);
2080
Table *name_lock= session->lock_table_name_if_not_cached(destination_identifier);
2145
2081
if (not name_lock)
2147
2083
table_exists= true;
2155
2091
bool was_created;
2157
boost_unique_lock_t lock(table::Cache::singleton().mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2093
boost::mutex::scoped_lock lock(table::Cache::mutex()); /* We lock for CREATE TABLE LIKE to copy table definition */
2158
2094
was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2159
2095
source_identifier, is_engine_set);
2202
bool analyze_table(Session* session, TableList* tables, HA_CHECK_OPT* check_opt)
2138
bool analyze_table(Session* session, TableList* tables)
2204
2140
thr_lock_type lock_type = TL_READ_NO_INSERT;
2206
return(admin_table(session, tables, check_opt,
2207
"analyze", lock_type, true,
2208
&Cursor::ha_analyze));
2142
return(admin_table(session, tables, "analyze", lock_type, true, &Cursor::ha_analyze));
2212
bool check_table(Session* session, TableList* tables,HA_CHECK_OPT* check_opt)
2146
bool check_table(Session* session, TableList* tables)
2214
2148
thr_lock_type lock_type = TL_READ_NO_INSERT;
2216
return(admin_table(session, tables, check_opt,
2219
&Cursor::ha_check));
2149
return admin_table(session, tables, "check", lock_type, false, &Cursor::ha_check);
2222
2152
} /* namespace drizzled */