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
44
44
#include "drizzled/internal/my_pthread.h"
45
45
#include "drizzled/plugin/event_observer.h"
47
#include "drizzled/table.h"
48
#include "drizzled/table/shell.h"
50
47
#include "drizzled/session.h"
52
49
#include "drizzled/charset.h"
70
67
#include "drizzled/field/decimal.h"
71
68
#include "drizzled/field/real.h"
72
69
#include "drizzled/field/double.h"
73
#include "drizzled/field/int32.h"
74
#include "drizzled/field/int64.h"
70
#include "drizzled/field/long.h"
71
#include "drizzled/field/int64_t.h"
75
72
#include "drizzled/field/num.h"
76
73
#include "drizzled/field/timestamp.h"
77
74
#include "drizzled/field/datetime.h"
78
75
#include "drizzled/field/varstring.h"
79
#include "drizzled/field/uuid.h"
81
#include "drizzled/definition/cache.h"
83
77
using namespace std;
88
82
extern size_t table_def_size;
83
static TableDefinitionCache table_def_cache;
90
85
/*****************************************************************************
91
86
Functions to handle table definition cach (TableShare)
92
87
*****************************************************************************/
90
// @todo switch this a boost::thread one only call.
91
void TableShare::cacheStart(void)
94
* This is going to overalloc a bit - as rehash sets the number of
95
* buckets, not the number of elements. BUT, it'll allow us to not need
96
* to rehash later on as the unordered_map grows.
98
table_def_cache.rehash(table_def_size);
103
* @TODO This should return size_t
105
uint32_t cached_table_definitions(void)
107
return static_cast<uint32_t>(table_def_cache.size());
95
112
Mark that we are not using table share anymore.
106
123
void TableShare::release(TableShare *share)
108
125
bool to_be_deleted= false;
109
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
112
if (!--share->ref_count)
120
definition::Cache::singleton().erase(share->getCacheKey());
124
void TableShare::release(TableShare::shared_ptr &share)
126
bool to_be_deleted= false;
127
safe_mutex_assert_owner(table::Cache::singleton().mutex().native_handle);
130
if (!--share->ref_count)
138
definition::Cache::singleton().erase(share->getCacheKey());
142
void TableShare::release(const TableIdentifier &identifier)
144
TableShare::shared_ptr share= definition::Cache::singleton().find(identifier.getKey());
126
safe_mutex_assert_owner(LOCK_open.native_handle);
129
if (!--share->ref_count)
136
TableIdentifier identifier(share->getSchemaName(), share->getTableName());
137
plugin::EventObserver::deregisterTableEvents(*share);
139
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
140
if (iter != table_def_cache.end())
142
table_def_cache.erase(iter);
150
void TableShare::release(TableIdentifier &identifier)
152
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
153
if (iter != table_def_cache.end())
155
TableShare *share= (*iter).second;
147
156
share->version= 0; // Mark for delete
148
157
if (share->ref_count == 0)
150
definition::Cache::singleton().erase(identifier.getKey());
160
plugin::EventObserver::deregisterTableEvents(*share);
161
table_def_cache.erase(identifier.getKey());
156
static TableShare::shared_ptr foundTableShare(TableShare::shared_ptr share)
168
static TableShare *foundTableShare(TableShare *share)
159
171
We found an existing table definition. Return it if we didn't get
166
178
/* Table definition contained an error */
167
179
share->open_table_error(share->error, share->open_errno, share->errarg);
169
return TableShare::shared_ptr();
172
184
share->incrementTableCount();
197
209
# Share for table
200
TableShare::shared_ptr TableShare::getShareCreate(Session *session,
201
const TableIdentifier &identifier,
212
TableShare *TableShare::getShareCreate(Session *session,
213
TableIdentifier &identifier,
204
TableShare::shared_ptr share;
216
TableShare *share= NULL;
208
220
/* Read table definition from cache */
209
if ((share= definition::Cache::singleton().find(identifier.getKey())))
221
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
222
if (iter != table_def_cache.end())
224
share= (*iter).second;
210
225
return foundTableShare(share);
212
share.reset(new TableShare(message::Table::STANDARD, identifier));
228
if (not (share= new TableShare(message::Table::STANDARD, identifier)))
234
Lock mutex to be able to read table definition from file without
240
* @TODO: we need to eject something if we exceed table_def_size
242
pair<TableDefinitionCache::iterator, bool> ret=
243
table_def_cache.insert(make_pair(identifier.getKey(), share));
244
if (ret.second == false)
214
251
if (share->open_table_def(*session, identifier))
216
in_error= share->error;
253
*error= share->error;
254
table_def_cache.erase(identifier.getKey());
218
return TableShare::shared_ptr();
220
259
share->ref_count++; // Mark in use
222
261
plugin::EventObserver::registerTableEvents(*share);
224
bool ret= definition::Cache::singleton().insert(identifier.getKey(), share);
227
return TableShare::shared_ptr();
270
Check if table definition exits in cache
273
get_cached_table_share()
275
table_name Table name
279
# TableShare for table
281
TableShare *TableShare::getShare(TableIdentifier &identifier)
283
safe_mutex_assert_owner(LOCK_open.native_handle);
285
TableDefinitionCache::iterator iter= table_def_cache.find(identifier.getKey());
286
if (iter != table_def_cache.end())
288
return (*iter).second;
232
296
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
234
298
enum_field_types field_type;
265
329
case message::Table::Field::BLOB:
266
330
field_type= DRIZZLE_TYPE_BLOB;
268
case message::Table::Field::UUID:
269
field_type= DRIZZLE_TYPE_UUID;
273
abort(); // Programming error
333
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
276
337
return field_type;
304
365
default_value->length());
306
367
case DRIZZLE_TYPE_NULL:
309
369
case DRIZZLE_TYPE_TIMESTAMP:
310
370
case DRIZZLE_TYPE_DATETIME:
311
371
case DRIZZLE_TYPE_DATE:
312
372
case DRIZZLE_TYPE_ENUM:
313
case DRIZZLE_TYPE_UUID:
314
373
default_item= new Item_string(default_value->c_str(),
315
374
default_value->length(),
316
375
system_charset_info);
372
TableShare::TableShare(const TableIdentifier::Type type_arg) :
431
const TableDefinitionCache &TableShare::getCache()
433
return table_def_cache;
436
TableShare::TableShare(TableIdentifier::Type type_arg) :
373
437
table_category(TABLE_UNKNOWN_CATEGORY),
374
439
found_next_number_field(NULL),
375
440
timestamp_field(NULL),
377
442
mem_root(TABLE_ALLOC_BLOCK_SIZE),
381
445
timestamp_offset(0),
426
495
if (type_arg == message::Table::INTERNAL)
428
TableIdentifier::build_tmptable_filename(private_key_for_cache.vectorPtr());
429
init(private_key_for_cache.vector(), private_key_for_cache.vector());
497
TableIdentifier::build_tmptable_filename(private_key_for_cache);
498
init(&private_key_for_cache[0], &private_key_for_cache[0]);
437
TableShare::TableShare(const TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
506
TableShare::TableShare(TableIdentifier &identifier, const TableIdentifier::Key &key) :// Used by placeholder
438
507
table_category(TABLE_UNKNOWN_CATEGORY),
439
509
found_next_number_field(NULL),
440
510
timestamp_field(NULL),
442
512
mem_root(TABLE_ALLOC_BLOCK_SIZE),
446
515
timestamp_offset(0),
492
566
table_category= TABLE_CATEGORY_TEMPORARY;
493
567
tmp_table= message::Table::INTERNAL;
495
db.str= const_cast<char *>(private_key_for_cache.vector());
496
db.length= strlen(private_key_for_cache.vector());
569
db.str= &private_key_for_cache[0];
570
db.length= strlen(&private_key_for_cache[0]);
498
table_name.str= const_cast<char *>(private_key_for_cache.vector()) + strlen(private_key_for_cache.vector()) + 1;
572
table_name.str= &private_key_for_cache[0] + strlen(&private_key_for_cache[0]) + 1;
499
573
table_name.length= strlen(table_name.str);
500
574
path.str= (char *)"";
501
575
normalized_path.str= path.str;
502
576
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);
577
assert(strcmp(identifier.getTableName().c_str(), table_name.str) == 0);
508
578
assert(strcmp(identifier.getSchemaName().c_str(), db.str) == 0);
512
582
TableShare::TableShare(const TableIdentifier &identifier) : // Just used during createTable()
513
583
table_category(TABLE_UNKNOWN_CATEGORY),
514
585
found_next_number_field(NULL),
515
586
timestamp_field(NULL),
517
588
mem_root(TABLE_ALLOC_BLOCK_SIZE),
521
591
timestamp_offset(0),
571
646
table_category= TABLE_CATEGORY_TEMPORARY;
572
647
tmp_table= message::Table::INTERNAL;
573
db.str= const_cast<char *>(private_key_for_cache.vector());
574
db.length= strlen(private_key_for_cache.vector());
648
db.str= &private_key_for_cache[0];
649
db.length= strlen(&private_key_for_cache[0]);
575
650
table_name.str= db.str + 1;
576
651
table_name.length= strlen(table_name.str);
577
652
path.str= &private_normalized_path[0];
585
660
Used for shares that will go into the cache.
587
TableShare::TableShare(const TableIdentifier::Type type_arg,
588
const TableIdentifier &identifier,
662
TableShare::TableShare(TableIdentifier::Type type_arg,
663
TableIdentifier &identifier,
590
665
uint32_t path_length_arg) :
591
666
table_category(TABLE_UNKNOWN_CATEGORY),
592
668
found_next_number_field(NULL),
593
669
timestamp_field(NULL),
595
671
mem_root(TABLE_ALLOC_BLOCK_SIZE),
599
674
timestamp_offset(0),
648
728
Let us use the fact that the key is "db/0/table_name/0" + optional
649
729
part for temporary tables.
651
db.str= const_cast<char *>(private_key_for_cache.vector());
731
db.str= &private_key_for_cache[0];
652
732
db.length= strlen(db.str);
653
733
table_name.str= db.str + db.length + 1;
654
734
table_name.length= strlen(table_name.str);
697
776
assert(ref_count == 0);
779
If someone is waiting for this to be deleted, inform it about this.
780
Don't do a delete until we know that no one is refering to this anymore.
782
if (tmp_table == message::Table::STANDARD)
784
/* share->mutex is locked in release_table_share() */
785
while (waiting_on_cond)
788
boost::mutex::scoped_lock scoped(mutex, boost::adopt_lock_t());
792
/* No thread refers to this anymore */
699
796
storage_engine= NULL;
701
798
delete table_proto;
702
799
table_proto= NULL;
704
plugin::EventObserver::deregisterTableEvents(*this);
706
801
mem_root.free_root(MYF(0)); // Free's share
709
void TableShare::setIdentifier(const TableIdentifier &identifier_arg)
804
void TableShare::setIdentifier(TableIdentifier &identifier_arg)
806
private_key_for_cache.clear();
711
807
private_key_for_cache= identifier_arg.getKey();
714
810
Let us use the fact that the key is "db/0/table_name/0" + optional
715
811
part for temporary tables.
717
db.str= const_cast<char *>(private_key_for_cache.vector());
813
db.str= &private_key_for_cache[0];
718
814
db.length= strlen(db.str);
719
815
table_name.str= db.str + db.length + 1;
720
816
table_name.length= strlen(table_name.str);
934
1030
uint32_t local_null_fields= 0;
937
std::vector<uint32_t> field_offsets;
938
std::vector<uint32_t> field_pack_length;
1033
vector<uint32_t> field_offsets;
1034
vector<uint32_t> field_pack_length;
940
1036
field_offsets.resize(fields);
941
1037
field_pack_length.resize(fields);
1135
1231
unireg_type= Field::TIMESTAMP_DN_FIELD;
1139
assert(0); // Invalid update value.
1234
assert(1); // Invalid update value.
1143
1236
else if (pfield.has_options() &&
1144
1237
pfield.options().has_update_expression() &&
1234
blob_ptr_size= portable_sizeof_char_ptr;
1327
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
1328
temp_table.setShare(this);
1329
temp_table.in_use= &session;
1330
temp_table.getMutableShare()->db_low_byte_first= true; //Cursor->low_byte_first();
1331
temp_table.getMutableShare()->blob_ptr_size= portable_sizeof_char_ptr;
1236
1333
uint32_t field_length= 0; //Assignment is for compiler complaint.
1315
1412
case DRIZZLE_TYPE_LONGLONG:
1316
1413
field_length= MAX_BIGINT_WIDTH;
1318
case DRIZZLE_TYPE_UUID:
1319
field_length= field::Uuid::max_string_length();
1321
1415
case DRIZZLE_TYPE_NULL:
1322
1416
abort(); // Programming error
1325
assert(enum_field_types_size == 12);
1327
1419
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());
1421
pfield.constraints().is_nullable(),
1427
(Field::utype) MTYP_TYPENR(unireg_type),
1428
((field_type == DRIZZLE_TYPE_ENUM) ?
1429
&intervals[interval_nr++]
1431
getTableProto()->field(fieldnr).name().c_str());
1339
1433
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
// This needs to go, we should be setting the "use" on the field so that
1360
// it does not reference the share/table.
1361
table::Shell temp_table(*this); /* Use this so that BLOB DEFAULT '' works */
1362
temp_table.in_use= &session;
1364
1435
f->init(&temp_table); /* blob default values need table obj */
1366
1437
if (! (f->flags & NOT_NULL_FLAG))
1385
1456
return local_error;
1388
else if (f->real_type() == DRIZZLE_TYPE_ENUM && (f->flags & NOT_NULL_FLAG))
1459
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
1460
(f->flags & NOT_NULL_FLAG))
1390
1462
f->set_notnull();
1391
1463
f->store((int64_t) 1, true);
1412
1484
if (f->unireg_check == Field::NEXT_NUMBER)
1413
1485
found_next_number_field= &(field[fieldnr]);
1487
if (timestamp_field == f)
1488
timestamp_field_offset= fieldnr;
1415
1490
if (use_hash) /* supposedly this never fails... but comments lie */
1417
1492
const char *local_field_name= field[fieldnr]->field_name;
1418
1493
name_hash.insert(make_pair(local_field_name, &(field[fieldnr])));
1422
1498
keyinfo= key_info;
1607
1684
if (blob_fields)
1609
1688
/* Store offsets to blob fields to find them fast */
1610
1689
blob_field.resize(blob_fields);
1611
uint32_t *save= &blob_field[0];
1690
save= &blob_field[0];
1613
1692
for (Fields::iterator iter= field.begin(); iter != field.end()-1; iter++, k++)
1615
1694
if ((*iter)->flags & BLOB_FLAG)
1621
all_set.resize(fields);
1699
db_low_byte_first= true; // @todo Question this.
1700
column_bitmap_size= bitmap_buffer_size(fields);
1702
all_bitmap.resize(column_bitmap_size);
1703
all_set.init(&all_bitmap[0], fields);
1624
1706
return local_error;
1652
1734
This function is called when the table definition is not cached in
1653
definition::Cache::singleton().getCache()
1654
1736
The data is returned in 'share', which is alloced by
1655
1737
alloc_table_share().. The code assumes that share is initialized.
1731
1813
5 Error (see open_table_error: charset unavailable)
1732
1814
7 Table definition has changed in engine
1734
1817
int TableShare::open_table_from_share(Session *session,
1735
1818
const TableIdentifier &identifier,
1736
1819
const char *alias,
1737
1820
uint32_t db_stat, uint32_t ha_open_flags,
1738
1821
Table &outparam)
1824
uint32_t records, bitmap_size;
1740
1825
bool error_reported= false;
1741
int ret= open_table_from_share_inner(session, alias, db_stat, outparam);
1744
ret= open_table_cursor_inner(identifier, db_stat, ha_open_flags, outparam, error_reported);
1749
if (not error_reported)
1750
open_table_error(ret, errno, 0);
1752
delete outparam.cursor;
1753
outparam.cursor= 0; // For easier error checking
1754
outparam.db_stat= 0;
1755
outparam.getMemRoot()->free_root(MYF(0)); // Safe to call on zeroed root
1756
outparam.clearAlias();
1761
int TableShare::open_table_from_share_inner(Session *session,
1768
unsigned char *record= NULL;
1826
unsigned char *record, *bitmaps;
1769
1827
Field **field_ptr;
1771
1829
/* Parsing of partitioning information from .frm needs session->lex set up. */
1774
1832
local_error= 1;
1775
1833
outparam.resetTable(session, this, db_stat);
1777
outparam.setAlias(alias);
1835
if (not (outparam.alias= strdup(alias)))
1779
1838
/* Allocate Cursor */
1780
if (not (outparam.cursor= db_type()->getCursor(outparam)))
1839
if (not (outparam.cursor= db_type()->getCursor(*this)))
1783
1842
local_error= 4;
1845
1904
outparam.found_next_number_field=
1846
1905
outparam.getField(positionFields(found_next_number_field));
1847
1906
if (timestamp_field)
1848
outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field->position());
1907
outparam.timestamp_field= (Field_timestamp*) outparam.getField(timestamp_field_offset);
1850
1910
/* Fix key->name and key_part->field */
1855
1915
uint32_t n_length;
1856
1916
n_length= keys*sizeof(KeyInfo) + key_parts*sizeof(KeyPartInfo);
1857
1917
if (!(local_key_info= (KeyInfo*) outparam.alloc_root(n_length)))
1859
1919
outparam.key_info= local_key_info;
1860
1920
key_part= (reinterpret_cast<KeyPartInfo*> (local_key_info+keys));
1895
1955
/* Allocate bitmaps */
1897
outparam.def_read_set.resize(fields);
1898
outparam.def_write_set.resize(fields);
1899
outparam.tmp_set.resize(fields);
1957
bitmap_size= column_bitmap_size;
1958
if (!(bitmaps= (unsigned char*) outparam.alloc_root(bitmap_size*3)))
1962
outparam.def_read_set.init((my_bitmap_map*) bitmaps, fields);
1963
outparam.def_write_set.init((my_bitmap_map*) (bitmaps+bitmap_size), fields);
1964
outparam.tmp_set.init((my_bitmap_map*) (bitmaps+bitmap_size*2), fields);
1900
1965
outparam.default_column_bitmaps();
1905
int TableShare::open_table_cursor_inner(const TableIdentifier &identifier,
1906
uint32_t db_stat, uint32_t ha_open_flags,
1908
bool &error_reported)
1910
1967
/* The table struct is now initialized; Open the table */
1914
1971
assert(!(db_stat & HA_WAIT_IF_LOCKED));
1917
if ((ha_err= (outparam.cursor->ha_open(identifier,
1918
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1919
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1974
if ((ha_err= (outparam.cursor->ha_open(identifier, &outparam,
1975
(db_stat & HA_READ_ONLY ? O_RDONLY : O_RDWR),
1976
(db_stat & HA_OPEN_TEMPORARY ? HA_OPEN_TMP_TABLE : HA_OPEN_IGNORE_IF_LOCKED) | ha_open_flags))))
1921
1978
switch (ha_err)
1943
2000
local_error= 7;
2007
#if defined(HAVE_purify)
2008
memset(bitmaps, 0, bitmap_size*3);
2014
if (!error_reported)
2015
open_table_error(local_error, errno, 0);
2017
delete outparam.cursor;
2018
outparam.cursor= 0; // For easier error checking
2019
outparam.db_stat= 0;
2020
outparam.getMemRoot()->free_root(MYF(0)); // Safe to call on zeroed root
2021
free((char*) outparam.alias);
2023
return (local_error);
1953
2026
/* error message when opening a form cursor */
2054
2126
field_charset);
2055
2127
case DRIZZLE_TYPE_VARCHAR:
2057
2128
return new (&mem_root) Field_varstring(ptr,field_length,
2058
ha_varchar_packlength(field_length),
2129
HA_VARCHAR_PACKLENGTH(field_length),
2059
2130
null_pos,null_bit,
2061
2133
field_charset);
2062
2134
case DRIZZLE_TYPE_BLOB:
2063
2135
return new (&mem_root) Field_blob(ptr,
2140
calc_pack_length(DRIZZLE_TYPE_LONG, 0),
2068
2141
field_charset);
2069
2142
case DRIZZLE_TYPE_DECIMAL:
2070
2143
return new (&mem_root) Field_decimal(ptr,
2088
2161
false /* is_unsigned */);
2089
case DRIZZLE_TYPE_UUID:
2090
return new (&mem_root) field::Uuid(ptr,
2095
2162
case DRIZZLE_TYPE_LONG:
2096
return new (&mem_root) field::Int32(ptr,
2163
return new (&mem_root) Field_long(ptr,
2170
false /* is_unsigned */);
2102
2171
case DRIZZLE_TYPE_LONGLONG:
2103
return new (&mem_root) field::Int64(ptr,
2172
return new (&mem_root) Field_int64_t(ptr,
2179
false /* is_unsigned */);
2109
2180
case DRIZZLE_TYPE_TIMESTAMP:
2110
2181
return new (&mem_root) Field_timestamp(ptr,