10541
/****************************************************************************
10542
Create internal temporary table
10543
****************************************************************************/
10546
Create field for temporary table from given field.
10548
@param thd Thread handler
10549
@param org_field field from which new field will be created
10550
@param name New field name
10551
@param table Temporary table
10552
@param item !=NULL if item->result_field should point to new field.
10553
This is relevant for how fill_record() is going to work:
10554
If item != NULL then fill_record() will update
10555
the record in the original table.
10556
If item == NULL then fill_record() will update
10557
the temporary table
10558
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10559
field instead of blob.
10567
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
10568
const char *name, TABLE *table,
10569
Item_field *item, uint convert_blob_length)
10574
Make sure that the blob fits into a Field_varstring which has
10577
if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
10578
(org_field->flags & BLOB_FLAG))
10579
new_field= new Field_varstring(convert_blob_length,
10580
org_field->maybe_null(),
10581
org_field->field_name, table->s,
10582
org_field->charset());
10584
new_field= org_field->new_field(thd->mem_root, table,
10585
table == org_field->table);
10588
new_field->init(table);
10589
new_field->orig_table= org_field->orig_table;
10591
item->result_field= new_field;
10593
new_field->field_name= name;
10594
new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
10595
if (org_field->maybe_null() || (item && item->maybe_null))
10596
new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
10597
if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
10598
org_field->type() == MYSQL_TYPE_VARCHAR)
10599
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
10600
else if (org_field->type() == FIELD_TYPE_DOUBLE)
10601
((Field_double *) new_field)->not_fixed= true;
10607
Create field for temporary table using type of given item.
10609
@param thd Thread handler
10610
@param item Item to create a field for
10611
@param table Temporary table
10612
@param copy_func If set and item is a function, store copy of
10614
@param modify_item 1 if item->result_field should point to new
10615
item. This is relevent for how fill_record()
10617
If modify_item is 1 then fill_record() will
10618
update the record in the original table.
10619
If modify_item is 0 then fill_record() will
10620
update the temporary table
10621
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10622
field instead of blob.
10630
static Field *create_tmp_field_from_item(THD *thd __attribute__((__unused__)),
10631
Item *item, TABLE *table,
10632
Item ***copy_func, bool modify_item,
10633
uint convert_blob_length)
10635
bool maybe_null= item->maybe_null;
10638
switch (item->result_type()) {
10640
new_field= new Field_double(item->max_length, maybe_null,
10641
item->name, item->decimals, true);
10645
Select an integer type with the minimal fit precision.
10646
MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
10647
Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
10648
Field_long : make them Field_longlong.
10650
if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
10651
new_field=new Field_longlong(item->max_length, maybe_null,
10652
item->name, item->unsigned_flag);
10654
new_field=new Field_long(item->max_length, maybe_null,
10655
item->name, item->unsigned_flag);
10657
case STRING_RESULT:
10658
assert(item->collation.collation);
10660
enum enum_field_types type;
10662
DATE/TIME fields have STRING_RESULT result type.
10663
To preserve type they needed to be handled separately.
10665
if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
10666
type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_NEWDATE ||
10667
type == MYSQL_TYPE_TIMESTAMP)
10668
new_field= item->tmp_table_field_from_field_type(table, 1);
10670
Make sure that the blob fits into a Field_varstring which has
10673
else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
10674
convert_blob_length <= Field_varstring::MAX_SIZE &&
10675
convert_blob_length)
10676
new_field= new Field_varstring(convert_blob_length, maybe_null,
10677
item->name, table->s,
10678
item->collation.collation);
10680
new_field= item->make_string_field(table);
10681
new_field->set_derivation(item->collation.derivation);
10683
case DECIMAL_RESULT:
10685
uint8 dec= item->decimals;
10686
uint8 intg= ((Item_decimal *) item)->decimal_precision() - dec;
10687
uint32 len= item->max_length;
10690
Trying to put too many digits overall in a DECIMAL(prec,dec)
10691
will always throw a warning. We must limit dec to
10692
DECIMAL_MAX_SCALE however to prevent an assert() later.
10697
signed int overflow;
10699
dec= min(dec, DECIMAL_MAX_SCALE);
10702
If the value still overflows the field with the corrected dec,
10703
we'll throw out decimals rather than integers. This is still
10704
bad and of course throws a truncation warning.
10705
+1: for decimal point
10708
overflow= my_decimal_precision_to_length(intg + dec, dec,
10709
item->unsigned_flag) - len;
10712
dec= max(0, dec - overflow); // too long, discard fract
10714
len -= item->decimals - dec; // corrected value fits
10717
new_field= new Field_new_decimal(len, maybe_null, item->name,
10718
dec, item->unsigned_flag);
10723
// This case should never be choosen
10729
new_field->init(table);
10731
if (copy_func && item->is_result_field())
10732
*((*copy_func)++) = item; // Save for copy_funcs
10734
item->set_result_field(new_field);
10735
if (item->type() == Item::NULL_ITEM)
10736
new_field->is_created_from_null_item= true;
10742
Create field for information schema table.
10744
@param thd Thread handler
10745
@param table Temporary table
10746
@param item Item to create a field for
10754
Field *create_tmp_field_for_schema(THD *thd __attribute__((__unused__)),
10755
Item *item, TABLE *table)
10757
if (item->field_type() == MYSQL_TYPE_VARCHAR)
10760
if (item->max_length > MAX_FIELD_VARCHARLENGTH)
10761
field= new Field_blob(item->max_length, item->maybe_null,
10762
item->name, item->collation.collation);
10764
field= new Field_varstring(item->max_length, item->maybe_null,
10766
table->s, item->collation.collation);
10768
field->init(table);
10771
return item->tmp_table_field_from_field_type(table, 0);
10776
Create field for temporary table.
10778
@param thd Thread handler
10779
@param table Temporary table
10780
@param item Item to create a field for
10781
@param type Type of item (normally item->type)
10782
@param copy_func If set and item is a function, store copy of item
10784
@param from_field if field will be created using other field as example,
10785
pointer example field will be written here
10786
@param default_field If field has a default value field, store it here
10787
@param group 1 if we are going to do a relative group by on result
10788
@param modify_item 1 if item->result_field should point to new item.
10789
This is relevent for how fill_record() is going to
10791
If modify_item is 1 then fill_record() will update
10792
the record in the original table.
10793
If modify_item is 0 then fill_record() will update
10794
the temporary table
10795
@param convert_blob_length If >0 create a varstring(convert_blob_length)
10796
field instead of blob.
10804
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
10805
Item ***copy_func, Field **from_field,
10806
Field **default_field,
10807
bool group, bool modify_item,
10808
bool table_cant_handle_bit_fields __attribute__((__unused__)),
10809
bool make_copy_field,
10810
uint convert_blob_length)
10813
Item::Type orig_type= type;
10814
Item *orig_item= 0;
10816
if (type != Item::FIELD_ITEM &&
10817
item->real_item()->type() == Item::FIELD_ITEM)
10820
item= item->real_item();
10821
type= Item::FIELD_ITEM;
10825
case Item::SUM_FUNC_ITEM:
10827
Item_sum *item_sum=(Item_sum*) item;
10828
result= item_sum->create_tmp_field(group, table, convert_blob_length);
10830
my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
10833
case Item::FIELD_ITEM:
10834
case Item::DEFAULT_VALUE_ITEM:
10836
Item_field *field= (Item_field*) item;
10837
bool orig_modify= modify_item;
10838
if (orig_type == Item::REF_ITEM)
10841
If item have to be able to store NULLs but underlaid field can't do it,
10842
create_tmp_field_from_field() can't be used for tmp field creation.
10844
if (field->maybe_null && !field->field->maybe_null())
10846
result= create_tmp_field_from_item(thd, item, table, NULL,
10847
modify_item, convert_blob_length);
10848
*from_field= field->field;
10849
if (result && modify_item)
10850
field->result_field= result;
10853
result= create_tmp_field_from_field(thd, (*from_field= field->field),
10854
orig_item ? orig_item->name :
10857
modify_item ? field :
10859
convert_blob_length);
10860
if (orig_type == Item::REF_ITEM && orig_modify)
10861
((Item_ref*)orig_item)->set_result_field(result);
10862
if (field->field->eq_def(result))
10863
*default_field= field->field;
10867
case Item::FUNC_ITEM:
10869
case Item::COND_ITEM:
10870
case Item::FIELD_AVG_ITEM:
10871
case Item::FIELD_STD_ITEM:
10872
case Item::SUBSELECT_ITEM:
10873
/* The following can only happen with 'CREATE TABLE ... SELECT' */
10874
case Item::PROC_ITEM:
10875
case Item::INT_ITEM:
10876
case Item::REAL_ITEM:
10877
case Item::DECIMAL_ITEM:
10878
case Item::STRING_ITEM:
10879
case Item::REF_ITEM:
10880
case Item::NULL_ITEM:
10881
case Item::VARBIN_ITEM:
10882
if (make_copy_field)
10884
assert(((Item_result_field*)item)->result_field);
10885
*from_field= ((Item_result_field*)item)->result_field;
10887
return create_tmp_field_from_item(thd, item, table,
10888
(make_copy_field ? 0 : copy_func),
10889
modify_item, convert_blob_length);
10890
case Item::TYPE_HOLDER:
10891
result= ((Item_type_holder *)item)->make_field_by_type(table);
10892
result->set_derivation(item->collation.derivation);
10894
default: // Dosen't have to be stored
10900
Set up column usage bitmaps for a temporary table
10903
For temporary tables, we need one bitmap with all columns set and
10904
a tmp_set bitmap to be used by things like filesort.
10907
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
10909
uint field_count= table->s->fields;
10910
bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
10912
bitmap_init(&table->tmp_set,
10913
(my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
10914
field_count, false);
10915
/* write_set and all_set are copies of read_set */
10916
table->def_write_set= table->def_read_set;
10917
table->s->all_set= table->def_read_set;
10918
bitmap_set_all(&table->s->all_set);
10919
table->default_column_bitmaps();
10924
Create a temp table according to a field list.
10926
Given field pointers are changed to point at tmp_table for
10927
send_fields. The table object is self contained: it's
10928
allocated in its own memory root, as well as Field objects
10929
created for table columns.
10930
This function will replace Item_sum items in 'fields' list with
10931
corresponding Item_field items, pointing at the fields in the
10932
temporary table, unless this was prohibited by true
10933
value of argument save_sum_fields. The Item_field objects
10934
are created in THD memory root.
10936
@param thd thread handle
10937
@param param a description used as input to create the table
10938
@param fields list of items that will be used to define
10939
column types of the table (also see NOTES)
10940
@param group TODO document
10941
@param distinct should table rows be distinct
10942
@param save_sum_fields see NOTES
10943
@param select_options
10945
@param table_alias possible name of the temporary table that can
10946
be used for name resolving; can be "".
10949
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
10950
#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
10951
#define RATIO_TO_PACK_ROWS 2
10952
#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
10955
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
10956
ORDER *group, bool distinct, bool save_sum_fields,
10957
ulonglong select_options, ha_rows rows_limit,
10960
MEM_ROOT *mem_root_save, own_root;
10962
TABLE_SHARE *share;
10963
uint i,field_count,null_count,null_pack_length;
10964
uint copy_func_count= param->func_count;
10965
uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
10966
uint blob_count,group_null_items, string_count;
10967
uint temp_pool_slot=MY_BIT_NONE;
10969
ulong reclength, string_total_length;
10970
bool using_unique_constraint= 0;
10971
bool use_packed_rows= 0;
10972
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
10973
char *tmpname,path[FN_REFLEN];
10974
uchar *pos, *group_buff, *bitmaps;
10976
Field **reg_field, **from_field, **default_field;
10978
Copy_field *copy=0;
10980
KEY_PART_INFO *key_part_info;
10982
MI_COLUMNDEF *recinfo;
10983
uint total_uneven_bit_length= 0;
10984
bool force_copy_fields= param->force_copy_fields;
10986
status_var_increment(thd->status_var.created_tmp_tables);
10988
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
10989
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
10991
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
10992
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
10993
current_pid, temp_pool_slot);
10996
/* if we run out of slots or we are not using tempool */
10997
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
10998
thd->thread_id, thd->tmp_table++);
11002
No need to change table name to lower case as we are only creating
11003
MyISAM or HEAP tables here
11005
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11010
if (!param->quick_group)
11011
group=0; // Can't use group key
11012
else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
11015
marker == 4 means two things:
11016
- store NULLs in the key, and
11017
- convert BIT fields to 64-bit long, needed because MEMORY tables
11018
can't index BIT fields.
11020
(*tmp->item)->marker= 4;
11021
if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
11022
using_unique_constraint=1;
11024
if (param->group_length >= MAX_BLOB_WIDTH)
11025
using_unique_constraint=1;
11027
distinct=0; // Can't use distinct
11030
field_count=param->field_count+param->func_count+param->sum_func_count;
11031
hidden_field_count=param->hidden_field_count;
11034
When loose index scan is employed as access method, it already
11035
computes all groups and the result of all aggregate functions. We
11036
make space for the items of the aggregate function in the list of
11037
functions TMP_TABLE_PARAM::items_to_copy, so that the values of
11038
these items are stored in the temporary table.
11040
if (param->precomputed_group_by)
11041
copy_func_count+= param->sum_func_count;
11043
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11045
if (!multi_alloc_root(&own_root,
11046
&table, sizeof(*table),
11047
&share, sizeof(*share),
11048
®_field, sizeof(Field*) * (field_count+1),
11049
&default_field, sizeof(Field*) * (field_count),
11050
&blob_field, sizeof(uint)*(field_count+1),
11051
&from_field, sizeof(Field*)*field_count,
11052
©_func, sizeof(*copy_func)*(copy_func_count+1),
11053
¶m->keyinfo, sizeof(*param->keyinfo),
11055
sizeof(*key_part_info)*(param->group_parts+1),
11056
¶m->start_recinfo,
11057
sizeof(*param->recinfo)*(field_count*2+4),
11058
&tmpname, (uint) strlen(path)+1,
11059
&group_buff, (group && ! using_unique_constraint ?
11060
param->group_length : 0),
11061
&bitmaps, bitmap_buffer_size(field_count)*2,
11064
if (temp_pool_slot != MY_BIT_NONE)
11065
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11066
return(NULL); /* purecov: inspected */
11068
/* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
11069
if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
11071
if (temp_pool_slot != MY_BIT_NONE)
11072
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11073
free_root(&own_root, MYF(0)); /* purecov: inspected */
11074
return(NULL); /* purecov: inspected */
11076
param->items_to_copy= copy_func;
11077
strmov(tmpname,path);
11078
/* make table according to fields */
11080
bzero((char*) table,sizeof(*table));
11081
bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
11082
bzero((char*) default_field, sizeof(Field*) * (field_count));
11083
bzero((char*) from_field,sizeof(Field*)*field_count);
11085
table->mem_root= own_root;
11086
mem_root_save= thd->mem_root;
11087
thd->mem_root= &table->mem_root;
11089
table->field=reg_field;
11090
table->alias= table_alias;
11091
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11092
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11094
table->temp_pool_slot = temp_pool_slot;
11095
table->copy_blobs= 1;
11096
table->in_use= thd;
11097
table->quick_keys.init();
11098
table->covering_keys.init();
11099
table->keys_in_use_for_query.init();
11102
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11103
share->blob_field= blob_field;
11104
share->blob_ptr_size= portable_sizeof_char_ptr;
11105
share->db_low_byte_first=1; // True for HEAP and MyISAM
11106
share->table_charset= param->table_charset;
11107
share->primary_key= MAX_KEY; // Indicate no primary key
11108
share->keys_for_keyread.init();
11109
share->keys_in_use.init();
11111
/* Calculate which type of fields we will store in the temporary table */
11113
reclength= string_total_length= 0;
11114
blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
11115
param->using_indirect_summary_function=0;
11117
List_iterator_fast<Item> li(fields);
11119
Field **tmp_from_field=from_field;
11120
while ((item=li++))
11122
Item::Type type=item->type();
11123
if (not_all_columns)
11125
if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
11127
if (item->used_tables() & OUTER_REF_TABLE_BIT)
11128
item->update_used_tables();
11129
if (type == Item::SUBSELECT_ITEM ||
11130
(item->used_tables() & ~OUTER_REF_TABLE_BIT))
11133
Mark that the we have ignored an item that refers to a summary
11134
function. We need to know this if someone is going to use
11135
DISTINCT on the result.
11137
param->using_indirect_summary_function=1;
11141
if (item->const_item() && (int) hidden_field_count <= 0)
11142
continue; // We don't have to store this
11144
if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
11145
{ /* Can't calc group yet */
11146
((Item_sum*) item)->result_field=0;
11147
for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
11149
Item **argp= ((Item_sum*) item)->args + i;
11151
if (!arg->const_item())
11154
create_tmp_field(thd, table, arg, arg->type(), ©_func,
11155
tmp_from_field, &default_field[fieldnr],
11156
group != 0,not_all_columns,
11158
param->convert_blob_length);
11160
goto err; // Should be OOM
11162
reclength+=new_field->pack_length();
11163
if (new_field->flags & BLOB_FLAG)
11165
*blob_field++= fieldnr;
11168
*(reg_field++)= new_field;
11169
if (new_field->real_type() == MYSQL_TYPE_STRING ||
11170
new_field->real_type() == MYSQL_TYPE_VARCHAR)
11173
string_total_length+= new_field->pack_length();
11175
thd->mem_root= mem_root_save;
11176
thd->change_item_tree(argp, new Item_field(new_field));
11177
thd->mem_root= &table->mem_root;
11178
if (!(new_field->flags & NOT_NULL_FLAG))
11182
new_field->maybe_null() is still false, it will be
11183
changed below. But we have to setup Item_field correctly
11185
(*argp)->maybe_null=1;
11187
new_field->field_index= fieldnr++;
11194
The last parameter to create_tmp_field() is a bit tricky:
11196
We need to set it to 0 in union, to get fill_record() to modify the
11198
We need to set it to 1 on multi-table-update and in select to
11199
write rows to the temporary table.
11200
We here distinguish between UNION and multi-table-updates by the fact
11201
that in the later case group is set to the row pointer.
11203
Field *new_field= (param->schema_table) ?
11204
create_tmp_field_for_schema(thd, item, table) :
11205
create_tmp_field(thd, table, item, type, ©_func,
11206
tmp_from_field, &default_field[fieldnr],
11208
!force_copy_fields &&
11209
(not_all_columns || group !=0),
11211
If item->marker == 4 then we force create_tmp_field
11212
to create a 64-bit longs for BIT fields because HEAP
11213
tables can't index BIT fields directly. We do the same
11214
for distinct, as we want the distinct index to be
11215
usable in this case too.
11217
item->marker == 4 || param->bit_fields_as_long,
11219
param->convert_blob_length);
11223
if (thd->is_fatal_error)
11224
goto err; // Got OOM
11225
continue; // Some kindf of const item
11227
if (type == Item::SUM_FUNC_ITEM)
11228
((Item_sum *) item)->result_field= new_field;
11230
reclength+=new_field->pack_length();
11231
if (!(new_field->flags & NOT_NULL_FLAG))
11233
if (new_field->flags & BLOB_FLAG)
11235
*blob_field++= fieldnr;
11238
if (item->marker == 4 && item->maybe_null)
11240
group_null_items++;
11241
new_field->flags|= GROUP_FLAG;
11243
new_field->field_index= fieldnr++;
11244
*(reg_field++)= new_field;
11246
if (!--hidden_field_count)
11249
This was the last hidden field; Remember how many hidden fields could
11252
hidden_null_count=null_count;
11254
We need to update hidden_field_count as we may have stored group
11255
functions with constant arguments
11257
param->hidden_field_count= fieldnr;
11261
assert(fieldnr == (uint) (reg_field - table->field));
11262
assert(field_count >= (uint) (reg_field - table->field));
11263
field_count= fieldnr;
11265
*blob_field= 0; // End marker
11266
share->fields= field_count;
11268
/* If result table is small; use a heap */
11269
/* future: storage engine selection can be made dynamic? */
11270
if (blob_count || using_unique_constraint ||
11271
(select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
11272
OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
11274
share->db_plugin= ha_lock_engine(0, myisam_hton);
11275
table->file= get_new_handler(share, &table->mem_root,
11278
(param->group_parts > table->file->max_key_parts() ||
11279
param->group_length > table->file->max_key_length()))
11280
using_unique_constraint=1;
11284
share->db_plugin= ha_lock_engine(0, heap_hton);
11285
table->file= get_new_handler(share, &table->mem_root,
11292
if (!using_unique_constraint)
11293
reclength+= group_null_items; // null flag is stored separately
11295
share->blob_fields= blob_count;
11296
if (blob_count == 0)
11298
/* We need to ensure that first byte is not 0 for the delete link */
11299
if (param->hidden_field_count)
11300
hidden_null_count++;
11304
hidden_null_pack_length=(hidden_null_count+7)/8;
11305
null_pack_length= (hidden_null_pack_length +
11306
(null_count + total_uneven_bit_length + 7) / 8);
11307
reclength+=null_pack_length;
11309
reclength=1; // Dummy select
11310
/* Use packed rows if there is blobs or a lot of space to gain */
11311
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)))
11312
use_packed_rows= 1;
11314
share->reclength= reclength;
11316
uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
11317
share->rec_buff_length= alloc_length;
11318
if (!(table->record[0]= (uchar*)
11319
alloc_root(&table->mem_root, alloc_length*3)))
11321
table->record[1]= table->record[0]+alloc_length;
11322
share->default_values= table->record[1]+alloc_length;
11324
copy_func[0]=0; // End marker
11325
param->func_count= copy_func - param->items_to_copy;
11327
setup_tmp_table_column_bitmaps(table, bitmaps);
11329
recinfo=param->start_recinfo;
11330
null_flags=(uchar*) table->record[0];
11331
pos=table->record[0]+ null_pack_length;
11332
if (null_pack_length)
11334
bzero((uchar*) recinfo,sizeof(*recinfo));
11335
recinfo->type=FIELD_NORMAL;
11336
recinfo->length=null_pack_length;
11338
bfill(null_flags,null_pack_length,255); // Set null fields
11340
table->null_flags= (uchar*) table->record[0];
11341
share->null_fields= null_count+ hidden_null_count;
11342
share->null_bytes= null_pack_length;
11344
null_count= (blob_count == 0) ? 1 : 0;
11345
hidden_field_count=param->hidden_field_count;
11346
for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
11348
Field *field= *reg_field;
11350
bzero((uchar*) recinfo,sizeof(*recinfo));
11352
if (!(field->flags & NOT_NULL_FLAG))
11354
if (field->flags & GROUP_FLAG && !using_unique_constraint)
11357
We have to reserve one byte here for NULL bits,
11358
as this is updated by 'end_update()'
11360
*pos++=0; // Null is stored here
11362
recinfo->type=FIELD_NORMAL;
11364
bzero((uchar*) recinfo,sizeof(*recinfo));
11368
recinfo->null_bit= 1 << (null_count & 7);
11369
recinfo->null_pos= null_count/8;
11371
field->move_field(pos,null_flags+null_count/8,
11372
1 << (null_count & 7));
11376
field->move_field(pos,(uchar*) 0,0);
11380
Test if there is a default field value. The test for ->ptr is to skip
11381
'offset' fields generated by initalize_tables
11383
if (default_field[i] && default_field[i]->ptr)
11386
default_field[i] is set only in the cases when 'field' can
11387
inherit the default value that is defined for the field referred
11388
by the Item_field object from which 'field' has been created.
11391
Field *orig_field= default_field[i];
11392
/* Get the value from default_values */
11393
diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
11394
orig_field->table->record[0]);
11395
orig_field->move_field_offset(diff); // Points now at default_values
11396
if (orig_field->is_real_null())
11400
field->set_notnull();
11401
memcpy(field->ptr, orig_field->ptr, field->pack_length());
11403
orig_field->move_field_offset(-diff); // Back to record[0]
11407
{ /* Not a table Item */
11408
copy->set(field,from_field[i],save_sum_fields);
11411
length=field->pack_length();
11414
/* Make entry for create table */
11415
recinfo->length=length;
11416
if (field->flags & BLOB_FLAG)
11417
recinfo->type= (int) FIELD_BLOB;
11418
else if (use_packed_rows &&
11419
field->real_type() == MYSQL_TYPE_STRING &&
11420
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
11421
recinfo->type=FIELD_SKIP_ENDSPACE;
11423
recinfo->type=FIELD_NORMAL;
11424
if (!--hidden_field_count)
11425
null_count=(null_count+7) & ~7; // move to next byte
11427
// fix table name in field entry
11428
field->table_name= &table->alias;
11431
param->copy_field_end=copy;
11432
param->recinfo=recinfo;
11433
store_record(table,s->default_values); // Make empty default record
11435
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
11436
share->max_rows= ~(ha_rows) 0;
11438
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11439
min(thd->variables.tmp_table_size,
11440
thd->variables.max_heap_table_size) :
11441
thd->variables.tmp_table_size) /
11443
set_if_bigger(share->max_rows,1); // For dummy start options
11445
Push the LIMIT clause to the temporary table creation, so that we
11446
materialize only up to 'rows_limit' records instead of all result records.
11448
set_if_smaller(share->max_rows, rows_limit);
11449
param->end_write_records= rows_limit;
11451
keyinfo= param->keyinfo;
11455
table->group=group; /* Table is grouped by key */
11456
param->group_buff=group_buff;
11458
share->uniques= test(using_unique_constraint);
11459
table->key_info=keyinfo;
11460
keyinfo->key_part=key_part_info;
11461
keyinfo->flags=HA_NOSAME;
11462
keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
11463
keyinfo->key_length=0;
11464
keyinfo->rec_per_key=0;
11465
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11466
keyinfo->name= (char*) "group_key";
11467
ORDER *cur_group= group;
11468
for (; cur_group ; cur_group= cur_group->next, key_part_info++)
11470
Field *field=(*cur_group->item)->get_tmp_table_field();
11471
bool maybe_null=(*cur_group->item)->maybe_null;
11472
key_part_info->null_bit=0;
11473
key_part_info->field= field;
11474
key_part_info->offset= field->offset(table->record[0]);
11475
key_part_info->length= (uint16) field->key_length();
11476
key_part_info->type= (uint8) field->key_type();
11477
key_part_info->key_type =
11478
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11479
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11480
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11481
0 : FIELDFLAG_BINARY;
11482
if (!using_unique_constraint)
11484
cur_group->buff=(char*) group_buff;
11485
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
11490
goto err; /* purecov: inspected */
11494
To be able to group on NULL, we reserved place in group_buff
11495
for the NULL flag just before the column. (see above).
11496
The field data is after this flag.
11497
The NULL flag is updated in 'end_update()' and 'end_write()'
11499
keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
11500
key_part_info->null_bit=field->null_bit;
11501
key_part_info->null_offset= (uint) (field->null_ptr -
11502
(uchar*) table->record[0]);
11503
cur_group->buff++; // Pointer to field data
11504
group_buff++; // Skipp null flag
11506
/* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
11507
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
11508
group_buff+= cur_group->field->pack_length();
11510
keyinfo->key_length+= key_part_info->length;
11514
if (distinct && field_count != param->hidden_field_count)
11517
Create an unique key or an unique constraint over all columns
11518
that should be in the result. In the temporary table, there are
11519
'param->hidden_field_count' extra columns, whose null bits are stored
11520
in the first 'hidden_null_pack_length' bytes of the row.
11525
Special mode for index creation in MyISAM used to support unique
11526
indexes on blobs with arbitrary length. Such indexes cannot be
11531
null_pack_length-=hidden_null_pack_length;
11532
keyinfo->key_parts= ((field_count-param->hidden_field_count)+
11533
(share->uniques ? test(null_pack_length) : 0));
11534
table->distinct= 1;
11536
if (!(key_part_info= (KEY_PART_INFO*)
11537
alloc_root(&table->mem_root,
11538
keyinfo->key_parts * sizeof(KEY_PART_INFO))))
11540
bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
11541
table->key_info=keyinfo;
11542
keyinfo->key_part=key_part_info;
11543
keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
11544
keyinfo->key_length=(uint16) reclength;
11545
keyinfo->name= (char*) "distinct_key";
11546
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11547
keyinfo->rec_per_key=0;
11550
Create an extra field to hold NULL bits so that unique indexes on
11551
blobs can distinguish NULL from 0. This extra field is not needed
11552
when we do not use UNIQUE indexes for blobs.
11554
if (null_pack_length && share->uniques)
11556
key_part_info->null_bit=0;
11557
key_part_info->offset=hidden_null_pack_length;
11558
key_part_info->length=null_pack_length;
11559
key_part_info->field= new Field_string(table->record[0],
11560
(uint32) key_part_info->length,
11564
NullS, &my_charset_bin);
11565
if (!key_part_info->field)
11567
key_part_info->field->init(table);
11568
key_part_info->key_type=FIELDFLAG_BINARY;
11569
key_part_info->type= HA_KEYTYPE_BINARY;
11572
/* Create a distinct key over the columns we are going to return */
11573
for (i=param->hidden_field_count, reg_field=table->field + i ;
11575
i++, reg_field++, key_part_info++)
11577
key_part_info->null_bit=0;
11578
key_part_info->field= *reg_field;
11579
key_part_info->offset= (*reg_field)->offset(table->record[0]);
11580
key_part_info->length= (uint16) (*reg_field)->pack_length();
11582
The below method of computing the key format length of the
11583
key part is a copy/paste from opt_range.cc, and table.cc.
11584
This should be factored out, e.g. as a method of Field.
11585
In addition it is not clear if any of the Field::*_length
11586
methods is supposed to compute the same length. If so, it
11589
key_part_info->store_length= key_part_info->length;
11591
if ((*reg_field)->real_maybe_null())
11592
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
11593
if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
11594
(*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
11595
key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
11597
key_part_info->type= (uint8) (*reg_field)->key_type();
11598
key_part_info->key_type =
11599
((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11600
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11601
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11602
0 : FIELDFLAG_BINARY;
11606
if (thd->is_fatal_error) // If end of memory
11607
goto err; /* purecov: inspected */
11608
share->db_record_offset= 1;
11609
if (share->db_type() == myisam_hton)
11611
if (create_myisam_tmp_table(table, param->keyinfo, param->start_recinfo,
11612
¶m->recinfo, select_options))
11615
if (open_tmp_table(table))
11618
thd->mem_root= mem_root_save;
11623
thd->mem_root= mem_root_save;
11624
free_tmp_table(thd,table); /* purecov: inspected */
11625
if (temp_pool_slot != MY_BIT_NONE)
11626
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11627
return(NULL); /* purecov: inspected */
11634
Create a temporary table to weed out duplicate rowid combinations
11638
create_duplicate_weedout_tmp_table()
11640
uniq_tuple_length_arg
11644
Create a temporary table to weed out duplicate rowid combinations. The
11645
table has a single column that is a concatenation of all rowids in the
11648
Depending on the needed length, there are two cases:
11650
1. When the length of the column < max_key_length:
11652
CREATE TABLE tmp (col VARBINARY(n) NOT NULL, UNIQUE KEY(col));
11654
2. Otherwise (not a valid SQL syntax but internally supported):
11656
CREATE TABLE tmp (col VARBINARY NOT NULL, UNIQUE CONSTRAINT(col));
11658
The code in this function was produced by extraction of relevant parts
11659
from create_tmp_table().
11666
TABLE *create_duplicate_weedout_tmp_table(THD *thd,
11667
uint uniq_tuple_length_arg,
11668
SJ_TMP_TABLE *sjtbl)
11670
MEM_ROOT *mem_root_save, own_root;
11672
TABLE_SHARE *share;
11673
uint temp_pool_slot=MY_BIT_NONE;
11674
char *tmpname,path[FN_REFLEN];
11676
KEY_PART_INFO *key_part_info;
11681
MI_COLUMNDEF *recinfo, *start_recinfo;
11682
bool using_unique_constraint=false;
11683
bool use_packed_rows= false;
11684
Field *field, *key_field;
11685
uint blob_count, null_pack_length, null_count;
11690
STEP 1: Get temporary table name
11692
statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
11693
if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11694
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11696
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11697
sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11698
current_pid, temp_pool_slot);
11701
/* if we run out of slots or we are not using tempool */
11702
sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11703
thd->thread_id, thd->tmp_table++);
11705
fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11707
/* STEP 2: Figure if we'll be using a key or blob+constraint */
11708
if (uniq_tuple_length_arg >= CONVERT_IF_BIGGER_TO_BLOB)
11709
using_unique_constraint= true;
11711
/* STEP 3: Allocate memory for temptable description */
11712
init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11713
if (!multi_alloc_root(&own_root,
11714
&table, sizeof(*table),
11715
&share, sizeof(*share),
11716
®_field, sizeof(Field*) * (1+1),
11717
&blob_field, sizeof(uint)*2,
11718
&keyinfo, sizeof(*keyinfo),
11719
&key_part_info, sizeof(*key_part_info) * 2,
11721
sizeof(*recinfo)*(1*2+4),
11722
&tmpname, (uint) strlen(path)+1,
11723
&group_buff, (!using_unique_constraint ?
11724
uniq_tuple_length_arg : 0),
11725
&bitmaps, bitmap_buffer_size(1)*2,
11728
if (temp_pool_slot != MY_BIT_NONE)
11729
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11732
strmov(tmpname,path);
11735
/* STEP 4: Create TABLE description */
11736
bzero((char*) table,sizeof(*table));
11737
bzero((char*) reg_field,sizeof(Field*)*2);
11739
table->mem_root= own_root;
11740
mem_root_save= thd->mem_root;
11741
thd->mem_root= &table->mem_root;
11743
table->field=reg_field;
11744
table->alias= "weedout-tmp";
11745
table->reginfo.lock_type=TL_WRITE; /* Will be updated */
11746
table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11748
table->temp_pool_slot = temp_pool_slot;
11749
table->copy_blobs= 1;
11750
table->in_use= thd;
11751
table->quick_keys.init();
11752
table->covering_keys.init();
11753
table->keys_in_use_for_query.init();
11756
init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11757
share->blob_field= blob_field;
11758
share->blob_ptr_size= portable_sizeof_char_ptr;
11759
share->db_low_byte_first=1; // True for HEAP and MyISAM
11760
share->table_charset= NULL;
11761
share->primary_key= MAX_KEY; // Indicate no primary key
11762
share->keys_for_keyread.init();
11763
share->keys_in_use.init();
11767
/* Create the field */
11770
For the sake of uniformity, always use Field_varstring (altough we could
11771
use Field_string for shorter keys)
11773
field= new Field_varstring(uniq_tuple_length_arg, false, "rowids", share,
11777
field->table= table;
11778
field->key_start.init(0);
11779
field->part_of_key.init(0);
11780
field->part_of_sortkey.init(0);
11781
field->unireg_check= Field::NONE;
11782
field->flags= (NOT_NULL_FLAG | BINARY_FLAG | NO_DEFAULT_VALUE_FLAG);
11783
field->reset_fields();
11784
field->init(table);
11785
field->orig_table= NULL;
11787
field->field_index= 0;
11789
*(reg_field++)= field;
11794
share->blob_fields= 0;
11797
uint reclength= field->pack_length();
11798
if (using_unique_constraint)
11800
share->db_plugin= ha_lock_engine(0, myisam_hton);
11801
table->file= get_new_handler(share, &table->mem_root,
11803
assert(uniq_tuple_length_arg <= table->file->max_key_length());
11807
share->db_plugin= ha_lock_engine(0, heap_hton);
11808
table->file= get_new_handler(share, &table->mem_root,
11816
null_pack_length= 1;
11817
reclength += null_pack_length;
11819
share->reclength= reclength;
11821
uint alloc_length=ALIGN_SIZE(share->reclength + MI_UNIQUE_HASH_LENGTH+1);
11822
share->rec_buff_length= alloc_length;
11823
if (!(table->record[0]= (uchar*)
11824
alloc_root(&table->mem_root, alloc_length*3)))
11826
table->record[1]= table->record[0]+alloc_length;
11827
share->default_values= table->record[1]+alloc_length;
11829
setup_tmp_table_column_bitmaps(table, bitmaps);
11831
recinfo= start_recinfo;
11832
null_flags=(uchar*) table->record[0];
11833
pos=table->record[0]+ null_pack_length;
11834
if (null_pack_length)
11836
bzero((uchar*) recinfo,sizeof(*recinfo));
11837
recinfo->type=FIELD_NORMAL;
11838
recinfo->length=null_pack_length;
11840
bfill(null_flags,null_pack_length,255); // Set null fields
11842
table->null_flags= (uchar*) table->record[0];
11843
share->null_fields= null_count;
11844
share->null_bytes= null_pack_length;
11849
//Field *field= *reg_field;
11851
bzero((uchar*) recinfo,sizeof(*recinfo));
11852
field->move_field(pos,(uchar*) 0,0);
11856
Test if there is a default field value. The test for ->ptr is to skip
11857
'offset' fields generated by initalize_tables
11859
// Initialize the table field:
11860
bzero(field->ptr, field->pack_length());
11862
length=field->pack_length();
11865
/* Make entry for create table */
11866
recinfo->length=length;
11867
if (field->flags & BLOB_FLAG)
11868
recinfo->type= (int) FIELD_BLOB;
11869
else if (use_packed_rows &&
11870
field->real_type() == MYSQL_TYPE_STRING &&
11871
length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
11872
recinfo->type=FIELD_SKIP_ENDSPACE;
11874
recinfo->type=FIELD_NORMAL;
11876
field->table_name= &table->alias;
11879
//param->recinfo=recinfo;
11880
//store_record(table,s->default_values); // Make empty default record
11882
if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
11883
share->max_rows= ~(ha_rows) 0;
11885
share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11886
min(thd->variables.tmp_table_size,
11887
thd->variables.max_heap_table_size) :
11888
thd->variables.tmp_table_size) /
11890
set_if_bigger(share->max_rows,1); // For dummy start options
11893
//// keyinfo= param->keyinfo;
11897
share->uniques= test(using_unique_constraint);
11898
table->key_info=keyinfo;
11899
keyinfo->key_part=key_part_info;
11900
keyinfo->flags=HA_NOSAME;
11901
keyinfo->usable_key_parts= keyinfo->key_parts= 1;
11902
keyinfo->key_length=0;
11903
keyinfo->rec_per_key=0;
11904
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11905
keyinfo->name= (char*) "weedout_key";
11907
key_part_info->null_bit=0;
11908
key_part_info->field= field;
11909
key_part_info->offset= field->offset(table->record[0]);
11910
key_part_info->length= (uint16) field->key_length();
11911
key_part_info->type= (uint8) field->key_type();
11912
key_part_info->key_type = FIELDFLAG_BINARY;
11913
if (!using_unique_constraint)
11915
if (!(key_field= field->new_key_field(thd->mem_root, table,
11920
key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this?
11922
keyinfo->key_length+= key_part_info->length;
11926
if (thd->is_fatal_error) // If end of memory
11928
share->db_record_offset= 1;
11929
if (share->db_type() == myisam_hton)
11932
if (create_myisam_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
11935
sjtbl->start_recinfo= start_recinfo;
11936
sjtbl->recinfo= recinfo;
11937
if (open_tmp_table(table))
11940
thd->mem_root= mem_root_save;
11944
thd->mem_root= mem_root_save;
11945
free_tmp_table(thd,table); /* purecov: inspected */
11946
if (temp_pool_slot != MY_BIT_NONE)
11947
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11948
return(NULL); /* purecov: inspected */
11951
/****************************************************************************/
11954
Create a reduced TABLE object with properly set up Field list from a
11955
list of field definitions.
11957
The created table doesn't have a table handler associated with
11958
it, has no keys, no group/distinct, no copy_funcs array.
11959
The sole purpose of this TABLE object is to use the power of Field
11960
class to read/write data to/from table->record[0]. Then one can store
11961
the record in any container (RB tree, hash, etc).
11962
The table is created in THD mem_root, so are the table's fields.
11963
Consequently, if you don't BLOB fields, you don't need to free it.
11965
@param thd connection handle
11966
@param field_list list of column definitions
11969
0 if out of memory, TABLE object in case of success
11972
TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
11974
uint field_count= field_list.elements;
11975
uint blob_count= 0;
11977
Create_field *cdef; /* column definition */
11978
uint record_length= 0;
11979
uint null_count= 0; /* number of columns which may be null */
11980
uint null_pack_length; /* NULL representation array length */
11984
TABLE_SHARE *share;
11986
if (!multi_alloc_root(thd->mem_root,
11987
&table, sizeof(*table),
11988
&share, sizeof(*share),
11989
&field, (field_count + 1) * sizeof(Field*),
11990
&blob_field, (field_count+1) *sizeof(uint),
11991
&bitmaps, bitmap_buffer_size(field_count)*2,
11995
bzero(table, sizeof(*table));
11996
bzero(share, sizeof(*share));
11997
table->field= field;
11999
share->blob_field= blob_field;
12000
share->fields= field_count;
12001
share->blob_ptr_size= portable_sizeof_char_ptr;
12002
setup_tmp_table_column_bitmaps(table, bitmaps);
12004
/* Create all fields and calculate the total length of record */
12005
List_iterator_fast<Create_field> it(field_list);
12006
while ((cdef= it++))
12008
*field= make_field(share, 0, cdef->length,
12009
(uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
12010
f_maybe_null(cdef->pack_flag) ? 1 : 0,
12011
cdef->pack_flag, cdef->sql_type, cdef->charset,
12012
cdef->unireg_check,
12013
cdef->interval, cdef->field_name);
12016
(*field)->init(table);
12017
record_length+= (*field)->pack_length();
12018
if (! ((*field)->flags & NOT_NULL_FLAG))
12021
if ((*field)->flags & BLOB_FLAG)
12022
share->blob_field[blob_count++]= (uint) (field - table->field);
12026
*field= NULL; /* mark the end of the list */
12027
share->blob_field[blob_count]= 0; /* mark the end of the list */
12028
share->blob_fields= blob_count;
12030
null_pack_length= (null_count + 7)/8;
12031
share->reclength= record_length + null_pack_length;
12032
share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
12033
table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
12034
if (!table->record[0])
12037
if (null_pack_length)
12039
table->null_flags= (uchar*) table->record[0];
12040
share->null_fields= null_count;
12041
share->null_bytes= null_pack_length;
12044
table->in_use= thd; /* field->reset() may access table->in_use */
12046
/* Set up field pointers */
12047
uchar *null_pos= table->record[0];
12048
uchar *field_pos= null_pos + share->null_bytes;
12051
for (field= table->field; *field; ++field)
12053
Field *cur_field= *field;
12054
if ((cur_field->flags & NOT_NULL_FLAG))
12055
cur_field->move_field(field_pos);
12058
cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
12060
if (null_bit == (1 << 8))
12066
cur_field->reset();
12068
field_pos+= cur_field->pack_length();
12073
for (field= table->field; *field; ++field)
12074
delete *field; /* just invokes field destructor */
12079
static bool open_tmp_table(TABLE *table)
12082
if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
12083
HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
12085
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12089
(void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
12095
Create MyISAM temporary table
12098
create_myisam_tmp_table()
12099
table Table object that descrimes the table to be created
12100
keyinfo Description of the index (there is always one index)
12101
start_recinfo MyISAM's column descriptions
12102
recinfo INOUT End of MyISAM's column descriptions
12103
options Option bits
12106
Create a MyISAM temporary table according to passed description. The is
12107
assumed to have one unique index or constraint.
12109
The passed array or MI_COLUMNDEF structures must have this form:
12111
1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
12112
when there are many nullable columns)
12114
3. One free MI_COLUMNDEF element (*recinfo points here)
12116
This function may use the free element to create hash column for unique
12124
static bool create_myisam_tmp_table(TABLE *table, KEY *keyinfo,
12125
MI_COLUMNDEF *start_recinfo,
12126
MI_COLUMNDEF **recinfo,
12131
MI_UNIQUEDEF uniquedef;
12132
TABLE_SHARE *share= table->s;
12135
{ // Get keys for ni_create
12136
bool using_unique_constraint=0;
12137
HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
12138
sizeof(*seg) * keyinfo->key_parts);
12142
bzero(seg, sizeof(*seg) * keyinfo->key_parts);
12143
if (keyinfo->key_length >= table->file->max_key_length() ||
12144
keyinfo->key_parts > table->file->max_key_parts() ||
12147
/* Can't create a key; Make a unique constraint instead of a key */
12150
using_unique_constraint=1;
12151
bzero((char*) &uniquedef,sizeof(uniquedef));
12152
uniquedef.keysegs=keyinfo->key_parts;
12154
uniquedef.null_are_equal=1;
12156
/* Create extra column for hash value */
12157
bzero((uchar*) *recinfo,sizeof(**recinfo));
12158
(*recinfo)->type= FIELD_CHECK;
12159
(*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
12161
share->reclength+=MI_UNIQUE_HASH_LENGTH;
12165
/* Create an unique key */
12166
bzero((char*) &keydef,sizeof(keydef));
12167
keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
12168
keydef.keysegs= keyinfo->key_parts;
12171
for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
12173
Field *field=keyinfo->key_part[i].field;
12175
seg->language= field->charset()->number;
12176
seg->length= keyinfo->key_part[i].length;
12177
seg->start= keyinfo->key_part[i].offset;
12178
if (field->flags & BLOB_FLAG)
12181
((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
12182
HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
12183
seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
12184
seg->flag= HA_BLOB_PART;
12185
seg->length=0; // Whole blob in unique constraint
12189
seg->type= keyinfo->key_part[i].type;
12190
/* Tell handler if it can do suffic space compression */
12191
if (field->real_type() == MYSQL_TYPE_STRING &&
12192
keyinfo->key_part[i].length > 4)
12193
seg->flag|= HA_SPACE_PACK;
12195
if (!(field->flags & NOT_NULL_FLAG))
12197
seg->null_bit= field->null_bit;
12198
seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
12200
We are using a GROUP BY on something that contains NULL
12201
In this case we have to tell MyISAM that two NULL should
12202
on INSERT be regarded at the same value
12204
if (!using_unique_constraint)
12205
keydef.flag|= HA_NULL_ARE_EQUAL;
12209
MI_CREATE_INFO create_info;
12210
bzero((char*) &create_info,sizeof(create_info));
12212
if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
12214
create_info.data_file_length= ~(ulonglong) 0;
12216
if ((error=mi_create(share->table_name.str, share->keys, &keydef,
12217
(uint) (*recinfo-start_recinfo),
12219
share->uniques, &uniquedef,
12221
HA_CREATE_TMP_TABLE)))
12223
table->file->print_error(error,MYF(0)); /* purecov: inspected */
12227
status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
12228
share->db_record_offset= 1;
12236
free_tmp_table(THD *thd, TABLE *entry)
12238
MEM_ROOT own_root= entry->mem_root;
12239
const char *save_proc_info;
12241
save_proc_info=thd->proc_info;
12242
thd_proc_info(thd, "removing tmp table");
12246
if (entry->db_stat)
12247
entry->file->ha_drop_table(entry->s->table_name.str);
12249
entry->file->ha_delete_table(entry->s->table_name.str);
12250
delete entry->file;
12254
for (Field **ptr=entry->field ; *ptr ; ptr++)
12256
free_io_cache(entry);
12258
if (entry->temp_pool_slot != MY_BIT_NONE)
12259
bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
12261
plugin_unlock(0, entry->s->db_plugin);
12263
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
12264
thd_proc_info(thd, save_proc_info);
12270
If a HEAP table gets full, create a MyISAM table and copy all rows
12274
bool create_myisam_from_heap(THD *thd, TABLE *table,
12275
MI_COLUMNDEF *start_recinfo,
12276
MI_COLUMNDEF **recinfo,
12277
int error, bool ignore_last_dupp_key_error)
12281
const char *save_proc_info;
12284
if (table->s->db_type() != heap_hton ||
12285
error != HA_ERR_RECORD_FILE_FULL)
12287
table->file->print_error(error,MYF(0));
12292
new_table.s= &share;
12293
new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
12294
if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
12295
new_table.s->db_type())))
12296
return(1); // End of memory
12298
save_proc_info=thd->proc_info;
12299
thd_proc_info(thd, "converting HEAP to MyISAM");
12301
if (create_myisam_tmp_table(&new_table, table->key_info, start_recinfo,
12302
recinfo, thd->lex->select_lex.options |
12305
if (open_tmp_table(&new_table))
12307
if (table->file->indexes_are_disabled())
12308
new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
12309
table->file->ha_index_or_rnd_end();
12310
table->file->ha_rnd_init(1);
12311
if (table->no_rows)
12313
new_table.file->extra(HA_EXTRA_NO_ROWS);
12314
new_table.no_rows=1;
12317
#ifdef TO_BE_DONE_LATER_IN_4_1
12319
To use start_bulk_insert() (which is new in 4.1) we need to find
12320
all places where a corresponding end_bulk_insert() should be put.
12322
table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
12323
new_table.file->ha_start_bulk_insert(table->file->stats.records);
12325
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
12326
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
12330
copy all old rows from heap table to MyISAM table
12331
This is the only code that uses record[1] to read/write but this
12332
is safe as this is a temporary MyISAM table without timestamp/autoincrement.
12334
while (!table->file->rnd_next(new_table.record[1]))
12336
write_err= new_table.file->ha_write_row(new_table.record[1]);
12340
/* copy row that filled HEAP table */
12341
if ((write_err=new_table.file->ha_write_row(table->record[0])))
12343
if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
12344
!ignore_last_dupp_key_error)
12348
/* remove heap table and change to use myisam table */
12349
(void) table->file->ha_rnd_end();
12350
(void) table->file->close(); // This deletes the table !
12351
delete table->file;
12353
plugin_unlock(0, table->s->db_plugin);
12354
share.db_plugin= my_plugin_lock(0, &share.db_plugin);
12355
new_table.s= table->s; // Keep old share
12359
table->file->change_table_ptr(table, table->s);
12360
table->use_all_columns();
12361
if (save_proc_info)
12363
const char *new_proc_info=
12364
(!strcmp(save_proc_info,"Copying to tmp table") ?
12365
"Copying to tmp table on disk" : save_proc_info);
12366
thd_proc_info(thd, new_proc_info);
12371
table->file->print_error(write_err, MYF(0));
12372
(void) table->file->ha_rnd_end();
12373
(void) new_table.file->close();
12375
new_table.file->ha_delete_table(new_table.s->table_name.str);
12377
delete new_table.file;
12378
thd_proc_info(thd, save_proc_info);
12379
table->mem_root= new_table.mem_root;