~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2008-08-15 21:14:46 UTC
  • mto: This revision was merged to the branch mainline in revision 346.
  • Revision ID: brian@tangent.org-20080815211446-aqtozo1hoe8mb2az
Commiting next pass of Table class cleanup.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
*/
26
26
#include <drizzled/server_includes.h>
27
27
#include <drizzled/sql_select.h>
 
28
#include "sj_tmp_table.h"
28
29
 
29
30
#include <mysys/my_bit.h>
30
31
#include <drizzled/drizzled_error_messages.h>
116
117
                           List<TABLE_LIST> *join_list,
117
118
                           Item::cond_result *cond_value);
118
119
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
119
 
static bool open_tmp_table(TABLE *table);
120
 
static bool create_myisam_tmp_table(TABLE *table, KEY *keyinfo, 
121
 
                                    MI_COLUMNDEF *start_recinfo,
122
 
                                    MI_COLUMNDEF **recinfo,
123
 
                                    uint64_t options);
124
120
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table);
125
121
 
126
122
static enum_nested_loop_state
847
843
}
848
844
 
849
845
 
850
 
TABLE *create_duplicate_weedout_tmp_table(THD *thd, uint uniq_tuple_length_arg,
851
 
                                          SJ_TMP_TABLE *sjtbl);
852
 
 
853
 
 
854
846
/*
855
847
  Setup the strategies to eliminate semi-join duplicates.
856
848
  
1198
1190
  {
1199
1191
    if (sj_tbl->tmp_table)
1200
1192
    {
1201
 
      free_tmp_table(join->thd, sj_tbl->tmp_table);
 
1193
      sj_tbl->tmp_table->free_tmp_table(join->thd);
1202
1194
    }
1203
1195
  }
1204
1196
  join->sj_tmp_tables= NULL;
2562
2554
 
2563
2555
  cleanup(1);
2564
2556
  if (exec_tmp_table1)
2565
 
    free_tmp_table(thd, exec_tmp_table1);
 
2557
    exec_tmp_table1->free_tmp_table(thd);
2566
2558
  if (exec_tmp_table2)
2567
 
    free_tmp_table(thd, exec_tmp_table2);
 
2559
    exec_tmp_table2->free_tmp_table(thd);
2568
2560
  delete select;
2569
2561
  delete_dynamic(&keyuse);
2570
2562
  return(error);
10522
10514
  return 0;
10523
10515
}
10524
10516
 
10525
 
/****************************************************************************
10526
 
  Create internal temporary table
10527
 
****************************************************************************/
10528
 
 
10529
 
/**
10530
 
  Create field for temporary table from given field.
10531
 
 
10532
 
  @param thd           Thread handler
10533
 
  @param org_field    field from which new field will be created
10534
 
  @param name         New field name
10535
 
  @param table         Temporary table
10536
 
  @param item          !=NULL if item->result_field should point to new field.
10537
 
                      This is relevant for how fill_record() is going to work:
10538
 
                      If item != NULL then fill_record() will update
10539
 
                      the record in the original table.
10540
 
                      If item == NULL then fill_record() will update
10541
 
                      the temporary table
10542
 
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
10543
 
                               field instead of blob.
10544
 
 
10545
 
  @retval
10546
 
    NULL                on error
10547
 
  @retval
10548
 
    new_created field
10549
 
*/
10550
 
 
10551
 
Field *create_tmp_field_from_field(THD *thd, Field *org_field,
10552
 
                                   const char *name, TABLE *table,
10553
 
                                   Item_field *item, uint convert_blob_length)
10554
 
{
10555
 
  Field *new_field;
10556
 
 
10557
 
  /* 
10558
 
    Make sure that the blob fits into a Field_varstring which has 
10559
 
    2-byte lenght. 
10560
 
  */
10561
 
  if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
10562
 
      (org_field->flags & BLOB_FLAG))
10563
 
    new_field= new Field_varstring(convert_blob_length,
10564
 
                                   org_field->maybe_null(),
10565
 
                                   org_field->field_name, table->s,
10566
 
                                   org_field->charset());
10567
 
  else
10568
 
    new_field= org_field->new_field(thd->mem_root, table,
10569
 
                                    table == org_field->table);
10570
 
  if (new_field)
10571
 
  {
10572
 
    new_field->init(table);
10573
 
    new_field->orig_table= org_field->orig_table;
10574
 
    if (item)
10575
 
      item->result_field= new_field;
10576
 
    else
10577
 
      new_field->field_name= name;
10578
 
    new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
10579
 
    if (org_field->maybe_null() || (item && item->maybe_null))
10580
 
      new_field->flags&= ~NOT_NULL_FLAG;        // Because of outer join
10581
 
    if (org_field->type() == DRIZZLE_TYPE_VARCHAR)
10582
 
      table->s->db_create_options|= HA_OPTION_PACK_RECORD;
10583
 
    else if (org_field->type() == DRIZZLE_TYPE_DOUBLE)
10584
 
      ((Field_double *) new_field)->not_fixed= true;
10585
 
  }
10586
 
  return new_field;
10587
 
}
10588
 
 
10589
 
/**
10590
 
  Create field for temporary table using type of given item.
10591
 
 
10592
 
  @param thd                   Thread handler
10593
 
  @param item                  Item to create a field for
10594
 
  @param table                 Temporary table
10595
 
  @param copy_func             If set and item is a function, store copy of
10596
 
                               item in this array
10597
 
  @param modify_item           1 if item->result_field should point to new
10598
 
                               item. This is relevent for how fill_record()
10599
 
                               is going to work:
10600
 
                               If modify_item is 1 then fill_record() will
10601
 
                               update the record in the original table.
10602
 
                               If modify_item is 0 then fill_record() will
10603
 
                               update the temporary table
10604
 
  @param convert_blob_length   If >0 create a varstring(convert_blob_length)
10605
 
                               field instead of blob.
10606
 
 
10607
 
  @retval
10608
 
    0  on error
10609
 
  @retval
10610
 
    new_created field
10611
 
*/
10612
 
 
10613
 
static Field *create_tmp_field_from_item(THD *thd __attribute__((unused)),
10614
 
                                         Item *item, TABLE *table,
10615
 
                                         Item ***copy_func, bool modify_item,
10616
 
                                         uint convert_blob_length)
10617
 
{
10618
 
  bool maybe_null= item->maybe_null;
10619
 
  Field *new_field;
10620
 
 
10621
 
  switch (item->result_type()) {
10622
 
  case REAL_RESULT:
10623
 
    new_field= new Field_double(item->max_length, maybe_null,
10624
 
                                item->name, item->decimals, true);
10625
 
    break;
10626
 
  case INT_RESULT:
10627
 
    /* 
10628
 
      Select an integer type with the minimal fit precision.
10629
 
      MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
10630
 
      Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into 
10631
 
      Field_long : make them Field_int64_t.  
10632
 
    */
10633
 
    if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
10634
 
      new_field=new Field_int64_t(item->max_length, maybe_null,
10635
 
                                   item->name, item->unsigned_flag);
10636
 
    else
10637
 
      new_field=new Field_long(item->max_length, maybe_null,
10638
 
                               item->name, item->unsigned_flag);
10639
 
    break;
10640
 
  case STRING_RESULT:
10641
 
    assert(item->collation.collation);
10642
 
  
10643
 
    enum enum_field_types type;
10644
 
    /*
10645
 
      DATE/TIME fields have STRING_RESULT result type. 
10646
 
      To preserve type they needed to be handled separately.
10647
 
    */
10648
 
    if ((type= item->field_type()) == DRIZZLE_TYPE_DATETIME ||
10649
 
        type == DRIZZLE_TYPE_TIME || type == DRIZZLE_TYPE_NEWDATE ||
10650
 
        type == DRIZZLE_TYPE_TIMESTAMP)
10651
 
      new_field= item->tmp_table_field_from_field_type(table, 1);
10652
 
    /* 
10653
 
      Make sure that the blob fits into a Field_varstring which has 
10654
 
      2-byte lenght. 
10655
 
    */
10656
 
    else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
10657
 
             convert_blob_length <= Field_varstring::MAX_SIZE && 
10658
 
             convert_blob_length)
10659
 
      new_field= new Field_varstring(convert_blob_length, maybe_null,
10660
 
                                     item->name, table->s,
10661
 
                                     item->collation.collation);
10662
 
    else
10663
 
      new_field= item->make_string_field(table);
10664
 
    new_field->set_derivation(item->collation.derivation);
10665
 
    break;
10666
 
  case DECIMAL_RESULT:
10667
 
  {
10668
 
    uint8_t dec= item->decimals;
10669
 
    uint8_t intg= ((Item_decimal *) item)->decimal_precision() - dec;
10670
 
    uint32_t len= item->max_length;
10671
 
 
10672
 
    /*
10673
 
      Trying to put too many digits overall in a DECIMAL(prec,dec)
10674
 
      will always throw a warning. We must limit dec to
10675
 
      DECIMAL_MAX_SCALE however to prevent an assert() later.
10676
 
    */
10677
 
 
10678
 
    if (dec > 0)
10679
 
    {
10680
 
      signed int overflow;
10681
 
 
10682
 
      dec= min(dec, (uint8_t)DECIMAL_MAX_SCALE);
10683
 
 
10684
 
      /*
10685
 
        If the value still overflows the field with the corrected dec,
10686
 
        we'll throw out decimals rather than integers. This is still
10687
 
        bad and of course throws a truncation warning.
10688
 
        +1: for decimal point
10689
 
      */
10690
 
 
10691
 
      overflow= my_decimal_precision_to_length(intg + dec, dec,
10692
 
                                               item->unsigned_flag) - len;
10693
 
 
10694
 
      if (overflow > 0)
10695
 
        dec= max(0, dec - overflow);            // too long, discard fract
10696
 
      else
10697
 
        len -= item->decimals - dec;            // corrected value fits
10698
 
    }
10699
 
 
10700
 
    new_field= new Field_new_decimal(len, maybe_null, item->name,
10701
 
                                     dec, item->unsigned_flag);
10702
 
    break;
10703
 
  }
10704
 
  case ROW_RESULT:
10705
 
  default:
10706
 
    // This case should never be choosen
10707
 
    assert(0);
10708
 
    new_field= 0;
10709
 
    break;
10710
 
  }
