10734
/****************************************************************************
10735
Create internal temporary table
10736
****************************************************************************/
10739
Create field for temporary table from given field.
10741
@param thd Thread handler
10742
@param org_field field from which new field will be created
10743
@param name New field name
10744
@param table Temporary table
10745
@param item !=NULL if item->result_field should point to new field.
10746
This is relevant for how fill_record() is going to work:
10747
If item != NULL then fill_record() will update
10748
the record in the original table.
10749
If item == NULL then fill_record() will update
10750
the temporary table
10751
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10752
field instead of blob.
10760
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
10761
const char *name, TABLE *table,
10762
Item_field *item, uint convert_blob_length)
10767
Make sure that the blob fits into a Field_varstring which has
10770
if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
10771
(org_field->flags & BLOB_FLAG))
10772
new_field= new Field_varstring(convert_blob_length,
10773
org_field->maybe_null(),
10774
org_field->field_name, table->s,
10775
org_field->charset());
10777
new_field= org_field->new_field(thd->mem_root, table,
10778
table == org_field->table);
10781
new_field->init(table);
10782
new_field->orig_table= org_field->orig_table;
10784
item->result_field= new_field;
10786
new_field->field_name= name;
10787
new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
10788
if (org_field->maybe_null() || (item && item->maybe_null))
10789
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
10790
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
10791
org_field->type() == MYSQL_TYPE_VARCHAR)
10792
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
10793
else if (org_field->type() == FIELD_TYPE_DOUBLE)
10794
((Field_double *) new_field)->not_fixed= TRUE;
10800
Create field for temporary table using type of given item.
10802
@param thd Thread handler
10803
@param item Item to create a field for
10804
@param table Temporary table
10805
@param copy_func If set and item is a function, store copy of
10807
@param modify_item 1 if item->result_field should point to new
10808
item. This is relevent for how fill_record()
10810
If modify_item is 1 then fill_record() will
10811
update the record in the original table.
10812
If modify_item is 0 then fill_record() will
10813
update the temporary table
10814
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10815
field instead of blob.
10823
static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
10824
Item ***copy_func, bool modify_item,
10825
uint convert_blob_length)
10827
bool maybe_null= item->maybe_null;
10830
switch (item->result_type()) {
10832
new_field= new Field_double(item->max_length, maybe_null,
10833
item->name, item->decimals, TRUE);
10837
Select an integer type with the minimal fit precision.
10838
MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
10839
Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
10840
Field_long : make them Field_longlong.
10842
if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
10843
new_field=new Field_longlong(item->max_length, maybe_null,
10844
item->name, item->unsigned_flag);
10846
new_field=new Field_long(item->max_length, maybe_null,
10847
item->name, item->unsigned_flag);
10849
case STRING_RESULT:
10850
DBUG_ASSERT(item->collation.collation);
10852
enum enum_field_types type;
10854
DATE/TIME fields have STRING_RESULT result type.
10855
To preserve type they needed to be handled separately.
10857
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
10858
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
10859
type == MYSQL_TYPE_TIMESTAMP)
10860
new_field= item->tmp_table_field_from_field_type(table, 1);
10862
Make sure that the blob fits into a Field_varstring which has
10865
else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
10866
convert_blob_length <= Field_varstring::MAX_SIZE &&
10867
convert_blob_length)
10868
new_field= new Field_varstring(convert_blob_length, maybe_null,
10869
item->name, table->s,
10870
item->collation.collation);
10872
new_field= item->make_string_field(table);
10873
new_field->set_derivation(item->collation.derivation);
10875
case DECIMAL_RESULT:
10877
uint8 dec= item->decimals;
10878
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
10879
uint32 len= item->max_length;
10882
Trying to put too many digits overall in a DECIMAL(prec,dec)
10883
will always throw a warning. We must limit dec to
10884
DECIMAL_MAX_SCALE however to prevent an assert() later.
10889
signed int overflow;
10891
dec= min(dec, DECIMAL_MAX_SCALE);
10894
If the value still overflows the field with the corrected dec,
10895
we'll throw out decimals rather than integers. This is still
10896
bad and of course throws a truncation warning.
10897
+1: for decimal point
10900
overflow= my_decimal_precision_to_length(intg + dec, dec,
10901
item->unsigned_flag) - len;
10904
dec= max(0, dec - overflow); // too long, discard fract
10906
len -= item->decimals - dec; // corrected value fits
10909
new_field= new Field_new_decimal(len, maybe_null, item->name,
10910
dec, item->unsigned_flag);
10915
// This case should never be choosen
10921
new_field->init(table);
10923
if (copy_func && item->is_result_field())
10924
*((*copy_func)++) = item; // Save for copy_funcs
10926
item->set_result_field(new_field);
10927
if (item->type() == Item::NULL_ITEM)
10928
new_field->is_created_from_null_item= TRUE;
10934
Create field for information schema table.
10936
@param thd Thread handler
10937
@param table Temporary table
10938
@param item Item to create a field for
10946
Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
10948
if (item->field_type() == MYSQL_TYPE_VARCHAR)
10951
if (item->max_length > MAX_FIELD_VARCHARLENGTH)
10952
field= new Field_blob(item->max_length, item->maybe_null,
10953
item->name, item->collation.collation);
10955
field= new Field_varstring(item->max_length, item->maybe_null,
10957
table->s, item->collation.collation);
10959
field->init(table);
10962
return item->tmp_table_field_from_field_type(table, 0);
10967
Create field for temporary table.
10969
@param thd Thread handler
10970
@param table Temporary table
10971
@param item Item to create a field for
10972
@param type Type of item (normally item->type)
10973
@param copy_func If set and item is a function, store copy of item
10975
@param from_field if field will be created using other field as example,
10976
pointer example field will be written here
10977
@param default_field If field has a default value field, store it here
10978
@param group 1 if we are going to do a relative group by on result
10979
@param modify_item 1 if item->result_field should point to new item.
10980
This is relevent for how fill_record() is going to
10982
If modify_item is 1 then fill_record() will update
10983
the record in the original table.
10984
If modify_item is 0 then fill_record() will update
10985
the temporary table
10986
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10987
field instead of blob.
10995
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
10996
Item ***copy_func, Field **from_field,
10997
Field **default_field,
10998
bool group, bool modify_item,
10999
bool table_cant_handle_bit_fields,
11000
bool make_copy_field,
11001
uint convert_blob_length)
11004
Item::Type orig_type= type;
11005
Item *orig_item= 0;
11007
if (type != Item::FIELD_ITEM &&
11008
item->real_item()->type() == Item::FIELD_ITEM)
11011
item= item->real_item();
11012
type= Item::FIELD_ITEM;
11016
case Item::SUM_FUNC_ITEM:
11018
Item_sum *item_sum=(Item_sum*) item;
11019
result= item_sum->create_tmp_field(group, table, convert_blob_length);
11021
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
11024
case Item::FIELD_ITEM:
11025
case Item::DEFAULT_VALUE_ITEM:
11027
Item_field *field= (Item_field*) item;
11028
bool orig_modify= modify_item;
11029
if (orig_type == Item::REF_ITEM)
11032
If item have to be able to store NULLs but underlaid field can't do it,
11033
create_tmp_field_from_field() can't be used for tmp field creation.
11035
if (field->maybe_null && !field->field->maybe_null())
11037
result= create_tmp_field_from_item(thd, item, table, NULL,
11038
modify_item, convert_blob_length);
11039
*from_field= field->field;
11040
if (result && modify_item)
11041
field->result_field= result;
11043
else if (table_cant_handle_bit_fields && field->field->type() ==
11046
*from_field= field->field;
11047
result= create_tmp_field_from_item(thd, item, table, copy_func,
11048
modify_item, convert_blob_length);
11049
if (result && modify_item)
11050
field->result_field= result;
11053
result= create_tmp_field_from_field(thd, (*from_field= field->field),
11054
orig_item ? orig_item->name :
11057
modify_item ? field :
11059
convert_blob_length);
11060
if (orig_type == Item::REF_ITEM && orig_modify)
11061
((Item_ref*)orig_item)->set_result_field(result);
11062
if (field->field->eq_def(result))
11063
*default_field= field->field;
11067
case Item::FUNC_ITEM:
11069
case Item::COND_ITEM:
11070
case Item::FIELD_AVG_ITEM:
11071
case Item::FIELD_STD_ITEM:
11072
case Item::SUBSELECT_ITEM:
11073
/* The following can only happen with 'CREATE TABLE ... SELECT' */
11074
case Item::PROC_ITEM:
11075
case Item::INT_ITEM:
11076
case Item::REAL_ITEM:
11077
case Item::DECIMAL_ITEM:
11078
case Item::STRING_ITEM:
11079
case Item::REF_ITEM:
11080
case Item::NULL_ITEM:
11081
case Item::VARBIN_ITEM:
11082
if (make_copy_field)
11084
DBUG_ASSERT(((Item_result_field*)item)->result_field);
11085
*from_field= ((Item_result_field*)item)->result_field;
11087
return create_tmp_field_from_item(thd, item, table,
11088
(make_copy_field ? 0 : copy_func),
11089
modify_item, convert_blob_length);
11090
case Item::TYPE_HOLDER:
11091
result= ((Item_type_holder *)item)->make_field_by_type(table);
11092
result->set_derivation(item->collation.derivation);
11094
default: // Dosen't have to be stored
11100
Set up column usage bitmaps for a temporary table
11103
For temporary tables, we need one bitmap with all columns set and
11104
a tmp_set bitmap to be used by things like filesort.
11107
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
11109
uint field_count= table->s->fields;
11110
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
11112
bitmap_init(&table->tmp_set,
11113
(my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
11114
field_count, FALSE);
11115
/* write_set and all_set are copies of read_set */
11116
table->def_write_set= table->def_read_set;
11117
table->s->all_set= table->def_read_set;
11118
bitmap_set_all(&table->s->all_set);
11119
table->default_column_bitmaps();
11124
Create a temp table according to a field list.
11126
Given field pointers are changed to point at tmp_table for
11127
send_fields. The table object is self contained: it's
11128
allocated in its own memory root, as well as Field objects
11129
created for table columns.
11130
This function will replace Item_sum items in 'fields' list with
11131
corresponding Item_field items, pointing at the fields in the
11132
temporary table, unless this was prohibited by TRUE
11133
value of argument save_sum_fields. The Item_field objects
11134
are created in THD memory root.
11136
@param thd thread handle
11137
@param param a description used as input to create the table
11138
@param fields list of items that will be used to define
11139
column types of the table (also see NOTES)
11140
@param group TODO document
11141
@param distinct should table rows be distinct
11142
@param save_sum_fields see NOTES
11143
@param select_options
11145
@param table_alias possible name of the temporary table that can
11146
be used for name resolving; can be "".
11149
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
11150
#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
11151
#define RATIO_TO_PACK_ROWS 2
11152
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
11155
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
11156
ORDER *group, bool distinct, bool save_sum_fields,
11157
ulonglong select_options, ha_rows rows_limit,
11160
MEM_ROOT *mem_root_save, own_root;
11162
TABLE_SHARE *share;
11163
uint i,field_count,null_count,null_pack_length;
11164
uint copy_func_count= param->func_count;
11165
uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
11166
uint blob_count,group_null_items, string_count;
11167
uint temp_pool_slot=MY_BIT_NONE;
11169
ulong reclength, string_total_length;
11170
bool using_unique_constraint= 0;
11171
bool use_packed_rows= 0;
11172
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
11173
char *tmpname,path[FN_REFLEN];
11174
uchar *pos, *group_buff, *bitmaps;
11176
Field **reg_field, **from_field, **default_field;
11178
Copy_field *copy=0;
11180
KEY_PART_INFO *key_part_info;
11182
MI_COLUMNDEF *recinfo;
11183
uint total_uneven_bit_length= 0;
11184
bool force_copy_fields= param->force_copy_fields;
11185
DBUG_ENTER("create_tmp_table");
11186
DBUG_PRINT("enter",
11187
("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d",
11188
(int) distinct, (int) save_sum_fields,
11189
(ulong) rows_limit,test(group)));
11191
status_var_increment(thd->status_var.created_tmp_tables);
11193
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11194
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11196
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11197
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11198
current_pid, temp_pool_slot);
11201
/* if we run out of slots or we are not using tempool */
11202
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11203
thd->thread_id, thd->tmp_table++);
11207
No need to change table name to lower case as we are only creating
11208
MyISAM or HEAP tables here
11210
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11215
if (!param->quick_group)
11216
group=0; // Can't use group key
11217
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
11220
marker == 4 means two things:
11221
- store NULLs in the key, and
11222
- convert BIT fields to 64-bit long, needed because MEMORY tables
11223
can't index BIT fields.
11225
(*tmp->item)->marker= 4;
11226
if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
11227
using_unique_constraint=1;
11229
if (param->group_length >= MAX_BLOB_WIDTH)
11230
using_unique_constraint=1;
11232
distinct=0; // Can't use distinct
11235
field_count=param->field_count+param->func_count+param->sum_func_count;
11236
hidden_field_count=param->hidden_field_count;
11239
When loose index scan is employed as access method, it already
11240
computes all groups and the result of all aggregate functions. We
11241
make space for the items of the aggregate function in the list of
11242
functions TMP_TABLE_PARAM::items_to_copy, so that the values of
11243
these items are stored in the temporary table.
11245
if (param->precomputed_group_by)
11246
copy_func_count+= param->sum_func_count;
11248
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11250
if (!multi_alloc_root(&own_root,
11251
&table, sizeof(*table),
11252
&share, sizeof(*share),
11253
®_field, sizeof(Field*) * (field_count+1),
11254
&default_field, sizeof(Field*) * (field_count),
11255
&blob_field, sizeof(uint)*(field_count+1),
11256
&from_field, sizeof(Field*)*field_count,
11257
©_func, sizeof(*copy_func)*(copy_func_count+1),
11258
¶m->keyinfo, sizeof(*param->keyinfo),
11260
sizeof(*key_part_info)*(param->group_parts+1),
11261
¶m->start_recinfo,
11262
sizeof(*param->recinfo)*(field_count*2+4),
11263
&tmpname, (uint) strlen(path)+1,
11264
&group_buff, (group && ! using_unique_constraint ?
11265
param->group_length : 0),
11266
&bitmaps, bitmap_buffer_size(field_count)*2,
11269
if (temp_pool_slot != MY_BIT_NONE)
11270
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11271
DBUG_RETURN(NULL); /* purecov: inspected */
11273
/* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
11274
if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
11276
if (temp_pool_slot != MY_BIT_NONE)
11277
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11278
free_root(&own_root, MYF(0)); /* purecov: inspected */
11279
DBUG_RETURN(NULL); /* purecov: inspected */
11281
param->items_to_copy= copy_func;
11282
strmov(tmpname,path);
11283
/* make table according to fields */
11285
bzero((char*) table,sizeof(*table));
11286
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
11287
bzero((char*) default_field, sizeof(Field*) * (field_count));
11288
bzero((char*) from_field,sizeof(Field*)*field_count);
11290
table->mem_root= own_root;
11291
mem_root_save= thd->mem_root;
11292
thd->mem_root= &table->mem_root;
11294
table->field=reg_field;
11295
table->alias= table_alias;
11296
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11297
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11299
table->temp_pool_slot = temp_pool_slot;
11300
table->copy_blobs= 1;
11301
table->in_use= thd;
11302
table->quick_keys.init();
11303
table->covering_keys.init();
11304
table->keys_in_use_for_query.init();
11307
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11308
share->blob_field= blob_field;
11309
share->blob_ptr_size= portable_sizeof_char_ptr;
11310
share->db_low_byte_first=1; // True for HEAP and MyISAM
11311
share->table_charset= param->table_charset;
11312
share->primary_key= MAX_KEY; // Indicate no primary key
11313
share->keys_for_keyread.init();
11314
share->keys_in_use.init();
11316
/* Calculate which type of fields we will store in the temporary table */
11318
reclength= string_total_length= 0;
11319
blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
11320
param->using_indirect_summary_function=0;
11322
List_iterator_fast<Item> li(fields);
11324
Field **tmp_from_field=from_field;
11325
while ((item=li++))
11327
Item::Type type=item->type();
11328
if (not_all_columns)
11330
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
11332
if (item->used_tables() & OUTER_REF_TABLE_BIT)
11333
item->update_used_tables();
11334
if (type == Item::SUBSELECT_ITEM ||
11335
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
11338
Mark that the we have ignored an item that refers to a summary
11339
function. We need to know this if someone is going to use
11340
DISTINCT on the result.
11342
param->using_indirect_summary_function=1;
11346
if (item->const_item() && (int) hidden_field_count <= 0)
11347
continue; // We don't have to store this
11349
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
11350
{ /* Can't calc group yet */
11351
((Item_sum*) item)->result_field=0;
11352
for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
11354
Item **argp= ((Item_sum*) item)->args + i;
11356
if (!arg->const_item())
11359
create_tmp_field(thd, table, arg, arg->type(), ©_func,
11360
tmp_from_field, &default_field[fieldnr],
11361
group != 0,not_all_columns,
11363
param->convert_blob_length);
11365
goto err; // Should be OOM
11367
reclength+=new_field->pack_length();
11368
if (new_field->flags & BLOB_FLAG)
11370
*blob_field++= fieldnr;
11373
if (new_field->type() == MYSQL_TYPE_BIT)
11374
total_uneven_bit_length+= new_field->field_length & 7;
11375
*(reg_field++)= new_field;
11376
if (new_field->real_type() == MYSQL_TYPE_STRING ||
11377
new_field->real_type() == MYSQL_TYPE_VARCHAR)
11380
string_total_length+= new_field->pack_length();
11382
thd->mem_root= mem_root_save;
11383
thd->change_item_tree(argp, new Item_field(new_field));
11384
thd->mem_root= &table->mem_root;
11385
if (!(new_field->flags & NOT_NULL_FLAG))
11389
new_field->maybe_null() is still false, it will be
11390
changed below. But we have to setup Item_field correctly
11392
(*argp)->maybe_null=1;
11394
new_field->field_index= fieldnr++;
11401
The last parameter to create_tmp_field() is a bit tricky:
11403
We need to set it to 0 in union, to get fill_record() to modify the
11405
We need to set it to 1 on multi-table-update and in select to
11406
write rows to the temporary table.
11407
We here distinguish between UNION and multi-table-updates by the fact
11408
that in the later case group is set to the row pointer.
11410
Field *new_field= (param->schema_table) ?
11411
create_tmp_field_for_schema(thd, item, table) :
11412
create_tmp_field(thd, table, item, type, ©_func,
11413
tmp_from_field, &default_field[fieldnr],
11415
!force_copy_fields &&
11416
(not_all_columns || group !=0),
11418
If item->marker == 4 then we force create_tmp_field
11419
to create a 64-bit longs for BIT fields because HEAP
11420
tables can't index BIT fields directly. We do the same
11421
for distinct, as we want the distinct index to be
11422
usable in this case too.
11424
item->marker == 4 || param->bit_fields_as_long,
11426
param->convert_blob_length);
11430
if (thd->is_fatal_error)
11431
goto err; // Got OOM
11432
continue; // Some kindf of const item
11434
if (type == Item::SUM_FUNC_ITEM)
11435
((Item_sum *) item)->result_field= new_field;
11437
reclength+=new_field->pack_length();
11438
if (!(new_field->flags & NOT_NULL_FLAG))
11440
if (new_field->type() == MYSQL_TYPE_BIT)
11441
total_uneven_bit_length+= new_field->field_length & 7;
11442
if (new_field->flags & BLOB_FLAG)
11444
*blob_field++= fieldnr;
11447
if (item->marker == 4 && item->maybe_null)
11449
group_null_items++;
11450
new_field->flags|= GROUP_FLAG;
11452
new_field->field_index= fieldnr++;
11453
*(reg_field++)= new_field;
11455
if (!--hidden_field_count)
11458
This was the last hidden field; Remember how many hidden fields could
11461
hidden_null_count=null_count;
11463
We need to update hidden_field_count as we may have stored group
11464
functions with constant arguments
11466
param->hidden_field_count= fieldnr;
11470
DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
11471
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
11472
field_count= fieldnr;
11474
*blob_field= 0; // End marker
11475
share->fields= field_count;
11477
/* If result table is small; use a heap */
11478
/* future: storage engine selection can be made dynamic? */
11479
if (blob_count || using_unique_constraint ||
11480
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
11481
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
11483
share->db_plugin= ha_lock_engine(0, myisam_hton);
11484
table->file= get_new_handler(share, &table->mem_root,
11487
(param->group_parts > table->file->max_key_parts() ||
11488
param->group_length > table->file->max_key_length()))
11489
using_unique_constraint=1;
11493
share->db_plugin= ha_lock_engine(0, heap_hton);
11494
table->file= get_new_handler(share, &table->mem_root,
11501
if (!using_unique_constraint)
11502
reclength+= group_null_items; // null flag is stored separately
11504
share->blob_fields= blob_count;
11505
if (blob_count == 0)
11507
/* We need to ensure that first byte is not 0 for the delete link */
11508
if (param->hidden_field_count)
11509
hidden_null_count++;
11513
hidden_null_pack_length=(hidden_null_count+7)/8;
11514
null_pack_length= (hidden_null_pack_length +
11515
(null_count + total_uneven_bit_length + 7) / 8);
11516
reclength+=null_pack_length;
11518
reclength=1; // Dummy select
11519
/* Use packed rows if there is blobs or a lot of space to gain */
11520
if (blob_count || ((string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS) && (reclength / string_total_length <= RATIO_TO_PACK_ROWS || (string_total_length / string_count) >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
11521
use_packed_rows= 1;
11523
share->reclength= reclength;
11525
uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
11526
share->rec_buff_length= alloc_length;
11527
if (!(table->record[0]= (uchar*)
11528
alloc_root(&table->mem_root, alloc_length*3)))
11530
table->record[1]= table->record[0]+alloc_length;
11531
share->default_values= table->record[1]+alloc_length;
11533
copy_func[0]=0; // End marker
11534
param->func_count= copy_func - param->items_to_copy;
11536
setup_tmp_table_column_bitmaps(table, bitmaps);
11538
recinfo=param->start_recinfo;
11539
null_flags=(uchar*) table->record[0];
11540
pos=table->record[0]+ null_pack_length;
11541
if (null_pack_length)
11543
bzero((uchar*) recinfo,sizeof(*recinfo));
11544
recinfo->type=FIELD_NORMAL;
11545
recinfo->length=null_pack_length;
11547
bfill(null_flags,null_pack_length,255); // Set null fields
11549
table->null_flags= (uchar*) table->record[0];
11550
share->null_fields= null_count+ hidden_null_count;
11551
share->null_bytes= null_pack_length;
11553
null_count= (blob_count == 0) ? 1 : 0;
11554
hidden_field_count=param->hidden_field_count;
11555
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
11557
Field *field= *reg_field;
11559
bzero((uchar*) recinfo,sizeof(*recinfo));
11561
if (!(field->flags & NOT_NULL_FLAG))
11563
if (field->flags & GROUP_FLAG && !using_unique_constraint)
11566
We have to reserve one byte here for NULL bits,
11567
as this is updated by 'end_update()'
11569
*pos++=0; // Null is stored here
11571
recinfo->type=FIELD_NORMAL;
11573
bzero((uchar*) recinfo,sizeof(*recinfo));
11577
recinfo->null_bit= 1 << (null_count & 7);
11578
recinfo->null_pos= null_count/8;
11580
field->move_field(pos,null_flags+null_count/8,
11581
1 << (null_count & 7));
11585
field->move_field(pos,(uchar*) 0,0);
11586
if (field->type() == MYSQL_TYPE_BIT)
11588
/* We have to reserve place for extra bits among null bits */
11589
((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8,
11591
null_count+= (field->field_length & 7);
11596
Test if there is a default field value. The test for ->ptr is to skip
11597
'offset' fields generated by initalize_tables
11599
if (default_field[i] && default_field[i]->ptr)
11602
default_field[i] is set only in the cases when 'field' can
11603
inherit the default value that is defined for the field referred
11604
by the Item_field object from which 'field' has been created.
11607
Field *orig_field= default_field[i];
11608
/* Get the value from default_values */
11609
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
11610
orig_field->table->record[0]);
11611
orig_field->move_field_offset(diff); // Points now at default_values
11612
if (orig_field->is_real_null())
11616
field->set_notnull();
11617
memcpy(field->ptr, orig_field->ptr, field->pack_length());
11619
orig_field->move_field_offset(-diff); // Back to record[0]
11623
{ /* Not a table Item */
11624
copy->set(field,from_field[i],save_sum_fields);
11627
length=field->pack_length();
11630
/* Make entry for create table */
11631
recinfo->length=length;
11632
if (field->flags & BLOB_FLAG)
11633
recinfo->type= (int) FIELD_BLOB;
11634
else if (use_packed_rows &&
11635
field->real_type() == MYSQL_TYPE_STRING &&
11636
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
11637
recinfo->type=FIELD_SKIP_ENDSPACE;
11639
recinfo->type=FIELD_NORMAL;
11640
if (!--hidden_field_count)
11641
null_count=(null_count+7) & ~7; // move to next byte
11643
// fix table name in field entry
11644
field->table_name= &table->alias;
11647
param->copy_field_end=copy;
11648
param->recinfo=recinfo;
11649
store_record(table,s->default_values); // Make empty default record
11651
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
11652
share->max_rows= ~(ha_rows) 0;
11654
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11655
min(thd->variables.tmp_table_size,
11656
thd->variables.max_heap_table_size) :
11657
thd->variables.tmp_table_size) /
11659
set_if_bigger(share->max_rows,1); // For dummy start options
11661
Push the LIMIT clause to the temporary table creation, so that we
11662
materialize only up to 'rows_limit' records instead of all result records.
11664
set_if_smaller(share->max_rows, rows_limit);
11665
param->end_write_records= rows_limit;
11667
keyinfo= param->keyinfo;
11671
DBUG_PRINT("info",("Creating group key in temporary table"));
11672
table->group=group; /* Table is grouped by key */
11673
param->group_buff=group_buff;
11675
share->uniques= test(using_unique_constraint);
11676
table->key_info=keyinfo;
11677
keyinfo->key_part=key_part_info;
11678
keyinfo->flags=HA_NOSAME;
11679
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
11680
keyinfo->key_length=0;
11681
keyinfo->rec_per_key=0;
11682
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11683
keyinfo->name= (char*) "group_key";
11684
ORDER *cur_group= group;
11685
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
11687
Field *field=(*cur_group->item)->get_tmp_table_field();
11688
bool maybe_null=(*cur_group->item)->maybe_null;
11689
key_part_info->null_bit=0;
11690
key_part_info->field= field;
11691
key_part_info->offset= field->offset(table->record[0]);
11692
key_part_info->length= (uint16) field->key_length();
11693
key_part_info->type= (uint8) field->key_type();
11694
key_part_info->key_type =
11695
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11696
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11697
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11698
0 : FIELDFLAG_BINARY;
11699
if (!using_unique_constraint)
11701
cur_group->buff=(char*) group_buff;
11702
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
11707
goto err; /* purecov: inspected */
11711
To be able to group on NULL, we reserved place in group_buff
11712
for the NULL flag just before the column. (see above).
11713
The field data is after this flag.
11714
The NULL flag is updated in 'end_update()' and 'end_write()'
11716
keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
11717
key_part_info->null_bit=field->null_bit;
11718
key_part_info->null_offset= (uint) (field->null_ptr -
11719
(uchar*) table->record[0]);
11720
cur_group->buff++; // Pointer to field data
11721
group_buff++; // Skipp null flag
11723
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
11724
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
11725
group_buff+= cur_group->field->pack_length();
11727
keyinfo->key_length+= key_part_info->length;
11731
if (distinct && field_count != param->hidden_field_count)
11734
Create an unique key or an unique constraint over all columns
11735
that should be in the result. In the temporary table, there are
11736
'param->hidden_field_count' extra columns, whose null bits are stored
11737
in the first 'hidden_null_pack_length' bytes of the row.
11739
DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
11744
Special mode for index creation in MyISAM used to support unique
11745
indexes on blobs with arbitrary length. Such indexes cannot be
11750
null_pack_length-=hidden_null_pack_length;
11751
keyinfo->key_parts= ((field_count-param->hidden_field_count)+
11752
(share->uniques ? test(null_pack_length) : 0));
11753
table->distinct= 1;
11755
if (!(key_part_info= (KEY_PART_INFO*)
11756
alloc_root(&table->mem_root,
11757
keyinfo->key_parts * sizeof(KEY_PART_INFO))))
11759
bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
11760
table->key_info=keyinfo;
11761
keyinfo->key_part=key_part_info;
11762
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
11763
keyinfo->key_length=(uint16) reclength;
11764
keyinfo->name= (char*) "distinct_key";
11765
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11766
keyinfo->rec_per_key=0;
11769
Create an extra field to hold NULL bits so that unique indexes on
11770
blobs can distinguish NULL from 0. This extra field is not needed
11771
when we do not use UNIQUE indexes for blobs.
11773
if (null_pack_length && share->uniques)
11775
key_part_info->null_bit=0;
11776
key_part_info->offset=hidden_null_pack_length;
11777
key_part_info->length=null_pack_length;
11778
key_part_info->field= new Field_string(table->record[0],
11779
(uint32) key_part_info->length,
11783
NullS, &my_charset_bin);
11784
if (!key_part_info->field)
11786
key_part_info->field->init(table);
11787
key_part_info->key_type=FIELDFLAG_BINARY;
11788
key_part_info->type= HA_KEYTYPE_BINARY;
11791
/* Create a distinct key over the columns we are going to return */
11792
for (i=param->hidden_field_count, reg_field=table->field + i ;
11794
i++, reg_field++, key_part_info++)
11796
key_part_info->null_bit=0;
11797
key_part_info->field= *reg_field;
11798
key_part_info->offset= (*reg_field)->offset(table->record[0]);
11799
key_part_info->length= (uint16) (*reg_field)->pack_length();
11801
The below method of computing the key format length of the
11802
key part is a copy/paste from opt_range.cc, and table.cc.
11803
This should be factored out, e.g. as a method of Field.
11804
In addition it is not clear if any of the Field::*_length
11805
methods is supposed to compute the same length. If so, it
11808
key_part_info->store_length= key_part_info->length;
11810
if ((*reg_field)->real_maybe_null())
11811
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
11812
if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
11813
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
11814
key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
11816
key_part_info->type= (uint8) (*reg_field)->key_type();
11817
key_part_info->key_type =
11818
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11819
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11820
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11821
0 : FIELDFLAG_BINARY;
11825
if (thd->is_fatal_error) // If end of memory
11826
goto err; /* purecov: inspected */
11827
share->db_record_offset= 1;
11828
if (share->db_type() == myisam_hton)
11830
if (create_myisam_tmp_table(table, param->keyinfo, param->start_recinfo,
11831
¶m->recinfo, select_options))
11834
if (open_tmp_table(table))
11837
thd->mem_root= mem_root_save;
11839
DBUG_RETURN(table);
11842
thd->mem_root= mem_root_save;
11843
free_tmp_table(thd,table); /* purecov: inspected */
11844
if (temp_pool_slot != MY_BIT_NONE)
11845
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11846
DBUG_RETURN(NULL); /* purecov: inspected */
11853
Create a temporary table to weed out duplicate rowid combinations
11857
create_duplicate_weedout_tmp_table()
11859
uniq_tuple_length_arg
11863
Create a temporary table to weed out duplicate rowid combinations. The
11864
table has a single column that is a concatenation of all rowids in the
11867
Depending on the needed length, there are two cases:
11869
1. When the length of the column < max_key_length:
11871
CREATE TABLE tmp (col VARBINARY(n) NOT NULL, UNIQUE KEY(col));
11873
2. Otherwise (not a valid SQL syntax but internally supported):
11875
CREATE TABLE tmp (col VARBINARY NOT NULL, UNIQUE CONSTRAINT(col));
11877
The code in this function was produced by extraction of relevant parts
11878
from create_tmp_table().
11885
TABLE *create_duplicate_weedout_tmp_table(THD *thd,
11886
uint uniq_tuple_length_arg,
11887
SJ_TMP_TABLE *sjtbl)
11889
MEM_ROOT *mem_root_save, own_root;
11891
TABLE_SHARE *share;
11892
uint temp_pool_slot=MY_BIT_NONE;
11893
char *tmpname,path[FN_REFLEN];
11895
KEY_PART_INFO *key_part_info;
11900
MI_COLUMNDEF *recinfo, *start_recinfo;
11901
bool using_unique_constraint=FALSE;
11902
bool use_packed_rows= FALSE;
11903
Field *field, *key_field;
11904
uint blob_count, null_pack_length, null_count;
11907
DBUG_ENTER("create_duplicate_weedout_tmp_table");
11910
STEP 1: Get temporary table name
11912
statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
11913
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11914
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11916
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11917
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11918
current_pid, temp_pool_slot);
11921
/* if we run out of slots or we are not using tempool */
11922
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11923
thd->thread_id, thd->tmp_table++);
11925
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11927
/* STEP 2: Figure if we'll be using a key or blob+constraint */
11928
if (uniq_tuple_length_arg >= CONVERT_IF_BIGGER_TO_BLOB)
11929
using_unique_constraint= TRUE;
11931
/* STEP 3: Allocate memory for temptable description */
11932
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11933
if (!multi_alloc_root(&own_root,
11934
&table, sizeof(*table),
11935
&share, sizeof(*share),
11936
®_field, sizeof(Field*) * (1+1),
11937
&blob_field, sizeof(uint)*2,
11938
&keyinfo, sizeof(*keyinfo),
11939
&key_part_info, sizeof(*key_part_info) * 2,
11941
sizeof(*recinfo)*(1*2+4),
11942
&tmpname, (uint) strlen(path)+1,
11943
&group_buff, (!using_unique_constraint ?
11944
uniq_tuple_length_arg : 0),
11945
&bitmaps, bitmap_buffer_size(1)*2,
11948
if (temp_pool_slot != MY_BIT_NONE)
11949
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11952
strmov(tmpname,path);
11955
/* STEP 4: Create TABLE description */
11956
bzero((char*) table,sizeof(*table));
11957
bzero((char*) reg_field,sizeof(Field*)*2);
11959
table->mem_root= own_root;
11960
mem_root_save= thd->mem_root;
11961
thd->mem_root= &table->mem_root;
11963
table->field=reg_field;
11964
table->alias= "weedout-tmp";
11965
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11966
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11968
table->temp_pool_slot = temp_pool_slot;
11969
table->copy_blobs= 1;
11970
table->in_use= thd;
11971
table->quick_keys.init();
11972
table->covering_keys.init();
11973
table->keys_in_use_for_query.init();
11976
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11977
share->blob_field= blob_field;
11978
share->blob_ptr_size= portable_sizeof_char_ptr;
11979
share->db_low_byte_first=1; // True for HEAP and MyISAM
11980
share->table_charset= NULL;
11981
share->primary_key= MAX_KEY; // Indicate no primary key
11982
share->keys_for_keyread.init();
11983
share->keys_in_use.init();
11987
/* Create the field */
11990
For the sake of uniformity, always use Field_varstring (altough we could
11991
use Field_string for shorter keys)
11993
field= new Field_varstring(uniq_tuple_length_arg, FALSE, "rowids", share,
11997
field->table= table;
11998
field->key_start.init(0);
11999
field->part_of_key.init(0);
12000
field->part_of_sortkey.init(0);
12001
field->unireg_check= Field::NONE;
12002
field->flags= (NOT_NULL_FLAG | BINARY_FLAG | NO_DEFAULT_VALUE_FLAG);
12003
field->reset_fields();
12004
field->init(table);
12005
field->orig_table= NULL;
12007
field->field_index= 0;
12009
*(reg_field++)= field;
12014
share->blob_fields= 0;
12017
uint reclength= field->pack_length();
12018
if (using_unique_constraint)
12020
share->db_plugin= ha_lock_engine(0, myisam_hton);
12021
table->file= get_new_handler(share, &table->mem_root,
12023
DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length());
12027
share->db_plugin= ha_lock_engine(0, heap_hton);
12028
table->file= get_new_handler(share, &table->mem_root,
12036
null_pack_length= 1;
12037
reclength += null_pack_length;
12039
share->reclength= reclength;
12041
uint alloc_length=ALIGN_SIZE(share->reclength + MI_UNIQUE_HASH_LENGTH+1);
12042
share->rec_buff_length= alloc_length;
12043
if (!(table->record[0]= (uchar*)
12044
alloc_root(&table->mem_root, alloc_length*3)))
12046
table->record[1]= table->record[0]+alloc_length;
12047
share->default_values= table->record[1]+alloc_length;
12049
setup_tmp_table_column_bitmaps(table, bitmaps);
12051
recinfo= start_recinfo;
12052
null_flags=(uchar*) table->record[0];
12053
pos=table->record[0]+ null_pack_length;
12054
if (null_pack_length)
12056
bzero((uchar*) recinfo,sizeof(*recinfo));
12057
recinfo->type=FIELD_NORMAL;
12058
recinfo->length=null_pack_length;
12060
bfill(null_flags,null_pack_length,255); // Set null fields
12062
table->null_flags= (uchar*) table->record[0];
12063
share->null_fields= null_count;
12064
share->null_bytes= null_pack_length;
12069
//Field *field= *reg_field;
12071
bzero((uchar*) recinfo,sizeof(*recinfo));
12072
field->move_field(pos,(uchar*) 0,0);
12076
Test if there is a default field value. The test for ->ptr is to skip
12077
'offset' fields generated by initalize_tables
12079
// Initialize the table field:
12080
bzero(field->ptr, field->pack_length());
12082
length=field->pack_length();
12085
/* Make entry for create table */
12086
recinfo->length=length;
12087
if (field->flags & BLOB_FLAG)
12088
recinfo->type= (int) FIELD_BLOB;
12089
else if (use_packed_rows &&
12090
field->real_type() == MYSQL_TYPE_STRING &&
12091
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
12092
recinfo->type=FIELD_SKIP_ENDSPACE;
12094
recinfo->type=FIELD_NORMAL;
12096
field->table_name= &table->alias;
12099
//param->recinfo=recinfo;
12100
//store_record(table,s->default_values); // Make empty default record
12102
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
12103
share->max_rows= ~(ha_rows) 0;
12105
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
12106
min(thd->variables.tmp_table_size,
12107
thd->variables.max_heap_table_size) :
12108
thd->variables.tmp_table_size) /
12110
set_if_bigger(share->max_rows,1); // For dummy start options
12113
//// keyinfo= param->keyinfo;
12116
DBUG_PRINT("info",("Creating group key in temporary table"));
12118
share->uniques= test(using_unique_constraint);
12119
table->key_info=keyinfo;
12120
keyinfo->key_part=key_part_info;
12121
keyinfo->flags=HA_NOSAME;
12122
keyinfo->usable_key_parts= keyinfo->key_parts= 1;
12123
keyinfo->key_length=0;
12124
keyinfo->rec_per_key=0;
12125
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
12126
keyinfo->name= (char*) "weedout_key";
12128
key_part_info->null_bit=0;
12129
key_part_info->field= field;
12130
key_part_info->offset= field->offset(table->record[0]);
12131
key_part_info->length= (uint16) field->key_length();
12132
key_part_info->type= (uint8) field->key_type();
12133
key_part_info->key_type = FIELDFLAG_BINARY;
12134
if (!using_unique_constraint)
12136
if (!(key_field= field->new_key_field(thd->mem_root, table,
12141
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this?
12143
keyinfo->key_length+= key_part_info->length;
12147
if (thd->is_fatal_error) // If end of memory
12149
share->db_record_offset= 1;
12150
if (share->db_type() == myisam_hton)
12153
if (create_myisam_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
12156
sjtbl->start_recinfo= start_recinfo;
12157
sjtbl->recinfo= recinfo;
12158
if (open_tmp_table(table))
12161
thd->mem_root= mem_root_save;
12162
DBUG_RETURN(table);
12165
thd->mem_root= mem_root_save;
12166
free_tmp_table(thd,table); /* purecov: inspected */
12167
if (temp_pool_slot != MY_BIT_NONE)
12168
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
12169
DBUG_RETURN(NULL); /* purecov: inspected */
12172
/****************************************************************************/
12175
Create a reduced TABLE object with properly set up Field list from a
12176
list of field definitions.
12178
The created table doesn't have a table handler associated with
12179
it, has no keys, no group/distinct, no copy_funcs array.
12180
The sole purpose of this TABLE object is to use the power of Field
12181
class to read/write data to/from table->record[0]. Then one can store
12182
the record in any container (RB tree, hash, etc).
12183
The table is created in THD mem_root, so are the table's fields.
12184
Consequently, if you don't BLOB fields, you don't need to free it.
12186
@param thd connection handle
12187
@param field_list list of column definitions
12190
0 if out of memory, TABLE object in case of success
12193
TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
12195
uint field_count= field_list.elements;
12196
uint blob_count= 0;
12198
Create_field *cdef; /* column definition */
12199
uint record_length= 0;
12200
uint null_count= 0; /* number of columns which may be null */
12201
uint null_pack_length; /* NULL representation array length */
12205
TABLE_SHARE *share;
12207
if (!multi_alloc_root(thd->mem_root,
12208
&table, sizeof(*table),
12209
&share, sizeof(*share),
12210
&field, (field_count + 1) * sizeof(Field*),
12211
&blob_field, (field_count+1) *sizeof(uint),
12212
&bitmaps, bitmap_buffer_size(field_count)*2,
12216
bzero(table, sizeof(*table));
12217
bzero(share, sizeof(*share));
12218
table->field= field;
12220
share->blob_field= blob_field;
12221
share->fields= field_count;
12222
share->blob_ptr_size= portable_sizeof_char_ptr;
12223
setup_tmp_table_column_bitmaps(table, bitmaps);
12225
/* Create all fields and calculate the total length of record */
12226
List_iterator_fast<Create_field> it(field_list);
12227
while ((cdef= it++))
12229
*field= make_field(share, 0, cdef->length,
12230
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
12231
f_maybe_null(cdef->pack_flag) ? 1 : 0,
12232
cdef->pack_flag, cdef->sql_type, cdef->charset,
12233
cdef->unireg_check,
12234
cdef->interval, cdef->field_name);
12237
(*field)->init(table);
12238
record_length+= (*field)->pack_length();
12239
if (! ((*field)->flags & NOT_NULL_FLAG))
12242
if ((*field)->flags & BLOB_FLAG)
12243
share->blob_field[blob_count++]= (uint) (field - table->field);
12247
*field= NULL; /* mark the end of the list */
12248
share->blob_field[blob_count]= 0; /* mark the end of the list */
12249
share->blob_fields= blob_count;
12251
null_pack_length= (null_count + 7)/8;
12252
share->reclength= record_length + null_pack_length;
12253
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
12254
table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
12255
if (!table->record[0])
12258
if (null_pack_length)
12260
table->null_flags= (uchar*) table->record[0];
12261
share->null_fields= null_count;
12262
share->null_bytes= null_pack_length;
12265
table->in_use= thd; /* field->reset() may access table->in_use */
12267
/* Set up field pointers */
12268
uchar *null_pos= table->record[0];
12269
uchar *field_pos= null_pos + share->null_bytes;
12272
for (field= table->field; *field; ++field)
12274
Field *cur_field= *field;
12275
if ((cur_field->flags & NOT_NULL_FLAG))
12276
cur_field->move_field(field_pos);
12279
cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
12281
if (null_bit == (1 << 8))
12287
cur_field->reset();
12289
field_pos+= cur_field->pack_length();
12294
for (field= table->field; *field; ++field)
12295
delete *field; /* just invokes field destructor */
12300
static bool open_tmp_table(TABLE *table)
12303
if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
12304
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
12306
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12310
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
12316
Create MyISAM temporary table
12319
create_myisam_tmp_table()
12320
table Table object that descrimes the table to be created
12321
keyinfo Description of the index (there is always one index)
12322
start_recinfo MyISAM's column descriptions
12323
recinfo INOUT End of MyISAM's column descriptions
12324
options Option bits
12327
Create a MyISAM temporary table according to passed description. The is
12328
assumed to have one unique index or constraint.
12330
The passed array or MI_COLUMNDEF structures must have this form:
12332
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
12333
when there are many nullable columns)
12335
3. One free MI_COLUMNDEF element (*recinfo points here)
12337
This function may use the free element to create hash column for unique
12345
static bool create_myisam_tmp_table(TABLE *table, KEY *keyinfo,
12346
MI_COLUMNDEF *start_recinfo,
12347
MI_COLUMNDEF **recinfo,
12352
MI_UNIQUEDEF uniquedef;
12353
TABLE_SHARE *share= table->s;
12354
DBUG_ENTER("create_myisam_tmp_table");
12357
{ // Get keys for ni_create
12358
bool using_unique_constraint=0;
12359
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
12360
sizeof(*seg) * keyinfo->key_parts);
12364
bzero(seg, sizeof(*seg) * keyinfo->key_parts);
12365
if (keyinfo->key_length >= table->file->max_key_length() ||
12366
keyinfo->key_parts > table->file->max_key_parts() ||
12369
/* Can't create a key; Make a unique constraint instead of a key */
12372
using_unique_constraint=1;
12373
bzero((char*) &uniquedef,sizeof(uniquedef));
12374
uniquedef.keysegs=keyinfo->key_parts;
12376
uniquedef.null_are_equal=1;
12378
/* Create extra column for hash value */
12379
bzero((uchar*) *recinfo,sizeof(**recinfo));
12380
(*recinfo)->type= FIELD_CHECK;
12381
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
12383
share->reclength+=MI_UNIQUE_HASH_LENGTH;
12387
/* Create an unique key */
12388
bzero((char*) &keydef,sizeof(keydef));
12389
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
12390
keydef.keysegs= keyinfo->key_parts;
12393
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
12395
Field *field=keyinfo->key_part[i].field;
12397
seg->language= field->charset()->number;
12398
seg->length= keyinfo->key_part[i].length;
12399
seg->start= keyinfo->key_part[i].offset;
12400
if (field->flags & BLOB_FLAG)
12403
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
12404
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
12405
seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
12406
seg->flag= HA_BLOB_PART;
12407
seg->length=0; // Whole blob in unique constraint
12411
seg->type= keyinfo->key_part[i].type;
12412
/* Tell handler if it can do suffic space compression */
12413
if (field->real_type() == MYSQL_TYPE_STRING &&
12414
keyinfo->key_part[i].length > 4)
12415
seg->flag|= HA_SPACE_PACK;
12417
if (!(field->flags & NOT_NULL_FLAG))
12419
seg->null_bit= field->null_bit;
12420
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
12422
We are using a GROUP BY on something that contains NULL
12423
In this case we have to tell MyISAM that two NULL should
12424
on INSERT be regarded at the same value
12426
if (!using_unique_constraint)
12427
keydef.flag|= HA_NULL_ARE_EQUAL;
12431
MI_CREATE_INFO create_info;
12432
bzero((char*) &create_info,sizeof(create_info));
12434
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
12436
create_info.data_file_length= ~(ulonglong) 0;
12438
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
12439
(uint) (*recinfo-start_recinfo),
12441
share->uniques, &uniquedef,
12443
HA_CREATE_TMP_TABLE)))
12445
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12449
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
12450
share->db_record_offset= 1;
12458
free_tmp_table(THD *thd, TABLE *entry)
12460
MEM_ROOT own_root= entry->mem_root;
12461
const char *save_proc_info;
12462
DBUG_ENTER("free_tmp_table");
12463
DBUG_PRINT("enter",("table: %s",entry->alias));
12465
save_proc_info=thd->proc_info;
12466
thd_proc_info(thd, "removing tmp table");
12470
if (entry->db_stat)
12471
entry->file->ha_drop_table(entry->s->table_name.str);
12473
entry->file->ha_delete_table(entry->s->table_name.str);
12474
delete entry->file;
12478
for (Field **ptr=entry->field ; *ptr ; ptr++)
12480
free_io_cache(entry);
12482
if (entry->temp_pool_slot != MY_BIT_NONE)
12483
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
12485
plugin_unlock(0, entry->s->db_plugin);
12487
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
12488
thd_proc_info(thd, save_proc_info);
12494
If a HEAP table gets full, create a MyISAM table and copy all rows
12498
bool create_myisam_from_heap(THD *thd, TABLE *table,
12499
MI_COLUMNDEF *start_recinfo,
12500
MI_COLUMNDEF **recinfo,
12501
int error, bool ignore_last_dupp_key_error)
12505
const char *save_proc_info;
12507
DBUG_ENTER("create_myisam_from_heap");
12509
if (table->s->db_type() != heap_hton ||
12510
error != HA_ERR_RECORD_FILE_FULL)
12512
table->file->print_error(error,MYF(0));
12517
new_table.s= &share;
12518
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
12519
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
12520
new_table.s->db_type())))
12521
DBUG_RETURN(1); // End of memory
12523
save_proc_info=thd->proc_info;
12524
thd_proc_info(thd, "converting HEAP to MyISAM");
12526
if (create_myisam_tmp_table(&new_table, table->key_info, start_recinfo,
12527
recinfo, thd->lex->select_lex.options |
12530
if (open_tmp_table(&new_table))
12532
if (table->file->indexes_are_disabled())
12533
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
12534
table->file->ha_index_or_rnd_end();
12535
table->file->ha_rnd_init(1);
12536
if (table->no_rows)
12538
new_table.file->extra(HA_EXTRA_NO_ROWS);
12539
new_table.no_rows=1;
12542
#ifdef TO_BE_DONE_LATER_IN_4_1
12544
To use start_bulk_insert() (which is new in 4.1) we need to find
12545
all places where a corresponding end_bulk_insert() should be put.
12547
table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
12548
new_table.file->ha_start_bulk_insert(table->file->stats.records);
12550
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
12551
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
12555
copy all old rows from heap table to MyISAM table
12556
This is the only code that uses record[1] to read/write but this
12557
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
12559
while (!table->file->rnd_next(new_table.record[1]))
12561
write_err= new_table.file->ha_write_row(new_table.record[1]);
12562
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
12566
/* copy row that filled HEAP table */
12567
if ((write_err=new_table.file->ha_write_row(table->record[0])))
12569
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
12570
!ignore_last_dupp_key_error)
12574
/* remove heap table and change to use myisam table */
12575
(void) table->file->ha_rnd_end();
12576
(void) table->file->close(); // This deletes the table !
12577
delete table->file;
12579
plugin_unlock(0, table->s->db_plugin);
12580
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
12581
new_table.s= table->s; // Keep old share
12585
table->file->change_table_ptr(table, table->s);
12586
table->use_all_columns();
12587
if (save_proc_info)
12589
const char *new_proc_info=
12590
(!strcmp(save_proc_info,"Copying to tmp table") ?
12591
"Copying to tmp table on disk" : save_proc_info);
12592
thd_proc_info(thd, new_proc_info);
12597
DBUG_PRINT("error",("Got error: %d",write_err));
12598
table->file->print_error(write_err, MYF(0));
12599
(void) table->file->ha_rnd_end();
12600
(void) new_table.file->close();
12602
new_table.file->ha_delete_table(new_table.s->table_name.str);
12604
delete new_table.file;
12605
thd_proc_info(thd, save_proc_info);
12606
table->mem_root= new_table.mem_root;