~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-12-21 16:39:40 UTC
  • mfrom: (1.2.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20101221163940-c1pfo1jjvx7909xq
Tags: 2010.12.06-0ubuntu1
* New upstream release.
* Added libaio-dev build depend for InnoDB.
* Removed libpcre patch - applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
 
29
29
#include <queue>
30
30
#include <algorithm>
 
31
#include <iostream>
31
32
 
32
33
#include "drizzled/drizzled.h"
33
34
#include "drizzled/sql_sort.h"
52
53
namespace drizzled
53
54
{
54
55
 
55
 
 
56
56
/* Defines used by filesort and uniques */
57
57
#define MERGEBUFF               7
58
58
#define MERGEBUFF2              15
381
381
      Use also the space previously used by string pointers in sort_buffer
382
382
      for temporary key storage.
383
383
    */
384
 
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
385
 
                param.rec_length-1);
 
384
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) / param.rec_length-1);
 
385
 
386
386
    maxbuffer--;                                // Offset from 0
387
387
    if (merge_many_buff(&param,(unsigned char*) sort_keys,buffpek_inst,&maxbuffer, &tempfile))
388
388
    {
418
418
 
419
419
  tempfile.close_cached_file();
420
420
  buffpek_pointers.close_cached_file();
 
421
 
421
422
  if (my_b_inited(outfile))
422
423
  {
423
424
    if (flush_io_cache(outfile))
425
426
      error=1;
426
427
    }
427
428
    {
428
 
      internal::my_off_t save_pos=outfile->pos_in_file;
 
429
      internal::my_off_t save_pos= outfile->pos_in_file;
429
430
      /* For following reads */
430
431
      if (outfile->reinit_io_cache(internal::READ_CACHE,0L,0,0))
431
432
      {
434
435
      outfile->end_of_file=save_pos;
435
436
    }
436
437
  }
 
438
 
437
439
  if (error)
438
440
  {
439
441
    my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
683
685
    sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
684
686
    return(HA_POS_ERROR);
685
687
  }
686
 
  if (indexpos && idx &&
687
 
      param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
 
688
 
 
689
  if (indexpos && idx && param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
 
690
  {
688
691
    return(HA_POS_ERROR);
 
692
  }
 
693
 
689
694
  return(my_b_inited(tempfile) ?
690
695
              (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
691
696
              idx);
812
817
    {                                           // Item
813
818
      Item *item=sort_field->item;
814
819
      maybe_null= item->maybe_null;
 
820
 
815
821
      switch (sort_field->result_type) {
816
822
      case STRING_RESULT:
817
 
      {
818
 
        const CHARSET_INFO * const cs=item->collation.collation;
819
 
        char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
820
 
        int diff;
821
 
        uint32_t sort_field_length;
 
823
        {
 
824
          const CHARSET_INFO * const cs=item->collation.collation;
 
825
          char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
 
826
          int diff;
 
827
          uint32_t sort_field_length;
822
828
 
823
 
        if (maybe_null)
824
 
          *to++=1;
825
 
        /* All item->str() to use some extra byte for end null.. */
826
 
        String tmp((char*) to,sort_field->length+4,cs);
827
 
        String *res= item->str_result(&tmp);
828
 
        if (!res)
829
 
        {
830
829
          if (maybe_null)
831
 
            memset(to-1, 0, sort_field->length+1);
 
830
            *to++=1;
 
831
          /* All item->str() to use some extra byte for end null.. */
 
832
          String tmp((char*) to,sort_field->length+4,cs);
 
833
          String *res= item->str_result(&tmp);
 
834
          if (!res)
 
835
          {
 
836
            if (maybe_null)
 
837
              memset(to-1, 0, sort_field->length+1);
 
838
            else
 
839
            {
 
840
              /*
 
841
                This should only happen during extreme conditions if we run out
 
842
                of memory or have an item marked not null when it can be null.
 
843
                This code is here mainly to avoid a hard crash in this case.
 
844
              */
 
845
              assert(0);
 
846
              memset(to, 0, sort_field->length);        // Avoid crash
 
847
            }
 
848
            break;
 
849
          }
 
850
          length= res->length();
 
851
          sort_field_length= sort_field->length - sort_field->suffix_length;
 
852
          diff=(int) (sort_field_length - length);
 
853
          if (diff < 0)
 
854
          {
 
855
            diff=0;
 
856
            length= sort_field_length;
 
857
          }
 
858
          if (sort_field->suffix_length)
 
859
          {
 
860
            /* Store length last in result_string */
 
861
            store_length(to + sort_field_length, length,
 
862
                         sort_field->suffix_length);
 
863
          }
 
864
          if (sort_field->need_strxnfrm)
 
865
          {
 
866
            char *from=(char*) res->ptr();
 
867
            uint32_t tmp_length;
 
868
            if ((unsigned char*) from == to)
 
869
            {
 
870
              set_if_smaller(length,sort_field->length);
 
871
              memcpy(tmp_buffer,from,length);
 
872
              from= tmp_buffer;
 
873
            }
 
874
            tmp_length= my_strnxfrm(cs,to,sort_field->length,
 
875
                                    (unsigned char*) from, length);
 
876
            assert(tmp_length == sort_field->length);
 
877
          }
832
878
          else
833
879
          {
834
 
            /*
835
 
              This should only happen during extreme conditions if we run out
836
 
              of memory or have an item marked not null when it can be null.
837
 
              This code is here mainly to avoid a hard crash in this case.
838
 
            */
839
 
            assert(0);
840
 
            memset(to, 0, sort_field->length);  // Avoid crash
 
880
            my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
 
881
            cs->cset->fill(cs, (char *)to+length,diff,fill_char);
841
882
          }
842
883
          break;
843
884
        }
844
 
        length= res->length();
845
 
        sort_field_length= sort_field->length - sort_field->suffix_length;
846
 
        diff=(int) (sort_field_length - length);
847
 
        if (diff < 0)
848
 
        {
849
 
          diff=0;
850
 
          length= sort_field_length;
851
 
        }
852
 
        if (sort_field->suffix_length)
853
 
        {
854
 
          /* Store length last in result_string */
855
 
          store_length(to + sort_field_length, length,
856
 
                       sort_field->suffix_length);
857
 
        }
858
 
        if (sort_field->need_strxnfrm)
859
 
        {
860
 
          char *from=(char*) res->ptr();
861
 
          uint32_t tmp_length;
862
 
          if ((unsigned char*) from == to)
863
 
          {
864
 
            set_if_smaller(length,sort_field->length);
865
 
            memcpy(tmp_buffer,from,length);
866
 
            from= tmp_buffer;
867
 
          }
868
 
          tmp_length= my_strnxfrm(cs,to,sort_field->length,
869
 
                                  (unsigned char*) from, length);
870
 
          assert(tmp_length == sort_field->length);
871
 
        }
872
 
        else
873
 
        {
874
 
          my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
875
 
          cs->cset->fill(cs, (char *)to+length,diff,fill_char);
876
 
        }
877
 
        break;
878
 
      }
879
885
      case INT_RESULT:
880
 
        {
 
886
        {
881
887
          int64_t value= item->val_int_result();
882
888
          if (maybe_null)
883
889
          {
884
 
            *to++=1;
 
890
            *to++=1;
885
891
            if (item->null_value)
886
892
            {
887
893
              if (maybe_null)
893
899
              break;
894
900
            }
895
901
          }
896
 
          to[7]= (unsigned char) value;
897
 
          to[6]= (unsigned char) (value >> 8);
898
 
          to[5]= (unsigned char) (value >> 16);
899
 
          to[4]= (unsigned char) (value >> 24);
900
 
          to[3]= (unsigned char) (value >> 32);
901
 
          to[2]= (unsigned char) (value >> 40);
902
 
          to[1]= (unsigned char) (value >> 48);
 
902
          to[7]= (unsigned char) value;
 
903
          to[6]= (unsigned char) (value >> 8);
 
904
          to[5]= (unsigned char) (value >> 16);
 
905
          to[4]= (unsigned char) (value >> 24);
 
906
          to[3]= (unsigned char) (value >> 32);
 
907
          to[2]= (unsigned char) (value >> 40);
 
908
          to[1]= (unsigned char) (value >> 48);
903
909
          if (item->unsigned_flag)                    /* Fix sign */
904
910
            to[0]= (unsigned char) (value >> 56);
905
911
          else
906
912
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
907
 
          break;
908
 
        }
 
913
          break;
 
914
        }
909
915
      case DECIMAL_RESULT:
910
916
        {
911
917
          my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
922
928
          my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to,
923
929
                            item->max_length - (item->decimals ? 1:0),
924
930
                            item->decimals);
925
 
         break;
 
931
          break;
926
932
        }
927
933
      case REAL_RESULT:
928
 
        {
 
934
        {
929
935
          double value= item->val_result();
930
 
          if (maybe_null)
 
936
          if (maybe_null)
931
937
          {
932
938
            if (item->null_value)
933
939
            {
935
941
              to++;
936
942
              break;
937
943
            }
938
 
            *to++=1;
 
944
            *to++=1;
939
945
          }
940
 
          change_double_for_sort(value,(unsigned char*) to);
941
 
          break;
942
 
        }
 
946
          change_double_for_sort(value,(unsigned char*) to);
 
947
          break;
 
948
        }
943
949
      case ROW_RESULT:
944
950
      default:
945
 
        // This case should never be choosen
946
 
        assert(0);
947
 
        break;
 
951
        // This case should never be choosen
 
952
        assert(0);
 
953
        break;
948
954
      }
949
955
    }
 
956
 
950
957
    if (sort_field->reverse)
951
958
    {                                                   /* Revers key */
952
959
      if (maybe_null)
959
966
      }
960
967
    }
961
968
    else
 
969
    {
962
970
      to+= sort_field->length;
 
971
    }
963
972
  }
964
973
 
965
974
  if (addon_field)
1024
1033
    if ((field= sort_field->field))
1025
1034
    {
1026
1035
      if (field->getTable() == table)
1027
 
        table->setReadSet(field->field_index);
 
1036
        table->setReadSet(field->position());
1028
1037
    }
1029
1038
    else
1030
1039
    {                                           // Item
1038
1047
    sort_addon_field *addonf= addon_field;
1039
1048
    Field *field;
1040
1049
    for ( ; (field= addonf->field) ; addonf++)
1041
 
      table->setReadSet(field->field_index);
 
1050
      table->setReadSet(field->position());
1042
1051
  }
1043
1052
  else
1044
1053
  {
1048
1057
}
1049
1058
 
1050
1059
 
1051
 
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count,
1052
 
                           filesort_info *table_sort)
 
1060
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
1053
1061
{
1054
1062
  uint32_t offset;
1055
1063
  unsigned char *to;
1056
1064
 
1057
1065
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1058
1066
  offset= rec_length - res_length;
 
1067
 
1059
1068
  if ((ha_rows) count > max_rows)
1060
1069
    count=(uint32_t) max_rows;
1061
 
  if (!(to= table_sort->record_pointers=
1062
 
        (unsigned char*) malloc(res_length*count)))
 
1070
 
 
1071
  if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
1063
1072
    return true;
1064
1073
 
1065
1074
  for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1067
1076
    memcpy(to, *sort_keys+offset, res_length);
1068
1077
    to+= res_length;
1069
1078
  }
 
1079
 
1070
1080
  return false;
1071
1081
}
1072
1082
 