10711
 
  if (new_field)
10712
 
    new_field->init(table);
10713
 
    
10714
 
  if (copy_func && item->is_result_field())
10715
 
    *((*copy_func)++) = item;                   // Save for copy_funcs
10716
 
  if (modify_item)
10717
 
    item->set_result_field(new_field);
10718
 
  if (item->type() == Item::NULL_ITEM)
10719
 
    new_field->is_created_from_null_item= true;
10720
 
  return new_field;
10721
 
}
10722
 
 
10723
 
 
10724
 
/**
10725
 
  Create field for information schema table.
10726
 
 
10727
 
  @param thd            Thread handler
10728
 
  @param table          Temporary table
10729
 
  @param item           Item to create a field for
10730
 
 
10731
 
  @retval
10732
 
    0                   on error
10733
 
  @retval
10734
 
    new_created field
10735
 
*/
10736
 
 
10737
 
Field *create_tmp_field_for_schema(THD *thd __attribute__((unused)),
10738
 
                                   Item *item, TABLE *table)
10739
 
{
10740
 
  if (item->field_type() == DRIZZLE_TYPE_VARCHAR)
10741
 
  {
10742
 
    Field *field;
10743
 
    if (item->max_length > MAX_FIELD_VARCHARLENGTH)
10744
 
      field= new Field_blob(item->max_length, item->maybe_null,
10745
 
                            item->name, item->collation.collation);
10746
 
    else
10747
 
      field= new Field_varstring(item->max_length, item->maybe_null,
10748
 
                                 item->name,
10749
 
                                 table->s, item->collation.collation);
10750
 
    if (field)
10751
 
      field->init(table);
10752
 
    return field;
10753
 
  }
10754
 
  return item->tmp_table_field_from_field_type(table, 0);
10755
 
}
10756
 
 
10757
 
 
10758
 
/**
10759
 
  Create field for temporary table.
10760
 
 
10761
 
  @param thd            Thread handler
10762
 
  @param table          Temporary table
10763
 
  @param item           Item to create a field for
10764
 
  @param type           Type of item (normally item->type)
10765
 
  @param copy_func      If set and item is a function, store copy of item
10766
 
                       in this array
10767
 
  @param from_field    if field will be created using other field as example,
10768
 
                       pointer example field will be written here
10769
 
  @param default_field  If field has a default value field, store it here
10770
 
  @param group          1 if we are going to do a relative group by on result
10771
 
  @param modify_item    1 if item->result_field should point to new item.
10772
 
                       This is relevent for how fill_record() is going to
10773
 
                       work:
10774
 
                       If modify_item is 1 then fill_record() will update
10775
 
                       the record in the original table.
10776
 
                       If modify_item is 0 then fill_record() will update
10777
 
                       the temporary table
10778
 
  @param convert_blob_length If >0 create a varstring(convert_blob_length)
10779
 
                             field instead of blob.
10780
 
 
10781
 
  @retval
10782
 
    0                   on error
10783
 
  @retval
10784
 
    new_created field
10785
 
*/
10786
 
 
10787
 
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
10788
 
                        Item ***copy_func, Field **from_field,
10789
 
                        Field **default_field,
10790
 
                        bool group, bool modify_item,
10791
 
                        bool table_cant_handle_bit_fields __attribute__((unused)),
10792
 
                        bool make_copy_field,
10793
 
                        uint convert_blob_length)
10794
 
{
10795
 
  Field *result;
10796
 
  Item::Type orig_type= type;
10797
 
  Item *orig_item= 0;
10798
 
 
10799
 
  if (type != Item::FIELD_ITEM &&
10800
 
      item->real_item()->type() == Item::FIELD_ITEM)
10801
 
  {
10802
 
    orig_item= item;
10803
 
    item= item->real_item();
10804
 
    type= Item::FIELD_ITEM;
10805
 
  }
10806
 
 
10807
 
  switch (type) {
10808
 
  case Item::SUM_FUNC_ITEM:
10809
 
  {
10810
 
    Item_sum *item_sum=(Item_sum*) item;
10811
 
    result= item_sum->create_tmp_field(group, table, convert_blob_length);
10812
 
    if (!result)
10813
 
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
10814
 
    return result;
10815
 
  }
10816
 
  case Item::FIELD_ITEM:
10817
 
  case Item::DEFAULT_VALUE_ITEM:
10818
 
  {
10819
 
    Item_field *field= (Item_field*) item;
10820
 
    bool orig_modify= modify_item;
10821
 
    if (orig_type == Item::REF_ITEM)
10822
 
      modify_item= 0;
10823
 
    /*
10824
 
      If item have to be able to store NULLs but underlaid field can't do it,
10825
 
      create_tmp_field_from_field() can't be used for tmp field creation.
10826
 
    */
10827
 
    if (field->maybe_null && !field->field->maybe_null())
10828
 
    {
10829
 
      result= create_tmp_field_from_item(thd, item, table, NULL,
10830
 
                                         modify_item, convert_blob_length);
10831
 
      *from_field= field->field;
10832
 
      if (result && modify_item)
10833
 
        field->result_field= result;
10834
 
    } 
10835
 
    else
10836
 
      result= create_tmp_field_from_field(thd, (*from_field= field->field),
10837
 
                                          orig_item ? orig_item->name :
10838
 
                                          item->name,
10839
 
                                          table,
10840
 
                                          modify_item ? field :
10841
 
                                          NULL,
10842
 
                                          convert_blob_length);
10843
 
    if (orig_type == Item::REF_ITEM && orig_modify)
10844
 
      ((Item_ref*)orig_item)->set_result_field(result);
10845
 
    if (field->field->eq_def(result))
10846
 
      *default_field= field->field;
10847
 
    return result;
10848
 
  }
10849
 
  /* Fall through */
10850
 
  case Item::FUNC_ITEM:
10851
 
    /* Fall through */
10852
 
  case Item::COND_ITEM:
10853
 
  case Item::FIELD_AVG_ITEM:
10854
 
  case Item::FIELD_STD_ITEM:
10855
 
  case Item::SUBSELECT_ITEM:
10856
 
    /* The following can only happen with 'CREATE TABLE ... SELECT' */
10857
 
  case Item::PROC_ITEM:
10858
 
  case Item::INT_ITEM:
10859
 
  case Item::REAL_ITEM:
10860
 
  case Item::DECIMAL_ITEM:
10861
 
  case Item::STRING_ITEM:
10862
 
  case Item::REF_ITEM:
10863
 
  case Item::NULL_ITEM:
10864
 
  case Item::VARBIN_ITEM:
10865
 
    if (make_copy_field)
10866
 
    {
10867
 
      assert(((Item_result_field*)item)->result_field);
10868
 
      *from_field= ((Item_result_field*)item)->result_field;
10869
 
    }
10870
 
    return create_tmp_field_from_item(thd, item, table,
10871
 
                                      (make_copy_field ? 0 : copy_func),
10872
 
                                       modify_item, convert_blob_length);
10873
 
  case Item::TYPE_HOLDER:  
10874
 
    result= ((Item_type_holder *)item)->make_field_by_type(table);
10875
 
    result->set_derivation(item->collation.derivation);
10876
 
    return result;
10877
 
  default:                                      // Dosen't have to be stored
10878
 
    return 0;
10879
 
  }
10880
 
}
10881
 
 
10882
 
/*
10883
 
  Set up column usage bitmaps for a temporary table
10884
 
 
10885
 
  IMPLEMENTATION
10886
 
    For temporary tables, we need one bitmap with all columns set and
10887
 
    a tmp_set bitmap to be used by things like filesort.
10888
 
*/
10889
 
 
10890
 
void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
10891
 
{
10892
 
  uint field_count= table->s->fields;
10893
 
  bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
10894
 
              false);
10895
 
  bitmap_init(&table->tmp_set,
10896
 
              (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
10897
 
              field_count, false);
10898
 
  /* write_set and all_set are copies of read_set */
10899
 
  table->def_write_set= table->def_read_set;
10900
 
  table->s->all_set= table->def_read_set;
10901
 
  bitmap_set_all(&table->s->all_set);
10902
 
  table->default_column_bitmaps();
10903
 
}
10904
 
 
10905
 
 
10906
 
/**
10907
 
  Create a temp table according to a field list.
10908
 
 
10909
 
  Given field pointers are changed to point at tmp_table for
10910
 
  send_fields. The table object is self contained: it's
10911
 
  allocated in its own memory root, as well as Field objects
10912
 
  created for table columns.
10913
 
  This function will replace Item_sum items in 'fields' list with
10914
 
  corresponding Item_field items, pointing at the fields in the
10915
 
  temporary table, unless this was prohibited by true
10916
 
  value of argument save_sum_fields. The Item_field objects
10917
 
  are created in THD memory root.
10918
 
 
10919
 
  @param thd                  thread handle
10920
 
  @param param                a description used as input to create the table
10921
 
  @param fields               list of items that will be used to define
10922
 
                              column types of the table (also see NOTES)
10923
 
  @param group                TODO document
10924
 
  @param distinct             should table rows be distinct
10925
 
  @param save_sum_fields      see NOTES
10926
 
  @param select_options
10927
 
  @param rows_limit
10928
 
  @param table_alias          possible name of the temporary table that can
10929
 
                              be used for name resolving; can be "".
10930
 
*/
10931
 
 
10932
 
#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
10933
 
#define AVG_STRING_LENGTH_TO_PACK_ROWS   64
10934
 
#define RATIO_TO_PACK_ROWS             2
10935
 
#define MIN_STRING_LENGTH_TO_PACK_ROWS   10
10936
 
 
10937
 
TABLE *
10938
 
create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
10939
 
                 ORDER *group, bool distinct, bool save_sum_fields,
10940
 
                 uint64_t select_options, ha_rows rows_limit,
10941
 
                 char *table_alias)
10942
 
