~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Brian Aker
  • Date: 2010-12-02 01:39:53 UTC
  • mto: This revision was merged to the branch mainline in revision 1968.
  • Revision ID: brian@tangent.org-20101202013953-9ie7kafjag0e051q
Style cleanup.

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>
32
31
 
33
32
#include "drizzled/drizzled.h"
34
33
#include "drizzled/sql_sort.h"
53
52
namespace drizzled
54
53
{
55
54
 
 
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*))) / param.rec_length-1);
385
 
 
 
384
    param.keys=((param.keys*(param.rec_length+sizeof(char*))) /
 
385
                param.rec_length-1);
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
 
 
422
421
  if (my_b_inited(outfile))
423
422
  {
424
423
    if (flush_io_cache(outfile))
426
425
      error=1;
427
426
    }
428
427
    {
429
 
      internal::my_off_t save_pos= outfile->pos_in_file;
 
428
      internal::my_off_t save_pos=outfile->pos_in_file;
430
429
      /* For following reads */
431
430
      if (outfile->reinit_io_cache(internal::READ_CACHE,0L,0,0))
432
431
      {
435
434
      outfile->end_of_file=save_pos;
436
435
    }
437
436
  }
438
 
 
439
437
  if (error)
440
438
  {
441
439
    my_message(ER_FILSORT_ABORT, ER(ER_FILSORT_ABORT),
685
683
    sort_form->print_error(error,MYF(ME_ERROR | ME_WAITTANG));
686
684
    return(HA_POS_ERROR);
687
685
  }
688
 
 
689
 
  if (indexpos && idx && param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
690
 
  {
 
686
  if (indexpos && idx &&
 
687
      param->write_keys(sort_keys,idx,buffpek_pointers,tempfile))
691
688
    return(HA_POS_ERROR);
692
 
  }
693
 
 
694
689
  return(my_b_inited(tempfile) ?
695
690
              (ha_rows) (my_b_tell(tempfile)/param->rec_length) :
696
691
              idx);
817
812
    {                                           // Item
818
813
      Item *item=sort_field->item;
819
814
      maybe_null= item->maybe_null;
820
 
 
821
815
      switch (sort_field->result_type) {
822
816
      case STRING_RESULT:
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;
 
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;
828
822
 
 
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
        {
829
830
          if (maybe_null)
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
 
          }
 
831
            memset(to-1, 0, sort_field->length+1);
878
832
          else
879
833
          {
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);
 
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
882
841
          }
883
842
          break;
884
843
        }
 
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
      }
885
879
      case INT_RESULT:
886
 
        {
 
880
        {
887
881
          int64_t value= item->val_int_result();
888
882
          if (maybe_null)
889
883
          {
890
 
            *to++=1;
 
884
            *to++=1;
891
885
            if (item->null_value)
892
886
            {
893
887
              if (maybe_null)
899
893
              break;
900
894
            }
901
895
          }
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);
 
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);
909
903
          if (item->unsigned_flag)                    /* Fix sign */
910
904
            to[0]= (unsigned char) (value >> 56);
911
905
          else
912
906
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
913
 
          break;
914
 
        }
 
907
          break;
 
908
        }
915
909
      case DECIMAL_RESULT:
916
910
        {
917
911
          my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
928
922
          my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to,
929
923
                            item->max_length - (item->decimals ? 1:0),
930
924
                            item->decimals);
931
 
          break;
 
925
         break;
932
926
        }
933
927
      case REAL_RESULT:
934
 
        {
 
928
        {
935
929
          double value= item->val_result();
936
 
          if (maybe_null)
 
930
          if (maybe_null)
937
931
          {
938
932
            if (item->null_value)
939
933
            {
941
935
              to++;
942
936
              break;
943
937
            }
944
 
            *to++=1;
 
938
            *to++=1;
945
939
          }
946
 
          change_double_for_sort(value,(unsigned char*) to);
947
 
          break;
948
 
        }
 
940
          change_double_for_sort(value,(unsigned char*) to);
 
941
          break;
 
942
        }
949
943
      case ROW_RESULT:
950
944
      default:
951
 
        // This case should never be choosen
952
 
        assert(0);
953
 
        break;
 
945
        // This case should never be choosen
 
946
        assert(0);
 
947
        break;
954
948
      }
955
949
    }
956
 
 
957
950
    if (sort_field->reverse)
958
951
    {                                                   /* Revers key */
959
952
      if (maybe_null)
966
959
      }
967
960
    }
968
961
    else
969
 
    {
970
962
      to+= sort_field->length;
971
 
    }
972
963
  }
973
964
 
974
965
  if (addon_field)
1033
1024
    if ((field= sort_field->field))
1034
1025
    {
1035
1026
      if (field->getTable() == table)
1036
 
        table->setReadSet(field->position());
 
1027
        table->setReadSet(field->field_index);
1037
1028
    }
1038
1029
    else
