10711
/****************************************************************************
10712
Create internal temporary table
10713
****************************************************************************/
10716
Create field for temporary table from given field.
10718
@param thd Thread handler
10719
@param org_field field from which new field will be created
10720
@param name New field name
10721
@param table Temporary table
10722
@param item !=NULL if item->result_field should point to new field.
10723
This is relevant for how fill_record() is going to work:
10724
If item != NULL then fill_record() will update
10725
the record in the original table.
10726
If item == NULL then fill_record() will update
10727
the temporary table
10728
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10729
field instead of blob.
10737
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
10738
const char *name, TABLE *table,
10739
Item_field *item, uint convert_blob_length)
10744
Make sure that the blob fits into a Field_varstring which has
10747
if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
10748
(org_field->flags & BLOB_FLAG))
10749
new_field= new Field_varstring(convert_blob_length,
10750
org_field->maybe_null(),
10751
org_field->field_name, table->s,
10752
org_field->charset());
10754
new_field= org_field->new_field(thd->mem_root, table,
10755
table == org_field->table);
10758
new_field->init(table);
10759
new_field->orig_table= org_field->orig_table;
10761
item->result_field= new_field;
10763
new_field->field_name= name;
10764
new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
10765
if (org_field->maybe_null() || (item && item->maybe_null))
10766
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
10767
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
10768
org_field->type() == MYSQL_TYPE_VARCHAR)
10769
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
10770
else if (org_field->type() == FIELD_TYPE_DOUBLE)
10771
((Field_double *) new_field)->not_fixed= true;
10777
Create field for temporary table using type of given item.
10779
@param thd Thread handler
10780
@param item Item to create a field for
10781
@param table Temporary table
10782
@param copy_func If set and item is a function, store copy of
10784
@param modify_item 1 if item->result_field should point to new
10785
item. This is relevent for how fill_record()
10787
If modify_item is 1 then fill_record() will
10788
update the record in the original table.
10789
If modify_item is 0 then fill_record() will
10790
update the temporary table
10791
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10792
field instead of blob.
10800
static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
10801
Item ***copy_func, bool modify_item,
10802
uint convert_blob_length)
10804
bool maybe_null= item->maybe_null;
10807
switch (item->result_type()) {
10809
new_field= new Field_double(item->max_length, maybe_null,
10810
item->name, item->decimals, true);
10814
Select an integer type with the minimal fit precision.
10815
MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
10816
Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
10817
Field_long : make them Field_longlong.
10819
if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
10820
new_field=new Field_longlong(item->max_length, maybe_null,
10821
item->name, item->unsigned_flag);
10823
new_field=new Field_long(item->max_length, maybe_null,
10824
item->name, item->unsigned_flag);
10826
case STRING_RESULT:
10827
DBUG_ASSERT(item->collation.collation);
10829
enum enum_field_types type;
10831
DATE/TIME fields have STRING_RESULT result type.
10832
To preserve type they needed to be handled separately.
10834
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
10835
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_NEWDATE ||
10836
type == MYSQL_TYPE_TIMESTAMP)
10837
new_field= item->tmp_table_field_from_field_type(table, 1);
10839
Make sure that the blob fits into a Field_varstring which has
10842
else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
10843
convert_blob_length <= Field_varstring::MAX_SIZE &&
10844
convert_blob_length)
10845
new_field= new Field_varstring(convert_blob_length, maybe_null,
10846
item->name, table->s,
10847
item->collation.collation);
10849
new_field= item->make_string_field(table);
10850
new_field->set_derivation(item->collation.derivation);
10852
case DECIMAL_RESULT:
10854
uint8 dec= item->decimals;
10855
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
10856
uint32 len= item->max_length;
10859
Trying to put too many digits overall in a DECIMAL(prec,dec)
10860
will always throw a warning. We must limit dec to
10861
DECIMAL_MAX_SCALE however to prevent an assert() later.
10866
signed int overflow;
10868
dec= min(dec, DECIMAL_MAX_SCALE);
10871
If the value still overflows the field with the corrected dec,
10872
we'll throw out decimals rather than integers. This is still
10873
bad and of course throws a truncation warning.
10874
+1: for decimal point
10877
overflow= my_decimal_precision_to_length(intg + dec, dec,
10878
item->unsigned_flag) - len;
10881
dec= max(0, dec - overflow); // too long, discard fract
10883
len -= item->decimals - dec; // corrected value fits
10886
new_field= new Field_new_decimal(len, maybe_null, item->name,
10887
dec, item->unsigned_flag);
10892
// This case should never be choosen
10898
new_field->init(table);
10900
if (copy_func && item->is_result_field())
10901
*((*copy_func)++) = item; // Save for copy_funcs
10903
item->set_result_field(new_field);
10904
if (item->type() == Item::NULL_ITEM)
10905
new_field->is_created_from_null_item= true;
10911
Create field for information schema table.
10913
@param thd Thread handler
10914
@param table Temporary table
10915
@param item Item to create a field for
10923
Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
10925
if (item->field_type() == MYSQL_TYPE_VARCHAR)
10928
if (item->max_length > MAX_FIELD_VARCHARLENGTH)
10929
field= new Field_blob(item->max_length, item->maybe_null,
10930
item->name, item->collation.collation);
10932
field= new Field_varstring(item->max_length, item->maybe_null,
10934
table->s, item->collation.collation);
10936
field->init(table);
10939
return item->tmp_table_field_from_field_type(table, 0);
10944
Create field for temporary table.
10946
@param thd Thread handler
10947
@param table Temporary table
10948
@param item Item to create a field for
10949
@param type Type of item (normally item->type)
10950
@param copy_func If set and item is a function, store copy of item
10952
@param from_field if field will be created using other field as example,
10953
pointer example field will be written here
10954
@param default_field If field has a default value field, store it here
10955
@param group 1 if we are going to do a relative group by on result
10956
@param modify_item 1 if item->result_field should point to new item.
10957
This is relevent for how fill_record() is going to
10959
If modify_item is 1 then fill_record() will update
10960
the record in the original table.
10961
If modify_item is 0 then fill_record() will update
10962
the temporary table
10963
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10964
field instead of blob.
10972
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
10973
Item ***copy_func, Field **from_field,
10974
Field **default_field,
10975
bool group, bool modify_item,
10976
bool table_cant_handle_bit_fields,
10977
bool make_copy_field,
10978
uint convert_blob_length)
10981
Item::Type orig_type= type;
10982
Item *orig_item= 0;
10984
if (type != Item::FIELD_ITEM &&
10985
item->real_item()->type() == Item::FIELD_ITEM)
10988
item= item->real_item();
10989
type= Item::FIELD_ITEM;
10993
case Item::SUM_FUNC_ITEM:
10995
Item_sum *item_sum=(Item_sum*) item;
10996
result= item_sum->create_tmp_field(group, table, convert_blob_length);
10998
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
11001
case Item::FIELD_ITEM:
11002
case Item::DEFAULT_VALUE_ITEM:
11004
Item_field *field= (Item_field*) item;
11005
bool orig_modify= modify_item;
11006
if (orig_type == Item::REF_ITEM)
11009
If item have to be able to store NULLs but underlaid field can't do it,
11010
create_tmp_field_from_field() can't be used for tmp field creation.
11012
if (field->maybe_null && !field->field->maybe_null())
11014
result= create_tmp_field_from_item(thd, item, table, NULL,
11015
modify_item, convert_blob_length);
11016
*from_field= field->field;
11017
if (result && modify_item)
11018
field->result_field= result;
11021
result= create_tmp_field_from_field(thd, (*from_field= field->field),
11022
orig_item ? orig_item->name :
11025
modify_item ? field :
11027
convert_blob_length);
11028
if (orig_type == Item::REF_ITEM && orig_modify)
11029
((Item_ref*)orig_item)->set_result_field(result);
11030
if (field->field->eq_def(result))
11031
*default_field= field->field;
11035
case Item::FUNC_ITEM:
11037
case Item::COND_ITEM:
11038
case Item::FIELD_AVG_ITEM:
11039
case Item::FIELD_STD_ITEM:
11040
case Item::SUBSELECT_ITEM:
11041
/* The following can only happen with 'CREATE TABLE ... SELECT' */
11042
case Item::PROC_ITEM:
11043
case Item::INT_ITEM:
11044
case Item::REAL_ITEM:
11045
case Item::DECIMAL_ITEM:
11046
case Item::STRING_ITEM:
11047
case Item::REF_ITEM:
11048
case Item::NULL_ITEM:
11049
case Item::VARBIN_ITEM:
11050
if (make_copy_field)
11052
DBUG_ASSERT(((Item_result_field*)item)->result_field);
11053
*from_field= ((Item_result_field*)item)->result_field;
11055
return create_tmp_field_from_item(thd, item, table,
11056
(make_copy_field ? 0 : copy_func),
11057
modify_item, convert_blob_length);
11058
case Item::TYPE_HOLDER:
11059
result= ((Item_type_holder *)item)->make_field_by_type(table);
11060
result->set_derivation(item->collation.derivation);
11062
default: // Dosen't have to be stored
11068
Set up column usage bitmaps for a temporary table
11071
For temporary tables, we need one bitmap with all columns set and
11072
a tmp_set bitmap to be used by things like filesort.
11075
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
11077
uint field_count= table->s->fields;
11078
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
11080
bitmap_init(&table->tmp_set,
11081
(my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
11082
field_count, false);
11083
/* write_set and all_set are copies of read_set */
11084
table->def_write_set= table->def_read_set;
11085
table->s->all_set= table->def_read_set;
11086
bitmap_set_all(&table->s->all_set);
11087
table->default_column_bitmaps();
11092
Create a temp table according to a field list.
11094
Given field pointers are changed to point at tmp_table for
11095
send_fields. The table object is self contained: it's
11096
allocated in its own memory root, as well as Field objects
11097
created for table columns.
11098
This function will replace Item_sum items in 'fields' list with
11099
corresponding Item_field items, pointing at the fields in the
11100
temporary table, unless this was prohibited by true
11101
value of argument save_sum_fields. The Item_field objects
11102
are created in THD memory root.
11104
@param thd thread handle
11105
@param param a description used as input to create the table
11106
@param fields list of items that will be used to define
11107
column types of the table (also see NOTES)
11108
@param group TODO document
11109
@param distinct should table rows be distinct
11110
@param save_sum_fields see NOTES
11111
@param select_options
11113
@param table_alias possible name of the temporary table that can
11114
be used for name resolving; can be "".
11117
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
11118
#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
11119
#define RATIO_TO_PACK_ROWS 2
11120
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
11123
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
11124
ORDER *group, bool distinct, bool save_sum_fields,
11125
ulonglong select_options, ha_rows rows_limit,
11128
MEM_ROOT *mem_root_save, own_root;
11130
TABLE_SHARE *share;
11131
uint i,field_count,null_count,null_pack_length;
11132
uint copy_func_count= param->func_count;
11133
uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
11134
uint blob_count,group_null_items, string_count;
11135
uint temp_pool_slot=MY_BIT_NONE;
11137
ulong reclength, string_total_length;
11138
bool using_unique_constraint= 0;
11139
bool use_packed_rows= 0;
11140
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
11141
char *tmpname,path[FN_REFLEN];
11142
uchar *pos, *group_buff, *bitmaps;
11144
Field **reg_field, **from_field, **default_field;
11146
Copy_field *copy=0;
11148
KEY_PART_INFO *key_part_info;
11150
MI_COLUMNDEF *recinfo;
11151
uint total_uneven_bit_length= 0;
11152
bool force_copy_fields= param->force_copy_fields;
11153
DBUG_ENTER("create_tmp_table");
11154
DBUG_PRINT("enter",
11155
("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d",
11156
(int) distinct, (int) save_sum_fields,
11157
(ulong) rows_limit,test(group)));
11159
status_var_increment(thd->status_var.created_tmp_tables);
11161
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11162
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11164
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11165
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11166
current_pid, temp_pool_slot);
11169
/* if we run out of slots or we are not using tempool */
11170
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11171
thd->thread_id, thd->tmp_table++);
11175
No need to change table name to lower case as we are only creating
11176
MyISAM or HEAP tables here
11178
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11183
if (!param->quick_group)
11184
group=0; // Can't use group key
11185
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
11188
marker == 4 means two things:
11189
- store NULLs in the key, and
11190
- convert BIT fields to 64-bit long, needed because MEMORY tables
11191
can't index BIT fields.
11193
(*tmp->item)->marker= 4;
11194
if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
11195
using_unique_constraint=1;
11197
if (param->group_length >= MAX_BLOB_WIDTH)
11198
using_unique_constraint=1;
11200
distinct=0; // Can't use distinct
11203
field_count=param->field_count+param->func_count+param->sum_func_count;
11204
hidden_field_count=param->hidden_field_count;
11207
When loose index scan is employed as access method, it already
11208
computes all groups and the result of all aggregate functions. We
11209
make space for the items of the aggregate function in the list of
11210
functions TMP_TABLE_PARAM::items_to_copy, so that the values of
11211
these items are stored in the temporary table.
11213
if (param->precomputed_group_by)
11214
copy_func_count+= param->sum_func_count;
11216
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11218
if (!multi_alloc_root(&own_root,
11219
&table, sizeof(*table),
11220
&share, sizeof(*share),
11221
®_field, sizeof(Field*) * (field_count+1),
11222
&default_field, sizeof(Field*) * (field_count),
11223
&blob_field, sizeof(uint)*(field_count+1),
11224
&from_field, sizeof(Field*)*field_count,
11225
©_func, sizeof(*copy_func)*(copy_func_count+1),
11226
¶m->keyinfo, sizeof(*param->keyinfo),
11228
sizeof(*key_part_info)*(param->group_parts+1),
11229
¶m->start_recinfo,
11230
sizeof(*param->recinfo)*(field_count*2+4),
11231
&tmpname, (uint) strlen(path)+1,
11232
&group_buff, (group && ! using_unique_constraint ?
11233
param->group_length : 0),
11234
&bitmaps, bitmap_buffer_size(field_count)*2,
11237
if (temp_pool_slot != MY_BIT_NONE)
11238
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11239
DBUG_RETURN(NULL); /* purecov: inspected */
11241
/* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
11242
if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
11244
if (temp_pool_slot != MY_BIT_NONE)
11245
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11246
free_root(&own_root, MYF(0)); /* purecov: inspected */
11247
DBUG_RETURN(NULL); /* purecov: inspected */
11249
param->items_to_copy= copy_func;
11250
strmov(tmpname,path);
11251
/* make table according to fields */
11253
bzero((char*) table,sizeof(*table));
11254
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
11255
bzero((char*) default_field, sizeof(Field*) * (field_count));
11256
bzero((char*) from_field,sizeof(Field*)*field_count);
11258
table->mem_root= own_root;
11259
mem_root_save= thd->mem_root;
11260
thd->mem_root= &table->mem_root;
11262
table->field=reg_field;
11263
table->alias= table_alias;
11264
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11265
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11267
table->temp_pool_slot = temp_pool_slot;
11268
table->copy_blobs= 1;
11269
table->in_use= thd;
11270
table->quick_keys.init();
11271
table->covering_keys.init();
11272
table->keys_in_use_for_query.init();
11275
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11276
share->blob_field= blob_field;
11277
share->blob_ptr_size= portable_sizeof_char_ptr;
11278
share->db_low_byte_first=1; // True for HEAP and MyISAM
11279
share->table_charset= param->table_charset;
11280
share->primary_key= MAX_KEY; // Indicate no primary key
11281
share->keys_for_keyread.init();
11282
share->keys_in_use.init();
11284
/* Calculate which type of fields we will store in the temporary table */
11286
reclength= string_total_length= 0;
11287
blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
11288
param->using_indirect_summary_function=0;
11290
List_iterator_fast<Item> li(fields);
11292
Field **tmp_from_field=from_field;
11293
while ((item=li++))
11295
Item::Type type=item->type();
11296
if (not_all_columns)
11298
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
11300
if (item->used_tables() & OUTER_REF_TABLE_BIT)
11301
item->update_used_tables();
11302
if (type == Item::SUBSELECT_ITEM ||
11303
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
11306
Mark that the we have ignored an item that refers to a summary
11307
function. We need to know this if someone is going to use
11308
DISTINCT on the result.
11310
param->using_indirect_summary_function=1;
11314
if (item->const_item() && (int) hidden_field_count <= 0)
11315
continue; // We don't have to store this
11317
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
11318
{ /* Can't calc group yet */
11319
((Item_sum*) item)->result_field=0;
11320
for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
11322
Item **argp= ((Item_sum*) item)->args + i;
11324
if (!arg->const_item())
11327
create_tmp_field(thd, table, arg, arg->type(), ©_func,
11328
tmp_from_field, &default_field[fieldnr],
11329
group != 0,not_all_columns,
11331
param->convert_blob_length);
11333
goto err; // Should be OOM
11335
reclength+=new_field->pack_length();
11336
if (new_field->flags & BLOB_FLAG)
11338
*blob_field++= fieldnr;
11341
*(reg_field++)= new_field;
11342
if (new_field->real_type() == MYSQL_TYPE_STRING ||
11343
new_field->real_type() == MYSQL_TYPE_VARCHAR)
11346
string_total_length+= new_field->pack_length();
11348
thd->mem_root= mem_root_save;
11349
thd->change_item_tree(argp, new Item_field(new_field));
11350
thd->mem_root= &table->mem_root;
11351
if (!(new_field->flags & NOT_NULL_FLAG))
11355
new_field->maybe_null() is still false, it will be
11356
changed below. But we have to setup Item_field correctly
11358
(*argp)->maybe_null=1;
11360
new_field->field_index= fieldnr++;
11367
The last parameter to create_tmp_field() is a bit tricky:
11369
We need to set it to 0 in union, to get fill_record() to modify the
11371
We need to set it to 1 on multi-table-update and in select to
11372
write rows to the temporary table.
11373
We here distinguish between UNION and multi-table-updates by the fact
11374
that in the later case group is set to the row pointer.
11376
Field *new_field= (param->schema_table) ?
11377
create_tmp_field_for_schema(thd, item, table) :
11378
create_tmp_field(thd, table, item, type, ©_func,
11379
tmp_from_field, &default_field[fieldnr],
11381
!force_copy_fields &&
11382
(not_all_columns || group !=0),
11384
If item->marker == 4 then we force create_tmp_field
11385
to create a 64-bit longs for BIT fields because HEAP
11386
tables can't index BIT fields directly. We do the same
11387
for distinct, as we want the distinct index to be
11388
usable in this case too.
11390
item->marker == 4 || param->bit_fields_as_long,
11392
param->convert_blob_length);
11396
if (thd->is_fatal_error)
11397
goto err; // Got OOM
11398
continue; // Some kindf of const item
11400
if (type == Item::SUM_FUNC_ITEM)
11401
((Item_sum *) item)->result_field= new_field;
11403
reclength+=new_field->pack_length();
11404
if (!(new_field->flags & NOT_NULL_FLAG))
11406
if (new_field->flags & BLOB_FLAG)
11408
*blob_field++= fieldnr;
11411
if (item->marker == 4 && item->maybe_null)
11413
group_null_items++;
11414
new_field->flags|= GROUP_FLAG;
11416
new_field->field_index= fieldnr++;
11417
*(reg_field++)= new_field;
11419
if (!--hidden_field_count)
11422
This was the last hidden field; Remember how many hidden fields could
11425
hidden_null_count=null_count;
11427
We need to update hidden_field_count as we may have stored group
11428
functions with constant arguments
11430
param->hidden_field_count= fieldnr;
11434
DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
11435
DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
11436
field_count= fieldnr;
11438
*blob_field= 0; // End marker
11439
share->fields= field_count;
11441
/* If result table is small; use a heap */
11442
/* future: storage engine selection can be made dynamic? */
11443
if (blob_count || using_unique_constraint ||
11444
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
11445
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
11447
share->db_plugin= ha_lock_engine(0, myisam_hton);
11448
table->file= get_new_handler(share, &table->mem_root,
11451
(param->group_parts > table->file->max_key_parts() ||
11452
param->group_length > table->file->max_key_length()))
11453
using_unique_constraint=1;
11457
share->db_plugin= ha_lock_engine(0, heap_hton);
11458
table->file= get_new_handler(share, &table->mem_root,
11465
if (!using_unique_constraint)
11466
reclength+= group_null_items; // null flag is stored separately
11468
share->blob_fields= blob_count;
11469
if (blob_count == 0)
11471
/* We need to ensure that first byte is not 0 for the delete link */
11472
if (param->hidden_field_count)
11473
hidden_null_count++;
11477
hidden_null_pack_length=(hidden_null_count+7)/8;
11478
null_pack_length= (hidden_null_pack_length +
11479
(null_count + total_uneven_bit_length + 7) / 8);
11480
reclength+=null_pack_length;
11482
reclength=1; // Dummy select
11483
/* Use packed rows if there is blobs or a lot of space to gain */
11484
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)))
11485
use_packed_rows= 1;
11487
share->reclength= reclength;
11489
uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
11490
share->rec_buff_length= alloc_length;
11491
if (!(table->record[0]= (uchar*)
11492
alloc_root(&table->mem_root, alloc_length*3)))
11494
table->record[1]= table->record[0]+alloc_length;
11495
share->default_values= table->record[1]+alloc_length;
11497
copy_func[0]=0; // End marker
11498
param->func_count= copy_func - param->items_to_copy;
11500
setup_tmp_table_column_bitmaps(table, bitmaps);
11502
recinfo=param->start_recinfo;
11503
null_flags=(uchar*) table->record[0];
11504
pos=table->record[0]+ null_pack_length;
11505
if (null_pack_length)
11507
bzero((uchar*) recinfo,sizeof(*recinfo));
11508
recinfo->type=FIELD_NORMAL;
11509
recinfo->length=null_pack_length;
11511
bfill(null_flags,null_pack_length,255); // Set null fields
11513
table->null_flags= (uchar*) table->record[0];
11514
share->null_fields= null_count+ hidden_null_count;
11515
share->null_bytes= null_pack_length;
11517
null_count= (blob_count == 0) ? 1 : 0;
11518
hidden_field_count=param->hidden_field_count;
11519
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
11521
Field *field= *reg_field;
11523
bzero((uchar*) recinfo,sizeof(*recinfo));
11525
if (!(field->flags & NOT_NULL_FLAG))
11527
if (field->flags & GROUP_FLAG && !using_unique_constraint)
11530
We have to reserve one byte here for NULL bits,
11531
as this is updated by 'end_update()'
11533
*pos++=0; // Null is stored here
11535
recinfo->type=FIELD_NORMAL;
11537
bzero((uchar*) recinfo,sizeof(*recinfo));
11541
recinfo->null_bit= 1 << (null_count & 7);
11542
recinfo->null_pos= null_count/8;
11544
field->move_field(pos,null_flags+null_count/8,
11545
1 << (null_count & 7));
11549
field->move_field(pos,(uchar*) 0,0);
11553
Test if there is a default field value. The test for ->ptr is to skip
11554
'offset' fields generated by initalize_tables
11556
if (default_field[i] && default_field[i]->ptr)
11559
default_field[i] is set only in the cases when 'field' can
11560
inherit the default value that is defined for the field referred
11561
by the Item_field object from which 'field' has been created.
11564
Field *orig_field= default_field[i];
11565
/* Get the value from default_values */
11566
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
11567
orig_field->table->record[0]);
11568
orig_field->move_field_offset(diff); // Points now at default_values
11569
if (orig_field->is_real_null())
11573
field->set_notnull();
11574
memcpy(field->ptr, orig_field->ptr, field->pack_length());
11576
orig_field->move_field_offset(-diff); // Back to record[0]
11580
{ /* Not a table Item */
11581
copy->set(field,from_field[i],save_sum_fields);
11584
length=field->pack_length();
11587
/* Make entry for create table */
11588
recinfo->length=length;
11589
if (field->flags & BLOB_FLAG)
11590
recinfo->type= (int) FIELD_BLOB;
11591
else if (use_packed_rows &&
11592
field->real_type() == MYSQL_TYPE_STRING &&
11593
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
11594
recinfo->type=FIELD_SKIP_ENDSPACE;
11596
recinfo->type=FIELD_NORMAL;
11597
if (!--hidden_field_count)
11598
null_count=(null_count+7) & ~7; // move to next byte
11600
// fix table name in field entry
11601
field->table_name= &table->alias;
11604
param->copy_field_end=copy;
11605
param->recinfo=recinfo;
11606
store_record(table,s->default_values); // Make empty default record
11608
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
11609
share->max_rows= ~(ha_rows) 0;
11611
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11612
min(thd->variables.tmp_table_size,
11613
thd->variables.max_heap_table_size) :
11614
thd->variables.tmp_table_size) /
11616
set_if_bigger(share->max_rows,1); // For dummy start options
11618
Push the LIMIT clause to the temporary table creation, so that we
11619
materialize only up to 'rows_limit' records instead of all result records.
11621
set_if_smaller(share->max_rows, rows_limit);
11622
param->end_write_records= rows_limit;
11624
keyinfo= param->keyinfo;
11628
DBUG_PRINT("info",("Creating group key in temporary table"));
11629
table->group=group; /* Table is grouped by key */
11630
param->group_buff=group_buff;
11632
share->uniques= test(using_unique_constraint);
11633
table->key_info=keyinfo;
11634
keyinfo->key_part=key_part_info;
11635
keyinfo->flags=HA_NOSAME;
11636
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
11637
keyinfo->key_length=0;
11638
keyinfo->rec_per_key=0;
11639
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11640
keyinfo->name= (char*) "group_key";
11641
ORDER *cur_group= group;
11642
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
11644
Field *field=(*cur_group->item)->get_tmp_table_field();
11645
bool maybe_null=(*cur_group->item)->maybe_null;
11646
key_part_info->null_bit=0;
11647
key_part_info->field= field;
11648
key_part_info->offset= field->offset(table->record[0]);
11649
key_part_info->length= (uint16) field->key_length();
11650
key_part_info->type= (uint8) field->key_type();
11651
key_part_info->key_type =
11652
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11653
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11654
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11655
0 : FIELDFLAG_BINARY;
11656
if (!using_unique_constraint)
11658
cur_group->buff=(char*) group_buff;
11659
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
11664
goto err; /* purecov: inspected */
11668
To be able to group on NULL, we reserved place in group_buff
11669
for the NULL flag just before the column. (see above).
11670
The field data is after this flag.
11671
The NULL flag is updated in 'end_update()' and 'end_write()'
11673
keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
11674
key_part_info->null_bit=field->null_bit;
11675
key_part_info->null_offset= (uint) (field->null_ptr -
11676
(uchar*) table->record[0]);
11677
cur_group->buff++; // Pointer to field data
11678
group_buff++; // Skipp null flag
11680
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
11681
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
11682
group_buff+= cur_group->field->pack_length();
11684
keyinfo->key_length+= key_part_info->length;
11688
if (distinct && field_count != param->hidden_field_count)
11691
Create an unique key or an unique constraint over all columns
11692
that should be in the result. In the temporary table, there are
11693
'param->hidden_field_count' extra columns, whose null bits are stored
11694
in the first 'hidden_null_pack_length' bytes of the row.
11696
DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
11701
Special mode for index creation in MyISAM used to support unique
11702
indexes on blobs with arbitrary length. Such indexes cannot be
11707
null_pack_length-=hidden_null_pack_length;
11708
keyinfo->key_parts= ((field_count-param->hidden_field_count)+
11709
(share->uniques ? test(null_pack_length) : 0));
11710
table->distinct= 1;
11712
if (!(key_part_info= (KEY_PART_INFO*)
11713
alloc_root(&table->mem_root,
11714
keyinfo->key_parts * sizeof(KEY_PART_INFO))))
11716
bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
11717
table->key_info=keyinfo;
11718
keyinfo->key_part=key_part_info;
11719
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
11720
keyinfo->key_length=(uint16) reclength;
11721
keyinfo->name= (char*) "distinct_key";
11722
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11723
keyinfo->rec_per_key=0;
11726
Create an extra field to hold NULL bits so that unique indexes on
11727
blobs can distinguish NULL from 0. This extra field is not needed
11728
when we do not use UNIQUE indexes for blobs.
11730
if (null_pack_length && share->uniques)
11732
key_part_info->null_bit=0;
11733
key_part_info->offset=hidden_null_pack_length;
11734
key_part_info->length=null_pack_length;
11735
key_part_info->field= new Field_string(table->record[0],
11736
(uint32) key_part_info->length,
11740
NullS, &my_charset_bin);
11741
if (!key_part_info->field)
11743
key_part_info->field->init(table);
11744
key_part_info->key_type=FIELDFLAG_BINARY;
11745
key_part_info->type= HA_KEYTYPE_BINARY;
11748
/* Create a distinct key over the columns we are going to return */
11749
for (i=param->hidden_field_count, reg_field=table->field + i ;
11751
i++, reg_field++, key_part_info++)
11753
key_part_info->null_bit=0;
11754
key_part_info->field= *reg_field;
11755
key_part_info->offset= (*reg_field)->offset(table->record[0]);
11756
key_part_info->length= (uint16) (*reg_field)->pack_length();
11758
The below method of computing the key format length of the
11759
key part is a copy/paste from opt_range.cc, and table.cc.
11760
This should be factored out, e.g. as a method of Field.
11761
In addition it is not clear if any of the Field::*_length
11762
methods is supposed to compute the same length. If so, it
11765
key_part_info->store_length= key_part_info->length;
11767
if ((*reg_field)->real_maybe_null())
11768
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
11769
if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
11770
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
11771
key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
11773
key_part_info->type= (uint8) (*reg_field)->key_type();
11774
key_part_info->key_type =
11775
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11776
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11777
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11778
0 : FIELDFLAG_BINARY;
11782
if (thd->is_fatal_error) // If end of memory
11783
goto err; /* purecov: inspected */
11784
share->db_record_offset= 1;
11785
if (share->db_type() == myisam_hton)
11787
if (create_myisam_tmp_table(table, param->keyinfo, param->start_recinfo,
11788
¶m->recinfo, select_options))
11791
if (open_tmp_table(table))
11794
thd->mem_root= mem_root_save;
11796
DBUG_RETURN(table);
11799
thd->mem_root= mem_root_save;
11800
free_tmp_table(thd,table); /* purecov: inspected */
11801
if (temp_pool_slot != MY_BIT_NONE)
11802
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11803
DBUG_RETURN(NULL); /* purecov: inspected */
11810
Create a temporary table to weed out duplicate rowid combinations
11814
create_duplicate_weedout_tmp_table()
11816
uniq_tuple_length_arg
11820
Create a temporary table to weed out duplicate rowid combinations. The
11821
table has a single column that is a concatenation of all rowids in the
11824
Depending on the needed length, there are two cases:
11826
1. When the length of the column < max_key_length:
11828
CREATE TABLE tmp (col VARBINARY(n) NOT NULL, UNIQUE KEY(col));
11830
2. Otherwise (not a valid SQL syntax but internally supported):
11832
CREATE TABLE tmp (col VARBINARY NOT NULL, UNIQUE CONSTRAINT(col));
11834
The code in this function was produced by extraction of relevant parts
11835
from create_tmp_table().
11842
TABLE *create_duplicate_weedout_tmp_table(THD *thd,
11843
uint uniq_tuple_length_arg,
11844
SJ_TMP_TABLE *sjtbl)
11846
MEM_ROOT *mem_root_save, own_root;
11848
TABLE_SHARE *share;
11849
uint temp_pool_slot=MY_BIT_NONE;
11850
char *tmpname,path[FN_REFLEN];
11852
KEY_PART_INFO *key_part_info;
11857
MI_COLUMNDEF *recinfo, *start_recinfo;
11858
bool using_unique_constraint=false;
11859
bool use_packed_rows= false;
11860
Field *field, *key_field;
11861
uint blob_count, null_pack_length, null_count;
11864
DBUG_ENTER("create_duplicate_weedout_tmp_table");
11867
STEP 1: Get temporary table name
11869
statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
11870
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11871
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11873
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11874
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11875
current_pid, temp_pool_slot);
11878
/* if we run out of slots or we are not using tempool */
11879
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11880
thd->thread_id, thd->tmp_table++);
11882
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11884
/* STEP 2: Figure if we'll be using a key or blob+constraint */
11885
if (uniq_tuple_length_arg >= CONVERT_IF_BIGGER_TO_BLOB)
11886
using_unique_constraint= true;
11888
/* STEP 3: Allocate memory for temptable description */
11889
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11890
if (!multi_alloc_root(&own_root,
11891
&table, sizeof(*table),
11892
&share, sizeof(*share),
11893
®_field, sizeof(Field*) * (1+1),
11894
&blob_field, sizeof(uint)*2,
11895
&keyinfo, sizeof(*keyinfo),
11896
&key_part_info, sizeof(*key_part_info) * 2,
11898
sizeof(*recinfo)*(1*2+4),
11899
&tmpname, (uint) strlen(path)+1,
11900
&group_buff, (!using_unique_constraint ?
11901
uniq_tuple_length_arg : 0),
11902
&bitmaps, bitmap_buffer_size(1)*2,
11905
if (temp_pool_slot != MY_BIT_NONE)
11906
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11909
strmov(tmpname,path);
11912
/* STEP 4: Create TABLE description */
11913
bzero((char*) table,sizeof(*table));
11914
bzero((char*) reg_field,sizeof(Field*)*2);
11916
table->mem_root= own_root;
11917
mem_root_save= thd->mem_root;
11918
thd->mem_root= &table->mem_root;
11920
table->field=reg_field;
11921
table->alias= "weedout-tmp";
11922
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11923
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11925
table->temp_pool_slot = temp_pool_slot;
11926
table->copy_blobs= 1;
11927
table->in_use= thd;
11928
table->quick_keys.init();
11929
table->covering_keys.init();
11930
table->keys_in_use_for_query.init();
11933
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11934
share->blob_field= blob_field;
11935
share->blob_ptr_size= portable_sizeof_char_ptr;
11936
share->db_low_byte_first=1; // True for HEAP and MyISAM
11937
share->table_charset= NULL;
11938
share->primary_key= MAX_KEY; // Indicate no primary key
11939
share->keys_for_keyread.init();
11940
share->keys_in_use.init();
11944
/* Create the field */
11947
For the sake of uniformity, always use Field_varstring (altough we could
11948
use Field_string for shorter keys)
11950
field= new Field_varstring(uniq_tuple_length_arg, false, "rowids", share,
11954
field->table= table;
11955
field->key_start.init(0);
11956
field->part_of_key.init(0);
11957
field->part_of_sortkey.init(0);
11958
field->unireg_check= Field::NONE;
11959
field->flags= (NOT_NULL_FLAG | BINARY_FLAG | NO_DEFAULT_VALUE_FLAG);
11960
field->reset_fields();
11961
field->init(table);
11962
field->orig_table= NULL;
11964
field->field_index= 0;
11966
*(reg_field++)= field;
11971
share->blob_fields= 0;
11974
uint reclength= field->pack_length();
11975
if (using_unique_constraint)
11977
share->db_plugin= ha_lock_engine(0, myisam_hton);
11978
table->file= get_new_handler(share, &table->mem_root,
11980
DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length());
11984
share->db_plugin= ha_lock_engine(0, heap_hton);
11985
table->file= get_new_handler(share, &table->mem_root,
11993
null_pack_length= 1;
11994
reclength += null_pack_length;
11996
share->reclength= reclength;
11998
uint alloc_length=ALIGN_SIZE(share->reclength + MI_UNIQUE_HASH_LENGTH+1);
11999
share->rec_buff_length= alloc_length;
12000
if (!(table->record[0]= (uchar*)
12001
alloc_root(&table->mem_root, alloc_length*3)))
12003
table->record[1]= table->record[0]+alloc_length;
12004
share->default_values= table->record[1]+alloc_length;
12006
setup_tmp_table_column_bitmaps(table, bitmaps);
12008
recinfo= start_recinfo;
12009
null_flags=(uchar*) table->record[0];
12010
pos=table->record[0]+ null_pack_length;
12011
if (null_pack_length)
12013
bzero((uchar*) recinfo,sizeof(*recinfo));
12014
recinfo->type=FIELD_NORMAL;
12015
recinfo->length=null_pack_length;
12017
bfill(null_flags,null_pack_length,255); // Set null fields
12019
table->null_flags= (uchar*) table->record[0];
12020
share->null_fields= null_count;
12021
share->null_bytes= null_pack_length;
12026
//Field *field= *reg_field;
12028
bzero((uchar*) recinfo,sizeof(*recinfo));
12029
field->move_field(pos,(uchar*) 0,0);
12033
Test if there is a default field value. The test for ->ptr is to skip
12034
'offset' fields generated by initalize_tables
12036
// Initialize the table field:
12037
bzero(field->ptr, field->pack_length());
12039
length=field->pack_length();
12042
/* Make entry for create table */
12043
recinfo->length=length;
12044
if (field->flags & BLOB_FLAG)
12045
recinfo->type= (int) FIELD_BLOB;
12046
else if (use_packed_rows &&
12047
field->real_type() == MYSQL_TYPE_STRING &&
12048
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
12049
recinfo->type=FIELD_SKIP_ENDSPACE;
12051
recinfo->type=FIELD_NORMAL;
12053
field->table_name= &table->alias;
12056
//param->recinfo=recinfo;
12057
//store_record(table,s->default_values); // Make empty default record
12059
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
12060
share->max_rows= ~(ha_rows) 0;
12062
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
12063
min(thd->variables.tmp_table_size,
12064
thd->variables.max_heap_table_size) :
12065
thd->variables.tmp_table_size) /
12067
set_if_bigger(share->max_rows,1); // For dummy start options
12070
//// keyinfo= param->keyinfo;
12073
DBUG_PRINT("info",("Creating group key in temporary table"));
12075
share->uniques= test(using_unique_constraint);
12076
table->key_info=keyinfo;
12077
keyinfo->key_part=key_part_info;
12078
keyinfo->flags=HA_NOSAME;
12079
keyinfo->usable_key_parts= keyinfo->key_parts= 1;
12080
keyinfo->key_length=0;
12081
keyinfo->rec_per_key=0;
12082
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
12083
keyinfo->name= (char*) "weedout_key";
12085
key_part_info->null_bit=0;
12086
key_part_info->field= field;
12087
key_part_info->offset= field->offset(table->record[0]);
12088
key_part_info->length= (uint16) field->key_length();
12089
key_part_info->type= (uint8) field->key_type();
12090
key_part_info->key_type = FIELDFLAG_BINARY;
12091
if (!using_unique_constraint)
12093
if (!(key_field= field->new_key_field(thd->mem_root, table,
12098
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this?
12100
keyinfo->key_length+= key_part_info->length;
12104
if (thd->is_fatal_error) // If end of memory
12106
share->db_record_offset= 1;
12107
if (share->db_type() == myisam_hton)
12110
if (create_myisam_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
12113
sjtbl->start_recinfo= start_recinfo;
12114
sjtbl->recinfo= recinfo;
12115
if (open_tmp_table(table))
12118
thd->mem_root= mem_root_save;
12119
DBUG_RETURN(table);
12122
thd->mem_root= mem_root_save;
12123
free_tmp_table(thd,table); /* purecov: inspected */
12124
if (temp_pool_slot != MY_BIT_NONE)
12125
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
12126
DBUG_RETURN(NULL); /* purecov: inspected */
12129
/****************************************************************************/
12132
Create a reduced TABLE object with properly set up Field list from a
12133
list of field definitions.
12135
The created table doesn't have a table handler associated with
12136
it, has no keys, no group/distinct, no copy_funcs array.
12137
The sole purpose of this TABLE object is to use the power of Field
12138
class to read/write data to/from table->record[0]. Then one can store
12139
the record in any container (RB tree, hash, etc).
12140
The table is created in THD mem_root, so are the table's fields.
12141
Consequently, if you don't BLOB fields, you don't need to free it.
12143
@param thd connection handle
12144
@param field_list list of column definitions
12147
0 if out of memory, TABLE object in case of success
12150
TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
12152
uint field_count= field_list.elements;
12153
uint blob_count= 0;
12155
Create_field *cdef; /* column definition */
12156
uint record_length= 0;
12157
uint null_count= 0; /* number of columns which may be null */
12158
uint null_pack_length; /* NULL representation array length */
12162
TABLE_SHARE *share;
12164
if (!multi_alloc_root(thd->mem_root,
12165
&table, sizeof(*table),
12166
&share, sizeof(*share),
12167
&field, (field_count + 1) * sizeof(Field*),
12168
&blob_field, (field_count+1) *sizeof(uint),
12169
&bitmaps, bitmap_buffer_size(field_count)*2,
12173
bzero(table, sizeof(*table));
12174
bzero(share, sizeof(*share));
12175
table->field= field;
12177
share->blob_field= blob_field;
12178
share->fields= field_count;
12179
share->blob_ptr_size= portable_sizeof_char_ptr;
12180
setup_tmp_table_column_bitmaps(table, bitmaps);
12182
/* Create all fields and calculate the total length of record */
12183
List_iterator_fast<Create_field> it(field_list);
12184
while ((cdef= it++))
12186
*field= make_field(share, 0, cdef->length,
12187
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
12188
f_maybe_null(cdef->pack_flag) ? 1 : 0,
12189
cdef->pack_flag, cdef->sql_type, cdef->charset,
12190
cdef->unireg_check,
12191
cdef->interval, cdef->field_name);
12194
(*field)->init(table);
12195
record_length+= (*field)->pack_length();
12196
if (! ((*field)->flags & NOT_NULL_FLAG))
12199
if ((*field)->flags & BLOB_FLAG)
12200
share->blob_field[blob_count++]= (uint) (field - table->field);
12204
*field= NULL; /* mark the end of the list */
12205
share->blob_field[blob_count]= 0; /* mark the end of the list */
12206
share->blob_fields= blob_count;
12208
null_pack_length= (null_count + 7)/8;
12209
share->reclength= record_length + null_pack_length;
12210
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
12211
table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
12212
if (!table->record[0])
12215
if (null_pack_length)
12217
table->null_flags= (uchar*) table->record[0];
12218
share->null_fields= null_count;
12219
share->null_bytes= null_pack_length;
12222
table->in_use= thd; /* field->reset() may access table->in_use */
12224
/* Set up field pointers */
12225
uchar *null_pos= table->record[0];
12226
uchar *field_pos= null_pos + share->null_bytes;
12229
for (field= table->field; *field; ++field)
12231
Field *cur_field= *field;
12232
if ((cur_field->flags & NOT_NULL_FLAG))
12233
cur_field->move_field(field_pos);
12236
cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
12238
if (null_bit == (1 << 8))
12244
cur_field->reset();
12246
field_pos+= cur_field->pack_length();
12251
for (field= table->field; *field; ++field)
12252
delete *field; /* just invokes field destructor */
12257
static bool open_tmp_table(TABLE *table)
12260
if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
12261
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
12263
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12267
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
12273
Create MyISAM temporary table
12276
create_myisam_tmp_table()
12277
table Table object that descrimes the table to be created
12278
keyinfo Description of the index (there is always one index)
12279
start_recinfo MyISAM's column descriptions
12280
recinfo INOUT End of MyISAM's column descriptions
12281
options Option bits
12284
Create a MyISAM temporary table according to passed description. The is
12285
assumed to have one unique index or constraint.
12287
The passed array or MI_COLUMNDEF structures must have this form:
12289
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
12290
when there are many nullable columns)
12292
3. One free MI_COLUMNDEF element (*recinfo points here)
12294
This function may use the free element to create hash column for unique
12302
static bool create_myisam_tmp_table(TABLE *table, KEY *keyinfo,
12303
MI_COLUMNDEF *start_recinfo,
12304
MI_COLUMNDEF **recinfo,
12309
MI_UNIQUEDEF uniquedef;
12310
TABLE_SHARE *share= table->s;
12311
DBUG_ENTER("create_myisam_tmp_table");
12314
{ // Get keys for ni_create
12315
bool using_unique_constraint=0;
12316
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
12317
sizeof(*seg) * keyinfo->key_parts);
12321
bzero(seg, sizeof(*seg) * keyinfo->key_parts);
12322
if (keyinfo->key_length >= table->file->max_key_length() ||
12323
keyinfo->key_parts > table->file->max_key_parts() ||
12326
/* Can't create a key; Make a unique constraint instead of a key */
12329
using_unique_constraint=1;
12330
bzero((char*) &uniquedef,sizeof(uniquedef));
12331
uniquedef.keysegs=keyinfo->key_parts;
12333
uniquedef.null_are_equal=1;
12335
/* Create extra column for hash value */
12336
bzero((uchar*) *recinfo,sizeof(**recinfo));
12337
(*recinfo)->type= FIELD_CHECK;
12338
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
12340
share->reclength+=MI_UNIQUE_HASH_LENGTH;
12344
/* Create an unique key */
12345
bzero((char*) &keydef,sizeof(keydef));
12346
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
12347
keydef.keysegs= keyinfo->key_parts;
12350
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
12352
Field *field=keyinfo->key_part[i].field;
12354
seg->language= field->charset()->number;
12355
seg->length= keyinfo->key_part[i].length;
12356
seg->start= keyinfo->key_part[i].offset;
12357
if (field->flags & BLOB_FLAG)
12360
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
12361
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
12362
seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
12363
seg->flag= HA_BLOB_PART;
12364
seg->length=0; // Whole blob in unique constraint
12368
seg->type= keyinfo->key_part[i].type;
12369
/* Tell handler if it can do suffic space compression */
12370
if (field->real_type() == MYSQL_TYPE_STRING &&
12371
keyinfo->key_part[i].length > 4)
12372
seg->flag|= HA_SPACE_PACK;
12374
if (!(field->flags & NOT_NULL_FLAG))
12376
seg->null_bit= field->null_bit;
12377
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
12379
We are using a GROUP BY on something that contains NULL
12380
In this case we have to tell MyISAM that two NULL should
12381
on INSERT be regarded at the same value
12383
if (!using_unique_constraint)
12384
keydef.flag|= HA_NULL_ARE_EQUAL;
12388
MI_CREATE_INFO create_info;
12389
bzero((char*) &create_info,sizeof(create_info));
12391
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
12393
create_info.data_file_length= ~(ulonglong) 0;
12395
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
12396
(uint) (*recinfo-start_recinfo),
12398
share->uniques, &uniquedef,
12400
HA_CREATE_TMP_TABLE)))
12402
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12406
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
12407
share->db_record_offset= 1;
12415
free_tmp_table(THD *thd, TABLE *entry)
12417
MEM_ROOT own_root= entry->mem_root;
12418
const char *save_proc_info;
12419
DBUG_ENTER("free_tmp_table");
12420
DBUG_PRINT("enter",("table: %s",entry->alias));
12422
save_proc_info=thd->proc_info;
12423
thd_proc_info(thd, "removing tmp table");
12427
if (entry->db_stat)
12428
entry->file->ha_drop_table(entry->s->table_name.str);
12430
entry->file->ha_delete_table(entry->s->table_name.str);
12431
delete entry->file;
12435
for (Field **ptr=entry->field ; *ptr ; ptr++)
12437
free_io_cache(entry);
12439
if (entry->temp_pool_slot != MY_BIT_NONE)
12440
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
12442
plugin_unlock(0, entry->s->db_plugin);
12444
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
12445
thd_proc_info(thd, save_proc_info);
12451
If a HEAP table gets full, create a MyISAM table and copy all rows
12455
bool create_myisam_from_heap(THD *thd, TABLE *table,
12456
MI_COLUMNDEF *start_recinfo,
12457
MI_COLUMNDEF **recinfo,
12458
int error, bool ignore_last_dupp_key_error)
12462
const char *save_proc_info;
12464
DBUG_ENTER("create_myisam_from_heap");
12466
if (table->s->db_type() != heap_hton ||
12467
error != HA_ERR_RECORD_FILE_FULL)
12469
table->file->print_error(error,MYF(0));
12474
new_table.s= &share;
12475
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
12476
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
12477
new_table.s->db_type())))
12478
DBUG_RETURN(1); // End of memory
12480
save_proc_info=thd->proc_info;
12481
thd_proc_info(thd, "converting HEAP to MyISAM");
12483
if (create_myisam_tmp_table(&new_table, table->key_info, start_recinfo,
12484
recinfo, thd->lex->select_lex.options |
12487
if (open_tmp_table(&new_table))
12489
if (table->file->indexes_are_disabled())
12490
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
12491
table->file->ha_index_or_rnd_end();
12492
table->file->ha_rnd_init(1);
12493
if (table->no_rows)
12495
new_table.file->extra(HA_EXTRA_NO_ROWS);
12496
new_table.no_rows=1;
12499
#ifdef TO_BE_DONE_LATER_IN_4_1
12501
To use start_bulk_insert() (which is new in 4.1) we need to find
12502
all places where a corresponding end_bulk_insert() should be put.
12504
table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
12505
new_table.file->ha_start_bulk_insert(table->file->stats.records);
12507
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
12508
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
12512
copy all old rows from heap table to MyISAM table
12513
This is the only code that uses record[1] to read/write but this
12514
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
12516
while (!table->file->rnd_next(new_table.record[1]))
12518
write_err= new_table.file->ha_write_row(new_table.record[1]);
12519
DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
12523
/* copy row that filled HEAP table */
12524
if ((write_err=new_table.file->ha_write_row(table->record[0])))
12526
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
12527
!ignore_last_dupp_key_error)
12531
/* remove heap table and change to use myisam table */
12532
(void) table->file->ha_rnd_end();
12533
(void) table->file->close(); // This deletes the table !
12534
delete table->file;
12536
plugin_unlock(0, table->s->db_plugin);
12537
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
12538
new_table.s= table->s; // Keep old share
12542
table->file->change_table_ptr(table, table->s);
12543
table->use_all_columns();
12544
if (save_proc_info)
12546
const char *new_proc_info=
12547
(!strcmp(save_proc_info,"Copying to tmp table") ?
12548
"Copying to tmp table on disk" : save_proc_info);
12549
thd_proc_info(thd, new_proc_info);
12554
DBUG_PRINT("error",("Got error: %d",write_err));
12555
table->file->print_error(write_err, MYF(0));
12556
(void) table->file->ha_rnd_end();
12557
(void) new_table.file->close();
12559
new_table.file->ha_delete_table(new_table.s->table_name.str);
12561
delete new_table.file;
12562
thd_proc_info(thd, save_proc_info);
12563
table->mem_root= new_table.mem_root;