~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/filesort.cc

  • Committer: Brian Aker
  • Date: 2010-12-17 00:08:06 UTC
  • mfrom: (2002.1.4 clean)
  • Revision ID: brian@tangent.org-20101217000806-fa6kmggjnhsl4q85
Rollup for field encapsulation, monty fix for bzrignore, and Andrew bug
fixes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
  Sorts a database
22
22
*/
23
23
 
24
 
#include <config.h>
 
24
#include "config.h"
25
25
 
26
26
#include <float.h>
27
27
#include <limits.h>
30
30
#include <algorithm>
31
31
#include <iostream>
32
32
 
33
 
#include <drizzled/drizzled.h>
34
 
#include <drizzled/sql_sort.h>
35
 
#include <drizzled/filesort.h>
36
 
#include <drizzled/error.h>
37
 
#include <drizzled/probes.h>
38
 
#include <drizzled/session.h>
39
 
#include <drizzled/table.h>
40
 
#include <drizzled/table_list.h>
41
 
#include <drizzled/optimizer/range.h>
42
 
#include <drizzled/records.h>
43
 
#include <drizzled/internal/iocache.h>
44
 
#include <drizzled/internal/my_sys.h>
45
 
#include <plugin/myisam/myisam.h>
46
 
#include <drizzled/plugin/transactional_storage_engine.h>
47
 
#include <drizzled/atomics.h>
48
 
#include <drizzled/global_buffer.h>
49
 
 
50
 
#include <drizzled/sort_field.h>
 
33
#include "drizzled/drizzled.h"
 
34
#include "drizzled/sql_sort.h"
 
35
#include "drizzled/filesort.h"
 
36
#include "drizzled/error.h"
 
37
#include "drizzled/probes.h"
 
38
#include "drizzled/session.h"
 
39
#include "drizzled/table.h"
 
40
#include "drizzled/table_list.h"
 
41
#include "drizzled/optimizer/range.h"
 
42
#include "drizzled/records.h"
 
43
#include "drizzled/internal/iocache.h"
 
44
#include "drizzled/internal/my_sys.h"
 
45
#include "plugin/myisam/myisam.h"
 
46
#include "drizzled/plugin/transactional_storage_engine.h"
 
47
#include "drizzled/atomics.h"
 
48
#include "drizzled/global_buffer.h"
51
49
 
52
50
 
53
51
using namespace std;
134
132
 
135
133
/* functions defined in this file */
136
134
 
137
 