1039
1030
    {                                           // Item
1047
1038
    sort_addon_field *addonf= addon_field;
1048
1039
    Field *field;
1049
1040
    for ( ; (field= addonf->field) ; addonf++)
1050
 
      table->setReadSet(field->position());
 
1041
      table->setReadSet(field->field_index);
1051
1042
  }
1052
1043
  else
1053
1044
  {
1057
1048
}
1058
1049
 
1059
1050
 
1060
 
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count, filesort_info *table_sort)
 
1051
bool SortParam::save_index(unsigned char **sort_keys, uint32_t count,
 
1052
                           filesort_info *table_sort)
1061
1053
{
1062
1054
  uint32_t offset;
1063
1055
  unsigned char *to;
1064
1056
 
1065
1057
  internal::my_string_ptr_sort((unsigned char*) sort_keys, (uint32_t) count, sort_length);
1066
1058
  offset= rec_length - res_length;
1067
 
 
1068
1059
  if ((ha_rows) count > max_rows)
1069
1060
    count=(uint32_t) max_rows;
1070
 
 
1071
 
  if (!(to= table_sort->record_pointers= (unsigned char*) malloc(res_length*count)))
 
1061
  if (!(to= table_sort->record_pointers=
 
1062
        (unsigned char*) malloc(res_length*count)))
1072
1063
    return true;
1073
1064
 
1074
1065
  for (unsigned char **end_ptr= sort_keys+count ; sort_keys != end_ptr ; sort_keys++)
1076
1067
    memcpy(to, *sort_keys+offset, res_length);
1077
1068
    to+= res_length;
1078
1069
  }
1079
 
 
1080
1070
  return false;
1081
1071
}
1082
1072
 
1181
1171
{
1182
1172
  qsort2_cmp key_compare;
1183
1173
  void *key_compare_arg;
1184
 
 
1185
1174
  public:
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
 
  
 
1175
  compare_functor(qsort2_cmp in_key_compare, void *in_compare_arg)
 
1176
    : key_compare(in_key_compare), key_compare_arg(in_compare_arg) { }
1191
1177
  inline bool operator()(const buffpek *i, const buffpek *j) const
1192
1178
  {
1193
 
    int val= key_compare(key_compare_arg, &i->key, &j->key);
1194
 
 
 
1179
    int val= key_compare(key_compare_arg,
 
1180
                      &i->key, &j->key);
1195
1181
    return (val >= 0);
1196
1182
  }
1197
1183
};
1500
1486
      sortorder->result_type= sortorder->item->result_type();
1501
1487
      if (sortorder->item->result_as_int64_t())
1502
1488
        sortorder->result_type= INT_RESULT;
1503
 
 
1504
1489
      switch (sortorder->result_type) {
1505
1490
      case STRING_RESULT:
1506
 
        sortorder->length=sortorder->item->max_length;
 
1491
        sortorder->length=sortorder->item->max_length;
1507
1492
        set_if_smaller(sortorder->length,
1508
1493
                       getSession().variables.max_sort_length);
1509
 
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1510
 
        {
 
1494
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
 
1495
        {
1511
1496
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1512
 
          sortorder->need_strxnfrm= 1;
1513
 
          *multi_byte_charset= 1;
1514
 
        }
 
1497
          sortorder->need_strxnfrm= 1;
 
1498
          *multi_byte_charset= 1;
 
1499
        }
1515
1500
        else if (cs == &my_charset_bin)
1516
1501
        {
1517
1502
          /* Store length last to be able to sort blob/varbinary */
1518
1503
          sortorder->suffix_length= suffix_length(sortorder->length);
1519
1504
          sortorder->length+= sortorder->suffix_length;
1520
1505
        }
1521
 
        break;
 
1506
        break;
1522
1507
      case INT_RESULT:
1523
 
        sortorder->length=8;                    // Size of intern int64_t
1524
 
        break;
 
1508
        sortorder->length=8;                    // Size of intern int64_t
 
1509
        break;
1525
1510
      case DECIMAL_RESULT:
1526
1511
        sortorder->length=
1527
1512
          my_decimal_get_binary_size(sortorder->item->max_length -
1529
1514
                                     sortorder->item->decimals);
1530
1515
        break;
1531
1516
      case REAL_RESULT:
1532
 
        sortorder->length=sizeof(double);
1533
 
        break;
 
1517
        sortorder->length=sizeof(double);
 
1518
        break;
1534
1519
      case ROW_RESULT:
1535
 
        // This case should never be choosen
1536
 
        assert(0);
1537
 
        break;
 
1520
      default:
 
1521
        // This case should never be choosen
 
1522
        assert(0);
 
1523
        break;
1538
1524
      }
1539
1525
      if (sortorder->item->maybe_null)
1540
 
        length++;                               // Place for NULL marker
 
1526
        length++;                               // Place for NULL marker
1541
1527
    }
1542
1528
    set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1543
1529
    length+=sortorder->length;