~ubuntu-branches/ubuntu/gutsy/mysql-dfsg-5.0/gutsy

« back to all changes in this revision

Viewing changes to libmysqld/opt_range.cc

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2007-04-03 09:43:01 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20070403094301-fnjhfr59hu72pvtg
Tags: 5.0.38-0ubuntu1
* Package the Enterprise version again (.37 was a community version), since
  Debian and we have always done so. This brings in a few more bug fixes and
  makes functional derivations less likely.
* debian/README.Maintainer: Add pointer to upstream download URL, since it
  is very hard to find the Enterprise versions.
* Disable 33_scripts__mysql_create_system_tables__no_test.dpatch, since that
  script was removed upstream.
* debian/patches/41_scripts__mysql_install_db.sh__no_test.dpatch: Adapted to
  changed formatting in new upstream version.
* Remove debian/patches/86_PATH_MAX.dpatch, fixed upstream.
* Add debian/patches/90_org_tables_definition.dpatch: Fix local variable
  declaration in libmysqld/sql_parse.cc to fix compilation with
  EMBEDDED_LIBRARY.

Show diffs side-by-side

added added

removed removed

Lines of Context:
499
499
                                         double read_time);
500
500
static
501
501
TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree);
502
 
static int get_index_merge_params(PARAM *param, key_map& needed_reg,
503
 
                           SEL_IMERGE *imerge, double *read_time,
504
 
                           ha_rows* imerge_rows);
505
502
static double get_index_only_read_time(const PARAM* param, ha_rows records,
506
503
                                       int keynr);
507
504
 
511
508
static void print_ror_scans_arr(TABLE *table, const char *msg,
512
509
                                struct st_ror_scan_info **start,
513
510
                                struct st_ror_scan_info **end);
514
 
static void print_rowid(byte* val, int len);
515
511
static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg);
516
512
#endif
517
513
 
823
819
 
824
820
QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
825
821
                                       bool no_alloc, MEM_ROOT *parent_alloc)
826
 
  :dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),range(0)
 
822
  :dont_free(0),error(0),free_file(0),in_range(0),cur_range(NULL),last_range(0)