{
10943
 
  MEM_ROOT *mem_root_save, own_root;
10944
 
  TABLE *table;
10945
 
  TABLE_SHARE *share;
10946
 
  uint  i,field_count,null_count,null_pack_length;
10947
 
  uint  copy_func_count= param->func_count;
10948
 
  uint  hidden_null_count, hidden_null_pack_length, hidden_field_count;
10949
 
  uint  blob_count,group_null_items, string_count;
10950
 
  uint  temp_pool_slot=MY_BIT_NONE;
10951
 
  uint fieldnr= 0;
10952
 
  ulong reclength, string_total_length;
10953
 
  bool  using_unique_constraint= 0;
10954
 
  bool  use_packed_rows= 0;
10955
 
  bool  not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
10956
 
  char  *tmpname,path[FN_REFLEN];
10957
 
  uchar *pos, *group_buff, *bitmaps;
10958
 
  uchar *null_flags;
10959
 
  Field **reg_field, **from_field, **default_field;
10960
 
  uint *blob_field;
10961
 
  Copy_field *copy=0;
10962
 
  KEY *keyinfo;
10963
 
  KEY_PART_INFO *key_part_info;
10964
 
  Item **copy_func;
10965
 
  MI_COLUMNDEF *recinfo;
10966
 
  uint total_uneven_bit_length= 0;
10967
 
  bool force_copy_fields= param->force_copy_fields;
10968
 
 
10969
 
  status_var_increment(thd->status_var.created_tmp_tables);
10970
 
 
10971
 
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
10972
 
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
10973
 
 
10974
 
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
10975
 
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
10976
 
            current_pid, temp_pool_slot);
10977
 
  else
10978
 
  {
10979
 
    /* if we run out of slots or we are not using tempool */
10980
 
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
10981
 
            thd->thread_id, thd->tmp_table++);
10982
 
  }
10983
 
 
10984
 
  /*
10985
 
    No need to change table name to lower case as we are only creating
10986
 
    MyISAM or HEAP tables here
10987
 
  */
10988
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
10989
 
 
10990
 
 
10991
 
  if (group)
10992
 
  {
10993
 
    if (!param->quick_group)
10994
 
      group=0;                                  // Can't use group key
10995
 
    else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
10996
 
    {
10997
 
      /*
10998
 
        marker == 4 means two things:
10999
 
        - store NULLs in the key, and
11000
 
        - convert BIT fields to 64-bit long, needed because MEMORY tables
11001
 
          can't index BIT fields.
11002
 
      */
11003
 
      (*tmp->item)->marker= 4;
11004
 
      if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
11005
 
        using_unique_constraint=1;
11006
 
    }
11007
 
    if (param->group_length >= MAX_BLOB_WIDTH)
11008
 
      using_unique_constraint=1;
11009
 
    if (group)
11010
 
      distinct=0;                               // Can't use distinct
11011
 
  }
11012
 
 
11013
 
  field_count=param->field_count+param->func_count+param->sum_func_count;
11014
 
  hidden_field_count=param->hidden_field_count;
11015
 
 
11016
 
  /*
11017
 
    When loose index scan is employed as access method, it already
11018
 
    computes all groups and the result of all aggregate functions. We
11019
 
    make space for the items of the aggregate function in the list of
11020
 
    functions TMP_TABLE_PARAM::items_to_copy, so that the values of
11021
 
    these items are stored in the temporary table.
11022
 
  */
11023
 
  if (param->precomputed_group_by)
11024
 
    copy_func_count+= param->sum_func_count;
11025
 
  
11026
 
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11027
 
 
11028
 
  if (!multi_alloc_root(&own_root,
11029
 
                        &table, sizeof(*table),
11030
 
                        &share, sizeof(*share),
11031
 
                        &reg_field, sizeof(Field*) * (field_count+1),
11032
 
                        &default_field, sizeof(Field*) * (field_count),
11033
 
                        &blob_field, sizeof(uint)*(field_count+1),
11034
 
                        &from_field, sizeof(Field*)*field_count,
11035
 
                        &copy_func, sizeof(*copy_func)*(copy_func_count+1),
11036
 
                        &param->keyinfo, sizeof(*param->keyinfo),
11037
 
                        &key_part_info,
11038
 
                        sizeof(*key_part_info)*(param->group_parts+1),
11039
 
                        &param->start_recinfo,
11040
 
                        sizeof(*param->recinfo)*(field_count*2+4),
11041
 
                        &tmpname, (uint) strlen(path)+1,
11042
 
                        &group_buff, (group && ! using_unique_constraint ?
11043
 
                                      param->group_length : 0),
11044
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
11045
 
                        NullS))
11046
 
  {
11047
 
    if (temp_pool_slot != MY_BIT_NONE)
11048
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11049
 
    return(NULL);                               /* purecov: inspected */
11050
 
  }
11051
 
  /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
11052
 
  if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
11053
 
  {
11054
 
    if (temp_pool_slot != MY_BIT_NONE)
11055
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11056
 
    free_root(&own_root, MYF(0));               /* purecov: inspected */
11057
 
    return(NULL);                               /* purecov: inspected */
11058
 
  }
11059
 
  param->items_to_copy= copy_func;
11060
 
  stpcpy(tmpname,path);
11061
 
  /* make table according to fields */
11062
 
 
11063
 
  memset(table, 0, sizeof(*table));
11064
 
  memset(reg_field, 0, sizeof(Field*)*(field_count+1));
11065
 
  memset(default_field, 0, sizeof(Field*) * (field_count));
11066
 
  memset(from_field, 0, sizeof(Field*)*field_count);
11067
 
 
11068
 
  table->mem_root= own_root;
11069
 
  mem_root_save= thd->mem_root;
11070
 
  thd->mem_root= &table->mem_root;
11071
 
 
11072
 
  table->field=reg_field;
11073
 
  table->alias= table_alias;
11074
 
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
11075
 
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11076
 
  table->map=1;
11077
 
  table->temp_pool_slot = temp_pool_slot;
11078
 
  table->copy_blobs= 1;
11079
 
  table->in_use= thd;
11080
 
  table->quick_keys.init();
11081
 
  table->covering_keys.init();
11082
 
  table->keys_in_use_for_query.init();
11083
 
 
11084
 
  table->setShare(share);
11085
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11086
 
  share->blob_field= blob_field;
11087
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
11088
 
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
11089
 
  share->table_charset= param->table_charset;
11090
 
  share->primary_key= MAX_KEY;               // Indicate no primary key
11091
 
  share->keys_for_keyread.init();
11092
 
  share->keys_in_use.init();
11093
 
 
11094
 
  /* Calculate which type of fields we will store in the temporary table */
11095
 
 
11096
 
  reclength= string_total_length= 0;
11097
 
  blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
11098
 
  param->using_indirect_summary_function=0;
11099
 
 
11100
 
  List_iterator_fast<Item> li(fields);
11101
 
  Item *item;
11102
 
  Field **tmp_from_field=from_field;
11103
 
  while ((item=li++))
11104
 
  {
11105
 
    Item::Type type=item->type();
11106
 
    if (not_all_columns)
11107
 
    {
11108
 
      if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
11109
 
      {
11110
 
        if (item->used_tables() & OUTER_REF_TABLE_BIT)
11111
 
          item->update_used_tables();
11112
 
        if (type == Item::SUBSELECT_ITEM ||
11113
 
            (item->used_tables() & ~OUTER_REF_TABLE_BIT))
11114
 
        {
11115
 
          /*
11116
 
            Mark that the we have ignored an item that refers to a summary
11117
 
            function. We need to know this if someone is going to use
11118
 
            DISTINCT on the result.
11119
 
          */
11120
 
          param->using_indirect_summary_function=1;
11121
 
          continue;
11122
 
        }
11123
 
      }
11124
 
      if (item->const_item() && (int) hidden_field_count <= 0)
11125
 
        continue; // We don't have to store this
11126
 
    }
11127
 
    if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
11128
 
    {                                           /* Can't calc group yet */
11129
 
      ((Item_sum*) item)->result_field=0;
11130
 
      for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++)
11131
 
      {
11132
 
        Item **argp= ((Item_sum*) item)->args + i;
11133
 
        Item *arg= *argp;
11134
 
        if (!arg->const_item())
11135
 
        {
11136
 
          Field *new_field=
11137
 
            create_tmp_field(thd, table, arg, arg->type(), &copy_func,
11138
 
                             tmp_from_field, &default_field[fieldnr],
11139
 
                             group != 0,not_all_columns,
11140
 
                             distinct, 0,
11141
 
                             param->convert_blob_length);
11142
 
          if (!new_field)
11143
 
            goto err;                                   // Should be OOM
11144
 
          tmp_from_field++;
11145
 
          reclength+=new_field->pack_length();
11146
 
          if (new_field->flags & BLOB_FLAG)
11147
 
          {
11148
 
            *blob_field++= fieldnr;
11149
 
            blob_count++;
11150
 
          }
11151
 
          *(reg_field++)= new_field;
11152
 
          if (new_field->real_type() == DRIZZLE_TYPE_VARCHAR)
11153
 
          {
11154
 
            string_count++;
11155
 
            string_total_length+= new_field->pack_length();
11156
 
          }
11157
 
          thd->mem_root= mem_root_save;
11158
 
          thd->change_item_tree(argp, new Item_field(new_field));
11159
 
          thd->mem_root= &table->mem_root;
11160
 
          if (!(new_field->flags & NOT_NULL_FLAG))
11161
 
          {
11162
 
            null_count++;
11163
 
            /*
11164
 
              new_field->maybe_null() is still false, it will be
11165
 
              changed below. But we have to setup Item_field correctly
11166
 
            */
11167
 
            (*argp)->maybe_null=1;
11168
 
          }
11169
 
          new_field->field_index= fieldnr++;
11170
 
        }
11171
 
      }
11172
 
    }
11173
 
    else
