167
Initialize share for temporary tables
170
init_tmp_table_share()
173
key Table_cache_key, as generated from create_table_def_key.
174
must start with db name.
175
key_length Length of key
176
table_name Table name
177
path Path to file (possible in lower case) without .frm
180
This is different from alloc_table_share() because temporary tables
181
don't have to be shared between threads or put into the table def
182
cache, so we can do some things notable simpler and faster
184
If table is not put in thd->temporary_tables (happens only when
185
one uses OPEN TEMPORARY) then one can specify 'db' as key and
186
use key_length= 0 as neither table_cache_key or key_length will be used).
189
void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key,
190
uint32_t key_length, const char *table_name,
194
memset(share, 0, sizeof(*share));
195
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
196
share->table_category= TABLE_CATEGORY_TEMPORARY;
197
share->tmp_table= INTERNAL_TMP_TABLE;
198
share->db.str= (char*) key;
199
share->db.length= strlen(key);
200
share->table_cache_key.str= (char*) key;
201
share->table_cache_key.length= key_length;
202
share->table_name.str= (char*) table_name;
203
share->table_name.length= strlen(table_name);
204
share->path.str= (char*) path;
205
share->normalized_path.str= (char*) path;
206
share->path.length= share->normalized_path.length= strlen(path);
207
share->frm_version= FRM_VER_TRUE_VARCHAR;
209
Temporary tables are not replicated, but we set up these fields
210
anyway to be able to catch errors.
212
share->table_map_version= ~(uint64_t)0;
213
share->cached_row_logging_check= -1;
216
table_map_id is also used for MERGE tables to suppress repeated
217
compatibility checks.
219
share->table_map_id= (ulong) thd->query_id;
226
Free table share and memory used by it
233
share->mutex must be locked when we come here if it's not a temp table
236
void free_table_share(TABLE_SHARE *share)
239
assert(share->ref_count == 0);
242
If someone is waiting for this to be deleted, inform it about this.
243
Don't do a delete until we know that no one is refering to this anymore.
245
if (share->tmp_table == NO_TMP_TABLE)
247
/* share->mutex is locked in release_table_share() */
248
while (share->waiting_on_cond)
250
pthread_cond_broadcast(&share->cond);
251
pthread_cond_wait(&share->cond, &share->mutex);
253
/* No thread refers to this anymore */
254
pthread_mutex_unlock(&share->mutex);
255
pthread_mutex_destroy(&share->mutex);
256
pthread_cond_destroy(&share->cond);
258
hash_free(&share->name_hash);
260
plugin_unlock(NULL, share->db_plugin);
261
share->db_plugin= NULL;
263
/* We must copy mem_root from share because share is allocated through it */
264
memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
265
free_root(&mem_root, MYF(0)); // Free's share
270
Read table definition from a binary / text based .frm file
275
share Fill this with table definition
276
db_flags Bit mask of the following flags: OPEN_VIEW
279
This function is called when the table definition is not cached in
281
The data is returned in 'share', which is alloced by
282
alloc_table_share().. The code assumes that share is initialized.
286
1 Error (see open_table_error)
287
2 Error (see open_table_error)
288
3 Wrong data in .frm file
289
4 Error (see open_table_error)
290
5 Error (see open_table_error: charset unavailable)
291
6 Unknown .frm version
294
int open_table_def(THD *thd, TABLE_SHARE *share, uint32_t db_flags __attribute__((unused)))
296
int error, table_type;
299
unsigned char head[64], *disk_buff;
300
char path[FN_REFLEN];
301
MEM_ROOT **root_ptr, *old_root;
307
strxmov(path, share->normalized_path.str, reg_ext, NULL);
308
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
311
We don't try to open 5.0 unencoded name, if
312
- non-encoded name contains '@' signs,
313
because '@' can be misinterpreted.
314
It is not clear if '@' is escape character in 5.1,
315
or a normal character in 5.0.
317
- non-encoded db or table name contain "#mysql50#" prefix.
318
This kind of tables must have been opened only by the
321
if (strchr(share->table_name.str, '@') ||
322
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
323
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
324
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
325
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
328
/* Try unencoded 5.0 name */
330
strxnmov(path, sizeof(path)-1,
331
mysql_data_home, "/", share->db.str, "/",
332
share->table_name.str, reg_ext, NULL);
333
length= unpack_filename(path, path) - reg_ext_length;
335
The following is a safety test and should never fail
336
as the old file name should never be longer than the new one.
338
assert(length <= share->normalized_path.length);
340
If the old and the new names have the same length,
341
then table name does not have tricky characters,
342
so no need to check the old file name.
344
if (length == share->normalized_path.length ||
345
((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
348
/* Unencoded 5.0 table name found */
349
path[length]= '\0'; // Remove .frm extension
350
my_stpcpy(share->normalized_path.str, path);
351
share->normalized_path.length= length;
355
if (my_read(file, head, 64, MYF(MY_NABP)))
358
if (head[0] == (unsigned char) 254 && head[1] == 1)
360
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
361
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
367
error= 6; // Unkown .frm version
374
/* No handling of text based files yet */
377
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
379
*root_ptr= &share->mem_root;
380
error= open_binary_frm(thd, share, head, file);
165
enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
167
enum_field_types field_type;
169
switch(proto_field_type)
171
case drizzled::message::Table::Field::TINYINT:
172
field_type= DRIZZLE_TYPE_TINY;
174
case drizzled::message::Table::Field::INTEGER:
175
field_type= DRIZZLE_TYPE_LONG;
177
case drizzled::message::Table::Field::DOUBLE:
178
field_type= DRIZZLE_TYPE_DOUBLE;
180
case drizzled::message::Table::Field::TIMESTAMP:
181
field_type= DRIZZLE_TYPE_TIMESTAMP;
183
case drizzled::message::Table::Field::BIGINT:
184
field_type= DRIZZLE_TYPE_LONGLONG;
186
case drizzled::message::Table::Field::DATETIME:
187
field_type= DRIZZLE_TYPE_DATETIME;
189
case drizzled::message::Table::Field::DATE:
190
field_type= DRIZZLE_TYPE_DATE;
192
case drizzled::message::Table::Field::VARCHAR:
193
field_type= DRIZZLE_TYPE_VARCHAR;
195
case drizzled::message::Table::Field::DECIMAL:
196
field_type= DRIZZLE_TYPE_NEWDECIMAL;
198
case drizzled::message::Table::Field::ENUM:
199
field_type= DRIZZLE_TYPE_ENUM;
201
case drizzled::message::Table::Field::BLOB:
202
field_type= DRIZZLE_TYPE_BLOB;
205
field_type= DRIZZLE_TYPE_TINY; /* Set value to kill GCC warning */
387
share->table_category= get_table_category(& share->db, & share->table_name);
390
thd->status_var.opened_shares++;
393
my_close(file, MYF(MY_WME));
396
if (error && !error_given)
399
open_table_error(share, error, (share->open_errno= my_errno), 0);
407
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
410
static int open_binary_frm(THD *thd, TABLE_SHARE *share, unsigned char *head,
413
int error, errarg= 0;
414
uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
415
uint32_t interval_count, interval_parts, read_length, int_length;
416
uint32_t db_create_options, keys, key_parts, n_length;
417
uint32_t key_info_length, com_length, null_bit_pos=0;
418
uint32_t extra_rec_buf_length;
421
unsigned char forminfo[288];
422
char *keynames, *names, *comment_pos;
423
unsigned char *record;
424
unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
425
ulong pos, record_offset, *rec_per_key, rec_buff_length;
426
handler *handler_file= 0;
428
KEY_PART_INFO *key_part;
429
Field **field_ptr, *reg_field;
430
const char **interval_array;
431
enum legacy_db_type legacy_db_type;
432
my_bitmap_map *bitmaps;
433
unsigned char *buff= 0;
434
unsigned char *field_extra_info= 0;
436
new_field_pack_flag= head[27];
437
new_frm_ver= (head[2] - FRM_VER);
438
field_pack_length= new_frm_ver < 2 ? 11 : 17;
442
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
443
goto err; /* purecov: inspected */
444
my_seek(file,pos,MY_SEEK_SET,MYF(0));
445
if (my_read(file,forminfo,288,MYF(MY_NABP)))
448
share->frm_version= head[2];
450
Check if .frm file created by MySQL 5.0. In this case we want to
451
display CHAR fields as CHAR and not as VARCHAR.
452
We do it this way as we want to keep the old frm version to enable
453
MySQL 4.1 to read these files.
455
if (share->frm_version == FRM_VER_TRUE_VARCHAR -1 && head[33] == 5)
456
share->frm_version= FRM_VER_TRUE_VARCHAR;
458
legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
459
assert(share->db_plugin == NULL);
461
if the storage engine is dynamic, no point in resolving it by its
462
dynamically allocated legacy_db_type. We will resolve it later by name.
464
if (legacy_db_type > DB_TYPE_UNKNOWN &&
465
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
466
share->db_plugin= ha_lock_engine(NULL,
467
ha_checktype(thd, legacy_db_type, 0, 0));
468
share->db_create_options= db_create_options= uint2korr(head+30);
212
Item * default_value_item(enum_field_types field_type,
213
const CHARSET_INFO *charset,
214
bool default_null, const string *default_value,
215
const string *default_bin_value)
217
Item *default_item= NULL;
222
return new Item_null();
227
case DRIZZLE_TYPE_TINY:
228
case DRIZZLE_TYPE_LONG:
229
case DRIZZLE_TYPE_LONGLONG:
230
default_item= new Item_int(default_value->c_str(),
231
(int64_t) my_strtoll10(default_value->c_str(),
234
default_value->length());
236
case DRIZZLE_TYPE_DOUBLE:
237
default_item= new Item_float(default_value->c_str(),
238
default_value->length());
240
case DRIZZLE_TYPE_NULL:
242
case DRIZZLE_TYPE_TIMESTAMP:
243
case DRIZZLE_TYPE_DATETIME:
244
case DRIZZLE_TYPE_DATE:
245
if (default_value->compare("NOW()") == 0)
247
case DRIZZLE_TYPE_ENUM:
248
default_item= new Item_string(default_value->c_str(),
249
default_value->length(),
250
system_charset_info);
252
case DRIZZLE_TYPE_VARCHAR:
253
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
254
if(charset==&my_charset_bin)
256
default_item= new Item_string(default_bin_value->c_str(),
257
default_bin_value->length(),
262
default_item= new Item_string(default_value->c_str(),
263
default_value->length(),
264
system_charset_info);
267
case DRIZZLE_TYPE_NEWDECIMAL:
268
default_item= new Item_decimal(default_value->c_str(),
269
default_value->length(),
270
system_charset_info);
277
int parse_table_proto(Session *session, drizzled::message::Table &table, TableShare *share)
280
handler *handler_file= NULL;
283
LEX_STRING engine_name= { (char*)table.engine().name().c_str(),
284
strlen(table.engine().name().c_str()) };
285
share->storage_engine= ha_resolve_by_name(session, &engine_name);
288
share->mysql_version= DRIZZLE_VERSION_ID; // TODO: remove
290
drizzled::message::Table::TableOptions table_options;
292
if(table.has_options())
293
table_options= table.options();
295
uint32_t db_create_options= HA_OPTION_LONG_BLOB_PTR;
297
if(table_options.has_pack_keys())
299
if(table_options.pack_keys())
300
db_create_options|= HA_OPTION_PACK_KEYS;
302
db_create_options|= HA_OPTION_NO_PACK_KEYS;
305
if(table_options.pack_record())
306
db_create_options|= HA_OPTION_PACK_RECORD;
308
if(table_options.has_checksum())
310
if(table_options.checksum())
311
db_create_options|= HA_OPTION_CHECKSUM;
313
db_create_options|= HA_OPTION_NO_CHECKSUM;
316
if(table_options.has_delay_key_write())
318
if(table_options.delay_key_write())
319
db_create_options|= HA_OPTION_DELAY_KEY_WRITE;
321
db_create_options|= HA_OPTION_NO_DELAY_KEY_WRITE;
324
/* db_create_options was stored as 2 bytes in FRM
325
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
327
share->db_create_options= (db_create_options & 0x0000FFFF);
469
328
share->db_options_in_use= share->db_create_options;
470
share->mysql_version= uint4korr(head+51);
471
share->null_field_first= 0;
472
if (!head[32]) // New frm file in 3.23
474
share->avg_row_length= uint4korr(head+34);
475
share->transactional= (ha_choice) (head[39] & 3);
476
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
477
share->row_type= (row_type) head[40];
478
share->block_size= uint4korr(head+43);
479
share->table_charset= get_charset((uint) head[38],MYF(0));
480
share->null_field_first= 1;
331
share->avg_row_length= table_options.has_avg_row_length() ?
332
table_options.avg_row_length() : 0;
334
share->page_checksum= table_options.has_page_checksum() ?
335
(table_options.page_checksum()?HA_CHOICE_YES:HA_CHOICE_NO)
338
share->row_type= table_options.has_row_type() ?
339
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
341
share->block_size= table_options.has_block_size() ?
342
table_options.block_size() : 0;
344
share->table_charset= get_charset(table_options.has_collation_id()?
345
table_options.collation_id() : 0);
482
347
if (!share->table_charset)
484
349
/* unknown charset in head[38] or pre-3.23 frm */
485
350
if (use_mb(default_charset_info))
487
352
/* Warn that we may be changing the size of character columns */
488
sql_print_warning(_("'%s' had no or invalid character set, "
489
"and default character set is multi-byte, "
490
"so character column sizes may have changed"),
353
errmsg_printf(ERRMSG_LVL_WARN,
354
_("'%s' had no or invalid character set, "
355
"and default character set is multi-byte, "
356
"so character column sizes may have changed"),
493
359
share->table_charset= default_charset_info;
495
362
share->db_record_offset= 1;
496
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
497
share->blob_ptr_size= portable_sizeof_char_ptr;
498
/* Set temporarily a good value for db_low_byte_first */
364
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
499
366
share->db_low_byte_first= true;
501
share->max_rows= uint4korr(head+18);
502
share->min_rows= uint4korr(head+22);
504
/* Read keyinformation */
505
key_info_length= (uint) uint2korr(head+28);
506
my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
507
if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
508
goto err; /* purecov: inspected */
509
if (disk_buff[0] & 0x80)
511
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
512
share->key_parts= key_parts= uint2korr(disk_buff+2);
516
share->keys= keys= disk_buff[0];
517
share->key_parts= key_parts= disk_buff[1];
519
share->keys_for_keyread.init(0);
520
share->keys_in_use.init(keys);
522
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
523
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
524
n_length + uint2korr(disk_buff+4))))
525
goto err; /* purecov: inspected */
526
memset(keyinfo, 0, n_length);
527
share->key_info= keyinfo;
528
key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
531
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
532
sizeof(ulong*)*key_parts)))
535
for (i=0 ; i < keys ; i++, keyinfo++)
537
keyinfo->table= 0; // Updated in open_frm
538
if (new_frm_ver >= 3)
540
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
541
keyinfo->key_length= (uint) uint2korr(strpos+2);
542
keyinfo->key_parts= (uint) strpos[4];
543
keyinfo->algorithm= (enum ha_key_alg) strpos[5];
544
keyinfo->block_size= uint2korr(strpos+6);
548
keyinfo->key_part= key_part;
368
share->max_rows= table_options.has_max_rows() ?
369
table_options.max_rows() : 0;
371
share->min_rows= table_options.has_min_rows() ?
372
table_options.min_rows() : 0;
374
share->keys= table.indexes_size();
377
for(int indx= 0; indx < table.indexes_size(); indx++)
378
share->key_parts+= table.indexes(indx).index_part_size();
380
share->key_info= (KEY*) alloc_root(&share->mem_root,
381
table.indexes_size() * sizeof(KEY)
382
+share->key_parts*sizeof(KEY_PART_INFO));
384
KEY_PART_INFO *key_part;
386
key_part= reinterpret_cast<KEY_PART_INFO*>
387
(share->key_info+table.indexes_size());
390
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
391
sizeof(ulong*)*share->key_parts);
393
share->keynames.count= table.indexes_size();
394
share->keynames.name= NULL;
395
share->keynames.type_names= (const char**)
396
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
398
share->keynames.type_lengths= (unsigned int*)
399
alloc_root(&share->mem_root,
400
sizeof(unsigned int) * (table.indexes_size()+1));
402
share->keynames.type_names[share->keynames.count]= NULL;
403
share->keynames.type_lengths[share->keynames.count]= 0;
405
KEY* keyinfo= share->key_info;
406
for (int keynr=0; keynr < table.indexes_size(); keynr++, keyinfo++)
408
drizzled::message::Table::Index indx= table.indexes(keynr);
414
keyinfo->flags|= HA_NOSAME;
416
if(indx.has_options())
418
drizzled::message::Table::Index::IndexOptions indx_options= indx.options();
419
if(indx_options.pack_key())
420
keyinfo->flags|= HA_PACK_KEY;
422
if(indx_options.var_length_key())
423
keyinfo->flags|= HA_VAR_LENGTH_PART;
425
if(indx_options.null_part_key())
426
keyinfo->flags|= HA_NULL_PART_KEY;
428
if(indx_options.binary_pack_key())
429
keyinfo->flags|= HA_BINARY_PACK_KEY;
431
if(indx_options.has_partial_segments())
432
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
434
if(indx_options.auto_generated_key())
435
keyinfo->flags|= HA_GENERATED_KEY;
437
if(indx_options.has_key_block_size())
439
keyinfo->flags|= HA_USES_BLOCK_SIZE;
440
keyinfo->block_size= indx_options.key_block_size();
444
keyinfo->block_size= 0;
451
case drizzled::message::Table::Index::UNKNOWN_INDEX:
452
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
454
case drizzled::message::Table::Index::BTREE:
455
keyinfo->algorithm= HA_KEY_ALG_BTREE;
457
case drizzled::message::Table::Index::RTREE:
458
keyinfo->algorithm= HA_KEY_ALG_RTREE;
460
case drizzled::message::Table::Index::HASH:
461
keyinfo->algorithm= HA_KEY_ALG_HASH;
463
case drizzled::message::Table::Index::FULLTEXT:
464
keyinfo->algorithm= HA_KEY_ALG_FULLTEXT;
467
/* TODO: suitable warning ? */
468
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
472
keyinfo->key_length= indx.key_length();
474
keyinfo->key_parts= indx.index_part_size();
476
keyinfo->key_part= key_part;
549
477
keyinfo->rec_per_key= rec_per_key;
550
for (j=keyinfo->key_parts ; j-- ; key_part++)
479
for(unsigned int partnr= 0;
480
partnr < keyinfo->key_parts;
481
partnr++, key_part++)
483
drizzled::message::Table::Index::IndexPart part;
484
part= indx.index_part(partnr);
552
486
*rec_per_key++=0;
553
key_part->fieldnr= (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
554
key_part->offset= (uint) uint2korr(strpos+2)-1;
555
key_part->key_type= (uint) uint2korr(strpos+5);
556
// key_part->field= (Field*) 0; // Will be fixed later
557
if (new_frm_ver >= 1)
559
key_part->key_part_flag= *(strpos+4);
560
key_part->length= (uint) uint2korr(strpos+7);
565
key_part->length= *(strpos+4);
566
key_part->key_part_flag=0;
567
if (key_part->length > 128)
569
key_part->length&=127; /* purecov: inspected */
570
key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
574
key_part->store_length=key_part->length;
577
keynames=(char*) key_part;
578
strpos+= (my_stpcpy(keynames, (char *) strpos) - keynames)+1;
580
//reading index comments
581
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
583
if (keyinfo->flags & HA_USES_COMMENT)
585
keyinfo->comment.length= uint2korr(strpos);
586
keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
587
keyinfo->comment.length);
588
strpos+= 2 + keyinfo->comment.length;
590
assert(test(keyinfo->flags & HA_USES_COMMENT) ==
591
(keyinfo->comment.length > 0));
594
share->reclength = uint2korr((head+16));
596
record_offset= (ulong) (uint2korr(head+6)+
597
((uint2korr(head+14) == 0xffff ?
598
uint4korr(head+47) : uint2korr(head+14))));
600
if ((n_length= uint4korr(head+55)))
602
/* Read extra data segment */
603
unsigned char *next_chunk, *buff_end;
604
if (!(next_chunk= buff= (unsigned char*) my_malloc(n_length, MYF(MY_WME))))
606
if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
610
share->connect_string.length= uint2korr(buff);
611
if (!(share->connect_string.str= strmake_root(&share->mem_root,
612
(char*) next_chunk + 2,
613
share->connect_string.
618
next_chunk+= share->connect_string.length + 2;
619
buff_end= buff + n_length;
620
if (next_chunk + 2 < buff_end)
622
uint32_t str_db_type_length= uint2korr(next_chunk);
624
name.str= (char*) next_chunk + 2;
625
name.length= str_db_type_length;
627
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
628
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
630
if (legacy_db_type > DB_TYPE_UNKNOWN &&
631
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
632
legacy_db_type != ha_legacy_type(
633
plugin_data(tmp_plugin, handlerton *)))
635
/* bad file, legacy_db_type did not match the name */
640
tmp_plugin is locked with a local lock.
641
we unlock the old value of share->db_plugin before
642
replacing it with a globally locked version of tmp_plugin
644
plugin_unlock(NULL, share->db_plugin);
645
share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
647
else if (!tmp_plugin)
649
/* purecov: begin inspected */
651
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
656
next_chunk+= str_db_type_length + 2;
658
if (share->mysql_version >= 50110)
660
/* New auto_partitioned indicator introduced in 5.1.11 */
663
if (forminfo[46] == (unsigned char)255)
665
//reading long table comment
666
if (next_chunk + 2 > buff_end)
671
share->comment.length = uint2korr(next_chunk);
672
if (! (share->comment.str= strmake_root(&share->mem_root,
673
(char*)next_chunk + 2, share->comment.length)))
678
next_chunk+= 2 + share->comment.length;
680
assert(next_chunk <= buff_end);
681
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
684
New frm format in mysql_version 5.2.5 (originally in
685
mysql-5.1.22-ndb-6.2.5)
686
New column properties added:
687
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
688
TABLESPACE name is now stored in frm
690
if (next_chunk >= buff_end)
692
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
699
const uint32_t format_section_header_size= 8;
700
uint32_t format_section_len= uint2korr(next_chunk+0);
702
field_extra_info= next_chunk + format_section_header_size + 1;
703
next_chunk+= format_section_len;
706
assert (next_chunk <= buff_end);
707
if (next_chunk > buff_end)
712
share->key_block_size= uint2korr(head+62);
715
extra_rec_buf_length= uint2korr(head+59);
716
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
488
key_part->field= NULL;
489
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
490
key_part->null_bit= 0;
491
/* key_part->null_offset is only set if null_bit (see later) */
492
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
493
/* key_part->type ???? */
494
key_part->key_part_flag= 0;
495
if(part.has_in_reverse_order())
496
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
498
key_part->length= part.compare_length();
500
key_part->store_length= key_part->length;
502
/* key_part->offset is set later */
503
key_part->key_type= part.key_type();
507
if(!indx.has_comment())
509
keyinfo->comment.length= 0;
510
keyinfo->comment.str= NULL;
514
keyinfo->flags|= HA_USES_COMMENT;
515
keyinfo->comment.length= indx.comment().length();
516
keyinfo->comment.str= strmake_root(&share->mem_root,
517
indx.comment().c_str(),
518
keyinfo->comment.length);
521
keyinfo->name= strmake_root(&share->mem_root,
523
indx.name().length());
525
share->keynames.type_names[keynr]= keyinfo->name;
526
share->keynames.type_lengths[keynr]= indx.name().length();
529
share->keys_for_keyread.reset();
530
set_prefix(share->keys_in_use, share->keys);
532
if(table_options.has_connect_string())
534
size_t len= table_options.connect_string().length();
535
const char* str= table_options.connect_string().c_str();
537
share->connect_string.length= len;
538
share->connect_string.str= strmake_root(&share->mem_root, str, len);
541
if(table_options.has_comment())
543
size_t len= table_options.comment().length();
544
const char* str= table_options.comment().c_str();
546
share->comment.length= len;
547
share->comment.str= strmake_root(&share->mem_root, str, len);
550
share->key_block_size= table_options.has_key_block_size() ?
551
table_options.key_block_size() : 0;
553
share->fields= table.field_size();
555
share->field= (Field**) alloc_root(&share->mem_root,
556
((share->fields+1) * sizeof(Field*)));
557
share->field[share->fields]= NULL;
559
uint32_t null_fields= 0;
562
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
563
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
565
assert(field_offsets && field_pack_length); // TODO: fixme
567
uint32_t interval_count= 0;
568
uint32_t interval_parts= 0;
570
uint32_t stored_columns_reclength= 0;
572
for (unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
574
drizzled::message::Table::Field pfield= table.field(fieldnr);
575
if(pfield.has_constraints() && pfield.constraints().is_nullable())
578
enum_field_types drizzle_field_type=
579
proto_field_type_to_drizzle_type(pfield.type());
581
field_offsets[fieldnr]= stored_columns_reclength;
583
/* the below switch is very similar to
584
Create_field::create_length_to_internal_length in field.cc
585
(which should one day be replace by just this code)
587
switch(drizzle_field_type)
589
case DRIZZLE_TYPE_BLOB:
590
case DRIZZLE_TYPE_VARCHAR:
592
drizzled::message::Table::Field::StringFieldOptions field_options=
593
pfield.string_options();
595
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id()?
596
field_options.collation_id() : 0);
599
cs= default_charset_info;
601
field_pack_length[fieldnr]=
602
calc_pack_length(drizzle_field_type,
603
field_options.length() * cs->mbmaxlen);
607
case DRIZZLE_TYPE_ENUM:
609
drizzled::message::Table::Field::SetFieldOptions field_options=
610
pfield.set_options();
612
field_pack_length[fieldnr]=
613
get_enum_pack_length(field_options.field_value_size());
616
interval_parts+= field_options.field_value_size();
619
case DRIZZLE_TYPE_NEWDECIMAL:
621
drizzled::message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
623
field_pack_length[fieldnr]=
624
my_decimal_get_binary_size(fo.precision(), fo.scale());
628
/* Zero is okay here as length is fixed for other types. */
629
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
632
share->reclength+= field_pack_length[fieldnr];
633
stored_columns_reclength+= field_pack_length[fieldnr];
637
/* data_offset added to stored_rec_length later */
638
share->stored_rec_length= stored_columns_reclength;
640
share->null_fields= null_fields;
642
ulong null_bits= null_fields;
643
if(!table_options.pack_record())
645
ulong data_offset= (null_bits + 7)/8;
648
share->reclength+= data_offset;
649
share->stored_rec_length+= data_offset;
651
ulong rec_buff_length;
653
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
717
654
share->rec_buff_length= rec_buff_length;
656
unsigned char* record= NULL;
718
658
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
719
659
rec_buff_length)))
720
goto err; /* purecov: inspected */
662
memset(record, 0, rec_buff_length);
666
if(!table_options.pack_record())
668
null_count++; // one bit for delete mark.
721
672
share->default_values= record;
722
if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
723
goto err; /* purecov: inspected */
725
my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
727
share->fields= uint2korr(forminfo+258);
728
pos= uint2korr(forminfo+260); /* Length of all screens */
729
n_length= uint2korr(forminfo+268);
730
interval_count= uint2korr(forminfo+270);
731
interval_parts= uint2korr(forminfo+272);
732
int_length= uint2korr(forminfo+274);
733
share->null_fields= uint2korr(forminfo+282);
734
com_length= uint2korr(forminfo+284);
735
if (forminfo[46] != (unsigned char)255)
737
share->comment.length= (int) (forminfo[46]);
738
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
share->comment.length);
676
share->intervals= (TYPELIB*)alloc_root(&share->mem_root,
677
interval_count*sizeof(TYPELIB));
743
if (!(field_ptr = (Field **)
744
alloc_root(&share->mem_root,
745
(uint) ((share->fields+1)*sizeof(Field*)+
746
interval_count*sizeof(TYPELIB)+
747
(share->fields+interval_parts+
748
keys+3)*sizeof(char *)+
749
(n_length+int_length+com_length)))))
750
goto err; /* purecov: inspected */
752
share->field= field_ptr;
753
read_length=(uint) (share->fields * field_pack_length +
754
pos+ (uint) (n_length+int_length+com_length));
755
if (read_string(file,(unsigned char**) &disk_buff,read_length))
756
goto err; /* purecov: inspected */
757
strpos= disk_buff+pos;
759
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
760
interval_array= (const char **) (share->intervals+interval_count);
761
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
763
share->intervals= 0; // For better debugging
764
memcpy(names, strpos+(share->fields*field_pack_length),
765
(uint) (n_length+int_length));
766
comment_pos= names+(n_length+int_length);
767
memcpy(comment_pos, disk_buff+read_length-com_length, com_length);
769
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
770
if (share->fieldnames.count != share->fields)
772
fix_type_pointers(&interval_array, share->intervals, interval_count,
680
share->intervals= NULL;
682
share->fieldnames.type_names= (const char**)alloc_root(&share->mem_root,
683
(share->fields+1)*sizeof(char*));
685
share->fieldnames.type_lengths= (unsigned int*) alloc_root(&share->mem_root,
686
(share->fields+1)*sizeof(unsigned int));
688
share->fieldnames.type_names[share->fields]= NULL;
689
share->fieldnames.type_lengths[share->fields]= 0;
690
share->fieldnames.count= share->fields;
693
/* Now fix the TYPELIBs for the intervals (enum values)
697
uint32_t interval_nr= 0;
699
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
776
/* Set ENUM and SET lengths */
778
for (interval= share->intervals;
779
interval < share->intervals + interval_count;
701
drizzled::message::Table::Field pfield= table.field(fieldnr);
704
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
705
pfield.name().c_str(),
706
pfield.name().length());
708
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
711
if(pfield.type() != drizzled::message::Table::Field::ENUM)
714
drizzled::message::Table::Field::SetFieldOptions field_options=
715
pfield.set_options();
717
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id()?
718
field_options.collation_id() : 0);
721
charset= default_charset_info;
723
TYPELIB *t= &(share->intervals[interval_nr]);
725
t->type_names= (const char**)alloc_root(&share->mem_root,
726
(field_options.field_value_size()+1)*sizeof(char*));
728
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
729
(field_options.field_value_size()+1)*sizeof(unsigned int));
731
t->type_names[field_options.field_value_size()]= NULL;
732
t->type_lengths[field_options.field_value_size()]= 0;
734
t->count= field_options.field_value_size();
737
for(int n=0; n < field_options.field_value_size(); n++)
782
uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
783
if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
786
for (count= 0; count < interval->count; count++)
788
char *val= (char*) interval->type_names[count];
789
interval->type_lengths[count]= strlen(val);
791
interval->type_lengths[count]= 0;
739
t->type_names[n]= strmake_root(&share->mem_root,
740
field_options.field_value(n).c_str(),
741
field_options.field_value(n).length());
743
/* Go ask the charset what the length is as for "" length=1
744
and there's stripping spaces or some other crack going on.
747
lengthsp= charset->cset->lengthsp(charset, t->type_names[n],
748
field_options.field_value(n).length());
749
t->type_lengths[n]= lengthsp;
796
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
798
/* Allocate handler */
799
if (!(handler_file= get_new_handler(share, thd->mem_root,
803
record= share->default_values-1; /* Fieldstart = 1 */
804
if (share->null_field_first)
806
null_flags= null_pos= (unsigned char*) record+1;
807
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
809
null_bytes below is only correct under the condition that
810
there are no bit fields. Correct values is set below after the
811
table struct is initialized
813
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
816
use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
755
/* and read the fields */
758
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
818
761
use_hash= !hash_init(&share->name_hash,
819
762
system_charset_info,
821
(hash_get_key) get_field_name,0,0);
823
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
764
(hash_get_key) get_field_name, 0, 0);
766
unsigned char* null_pos= record;;
767
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
769
for(unsigned int fieldnr=0; fieldnr < share->fields; fieldnr++)
825
uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
enum_field_types field_type;
771
drizzled::message::Table::Field pfield= table.field(fieldnr);
827
773
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
828
const CHARSET_INFO *charset= NULL;
775
switch(pfield.format())
777
case drizzled::message::Table::Field::DefaultFormat:
778
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
780
case drizzled::message::Table::Field::FixedFormat:
781
column_format= COLUMN_FORMAT_TYPE_FIXED;
783
case drizzled::message::Table::Field::DynamicFormat:
784
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
790
Field::utype unireg_type= Field::NONE;
792
if(pfield.has_numeric_options()
793
&& pfield.numeric_options().is_autoincrement())
795
unireg_type= Field::NEXT_NUMBER;
798
if(pfield.has_options()
799
&& pfield.options().has_default_value()
800
&& pfield.options().default_value().compare("NOW()")==0)
802
if(pfield.options().has_update_value()
803
&& pfield.options().update_value().compare("NOW()")==0)
805
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
807
else if (!pfield.options().has_update_value())
809
unireg_type= Field::TIMESTAMP_DN_FIELD;
812
assert(1); // Invalid update value.
814
else if (pfield.has_options()
815
&& pfield.options().has_update_value()
816
&& pfield.options().update_value().compare("NOW()")==0)
818
unireg_type= Field::TIMESTAMP_UN_FIELD;
829
821
LEX_STRING comment;
831
if (field_extra_info)
833
char tmp= field_extra_info[i];
834
column_format= (enum column_format_type)
835
((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
837
if (new_frm_ver >= 3)
839
/* new frm file in 4.1 */
840
field_length= uint2korr(strpos+3);
841
recpos= uint3korr(strpos+5);
842
pack_flag= uint2korr(strpos+8);
843
unireg_type= (uint) strpos[10];
844
interval_nr= (uint) strpos[12];
845
uint32_t comment_length=uint2korr(strpos+15);
846
field_type=(enum_field_types) (uint) strpos[13];
850
charset= &my_charset_bin;
851
else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
853
error= 5; // Unknown or unavailable charset
854
errarg= (int) strpos[14];
860
comment.str= (char*) "";
865
comment.str= (char*) comment_pos;
866
comment.length= comment_length;
867
comment_pos+= comment_length;
822
if(!pfield.has_comment())
824
comment.str= (char*)"";
872
field_length= (uint) strpos[3];
873
recpos= uint2korr(strpos+4),
874
pack_flag= uint2korr(strpos+6);
875
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
876
unireg_type= (uint) strpos[8];
877
interval_nr= (uint) strpos[10];
880
field_type= (enum_field_types) f_packtype(pack_flag);
881
if (f_is_binary(pack_flag))
884
Try to choose the best 4.1 type:
885
- for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
886
try to find a binary collation for character set.
887
- for other types (e.g. BLOB) just use my_charset_bin.
889
if (!f_is_blob(pack_flag))
891
// 3.23 or 4.0 string
892
if (!(charset= get_charset_by_csname(share->table_charset->csname,
893
MY_CS_BINSORT, MYF(0))))
894
charset= &my_charset_bin;
897
charset= &my_charset_bin;
900
charset= share->table_charset;
901
memset(&comment, 0, sizeof(comment));
904
if (interval_nr && charset->mbminlen > 1)
906
/* Unescape UCS2 intervals from HEX notation */
907
TYPELIB *interval= share->intervals + interval_nr - 1;
908
unhex_type2(interval);
911
*field_ptr= reg_field=
912
make_field(share, record+recpos,
913
(uint32_t) field_length,
914
null_pos, null_bit_pos,
918
(Field::utype) MTYP_TYPENR(unireg_type),
920
share->intervals+interval_nr-1 :
922
share->fieldnames.type_names[i]);
923
if (!reg_field) // Not supported field type
926
goto err; /* purecov: inspected */
929
reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
930
reg_field->field_index= i;
931
reg_field->comment=comment;
932
if (!(reg_field->flags & NOT_NULL_FLAG))
829
size_t len= pfield.comment().length();
830
const char* str= pfield.comment().c_str();
832
comment.str= strmake_root(&share->mem_root, str, len);
836
enum_field_types field_type;
838
field_type= proto_field_type_to_drizzle_type(pfield.type());
840
const CHARSET_INFO *charset= &my_charset_bin;
842
if(field_type==DRIZZLE_TYPE_BLOB
843
|| field_type==DRIZZLE_TYPE_VARCHAR)
845
drizzled::message::Table::Field::StringFieldOptions field_options=
846
pfield.string_options();
848
charset= get_charset(field_options.has_collation_id()?
849
field_options.collation_id() : 0);
852
charset= default_charset_info;
856
if(field_type==DRIZZLE_TYPE_ENUM)
858
drizzled::message::Table::Field::SetFieldOptions field_options=
859
pfield.set_options();
861
charset= get_charset(field_options.has_collation_id()?
862
field_options.collation_id() : 0);
865
charset= default_charset_info;
869
Item *default_value= NULL;
871
if(pfield.options().has_default_value()
872
|| pfield.options().has_default_null()
873
|| pfield.options().has_default_bin_value())
875
default_value= default_value_item(field_type,
877
pfield.options().default_null(),
878
&pfield.options().default_value(),
879
&pfield.options().default_bin_value());
882
uint32_t pack_flag= pfield.pack_flag(); /* TODO: MUST DIE */
884
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
885
memset(&temp_table, 0, sizeof(temp_table));
887
temp_table.in_use= session;
888
temp_table.s->db_low_byte_first= 1; //handler->low_byte_first();
889
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
891
Field* f= make_field(share, &share->mem_root,
892
record+field_offsets[fieldnr]+data_offset,
893
pfield.options().length(),
899
(Field::utype) MTYP_TYPENR(unireg_type),
900
((field_type==DRIZZLE_TYPE_ENUM)?
901
share->intervals+(interval_nr++)
903
share->fieldnames.type_names[fieldnr]);
905
share->field[fieldnr]= f;
907
f->init(&temp_table); /* blob default values need table obj */
909
if(!(f->flags & NOT_NULL_FLAG))
911
*f->null_ptr|= f->null_bit;
934
912
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
937
if (f_no_default(pack_flag))
938
reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
940
if (reg_field->unireg_check == Field::NEXT_NUMBER)
941
share->found_next_number_field= field_ptr;
942
if (share->timestamp_field == reg_field)
943
share->timestamp_field_offset= i;
919
enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
920
session->count_cuted_fields= CHECK_FIELD_WARN;
921
int res= default_value->save_in_field(f, 1);
922
session->count_cuted_fields= old_count_cuted_fields;
923
if (res != 0 && res != 3)
925
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
930
else if(f->real_type() == DRIZZLE_TYPE_ENUM &&
931
(f->flags & NOT_NULL_FLAG))
934
f->store((int64_t) 1, true);
939
/* hack to undo f->init() */
943
f->field_index= fieldnr;
946
&& !(f->unireg_check==Field::NEXT_NUMBER)
947
&& (f->flags & NOT_NULL_FLAG)
948
&& (f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
949
f->flags|= NO_DEFAULT_VALUE_FLAG;
951
if(f->unireg_check == Field::NEXT_NUMBER)
952
share->found_next_number_field= &(share->field[fieldnr]);
954
if(share->timestamp_field == f)
955
share->timestamp_field_offset= fieldnr;
957
if (use_hash) /* supposedly this never fails... but comments lie */
946
958
(void) my_hash_insert(&share->name_hash,
947
(unsigned char*) field_ptr); // never fail
949
*field_ptr=0; // End marker
951
/* Fix key->name and key_part->field */
954
uint32_t primary_key=(uint) (find_type((char*) primary_key_name,
959
(unsigned char*)&(share->field[fieldnr]));
963
keyinfo= share->key_info;
964
for (unsigned int keynr=0; keynr < share->keys; keynr++, keyinfo++)
966
key_part= keyinfo->key_part;
968
for(unsigned int partnr= 0;
969
partnr < keyinfo->key_parts;
970
partnr++, key_part++)
972
/* Fix up key_part->offset by adding data_offset.
973
We really should compute offset as well.
974
But at least this way we are a little better. */
975
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
980
We need to set the unused bits to 1. If the number of bits is a multiple
981
of 8 there are no unused bits.
985
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
987
share->null_bytes= (null_pos - (unsigned char*) record +
988
(null_bit_pos + 7) / 8);
990
share->last_null_bit_pos= null_bit_pos;
993
free(field_pack_length);
995
if(!(handler_file= get_new_handler(share, session->mem_root,
1000
if (share->key_parts)
1002
uint32_t primary_key=(uint32_t) (find_type((char*) "PRIMARY",
955
1003
&share->keynames, 3) - 1);
956
1005
int64_t ha_option= handler_file->ha_table_flags();
957
1007
keyinfo= share->key_info;
958
1008
key_part= keyinfo->key_part;
960
1010
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
962
1012
uint32_t usable_parts= 0;
963
keyinfo->name=(char*) share->keynames.type_names[key];
965
1014
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))