33
33
void open_table_error(TABLE_SHARE *share, int error, int db_errno,
34
34
myf errortype, int errarg);
35
static int open_binary_frm(Session *thd, TABLE_SHARE *share,
35
static int open_binary_frm(Session *session, TABLE_SHARE *share,
36
36
unsigned char *head, File file);
37
37
static void fix_type_pointers(const char ***array, TYPELIB *point_to_type,
38
38
uint32_t types, char **names);
184
184
don't have to be shared between threads or put into the table def
185
185
cache, so we can do some things notable simpler and faster
187
If table is not put in thd->temporary_tables (happens only when
187
If table is not put in session->temporary_tables (happens only when
188
188
one uses OPEN TEMPORARY) then one can specify 'db' as key and
189
189
use key_length= 0 as neither table_cache_key or key_length will be used).
192
void init_tmp_table_share(Session *thd, TABLE_SHARE *share, const char *key,
192
void init_tmp_table_share(Session *session, TABLE_SHARE *share, const char *key,
193
193
uint32_t key_length, const char *table_name,
194
194
const char *path)
380
380
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
381
381
old_root= *root_ptr;
382
382
*root_ptr= &share->mem_root;
383
error= open_binary_frm(thd, share, head, file);
383
error= open_binary_frm(session, share, head, file);
384
384
*root_ptr= old_root;
390
390
share->table_category= get_table_category(& share->db, & share->table_name);
393
thd->status_var.opened_shares++;
393
session->status_var.opened_shares++;
396
396
my_close(file, MYF(MY_WME));
410
410
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
413
static int open_binary_frm(Session *thd, TABLE_SHARE *share, unsigned char *head,
413
static int open_binary_frm(Session *session, TABLE_SHARE *share, unsigned char *head,
416
416
int error, errarg= 0;
468
468
if (legacy_db_type > DB_TYPE_UNKNOWN &&
469
469
legacy_db_type < DB_TYPE_FIRST_DYNAMIC)
470
470
share->db_plugin= ha_lock_engine(NULL,
471
ha_checktype(thd, legacy_db_type, 0, 0));
471
ha_checktype(session, legacy_db_type, 0, 0));
472
472
share->db_create_options= db_create_options= uint2korr(head+30);
473
473
share->db_options_in_use= share->db_create_options;
474
474
share->mysql_version= uint4korr(head+51);
629
629
name.str= (char*) next_chunk + 2;
630
630
name.length= str_db_type_length;
632
plugin_ref tmp_plugin= ha_resolve_by_name(thd, &name);
632
plugin_ref tmp_plugin= ha_resolve_by_name(session, &name);
633
633
if (tmp_plugin != NULL && !plugin_equals(tmp_plugin, share->db_plugin))
635
635
if (legacy_db_type > DB_TYPE_UNKNOWN &&
810
810
fix_type_pointers(&interval_array, &share->keynames, 1, &keynames);
812
812
/* Allocate handler */
813
if (!(handler_file= get_new_handler(share, thd->mem_root,
813
if (!(handler_file= get_new_handler(share, session->mem_root,
814
814
share->db_type())))
1282
1282
false Ok, a partition field array was created
1285
bool fix_fields_vcol_func(Session *thd,
1285
bool fix_fields_vcol_func(Session *session,
1286
1286
Item* func_expr,
1288
1288
const char *field_name)
1321
1321
db_name= &db_name_string[home_dir_length];
1322
1322
tables.db= db_name;
1324
thd->mark_used_columns= MARK_COLUMNS_NONE;
1324
session->mark_used_columns= MARK_COLUMNS_NONE;
1326
context= thd->lex->current_context();
1326
context= session->lex->current_context();
1327
1327
table->map= 1; //To ensure correct calculation of const item
1328
1328
table->get_fields_in_item_tree= true;
1329
1329
save_table_list= context->table_list;
1333
1333
context->first_name_resolution_table= &tables;
1334
1334
context->last_name_resolution_table= NULL;
1335
1335
func_expr->walk(&Item::change_context_processor, 0, (unsigned char*) context);
1336
save_where= thd->where;
1337
thd->where= "virtual column function";
1336
save_where= session->where;
1337
session->where= "virtual column function";
1339
1339
/* Save the context before fixing the fields*/
1340
save_use_only_table_context= thd->lex->use_only_table_context;
1341
thd->lex->use_only_table_context= true;
1340
save_use_only_table_context= session->lex->use_only_table_context;
1341
session->lex->use_only_table_context= true;
1342
1342
/* Fix fields referenced to by the virtual column function */
1343
error= func_expr->fix_fields(thd, (Item**)0);
1343
error= func_expr->fix_fields(session, (Item**)0);
1344
1344
/* Restore the original context*/
1345
thd->lex->use_only_table_context= save_use_only_table_context;
1345
session->lex->use_only_table_context= save_use_only_table_context;
1346
1346
context->table_list= save_table_list;
1347
1347
context->first_name_resolution_table= save_first_table;
1348
1348
context->last_name_resolution_table= save_last_table;
1451
1451
memcpy(vcol_expr_str + str_len, "\0", 1);
1453
Lex_input_stream lip(thd, vcol_expr_str, str_len);
1453
Lex_input_stream lip(session, vcol_expr_str, str_len);
1456
Step 2: Setup thd for parsing.
1456
Step 2: Setup session for parsing.
1457
1457
1) make Item objects be created in the memory allocated for the Table
1458
1458
object (not TABLE_SHARE)
1459
2) ensure that created Item's are not put on to thd->free_list
1459
2) ensure that created Item's are not put on to session->free_list
1460
1460
(which is associated with the parsed statement and hence cleared after
1462
1462
3) setup a flag in the LEX structure to allow "PARSE_VCOL_EXPR"
1463
1463
to be parsed as a SQL command.
1465
1465
MEM_ROOT **root_ptr, *old_root;
1466
Item *backup_free_list= thd->free_list;
1466
Item *backup_free_list= session->free_list;
1467
1467
root_ptr= (MEM_ROOT **)pthread_getspecific(THR_MALLOC);
1468
1468
old_root= *root_ptr;
1469
1469
*root_ptr= &table->mem_root;
1470
thd->free_list= NULL;
1471
thd->lex->parse_vcol_expr= true;
1470
session->free_list= NULL;
1471
session->lex->parse_vcol_expr= true;
1474
1474
Step 3: Use the parser to build an Item object from.
1476
if (parse_sql(thd, &lip))
1476
if (parse_sql(session, &lip))
1478
1478
goto parse_err;
1480
1480
/* From now on use vcol_info generated by the parser. */
1481
field->vcol_info= thd->lex->vcol_info;
1481
field->vcol_info= session->lex->vcol_info;
1483
1483
/* Validate the Item tree. */
1484
if (fix_fields_vcol_func(thd,
1484
if (fix_fields_vcol_func(session,
1485
1485
field->vcol_info->expr_item,
1487
1487
field->field_name))
1498
1498
field->vcol_info= NULL;
1499
1499
goto parse_err;
1501
field->vcol_info->item_free_list= thd->free_list;
1502
thd->free_list= backup_free_list;
1501
field->vcol_info->item_free_list= session->free_list;
1502
session->free_list= backup_free_list;
1503
1503
*root_ptr= old_root;
1508
thd->lex->parse_vcol_expr= false;
1508
session->lex->parse_vcol_expr= false;
1509
session->free_items();
1510
1510
*root_ptr= old_root;
1511
thd->free_list= backup_free_list;
1511
session->free_list= backup_free_list;
1541
1541
7 Table definition has changed in engine
1544
int open_table_from_share(Session *thd, TABLE_SHARE *share, const char *alias,
1544
int open_table_from_share(Session *session, TABLE_SHARE *share, const char *alias,
1545
1545
uint32_t db_stat, uint32_t prgflag, uint32_t ha_open_flags,
1546
1546
Table *outparam, open_table_mode open_mode)
1551
1551
unsigned char *record, *bitmaps;
1552
1552
Field **field_ptr, **vfield_ptr;
1554
/* Parsing of partitioning information from .frm needs thd->lex set up. */
1555
assert(thd->lex->is_lex_started);
1554
/* Parsing of partitioning information from .frm needs session->lex set up. */
1555
assert(session->lex->is_lex_started);
1558
1558
memset(outparam, 0, sizeof(*outparam));
1559
outparam->in_use= thd;
1559
outparam->in_use= session;
1560
1560
outparam->s= share;
1561
1561
outparam->db_stat= db_stat;
1562
1562
outparam->write_row_record= NULL;
1714
1714
if ((*field_ptr)->vcol_info)
1716
if (unpack_vcol_info_from_frm(thd,
1716
if (unpack_vcol_info_from_frm(session,
1719
1719
&(*field_ptr)->vcol_info->expr_str,
2041
2041
if (share->db_type() != NULL)
2043
if ((file= get_new_handler(share, current_thd->mem_root,
2043
if ((file= get_new_handler(share, current_session->mem_root,
2044
2044
share->db_type())))
2046
2046
if (!(datext= *file->bas_ext()))
2272
2272
/* Create a .frm file */
2274
File create_frm(Session *thd, const char *name, const char *db,
2274
File create_frm(Session *session, const char *name, const char *db,
2275
2275
const char *table, uint32_t reclength, unsigned char *fileinfo,
2276
2276
HA_CREATE_INFO *create_info, uint32_t keys, KEY *key_info)
2302
2302
fileinfo[2]= FRM_VER+3+ test(create_info->varchar);
2304
2304
fileinfo[3]= (unsigned char) ha_legacy_type(
2305
ha_checktype(thd,ha_legacy_type(create_info->db_type),0,0));
2305
ha_checktype(session,ha_legacy_type(create_info->db_type),0,0));
2307
2307
int2store(fileinfo+6,IO_SIZE); /* Next block starts here */
2308
2308
for (i= 0; i < keys; i++)
3325
3325
embedded= parent_embedding;
3326
3326
if (embedded->prep_on_expr)
3327
embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd);
3327
embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(session);
3328
3328
parent_embedding= embedded->embedding;
3330
3330
while (parent_embedding &&
3550
bool mysql_frm_type(Session *thd __attribute__((unused)),
3550
bool mysql_frm_type(Session *session __attribute__((unused)),
3551
3551
char *path, enum legacy_db_type *dbt)
3586
3586
/* Prototypes */
3587
void free_tmp_table(Session *thd, Table *entry);
3587
void free_tmp_table(Session *session, Table *entry);
3590
3590
Create field for temporary table from given field.
3592
@param thd Thread handler
3592
@param session Thread handler
3593
3593
@param org_field field from which new field will be created
3594
3594
@param name New field name
3595
3595
@param table Temporary table
3608
3608
new_created field
3611
Field *create_tmp_field_from_field(Session *thd, Field *org_field,
3611
Field *create_tmp_field_from_field(Session *session, Field *org_field,
3612
3612
const char *name, Table *table,
3613
3613
Item_field *item, uint32_t convert_blob_length)
3625
3625
org_field->field_name, table->s,
3626
3626
org_field->charset());
3628
new_field= org_field->new_field(thd->mem_root, table,
3628
new_field= org_field->new_field(session->mem_root, table,
3629
3629
table == org_field->table);
3650
3650
Create field for temporary table using type of given item.
3652
@param thd Thread handler
3652
@param session Thread handler
3653
3653
@param item Item to create a field for
3654
3654
@param table Temporary table
3655
3655
@param copy_func If set and item is a function, store copy of
3670
3670
new_created field
3673
static Field *create_tmp_field_from_item(Session *thd __attribute__((unused)),
3673
static Field *create_tmp_field_from_item(Session *session __attribute__((unused)),
3674
3674
Item *item, Table *table,
3675
3675
Item ***copy_func, bool modify_item,
3676
3676
uint32_t convert_blob_length)
3785
3785
Create field for information schema table.
3787
@param thd Thread handler
3787
@param session Thread handler
3788
3788
@param table Temporary table
3789
3789
@param item Item to create a field for
3794
3794
new_created field
3797
Field *create_tmp_field_for_schema(Session *thd __attribute__((unused)),
3797
Field *create_tmp_field_for_schema(Session *session __attribute__((unused)),
3798
3798
Item *item, Table *table)
3800
3800
if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
3819
3819
Create field for temporary table.
3821
@param thd Thread handler
3821
@param session Thread handler
3822
3822
@param table Temporary table
3823
3823
@param item Item to create a field for
3824
3824
@param type Type of item (normally item->type)
3844
3844
new_created field
3847
Field *create_tmp_field(Session *thd, Table *table,Item *item, Item::Type type,
3847
Field *create_tmp_field(Session *session, Table *table,Item *item, Item::Type type,
3848
3848
Item ***copy_func, Field **from_field,
3849
3849
Field **default_field,
3850
3850
bool group, bool modify_item,
3887
3887
if (field->maybe_null && !field->field->maybe_null())
3889
result= create_tmp_field_from_item(thd, item, table, NULL,
3889
result= create_tmp_field_from_item(session, item, table, NULL,
3890
3890
modify_item, convert_blob_length);
3891
3891
*from_field= field->field;
3892
3892
if (result && modify_item)
3893
3893
field->result_field= result;
3896
result= create_tmp_field_from_field(thd, (*from_field= field->field),
3896
result= create_tmp_field_from_field(session, (*from_field= field->field),
3897
3897
orig_item ? orig_item->name :
3927
3927
assert(((Item_result_field*)item)->result_field);
3928
3928
*from_field= ((Item_result_field*)item)->result_field;
3930
return create_tmp_field_from_item(thd, item, table,
3930
return create_tmp_field_from_item(session, item, table,
3931
3931
(make_copy_field ? 0 : copy_func),
3932
3932
modify_item, convert_blob_length);
3933
3933
case Item::TYPE_HOLDER:
3952
3952
value of argument save_sum_fields. The Item_field objects
3953
3953
are created in Session memory root.
3955
@param thd thread handle
3955
@param session thread handle
3956
3956
@param param a description used as input to create the table
3957
3957
@param fields list of items that will be used to define
3958
3958
column types of the table (also see NOTES)
3970
3970
#define RATIO_TO_PACK_ROWS 2
3973
create_tmp_table(Session *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
3973
create_tmp_table(Session *session,TMP_TABLE_PARAM *param,List<Item> &fields,
3974
3974
order_st *group, bool distinct, bool save_sum_fields,
3975
3975
uint64_t select_options, ha_rows rows_limit,
3976
3976
char *table_alias)
4001
4001
uint32_t total_uneven_bit_length= 0;
4002
4002
bool force_copy_fields= param->force_copy_fields;
4004
status_var_increment(thd->status_var.created_tmp_tables);
4004
status_var_increment(session->status_var.created_tmp_tables);
4006
4006
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
4007
4007
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
4014
4014
/* if we run out of slots or we are not using tempool */
4015
4015
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
4016
thd->thread_id, thd->tmp_table++);
4016
session->thread_id, session->tmp_table++);
4084
4084
return(NULL); /* purecov: inspected */
4086
4086
/* Copy_field belongs to TMP_TABLE_PARAM, allocate it in Session mem_root */
4087
if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
4087
if (!(param->copy_field= copy= new (session->mem_root) Copy_field[field_count]))
4089
4089
if (temp_pool_slot != MY_BIT_NONE)
4090
4090
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4101
4101
memset(from_field, 0, sizeof(Field*)*field_count);
4103
4103
table->mem_root= own_root;
4104
mem_root_save= thd->mem_root;
4105
thd->mem_root= &table->mem_root;
4104
mem_root_save= session->mem_root;
4105
session->mem_root= &table->mem_root;
4107
4107
table->field=reg_field;
4108
4108
table->alias= table_alias;
4112
4112
table->temp_pool_slot = temp_pool_slot;
4113
4113
table->copy_blobs= 1;
4114
table->in_use= session;
4115
4115
table->quick_keys.init();
4116
4116
table->covering_keys.init();
4117
4117
table->keys_in_use_for_query.init();
4119
4119
table->setShare(share);
4120
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
4120
init_tmp_table_share(session, share, "", 0, tmpname, tmpname);
4121
4121
share->blob_field= blob_field;
4122
4122
share->blob_ptr_size= portable_sizeof_char_ptr;
4123
4123
share->db_low_byte_first=1; // True for HEAP and MyISAM
4169
4169
if (!arg->const_item())
4171
4171
Field *new_field=
4172
create_tmp_field(thd, table, arg, arg->type(), ©_func,
4172
create_tmp_field(session, table, arg, arg->type(), ©_func,
4173
4173
tmp_from_field, &default_field[fieldnr],
4174
4174
group != 0,not_all_columns,
4189
4189
string_count++;
4190
4190
string_total_length+= new_field->pack_length();
4192
thd->mem_root= mem_root_save;
4193
thd->change_item_tree(argp, new Item_field(new_field));
4194
thd->mem_root= &table->mem_root;
4192
session->mem_root= mem_root_save;
4193
session->change_item_tree(argp, new Item_field(new_field));
4194
session->mem_root= &table->mem_root;
4195
4195
if (!(new_field->flags & NOT_NULL_FLAG))
4218
4218
that in the later case group is set to the row pointer.
4220
4220
Field *new_field= (param->schema_table) ?
4221
create_tmp_field_for_schema(thd, item, table) :
4222
create_tmp_field(thd, table, item, type, ©_func,
4221
create_tmp_field_for_schema(session, item, table) :
4222
create_tmp_field(session, table, item, type, ©_func,
4223
4223
tmp_from_field, &default_field[fieldnr],
4225
4225
!force_copy_fields &&
4445
4445
param->recinfo=recinfo;
4446
4446
store_record(table,s->default_values); // Make empty default record
4448
if (thd->variables.tmp_table_size == ~ (uint64_t) 0) // No limit
4448
if (session->variables.tmp_table_size == ~ (uint64_t) 0) // No limit
4449
4449
share->max_rows= ~(ha_rows) 0;
4451
4451
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
4452
cmin(thd->variables.tmp_table_size,
4453
thd->variables.max_heap_table_size) :
4454
thd->variables.tmp_table_size) /
4452
cmin(session->variables.tmp_table_size,
4453
session->variables.max_heap_table_size) :
4454
session->variables.tmp_table_size) /
4455
4455
share->reclength);
4456
4456
set_if_bigger(share->max_rows,1); // For dummy start options
4495
4495
if (!using_unique_constraint)
4497
4497
cur_group->buff=(char*) group_buff;
4498
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
4498
if (!(cur_group->field= field->new_key_field(session->mem_root,table,
4500
4500
test(maybe_null),
4501
4501
field->null_ptr,
4622
if (thd->is_fatal_error) // If end of memory
4622
if (session->is_fatal_error) // If end of memory
4623
4623
goto err; /* purecov: inspected */
4624
4624
share->db_record_offset= 1;
4625
4625
if (share->db_type() == myisam_hton)
4631
4631
if (table->open_tmp_table())
4634
thd->mem_root= mem_root_save;
4634
session->mem_root= mem_root_save;
4639
thd->mem_root= mem_root_save;
4640
table->free_tmp_table(thd); /* purecov: inspected */
4639
session->mem_root= mem_root_save;
4640
table->free_tmp_table(session); /* purecov: inspected */
4641
4641
if (temp_pool_slot != MY_BIT_NONE)
4642
4642
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
4643
4643
return(NULL); /* purecov: inspected */
4657
4657
The table is created in Session mem_root, so are the table's fields.
4658
4658
Consequently, if you don't BLOB fields, you don't need to free it.
4660
@param thd connection handle
4660
@param session connection handle
4661
4661
@param field_list list of column definitions
4664
4664
0 if out of memory, Table object in case of success
4667
Table *create_virtual_tmp_table(Session *thd, List<Create_field> &field_list)
4667
Table *create_virtual_tmp_table(Session *session, List<Create_field> &field_list)
4669
4669
uint32_t field_count= field_list.elements;
4670
4670
uint32_t blob_count= 0;
4679
4679
TABLE_SHARE *share;
4681
if (!multi_alloc_root(thd->mem_root,
4681
if (!multi_alloc_root(session->mem_root,
4682
4682
&table, sizeof(*table),
4683
4683
&share, sizeof(*share),
4684
4684
&field, (field_count + 1) * sizeof(Field*),
4725
4725
null_pack_length= (null_count + 7)/8;
4726
4726
share->reclength= record_length + null_pack_length;
4727
4727
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
4728
table->record[0]= (unsigned char*) thd->alloc(share->rec_buff_length);
4728
table->record[0]= (unsigned char*) session->alloc(share->rec_buff_length);
4729
4729
if (!table->record[0])
4736
4736
share->null_bytes= null_pack_length;
4739
table->in_use= thd; /* field->reset() may access table->in_use */
4739
table->in_use= session; /* field->reset() may access table->in_use */
4741
4741
/* Set up field pointers */
4742
4742
unsigned char *null_pos= table->record[0];
4925
void Table::free_tmp_table(Session *thd)
4925
void Table::free_tmp_table(Session *session)
4927
4927
MEM_ROOT own_root= mem_root;
4928
4928
const char *save_proc_info;
4930
save_proc_info=thd->get_proc_info();
4931
thd->set_proc_info("removing tmp table");
4930
save_proc_info=session->get_proc_info();
4931
session->set_proc_info("removing tmp table");
4950
4950
plugin_unlock(0, s->db_plugin);
4952
4952
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
4953
thd->set_proc_info(save_proc_info);
4953
session->set_proc_info(save_proc_info);
4963
bool create_myisam_from_heap(Session *thd, Table *table,
4963
bool create_myisam_from_heap(Session *session, Table *table,
4964
4964
MI_COLUMNDEF *start_recinfo,
4965
4965
MI_COLUMNDEF **recinfo,
4966
4966
int error, bool ignore_last_dupp_key_error)
4979
4979
new_table= *table;
4980
4980
share= *table->s;
4981
4981
new_table.s= &share;
4982
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
4982
new_table.s->db_plugin= ha_lock_engine(session, myisam_hton);
4983
4983
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
4984
4984
new_table.s->db_type())))
4985
4985
return(1); // End of memory
4987
save_proc_info=thd->get_proc_info();
4988
thd->set_proc_info("converting HEAP to MyISAM");
4987
save_proc_info=session->get_proc_info();
4988
session->set_proc_info("converting HEAP to MyISAM");
4990
4990
if (new_table.create_myisam_tmp_table(table->key_info, start_recinfo,
4991
recinfo, thd->lex->select_lex.options |
4991
recinfo, session->lex->select_lex.options |
4994
4994
if (new_table.open_tmp_table())
5052
5052
const char *new_proc_info=
5053
5053
(!strcmp(save_proc_info,"Copying to tmp table") ?
5054
5054
"Copying to tmp table on disk" : save_proc_info);
5055
thd->set_proc_info(new_proc_info);
5055
session->set_proc_info(new_proc_info);