40
#include "drizzled/error.h"
41
#include "drizzled/gettext.h"
42
#include "drizzled/sql_base.h"
43
#include "drizzled/pthread_globals.h"
44
#include "drizzled/internal/my_pthread.h"
45
#include "drizzled/plugin/event_observer.h"
47
#include "drizzled/table.h"
48
#include "drizzled/table/shell.h"
50
#include "drizzled/session.h"
52
#include "drizzled/charset.h"
53
#include "drizzled/internal/m_string.h"
54
#include "drizzled/internal/my_sys.h"
56
#include "drizzled/item/string.h"
57
#include "drizzled/item/int.h"
58
#include "drizzled/item/decimal.h"
59
#include "drizzled/item/float.h"
60
#include "drizzled/item/null.h"
61
#include "drizzled/temporal.h"
63
#include "drizzled/field.h"
64
#include "drizzled/field/str.h"
65
#include "drizzled/field/num.h"
66
#include "drizzled/field/blob.h"
67
#include "drizzled/field/enum.h"
68
#include "drizzled/field/null.h"
69
#include "drizzled/field/date.h"
70
#include "drizzled/field/decimal.h"
71
#include "drizzled/field/real.h"
72
#include "drizzled/field/double.h"
73
#include "drizzled/field/long.h"
74
#include "drizzled/field/int64_t.h"
75
#include "drizzled/field/num.h"
76
#include "drizzled/field/timestamp.h"
77
#include "drizzled/field/datetime.h"
78
#include "drizzled/field/varstring.h"
40
#include <drizzled/error.h>
41
#include <drizzled/gettext.h>
42
#include <drizzled/sql_base.h>
43
#include <drizzled/pthread_globals.h>
44
#include <drizzled/internal/my_pthread.h>
46
#include <drizzled/table.h>
47
#include <drizzled/table/shell.h>
49
#include <drizzled/session.h>
51
#include <drizzled/charset.h>
52
#include <drizzled/internal/m_string.h>
53
#include <drizzled/internal/my_sys.h>
55
#include <drizzled/item/string.h>
56
#include <drizzled/item/int.h>
57
#include <drizzled/item/decimal.h>
58
#include <drizzled/item/float.h>
59
#include <drizzled/item/null.h>
60
#include <drizzled/temporal.h>
62
#include <drizzled/field.h>
63
#include <drizzled/field/str.h>
64
#include <drizzled/field/num.h>
65
#include <drizzled/field/blob.h>
66
#include <drizzled/field/boolean.h>
67
#include <drizzled/field/enum.h>
68
#include <drizzled/field/null.h>
69
#include <drizzled/field/date.h>
70
#include <drizzled/field/decimal.h>
71
#include <drizzled/field/real.h>
72
#include <drizzled/field/double.h>
73
#include <drizzled/field/int32.h>
74
#include <drizzled/field/int64.h>
75
#include <drizzled/field/size.h>
76
#include <drizzled/field/num.h>
77
#include <drizzled/field/time.h>
78
#include <drizzled/field/epoch.h>
79
#include <drizzled/field/datetime.h>
80
#include <drizzled/field/microtime.h>
81
#include <drizzled/field/varstring.h>
82
#include <drizzled/field/uuid.h>
84
#include <drizzled/plugin/storage_engine.h>
86
#include <drizzled/definition/cache.h>
87
#include <drizzled/typelib.h>
89
#include <drizzled/refresh_version.h>
80
91
using namespace std;
85
96
extern size_t table_def_size;
86
static TableDefinitionCache table_def_cache;
88
/*****************************************************************************
89
Functions to handle table definition cach (TableShare)
90
*****************************************************************************/
93
// @todo switch this a boost::thread one only call.
94
void TableShare::cacheStart(void)
97
* This is going to overalloc a bit - as rehash sets the number of
98
* buckets, not the number of elements. BUT, it'll allow us to not need
99
* to rehash later on as the unordered_map grows.
101
table_def_cache.rehash(table_def_size);
106
* @TODO This should return size_t
108
uint32_t cached_table_definitions(void)
110
return static_cast<uint32_t>(table_def_cache.size());
115
Mark that we are not using table share anymore.
122
If ref_count goes to zero and (we have done a refresh or if we have
123
already too many open table shares) then delete the definition.
126
void TableShare::release(TableShare *share)
128
bool to_be_deleted= false;
129
safe_mutex_assert_owner(LOCK_open.native_handle);
132
if (!--share->ref_count)
139
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
140
plugin::EventObserver::deregisterTableEvents(*share);
142
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
143
if (iter != table_def_cache.end())
145
table_def_cache.erase(iter);
152
void TableShare::release(TableSharePtr &share)
154
bool to_be_deleted= false;
155
safe_mutex_assert_owner(LOCK_open.native_handle);
158
if (!--share->ref_count)
165
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
166
plugin::EventObserver::deregisterTableEvents(*share);
168
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
169
if (iter != table_def_cache.end())
171
table_def_cache.erase(iter);
178
void TableShare::release(TableIdentifier &identifier)
180
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
181
if (iter != table_def_cache.end())
183
TableSharePtr share= (*iter).second;
184
share->version= 0; // Mark for delete
185
if (share->ref_count == 0)
188
plugin::EventObserver::deregisterTableEvents(*share);
189
table_def_cache.erase(identifier.getKey());
195
static TableSharePtr foundTableShare(TableSharePtr share)
198
We found an existing table definition. Return it if we didn't get
199
an error when reading the table definition from file.
202
/* We must do a lock to ensure that the structure is initialized */
205
/* Table definition contained an error */
206
share->open_table_error(share->error, share->open_errno, share->errarg);
208
return TableSharePtr();
211
share->incrementTableCount();
217
Get TableShare for a table.
220
session Thread handle
221
table_list Table that should be opened
223
key_length Length of key
224
error out: Error code from open_table_def()
227
Get a table definition from the table definition cache.
228
If it doesn't exist, create a new from the table definition file.
231
We must have wrlock on LOCK_open when we come here
232
(To be changed later)
239
TableSharePtr TableShare::getShareCreate(Session *session,
240
TableIdentifier &identifier,
247
/* Read table definition from cache */
248
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
249
if (iter != table_def_cache.end())
251
share= (*iter).second;
252
return foundTableShare(share);
255
share.reset(new TableShare(message::Table::STANDARD, identifier));
258
Lock mutex to be able to read table definition from file without
263
pair<TableDefinitionCache::iterator, bool> ret=
264
table_def_cache.insert(make_pair(identifier.getKey(), share));
265
if (ret.second == false)
267
return TableSharePtr();
270
if (share->open_table_def(*session, identifier))
272
*error= share->error;
273
table_def_cache.erase(identifier.getKey());
275
return TableSharePtr();
277
share->ref_count++; // Mark in use
279
plugin::EventObserver::registerTableEvents(*share);
288
Check if table definition exits in cache
291
get_cached_table_share()
293
table_name Table name
297
# TableShare for table
299
TableSharePtr TableShare::getShare(TableIdentifier &identifier)
301
safe_mutex_assert_owner(LOCK_open.native_handle);
303
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
304
if (iter != table_def_cache.end())
306
return (*iter).second;
309
return TableSharePtr();
312
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
314
enum_field_types field_type;
316
switch(proto_field_type)
99
static enum_field_types proto_field_type_to_drizzle_type(const message::Table::Field &field)
318
103
case message::Table::Field::INTEGER:
319
field_type= DRIZZLE_TYPE_LONG;
104
return DRIZZLE_TYPE_LONG;
321
106
case message::Table::Field::DOUBLE:
322
field_type= DRIZZLE_TYPE_DOUBLE;
324
case message::Table::Field::TIMESTAMP:
325
field_type= DRIZZLE_TYPE_TIMESTAMP;
107
return DRIZZLE_TYPE_DOUBLE;
109
case message::Table::Field::EPOCH:
110
if (field.has_time_options() and field.time_options().microseconds())
111
return DRIZZLE_TYPE_MICROTIME;
113
return DRIZZLE_TYPE_TIMESTAMP;
327
115
case message::Table::Field::BIGINT:
328
field_type= DRIZZLE_TYPE_LONGLONG;
116
return DRIZZLE_TYPE_LONGLONG;
330
118
case message::Table::Field::DATETIME:
331
field_type= DRIZZLE_TYPE_DATETIME;
119
return DRIZZLE_TYPE_DATETIME;
333
121
case message::Table::Field::DATE:
334
field_type= DRIZZLE_TYPE_DATE;
122
return DRIZZLE_TYPE_DATE;
336
124
case message::Table::Field::VARCHAR:
337
field_type= DRIZZLE_TYPE_VARCHAR;
125
return DRIZZLE_TYPE_VARCHAR;
339
127
case message::Table::Field::DECIMAL:
340
field_type= DRIZZLE_TYPE_DECIMAL;
128
return DRIZZLE_TYPE_DECIMAL;
342
130
case message::Table::Field::ENUM:
343
field_type= DRIZZLE_TYPE_ENUM;
131
return DRIZZLE_TYPE_ENUM;
345
133
case message::Table::Field::BLOB:
346
field_type= DRIZZLE_TYPE_BLOB;
349
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
134
return DRIZZLE_TYPE_BLOB;
136
case message::Table::Field::UUID:
137
return DRIZZLE_TYPE_UUID;
139
case message::Table::Field::BOOLEAN:
140
return DRIZZLE_TYPE_BOOLEAN;
142
case message::Table::Field::TIME:
143
return DRIZZLE_TYPE_TIME;
356
149
static Item *default_value_item(enum_field_types field_type,
352
blob_ptr_size(portable_sizeof_char_ptr),
566
353
db_low_byte_first(false),
568
replace_with_name_lock(false),
569
waiting_on_cond(false),
572
event_observers(NULL)
574
357
assert(identifier.getKey() == key);
577
memset(&path, 0, sizeof(LEX_STRING));
578
memset(&normalized_path, 0, sizeof(LEX_STRING));
580
359
private_key_for_cache= key;
582
361
table_category= TABLE_CATEGORY_TEMPORARY;
583
362
tmp_table= message::Table::INTERNAL;
585
db.str= &private_key_for_cache[0];
586
db.length= strlen(&private_key_for_cache[0]);
364
db.str= const_cast<char *>(private_key_for_cache.vector());
365
db.length= strlen(private_key_for_cache.vector());
588
table_name.str= &private_key_for_cache[0] + strlen(&private_key_for_cache[0]) + 1;
367
table_name.str= const_cast<char *>(private_key_for_cache.vector()) + strlen(private_key_for_cache.vector()) + 1;
589
368
table_name.length= strlen(table_name.str);
590
369
path.str= (char *)"";
591
370
normalized_path.str= path.str;
592
371
path.length= normalized_path.length= 0;
593
assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
373
std::string tb_name(identifier.getTableName());
374
std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
375
assert(strcmp(tb_name.c_str(), table_name.str) == 0);
594
377
assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
598
TableShare::TableShare(const TableIdentifier &identifier) : // Just used during createTable()
381
TableShare::TableShare(const identifier::Table &identifier) : // Just used during createTable()
599
382
table_category(TABLE_UNKNOWN_CATEGORY),
601
383
found_next_number_field(NULL),
602
384
timestamp_field(NULL),
604
386
mem_root(TABLE_ALLOC_BLOCK_SIZE),
390
table_name(NULL_LEX_STRING),
391
path(NULL_LEX_STRING),
392
normalized_path(NULL_LEX_STRING),
608
395
timestamp_offset(0),
610
397
stored_rec_length(0),
399
_table_message(NULL),
613
400
storage_engine(NULL),
614
401
tmp_table(identifier.getType()),
617
404
last_null_bit_pos(0),
619
406
rec_buff_length(0),
790
560
TableShare::~TableShare()
792
assert(ref_count == 0);
795
If someone is waiting for this to be deleted, inform it about this.
796
Don't do a delete until we know that no one is refering to this anymore.
798
if (tmp_table == message::Table::STANDARD)
800
/* share->mutex is locked in release_table_share() */
801
while (waiting_on_cond)
804
boost::mutex::scoped_lock scoped(mutex, boost::adopt_lock_t());
808
/* No thread refers to this anymore */
812
562
storage_engine= NULL;
817
564
mem_root.free_root(MYF(0)); // Free's share
820
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
567
void TableShare::setIdentifier(const identifier::Table &identifier_arg)
822
private_key_for_cache.clear();
823
569
private_key_for_cache= identifier_arg.getKey();
826
572
Let us use the fact that the key is "db/0/table_name/0" + optional
827
573
part for temporary tables.
829
db.str= &private_key_for_cache[0];
575
db.str= const_cast<char *>(private_key_for_cache.vector());
830
576
db.length= strlen(db.str);
831
577
table_name.str= db.str + db.length + 1;
832
578
table_name.length= strlen(table_name.str);
834
table_proto->set_name(identifier_arg.getTableName());
835
table_proto->set_schema(identifier_arg.getSchemaName());
580
getTableMessage()->set_name(identifier_arg.getTableName());
581
getTableMessage()->set_schema(identifier_arg.getSchemaName());
838
int TableShare::inner_parse_table_proto(Session& session, message::Table &table)
584
bool TableShare::parse_table_proto(Session& session, message::Table &table)
586
drizzled::error_t local_error= EE_OK;
842
588
if (! table.IsInitialized())
844
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
590
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0),
591
table.name().empty() ? " " : table.name().c_str(),
592
table.InitializationErrorString().c_str());
845
594
return ER_CORRUPT_TABLE_DEFINITION;
848
setTableProto(new(nothrow) message::Table(table));
597
setTableMessage(table);
850
599
storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
851
600
assert(storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
1038
780
keys_for_keyread.reset();
1039
781
set_prefix(keys_in_use, keys);
1041
fields= table.field_size();
783
_field_size= table.field_size();
1043
setFields(fields + 1);
1044
field[fields]= NULL;
785
setFields(_field_size + 1);
786
_fields[_field_size]= NULL;
1046
788
uint32_t local_null_fields= 0;
1049
vector<uint32_t> field_offsets;
1050
vector<uint32_t> field_pack_length;
791
std::vector<uint32_t> field_offsets;
792
std::vector<uint32_t> field_pack_length;
1052
field_offsets.resize(fields);
1053
field_pack_length.resize(fields);
794
field_offsets.resize(_field_size);
795
field_pack_length.resize(_field_size);
1055
797
uint32_t interval_count= 0;
1056
798
uint32_t interval_parts= 0;
1058
800
uint32_t stored_columns_reclength= 0;
1060
for (unsigned int fieldnr= 0; fieldnr < fields; fieldnr++)
802
for (unsigned int fieldnr= 0; fieldnr < _field_size; fieldnr++)
1062
804
message::Table::Field pfield= table.field(fieldnr);
1063
if (pfield.constraints().is_nullable())
1064
local_null_fields++;
805
if (pfield.constraints().is_nullable()) // Historical reference
809
else if (not pfield.constraints().is_notnull())
1066
enum_field_types drizzle_field_type=
1067
proto_field_type_to_drizzle_type(pfield.type());
814
enum_field_types drizzle_field_type= proto_field_type_to_drizzle_type(pfield);
1069
816
field_offsets[fieldnr]= stored_columns_reclength;
1425
1165
case DRIZZLE_TYPE_LONGLONG:
1426
field_length= MAX_BIGINT_WIDTH;
1167
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
1168
field_length= MAX_BIGINT_WIDTH+sign_len;
1171
case DRIZZLE_TYPE_UUID:
1172
field_length= field::Uuid::max_string_length();
1174
case DRIZZLE_TYPE_BOOLEAN:
1175
field_length= field::Boolean::max_string_length();
1177
case DRIZZLE_TYPE_MICROTIME:
1178
field_length= field::Microtime::max_string_length();
1180
case DRIZZLE_TYPE_TIMESTAMP:
1181
field_length= field::Epoch::max_string_length();
1183
case DRIZZLE_TYPE_TIME:
1184
field_length= field::Time::max_string_length();
1428
1186
case DRIZZLE_TYPE_NULL:
1429
1187
abort(); // Programming error
1432
Field* f= make_field(record + field_offsets[fieldnr] + data_offset,
1434
pfield.constraints().is_nullable(),
1440
(Field::utype) MTYP_TYPENR(unireg_type),
1441
((field_type == DRIZZLE_TYPE_ENUM) ?
1442
&intervals[interval_nr++]
1444
getTableProto()->field(fieldnr).name().c_str());
1190
bool is_not_null= false;
1192
if (not pfield.constraints().is_nullable())
1196
else if (pfield.constraints().is_notnull())
1201
Field* f= make_field(pfield,
1202
record + field_offsets[fieldnr] + data_offset,
1210
MTYP_TYPENR(unireg_type),
1211
((field_type == DRIZZLE_TYPE_ENUM) ? &intervals[interval_nr++] : (TYPELIB*) 0),
1212
getTableMessage()->field(fieldnr).name().c_str());
1214
_fields[fieldnr]= f;
1216
// Insert post make_field code here.
1219
case DRIZZLE_TYPE_BLOB:
1220
case DRIZZLE_TYPE_VARCHAR:
1221
case DRIZZLE_TYPE_DOUBLE:
1222
case DRIZZLE_TYPE_DECIMAL:
1223
case DRIZZLE_TYPE_TIMESTAMP:
1224
case DRIZZLE_TYPE_TIME:
1225
case DRIZZLE_TYPE_DATETIME:
1226
case DRIZZLE_TYPE_MICROTIME:
1227
case DRIZZLE_TYPE_DATE:
1228
case DRIZZLE_TYPE_ENUM:
1229
case DRIZZLE_TYPE_LONG:
1230
case DRIZZLE_TYPE_LONGLONG:
1231
case DRIZZLE_TYPE_NULL:
1232
case DRIZZLE_TYPE_UUID:
1233
case DRIZZLE_TYPE_BOOLEAN:
1448
1237
// This needs to go, we should be setting the "use" on the field so that
1449
1238
// it does not reference the share/table.
1760
1526
6 Unknown .frm version
1763
int TableShare::open_table_def(Session& session, TableIdentifier &identifier)
1529
int TableShare::open_table_def(Session& session, const identifier::Table &identifier)
1771
message::Table table;
1773
local_error= plugin::StorageEngine::getTableDefinition(session, identifier, table);
1775
if (local_error != EEXIST)
1531
drizzled::error_t local_error= EE_OK;
1533
message::table::shared_ptr table= plugin::StorageEngine::getTableMessage(session, identifier, local_error);
1535
if (table and table->IsInitialized())
1777
if (local_error > 0)
1537
if (parse_table_proto(session, *table))
1539
local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
1540
my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
1784
if (not table.IsInitialized())
1544
setTableCategory(TABLE_CATEGORY_USER);
1792
local_error= parse_table_proto(session, table);
1794
setTableCategory(TABLE_CATEGORY_USER);
1797
if (local_error && !error_given)
1800
open_table_error(error, (open_errno= errno), 0);
1548
else if (table and not table->IsInitialized())
1550
local_error= ER_CORRUPT_TABLE_DEFINITION_UNKNOWN;
1551
my_error(ER_CORRUPT_TABLE_DEFINITION_UNKNOWN, identifier);
1555
local_error= ER_TABLE_UNKNOWN;
1556
my_error(ER_TABLE_UNKNOWN, identifier);
1559
return static_cast<int>(local_error);
2189
1958
false /* is_unsigned */);
1959
case DRIZZLE_TYPE_UUID:
1960
return new (&mem_root) field::Uuid(ptr,
1965
case DRIZZLE_TYPE_BOOLEAN:
1966
return new (&mem_root) field::Boolean(ptr,
2190
1972
case DRIZZLE_TYPE_LONG:
2191
return new (&mem_root) Field_long(ptr,
2198
false /* is_unsigned */);
1973
return new (&mem_root) field::Int32(ptr,
2199
1979
case DRIZZLE_TYPE_LONGLONG:
2200
return new (&mem_root) Field_int64_t(ptr,
2207
false /* is_unsigned */);
1983
return new (&mem_root) field::Size(ptr,
1991
return new (&mem_root) field::Int64(ptr,
1998
case DRIZZLE_TYPE_MICROTIME:
1999
return new (&mem_root) field::Microtime(ptr,
2208
2005
case DRIZZLE_TYPE_TIMESTAMP:
2209
return new (&mem_root) Field_timestamp(ptr,
2006
return new (&mem_root) field::Epoch(ptr,
2012
case DRIZZLE_TYPE_TIME:
2013
return new (&mem_root) field::Time(ptr,
2217
2018
case DRIZZLE_TYPE_DATE:
2218
2019
return new (&mem_root) Field_date(ptr,
2223
2023
case DRIZZLE_TYPE_DATETIME:
2224
2024
return new (&mem_root) Field_datetime(ptr,
2229
2028
case DRIZZLE_TYPE_NULL:
2230
2029
return new (&mem_root) Field_null(ptr,
2234
default: // Impossible (Wrong version)
2037
void TableShare::refreshVersion()
2039
version= refresh_version;