134
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
136
enum_field_types field_type;
138
switch(proto_field_type)
140
case message::Table::Field::INTEGER:
141
field_type= DRIZZLE_TYPE_LONG;
143
case message::Table::Field::DOUBLE:
144
field_type= DRIZZLE_TYPE_DOUBLE;
146
case message::Table::Field::TIMESTAMP:
147
field_type= DRIZZLE_TYPE_TIMESTAMP;
149
case message::Table::Field::BIGINT:
150
field_type= DRIZZLE_TYPE_LONGLONG;
152
case message::Table::Field::DATETIME:
153
field_type= DRIZZLE_TYPE_DATETIME;
155
case message::Table::Field::DATE:
156
field_type= DRIZZLE_TYPE_DATE;
158
case message::Table::Field::VARCHAR:
159
field_type= DRIZZLE_TYPE_VARCHAR;
161
case message::Table::Field::DECIMAL:
162
field_type= DRIZZLE_TYPE_DECIMAL;
164
case message::Table::Field::ENUM:
165
field_type= DRIZZLE_TYPE_ENUM;
167
case message::Table::Field::BLOB:
168
field_type= DRIZZLE_TYPE_BLOB;
171
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
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);
178
static Item *default_value_item(enum_field_types field_type,
179
const CHARSET_INFO *charset,
180
bool default_null, const string *default_value,
181
const string *default_bin_value)
183
Item *default_item= NULL;
188
return new Item_null();
193
case DRIZZLE_TYPE_LONG:
194
case DRIZZLE_TYPE_LONGLONG:
195
default_item= new Item_int(default_value->c_str(),
196
(int64_t) internal::my_strtoll10(default_value->c_str(),
199
default_value->length());
201
case DRIZZLE_TYPE_DOUBLE:
202
default_item= new Item_float(default_value->c_str(),
203
default_value->length());
205
case DRIZZLE_TYPE_NULL:
207
case DRIZZLE_TYPE_TIMESTAMP:
208
case DRIZZLE_TYPE_DATETIME:
209
case DRIZZLE_TYPE_DATE:
210
if (default_value->compare("NOW()") == 0)
212
case DRIZZLE_TYPE_ENUM:
213
default_item= new Item_string(default_value->c_str(),
214
default_value->length(),
215
system_charset_info);
217
case DRIZZLE_TYPE_VARCHAR:
218
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
219
if (charset==&my_charset_bin)
221
default_item= new Item_string(default_bin_value->c_str(),
222
default_bin_value->length(),
227
default_item= new Item_string(default_value->c_str(),
228
default_value->length(),
229
system_charset_info);
232
case DRIZZLE_TYPE_DECIMAL:
233
default_item= new Item_decimal(default_value->c_str(),
234
default_value->length(),
235
system_charset_info);
242
int parse_table_proto(Session& session,
243
message::Table &table,
248
if (! table.IsInitialized())
250
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
251
return ER_CORRUPT_TABLE_DEFINITION;
254
share->setTableProto(new(nothrow) message::Table(table));
256
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
257
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
259
message::Table::TableOptions table_options;
261
if (table.has_options())
262
table_options= table.options();
264
uint32_t db_create_options= 0;
266
if (table_options.has_pack_keys())
268
if (table_options.pack_keys())
269
db_create_options|= HA_OPTION_PACK_KEYS;
271
db_create_options|= HA_OPTION_NO_PACK_KEYS;
274
if (table_options.pack_record())
275
db_create_options|= HA_OPTION_PACK_RECORD;
277
/* db_create_options was stored as 2 bytes in FRM
278
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
280
share->db_create_options= (db_create_options & 0x0000FFFF);
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);
281
469
share->db_options_in_use= share->db_create_options;
283
share->row_type= table_options.has_row_type() ?
284
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
286
share->block_size= table_options.has_block_size() ?
287
table_options.block_size() : 0;
289
share->table_charset= get_charset(table_options.has_collation_id()?
290
table_options.collation_id() : 0);
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;
292
482
if (!share->table_charset)
294
484
/* unknown charset in head[38] or pre-3.23 frm */
295
485
if (use_mb(default_charset_info))
297
487
/* Warn that we may be changing the size of character columns */
298
errmsg_printf(ERRMSG_LVL_WARN,
299
_("'%s' had no or invalid character set, "
300
"and default character set is multi-byte, "
301
"so character column sizes may have changed"),
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"),
304
493
share->table_charset= default_charset_info;
307
495
share->db_record_offset= 1;
309
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
311
share->keys= table.indexes_size();
314
for (int indx= 0; indx < table.indexes_size(); indx++)
315
share->key_parts+= table.indexes(indx).index_part_size();
317
share->key_info= (KEY*) alloc_root(&share->mem_root,
318
table.indexes_size() * sizeof(KEY)
319
+share->key_parts*sizeof(KEY_PART_INFO));
321
KEY_PART_INFO *key_part;
323
key_part= reinterpret_cast<KEY_PART_INFO*>
324
(share->key_info+table.indexes_size());
327
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
328
sizeof(ulong*)*share->key_parts);
330
share->keynames.count= table.indexes_size();
331
share->keynames.name= NULL;
332
share->keynames.type_names= (const char**)
333
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
335
share->keynames.type_lengths= (unsigned int*)
336
alloc_root(&share->mem_root,
337
sizeof(unsigned int) * (table.indexes_size()+1));
339
share->keynames.type_names[share->keynames.count]= NULL;
340
share->keynames.type_lengths[share->keynames.count]= 0;
342
KEY* keyinfo= share->key_info;
343
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
345
message::Table::Index indx= table.indexes(keynr);
350
if (indx.is_unique())
351
keyinfo->flags|= HA_NOSAME;
353
if (indx.has_options())
355
message::Table::Index::IndexOptions indx_options= indx.options();
356
if (indx_options.pack_key())
357
keyinfo->flags|= HA_PACK_KEY;
359
if (indx_options.var_length_key())
360
keyinfo->flags|= HA_VAR_LENGTH_PART;
362
if (indx_options.null_part_key())
363
keyinfo->flags|= HA_NULL_PART_KEY;
365
if (indx_options.binary_pack_key())
366
keyinfo->flags|= HA_BINARY_PACK_KEY;
368
if (indx_options.has_partial_segments())
369
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
371
if (indx_options.auto_generated_key())
372
keyinfo->flags|= HA_GENERATED_KEY;
374
if (indx_options.has_key_block_size())
376
keyinfo->flags|= HA_USES_BLOCK_SIZE;
377
keyinfo->block_size= indx_options.key_block_size();
381
keyinfo->block_size= 0;
387
case message::Table::Index::UNKNOWN_INDEX:
388
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
390
case message::Table::Index::BTREE:
391
keyinfo->algorithm= HA_KEY_ALG_BTREE;
393
case message::Table::Index::HASH:
394
keyinfo->algorithm= HA_KEY_ALG_HASH;
398
/* TODO: suitable warning ? */
399
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
403
keyinfo->key_length= indx.key_length();
405
keyinfo->key_parts= indx.index_part_size();
407
keyinfo->key_part= key_part;
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 */
499
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;
408
549
keyinfo->rec_per_key= rec_per_key;
410
for (unsigned int partnr= 0;
411
partnr < keyinfo->key_parts;
412
partnr++, key_part++)
414
message::Table::Index::IndexPart part;
415
part= indx.index_part(partnr);
419
key_part->field= NULL;
420
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
421
key_part->null_bit= 0;
422
/* key_part->null_offset is only set if null_bit (see later) */
423
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
424
/* key_part->type ???? */
425
key_part->key_part_flag= 0;
426
if (part.has_in_reverse_order())
427
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
429
key_part->length= part.compare_length();
431
key_part->store_length= key_part->length;
433
/* key_part->offset is set later */
434
key_part->key_type= part.key_type();
437
if (! indx.has_comment())
439
keyinfo->comment.length= 0;
440
keyinfo->comment.str= NULL;
444
keyinfo->flags|= HA_USES_COMMENT;
445
keyinfo->comment.length= indx.comment().length();
446
keyinfo->comment.str= strmake_root(&share->mem_root,
447
indx.comment().c_str(),
448
keyinfo->comment.length);
451
keyinfo->name= strmake_root(&share->mem_root,
453
indx.name().length());
455
share->keynames.type_names[keynr]= keyinfo->name;
456
share->keynames.type_lengths[keynr]= indx.name().length();
459
share->keys_for_keyread.reset();
460
set_prefix(share->keys_in_use, share->keys);
462
share->fields= table.field_size();
464
share->field= (Field**) alloc_root(&share->mem_root,
465
((share->fields+1) * sizeof(Field*)));
466
share->field[share->fields]= NULL;
468
uint32_t null_fields= 0;
471
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
472
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
474
assert(field_offsets && field_pack_length); // TODO: fixme
476
uint32_t interval_count= 0;
477
uint32_t interval_parts= 0;
479
uint32_t stored_columns_reclength= 0;
481
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
483
message::Table::Field pfield= table.field(fieldnr);
484
if (pfield.constraints().is_nullable())
487
enum_field_types drizzle_field_type=
488
proto_field_type_to_drizzle_type(pfield.type());
490
field_offsets[fieldnr]= stored_columns_reclength;
492
/* the below switch is very similar to
493
CreateField::create_length_to_internal_length in field.cc
494
(which should one day be replace by just this code)
496
switch(drizzle_field_type)
498
case DRIZZLE_TYPE_BLOB:
499
case DRIZZLE_TYPE_VARCHAR:
501
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
503
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
504
field_options.collation_id() : 0);
507
cs= default_charset_info;
509
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
510
field_options.length() * cs->mbmaxlen);
513
case DRIZZLE_TYPE_ENUM:
515
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
517
field_pack_length[fieldnr]=
518
get_enum_pack_length(field_options.field_value_size());
521
interval_parts+= field_options.field_value_size();
524
case DRIZZLE_TYPE_DECIMAL:
526
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
528
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
532
/* Zero is okay here as length is fixed for other types. */
533
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
536
share->reclength+= field_pack_length[fieldnr];
537
stored_columns_reclength+= field_pack_length[fieldnr];
540
/* data_offset added to stored_rec_length later */
541
share->stored_rec_length= stored_columns_reclength;
543
share->null_fields= null_fields;
545
ulong null_bits= null_fields;
546
if (! table_options.pack_record())
548
ulong data_offset= (null_bits + 7)/8;
551
share->reclength+= data_offset;
552
share->stored_rec_length+= data_offset;
554
ulong rec_buff_length;
556
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
550
for (j=keyinfo->key_parts ; j-- ; key_part++)
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);
557
717
share->rec_buff_length= rec_buff_length;
559
unsigned char* record= NULL;
561
if (! (record= (unsigned char *) alloc_root(&share->mem_root,
565
memset(record, 0, rec_buff_length);
569
if (! table_options.pack_record())
571
null_count++; // one bit for delete mark.
718
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
720
goto err; /* purecov: inspected */
575
721
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)
579
share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
580
interval_count*sizeof(TYPELIB));
737
share->comment.length= (int) (forminfo[46]);
738
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
739
share->comment.length);
583
share->intervals= NULL;
585
share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
586
(share->fields + 1) * sizeof(char*));
588
share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
589
(share->fields + 1) * sizeof(unsigned int));
591
share->fieldnames.type_names[share->fields]= NULL;
592
share->fieldnames.type_lengths[share->fields]= 0;
593
share->fieldnames.count= share->fields;
596
/* Now fix the TYPELIBs for the intervals (enum values)
600
uint32_t interval_nr= 0;
602
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
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,
604
message::Table::Field pfield= table.field(fieldnr);
607
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
608
pfield.name().c_str(),
609
pfield.name().length());
611
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
614
if (pfield.type() != message::Table::Field::ENUM)
617
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
619
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
620
field_options.collation_id() : 0);
623
charset= default_charset_info;
625
TYPELIB *t= &(share->intervals[interval_nr]);
627
t->type_names= (const char**)alloc_root(&share->mem_root,
628
(field_options.field_value_size() + 1) * sizeof(char*));
630
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
631
(field_options.field_value_size() + 1) * sizeof(unsigned int));
633
t->type_names[field_options.field_value_size()]= NULL;
634
t->type_lengths[field_options.field_value_size()]= 0;
636
t->count= field_options.field_value_size();
639
for (int n= 0; n < field_options.field_value_size(); n++)
776
/* Set ENUM and SET lengths */
778
for (interval= share->intervals;
779
interval < share->intervals + interval_count;
641
t->type_names[n]= strmake_root(&share->mem_root,
642
field_options.field_value(n).c_str(),
643
field_options.field_value(n).length());
646
* Go ask the charset what the length is as for "" length=1
647
* and there's stripping spaces or some other crack going on.
650
lengthsp= charset->cset->lengthsp(charset,
652
field_options.field_value(n).length());
653
t->type_lengths[n]= lengthsp;
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;
659
/* and read the fields */
662
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
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;
665
use_hash= ! hash_init(&share->name_hash,
670
(hash_get_key) get_field_name,
674
unsigned char* null_pos= record;;
675
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
677
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
818
use_hash= !hash_init(&share->name_hash,
821
(hash_get_key) get_field_name,0,0);
823
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
679
message::Table::Field pfield= table.field(fieldnr);
825
uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
826
enum_field_types field_type;
681
827
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
683
switch (pfield.format())
685
case message::Table::Field::DefaultFormat:
686
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
688
case message::Table::Field::FixedFormat:
689
column_format= COLUMN_FORMAT_TYPE_FIXED;
691
case message::Table::Field::DynamicFormat:
692
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
698
Field::utype unireg_type= Field::NONE;
700
if (pfield.has_numeric_options() &&
701
pfield.numeric_options().is_autoincrement())
703
unireg_type= Field::NEXT_NUMBER;
706
if (pfield.has_options() &&
707
pfield.options().has_default_value() &&
708
pfield.options().default_value().compare("NOW()") == 0)
710
if (pfield.options().has_update_value() &&
711
pfield.options().update_value().compare("NOW()") == 0)
713
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
715
else if (! pfield.options().has_update_value())
717
unireg_type= Field::TIMESTAMP_DN_FIELD;
720
assert(1); // Invalid update value.
722
else if (pfield.has_options() &&
723
pfield.options().has_update_value() &&
724
pfield.options().update_value().compare("NOW()") == 0)
726
unireg_type= Field::TIMESTAMP_UN_FIELD;
828
const CHARSET_INFO *charset= NULL;
729
829
LEX_STRING comment;
730
if (!pfield.has_comment())
732
comment.str= (char*)"";
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;
737
size_t len= pfield.comment().length();
738
const char* str= pfield.comment().c_str();
740
comment.str= strmake_root(&share->mem_root, str, len);
744
enum_field_types field_type;
746
field_type= proto_field_type_to_drizzle_type(pfield.type());
748
const CHARSET_INFO *charset= &my_charset_bin;
750
if (field_type == DRIZZLE_TYPE_BLOB ||
751
field_type == DRIZZLE_TYPE_VARCHAR)
753
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
755
charset= get_charset(field_options.has_collation_id() ?
756
field_options.collation_id() : 0);
759
charset= default_charset_info;
762
if (field_type == DRIZZLE_TYPE_ENUM)
764
message::Table::Field::EnumerationValues field_options= pfield.enumeration_values();
766
charset= get_charset(field_options.has_collation_id()?
767
field_options.collation_id() : 0);
770
charset= default_charset_info;
774
if (field_type == DRIZZLE_TYPE_DECIMAL
775
|| field_type == DRIZZLE_TYPE_DOUBLE)
777
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
779
if (! pfield.has_numeric_options() || ! fo.has_scale())
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))
782
We don't write the default to table proto so
783
if no decimals specified for DOUBLE, we use the default.
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.
785
decimals= NOT_FIXED_DEC;
789
if (fo.scale() > DECIMAL_MAX_SCALE)
794
decimals= static_cast<uint8_t>(fo.scale());
798
Item *default_value= NULL;
800
if (pfield.options().has_default_value() ||
801
pfield.options().has_default_null() ||
802
pfield.options().has_default_bin_value())
804
default_value= default_value_item(field_type,
806
pfield.options().default_null(),
807
&pfield.options().default_value(),
808
&pfield.options().default_bin_value());
812
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
813
memset(&temp_table, 0, sizeof(temp_table));
815
temp_table.in_use= &session;
816
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
817
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
819
uint32_t field_length= 0; //Assignment is for compiler complaint.
823
case DRIZZLE_TYPE_BLOB:
824
case DRIZZLE_TYPE_VARCHAR:
826
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
828
charset= get_charset(field_options.has_collation_id() ?
829
field_options.collation_id() : 0);
832
charset= default_charset_info;
834
field_length= field_options.length() * charset->mbmaxlen;
837
case DRIZZLE_TYPE_DOUBLE:
839
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
840
if (!fo.has_precision() && !fo.has_scale())
842
field_length= DBL_DIG+7;
846
field_length= fo.precision();
848
if (field_length < decimals &&
849
decimals != NOT_FIXED_DEC)
851
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
857
case DRIZZLE_TYPE_DECIMAL:
859
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
861
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
865
case DRIZZLE_TYPE_TIMESTAMP:
866
case DRIZZLE_TYPE_DATETIME:
867
field_length= DateTime::MAX_STRING_LENGTH;
869
case DRIZZLE_TYPE_DATE:
870
field_length= Date::MAX_STRING_LENGTH;
872
case DRIZZLE_TYPE_ENUM:
876
message::Table::Field::EnumerationValues fo= pfield.enumeration_values();
878
for (int valnr= 0; valnr < fo.field_value_size(); valnr++)
880
if (fo.field_value(valnr).length() > field_length)
882
field_length= charset->cset->numchars(charset,
883
fo.field_value(valnr).c_str(),
884
fo.field_value(valnr).c_str()
885
+ fo.field_value(valnr).length())
891
case DRIZZLE_TYPE_LONG:
893
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
894
field_length= MAX_INT_WIDTH+sign_len;
897
case DRIZZLE_TYPE_LONGLONG:
898
field_length= MAX_BIGINT_WIDTH;
900
case DRIZZLE_TYPE_NULL:
901
abort(); // Programming error
904
Field* f= make_field(share,
906
record + field_offsets[fieldnr] + data_offset,
908
pfield.constraints().is_nullable(),
914
(Field::utype) MTYP_TYPENR(unireg_type),
915
((field_type == DRIZZLE_TYPE_ENUM) ?
916
share->intervals + (interval_nr++)
918
share->fieldnames.type_names[fieldnr]);
920
share->field[fieldnr]= f;
922
f->init(&temp_table); /* blob default values need table obj */
924
if (! (f->flags & NOT_NULL_FLAG))
926
*f->null_ptr|= f->null_bit;
927
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
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))
934
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
934
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
935
session.count_cuted_fields= CHECK_FIELD_WARN;
936
int res= default_value->save_in_field(f, 1);
937
session.count_cuted_fields= old_count_cuted_fields;
938
if (res != 0 && res != 3) /* @TODO Huh? */
940
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
945
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
946
(f->flags & NOT_NULL_FLAG))
949
f->store((int64_t) 1, true);
954
/* hack to undo f->init() */
958
f->field_index= fieldnr;
960
if (! default_value &&
961
! (f->unireg_check==Field::NEXT_NUMBER) &&
962
(f->flags & NOT_NULL_FLAG) &&
963
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
965
f->flags|= NO_DEFAULT_VALUE_FLAG;
968
if (f->unireg_check == Field::NEXT_NUMBER)
969
share->found_next_number_field= &(share->field[fieldnr]);
971
if (share->timestamp_field == f)
972
share->timestamp_field_offset= fieldnr;
974
if (use_hash) /* supposedly this never fails... but comments lie */
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;
975
946
(void) my_hash_insert(&share->name_hash,
976
(unsigned char*)&(share->field[fieldnr]));
980
keyinfo= share->key_info;
981
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
983
key_part= keyinfo->key_part;
985
for (unsigned int partnr= 0;
986
partnr < keyinfo->key_parts;
987
partnr++, key_part++)
990
* Fix up key_part->offset by adding data_offset.
991
* We really should compute offset as well.
992
* But at least this way we are a little better.
994
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
999
We need to set the unused bits to 1. If the number of bits is a multiple
1000
of 8 there are no unused bits.
1004
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1006
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1008
share->last_null_bit_pos= null_bit_pos;
1010
free(field_offsets);
1011
field_offsets= NULL;
1012
free(field_pack_length);
1013
field_pack_length= NULL;
1016
if (share->key_parts)
1018
uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1019
&share->keynames, 3) - 1); /* @TODO Huh? */
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,
955
&share->keynames, 3) - 1);
956
int64_t ha_option= handler_file->ha_table_flags();
1021
957
keyinfo= share->key_info;
1022
958
key_part= keyinfo->key_part;
1024
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
960
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1026
962
uint32_t usable_parts= 0;
963
keyinfo->name=(char*) share->keynames.type_names[key];
1028
965
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1031
If the UNIQUE key doesn't have NULL columns and is not a part key
1032
declare this as a primary key.
1035
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1037
uint32_t fieldnr= key_part[i].fieldnr;
1039
share->field[fieldnr-1]->null_ptr ||
1040
share->field[fieldnr-1]->key_length() != key_part[i].length)
1042
primary_key= MAX_KEY; // Can't be used
968
If the UNIQUE key doesn't have NULL columns and is not a part key
969
declare this as a primary key.
972
for (i=0 ; i < keyinfo->key_parts ;i++)
974
uint32_t fieldnr= key_part[i].fieldnr;
976
share->field[fieldnr-1]->null_ptr ||
977
share->field[fieldnr-1]->key_length() !=
980
primary_key=MAX_KEY; // Can't be used
1048
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
986
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1051
if (! key_part->fieldnr)
989
if (new_field_pack_flag <= 1)
990
key_part->fieldnr= (uint16_t) find_field(share->field,
991
share->default_values,
992
(uint) key_part->offset,
993
(uint) key_part->length);
994
if (!key_part->fieldnr)
1053
abort(); // goto err;
996
error= 4; // Wrong file
1055
999
field= key_part->field= share->field[key_part->fieldnr-1];
1056
1000
key_part->type= field->key_type();
1057
1001
if (field->null_ptr)
1059
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1003
key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1060
1004
share->default_values);
1061
1005
key_part->null_bit= field->null_bit;
1062
1006
key_part->store_length+=HA_KEY_NULL_LENGTH;
1987
2240
/* Error if empty or too long column name */
1988
return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2241
return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2246
Checks whether a table is intact. Should be done *just* after the table has
2249
@param[in] table The table to check
2250
@param[in] table_f_count Expected number of columns in the table
2251
@param[in] table_def Expected structure of the table (column name
2255
@retval TRUE There was an error. An error message is output
2256
to the error log. We do not push an error
2257
message into the error stack because this
2258
function is currently only called at start up,
2259
and such errors never reach the user.
2263
Table::table_check_intact(const uint32_t table_f_count,
2264
const TABLE_FIELD_W_TYPE *table_def)
2268
bool fields_diff_count;
2270
fields_diff_count= (s->fields != table_f_count);
2271
if (fields_diff_count)
2274
/* previous MySQL version */
2275
if (DRIZZLE_VERSION_ID > s->mysql_version)
2277
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2278
alias, table_f_count, s->fields,
2279
s->mysql_version, DRIZZLE_VERSION_ID);
2282
else if (DRIZZLE_VERSION_ID == s->mysql_version)
2284
sql_print_error(ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2285
table_f_count, s->fields);
2289
Something has definitely changed, but we're running an older
2290
version of MySQL with new system tables.
2291
Let's check column definitions. If a column was added at
2292
the end of the table, then we don't care much since such change
2293
is backward compatible.
2296
char buffer[STRING_BUFFER_USUAL_SIZE];
2297
for (i=0 ; i < table_f_count; i++, table_def++)
2299
String sql_type(buffer, sizeof(buffer), system_charset_info);
2303
Field *field= this->field[i];
2305
if (strncmp(field->field_name, table_def->name.str,
2306
table_def->name.length))
2309
Name changes are not fatal, we use ordinal numbers to access columns.
2310
Still this can be a sign of a tampered table, output an error
2313
sql_print_error(_("Incorrect definition of table %s.%s: "
2314
"expected column '%s' at position %d, found '%s'."),
2315
s->db.str, alias, table_def->name.str, i,
2318
field->sql_type(sql_type);
2320
Generally, if column types don't match, then something is
2323
However, we only compare column definitions up to the
2324
length of the original definition, since we consider the
2325
following definitions compatible:
2327
1. DATETIME and DATETIM
2328
2. INT(11) and INT(11
2329
3. SET('one', 'two') and SET('one', 'two', 'more')
2331
For SETs or ENUMs, if the same prefix is there it's OK to
2332
add more elements - they will get higher ordinal numbers and
2333
the new table definition is backward compatible with the
2336
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2337
table_def->type.length - 1))
2339
sql_print_error(_("Incorrect definition of table %s.%s: "
2340
"expected column '%s' at position %d to have type "
2341
"%s, found type %s."), s->db.str, alias,
2342
table_def->name.str, i, table_def->type.str,
2343
sql_type.c_ptr_safe());
2346
else if (table_def->cset.str && !field->has_charset())
2348
sql_print_error(_("Incorrect definition of table %s.%s: "
2349
"expected the type of column '%s' at position %d "
2350
"to have character set '%s' but the type has no "
2351
"character set."), s->db.str, alias,
2352
table_def->name.str, i, table_def->cset.str);
2355
else if (table_def->cset.str &&
2356
strcmp(field->charset()->csname, table_def->cset.str))
2358
sql_print_error(_("Incorrect definition of table %s.%s: "
2359
"expected the type of column '%s' at position %d "
2360
"to have character set '%s' but found "
2361
"character set '%s'."), s->db.str, alias,
2362
table_def->name.str, i, table_def->cset.str,
2363
field->charset()->csname);
2369
sql_print_error(_("Incorrect definition of table %s.%s: "
2370
"expected column '%s' at position %d to have type %s "
2371
" but the column is not found."),
2373
table_def->name.str, i, table_def->type.str);
2382
Create Item_field for each column in the table.
2385
Table::fill_item_list()
2386
item_list a pointer to an empty list used to store items
2389
Create Item_field object for each column in the table and
2390
initialize it with the corresponding Field. New items are
2391
created in the current THD memory root.
2398
bool Table::fill_item_list(List<Item> *item_list) const
2401
All Item_field's created using a direct pointer to a field
2402
are fixed in Item_field constructor.
2404
for (Field **ptr= field; *ptr; ptr++)
2406
Item_field *item= new Item_field(*ptr);
2407
if (!item || item_list->push_back(item))
2414
Reset an existing list of Item_field items to point to the
2415
Fields of this table.
2418
Table::fill_item_list()
2419
item_list a non-empty list with Item_fields
2422
This is a counterpart of fill_item_list used to redirect
2423
Item_fields to the fields of a newly created table.
2424
The caller must ensure that number of items in the item_list
2425
is the same as the number of columns in the table.
2428
void Table::reset_item_list(List<Item> *item_list) const
2430
List_iterator_fast<Item> it(*item_list);
2431
for (Field **ptr= field; *ptr; ptr++)
2433
Item_field *item_field= (Item_field*) it++;
2434
assert(item_field != 0);
2435
item_field->reset_field(*ptr);
2441
Find underlying base tables (TableList) which represent given
2442
table_to_find (Table)
2445
TableList::find_underlying_table()
2446
table_to_find table to find
2449
0 table is not found
2450
found table reference
2453
TableList *TableList::find_underlying_table(Table *table_to_find)
2455
/* is this real table and table which we are looking for? */
2456
if (table == table_to_find && merge_underlying_list == 0)
2459
for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2462
if ((result= tbl->find_underlying_table(table_to_find)))
2469
cleunup items belonged to view fields translation table
2472
TableList::cleanup_items()
2475
void TableList::cleanup_items()
2477
if (!field_translation)
2480
for (Field_translator *transl= field_translation;
2481
transl < field_translation_end;
2483
transl->item->walk(&Item::cleanup_processor, 0, 0);
2488
Set insert_values buffer
2492
mem_root memory pool for allocating
2496
TRUE - out of memory
2499
bool TableList::set_insert_values(MEM_ROOT *mem_root)
2503
if (!table->insert_values &&
2504
!(table->insert_values= (unsigned char *)alloc_root(mem_root,
2505
table->s->rec_buff_length)))
2514
Test if this is a leaf with respect to name resolution.
2517
TableList::is_leaf_for_name_resolution()
2520
A table reference is a leaf with respect to name resolution if
2521
it is either a leaf node in a nested join tree (table, view,
2522
schema table, subquery), or an inner node that represents a
2523
NATURAL/USING join, or a nested join with materialized join
2527
TRUE if a leaf, false otherwise.
2529
bool TableList::is_leaf_for_name_resolution()
2531
return (is_natural_join || is_join_columns_complete || !nested_join);
2536
Retrieve the first (left-most) leaf in a nested join tree with
2537
respect to name resolution.
2540
TableList::first_leaf_for_name_resolution()
2543
Given that 'this' is a nested table reference, recursively walk
2544
down the left-most children of 'this' until we reach a leaf
2545
table reference with respect to name resolution.
2548
The left-most child of a nested table reference is the last element
2549
in the list of children because the children are inserted in
2553
If 'this' is a nested table reference - the left-most child of
2554
the tree rooted in 'this',
2558
TableList *TableList::first_leaf_for_name_resolution()
2560
TableList *cur_table_ref= NULL;
2561
nested_join_st *cur_nested_join;
2563
if (is_leaf_for_name_resolution())
2565
assert(nested_join);
2567
for (cur_nested_join= nested_join;
2569
cur_nested_join= cur_table_ref->nested_join)
2571
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2572
cur_table_ref= it++;
2574
If the current nested join is a RIGHT JOIN, the operands in
2575
'join_list' are in reverse order, thus the first operand is
2576
already at the front of the list. Otherwise the first operand
2577
is in the end of the list of join operands.
2579
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2582
while ((next= it++))
2583
cur_table_ref= next;
2585
if (cur_table_ref->is_leaf_for_name_resolution())
2588
return cur_table_ref;
2593
Retrieve the last (right-most) leaf in a nested join tree with
2594
respect to name resolution.
2597
TableList::last_leaf_for_name_resolution()
2600
Given that 'this' is a nested table reference, recursively walk
2601
down the right-most children of 'this' until we reach a leaf
2602
table reference with respect to name resolution.
2605
The right-most child of a nested table reference is the first
2606
element in the list of children because the children are inserted
2610
- If 'this' is a nested table reference - the right-most child of
2611
the tree rooted in 'this',
2615
TableList *TableList::last_leaf_for_name_resolution()
2617
TableList *cur_table_ref= this;
2618
nested_join_st *cur_nested_join;
2620
if (is_leaf_for_name_resolution())
2622
assert(nested_join);
2624
for (cur_nested_join= nested_join;
2626
cur_nested_join= cur_table_ref->nested_join)
2628
cur_table_ref= cur_nested_join->join_list.head();
2630
If the current nested is a RIGHT JOIN, the operands in
2631
'join_list' are in reverse order, thus the last operand is in the
2634
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2636
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2638
cur_table_ref= it++;
2639
while ((next= it++))
2640
cur_table_ref= next;
2642
if (cur_table_ref->is_leaf_for_name_resolution())
2645
return cur_table_ref;