1171
1181
{
1172
1182
  qsort2_cmp key_compare;
1173
1183
  void *key_compare_arg;
 
1184
 
1174
1185
  public:
1175
 
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
1176
 
    : key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
 
1186
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg) :
 
1187
    key_compare(in_key_compare),
 
1188
    key_compare_arg(in_compare_arg)
 
1189
  { }
 
1190
  
1177
1191
  inline bool operator()(const buffpek *i, const buffpek *j) const
1178
1192
  {
1179
 
    int val= key_compare(key_compare_arg,
1180
 
                      &i->key, &j->key);
 
1193
    int val= key_compare(key_compare_arg, &i->key, &j->key);
 
1194
 
1181
1195
    return (val >= 0);
1182
1196
  }
1183
1197
};
1486
1500
      sortorder->result_type= sortorder->item->result_type();
1487
1501
      if (sortorder->item->result_as_int64_t())
1488
1502
        sortorder->result_type= INT_RESULT;
 
1503
 
1489
1504
      switch (sortorder->result_type) {
1490
1505
      case STRING_RESULT:
1491
 
        sortorder->length=sortorder->item->max_length;
 
1506
        sortorder->length=sortorder->item->max_length;
1492
1507
        set_if_smaller(sortorder->length,
1493
1508
                       getSession().variables.max_sort_length);
1494
 
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1495
 
        {
 
1509
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
 
1510
        {
1496
1511
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1497
 
          sortorder->need_strxnfrm= 1;
1498
 
          *multi_byte_charset= 1;
1499
 
        }
 
1512
          sortorder->need_strxnfrm= 1;
 
1513
          *multi_byte_charset= 1;
 
1514
        }
1500
1515
        else if (cs == &my_charset_bin)
1501
1516
        {
1502
1517
          /* Store length last to be able to sort blob/varbinary */
1503
1518
          sortorder->suffix_length= suffix_length(sortorder->length);
1504
1519
          sortorder->length+= sortorder->suffix_length;
1505
1520
        }
1506
 
        break;
 
1521
        break;
1507
1522
      case INT_RESULT:
1508
 
        sortorder->length=8;                    // Size of intern int64_t
1509
 
        break;
 
1523
        sortorder->length=8;                    // Size of intern int64_t
 
1524
        break;
1510
1525
      case DECIMAL_RESULT:
1511
1526
        sortorder->length=
1512
1527
          my_decimal_get_binary_size(sortorder->item->max_length -
1514
1529
                                     sortorder->item->decimals);
1515
1530
        break;
1516
1531
      case REAL_RESULT:
1517
 
        sortorder->length=sizeof(double);
1518
 
        break;
 
1532
        sortorder->length=sizeof(double);
 
1533
        break;
1519
1534
      case ROW_RESULT:
1520
 
      default:
1521
 
        // This case should never be choosen
1522
 
        assert(0);
1523
 
        break;
 
1535
        // This case should never be choosen
 
1536
        assert(0);
 
1537
        break;
1524
1538
      }
1525
1539
      if (sortorder->item->maybe_null)
1526
 
        length++;                               // Place for NULL marker
 
1540
        length++;                               // Place for NULL marker
1527
1541
    }
1528
1542
    set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1529
1543
    length+=sortorder->length;