11174
 
    {
11175
 
      /*
11176
 
        The last parameter to create_tmp_field() is a bit tricky:
11177
 
 
11178
 
        We need to set it to 0 in union, to get fill_record() to modify the
11179
 
        temporary table.
11180
 
        We need to set it to 1 on multi-table-update and in select to
11181
 
        write rows to the temporary table.
11182
 
        We here distinguish between UNION and multi-table-updates by the fact
11183
 
        that in the later case group is set to the row pointer.
11184
 
      */
11185
 
      Field *new_field= (param->schema_table) ?
11186
 
        create_tmp_field_for_schema(thd, item, table) :
11187
 
        create_tmp_field(thd, table, item, type, &copy_func,
11188
 
                         tmp_from_field, &default_field[fieldnr],
11189
 
                         group != 0,
11190
 
                         !force_copy_fields &&
11191
 
                           (not_all_columns || group !=0),
11192
 
                         /*
11193
 
                           If item->marker == 4 then we force create_tmp_field
11194
 
                           to create a 64-bit longs for BIT fields because HEAP
11195
 
                           tables can't index BIT fields directly. We do the same
11196
 
                           for distinct, as we want the distinct index to be
11197
 
                           usable in this case too.
11198
 
                         */
11199
 
                         item->marker == 4 || param->bit_fields_as_long,
11200
 
                         force_copy_fields,
11201
 
                         param->convert_blob_length);
11202
 
 
11203
 
      if (!new_field)
11204
 
      {
11205
 
        if (thd->is_fatal_error)
11206
 
          goto err;                             // Got OOM
11207
 
        continue;                               // Some kindf of const item
11208
 
      }
11209
 
      if (type == Item::SUM_FUNC_ITEM)
11210
 
        ((Item_sum *) item)->result_field= new_field;
11211
 
      tmp_from_field++;
11212
 
      reclength+=new_field->pack_length();
11213
 
      if (!(new_field->flags & NOT_NULL_FLAG))
11214
 
        null_count++;
11215
 
      if (new_field->flags & BLOB_FLAG)
11216
 
      {
11217
 
        *blob_field++= fieldnr;
11218
 
        blob_count++;
11219
 
      }
11220
 
      if (item->marker == 4 && item->maybe_null)
11221
 
      {
11222
 
        group_null_items++;
11223
 
        new_field->flags|= GROUP_FLAG;
11224
 
      }
11225
 
      new_field->field_index= fieldnr++;
11226
 
      *(reg_field++)= new_field;
11227
 
    }
11228
 
    if (!--hidden_field_count)
11229
 
    {
11230
 
      /*
11231
 
        This was the last hidden field; Remember how many hidden fields could
11232
 
        have null
11233
 
      */
11234
 
      hidden_null_count=null_count;
11235
 
      /*
11236
 
        We need to update hidden_field_count as we may have stored group
11237
 
        functions with constant arguments
11238
 
      */
11239
 
      param->hidden_field_count= fieldnr;
11240
 
      null_count= 0;
11241
 
    }
11242
 
  }
11243
 
  assert(fieldnr == (uint) (reg_field - table->field));
11244
 
  assert(field_count >= (uint) (reg_field - table->field));
11245
 
  field_count= fieldnr;
11246
 
  *reg_field= 0;
11247
 
  *blob_field= 0;                               // End marker
11248
 
  share->fields= field_count;
11249
 
 
11250
 
  /* If result table is small; use a heap */
11251
 
  /* future: storage engine selection can be made dynamic? */
11252
 
  if (blob_count || using_unique_constraint ||
11253
 
      (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
11254
 
      OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
11255
 
  {
11256
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
11257
 
    table->file= get_new_handler(share, &table->mem_root,
11258
 
                                 share->db_type());
11259
 
    if (group &&
11260
 
        (param->group_parts > table->file->max_key_parts() ||
11261
 
         param->group_length > table->file->max_key_length()))
11262
 
      using_unique_constraint=1;
11263
 
  }
11264
 
  else
11265
 
  {
11266
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
11267
 
    table->file= get_new_handler(share, &table->mem_root,
11268
 
                                 share->db_type());
11269
 
  }
11270
 
  if (!table->file)
11271
 
    goto err;
11272
 
 
11273
 
 
11274
 
  if (!using_unique_constraint)
11275
 
    reclength+= group_null_items;       // null flag is stored separately
11276
 
 
11277
 
  share->blob_fields= blob_count;
11278
 
  if (blob_count == 0)
11279
 
  {
11280
 
    /* We need to ensure that first byte is not 0 for the delete link */
11281
 
    if (param->hidden_field_count)
11282
 
      hidden_null_count++;
11283
 
    else
11284
 
      null_count++;
11285
 
  }
11286
 
  hidden_null_pack_length=(hidden_null_count+7)/8;
11287
 
  null_pack_length= (hidden_null_pack_length +
11288
 
                     (null_count + total_uneven_bit_length + 7) / 8);
11289
 
  reclength+=null_pack_length;
11290
 
  if (!reclength)
11291
 
    reclength=1;                                // Dummy select
11292
 
  /* Use packed rows if there is blobs or a lot of space to gain */
11293
 
  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)))
11294
 
    use_packed_rows= 1;
11295
 
 
11296
 
  share->reclength= reclength;
11297
 
  {
11298
 
    uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
11299
 
    share->rec_buff_length= alloc_length;
11300
 
    if (!(table->record[0]= (uchar*)
11301
 
                            alloc_root(&table->mem_root, alloc_length*3)))
11302
 
      goto err;
11303
 
    table->record[1]= table->record[0]+alloc_length;
11304
 
    share->default_values= table->record[1]+alloc_length;
11305
 
  }
11306
 
  copy_func[0]=0;                               // End marker
11307
 
  param->func_count= copy_func - param->items_to_copy; 
11308
 
 
11309
 
  setup_tmp_table_column_bitmaps(table, bitmaps);
11310
 
 
11311
 
  recinfo=param->start_recinfo;
11312
 
  null_flags=(uchar*) table->record[0];
11313
 
  pos=table->record[0]+ null_pack_length;
11314
 
  if (null_pack_length)
11315
 
  {
11316
 
    memset(recinfo, 0, sizeof(*recinfo));
11317
 
    recinfo->type=FIELD_NORMAL;
11318
 
    recinfo->length=null_pack_length;
11319
 
    recinfo++;
11320
 
    memset(null_flags, 255, null_pack_length);  // Set null fields
11321
 
 
11322
 
    table->null_flags= (uchar*) table->record[0];
11323
 
    share->null_fields= null_count+ hidden_null_count;
11324
 
    share->null_bytes= null_pack_length;
11325
 
  }
11326
 
  null_count= (blob_count == 0) ? 1 : 0;
11327
 
  hidden_field_count=param->hidden_field_count;
11328
 
  for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
11329
 
  {
11330
 
    Field *field= *reg_field;
11331
 
    uint length;
11332
 
    memset(recinfo, 0, sizeof(*recinfo));
11333
 
 
11334
 
    if (!(field->flags & NOT_NULL_FLAG))
11335
 
    {
11336
 
      if (field->flags & GROUP_FLAG && !using_unique_constraint)
11337
 
      {
11338
 
        /*
11339
 
          We have to reserve one byte here for NULL bits,
11340
 
          as this is updated by 'end_update()'
11341
 
        */
11342
 
        *pos++=0;                               // Null is stored here
11343
 
        recinfo->length=1;
11344
 
        recinfo->type=FIELD_NORMAL;
11345
 
        recinfo++;
11346
 
        memset(recinfo, 0, sizeof(*recinfo));
11347
 
      }
11348
 
      else
11349
 
      {
11350
 
        recinfo->null_bit= 1 << (null_count & 7);
11351
 
        recinfo->null_pos= null_count/8;
11352
 
      }
11353
 
      field->move_field(pos,null_flags+null_count/8,
11354
 
                        1 << (null_count & 7));
11355
 
      null_count++;
11356
 
    }
11357
 
    else
11358
 
      field->move_field(pos,(uchar*) 0,0);
11359
 
    field->reset();
11360
 
 
11361
 
    /*
11362
 
      Test if there is a default field value. The test for ->ptr is to skip
11363
 
      'offset' fields generated by initalize_tables
11364
 
    */
11365
 
    if (default_field[i] && default_field[i]->ptr)
11366
 
    {
11367
 
      /* 
11368
 
         default_field[i] is set only in the cases  when 'field' can
11369
 
         inherit the default value that is defined for the field referred
11370
 
         by the Item_field object from which 'field' has been created.
11371
 
      */
11372
 
      my_ptrdiff_t diff;
11373
 
      Field *orig_field= default_field[i];
11374
 
      /* Get the value from default_values */
11375
 
      diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
11376
 
                            orig_field->table->record[0]);
11377
 
      orig_field->move_field_offset(diff);      // Points now at default_values
11378
 
      if (orig_field->is_real_null())
11379
 
        field->set_null();
11380
 
      else
11381
 
      {
11382
 
        field->set_notnull();
11383
 
        memcpy(field->ptr, orig_field->ptr, field->pack_length());
11384
 
      }
11385
 
      orig_field->move_field_offset(-diff);     // Back to record[0]
11386
 
    } 
11387
 
 
11388
 
    if (from_field[i])
11389
 
    {                                           /* Not a table Item */
11390
 
      copy->set(field,from_field[i],save_sum_fields);
11391
 
      copy++;
11392
 
    }
11393
 
    length=field->pack_length();
11394
 
    pos+= length;
11395
 
 
11396
 
    /* Make entry for create table */
11397
 
    recinfo->length=length;
11398
 
    if (field->flags & BLOB_FLAG)
11399
 
      recinfo->type= (int) FIELD_BLOB;
11400
 
    else
11401
 
      recinfo->type=FIELD_NORMAL;
11402
 
    if (!--hidden_field_count)
11403
 
      null_count=(null_count+7) & ~7;           // move to next byte
11404
 
 
11405
 
    // fix table name in field entry
11406
 
    field->table_name= &table->alias;
11407
 
  }
11408
 
 
11409
 
  param->copy_field_end=copy;
11410
 
  param->recinfo=recinfo;
11411
 
  store_record(table,s->default_values);        // Make empty default record
11412
 
 
11413
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
11414
 
    share->max_rows= ~(ha_rows) 0;
11415
 
  else
11416
 
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11417
 
                                 min(thd->variables.tmp_table_size,
11418
 
                                     thd->variables.max_heap_table_size) :
11419
 
                                 thd->variables.tmp_table_size) /
11420
 
                                 share->reclength);
11421
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
11422
 
  /*
11423
 
    Push the LIMIT clause to the temporary table creation, so that we
11424
 
    materialize only up to 'rows_limit' records instead of all result records.
11425
 
  */
