144
static enum_field_types proto_field_type_to_drizzle_type(uint32_t proto_field_type)
146
enum_field_types field_type;
148
switch(proto_field_type)
150
case message::Table::Field::INTEGER:
151
field_type= DRIZZLE_TYPE_LONG;
153
case message::Table::Field::DOUBLE:
154
field_type= DRIZZLE_TYPE_DOUBLE;
156
case message::Table::Field::TIMESTAMP:
157
field_type= DRIZZLE_TYPE_TIMESTAMP;
159
case message::Table::Field::BIGINT:
160
field_type= DRIZZLE_TYPE_LONGLONG;
162
case message::Table::Field::DATETIME:
163
field_type= DRIZZLE_TYPE_DATETIME;
165
case message::Table::Field::DATE:
166
field_type= DRIZZLE_TYPE_DATE;
168
case message::Table::Field::VARCHAR:
169
field_type= DRIZZLE_TYPE_VARCHAR;
171
case message::Table::Field::DECIMAL:
172
field_type= DRIZZLE_TYPE_DECIMAL;
174
case message::Table::Field::ENUM:
175
field_type= DRIZZLE_TYPE_ENUM;
177
case message::Table::Field::BLOB:
178
field_type= DRIZZLE_TYPE_BLOB;
181
field_type= DRIZZLE_TYPE_LONG; /* Set value to kill GCC warning */
182
Initialize share for temporary tables
185
init_tmp_table_share()
186
session thread handle
188
key Table_cache_key, as generated from create_table_def_key.
189
must start with db name.
190
key_length Length of key
191
table_name Table name
192
path Path to file (possible in lower case) without .frm
195
This is different from alloc_table_share() because temporary tables
196
don't have to be shared between threads or put into the table def
197
cache, so we can do some things notable simpler and faster
199
If table is not put in session->temporary_tables (happens only when
200
one uses OPEN TEMPORARY) then one can specify 'db' as key and
201
use key_length= 0 as neither table_cache_key or key_length will be used).
204
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
205
uint32_t key_length, const char *table_name,
209
memset(share, 0, sizeof(*share));
210
init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
211
share->table_category= TABLE_CATEGORY_TEMPORARY;
212
share->tmp_table= INTERNAL_TMP_TABLE;
213
share->db.str= (char*) key;
214
share->db.length= strlen(key);
215
share->table_cache_key.str= (char*) key;
216
share->table_cache_key.length= key_length;
217
share->table_name.str= (char*) table_name;
218
share->table_name.length= strlen(table_name);
219
share->path.str= (char*) path;
220
share->normalized_path.str= (char*) path;
221
share->path.length= share->normalized_path.length= strlen(path);
224
Temporary tables are not replicated, but we set up these fields
225
anyway to be able to catch errors.
227
share->table_map_version= ~(uint64_t)0;
228
share->cached_row_logging_check= -1;
231
table_map_id is also used for MERGE tables to suppress repeated
232
compatibility checks.
234
share->table_map_id= (ulong) session->query_id;
241
Free table share and memory used by it
248
share->mutex must be locked when we come here if it's not a temp table
251
void free_table_share(TABLE_SHARE *share)
254
assert(share->ref_count == 0);
257
If someone is waiting for this to be deleted, inform it about this.
258
Don't do a delete until we know that no one is refering to this anymore.
260
if (share->tmp_table == NO_TMP_TABLE)
262
/* share->mutex is locked in release_table_share() */
263
while (share->waiting_on_cond)
265
pthread_cond_broadcast(&share->cond);
266
pthread_cond_wait(&share->cond, &share->mutex);
268
/* No thread refers to this anymore */
269
pthread_mutex_unlock(&share->mutex);
270
pthread_mutex_destroy(&share->mutex);
271
pthread_cond_destroy(&share->cond);
273
hash_free(&share->name_hash);
275
plugin_unlock(NULL, share->db_plugin);
276
share->db_plugin= NULL;
278
/* We must copy mem_root from share because share is allocated through it */
279
memcpy(&mem_root, &share->mem_root, sizeof(mem_root));
280
free_root(&mem_root, MYF(0)); // Free's share
285
Read table definition from a binary / text based .frm file
289
session Thread handler
290
share Fill this with table definition
291
db_flags Bit mask of the following flags: OPEN_VIEW
294
This function is called when the table definition is not cached in
296
The data is returned in 'share', which is alloced by
297
alloc_table_share().. The code assumes that share is initialized.
301
1 Error (see open_table_error)
302
2 Error (see open_table_error)
303
3 Wrong data in .frm file
304
4 Error (see open_table_error)
305
5 Error (see open_table_error: charset unavailable)
306
6 Unknown .frm version
309
int open_table_def(Session *session, TABLE_SHARE *share, uint32_t)
311
int error, table_type;
314
unsigned char head[64], *disk_buff;
317
MEM_ROOT **root_ptr, *old_root;
323
path.reserve(FN_REFLEN);
324
path.append(share->normalized_path.str);
325
path.append(reg_ext);
326
if ((file= open(path.c_str(), O_RDONLY)) < 0)
329
We don't try to open 5.0 unencoded name, if
330
- non-encoded name contains '@' signs,
331
because '@' can be misinterpreted.
332
It is not clear if '@' is escape character in 5.1,
333
or a normal character in 5.0.
335
- non-encoded db or table name contain "#mysql50#" prefix.
336
This kind of tables must have been opened only by the
339
if (strchr(share->table_name.str, '@') ||
340
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
341
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
342
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
343
MYSQL50_TABLE_NAME_PREFIX_LENGTH))
346
/* Try unencoded 5.0 name */
348
char unpacked_path[FN_REFLEN];
350
path.append(drizzle_data_home);
352
path.append(share->db.str);
354
path.append(share->table_name.str);
355
path.append(reg_ext);
356
length= unpack_filename(unpacked_path, path.c_str()) - reg_ext_length;
358
The following is a safety test and should never fail
359
as the old file name should never be longer than the new one.
361
assert(length <= share->normalized_path.length);
363
If the old and the new names have the same length,
364
then table name does not have tricky characters,
365
so no need to check the old file name.
367
if (length == share->normalized_path.length ||
368
((file= open(unpacked_path, O_RDONLY)) < 0))
371
/* Unencoded 5.0 table name found */
372
unpacked_path[length]= '\0'; // Remove .frm extension
373
strcpy(share->normalized_path.str, unpacked_path);
374
share->normalized_path.length= length;
378
if (my_read(file, head, 64, MYF(MY_NABP)))
381
if (head[0] == (unsigned char) 254 && head[1] == 1)
383
if (head[2] == FRM_VER || head[2] == FRM_VER+1 ||
384
(head[2] >= FRM_VER+3 && head[2] <= FRM_VER+4))
390
error= 6; // Unkown .frm version
397
/* No handling of text based files yet */
400
root_ptr= current_mem_root_ptr();
402
*root_ptr= &share->mem_root;
403
error= open_binary_frm(session, share, head, file);
188
static Item *default_value_item(enum_field_types field_type,
189
const CHARSET_INFO *charset,
190
bool default_null, const string *default_value,
191
const string *default_bin_value)
193
Item *default_item= NULL;
198
return new Item_null();
203
case DRIZZLE_TYPE_LONG:
204
case DRIZZLE_TYPE_LONGLONG:
205
default_item= new Item_int(default_value->c_str(),
206
(int64_t) internal::my_strtoll10(default_value->c_str(),
209
default_value->length());
211
case DRIZZLE_TYPE_DOUBLE:
212
default_item= new Item_float(default_value->c_str(),
213
default_value->length());
215
case DRIZZLE_TYPE_NULL:
217
case DRIZZLE_TYPE_TIMESTAMP:
218
case DRIZZLE_TYPE_DATETIME:
219
case DRIZZLE_TYPE_DATE:
220
if (default_value->compare("NOW()") == 0)
222
case DRIZZLE_TYPE_ENUM:
223
default_item= new Item_string(default_value->c_str(),
224
default_value->length(),
225
system_charset_info);
227
case DRIZZLE_TYPE_VARCHAR:
228
case DRIZZLE_TYPE_BLOB: /* Blob is here due to TINYTEXT. Feel the hate. */
229
if (charset==&my_charset_bin)
231
default_item= new Item_string(default_bin_value->c_str(),
232
default_bin_value->length(),
237
default_item= new Item_string(default_value->c_str(),
238
default_value->length(),
239
system_charset_info);
242
case DRIZZLE_TYPE_DECIMAL:
243
default_item= new Item_decimal(default_value->c_str(),
244
default_value->length(),
245
system_charset_info);
252
int parse_table_proto(Session& session,
253
message::Table &table,
258
if (! table.IsInitialized())
260
my_error(ER_CORRUPT_TABLE_DEFINITION, MYF(0), table.InitializationErrorString().c_str());
261
return ER_CORRUPT_TABLE_DEFINITION;
264
share->setTableProto(new(nothrow) message::Table(table));
266
share->storage_engine= plugin::StorageEngine::findByName(session, table.engine().name());
267
assert(share->storage_engine); // We use an assert() here because we should never get this far and still have no suitable engine.
269
message::Table::TableOptions table_options;
271
if (table.has_options())
272
table_options= table.options();
274
uint32_t db_create_options= 0;
276
if (table_options.has_pack_keys())
278
if (table_options.pack_keys())
279
db_create_options|= HA_OPTION_PACK_KEYS;
281
db_create_options|= HA_OPTION_NO_PACK_KEYS;
284
if (table_options.pack_record())
285
db_create_options|= HA_OPTION_PACK_RECORD;
287
/* db_create_options was stored as 2 bytes in FRM
288
Any HA_OPTION_ that doesn't fit into 2 bytes was silently truncated away.
290
share->db_create_options= (db_create_options & 0x0000FFFF);
410
share->table_category= get_table_category(& share->db, & share->table_name);
413
session->status_var.opened_shares++;
416
my_close(file, MYF(MY_WME));
419
if (error && !error_given)
422
open_table_error(share, error, (share->open_errno= my_errno), 0);
430
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
433
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
436
int error, errarg= 0;
437
uint32_t new_frm_ver, field_pack_length, new_field_pack_flag;
438
uint32_t interval_count, interval_parts, read_length, int_length;
439
uint32_t db_create_options, keys, key_parts, n_length;
440
uint32_t key_info_length, com_length, null_bit_pos=0;
441
uint32_t vcol_screen_length;
442
uint32_t extra_rec_buf_length;
445
unsigned char forminfo[288];
446
char *keynames, *names, *comment_pos, *vcol_screen_pos;
447
unsigned char *record;
448
unsigned char *disk_buff, *strpos, *null_flags=NULL, *null_pos=NULL;
449
ulong pos, record_offset, *rec_per_key, rec_buff_length;
450
handler *handler_file= 0;
452
KEY_PART_INFO *key_part;
453
Field **field_ptr, *reg_field;
454
const char **interval_array;
455
enum legacy_db_type legacy_db_type;
456
my_bitmap_map *bitmaps;
457
unsigned char *buff= 0;
458
unsigned char *field_extra_info= 0;
460
new_field_pack_flag= head[27];
461
new_frm_ver= (head[2] - FRM_VER);
462
field_pack_length= new_frm_ver < 2 ? 11 : 17;
466
if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
467
goto err; /* purecov: inspected */
468
lseek(file,pos,SEEK_SET);
469
if (my_read(file,forminfo,288,MYF(MY_NABP)))
472
legacy_db_type= DB_TYPE_FIRST_DYNAMIC;
473
assert(share->db_plugin == NULL);
475
if the storage engine is dynamic, no point in resolving it by its
476
dynamically allocated legacy_db_type. We will resolve it later by name.
478
if (legacy_db_type > DB_TYPE_UNKNOWN &&
479
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
480
share->db_plugin= ha_lock_engine(NULL,
481
ha_checktype(session, legacy_db_type, 0, 0));
482
share->db_create_options= db_create_options= uint2korr(head+30);
291
483
share->db_options_in_use= share->db_create_options;
293
share->row_type= table_options.has_row_type() ?
294
(enum row_type) table_options.row_type() : ROW_TYPE_DEFAULT;
296
share->block_size= table_options.has_block_size() ?
297
table_options.block_size() : 0;
299
share->table_charset= get_charset(table_options.has_collation_id()?
300
table_options.collation_id() : 0);
484
share->mysql_version= uint4korr(head+51);
485
share->null_field_first= 0;
486
if (!head[32]) // New frm file in 3.23
488
share->avg_row_length= uint4korr(head+34);
489
share->transactional= (ha_choice) (head[39] & 3);
490
share->page_checksum= (ha_choice) ((head[39] >> 2) & 3);
491
share->row_type= (row_type) head[40];
492
share->block_size= uint4korr(head+43);
493
share->table_charset= get_charset((uint) head[38],MYF(0));
494
share->null_field_first= 1;
302
496
if (!share->table_charset)
304
498
/* unknown charset in head[38] or pre-3.23 frm */
305
499
if (use_mb(default_charset_info))
307
501
/* Warn that we may be changing the size of character columns */
308
errmsg_printf(ERRMSG_LVL_WARN,
309
_("'%s' had no or invalid character set, "
310
"and default character set is multi-byte, "
311
"so character column sizes may have changed"),
502
errmsg_printf(ERRMSG_LVL_WARN, _("'%s' had no or invalid character set, "
503
"and default character set is multi-byte, "
504
"so character column sizes may have changed"),
314
507
share->table_charset= default_charset_info;
317
509
share->db_record_offset= 1;
319
share->blob_ptr_size= portable_sizeof_char_ptr; // more bonghits.
321
share->keys= table.indexes_size();
324
for (int indx= 0; indx < table.indexes_size(); indx++)
325
share->key_parts+= table.indexes(indx).index_part_size();
327
share->key_info= (KEY*) alloc_root(&share->mem_root,
328
table.indexes_size() * sizeof(KEY)
329
+share->key_parts*sizeof(KEY_PART_INFO));
331
KEY_PART_INFO *key_part;
333
key_part= reinterpret_cast<KEY_PART_INFO*>
334
(share->key_info+table.indexes_size());
337
ulong *rec_per_key= (ulong*) alloc_root(&share->mem_root,
338
sizeof(ulong*)*share->key_parts);
340
share->keynames.count= table.indexes_size();
341
share->keynames.name= NULL;
342
share->keynames.type_names= (const char**)
343
alloc_root(&share->mem_root, sizeof(char*) * (table.indexes_size()+1));
345
share->keynames.type_lengths= (unsigned int*)
346
alloc_root(&share->mem_root,
347
sizeof(unsigned int) * (table.indexes_size()+1));
349
share->keynames.type_names[share->keynames.count]= NULL;
350
share->keynames.type_lengths[share->keynames.count]= 0;
352
KEY* keyinfo= share->key_info;
353
for (int keynr= 0; keynr < table.indexes_size(); keynr++, keyinfo++)
355
message::Table::Index indx= table.indexes(keynr);
360
if (indx.is_unique())
361
keyinfo->flags|= HA_NOSAME;
363
if (indx.has_options())
365
message::Table::Index::IndexOptions indx_options= indx.options();
366
if (indx_options.pack_key())
367
keyinfo->flags|= HA_PACK_KEY;
369
if (indx_options.var_length_key())
370
keyinfo->flags|= HA_VAR_LENGTH_PART;
372
if (indx_options.null_part_key())
373
keyinfo->flags|= HA_NULL_PART_KEY;
375
if (indx_options.binary_pack_key())
376
keyinfo->flags|= HA_BINARY_PACK_KEY;
378
if (indx_options.has_partial_segments())
379
keyinfo->flags|= HA_KEY_HAS_PART_KEY_SEG;
381
if (indx_options.auto_generated_key())
382
keyinfo->flags|= HA_GENERATED_KEY;
384
if (indx_options.has_key_block_size())
386
keyinfo->flags|= HA_USES_BLOCK_SIZE;
387
keyinfo->block_size= indx_options.key_block_size();
391
keyinfo->block_size= 0;
397
case message::Table::Index::UNKNOWN_INDEX:
398
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
400
case message::Table::Index::BTREE:
401
keyinfo->algorithm= HA_KEY_ALG_BTREE;
403
case message::Table::Index::HASH:
404
keyinfo->algorithm= HA_KEY_ALG_HASH;
408
/* TODO: suitable warning ? */
409
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
413
keyinfo->key_length= indx.key_length();
415
keyinfo->key_parts= indx.index_part_size();
417
keyinfo->key_part= key_part;
510
if (db_create_options & HA_OPTION_LONG_BLOB_PTR)
511
share->blob_ptr_size= portable_sizeof_char_ptr;
512
/* Set temporarily a good value for db_low_byte_first */
513
share->db_low_byte_first= true;
515
share->max_rows= uint4korr(head+18);
516
share->min_rows= uint4korr(head+22);
518
/* Read keyinformation */
519
key_info_length= (uint) uint2korr(head+28);
520
lseek(file,(ulong) uint2korr(head+6),SEEK_SET);
521
if (read_string(file,(unsigned char**) &disk_buff,key_info_length))
522
goto err; /* purecov: inspected */
523
if (disk_buff[0] & 0x80)
525
share->keys= keys= (disk_buff[1] << 7) | (disk_buff[0] & 0x7f);
526
share->key_parts= key_parts= uint2korr(disk_buff+2);
530
share->keys= keys= disk_buff[0];
531
share->key_parts= key_parts= disk_buff[1];
533
share->keys_for_keyread.init(0);
534
share->keys_in_use.init(keys);
536
n_length=keys*sizeof(KEY)+key_parts*sizeof(KEY_PART_INFO);
537
if (!(keyinfo = (KEY*) alloc_root(&share->mem_root,
538
n_length + uint2korr(disk_buff+4))))
539
goto err; /* purecov: inspected */
540
memset(keyinfo, 0, n_length);
541
share->key_info= keyinfo;
542
key_part= reinterpret_cast<KEY_PART_INFO*> (keyinfo+keys);
545
if (!(rec_per_key= (ulong*) alloc_root(&share->mem_root,
546
sizeof(ulong*)*key_parts)))
549
for (i=0 ; i < keys ; i++, keyinfo++)
551
keyinfo->table= 0; // Updated in open_frm
552
if (new_frm_ver >= 3)
554
keyinfo->flags= (uint) uint2korr(strpos) ^ HA_NOSAME;
555
keyinfo->key_length= (uint) uint2korr(strpos+2);
556
keyinfo->key_parts= (uint) strpos[4];
557
keyinfo->algorithm= (enum ha_key_alg) strpos[5];
558
keyinfo->block_size= uint2korr(strpos+6);
562
keyinfo->key_part= key_part;
418
563
keyinfo->rec_per_key= rec_per_key;
420
for (unsigned int partnr= 0;
421
partnr < keyinfo->key_parts;
422
partnr++, key_part++)
424
message::Table::Index::IndexPart part;
425
part= indx.index_part(partnr);
429
key_part->field= NULL;
430
key_part->fieldnr= part.fieldnr() + 1; // start from 1.
431
key_part->null_bit= 0;
432
/* key_part->null_offset is only set if null_bit (see later) */
433
/* key_part->key_type= */ /* I *THINK* this may be okay.... */
434
/* key_part->type ???? */
435
key_part->key_part_flag= 0;
436
if (part.has_in_reverse_order())
437
key_part->key_part_flag= part.in_reverse_order()? HA_REVERSE_SORT : 0;
439
key_part->length= part.compare_length();
441
key_part->store_length= key_part->length;
443
/* key_part->offset is set later */
444
key_part->key_type= part.key_type();
447
if (! indx.has_comment())
449
keyinfo->comment.length= 0;
450
keyinfo->comment.str= NULL;
454
keyinfo->flags|= HA_USES_COMMENT;
455
keyinfo->comment.length= indx.comment().length();
456
keyinfo->comment.str= strmake_root(&share->mem_root,
457
indx.comment().c_str(),
458
keyinfo->comment.length);
461
keyinfo->name= strmake_root(&share->mem_root,
463
indx.name().length());
465
share->keynames.type_names[keynr]= keyinfo->name;
466
share->keynames.type_lengths[keynr]= indx.name().length();
469
share->keys_for_keyread.reset();
470
set_prefix(share->keys_in_use, share->keys);
472
share->fields= table.field_size();
474
share->field= (Field**) alloc_root(&share->mem_root,
475
((share->fields+1) * sizeof(Field*)));
476
share->field[share->fields]= NULL;
478
uint32_t null_fields= 0;
481
uint32_t *field_offsets= (uint32_t*)malloc(share->fields * sizeof(uint32_t));
482
uint32_t *field_pack_length=(uint32_t*)malloc(share->fields*sizeof(uint32_t));
484
assert(field_offsets && field_pack_length); // TODO: fixme
486
uint32_t interval_count= 0;
487
uint32_t interval_parts= 0;
489
uint32_t stored_columns_reclength= 0;
491
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
493
message::Table::Field pfield= table.field(fieldnr);
494
if (pfield.constraints().is_nullable())
497
enum_field_types drizzle_field_type=
498
proto_field_type_to_drizzle_type(pfield.type());
500
field_offsets[fieldnr]= stored_columns_reclength;
502
/* the below switch is very similar to
503
CreateField::create_length_to_internal_length in field.cc
504
(which should one day be replace by just this code)
506
switch(drizzle_field_type)
508
case DRIZZLE_TYPE_BLOB:
509
case DRIZZLE_TYPE_VARCHAR:
511
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
513
const CHARSET_INFO *cs= get_charset(field_options.has_collation_id() ?
514
field_options.collation_id() : 0);
517
cs= default_charset_info;
519
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type,
520
field_options.length() * cs->mbmaxlen);
523
case DRIZZLE_TYPE_ENUM:
525
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
527
field_pack_length[fieldnr]=
528
get_enum_pack_length(field_options.field_value_size());
531
interval_parts+= field_options.field_value_size();
534
case DRIZZLE_TYPE_DECIMAL:
536
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
538
field_pack_length[fieldnr]= my_decimal_get_binary_size(fo.precision(), fo.scale());
542
/* Zero is okay here as length is fixed for other types. */
543
field_pack_length[fieldnr]= calc_pack_length(drizzle_field_type, 0);
546
share->reclength+= field_pack_length[fieldnr];
547
stored_columns_reclength+= field_pack_length[fieldnr];
550
/* data_offset added to stored_rec_length later */
551
share->stored_rec_length= stored_columns_reclength;
553
share->null_fields= null_fields;
555
ulong null_bits= null_fields;
556
if (! table_options.pack_record())
558
ulong data_offset= (null_bits + 7)/8;
561
share->reclength+= data_offset;
562
share->stored_rec_length+= data_offset;
564
ulong rec_buff_length;
566
rec_buff_length= ALIGN_SIZE(share->reclength + 1);
564
for (j=keyinfo->key_parts ; j-- ; key_part++)
567
key_part->fieldnr= (uint16_t) (uint2korr(strpos) & FIELD_NR_MASK);
568
key_part->offset= (uint) uint2korr(strpos+2)-1;
569
key_part->key_type= (uint) uint2korr(strpos+5);
570
// key_part->field= (Field*) 0; // Will be fixed later
571
if (new_frm_ver >= 1)
573
key_part->key_part_flag= *(strpos+4);
574
key_part->length= (uint) uint2korr(strpos+7);
579
key_part->length= *(strpos+4);
580
key_part->key_part_flag=0;
581
if (key_part->length > 128)
583
key_part->length&=127; /* purecov: inspected */
584
key_part->key_part_flag=HA_REVERSE_SORT; /* purecov: inspected */
588
key_part->store_length=key_part->length;
591
keynames=(char*) key_part;
592
strpos+= (strcpy(keynames, (char*)strpos)+strlen((char*)strpos)-keynames)+1;
594
//reading index comments
595
for (keyinfo= share->key_info, i=0; i < keys; i++, keyinfo++)
597
if (keyinfo->flags & HA_USES_COMMENT)
599
keyinfo->comment.length= uint2korr(strpos);
600
keyinfo->comment.str= strmake_root(&share->mem_root, (char*) strpos+2,
601
keyinfo->comment.length);
602
strpos+= 2 + keyinfo->comment.length;
604
assert(test(keyinfo->flags & HA_USES_COMMENT) ==
605
(keyinfo->comment.length > 0));
608
share->reclength = uint2korr((head+16));
609
share->stored_rec_length= share->reclength;
611
record_offset= (ulong) (uint2korr(head+6)+
612
((uint2korr(head+14) == 0xffff ?
613
uint4korr(head+47) : uint2korr(head+14))));
615
if ((n_length= uint4korr(head+55)))
617
/* Read extra data segment */
618
unsigned char *next_chunk, *buff_end;
619
if (!(next_chunk= buff= (unsigned char*) malloc(n_length)))
621
if (pread(file, buff, n_length, record_offset + share->reclength) == 0)
625
share->connect_string.length= uint2korr(buff);
626
if (!(share->connect_string.str= strmake_root(&share->mem_root,
627
(char*) next_chunk + 2,
628
share->connect_string.
633
next_chunk+= share->connect_string.length + 2;
634
buff_end= buff + n_length;
635
if (next_chunk + 2 < buff_end)
637
uint32_t str_db_type_length= uint2korr(next_chunk);
639
name.str= (char*) next_chunk + 2;
640
name.length= str_db_type_length;
642
plugin_ref tmp_plugin= ha_resolve_by_name(session, &name);
643
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
645
if (legacy_db_type > DB_TYPE_UNKNOWN &&
646
legacy_db_type < DB_TYPE_FIRST_DYNAMIC &&
647
legacy_db_type != ha_legacy_type(
648
plugin_data(tmp_plugin, handlerton *)))
650
/* bad file, legacy_db_type did not match the name */
655
tmp_plugin is locked with a local lock.
656
we unlock the old value of share->db_plugin before
657
replacing it with a globally locked version of tmp_plugin
659
plugin_unlock(NULL, share->db_plugin);
660
share->db_plugin= my_plugin_lock(NULL, &tmp_plugin);
662
else if (!tmp_plugin)
664
/* purecov: begin inspected */
666
my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), name.str);
671
next_chunk+= str_db_type_length + 2;
673
if (share->mysql_version >= 50110)
675
/* New auto_partitioned indicator introduced in 5.1.11 */
678
if (forminfo[46] == (unsigned char)255)
680
//reading long table comment
681
if (next_chunk + 2 > buff_end)
686
share->comment.length = uint2korr(next_chunk);
687
if (! (share->comment.str= strmake_root(&share->mem_root,
688
(char*)next_chunk + 2, share->comment.length)))
693
next_chunk+= 2 + share->comment.length;
695
assert(next_chunk <= buff_end);
696
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM_CGE)
699
New frm format in mysql_version 5.2.5 (originally in
700
mysql-5.1.22-ndb-6.2.5)
701
New column properties added:
702
COLUMN_FORMAT DYNAMIC|FIXED and STORAGE DISK|MEMORY
703
TABLESPACE name is now stored in frm
705
if (next_chunk >= buff_end)
707
if (share->mysql_version >= DRIZZLE_VERSION_TABLESPACE_IN_FRM)
714
const uint32_t format_section_header_size= 8;
715
uint32_t format_section_len= uint2korr(next_chunk+0);
717
field_extra_info= next_chunk + format_section_header_size + 1;
718
next_chunk+= format_section_len;
721
assert (next_chunk <= buff_end);
722
if (next_chunk > buff_end)
727
share->key_block_size= uint2korr(head+62);
730
extra_rec_buf_length= uint2korr(head+59);
731
rec_buff_length= ALIGN_SIZE(share->reclength + 1 + extra_rec_buf_length);
567
732
share->rec_buff_length= rec_buff_length;
569
unsigned char* record= NULL;
571
if (! (record= (unsigned char *) alloc_root(&share->mem_root,
575
memset(record, 0, rec_buff_length);
579
if (! table_options.pack_record())
581
null_count++; // one bit for delete mark.
733
if (!(record= (unsigned char *) alloc_root(&share->mem_root,
735
goto err; /* purecov: inspected */
585
736
share->default_values= record;
737
if (pread(file, record, (size_t) share->reclength, record_offset) == 0)
738
goto err; /* purecov: inspected */
740
lseek(file,pos+288,SEEK_SET);
742
share->fields= uint2korr(forminfo+258);
743
pos= uint2korr(forminfo+260); /* Length of all screens */
744
n_length= uint2korr(forminfo+268);
745
interval_count= uint2korr(forminfo+270);
746
interval_parts= uint2korr(forminfo+272);
747
int_length= uint2korr(forminfo+274);
748
share->null_fields= uint2korr(forminfo+282);
749
com_length= uint2korr(forminfo+284);
750
vcol_screen_length= uint2korr(forminfo+286);
752
share->stored_fields= share->fields;
753
if (forminfo[46] != (unsigned char)255)
589
share->intervals= (TYPELIB *) alloc_root(&share->mem_root,
590
interval_count*sizeof(TYPELIB));
755
share->comment.length= (int) (forminfo[46]);
756
share->comment.str= strmake_root(&share->mem_root, (char*) forminfo+47,
757
share->comment.length);
593
share->intervals= NULL;
595
share->fieldnames.type_names= (const char **) alloc_root(&share->mem_root,
596
(share->fields + 1) * sizeof(char*));
598
share->fieldnames.type_lengths= (unsigned int *) alloc_root(&share->mem_root,
599
(share->fields + 1) * sizeof(unsigned int));
601
share->fieldnames.type_names[share->fields]= NULL;
602
share->fieldnames.type_lengths[share->fields]= 0;
603
share->fieldnames.count= share->fields;
606
/* Now fix the TYPELIBs for the intervals (enum values)
610
uint32_t interval_nr= 0;
612
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
761
if (!(field_ptr = (Field **)
762
alloc_root(&share->mem_root,
763
(uint) ((share->fields+1)*sizeof(Field*)+
764
interval_count*sizeof(TYPELIB)+
765
(share->fields+interval_parts+
766
keys+3)*sizeof(char *)+
767
(n_length+int_length+
768
vcol_screen_length)))))
769
goto err; /* purecov: inspected */
771
share->field= field_ptr;
772
read_length=(uint) (share->fields * field_pack_length +
773
pos+ (uint) (n_length+int_length+com_length+
774
vcol_screen_length));
775
if (read_string(file,(unsigned char**) &disk_buff,read_length))
776
goto err; /* purecov: inspected */
777
strpos= disk_buff+pos;
779
share->intervals= (TYPELIB*) (field_ptr+share->fields+1);
780
interval_array= (const char **) (share->intervals+interval_count);
781
names= (char*) (interval_array+share->fields+interval_parts+keys+3);
783
share->intervals= 0; // For better debugging
784
memcpy(names, strpos+(share->fields*field_pack_length),
785
(uint) (n_length+int_length));
786
comment_pos= (char *)(disk_buff+read_length-com_length-vcol_screen_length);
787
vcol_screen_pos= names+(n_length+int_length);
788
memcpy(vcol_screen_pos, disk_buff+read_length-vcol_screen_length,
791
fix_type_pointers(&interval_array, &share->fieldnames, 1, &names);
792
if (share->fieldnames.count != share->fields)
794
fix_type_pointers(&interval_array, share->intervals, interval_count,
614
message::Table::Field pfield= table.field(fieldnr);
617
share->fieldnames.type_names[fieldnr]= strmake_root(&share->mem_root,
618
pfield.name().c_str(),
619
pfield.name().length());
621
share->fieldnames.type_lengths[fieldnr]= pfield.name().length();
624
if (pfield.type() != message::Table::Field::ENUM)
627
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
629
const CHARSET_INFO *charset= get_charset(field_options.has_collation_id() ?
630
field_options.collation_id() : 0);
633
charset= default_charset_info;
635
TYPELIB *t= &(share->intervals[interval_nr]);
637
t->type_names= (const char**)alloc_root(&share->mem_root,
638
(field_options.field_value_size() + 1) * sizeof(char*));
640
t->type_lengths= (unsigned int*) alloc_root(&share->mem_root,
641
(field_options.field_value_size() + 1) * sizeof(unsigned int));
643
t->type_names[field_options.field_value_size()]= NULL;
644
t->type_lengths[field_options.field_value_size()]= 0;
646
t->count= field_options.field_value_size();
649
for (int n= 0; n < field_options.field_value_size(); n++)
798
/* Set ENUM and SET lengths */
800
for (interval= share->intervals;
801
interval < share->intervals + interval_count;
651
t->type_names[n]= strmake_root(&share->mem_root,
652
field_options.field_value(n).c_str(),
653
field_options.field_value(n).length());
656
* Go ask the charset what the length is as for "" length=1
657
* and there's stripping spaces or some other crack going on.
660
lengthsp= charset->cset->lengthsp(charset,
662
field_options.field_value(n).length());
663
t->type_lengths[n]= lengthsp;
804
uint32_t count= (uint) (interval->count + 1) * sizeof(uint);
805
if (!(interval->type_lengths= (uint32_t *) alloc_root(&share->mem_root,
808
for (count= 0; count < interval->count; count++)
810
char *val= (char*) interval->type_names[count];
811
interval->type_lengths[count]= strlen(val);
813
interval->type_lengths[count]= 0;
669
/* and read the fields */
672
bool use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
818
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
820
/* Allocate handler */
821
if (!(handler_file= get_new_handler(share, session->mem_root,
825
record= share->default_values-1; /* Fieldstart = 1 */
826
if (share->null_field_first)
828
null_flags= null_pos= (unsigned char*) record+1;
829
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
831
null_bytes below is only correct under the condition that
832
there are no bit fields. Correct values is set below after the
833
table struct is initialized
835
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
838
use_hash= share->fields >= MAX_FIELDS_BEFORE_HASH;
675
use_hash= ! hash_init(&share->name_hash,
680
(hash_get_key) get_field_name,
684
unsigned char* null_pos= record;;
685
int null_bit_pos= (table_options.pack_record()) ? 0 : 1;
687
for (unsigned int fieldnr= 0; fieldnr < share->fields; fieldnr++)
840
use_hash= !hash_init(&share->name_hash,
843
(hash_get_key) get_field_name,0,0);
845
for (i=0 ; i < share->fields; i++, strpos+=field_pack_length, field_ptr++)
689
message::Table::Field pfield= table.field(fieldnr);
847
uint32_t pack_flag, interval_nr, unireg_type, recpos, field_length;
848
uint32_t vcol_info_length=0;
849
enum_field_types field_type;
691
850
enum column_format_type column_format= COLUMN_FORMAT_TYPE_DEFAULT;
693
switch (pfield.format())
695
case message::Table::Field::DefaultFormat:
696
column_format= COLUMN_FORMAT_TYPE_DEFAULT;
698
case message::Table::Field::FixedFormat:
699
column_format= COLUMN_FORMAT_TYPE_FIXED;
701
case message::Table::Field::DynamicFormat:
702
column_format= COLUMN_FORMAT_TYPE_DYNAMIC;
708
Field::utype unireg_type= Field::NONE;
710
if (pfield.has_numeric_options() &&
711
pfield.numeric_options().is_autoincrement())
713
unireg_type= Field::NEXT_NUMBER;
716
if (pfield.has_options() &&
717
pfield.options().has_default_value() &&
718
pfield.options().default_value().compare("NOW()") == 0)
720
if (pfield.options().has_update_value() &&
721
pfield.options().update_value().compare("NOW()") == 0)
723
unireg_type= Field::TIMESTAMP_DNUN_FIELD;
725
else if (! pfield.options().has_update_value())
727
unireg_type= Field::TIMESTAMP_DN_FIELD;
730
assert(1); // Invalid update value.
732
else if (pfield.has_options() &&
733
pfield.options().has_update_value() &&
734
pfield.options().update_value().compare("NOW()") == 0)
736
unireg_type= Field::TIMESTAMP_UN_FIELD;
851
const CHARSET_INFO *charset= NULL;
739
852
LEX_STRING comment;
740
if (!pfield.has_comment())
742
comment.str= (char*)"";
747
size_t len= pfield.comment().length();
748
const char* str= pfield.comment().c_str();
750
comment.str= strmake_root(&share->mem_root, str, len);
754
enum_field_types field_type;
756
field_type= proto_field_type_to_drizzle_type(pfield.type());
758
const CHARSET_INFO *charset= &my_charset_bin;
760
if (field_type == DRIZZLE_TYPE_BLOB ||
761
field_type == DRIZZLE_TYPE_VARCHAR)
763
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
765
charset= get_charset(field_options.has_collation_id() ?
766
field_options.collation_id() : 0);
769
charset= default_charset_info;
772
if (field_type == DRIZZLE_TYPE_ENUM)
774
message::Table::Field::SetFieldOptions field_options= pfield.set_options();
776
charset= get_charset(field_options.has_collation_id()?
777
field_options.collation_id() : 0);
780
charset= default_charset_info;
784
if (field_type == DRIZZLE_TYPE_DECIMAL
785
|| field_type == DRIZZLE_TYPE_DOUBLE)
787
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
789
if (! pfield.has_numeric_options() || ! fo.has_scale())
853
virtual_column_info *vcol_info= NULL;
854
bool fld_is_stored= true;
856
if (field_extra_info)
858
char tmp= field_extra_info[i];
859
column_format= (enum column_format_type)
860
((tmp >> COLUMN_FORMAT_SHIFT) & COLUMN_FORMAT_MASK);
862
if (new_frm_ver >= 3)
864
/* new frm file in 4.1 */
865
field_length= uint2korr(strpos+3);
866
recpos= uint3korr(strpos+5);
867
pack_flag= uint2korr(strpos+8);
868
unireg_type= (uint) strpos[10];
869
interval_nr= (uint) strpos[12];
870
uint32_t comment_length=uint2korr(strpos+15);
871
field_type=(enum_field_types) (uint) strpos[13];
875
charset= &my_charset_bin;
876
else if (!(charset=get_charset((uint) strpos[14], MYF(0))))
878
error= 5; // Unknown or unavailable charset
879
errarg= (int) strpos[14];
883
if (field_type == DRIZZLE_TYPE_VIRTUAL)
885
assert(interval_nr); // Expect non-null expression
792
We don't write the default to table proto so
793
if no decimals specified for DOUBLE, we use the default.
887
The interval_id byte in the .frm file stores the length of the
888
expression statement for a virtual column.
795
decimals= NOT_FIXED_DEC;
890
vcol_info_length= interval_nr;
895
comment.str= (char*) "";
799
if (fo.scale() > DECIMAL_MAX_SCALE)
900
comment.str= strmake_root(&share->mem_root, comment_pos, comment_length);
901
comment.length= comment_length;
902
comment_pos+= comment_length;
904
if (vcol_info_length)
907
Get virtual column data stored in the .frm file as follows:
908
byte 1 = 1 (always 1 to allow for future extensions)
910
byte 3 = flags (as of now, 0 - no flags, 1 - field is physically stored)
911
byte 4-... = virtual column expression (text data)
913
vcol_info= new virtual_column_info();
914
if ((uint)vcol_screen_pos[0] != 1)
804
decimals= static_cast<uint8_t>(fo.scale());
919
field_type= (enum_field_types) (unsigned char) vcol_screen_pos[1];
920
fld_is_stored= (bool) (uint) vcol_screen_pos[2];
921
vcol_info->expr_str.str= (char *)memdup_root(&share->mem_root,
923
(uint)FRM_VCOL_HEADER_SIZE,
925
(uint)FRM_VCOL_HEADER_SIZE);
926
vcol_info->expr_str.length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE;
927
vcol_screen_pos+= vcol_info_length;
808
Item *default_value= NULL;
810
if (pfield.options().has_default_value() ||
811
pfield.options().has_default_null() ||
812
pfield.options().has_default_bin_value())
814
default_value= default_value_item(field_type,
816
pfield.options().default_null(),
817
&pfield.options().default_value(),
818
&pfield.options().default_bin_value());
822
Table temp_table; /* Use this so that BLOB DEFAULT '' works */
823
memset(&temp_table, 0, sizeof(temp_table));
825
temp_table.in_use= &session;
826
temp_table.s->db_low_byte_first= true; //Cursor->low_byte_first();
827
temp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
829
uint32_t field_length= 0; //Assignment is for compiler complaint.
833
case DRIZZLE_TYPE_BLOB:
834
case DRIZZLE_TYPE_VARCHAR:
836
message::Table::Field::StringFieldOptions field_options= pfield.string_options();
838
charset= get_charset(field_options.has_collation_id() ?
839
field_options.collation_id() : 0);
842
charset= default_charset_info;
844
field_length= field_options.length() * charset->mbmaxlen;
847
case DRIZZLE_TYPE_DOUBLE:
849
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
850
if (!fo.has_precision() && !fo.has_scale())
933
field_length= (uint) strpos[3];
934
recpos= uint2korr(strpos+4),
935
pack_flag= uint2korr(strpos+6);
936
pack_flag&= ~FIELDFLAG_NO_DEFAULT; // Safety for old files
937
unireg_type= (uint) strpos[8];
938
interval_nr= (uint) strpos[10];
941
field_type= (enum_field_types) f_packtype(pack_flag);
942
if (f_is_binary(pack_flag))
852
field_length= DBL_DIG+7;
945
Try to choose the best 4.1 type:
946
- for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY"
947
try to find a binary collation for character set.
948
- for other types (e.g. BLOB) just use my_charset_bin.
950
if (!f_is_blob(pack_flag))
952
// 3.23 or 4.0 string
953
if (!(charset= get_charset_by_csname(share->table_charset->csname,
954
MY_CS_BINSORT, MYF(0))))
955
charset= &my_charset_bin;
958
charset= &my_charset_bin;
856
field_length= fo.precision();
858
if (field_length < decimals &&
859
decimals != NOT_FIXED_DEC)
861
my_error(ER_M_BIGGER_THAN_D, MYF(0), pfield.name().c_str());
867
case DRIZZLE_TYPE_DECIMAL:
869
message::Table::Field::NumericFieldOptions fo= pfield.numeric_options();
871
field_length= my_decimal_precision_to_length(fo.precision(), fo.scale(),
875
case DRIZZLE_TYPE_TIMESTAMP:
876
case DRIZZLE_TYPE_DATETIME:
877
field_length= DateTime::MAX_STRING_LENGTH;
879
case DRIZZLE_TYPE_DATE:
880
field_length= Date::MAX_STRING_LENGTH;
882
case DRIZZLE_TYPE_ENUM:
886
message::Table::Field::SetFieldOptions fo= pfield.set_options();
888
for(int valnr= 0; valnr < fo.field_value_size(); valnr++)
890
if (fo.field_value(valnr).length() > field_length)
891
field_length= charset->cset->numchars(charset,
892
fo.field_value(valnr).c_str(),
893
fo.field_value(valnr).c_str()
894
+ fo.field_value(valnr).length())
899
case DRIZZLE_TYPE_LONG:
901
uint32_t sign_len= pfield.constraints().is_unsigned() ? 0 : 1;
902
field_length= MAX_INT_WIDTH+sign_len;
905
case DRIZZLE_TYPE_LONGLONG:
906
field_length= MAX_BIGINT_WIDTH;
908
case DRIZZLE_TYPE_NULL:
909
abort(); // Programming error
912
Field* f= make_field(share,
914
record + field_offsets[fieldnr] + data_offset,
916
pfield.constraints().is_nullable(),
922
(Field::utype) MTYP_TYPENR(unireg_type),
923
((field_type == DRIZZLE_TYPE_ENUM) ?
924
share->intervals + (interval_nr++)
926
share->fieldnames.type_names[fieldnr]);
928
share->field[fieldnr]= f;
930
f->init(&temp_table); /* blob default values need table obj */
932
if (! (f->flags & NOT_NULL_FLAG))
934
*f->null_ptr|= f->null_bit;
935
if (! (null_bit_pos= (null_bit_pos + 1) & 7)) /* @TODO Ugh. */
961
charset= share->table_charset;
962
memset(&comment, 0, sizeof(comment));
965
if (interval_nr && charset->mbminlen > 1)
967
/* Unescape UCS2 intervals from HEX notation */
968
TYPELIB *interval= share->intervals + interval_nr - 1;
969
unhex_type2(interval);
972
*field_ptr= reg_field=
973
make_field(share, record+recpos,
974
(uint32_t) field_length,
975
null_pos, null_bit_pos,
979
(Field::utype) MTYP_TYPENR(unireg_type),
981
share->intervals+interval_nr-1 :
983
share->fieldnames.type_names[i]);
984
if (!reg_field) // Not supported field type
987
goto err; /* purecov: inspected */
990
reg_field->flags|= ((uint)column_format << COLUMN_FORMAT_FLAGS);
991
reg_field->field_index= i;
992
reg_field->comment=comment;
993
reg_field->vcol_info= vcol_info;
994
reg_field->is_stored= fld_is_stored;
995
if (!(reg_field->flags & NOT_NULL_FLAG))
997
if (!(null_bit_pos= (null_bit_pos + 1) & 7))
942
enum_check_fields old_count_cuted_fields= session.count_cuted_fields;
943
session.count_cuted_fields= CHECK_FIELD_WARN;
944
int res= default_value->save_in_field(f, 1);
945
session.count_cuted_fields= old_count_cuted_fields;
946
if (res != 0 && res != 3) /* @TODO Huh? */
948
my_error(ER_INVALID_DEFAULT, MYF(0), f->field_name);
953
else if (f->real_type() == DRIZZLE_TYPE_ENUM &&
954
(f->flags & NOT_NULL_FLAG))
957
f->store((int64_t) 1, true);
962
/* hack to undo f->init() */
966
f->field_index= fieldnr;
968
if (! default_value &&
969
! (f->unireg_check==Field::NEXT_NUMBER) &&
970
(f->flags & NOT_NULL_FLAG) &&
971
(f->real_type() != DRIZZLE_TYPE_TIMESTAMP))
973
f->flags|= NO_DEFAULT_VALUE_FLAG;
976
if (f->unireg_check == Field::NEXT_NUMBER)
977
share->found_next_number_field= &(share->field[fieldnr]);
979
if (share->timestamp_field == f)
980
share->timestamp_field_offset= fieldnr;
982
if (use_hash) /* supposedly this never fails... but comments lie */
1000
if (f_no_default(pack_flag))
1001
reg_field->flags|= NO_DEFAULT_VALUE_FLAG;
1003
if (reg_field->unireg_check == Field::NEXT_NUMBER)
1004
share->found_next_number_field= field_ptr;
1005
if (share->timestamp_field == reg_field)
1006
share->timestamp_field_offset= i;
983
1009
(void) my_hash_insert(&share->name_hash,
984
(unsigned char*)&(share->field[fieldnr]));
988
keyinfo= share->key_info;
989
for (unsigned int keynr= 0; keynr < share->keys; keynr++, keyinfo++)
991
key_part= keyinfo->key_part;
993
for (unsigned int partnr= 0;
994
partnr < keyinfo->key_parts;
995
partnr++, key_part++)
1010
(unsigned char*) field_ptr); // never fail
1011
if (!reg_field->is_stored)
998
* Fix up key_part->offset by adding data_offset.
999
* We really should compute offset as well.
1000
* But at least this way we are a little better.
1002
key_part->offset= field_offsets[key_part->fieldnr-1] + data_offset;
1013
share->stored_fields--;
1014
if (share->stored_rec_length>=recpos)
1015
share->stored_rec_length= recpos-1;
1007
We need to set the unused bits to 1. If the number of bits is a multiple
1008
of 8 there are no unused bits.
1012
*(record + null_count / 8)|= ~(((unsigned char) 1 << (null_count & 7)) - 1);
1014
share->null_bytes= (null_pos - (unsigned char*) record + (null_bit_pos + 7) / 8);
1016
share->last_null_bit_pos= null_bit_pos;
1018
free(field_offsets);
1019
field_offsets= NULL;
1020
free(field_pack_length);
1021
field_pack_length= NULL;
1024
if (share->key_parts)
1018
*field_ptr=0; // End marker
1019
/* Sanity checks: */
1020
assert(share->fields>=share->stored_fields);
1021
assert(share->reclength>=share->stored_rec_length);
1023
/* Fix key->name and key_part->field */
1026
uint32_t primary_key= (uint32_t) (find_type((char*) "PRIMARY",
1027
&share->keynames, 3) - 1); /* @TODO Huh? */
1026
uint32_t primary_key=(uint) (find_type((char*) "PRIMARY",
1027
&share->keynames, 3) - 1);
1028
int64_t ha_option= handler_file->ha_table_flags();
1029
1029
keyinfo= share->key_info;
1030
1030
key_part= keyinfo->key_part;
1032
for (uint32_t key= 0; key < share->keys; key++,keyinfo++)
1032
for (uint32_t key=0 ; key < share->keys ; key++,keyinfo++)
1034
1034
uint32_t usable_parts= 0;
1035
keyinfo->name=(char*) share->keynames.type_names[key];
1036
1037
if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME))
1039
If the UNIQUE key doesn't have NULL columns and is not a part key
1040
declare this as a primary key.
1043
for (uint32_t i= 0; i < keyinfo->key_parts; i++)
1045
uint32_t fieldnr= key_part[i].fieldnr;
1047
share->field[fieldnr-1]->null_ptr ||
1048
share->field[fieldnr-1]->key_length() != key_part[i].length)
1050
primary_key= MAX_KEY; // Can't be used
1040
If the UNIQUE key doesn't have NULL columns and is not a part key
1041
declare this as a primary key.
1044
for (i=0 ; i < keyinfo->key_parts ;i++)
1046
uint32_t fieldnr= key_part[i].fieldnr;
1048
share->field[fieldnr-1]->null_ptr ||
1049
share->field[fieldnr-1]->key_length() !=
1052
primary_key=MAX_KEY; // Can't be used
1056
for (uint32_t i= 0 ; i < keyinfo->key_parts ; key_part++,i++)
1058
for (i=0 ; i < keyinfo->key_parts ; key_part++,i++)
1059
if (! key_part->fieldnr)
1061
if (new_field_pack_flag <= 1)
1062
key_part->fieldnr= (uint16_t) find_field(share->field,
1063
share->default_values,
1064
(uint) key_part->offset,
1065
(uint) key_part->length);
1066
if (!key_part->fieldnr)
1061
abort(); // goto err;
1068
error= 4; // Wrong file
1063
1071
field= key_part->field= share->field[key_part->fieldnr-1];
1064
1072
key_part->type= field->key_type();
1065
1073
if (field->null_ptr)
1067
key_part->null_offset=(uint32_t) ((unsigned char*) field->null_ptr -
1075
key_part->null_offset=(uint) ((unsigned char*) field->null_ptr -
1068
1076
share->default_values);
1069
1077
key_part->null_bit= field->null_bit;
1070
1078
key_part->store_length+=HA_KEY_NULL_LENGTH;
1186
1205
/* Store offsets to blob fields to find them fast */
1187
1206
if (!(share->blob_field= save=
1188
1207
(uint*) alloc_root(&share->mem_root,
1189
(uint32_t) (share->blob_fields* sizeof(uint32_t)))))
1208
(uint) (share->blob_fields* sizeof(uint)))))
1191
for (k= 0, ptr= share->field ; *ptr ; ptr++, k++)
1210
for (k=0, ptr= share->field ; *ptr ; ptr++, k++)
1193
1212
if ((*ptr)->flags & BLOB_FLAG)
1198
share->db_low_byte_first= true; // @todo Question this.
1218
the correct null_bytes can now be set, since bitfields have been taken
1221
share->null_bytes= (null_pos - (unsigned char*) null_flags +
1222
(null_bit_pos + 7) / 8);
1223
share->last_null_bit_pos= null_bit_pos;
1225
share->db_low_byte_first= handler_file->low_byte_first();
1199
1226
share->column_bitmap_size= bitmap_buffer_size(share->fields);
1201
my_bitmap_map *bitmaps;
1203
1228
if (!(bitmaps= (my_bitmap_map*) alloc_root(&share->mem_root,
1204
1229
share->column_bitmap_size)))
1206
share->all_set.init(bitmaps, share->fields);
1207
share->all_set.setAll();
1231
bitmap_init(&share->all_set, bitmaps, share->fields, false);
1232
bitmap_set_all(&share->all_set);
1234
delete handler_file;
1213
free(field_offsets);
1214
if (field_pack_length)
1215
free(field_pack_length);
1217
1242
share->error= error;
1218
share->open_errno= errno;
1243
share->open_errno= my_errno;
1244
share->errarg= errarg;
1247
delete handler_file;
1220
1248
hash_free(&share->name_hash);
1221
share->open_table_error(error, share->open_errno, 0);
1227
Read table definition from a binary / text based .frm cursor
1231
session Thread Cursor
1232
share Fill this with table definition
1235
This function is called when the table definition is not cached in
1237
The data is returned in 'share', which is alloced by
1238
alloc_table_share().. The code assumes that share is initialized.
1250
open_table_error(share, error, share->open_errno, errarg);
1252
} /* open_binary_frm */
1256
Clear flag GET_FIXED_FIELDS_FLAG in all fields of the table.
1257
This routine is used for error handling purposes.
1261
table Table object for which virtual columns are set-up
1266
static void clear_field_flag(Table *table)
1270
for (ptr= table->field; *ptr; ptr++)
1271
(*ptr)->flags&= (~GET_FIXED_FIELDS_FLAG);
1275
The function uses the feature in fix_fields where the flag
1276
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
1277
This field must always be reset before returning from the function
1278
since it is used for other purposes as well.
1281
fix_fields_vcol_func()
1282
session The thread object
1283
func_item The item tree reference of the virtual columnfunction
1284
table The table object
1285
field_name The name of the processed field
1288
true An error occurred, something was wrong with the
1290
false Ok, a partition field array was created
1293
bool fix_fields_vcol_func(Session *session,
1296
const char *field_name)
1298
uint dir_length, home_dir_length;
1301
TableList *save_table_list, *save_first_table, *save_last_table;
1303
Name_resolution_context *context;
1304
const char *save_where;
1306
char db_name_string[FN_REFLEN];
1307
bool save_use_only_table_context;
1308
Field **ptr, *field;
1309
enum_mark_columns save_mark_used_columns= session->mark_used_columns;
1313
Set-up the TABLE_LIST object to be a list with a single table
1314
Set the object to zero to create NULL pointers and set alias
1315
and real name to table name and get database name from file name.
1318
bzero((void*)&tables, sizeof(TableList));
1319
tables.alias= tables.table_name= (char*) table->s->table_name.str;
1320
tables.table= table;
1321
tables.next_local= NULL;
1322
tables.next_name_resolution_table= NULL;
1323
memcpy(db_name_string,
1324
table->s->normalized_path.str,
1325
table->s->normalized_path.length);
1326
dir_length= dirname_length(db_name_string);
1327
db_name_string[dir_length - 1]= 0;
1328
home_dir_length= dirname_length(db_name_string);
1329
db_name= &db_name_string[home_dir_length];
1332
session->mark_used_columns= MARK_COLUMNS_NONE;
1334
context= session->lex->current_context();
1335
table->map= 1; //To ensure correct calculation of const item
1336
table->get_fields_in_item_tree= true;
1337
save_table_list= context->table_list;
1338
save_first_table= context->first_name_resolution_table;
1339
save_last_table= context->last_name_resolution_table;
1340
context->table_list= &tables;
1341
context->first_name_resolution_table= &tables;
1342
context->last_name_resolution_table= NULL;
1343
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1344
save_where= session->where;
1345
session->where= "virtual column function";
1347
/* Save the context before fixing the fields*/
1348
save_use_only_table_context= session->lex->use_only_table_context;
1349
session->lex->use_only_table_context= true;
1350
/* Fix fields referenced to by the virtual column function */
1351
error= func_expr->fix_fields(session, (Item**)0);
1352
/* Restore the original context*/
1353
session->lex->use_only_table_context= save_use_only_table_context;
1354
context->table_list= save_table_list;
1355
context->first_name_resolution_table= save_first_table;
1356
context->last_name_resolution_table= save_last_table;
1358
if (unlikely(error))
1360
clear_field_flag(table);
1363
session->where= save_where;
1365
Walk through the Item tree checking if all items are valid
1366
to be part of the virtual column
1368
error= func_expr->walk(&Item::check_vcol_func_processor, 0, NULL);
1371
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), field_name);
1372
clear_field_flag(table);
1375
if (unlikely(func_expr->const_item()))
1377
my_error(ER_CONST_EXPR_IN_VCOL, MYF(0));
1378
clear_field_flag(table);
1381
/* Ensure that this virtual column is not based on another virtual field. */
1383
while ((field= *(ptr++)))
1385
if ((field->flags & GET_FIXED_FIELDS_FLAG) &&
1388
my_error(ER_VCOL_BASED_ON_VCOL, MYF(0));
1389
clear_field_flag(table);
1394
Cleanup the fields marked with flag GET_FIXED_FIELDS_FLAG
1395
when calling fix_fields.
1397
clear_field_flag(table);
1401
table->get_fields_in_item_tree= false;
1402
session->mark_used_columns= save_mark_used_columns;
1403
table->map= 0; //Restore old value
1408
Unpack the definition of a virtual column
1411
unpack_vcol_info_from_frm()
1412
session Thread handler
1413
table Table with the checked field
1414
field Pointer to Field object
1415
open_mode Open table mode needed to determine
1416
which errors need to be generated in a failure
1417
error_reported updated flag for the caller that no other error
1418
messages are to be generated.
1242
1 Error (see open_table_error)
1243
2 Error (see open_table_error)
1244
3 Wrong data in .frm cursor
1245
4 Error (see open_table_error)
1246
5 Error (see open_table_error: charset unavailable)
1247
6 Unknown .frm version
1250
int open_table_def(Session& session, TableShare *share)
1424
bool unpack_vcol_info_from_frm(Session *session,
1427
LEX_STRING *vcol_expr,
1428
open_table_mode open_mode,
1429
bool *error_reported)
1258
message::Table table;
1260
error= plugin::StorageEngine::getTableDefinition(session, share->normalized_path.str,
1262
share->table_name.str,
1266
if (error != EEXIST)
1275
if (not table.IsInitialized())
1283
error= parse_table_proto(session, table, share);
1285
share->table_category= get_table_category(& share->db);
1288
session.status_var.opened_shares++;
1291
if (error && !error_given)
1293
share->error= error;
1294
share->open_table_error(error, (share->open_errno= errno), 0);
1434
Step 1: Construct a statement for the parser.
1435
The parsed string needs to take the following format:
1436
"PARSE_VCOL_EXPR (<expr_string_from_frm>)"
1438
char *vcol_expr_str;
1441
if (!(vcol_expr_str= (char*) alloc_root(&table->mem_root,
1443
parse_vcol_keyword.length + 3)))
1447
memcpy(vcol_expr_str,
1448
(char*) parse_vcol_keyword.str,
1449
parse_vcol_keyword.length);
1450
str_len= parse_vcol_keyword.length;
1451
memcpy(vcol_expr_str + str_len, "(", 1);
1453
memcpy(vcol_expr_str + str_len,
1454
(char*) vcol_expr->str,
1456
str_len+= vcol_expr->length;
1457
memcpy(vcol_expr_str + str_len, ")", 1);
1459
memcpy(vcol_expr_str + str_len, "\0", 1);
1461
Lex_input_stream lip(session, vcol_expr_str, str_len);
1464
Step 2: Setup session for parsing.
1465
1) make Item objects be created in the memory allocated for the Table
1466
object (not TABLE_SHARE)
1467
2) ensure that created Item's are not put on to session->free_list
1468
(which is associated with the parsed statement and hence cleared after
1470
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1471
to be parsed as a SQL command.
1473
MEM_ROOT **root_ptr, *old_root;
1474
Item *backup_free_list= session->free_list;
1475
root_ptr= current_mem_root_ptr();
1476
old_root= *root_ptr;
1477
*root_ptr= &table->mem_root;
1478
session->free_list= NULL;
1479
session->lex->parse_vcol_expr= true;
1482
Step 3: Use the parser to build an Item object from.
1484
if (parse_sql(session, &lip))
1488
/* From now on use vcol_info generated by the parser. */
1489
field->vcol_info= session->lex->vcol_info;
1491
/* Validate the Item tree. */
1492
if (fix_fields_vcol_func(session,
1493
field->vcol_info->expr_item,
1497
if (open_mode == OTM_CREATE)
1500
During CREATE/ALTER TABLE it is ok to receive errors here.
1501
It is not ok if it happens during the opening of an frm
1502
file as part of a normal query.
1504
*error_reported= true;
1506
field->vcol_info= NULL;
1509
field->vcol_info->item_free_list= session->free_list;
1510
session->free_list= backup_free_list;
1511
*root_ptr= old_root;
1516
session->lex->parse_vcol_expr= false;
1517
session->free_items();
1518
*root_ptr= old_root;
1519
session->free_list= backup_free_list;
1302
Open a table based on a TableShare
1525
Open a table based on a TABLE_SHARE
1305
1528
open_table_from_share()
1306
session Thread Cursor
1529
session Thread handler
1307
1530
share Table definition
1308
1531
alias Alias for table
1309
1532
db_stat open flags (for example HA_OPEN_KEYFILE|
1310
1533
HA_OPEN_RNDFILE..) can be 0 (example in
1311
1534
ha_example_table)
1535
prgflag READ_ALL etc..
1312
1536
ha_open_flags HA_OPEN_ABORT_IF_LOCKED etc..
1313
1537
outparam result table
1538
open_mode One of OTM_OPEN|OTM_CREATE|OTM_ALTER
1539
if OTM_CREATE some errors are ignore
1540
if OTM_ALTER HA_OPEN is not called
1317
1544
1 Error (see open_table_error)
1318
1545
2 Error (see open_table_error)
1319
3 Wrong data in .frm cursor
1546
3 Wrong data in .frm file
1320
1547
4 Error (see open_table_error)
1321
1548
5 Error (see open_table_error: charset unavailable)
1322
1549
7 Table definition has changed in engine
1325
int open_table_from_share(Session *session, TableShare *share, const char *alias,
1326
uint32_t db_stat, uint32_t ha_open_flags,
1552
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1553
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1554
Table *outparam, open_table_mode open_mode)
1330
1557
uint32_t records, i, bitmap_size;
1331
1558
bool error_reported= false;
1332
1559
unsigned char *record, *bitmaps;
1560
Field **field_ptr, **vfield_ptr;
1335
1562
/* Parsing of partitioning information from .frm needs session->lex set up. */
1336
1563
assert(session->lex->is_lex_started);
1339
outparam->resetTable(session, share, db_stat);
1342
if (not (outparam->alias= strdup(alias)))
1345
/* Allocate Cursor */
1346
if (not (outparam->cursor= share->db_type()->getCursor(*share, &outparam->mem_root)))
1566
memset(outparam, 0, sizeof(*outparam));
1567
outparam->in_use= session;
1569
outparam->db_stat= db_stat;
1570
outparam->write_row_record= NULL;
1572
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1574
if (!(outparam->alias= strdup(alias)))
1576
outparam->quick_keys.init();
1577
outparam->covering_keys.init();
1578
outparam->keys_in_use_for_query.init();
1580
/* Allocate handler */
1582
if (!(prgflag & OPEN_FRM_FILE_ONLY))
1584
if (!(outparam->file= get_new_handler(share, &outparam->mem_root,
1351
if ((db_stat & HA_OPEN_KEYFILE))
1594
outparam->reginfo.lock_type= TL_UNLOCK;
1595
outparam->current_lock= F_UNLCK;
1597
if ((db_stat & HA_OPEN_KEYFILE) || (prgflag & DELAYED_OPEN))
1599
if (prgflag & (READ_ALL+EXTRA_RECORD))
1356
1602
if (!(record= (unsigned char*) alloc_root(&outparam->mem_root,
1357
1603
share->rec_buff_length * records)))
1604
goto err; /* purecov: inspected */
1360
1606
if (records == 0)
2013
2626
/* Error if empty or too long column name */
2014
return last_char_is_space || (uint32_t) name_length > NAME_CHAR_LEN;
2627
return last_char_is_space || (uint) name_length > NAME_CHAR_LEN;
2632
Checks whether a table is intact. Should be done *just* after the table has
2635
@param[in] table The table to check
2636
@param[in] table_f_count Expected number of columns in the table
2637
@param[in] table_def Expected structure of the table (column name
2641
@retval TRUE There was an error. An error message is output
2642
to the error log. We do not push an error
2643
message into the error stack because this
2644
function is currently only called at start up,
2645
and such errors never reach the user.
2649
Table::table_check_intact(const uint32_t table_f_count,
2650
const TABLE_FIELD_W_TYPE *table_def)
2654
bool fields_diff_count;
2656
fields_diff_count= (s->fields != table_f_count);
2657
if (fields_diff_count)
2660
/* previous MySQL version */
2661
if (DRIZZLE_VERSION_ID > s->mysql_version)
2663
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE),
2664
alias, table_f_count, s->fields,
2665
s->mysql_version, DRIZZLE_VERSION_ID);
2668
else if (DRIZZLE_VERSION_ID == s->mysql_version)
2670
errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_COL_COUNT_DOESNT_MATCH_CORRUPTED), alias,
2671
table_f_count, s->fields);
2675
Something has definitely changed, but we're running an older
2676
version of MySQL with new system tables.
2677
Let's check column definitions. If a column was added at
2678
the end of the table, then we don't care much since such change
2679
is backward compatible.
2682
char buffer[STRING_BUFFER_USUAL_SIZE];
2683
for (i=0 ; i < table_f_count; i++, table_def++)
2685
String sql_type(buffer, sizeof(buffer), system_charset_info);
2689
Field *field= this->field[i];
2691
if (strncmp(field->field_name, table_def->name.str,
2692
table_def->name.length))
2695
Name changes are not fatal, we use ordinal numbers to access columns.
2696
Still this can be a sign of a tampered table, output an error
2699
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2700
"expected column '%s' at position %d, found '%s'."),
2701
s->db.str, alias, table_def->name.str, i,
2704
field->sql_type(sql_type);
2706
Generally, if column types don't match, then something is
2709
However, we only compare column definitions up to the
2710
length of the original definition, since we consider the
2711
following definitions compatible:
2713
1. DATETIME and DATETIM
2714
2. INT(11) and INT(11
2715
3. SET('one', 'two') and SET('one', 'two', 'more')
2717
For SETs or ENUMs, if the same prefix is there it's OK to
2718
add more elements - they will get higher ordinal numbers and
2719
the new table definition is backward compatible with the
2722
if (strncmp(sql_type.c_ptr_safe(), table_def->type.str,
2723
table_def->type.length - 1))
2725
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2726
"expected column '%s' at position %d to have type "
2727
"%s, found type %s."), s->db.str, alias,
2728
table_def->name.str, i, table_def->type.str,
2729
sql_type.c_ptr_safe());
2732
else if (table_def->cset.str && !field->has_charset())
2734
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2735
"expected the type of column '%s' at position %d "
2736
"to have character set '%s' but the type has no "
2737
"character set."), s->db.str, alias,
2738
table_def->name.str, i, table_def->cset.str);
2741
else if (table_def->cset.str &&
2742
strcmp(field->charset()->csname, table_def->cset.str))
2744
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2745
"expected the type of column '%s' at position %d "
2746
"to have character set '%s' but found "
2747
"character set '%s'."), s->db.str, alias,
2748
table_def->name.str, i, table_def->cset.str,
2749
field->charset()->csname);
2755
errmsg_printf(ERRMSG_LVL_ERROR, _("Incorrect definition of table %s.%s: "
2756
"expected column '%s' at position %d to have type %s "
2757
" but the column is not found."),
2759
table_def->name.str, i, table_def->type.str);
2768
Create Item_field for each column in the table.
2771
Table::fill_item_list()
2772
item_list a pointer to an empty list used to store items
2775
Create Item_field object for each column in the table and
2776
initialize it with the corresponding Field. New items are
2777
created in the current Session memory root.
2784
bool Table::fill_item_list(List<Item> *item_list) const
2787
All Item_field's created using a direct pointer to a field
2788
are fixed in Item_field constructor.
2790
for (Field **ptr= field; *ptr; ptr++)
2792
Item_field *item= new Item_field(*ptr);
2793
if (!item || item_list->push_back(item))
2800
Reset an existing list of Item_field items to point to the
2801
Fields of this table.
2804
Table::fill_item_list()
2805
item_list a non-empty list with Item_fields
2808
This is a counterpart of fill_item_list used to redirect
2809
Item_fields to the fields of a newly created table.
2810
The caller must ensure that number of items in the item_list
2811
is the same as the number of columns in the table.
2814
void Table::reset_item_list(List<Item> *item_list) const
2816
List_iterator_fast<Item> it(*item_list);
2817
for (Field **ptr= field; *ptr; ptr++)
2819
Item_field *item_field= (Item_field*) it++;
2820
assert(item_field != 0);
2821
item_field->reset_field(*ptr);
2827
Find underlying base tables (TableList) which represent given
2828
table_to_find (Table)
2831
TableList::find_underlying_table()
2832
table_to_find table to find
2835
0 table is not found
2836
found table reference
2839
TableList *TableList::find_underlying_table(Table *table_to_find)
2841
/* is this real table and table which we are looking for? */
2842
if (table == table_to_find && merge_underlying_list == 0)
2845
for (TableList *tbl= merge_underlying_list; tbl; tbl= tbl->next_local)
2848
if ((result= tbl->find_underlying_table(table_to_find)))
2855
cleunup items belonged to view fields translation table
2858
TableList::cleanup_items()
2861
void TableList::cleanup_items()
2866
bool TableList::placeholder()
2868
return derived || schema_table || (create && !table->getDBStat()) || !table;
2873
Set insert_values buffer
2877
mem_root memory pool for allocating
2881
TRUE - out of memory
2884
bool TableList::set_insert_values(MEM_ROOT *mem_root)
2888
if (!table->insert_values &&
2889
!(table->insert_values= (unsigned char *)alloc_root(mem_root,
2890
table->s->rec_buff_length)))
2899
Test if this is a leaf with respect to name resolution.
2902
TableList::is_leaf_for_name_resolution()
2905
A table reference is a leaf with respect to name resolution if
2906
it is either a leaf node in a nested join tree (table, view,
2907
schema table, subquery), or an inner node that represents a
2908
NATURAL/USING join, or a nested join with materialized join
2912
TRUE if a leaf, false otherwise.
2914
bool TableList::is_leaf_for_name_resolution()
2916
return (is_natural_join || is_join_columns_complete || !nested_join);
2921
Retrieve the first (left-most) leaf in a nested join tree with
2922
respect to name resolution.
2925
TableList::first_leaf_for_name_resolution()
2928
Given that 'this' is a nested table reference, recursively walk
2929
down the left-most children of 'this' until we reach a leaf
2930
table reference with respect to name resolution.
2933
The left-most child of a nested table reference is the last element
2934
in the list of children because the children are inserted in
2938
If 'this' is a nested table reference - the left-most child of
2939
the tree rooted in 'this',
2943
TableList *TableList::first_leaf_for_name_resolution()
2945
TableList *cur_table_ref= NULL;
2946
nested_join_st *cur_nested_join;
2948
if (is_leaf_for_name_resolution())
2950
assert(nested_join);
2952
for (cur_nested_join= nested_join;
2954
cur_nested_join= cur_table_ref->nested_join)
2956
List_iterator_fast<TableList> it(cur_nested_join->join_list);
2957
cur_table_ref= it++;
2959
If the current nested join is a RIGHT JOIN, the operands in
2960
'join_list' are in reverse order, thus the first operand is
2961
already at the front of the list. Otherwise the first operand
2962
is in the end of the list of join operands.
2964
if (!(cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
2967
while ((next= it++))
2968
cur_table_ref= next;
2970
if (cur_table_ref->is_leaf_for_name_resolution())
2973
return cur_table_ref;
2978
Retrieve the last (right-most) leaf in a nested join tree with
2979
respect to name resolution.
2982
TableList::last_leaf_for_name_resolution()
2985
Given that 'this' is a nested table reference, recursively walk
2986
down the right-most children of 'this' until we reach a leaf
2987
table reference with respect to name resolution.
2990
The right-most child of a nested table reference is the first
2991
element in the list of children because the children are inserted
2995
- If 'this' is a nested table reference - the right-most child of
2996
the tree rooted in 'this',
3000
TableList *TableList::last_leaf_for_name_resolution()
3002
TableList *cur_table_ref= this;
3003
nested_join_st *cur_nested_join;
3005
if (is_leaf_for_name_resolution())
3007
assert(nested_join);
3009
for (cur_nested_join= nested_join;
3011
cur_nested_join= cur_table_ref->nested_join)
3013
cur_table_ref= cur_nested_join->join_list.head();
3015
If the current nested is a RIGHT JOIN, the operands in
3016
'join_list' are in reverse order, thus the last operand is in the
3019
if ((cur_table_ref->outer_join & JOIN_TYPE_RIGHT))
3021
List_iterator_fast<TableList> it(cur_nested_join->join_list);
3023
cur_table_ref= it++;
3024
while ((next= it++))
3025
cur_table_ref= next;
3027
if (cur_table_ref->is_leaf_for_name_resolution())
3030
return cur_table_ref;