static char **make_char_array(char **old_pos, uint32_t fields,
 
135
static char **make_char_array(char **old_pos, register uint32_t fields,
138
136
                              uint32_t length);
139
137
 
140
138
static unsigned char *read_buffpek_from_file(internal::IO_CACHE *buffer_file,
456
454
 
457
455
/** Make a array of string pointers. */
458
456
 
459
 
static char **make_char_array(char **old_pos, uint32_t fields,
 
457
static char **make_char_array(char **old_pos, register uint32_t fields,
460
458
                              uint32_t length)
461
459
{
462
 
  char **pos;
 
460
  register char **pos;
463
461
  char *char_pos;
464
462
 
465
463
  if (old_pos ||
566
564
  if (! indexfile && ! quick_select)
567
565
  {
568
566
    next_pos=(unsigned char*) 0;                        /* Find records in sequence */
569
 
    if (file->startTableScan(1))
570
 
      return(HA_POS_ERROR);
 
567
    file->startTableScan(1);
571
568
    file->extra_opt(HA_EXTRA_CACHE, getSession().variables.read_buff_size);
572
569
  }
573
570
 
577
574
    if (select->quick->reset())
578
575
      return(HA_POS_ERROR);
579
576
 
580
 
    if (read_record_info.init_read_record(&getSession(), select->quick->head, select, 1, 1))
581
 
      return(HA_POS_ERROR);
 
577
    read_record_info.init_read_record(&getSession(), select->quick->head, select, 1, 1);
582
578
  }
583
579
 
584
580
  /* Remember original bitmaps */
723
719
    1 Error
724
720
*/
725
721
 
726
 
int SortParam::write_keys(unsigned char **sort_keys, uint32_t count,
 
722
int SortParam::write_keys(register unsigned char **sort_keys, uint32_t count,
727
723
                          internal::IO_CACHE *buffpek_pointers, internal::IO_CACHE *tempfile)
728
724
{
729
725
  buffpek buffpek;
788
784
 
789
785
/** Make a sort-key from record. */
790
786
 
791
 
void SortParam::make_sortkey(unsigned char *to, unsigned char *ref_pos)
 
787
void SortParam::make_sortkey(register unsigned char *to, unsigned char *ref_pos)
792
788
{
793
789
  Field *field;
794
790
  SortField *sort_field;
821
817
    {                                           // Item
822
818
      Item *item=sort_field->item;
823
819
      maybe_null= item->maybe_null;
824
 
 
825
820
      switch (sort_field->result_type) {
826
821
      case STRING_RESULT:
827
 
        {
828
 
          const CHARSET_INFO * const cs=item->collation.collation;
829
 
          char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
830
 
          int diff;
831
 
          uint32_t sort_field_length;
 
822
      {
 
823
        const CHARSET_INFO * const cs=item->collation.collation;
 
824
        char fill_char= ((cs->state & MY_CS_BINSORT) ? (char) 0 : ' ');
 
825
        int diff;
 
826
        uint32_t sort_field_length;
832
827
 
 
828
        if (maybe_null)
 
829
          *to++=1;
 
830
        /* All item->str() to use some extra byte for end null.. */
 
831
        String tmp((char*) to,sort_field->length+4,cs);
 
832
        String *res= item->str_result(&tmp);
 
833
        if (!res)
 
834
        {
833
835
          if (maybe_null)
834
 
            *to++=1;
835
 
          /* All item->str() to use some extra byte for end null.. */
836
 
          String tmp((char*) to,sort_field->length+4,cs);
837
 
          String *res= item->str_result(&tmp);
838
 
          if (!res)
839
 
          {
840
 
            if (maybe_null)
841
 
              memset(to-1, 0, sort_field->length+1);
842
 
            else
843
 
            {
844
 
              /*
845
 
                This should only happen during extreme conditions if we run out
846
 
                of memory or have an item marked not null when it can be null.
847
 
                This code is here mainly to avoid a hard crash in this case.
848
 
              */
849
 
              assert(0);
850
 
              memset(to, 0, sort_field->length);        // Avoid crash
851
 
            }
852
 
            break;
853
 
          }
854
 
          length= res->length();
855
 
          sort_field_length= sort_field->length - sort_field->suffix_length;
856
 
          diff=(int) (sort_field_length - length);
857
 
          if (diff < 0)
858
 
          {
859
 
            diff=0;
860
 
            length= sort_field_length;
861
 
          }
862
 
          if (sort_field->suffix_length)
863
 
          {
864
 
            /* Store length last in result_string */
865
 
            store_length(to + sort_field_length, length,
866
 
                         sort_field->suffix_length);
867
 
          }
868
 
          if (sort_field->need_strxnfrm)
869
 
          {
870
 
            char *from=(char*) res->ptr();
871
 
            uint32_t tmp_length;
872
 
            if ((unsigned char*) from == to)
873
 
            {
874
 
              set_if_smaller(length,sort_field->length);
875
 
              memcpy(tmp_buffer,from,length);
876
 
              from= tmp_buffer;
877
 
            }
878
 
            tmp_length= my_strnxfrm(cs,to,sort_field->length,
879
 
                                    (unsigned char*) from, length);
880
 
            assert(tmp_length == sort_field->length);
881
 
          }
 
836
            memset(to-1, 0, sort_field->length+1);
882
837
          else
883
838
          {
884
 
            my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
885
 
            cs->cset->fill(cs, (char *)to+length,diff,fill_char);
 
839
            /*
 
840
              This should only happen during extreme conditions if we run out
 
841
              of memory or have an item marked not null when it can be null.
 
842
              This code is here mainly to avoid a hard crash in this case.
 
843
            */
 
844
            assert(0);
 
845
            memset(to, 0, sort_field->length);  // Avoid crash
886
846
          }
887
847
          break;
888
848
        }
 
849
        length= res->length();
 
850
        sort_field_length= sort_field->length - sort_field->suffix_length;
 
851
        diff=(int) (sort_field_length - length);
 
852
        if (diff < 0)
 
853
        {
 
854
          diff=0;
 
855
          length= sort_field_length;
 
856
        }
 
857
        if (sort_field->suffix_length)
 
858
        {
 
859
          /* Store length last in result_string */
 
860
          store_length(to + sort_field_length, length,
 
861
                       sort_field->suffix_length);
 
862
        }
 
863
        if (sort_field->need_strxnfrm)
 
864
        {
 
865
          char *from=(char*) res->ptr();
 
866
          uint32_t tmp_length;
 
867
          if ((unsigned char*) from == to)
 
868
          {
 
869
            set_if_smaller(length,sort_field->length);
 
870
            memcpy(tmp_buffer,from,length);
 
871
            from= tmp_buffer;
 
872
          }
 
873
          tmp_length= my_strnxfrm(cs,to,sort_field->length,
 
874
                                  (unsigned char*) from, length);
 
875
          assert(tmp_length == sort_field->length);
 
876
        }
 
877
        else
 
878
        {
 
879
          my_strnxfrm(cs,(unsigned char*)to,length,(const unsigned char*)res->ptr(),length);
 
880
          cs->cset->fill(cs, (char *)to+length,diff,fill_char);
 
881
        }
 
882
        break;
 
883
      }
889
884
      case INT_RESULT:
890
 
        {
 
885
        {
891
886
          int64_t value= item->val_int_result();
892
887
          if (maybe_null)
893
888
          {
894
 
            *to++=1;
 
889
            *to++=1;
895
890
            if (item->null_value)
896
891
            {
897
892
              if (maybe_null)
903
898
              break;
904
899
            }
905
900
          }
906
 
          to[7]= (unsigned char) value;
907
 
          to[6]= (unsigned char) (value >> 8);
908
 
          to[5]= (unsigned char) (value >> 16);
909
 
          to[4]= (unsigned char) (value >> 24);
910
 
          to[3]= (unsigned char) (value >> 32);
911
 
          to[2]= (unsigned char) (value >> 40);
912
 
          to[1]= (unsigned char) (value >> 48);
 
901
          to[7]= (unsigned char) value;
 
902
          to[6]= (unsigned char) (value >> 8);
 
903
          to[5]= (unsigned char) (value >> 16);
 
904
          to[4]= (unsigned char) (value >> 24);
 
905
          to[3]= (unsigned char) (value >> 32);
 
906
          to[2]= (unsigned char) (value >> 40);
 
907
          to[1]= (unsigned char) (value >> 48);
913
908
          if (item->unsigned_flag)                    /* Fix sign */
914
909
            to[0]= (unsigned char) (value >> 56);
915
910
          else
916
911
            to[0]= (unsigned char) (value >> 56) ^ 128; /* Reverse signbit */
917
 
          break;
918
 
        }
 
912
          break;
 
913
        }
919
914
      case DECIMAL_RESULT:
920
915
        {
921
 
          type::Decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
 
916
          my_decimal dec_buf, *dec_val= item->val_decimal_result(&dec_buf);
922
917
          if (maybe_null)
923
918
          {
924
919
            if (item->null_value)
929
924
            }
930
925
            *to++=1;
931
926
          }
932
 
          dec_val->val_binary(E_DEC_FATAL_ERROR, to,
933
 
                              item->max_length - (item->decimals ? 1:0),
934
 
                              item->decimals);
935
 
          break;
 
927
          my_decimal2binary(E_DEC_FATAL_ERROR, dec_val, to,
 
928
                            item->max_length - (item->decimals ? 1:0),
 
929
                            item->decimals);
 
930
         break;
936
931
        }
937
932
      case REAL_RESULT:
938
 
        {
 
933
        {
939
934
          double value= item->val_result();
940
 
          if (maybe_null)
 
935
          if (maybe_null)
941
936
          {
942
937
            if (item->null_value)
943
938
            {
945
940
              to++;
946
941
              break;
947
942
            }
948
 
            *to++=1;
 
943
            *to++=1;
949
944
          }
950
 
          change_double_for_sort(value,(unsigned char*) to);
951
 
          break;
952
 
        }
 
945
          change_double_for_sort(value,(unsigned char*) to);
 
946
          break;
 
947
        }
953
948
      case ROW_RESULT:
954
949
      default:
955
 
        // This case should never be choosen
956
 
        assert(0);
957
 
        break;
 
950
        // This case should never be choosen
 
951
        assert(0);
 
952
        break;
958
953
      }
959
954
    }
960
 
 
961
955
    if (sort_field->reverse)
962
956
    {                                                   /* Revers key */
963
957
      if (maybe_null)
970
964
      }
971
965
    }
972
966
    else
973
 
    {
974
967
      to+= sort_field->length;
975
 
    }
976
968
  }
977
969
 
978
970
  if (addon_field)
1021
1013
 
1022
1014
 
1023
1015
/*
1024
 
  fields used by sorting in the sorted table's read set
 
1016
  Register fields used by sorting in the sorted table's read set
1025
1017
*/
1026
1018
 
1027
1019
void SortParam::register_used_fields()
1104
1096
  from_file= t_file ; to_file= &t_file2;
1105
1097
  while (*maxbuffer >= MERGEBUFF2)
1106
1098
  {
1107
 
    uint32_t i;
 
1099
    register uint32_t i;
1108
1100
 
1109
1101
    if (from_file->reinit_io_cache(internal::READ_CACHE,0L,0,0))
1110
1102
    {
1164
1156
 
1165
1157
uint32_t FileSort::read_to_buffer(internal::IO_CACHE *fromfile, buffpek *buffpek_inst, uint32_t rec_length)
1166
1158
{
1167
 
  uint32_t count;
 
1159
  register uint32_t count;
1168
1160
  uint32_t length;
1169
1161
 
1170
1162
  if ((count= (uint32_t) min((ha_rows) buffpek_inst->max_keys,buffpek_inst->count)))
1405
1397
    }
1406
1398
    else
1407
1399
    {
1408
 
      unsigned char *end;
 
1400
      register unsigned char *end;
1409
1401
      strpos= buffpek_inst->key+offset;
1410
1402
      for (end= strpos+buffpek_inst->mem_count*rec_length ;
1411
1403
           strpos != end ;
1476
1468
 
1477
1469
uint32_t FileSort::sortlength(SortField *sortorder, uint32_t s_length, bool *multi_byte_charset)
1478
1470
{
1479
 
  uint32_t length;
 
1471
  register uint32_t length;
1480
1472
  const CHARSET_INFO *cs;
1481
1473
  *multi_byte_charset= 0;
1482
1474
 
1504
1496
      sortorder->result_type= sortorder->item->result_type();
1505
1497
      if (sortorder->item->result_as_int64_t())
1506
1498
        sortorder->result_type= INT_RESULT;
1507
 
 
1508
1499
      switch (sortorder->result_type) {
1509
1500
      case STRING_RESULT:
1510
 
        sortorder->length=sortorder->item->max_length;
 
1501
        sortorder->length=sortorder->item->max_length;
1511
1502
        set_if_smaller(sortorder->length,
1512
1503
                       getSession().variables.max_sort_length);
1513
 
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
1514
 
        {
 
1504
        if (use_strnxfrm((cs=sortorder->item->collation.collation)))
 
1505
        {
1515
1506
          sortorder->length= cs->coll->strnxfrmlen(cs, sortorder->length);
1516
 
          sortorder->need_strxnfrm= 1;
1517
 
          *multi_byte_charset= 1;
1518
 
        }
 
1507
          sortorder->need_strxnfrm= 1;
 
1508
          *multi_byte_charset= 1;
 
1509
        }
1519
1510
        else if (cs == &my_charset_bin)
1520
1511
        {
1521
1512
          /* Store length last to be able to sort blob/varbinary */
1522
1513
          sortorder->suffix_length= suffix_length(sortorder->length);
1523
1514
          sortorder->length+= sortorder->suffix_length;
1524
1515
        }
1525
 
        break;
 
1516
        break;
1526
1517
      case INT_RESULT:
1527
 
        sortorder->length=8;                    // Size of intern int64_t
1528
 
        break;
 
1518
        sortorder->length=8;                    // Size of intern int64_t
 
1519
        break;
1529
1520
      case DECIMAL_RESULT:
1530
1521
        sortorder->length=
1531
 
          class_decimal_get_binary_size(sortorder->item->max_length -
 
1522
          my_decimal_get_binary_size(sortorder->item->max_length -
1532
1523
                                     (sortorder->item->decimals ? 1 : 0),
1533
1524
                                     sortorder->item->decimals);
1534
1525
        break;
1535
1526
      case REAL_RESULT:
1536
 
        sortorder->length=sizeof(double);
1537
 
        break;
 
1527
        sortorder->length=sizeof(double);
 
1528
        break;
1538
1529
      case ROW_RESULT:
1539
 
        // This case should never be choosen
1540
 
        assert(0);
1541
 
        break;
 
1530
      default:
 
1531
        // This case should never be choosen
 
1532
        assert(0);
 
1533
        break;
1542
1534
      }
1543
1535
      if (sortorder->item->maybe_null)
1544
 
        length++;                               // Place for NULL marker
 
1536
        length++;                               // Place for NULL marker
1545
1537
    }
1546
1538
    set_if_smaller(sortorder->length, (size_t)getSession().variables.max_sort_length);
1547
1539
    length+=sortorder->length;