11426
 
  set_if_smaller(share->max_rows, rows_limit);
11427
 
  param->end_write_records= rows_limit;
11428
 
 
11429
 
  keyinfo= param->keyinfo;
11430
 
 
11431
 
  if (group)
11432
 
  {
11433
 
    table->group=group;                         /* Table is grouped by key */
11434
 
    param->group_buff=group_buff;
11435
 
    share->keys=1;
11436
 
    share->uniques= test(using_unique_constraint);
11437
 
    table->key_info=keyinfo;
11438
 
    keyinfo->key_part=key_part_info;
11439
 
    keyinfo->flags=HA_NOSAME;
11440
 
    keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
11441
 
    keyinfo->key_length=0;
11442
 
    keyinfo->rec_per_key=0;
11443
 
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11444
 
    keyinfo->name= (char*) "group_key";
11445
 
    ORDER *cur_group= group;
11446
 
    for (; cur_group ; cur_group= cur_group->next, key_part_info++)
11447
 
    {
11448
 
      Field *field=(*cur_group->item)->get_tmp_table_field();
11449
 
      bool maybe_null=(*cur_group->item)->maybe_null;
11450
 
      key_part_info->null_bit=0;
11451
 
      key_part_info->field=  field;
11452
 
      key_part_info->offset= field->offset(table->record[0]);
11453
 
      key_part_info->length= (uint16_t) field->key_length();
11454
 
      key_part_info->type=   (uint8_t) field->key_type();
11455
 
      key_part_info->key_type =
11456
 
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11457
 
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11458
 
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11459
 
        0 : FIELDFLAG_BINARY;
11460
 
      if (!using_unique_constraint)
11461
 
      {
11462
 
        cur_group->buff=(char*) group_buff;
11463
 
        if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
11464
 
                                                     group_buff +
11465
 
                                                     test(maybe_null),
11466
 
                                                     field->null_ptr,
11467
 
                                                     field->null_bit)))
11468
 
          goto err; /* purecov: inspected */
11469
 
        if (maybe_null)
11470
 
        {
11471
 
          /*
11472
 
            To be able to group on NULL, we reserved place in group_buff
11473
 
            for the NULL flag just before the column. (see above).
11474
 
            The field data is after this flag.
11475
 
            The NULL flag is updated in 'end_update()' and 'end_write()'
11476
 
          */
11477
 
          keyinfo->flags|= HA_NULL_ARE_EQUAL;   // def. that NULL == NULL
11478
 
          key_part_info->null_bit=field->null_bit;
11479
 
          key_part_info->null_offset= (uint) (field->null_ptr -
11480
 
                                              (uchar*) table->record[0]);
11481
 
          cur_group->buff++;                        // Pointer to field data
11482
 
          group_buff++;                         // Skipp null flag
11483
 
        }
11484
 
        /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
11485
 
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
11486
 
        group_buff+= cur_group->field->pack_length();
11487
 
      }
11488
 
      keyinfo->key_length+=  key_part_info->length;
11489
 
    }
11490
 
  }
11491
 
 
11492
 
  if (distinct && field_count != param->hidden_field_count)
11493
 
  {
11494
 
    /*
11495
 
      Create an unique key or an unique constraint over all columns
11496
 
      that should be in the result.  In the temporary table, there are
11497
 
      'param->hidden_field_count' extra columns, whose null bits are stored
11498
 
      in the first 'hidden_null_pack_length' bytes of the row.
11499
 
    */
11500
 
    if (blob_count)
11501
 
    {
11502
 
      /*
11503
 
        Special mode for index creation in MyISAM used to support unique
11504
 
        indexes on blobs with arbitrary length. Such indexes cannot be
11505
 
        used for lookups.
11506
 
      */
11507
 
      share->uniques= 1;
11508
 
    }
11509
 
    null_pack_length-=hidden_null_pack_length;
11510
 
    keyinfo->key_parts= ((field_count-param->hidden_field_count)+
11511
 
                         (share->uniques ? test(null_pack_length) : 0));
11512
 
    table->distinct= 1;
11513
 
    share->keys= 1;
11514
 
    if (!(key_part_info= (KEY_PART_INFO*)
11515
 
          alloc_root(&table->mem_root,
11516
 
                     keyinfo->key_parts * sizeof(KEY_PART_INFO))))
11517
 
      goto err;
11518
 
    memset(key_part_info, 0, keyinfo->key_parts * sizeof(KEY_PART_INFO));
11519
 
    table->key_info=keyinfo;
11520
 
    keyinfo->key_part=key_part_info;
11521
 
    keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
11522
 
    keyinfo->key_length=(uint16_t) reclength;
11523
 
    keyinfo->name= (char*) "distinct_key";
11524
 
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11525
 
    keyinfo->rec_per_key=0;
11526
 
 
11527
 
    /*
11528
 
      Create an extra field to hold NULL bits so that unique indexes on
11529
 
      blobs can distinguish NULL from 0. This extra field is not needed
11530
 
      when we do not use UNIQUE indexes for blobs.
11531
 
    */
11532
 
    if (null_pack_length && share->uniques)
11533
 
    {
11534
 
      key_part_info->null_bit=0;
11535
 
      key_part_info->offset=hidden_null_pack_length;
11536
 
      key_part_info->length=null_pack_length;
11537
 
      key_part_info->field= new Field_varstring(table->record[0],
11538
 
                                                (uint32_t) key_part_info->length,
11539
 
                                                0,
11540
 
                                                (uchar*) 0,
11541
 
                                                (uint) 0,
11542
 
                                                Field::NONE,
11543
 
                                                NullS, 
11544
 
                                                table->s,
11545
 
                                                &my_charset_bin);
11546
 
      if (!key_part_info->field)
11547
 
        goto err;
11548
 
      key_part_info->field->init(table);
11549
 
      key_part_info->key_type=FIELDFLAG_BINARY;
11550
 
      key_part_info->type=    HA_KEYTYPE_BINARY;
11551
 
      key_part_info++;
11552
 
    }
11553
 
    /* Create a distinct key over the columns we are going to return */
11554
 
    for (i=param->hidden_field_count, reg_field=table->field + i ;
11555
 
         i < field_count;
11556
 
         i++, reg_field++, key_part_info++)
11557
 
    {
11558
 
      key_part_info->null_bit=0;
11559
 
      key_part_info->field=    *reg_field;
11560
 
      key_part_info->offset=   (*reg_field)->offset(table->record[0]);
11561
 
      key_part_info->length=   (uint16_t) (*reg_field)->pack_length();
11562
 
      /* TODO:
11563
 
        The below method of computing the key format length of the
11564
 
        key part is a copy/paste from opt_range.cc, and table.cc.
11565
 
        This should be factored out, e.g. as a method of Field.
11566
 
        In addition it is not clear if any of the Field::*_length
11567
 
        methods is supposed to compute the same length. If so, it
11568
 
        might be reused.
11569
 
      */
11570
 
      key_part_info->store_length= key_part_info->length;
11571
 
 
11572
 
      if ((*reg_field)->real_maybe_null())
11573
 
        key_part_info->store_length+= HA_KEY_NULL_LENGTH;
11574
 
      if ((*reg_field)->type() == DRIZZLE_TYPE_BLOB || 
11575
 
          (*reg_field)->real_type() == DRIZZLE_TYPE_VARCHAR)
11576
 
        key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
11577
 
 
11578
 
      key_part_info->type=     (uint8_t) (*reg_field)->key_type();
11579
 
      key_part_info->key_type =
11580
 
        ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
11581
 
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
11582
 
         (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
11583
 
        0 : FIELDFLAG_BINARY;
11584
 
    }
11585
 
  }
11586
 
 
11587
 
  if (thd->is_fatal_error)                              // If end of memory
11588
 
    goto err;                                    /* purecov: inspected */
11589
 
  share->db_record_offset= 1;
11590
 
  if (share->db_type() == myisam_hton)
11591
 
  {
11592
 
    if (create_myisam_tmp_table(table, param->keyinfo, param->start_recinfo,
11593
 
                                &param->recinfo, select_options))
11594
 
      goto err;
11595
 
  }
11596
 
  if (open_tmp_table(table))
11597
 
    goto err;
11598
 
 
11599
 
  thd->mem_root= mem_root_save;
11600
 
 
11601
 
  return(table);
11602
 
 
11603
 
err:
11604
 
  thd->mem_root= mem_root_save;
11605
 
  free_tmp_table(thd,table);                    /* purecov: inspected */
11606
 
  if (temp_pool_slot != MY_BIT_NONE)
11607
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11608
 
  return(NULL);                         /* purecov: inspected */
11609
 
}
11610
 
 
11611
 
 
11612
 
 
11613
 
 
11614
 
/*
11615
 
  Create a temporary table to weed out duplicate rowid combinations
11616
 
 
11617
 
  SYNOPSIS
11618
 
 
11619
 
    create_duplicate_weedout_tmp_table()
11620
 
      thd
11621
 
      uniq_tuple_length_arg
11622
 
      SJ_TMP_TABLE 
11623
 
 
11624
 
  DESCRIPTION
11625
 
    Create a temporary table to weed out duplicate rowid combinations. The
11626
 
    table has a single column that is a concatenation of all rowids in the
11627
 
    combination. 
11628
 
 
11629
 
    Depending on the needed length, there are two cases:
11630
 
 
11631
 
    1. When the length of the column < max_key_length:
11632
 
 
11633
 
      CREATE TABLE tmp (col VARBINARY(n) NOT NULL, UNIQUE KEY(col));
11634
 
 
11635
 
    2. Otherwise (not a valid SQL syntax but internally supported):
11636
 
 
11637
 
      CREATE TABLE tmp (col VARBINARY NOT NULL, UNIQUE CONSTRAINT(col));
11638
 
 
11639
 
    The code in this function was produced by extraction of relevant parts
11640
 
    from create_tmp_table().
11641
 
 
11642
 
  RETURN
11643
 
    created table
11644
 
    NULL on error
11645
 
*/
11646
 
 
11647
 
