1
/* -*- mode: c++; c-basic-offset: 2; i/dent-tabs-mode: nil; -*-
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
4
* Copyright (C) 2010 Brian Aker
70
70
#include "drizzled/field/decimal.h"
71
71
#include "drizzled/field/real.h"
72
72
#include "drizzled/field/double.h"
73
#include "drizzled/field/int32.h"
74
#include "drizzled/field/int64.h"
73
#include "drizzled/field/long.h"
74
#include "drizzled/field/int64_t.h"
75
75
#include "drizzled/field/num.h"
76
76
#include "drizzled/field/timestamp.h"
77
77
#include "drizzled/field/datetime.h"
78
78
#include "drizzled/field/varstring.h"
79
#include "drizzled/field/uuid.h"
81
#include "drizzled/definition/cache.h"
83
80
using namespace std;
106
103
void TableShare::release(TableShare *share)
108
105
bool to_be_deleted= false;
109
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
106
safe_mutex_assert_owner(LOCK_open.native_handle);
112
109
if (!--share->ref_count)
114
111
to_be_deleted= true;
116
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
117
plugin::EventObserver::deregisterTableEvents(*share);
119
definition::Cache::singleton().erase(identifier);
120
definition::Cache::singleton().erase(share->getCacheKey());
124
void TableShare::release(TableShare::shared_ptr &share)
125
void TableShare::release(TableSharePtr &share)
126
127
bool to_be_deleted= false;
127
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
128
safe_mutex_assert_owner(LOCK_open.native_handle);
130
131
if (!--share->ref_count)
132
133
to_be_deleted= true;
138
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
139
plugin::EventObserver::deregisterTableEvents(*share);
141
definition::Cache::singleton().erase(identifier);
138
definition::Cache::singleton().erase(share->getCacheKey());
142
void TableShare::release(const TableIdentifier &identifier)
147
void TableShare::release(TableIdentifier &identifier)
144
TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
149
TableSharePtr share= definition::Cache::singleton().find(identifier);
147
152
share->version= 0; // Mark for delete
148
153
if (share->ref_count == 0)
150
definition::Cache::singleton().erase(identifier.getKey());
156
plugin::EventObserver::deregisterTableEvents(*share);
157
definition::Cache::singleton().erase(identifier);
156
static TableShare::shared_ptr foundTableShare(TableShare::shared_ptr share)
163
static TableSharePtr foundTableShare(TableSharePtr share)
159
166
We found an existing table definition. Return it if we didn't get
166
173
/* Table definition contained an error */
167
174
share->open_table_error(share->error, share->open_errno, share->errarg);
169
return TableShare::shared_ptr();
176
return TableSharePtr();
172
179
share->incrementTableCount();
197
204
# Share for table
200
TableShare::shared_ptr TableShare::getShareCreate(Session *session,
201
const TableIdentifier &identifier,
207
TableSharePtr TableShare::getShareCreate(Session *session,
208
TableIdentifier &identifier,
204
TableShare::shared_ptr share;
208
215
/* Read table definition from cache */
209
if ((share= definition::Cache::singleton().find(identifier.getKey())))
216
if ((share= definition::Cache::singleton().find(identifier)))
210
217
return foundTableShare(share);
212
219
share.reset(new TableShare(message::Table::STANDARD, identifier));
222
Lock mutex to be able to read table definition from file without
227
bool ret= definition::Cache::singleton().insert(identifier, share);
230
return TableSharePtr();
214
232
if (share->open_table_def(*session, identifier))
216
in_error= share->error;
234
*error= share->error;
235
definition::Cache::singleton().erase(identifier);
218
return TableShare::shared_ptr();
237
return TableSharePtr();
220
239
share->ref_count++; // Mark in use
222
241
plugin::EventObserver::registerTableEvents(*share);
224
bool ret= definition::Cache::singleton().insert(identifier.getKey(), share);
227
return TableShare::shared_ptr();
250
Check if table definition exits in cache
253
get_cached_table_share()
255
table_name Table name
259
# TableShare for table
261
TableSharePtr TableShare::getShare(TableIdentifier &identifier)
263
safe_mutex_assert_owner(LOCK_open.native_handle);
265
return definition::Cache::singleton().find(identifier);
232
268
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
234
270
enum_field_types field_type;
265
301
case message::Table::Field::BLOB:
266
302
field_type= DRIZZLE_TYPE_BLOB;
268
case message::Table::Field::UUID:
269
field_type= DRIZZLE_TYPE_UUID;
273
abort(); // Programming error
305
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
276
309
return field_type;
304
337
default_value->length());
306
339
case DRIZZLE_TYPE_NULL:
309
341
case DRIZZLE_TYPE_TIMESTAMP:
310
342
case DRIZZLE_TYPE_DATETIME:
311
343
case DRIZZLE_TYPE_DATE:
312
344
case DRIZZLE_TYPE_ENUM:
313
case DRIZZLE_TYPE_UUID:
314
345
default_item= new Item_string(default_value->c_str(),
315
346
default_value->length(),
316
347
system_charset_info);
372
TableShare::TableShare(const TableIdentifier::Type type_arg) :
403
TableShare::TableShare(TableIdentifier::Type type_arg) :
373
404
table_category(TABLE_UNKNOWN_CATEGORY),
374
405
found_next_number_field(NULL),
375
406
timestamp_field(NULL),
437
TableShare::TableShare(const TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
472
TableShare::TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
438
473
table_category(TABLE_UNKNOWN_CATEGORY),
439
474
found_next_number_field(NULL),
440
475
timestamp_field(NULL),
500
539
path.str= (char *)"";
501
540
normalized_path.str= path.str;
502
541
path.length= normalized_path.length= 0;
504
std::string tb_name(identifier.getTableName());
505
std::transform(tb_name.begin(), tb_name.end(), tb_name.begin(), ::tolower);
506
assert(strcmp(tb_name.c_str(), table_name.str) == 0);
542
assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
508
543
assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
585
624
Used for shares that will go into the cache.
587
TableShare::TableShare(const TableIdentifier::Type type_arg,
588
const TableIdentifier &identifier,
626
TableShare::TableShare(TableIdentifier::Type type_arg,
627
TableIdentifier &identifier,
590
629
uint32_t path_length_arg) :
591
630
table_category(TABLE_UNKNOWN_CATEGORY),
697
739
assert(ref_count == 0);
742
If someone is waiting for this to be deleted, inform it about this.
743
Don't do a delete until we know that no one is refering to this anymore.
745
if (tmp_table == message::Table::STANDARD)
747
/* share->mutex is locked in release_table_share() */
748
while (waiting_on_cond)
751
boost::mutex::scoped_lock scoped(mutex, boost::adopt_lock_t());
755
/* No thread refers to this anymore */
699
759
storage_engine= NULL;
701
761
delete table_proto;
702
762
table_proto= NULL;
704
plugin::EventObserver::deregisterTableEvents(*this);
706
764
mem_root.free_root(MYF(0)); // Free's share
709
void TableShare::setIdentifier(const TableIdentifier &identifier_arg)
767
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
711
769
private_key_for_cache= identifier_arg.getKey();
934
992
uint32_t local_null_fields= 0;
937
std::vector<uint32_t> field_offsets;
938
std::vector<uint32_t> field_pack_length;
995
vector<uint32_t> field_offsets;
996
vector<uint32_t> field_pack_length;
940
998
field_offsets.resize(fields);
941
999
field_pack_length.resize(fields);
1135
1193
unireg_type= Field::TIMESTAMP_DN_FIELD;
1139
assert(0); // Invalid update value.
1196
assert(1); // Invalid update value.
1143
1198
else if (pfield.has_options() &&
1144
1199
pfield.options().has_update_expression() &&
1315
1371
case DRIZZLE_TYPE_LONGLONG:
1316
1372
field_length= MAX_BIGINT_WIDTH;
1318
case DRIZZLE_TYPE_UUID:
1319
field_length= field::Uuid::max_string_length();
1321
1374
case DRIZZLE_TYPE_NULL:
1322
1375
abort(); // Programming error
1325
assert(enum_field_types_size == 12);
1327
1378
Field* f= make_field(record + field_offsets[fieldnr] + data_offset,
1329
pfield.constraints().is_nullable(),
1335
MTYP_TYPENR(unireg_type),
1336
((field_type == DRIZZLE_TYPE_ENUM) ? &intervals[interval_nr++] : (TYPELIB*) 0),
1337
getTableProto()->field(fieldnr).name().c_str());
1380
pfield.constraints().is_nullable(),
1386
(Field::utype) MTYP_TYPENR(unireg_type),
1387
((field_type == DRIZZLE_TYPE_ENUM) ?
1388
&intervals[interval_nr++]
1390
getTableProto()->field(fieldnr).name().c_str());
1339
1392
field[fieldnr]= f;
1341
// Insert post make_field code here.
1344
case DRIZZLE_TYPE_BLOB:
1345
case DRIZZLE_TYPE_VARCHAR:
1346
case DRIZZLE_TYPE_DOUBLE:
1347
case DRIZZLE_TYPE_DECIMAL:
1348
case DRIZZLE_TYPE_TIMESTAMP:
1349
case DRIZZLE_TYPE_DATETIME:
1350
case DRIZZLE_TYPE_DATE:
1351
case DRIZZLE_TYPE_ENUM:
1352
case DRIZZLE_TYPE_LONG:
1353
case DRIZZLE_TYPE_LONGLONG:
1354
case DRIZZLE_TYPE_NULL:
1355
case DRIZZLE_TYPE_UUID:
1359
1394
// This needs to go, we should be setting the "use" on the field so that
1360
1395
// it does not reference the share/table.
1361
1396
table::Shell temp_table(*this); /* Use this so that BLOB DEFAULT '' works */
1385
1420
return local_error;
1388
else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
1423
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
1424
(f->flags & NOT_NULL_FLAG))
1390
1426
f->set_notnull();
1391
1427
f->store((int64_t) 1, true);
1412
1448
if (f->unireg_check == Field::NEXT_NUMBER)
1413
1449
found_next_number_field= &(field[fieldnr]);
1451
if (timestamp_field == f)
1452
timestamp_field_offset= fieldnr;
1415
1454
if (use_hash) /* supposedly this never fails... but comments lie */
1417
1456
const char *local_field_name= field[fieldnr]->field_name;
1418
1457
name_hash.insert(make_pair(local_field_name, &(field[fieldnr])));
1422
1462
keyinfo= key_info;
1845
1887
outparam.found_next_number_field=
1846
1888
outparam.getField(positionFields(found_next_number_field));
1847
1889
if (timestamp_field)
1848
outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field->position());
1890
outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field_offset);
1850
1893
/* Fix key->name and key_part->field */
2055
2097
case DRIZZLE_TYPE_VARCHAR:
2056
2098
setVariableWidth();
2057
2099
return new (&mem_root) Field_varstring(ptr,field_length,
2058
ha_varchar_packlength(field_length),
2100
HA_VARCHAR_PACKLENGTH(field_length),
2059
2101
null_pos,null_bit,
2061
2103
field_charset);
2110
calc_pack_length(DRIZZLE_TYPE_LONG, 0),
2068
2111
field_charset);
2069
2112
case DRIZZLE_TYPE_DECIMAL:
2070
2113
return new (&mem_root) Field_decimal(ptr,
2088
2131
false /* is_unsigned */);
2089
case DRIZZLE_TYPE_UUID:
2090
return new (&mem_root) field::Uuid(ptr,
2095
2132
case DRIZZLE_TYPE_LONG:
2096
return new (&mem_root) field::Int32(ptr,
2133
return new (&mem_root) Field_long(ptr,
2140
false /* is_unsigned */);
2102
2141
case DRIZZLE_TYPE_LONGLONG:
2103
return new (&mem_root) field::Int64(ptr,
2142
return new (&mem_root) Field_int64_t(ptr,
2149
false /* is_unsigned */);
2109
2150
case DRIZZLE_TYPE_TIMESTAMP:
2110
2151
return new (&mem_root) Field_timestamp(ptr,