827
823
{
828
824
  sorted= 0;
829
825
  index= key_nr;
1248
1244
 
1249
1245
int QUICK_ROR_UNION_SELECT::reset()
1250
1246
{
1251
 
  QUICK_SELECT_I* quick;
 
1247
  QUICK_SELECT_I *quick;
1252
1248
  int error;
1253
1249
  DBUG_ENTER("QUICK_ROR_UNION_SELECT::reset");
1254
1250
  have_prev_rowid= FALSE;
1255
1251
  if (!scans_inited)
1256
1252
  {
1257
 
    QUICK_SELECT_I *quick;
1258
1253
    List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
1259
1254
    while ((quick= it++))
1260
1255
    {
6614
6609
  byte  *mrange_buff;
6615
6610
  DBUG_ENTER("QUICK_RANGE_SELECT::reset");
6616
6611
  next=0;
6617
 
  range= NULL;
 
6612
  last_range= NULL;
6618
6613
  in_range= FALSE;
6619
6614
  cur_range= (QUICK_RANGE**) ranges.buffer;
6620
6615
 
6732
6727
    {
6733
6728
      start_key= &mrange_slot->start_key;
6734
6729
      end_key= &mrange_slot->end_key;
6735
 
      range= *(cur_range++);
 
6730
      last_range= *(cur_range++);
6736
6731
 
6737
 
      start_key->key=    (const byte*) range->min_key;
6738
 
      start_key->length= range->min_length;
6739
 
      start_key->flag=   ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6740
 
                          (range->flag & EQ_RANGE) ?
 
6732
      start_key->key=    (const byte*) last_range->min_key;
 
6733
      start_key->length= last_range->min_length;
 
6734
      start_key->flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
6735
                          (last_range->flag & EQ_RANGE) ?
6741
6736
                          HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
6742
 
      end_key->key=      (const byte*) range->max_key;
6743
 
      end_key->length=   range->max_length;
 
6737
      end_key->key=      (const byte*) last_range->max_key;
 
6738
      end_key->length=   last_range->max_length;
6744
6739
      /*
6745
6740
        We use HA_READ_AFTER_KEY here because if we are reading on a key
6746
6741
        prefix. We want to find all keys with this prefix.
6747
6742
      */
6748
 
      end_key->flag=     (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
6743
      end_key->flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6749
6744
                          HA_READ_AFTER_KEY);
6750
6745
 
6751
 
      mrange_slot->range_flag= range->flag;
 
6746
      mrange_slot->range_flag= last_range->flag;
6752
6747
    }
6753
6748
 
6754
6749
    result= file->read_multi_range_first(&mrange, multi_range, count,
6798
6793
  {
6799
6794
    int result;
6800
6795
    key_range start_key, end_key;
6801
 
    if (range)
 
6796
    if (last_range)
6802
6797
    {
6803
6798
      /* Read the next record in the same range with prefix after cur_prefix. */
6804
6799
      DBUG_ASSERT(cur_prefix != 0);
6812
6807
    if (count == 0)
6813
6808
    {
6814
6809
      /* Ranges have already been used up before. None is left for read. */
6815
 
      range= 0;
 
6810
      last_range= 0;
6816
6811
      DBUG_RETURN(HA_ERR_END_OF_FILE);
6817
6812
    }
6818
 
    range= *(cur_range++);
 
6813
    last_range= *(cur_range++);
6819
6814
 
6820
 
    start_key.key=    (const byte*) range->min_key;
6821
 
    start_key.length= min(range->min_length, prefix_length);
6822
 
    start_key.flag=   ((range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
6823
 
                       (range->flag & EQ_RANGE) ?
 
6815
    start_key.key=    (const byte*) last_range->min_key;
 
6816
    start_key.length= min(last_range->min_length, prefix_length);
 
6817
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
 
6818
                       (last_range->flag & EQ_RANGE) ?
6824
6819
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
6825
 
    end_key.key=      (const byte*) range->max_key;
6826
 
    end_key.length=   min(range->max_length, prefix_length);
 
6820
    end_key.key=      (const byte*) last_range->max_key;
 
6821
    end_key.length=   min(last_range->max_length, prefix_length);
6827
6822
    /*
6828
6823
      We use READ_AFTER_KEY here because if we are reading on a key
6829
6824
      prefix we want to find all keys with this prefix
6830
6825
    */
6831
 
    end_key.flag=     (range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
 
6826
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
6832
6827
                       HA_READ_AFTER_KEY);
6833
6828
 
6834
 
    result= file->read_range_first(range->min_length ? &start_key : 0,
6835
 
                                   range->max_length ? &end_key : 0,
6836
 
                                   test(range->flag & EQ_RANGE),
 
6829
    result= file->read_range_first(last_range->min_length ? &start_key : 0,
 
6830
                                   last_range->max_length ? &end_key : 0,
 
6831
                                   test(last_range->flag & EQ_RANGE),
6837
6832
                                   sorted);
6838
 
    if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
6839
 
      range=0;                          // Stop searching
 
6833
    if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
 
6834
      last_range= 0;                    // Stop searching
6840
6835
 
6841
6836
    if (result != HA_ERR_END_OF_FILE)
6842
6837
      DBUG_RETURN(result);
6843
 
    range=0;                            // No matching rows; go to next range
 
6838
    last_range= 0;                      // No matching rows; go to next range
6844
6839
  }
6845
6840
}
6846
6841
 
6854
6849
  for (;;)
6855
6850
  {
6856
6851
    int result;
6857
 
    if (range)
 
6852
    if (last_range)
6858
6853
    {
6859
6854
      // Already read through key
6860
 
      result= file->index_next_same(record, (byte*) range->min_key,
6861
 
                                    range->min_length);
 
6855
      result= file->index_next_same(record, (byte*) last_range->min_key,
 
6856
                                    last_range->min_length);
6862
6857
      if (result != HA_ERR_END_OF_FILE)
6863
6858
        DBUG_RETURN(result);
6864
6859
    }
6867
6862
    if (count == 0)
6868
6863
    {
6869
6864
      /* Ranges have already been used up before. None is left for read. */
6870
 
      range= 0;
 
6865
      last_range= 0;
6871
6866
      DBUG_RETURN(HA_ERR_END_OF_FILE);
6872
6867
    }
6873
 
    range= *(cur_range++);
 
6868
    last_range= *(cur_range++);
6874
6869
 
6875
6870
    result= file->index_read(record,
6876
 
                             (byte*) range->min_key,
6877
 
                             range->min_length,
6878
 
                             (ha_rkey_function)(range->flag ^ GEOM_FLAG));
 
6871
                             (byte*) last_range->min_key,
 
6872
                             last_range->min_length,
 
6873
                             (ha_rkey_function)(last_range->flag ^ GEOM_FLAG));
6879
6874
    if (result != HA_ERR_KEY_NOT_FOUND)
6880
6875
      DBUG_RETURN(result);
6881
 
    range=0;                            // Not found, to next range
 
6876
    last_range= 0;                              // Not found, to next range
6882
6877
  }
6883
6878
}
6884
6879
 
6903
6898
 
6904
6899
bool QUICK_RANGE_SELECT::row_in_ranges()
6905
6900
{
6906
 
  QUICK_RANGE *range;
 
6901
  QUICK_RANGE *res;
6907
6902
  uint min= 0;
6908
6903
  uint max= ranges.elements - 1;
6909
6904
  uint mid= (max + min)/2;
6919
6914
      max= mid;
6920
6915
    mid= (min + max) / 2;
6921
6916
  }
6922
 
  range= *(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
6923
 
  return (!cmp_next(range) && !cmp_prev(range));
 
6917
  res= *(QUICK_RANGE**)dynamic_array_ptr(&ranges, mid);
 
6918
  return (!cmp_next(res) && !cmp_prev(res));
6924
6919
}
6925
6920
 
6926
6921
/*
6934
6929
 */
6935
6930
 
6936
6931
QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
6937
 
                                     uint used_key_parts)
 
6932
                                     uint used_key_parts_arg)
6938
6933
 : QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
6939
6934
{
6940
6935
  QUICK_RANGE *r;
6941
6936
 
6942
6937
  QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
6943
 
  QUICK_RANGE **last_range= pr + ranges.elements;
6944
 
  for (; pr!=last_range; pr++)
 
6938
  QUICK_RANGE **end_range= pr + ranges.elements;
 
6939
  for (; pr!=end_range; pr++)
6945
6940
    rev_ranges.push_front(*pr);
6946
6941
 
6947
6942
  /* Remove EQ_RANGE flag for keys that are not using the full key */
6975
6970
  for (;;)
6976
6971
  {
6977
6972
    int result;
6978
 
    if (range)
 
6973
    if (last_range)
6979
6974
    {                                           // Already read through key
6980
 
      result = ((range->flag & EQ_RANGE)
6981
 
                ? file->index_next_same(record, (byte*) range->min_key,
6982
 
                                        range->min_length) :
 
6975
      result = ((last_range->flag & EQ_RANGE)
 
6976
                ? file->index_next_same(record, (byte*) last_range->min_key,
 
6977
                                        last_range->min_length) :
6983
6978
                file->index_prev(record));
6984
6979
      if (!result)
6985
6980
      {
6990
6985
        DBUG_RETURN(result);
6991
6986
    }
6992
6987
 
6993
 
    if (!(range=rev_it++))
 
6988
    if (!(last_range= rev_it++))
6994
6989
      DBUG_RETURN(HA_ERR_END_OF_FILE);          // All ranges used
6995
6990
 
6996
 
    if (range->flag & NO_MAX_RANGE)             // Read last record
 
6991
    if (last_range->flag & NO_MAX_RANGE)        // Read last record
6997
6992
    {
6998
6993
      int local_error;
6999
6994
      if ((local_error=file->index_last(record)))
7000
6995
        DBUG_RETURN(local_error);               // Empty table
7001
 
      if (cmp_prev(range) == 0)
 
6996
      if (cmp_prev(last_range) == 0)
7002
6997
        DBUG_RETURN(0);
7003
 
      range=0;                  // No matching records; go to next range
 
6998
      last_range= 0;                            // No match; go to next range
7004
6999
      continue;
7005
7000
    }
7006
7001
 
7007
 
    if (range->flag & EQ_RANGE)
 
7002
    if (last_range->flag & EQ_RANGE)
7008
7003
    {
7009
 
      result = file->index_read(record, (byte*) range->max_key,
7010
 
                                range->max_length, HA_READ_KEY_EXACT);
 
7004
      result= file->index_read(record, (byte*) last_range->max_key,
 
7005
                               last_range->max_length, HA_READ_KEY_EXACT);
7011
7006
    }
7012
7007
    else
7013
7008
    {
7014
 
      DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
7015
 
      result=file->index_read(record, (byte*) range->max_key,
7016
 
                              range->max_length,
7017
 
                              ((range->flag & NEAR_MAX) ?
7018
 
                               HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV));
 
7009
      DBUG_ASSERT(last_range->flag & NEAR_MAX ||
 
7010
                  range_reads_after_key(last_range));
 
7011
      result=file->index_read(record, (byte*) last_range->max_key,
 
7012
                              last_range->max_length,
 
7013
                              ((last_range->flag & NEAR_MAX) ?
 
7014
                               HA_READ_BEFORE_KEY :
 
7015
                               HA_READ_PREFIX_LAST_OR_PREV));
7019
7016
    }
7020
7017
    if (result)
7021
7018
    {
7022
7019
      if (result != HA_ERR_KEY_NOT_FOUND)
7023
7020
        DBUG_RETURN(result);
7024
 
      range=0;                                  // Not found, to next range
 
7021
      last_range= 0;                            // Not found, to next range
7025
7022
      continue;
7026
7023
    }
7027
 
    if (cmp_prev(range) == 0)
 
7024
    if (cmp_prev(last_range) == 0)
7028
7025
    {
7029
 
      if (range->flag == (UNIQUE_RANGE | EQ_RANGE))
7030
 
        range = 0;                              // Stop searching
 
7026
      if (last_range->flag == (UNIQUE_RANGE | EQ_RANGE))
 
7027
        last_range= 0;                          // Stop searching
7031
7028
      DBUG_RETURN(0);                           // Found key is in range
7032
7029
    }
7033
 
    range = 0;                                  // To next range
 
7030
    last_range= 0;                              // To next range
7034
7031
  }
7035
7032
}
7036
7033
 
7507
7504
  if ((join->tables != 1) ||  /* The query must reference one table. */
7508
7505
      ((!join->group_list) && /* Neither GROUP BY nor a DISTINCT query. */
7509
7506
       (!join->select_distinct)) ||
7510
 
      (thd->lex->select_lex.olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
 
7507
      (join->select_lex->olap == ROLLUP_TYPE)) /* Check (B3) for ROLLUP */
7511
7508
    DBUG_RETURN(NULL);
7512
7509
  if (table->s->keys == 0)        /* There are no indexes to use. */
7513
7510
    DBUG_RETURN(NULL);
9514
9511
}
9515
9512
 
9516
9513
 
9517
 
static void print_rowid(byte* val, int len)
9518
 
{
9519
 
  byte *pb;
9520
 
  DBUG_LOCK_FILE;
9521
 
  fputc('\"', DBUG_FILE);
9522
 
  for (pb= val; pb!= val + len; ++pb)
9523
 
    fprintf(DBUG_FILE, "%c", *pb);
9524
 
  fprintf(DBUG_FILE, "\", hex: ");
9525
 
 
9526
 
  for (pb= val; pb!= val + len; ++pb)
9527
 
    fprintf(DBUG_FILE, "%x ", *pb);
9528
 
  fputc('\n', DBUG_FILE);
9529
 
  DBUG_UNLOCK_FILE;
9530
 
}
9531
 
 
9532
9514
void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
9533
9515
{
 
9516
  /* purecov: begin inspected */
9534
9517
  fprintf(DBUG_FILE, "%*squick range select, key %s, length: %d\n",
9535
9518
          indent, "", head->key_info[index].name, max_used_key_length);
9536
9519
 
9538
9521
  {
9539
9522
    QUICK_RANGE *range;
9540
9523
    QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
9541
 
    QUICK_RANGE **last_range= pr + ranges.elements;
9542
 
    for (; pr!=last_range; ++pr)
 
9524
    QUICK_RANGE **end_range= pr + ranges.elements;
 
9525
    for (; pr != end_range; ++pr)
9543
9526
    {
9544
9527
      fprintf(DBUG_FILE, "%*s", indent + 2, "");
9545
9528
      range= *pr;
9564
9547
      fputs("\n",DBUG_FILE);
9565
9548
    }
9566
9549
  }
 
9550
  /* purecov: end */    
9567
9551
}
9568
9552
 
9569
9553
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)