TABLE *create_duplicate_weedout_tmp_table(THD *thd, 
11648
 
                                          uint uniq_tuple_length_arg,
11649
 
                                          SJ_TMP_TABLE *sjtbl)
11650
 
{
11651
 
  MEM_ROOT *mem_root_save, own_root;
11652
 
  TABLE *table;
11653
 
  TABLE_SHARE *share;
11654
 
  uint  temp_pool_slot=MY_BIT_NONE;
11655
 
  char  *tmpname,path[FN_REFLEN];
11656
 
  Field **reg_field;
11657
 
  KEY_PART_INFO *key_part_info;
11658
 
  KEY *keyinfo;
11659
 
  uchar *group_buff;
11660
 
  uchar *bitmaps;
11661
 
  uint *blob_field;
11662
 
  MI_COLUMNDEF *recinfo, *start_recinfo;
11663
 
  bool using_unique_constraint=false;
11664
 
  Field *field, *key_field;
11665
 
  uint blob_count, null_pack_length, null_count;
11666
 
  uchar *null_flags;
11667
 
  uchar *pos;
11668
 
  
11669
 
  /*
11670
 
    STEP 1: Get temporary table name
11671
 
  */
11672
 
  statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
11673
 
  if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
11674
 
    temp_pool_slot = bitmap_lock_set_next(&temp_pool);
11675
 
 
11676
 
  if (temp_pool_slot != MY_BIT_NONE) // we got a slot
11677
 
    sprintf(path, "%s_%lx_%i", tmp_file_prefix,
11678
 
            current_pid, temp_pool_slot);
11679
 
  else
11680
 
  {
11681
 
    /* if we run out of slots or we are not using tempool */
11682
 
    sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
11683
 
            thd->thread_id, thd->tmp_table++);
11684
 
  }
11685
 
  fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
11686
 
 
11687
 
  /* STEP 2: Figure if we'll be using a key or blob+constraint */
11688
 
  if (uniq_tuple_length_arg >= CONVERT_IF_BIGGER_TO_BLOB)
11689
 
    using_unique_constraint= true;
11690
 
 
11691
 
  /* STEP 3: Allocate memory for temptable description */
11692
 
  init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
11693
 
  if (!multi_alloc_root(&own_root,
11694
 
                        &table, sizeof(*table),
11695
 
                        &share, sizeof(*share),
11696
 
                        &reg_field, sizeof(Field*) * (1+1),
11697
 
                        &blob_field, sizeof(uint)*2,
11698
 
                        &keyinfo, sizeof(*keyinfo),
11699
 
                        &key_part_info, sizeof(*key_part_info) * 2,
11700
 
                        &start_recinfo,
11701
 
                        sizeof(*recinfo)*(1*2+4),
11702
 
                        &tmpname, (uint) strlen(path)+1,
11703
 
                        &group_buff, (!using_unique_constraint ?
11704
 
                                      uniq_tuple_length_arg : 0),
11705
 
                        &bitmaps, bitmap_buffer_size(1)*2,
11706
 
                        NullS))
11707
 
  {
11708
 
    if (temp_pool_slot != MY_BIT_NONE)
11709
 
      bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11710
 
    return(NULL);
11711
 
  }
11712
 
  stpcpy(tmpname,path);
11713
 
  
11714
 
 
11715
 
  /* STEP 4: Create TABLE description */
11716
 
  memset(table, 0, sizeof(*table));
11717
 
  memset(reg_field, 0, sizeof(Field*)*2);
11718
 
 
11719
 
  table->mem_root= own_root;
11720
 
  mem_root_save= thd->mem_root;
11721
 
  thd->mem_root= &table->mem_root;
11722
 
 
11723
 
  table->field=reg_field;
11724
 
  table->alias= "weedout-tmp";
11725
 
  table->reginfo.lock_type=TL_WRITE;    /* Will be updated */
11726
 
  table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
11727
 
  table->map=1;
11728
 
  table->temp_pool_slot = temp_pool_slot;
11729
 
  table->copy_blobs= 1;
11730
 
  table->in_use= thd;
11731
 
  table->quick_keys.init();
11732
 
  table->covering_keys.init();
11733
 
  table->keys_in_use_for_query.init();
11734
 
 
11735
 
  table->s= share;
11736
 
  init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
11737
 
  share->blob_field= blob_field;
11738
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
11739
 
  share->db_low_byte_first=1;                // True for HEAP and MyISAM
11740
 
  share->table_charset= NULL;
11741
 
  share->primary_key= MAX_KEY;               // Indicate no primary key
11742
 
  share->keys_for_keyread.init();
11743
 
  share->keys_in_use.init();
11744
 
 
11745
 
  blob_count= 0;
11746
 
 
11747
 
  /* Create the field */
11748
 
  {
11749
 
    /*
11750
 
      For the sake of uniformity, always use Field_varstring.
11751
 
    */
11752
 
    field= new Field_varstring(uniq_tuple_length_arg, false, "rowids", share,
11753
 
                               &my_charset_bin);
11754
 
    if (!field)
11755
 
      return(0);
11756
 
    field->table= table;
11757
 
    field->key_start.init(0);
11758
 
    field->part_of_key.init(0);
11759
 
    field->part_of_sortkey.init(0);
11760
 
    field->unireg_check= Field::NONE;
11761
 
    field->flags= (NOT_NULL_FLAG | BINARY_FLAG | NO_DEFAULT_VALUE_FLAG);
11762
 
    field->reset_fields();
11763
 
    field->init(table);
11764
 
    field->orig_table= NULL;
11765
 
     
11766
 
    field->field_index= 0;
11767
 
    
11768
 
    *(reg_field++)= field;
11769
 
    *blob_field= 0;
11770
 
    *reg_field= 0;
11771
 
 
11772
 
    share->fields= 1;
11773
 
    share->blob_fields= 0;
11774
 
  }
11775
 
 
11776
 
  uint reclength= field->pack_length();
11777
 
  if (using_unique_constraint)
11778
 
  { 
11779
 
    share->db_plugin= ha_lock_engine(0, myisam_hton);
11780
 
    table->file= get_new_handler(share, &table->mem_root,
11781
 
                                 share->db_type());
11782
 
    assert(uniq_tuple_length_arg <= table->file->max_key_length());
11783
 
  }
11784
 
  else
11785
 
  {
11786
 
    share->db_plugin= ha_lock_engine(0, heap_hton);
11787
 
    table->file= get_new_handler(share, &table->mem_root,
11788
 
                                 share->db_type());
11789
 
  }
11790
 
  if (!table->file)
11791
 
    goto err;
11792
 
 
11793
 
  null_count=1;
11794
 
  
11795
 
  null_pack_length= 1;
11796
 
  reclength += null_pack_length;
11797
 
 
11798
 
  share->reclength= reclength;
11799
 
  {
11800
 
    uint alloc_length=ALIGN_SIZE(share->reclength + MI_UNIQUE_HASH_LENGTH+1);
11801
 
    share->rec_buff_length= alloc_length;
11802
 
    if (!(table->record[0]= (uchar*)
11803
 
                            alloc_root(&table->mem_root, alloc_length*3)))
11804
 
      goto err;
11805
 
    table->record[1]= table->record[0]+alloc_length;
11806
 
    share->default_values= table->record[1]+alloc_length;
11807
 
  }
11808
 
  setup_tmp_table_column_bitmaps(table, bitmaps);
11809
 
 
11810
 
  recinfo= start_recinfo;
11811
 
  null_flags=(uchar*) table->record[0];
11812
 
  pos=table->record[0]+ null_pack_length;
11813
 
  if (null_pack_length)
11814
 
  {
11815
 
    memset(recinfo, 0, sizeof(*recinfo));
11816
 
    recinfo->type=FIELD_NORMAL;
11817
 
    recinfo->length=null_pack_length;
11818
 
    recinfo++;
11819
 
    memset(null_flags, 255, null_pack_length);  // Set null fields
11820
 
 
11821
 
    table->null_flags= (uchar*) table->record[0];
11822
 
    share->null_fields= null_count;
11823
 
    share->null_bytes= null_pack_length;
11824
 
  }
11825
 
  null_count=1;
11826
 
 
11827
 
  {
11828
 
    //Field *field= *reg_field;
11829
 
    uint length;
11830
 
    memset(recinfo, 0, sizeof(*recinfo));
11831
 
    field->move_field(pos,(uchar*) 0,0);
11832
 
 
11833
 
    field->reset();
11834
 
    /*
11835
 
      Test if there is a default field value. The test for ->ptr is to skip
11836
 
      'offset' fields generated by initalize_tables
11837
 
    */
11838
 
    // Initialize the table field:
11839
 
    memset(field->ptr, 0, field->pack_length());
11840
 
 
11841
 
    length=field->pack_length();
11842
 
    pos+= length;
11843
 
 
11844
 
    /* Make entry for create table */
11845
 
    recinfo->length=length;
11846
 
    if (field->flags & BLOB_FLAG)
11847
 
      recinfo->type= (int) FIELD_BLOB;
11848
 
    else
11849
 
      recinfo->type=FIELD_NORMAL;
11850
 
 
11851
 
    field->table_name= &table->alias;
11852
 
  }
11853
 
 
11854
 
  //param->recinfo=recinfo;
11855
 
  //store_record(table,s->default_values);        // Make empty default record
11856
 
 
11857
 
  if (thd->variables.tmp_table_size == ~ (uint64_t) 0)          // No limit
11858
 
    share->max_rows= ~(ha_rows) 0;
11859
 
  else
11860
 
    share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
11861
 
                                 min(thd->variables.tmp_table_size,
11862
 
                                     thd->variables.max_heap_table_size) :
11863
 
                                 thd->variables.tmp_table_size) /
11864
 
                                 share->reclength);
11865
 
  set_if_bigger(share->max_rows,1);             // For dummy start options
11866
 
 
11867
 
 
11868
 
  //// keyinfo= param->keyinfo;
11869
 
  if (true)
11870
 
  {
11871
 
    share->keys=1;
11872
 
    share->uniques= test(using_unique_constraint);
11873
 
    table->key_info=keyinfo;
11874
 
    keyinfo->key_part=key_part_info;
11875
 
    keyinfo->flags=HA_NOSAME;
11876
 
    keyinfo->usable_key_parts= keyinfo->key_parts= 1;
11877
 
    keyinfo->key_length=0;
11878
 
    keyinfo->rec_per_key=0;
11879
 
    keyinfo->algorithm= HA_KEY_ALG_UNDEF;
11880
 
    keyinfo->name= (char*) "weedout_key";
11881
 
    {
11882
 
      key_part_info->null_bit=0;
11883
 
      key_part_info->field=  field;
11884
 
      key_part_info->offset= field->offset(table->record[0]);
11885
 
      key_part_info->length= (uint16_t) field->key_length();
11886
 
      key_part_info->type=   (uint8_t) field->key_type();
11887
 
      key_part_info->key_type = FIELDFLAG_BINARY;
11888
 
      if (!using_unique_constraint)
11889
 
      {
11890
 
        if (!(key_field= field->new_key_field(thd->mem_root, table,
11891
 
                                              group_buff,
11892
 
                                              field->null_ptr,
11893
 
                                              field->null_bit)))
11894
 
          goto err;
11895
 
        key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; //todo need this?
11896
 
      }
11897
 
      keyinfo->key_length+=  key_part_info->length;
11898
 
    }
11899
 
  }
11900
 
 
11901
 
  if (thd->is_fatal_error)                              // If end of memory
11902
 
    goto err;
11903
 
  share->db_record_offset= 1;
11904
 
  if (share->db_type() == myisam_hton)
11905
 
  {
11906
 
    recinfo++;
11907
 
    if (create_myisam_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0))
11908
 
      goto err;
11909
 
  }
11910
 
  sjtbl->start_recinfo= start_recinfo;
11911
 
  sjtbl->recinfo=       recinfo;
11912
 
  if (open_tmp_table(table))
11913
 
    goto err;
11914
 
 
11915
 
  thd->mem_root= mem_root_save;
11916
 
  return(table);
11917
 
 
11918
 
err:
11919
 
  thd->mem_root= mem_root_save;
11920
 
  free_tmp_table(thd,table);                    /* purecov: inspected */
11921
 
  if (temp_pool_slot != MY_BIT_NONE)
11922
 
    bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
11923
 
  return(NULL);                         /* purecov: inspected */
11924
 
}
11925
 
 
11926
 
/****************************************************************************/
11927
 
 
11928
 
/**
11929
 
  Create a reduced TABLE object with properly set up Field list from a
11930
 
  list of field definitions.
11931
 
 
11932
 
    The created table doesn't have a table handler associated with
11933
 
    it, has no keys, no group/distinct, no copy_funcs array.
11934
 
    The sole purpose of this TABLE object is to use the power of Field
11935
 
    class to read/write data to/from table->record[0]. Then one can store
11936
 
    the record in any container (RB tree, hash, etc).
11937
 
    The table is created in THD mem_root, so are the table's fields.
11938
 
    Consequently, if you don't BLOB fields, you don't need to free it.
11939
 
 
11940
 
  @param thd         connection handle
11941
 
  @param field_list  list of column definitions
11942
 
 
11943
 
  @return
11944
 
    0 if out of memory, TABLE object in case of success
11945
 
*/
11946
 
 
11947
 
TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
11948
 
{
11949
 
  uint field_count= field_list.elements;
11950
 
  uint blob_count= 0;
11951
 
  Field **field;
11952
 
  Create_field *cdef;                           /* column definition */
11953
 
  uint record_length= 0;
11954
 
  uint null_count= 0;                 /* number of columns which may be null */
11955
 
  uint null_pack_length;              /* NULL representation array length */
11956
 
  uint *blob_field;
11957
 
  uchar *bitmaps;
11958
 
  TABLE *table;
11959
 
  TABLE_SHARE *share;
11960
 
 
11961
 
  if (!multi_alloc_root(thd->mem_root,
11962
 
                        &table, sizeof(*table),
11963
 
                        &share, sizeof(*share),
11964
 
                        &field, (field_count + 1) * sizeof(Field*),
11965
 
                        &blob_field, (field_count+1) *sizeof(uint),
11966
 
                        &bitmaps, bitmap_buffer_size(field_count)*2,
11967
 
                        NullS))
11968
 
    return 0;
11969
 
 
11970
 
  memset(table, 0, sizeof(*table));
11971
 
  memset(share, 0, sizeof(*share));
11972
 
  table->field= field;
11973
 
  table->s= share;
11974
 
  share->blob_field= blob_field;
11975
 
  share->fields= field_count;
11976
 
  share->blob_ptr_size= portable_sizeof_char_ptr;
11977
 
  setup_tmp_table_column_bitmaps(table, bitmaps);
11978
 
 
11979
 
  /* Create all fields and calculate the total length of record */
11980
 
  List_iterator_fast<Create_field> it(field_list);
11981
 
  while ((cdef= it++))
11982
 
  {
11983
 
    *field= make_field(share, 0, cdef->length,
11984
 
                       (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
11985
 
                       f_maybe_null(cdef->pack_flag) ? 1 : 0,
11986
 
                       cdef->pack_flag, cdef->sql_type, cdef->charset,
11987
 
                       cdef->unireg_check,
11988
 
                       cdef->interval, cdef->field_name);
11989
 
    if (!*field)
11990
 
      goto error;
11991
 
    (*field)->init(table);
11992
 
    record_length+= (*field)->pack_length();
11993
 
    if (! ((*field)->flags & NOT_NULL_FLAG))
11994
 
      null_count++;
11995
 
 
11996
 
    if ((*field)->flags & BLOB_FLAG)
11997
 
      share->blob_field[blob_count++]= (uint) (field - table->field);
11998
 
 
11999
 
    field++;
12000
 
  }
12001
 
  *field= NULL;                             /* mark the end of the list */
12002
 
  share->blob_field[blob_count]= 0;            /* mark the end of the list */
12003
 
  share->blob_fields= blob_count;
12004
 
 
12005
 
  null_pack_length= (null_count + 7)/8;
12006
 
  share->reclength= record_length + null_pack_length;
12007
 
  share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
12008
 
  table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
12009
 
  if (!table->record[0])
12010
 
    goto error;
12011
 
 
12012
 
  if (null_pack_length)
12013
 
  {
12014
 
    table->null_flags= (uchar*) table->record[0];
12015
 
    share->null_fields= null_count;
12016
 
    share->null_bytes= null_pack_length;
12017
 
  }
12018
 
 
12019
 
  table->in_use= thd;           /* field->reset() may access table->in_use */
12020
 
  {
12021
 
    /* Set up field pointers */
12022
 
    uchar *null_pos= table->record[0];
12023
 
    uchar *field_pos= null_pos + share->null_bytes;
12024
 
    uint null_bit= 1;
12025
 
 
12026
 
    for (field= table->field; *field; ++field)
12027
 
    {
12028
 
      Field *cur_field= *field;
12029
 
      if ((cur_field->flags & NOT_NULL_FLAG))
12030
 
        cur_field->move_field(field_pos);
12031
 
      else
12032
 
      {
12033
 
        cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
12034
 
        null_bit<<= 1;
12035
 
        if (null_bit == (1 << 8))
12036
 
        {
12037
 
          ++null_pos;
12038
 
          null_bit= 1;
12039
 
        }
12040
 
      }
12041
 
      cur_field->reset();
12042
 
 
12043
 
      field_pos+= cur_field->pack_length();
12044
 
    }
12045
 
  }
12046
 
  return table;
12047
 
error:
12048
 
  for (field= table->field; *field; ++field)
12049
 
    delete *field;                         /* just invokes field destructor */
12050
 
  return 0;
12051
 
}
12052
 
 
12053
 
 
12054
 
static bool open_tmp_table(TABLE *table)
12055
 
{
12056
 
  int error;
12057
 
  if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
12058
 
                                  HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
12059
 
  {
12060
 
    table->file->print_error(error,MYF(0)); /* purecov: inspected */
12061
 
    table->db_stat=0;
12062
 
    return(1);
12063
 
  }
12064
 
  (void) table->file->extra(HA_EXTRA_QUICK);            /* Faster */
12065
 
  return(0);
12066
 
}
12067
 
 
12068
 
 
12069
 
/*
12070
 
  Create MyISAM temporary table
12071
 
 
12072
 
  SYNOPSIS
12073
 
    create_myisam_tmp_table()
12074
 
      table           Table object that descrimes the table to be created
12075
 
      keyinfo         Description of the index (there is always one index)
12076
 
      start_recinfo   MyISAM's column descriptions
12077
 
      recinfo INOUT   End of MyISAM's column descriptions
12078
 
      options         Option bits
12079
 
   
12080
 
  DESCRIPTION
12081
 
    Create a MyISAM temporary table according to passed description. The is
12082
 
    assumed to have one unique index or constraint.
12083
 
 
12084
 
    The passed array or MI_COLUMNDEF structures must have this form:
12085
 
 
12086
 
      1. 1-byte column (afaiu for 'deleted' flag) (note maybe not 1-byte
12087
 
         when there are many nullable columns)
12088
 
      2. Table columns
12089
 
      3. One free MI_COLUMNDEF element (*recinfo points here)
12090
 
   
12091
 
    This function may use the free element to create hash column for unique
12092
 
    constraint.
12093
 
 
12094
 
   RETURN
12095
 
     false - OK
12096
 
     true  - Error
12097
 
*/
12098
 
 
12099
 
static bool create_myisam_tmp_table(TABLE *table, KEY *keyinfo, 
12100
 
                                    MI_COLUMNDEF *start_recinfo,
12101
 
                                    MI_COLUMNDEF **recinfo, 
12102
 
                                    uint64_t options)
12103
 
{
12104
 
  int error;
12105
 
  MI_KEYDEF keydef;
12106
 
  MI_UNIQUEDEF uniquedef;
12107
 
  TABLE_SHARE *share= table->s;
12108
 
 
12109
 
  if (share->keys)
12110
 
  {                                             // Get keys for ni_create
12111
 
    bool using_unique_constraint=0;
12112
 
    HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
12113
 
                                            sizeof(*seg) * keyinfo->key_parts);
12114
 
    if (!seg)
12115
 
      goto err;
12116
 
 
12117
 
    memset(seg, 0, sizeof(*seg) * keyinfo->key_parts);
12118
 
    if (keyinfo->key_length >= table->file->max_key_length() ||
12119
 
        keyinfo->key_parts > table->file->max_key_parts() ||
12120
 
        share->uniques)
12121
 
    {
12122
 
      /* Can't create a key; Make a unique constraint instead of a key */
12123
 
      share->keys=    0;
12124
 
      share->uniques= 1;
12125
 
      using_unique_constraint=1;
12126
 
      memset(&uniquedef, 0, sizeof(uniquedef));
12127
 
      uniquedef.keysegs=keyinfo->key_parts;
12128
 
      uniquedef.seg=seg;
12129
 
      uniquedef.null_are_equal=1;
12130
 
 
12131
 
      /* Create extra column for hash value */
12132
 
      memset(*recinfo, 0, sizeof(**recinfo));
12133
 
      (*recinfo)->type= FIELD_CHECK;
12134
 
      (*recinfo)->length=MI_UNIQUE_HASH_LENGTH;
12135
 
      (*recinfo)++;
12136
 
      share->reclength+=MI_UNIQUE_HASH_LENGTH;
12137
 
    }
12138
 
    else
12139
 
    {
12140
 
      /* Create an unique key */
12141
 
      memset(&keydef, 0, sizeof(keydef));
12142
 
      keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
12143
 
      keydef.keysegs=  keyinfo->key_parts;
12144
 
      keydef.seg= seg;
12145
 
    }
12146
 
    for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
12147
 
    {
12148
 
      Field *field=keyinfo->key_part[i].field;
12149
 
      seg->flag=     0;
12150
 
      seg->language= field->charset()->number;
12151
 
      seg->length=   keyinfo->key_part[i].length;
12152
 
      seg->start=    keyinfo->key_part[i].offset;
12153
 
      if (field->flags & BLOB_FLAG)
12154
 
      {
12155
 
        seg->type=
12156
 
        ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
12157
 
         HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
12158
 
        seg->bit_start= (uint8_t)(field->pack_length() - share->blob_ptr_size);
12159
 
        seg->flag= HA_BLOB_PART;
12160
 
        seg->length=0;                  // Whole blob in unique constraint
12161
 
      }
12162
 
      else
12163
 
      {
12164
 
        seg->type= keyinfo->key_part[i].type;
12165
 
      }
12166
 
      if (!(field->flags & NOT_NULL_FLAG))
12167
 
      {
12168
 
        seg->null_bit= field->null_bit;
12169
 
        seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
12170
 
        /*
12171
 
          We are using a GROUP BY on something that contains NULL
12172
 
          In this case we have to tell MyISAM that two NULL should
12173
 
          on INSERT be regarded at the same value
12174
 
        */
12175
 
        if (!using_unique_constraint)
12176
 
          keydef.flag|= HA_NULL_ARE_EQUAL;
12177
 
      }
12178
 
    }
12179
 
  }
12180
 
  MI_CREATE_INFO create_info;
12181
 
  memset(&create_info, 0, sizeof(create_info));
12182
 
 
12183
 
  if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
12184
 
      OPTION_BIG_TABLES)
12185
 
    create_info.data_file_length= ~(uint64_t) 0;
12186
 
 
12187
 
  if ((error=mi_create(share->table_name.str, share->keys, &keydef,
12188
 
                       (uint) (*recinfo-start_recinfo),
12189
 
                       start_recinfo,
12190
 
                       share->uniques, &uniquedef,
12191
 
                       &create_info,
12192
 
                       HA_CREATE_TMP_TABLE)))
12193
 
  {
12194
 
    table->file->print_error(error,MYF(0));     /* purecov: inspected */
12195
 
    table->db_stat=0;
12196
 
    goto err;
12197
 
  }
12198
 
  status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
12199
 
  share->db_record_offset= 1;
12200
 
  return(0);
12201
 
 err:
12202
 
  return(1);
12203
 
}
12204
 
 
12205
 
 
12206
 
void
12207
 
free_tmp_table(THD *thd, TABLE *entry)
12208
 
{
12209
 
  MEM_ROOT own_root= entry->mem_root;
12210
 
  const char *save_proc_info;
12211
 
 
12212
 
  save_proc_info=thd->proc_info;
12213
 
  thd_proc_info(thd, "removing tmp table");
12214
 
 
12215
 
  if (entry->file)
12216
 
  {
12217
 
    if (entry->db_stat)
12218
 
      entry->file->ha_drop_table(entry->s->table_name.str);
12219
 
    else
12220
 
      entry->file->ha_delete_table(entry->s->table_name.str);
12221
 
    delete entry->file;
12222
 
  }
12223
 
 
12224
 
  /* free blobs */
12225
 
  for (Field **ptr=entry->field ; *ptr ; ptr++)
12226
 
    (*ptr)->free();
12227
 
  free_io_cache(entry);
12228
 
 
12229
 
  if (entry->temp_pool_slot != MY_BIT_NONE)
12230
 
    bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
12231
 
 
12232
 
  plugin_unlock(0, entry->s->db_plugin);
12233
 
 
12234
 
  free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
12235
 
  thd_proc_info(thd, save_proc_info);
12236
 
 
12237
 
  return;
12238
 
}
12239
 
 
12240
 
/**
12241
 
  If a HEAP table gets full, create a MyISAM table and copy all rows
12242
 
  to this.
12243
 
*/
12244
 
 
12245
 
bool create_myisam_from_heap(THD *thd, TABLE *table,
12246
 
                             MI_COLUMNDEF *start_recinfo,
12247
 
                             MI_COLUMNDEF **recinfo, 
12248
 
                             int error, bool ignore_last_dupp_key_error)
12249
 
{
12250
 
  TABLE new_table;
12251
 
  TABLE_SHARE share;
12252
 
  const char *save_proc_info;
12253
 
  int write_err;
12254
 
 
12255
 
  if (table->s->db_type() != heap_hton || 
12256
 
      error != HA_ERR_RECORD_FILE_FULL)
12257
 
  {
12258
 
    table->file->print_error(error,MYF(0));
12259
 
    return(1);
12260
 
  }
12261
 
  new_table= *table;
12262
 
  share= *table->s;
12263
 
  new_table.s= &share;
12264
 
  new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
12265
 
  if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
12266
 
                                        new_table.s->db_type())))
12267
 
    return(1);                          // End of memory
12268
 
 
12269
 
  save_proc_info=thd->proc_info;
12270
 
  thd_proc_info(thd, "converting HEAP to MyISAM");
12271
 
 
12272
 
  if (create_myisam_tmp_table(&new_table, table->key_info, start_recinfo,
12273
 
                              recinfo, thd->lex->select_lex.options | 
12274
 
                                               thd->options))
12275
 
    goto err2;
12276
 
  if (open_tmp_table(&new_table))
12277
 
    goto err1;
12278
 
  if (table->file->indexes_are_disabled())
12279
 
    new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
12280
 
  table->file->ha_index_or_rnd_end();
12281
 
  table->file->ha_rnd_init(1);
12282
 
  if (table->no_rows)
12283
 
  {
12284
 
    new_table.file->extra(HA_EXTRA_NO_ROWS);
12285
 
    new_table.no_rows=1;
12286
 
  }
12287
 
 
12288
 
#ifdef TO_BE_DONE_LATER_IN_4_1
12289
 
  /*
12290
 
    To use start_bulk_insert() (which is new in 4.1) we need to find
12291
 
    all places where a corresponding end_bulk_insert() should be put.
12292
 
  */
12293
 
  table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
12294
 
  new_table.file->ha_start_bulk_insert(table->file->stats.records);
12295
 
#else
12296
 
  /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
12297
 
  new_table.file->extra(HA_EXTRA_WRITE_CACHE);
12298
 
#endif
12299
 
 
12300
 
  /*
12301
 
    copy all old rows from heap table to MyISAM table
12302
 
    This is the only code that uses record[1] to read/write but this
12303
 
    is safe as this is a temporary MyISAM table without timestamp/autoincrement.
12304
 
  */
12305
 
  while (!table->file->rnd_next(new_table.record[1]))
12306
 
  {
12307
 
    write_err= new_table.file->ha_write_row(new_table.record[1]);
12308
 
    if (write_err)
12309
 
      goto err;
12310
 
  }
12311
 
  /* copy row that filled HEAP table */
12312
 
  if ((write_err=new_table.file->ha_write_row(table->record[0])))
12313
 
  {
12314
 
    if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
12315
 
        !ignore_last_dupp_key_error)
12316
 
      goto err;
12317
 
  }
12318
 
 
12319
 
  /* remove heap table and change to use myisam table */
12320
 
  (void) table->file->ha_rnd_end();
12321
 
  (void) table->file->close();                  // This deletes the table !
12322
 
  delete table->file;
12323
 
  table->file=0;
12324
 
  plugin_unlock(0, table->s->db_plugin);
12325
 
  share.db_plugin= my_plugin_lock(0, &share.db_plugin);
12326
 
  new_table.s= table->s;                       // Keep old share
12327
 
  *table= new_table;
12328
 
  *table->s= share;
12329
 
  
12330
 
  table->file->change_table_ptr(table, table->s);
12331
 
  table->use_all_columns();
12332
 
  if (save_proc_info)
12333
 
  {
12334
 
    const char *new_proc_info=
12335
 
      (!strcmp(save_proc_info,"Copying to tmp table") ?
12336
 
      "Copying to tmp table on disk" : save_proc_info);
12337
 
    thd_proc_info(thd, new_proc_info);
12338
 
  }
12339
 
  return(0);
12340
 
 
12341
 
 err:
12342
 
  table->file->print_error(write_err, MYF(0));
12343
 
  (void) table->file->ha_rnd_end();
12344
 
  (void) new_table.file->close();
12345
 
 err1:
12346
 
  new_table.file->ha_delete_table(new_table.s->table_name.str);
12347
 
 err2:
12348
 
  delete new_table.file;
12349
 
  thd_proc_info(thd, save_proc_info);
12350
 
  table->mem_root= new_table.mem_root;
12351
 
  return(1);
12352
 
}
12353
 
 
12354
10517
 
12355
10518
/**
12356
10519
  @details