~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql/opt_range.cc

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2010-06-21 15:31:05 UTC
  • mfrom: (1.1.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 6.
  • Revision ID: james.westby@ubuntu.com-20100621153105-pbbz3t6nyrf9t2zq
Tags: upstream-5.1.48
ImportĀ upstreamĀ versionĀ 5.1.48

Show diffs side-by-side

added added

removed removed

Lines of Context:
8532
8532
{
8533
8533
  int             result;
8534
8534
  KEY_MULTI_RANGE *mrange;
8535
 
  key_range       *start_key;
8536
 
  key_range       *end_key;
8537
8535
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
8538
8536
  DBUG_ASSERT(multi_range_length && multi_range &&
8539
8537
              (cur_range >= (QUICK_RANGE**) ranges.buffer) &&
8573
8571
         mrange_slot < mrange_end;
8574
8572
         mrange_slot++)
8575
8573
    {
8576
 
      start_key= &mrange_slot->start_key;
8577
 
      end_key= &mrange_slot->end_key;
8578
8574
      last_range= *(cur_range++);
8579
 
 
8580
 
      start_key->key=    (const uchar*) last_range->min_key;
8581
 
      start_key->length= last_range->min_length;
8582
 
      start_key->flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8583
 
                          (last_range->flag & EQ_RANGE) ?
8584
 
                          HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8585
 
      start_key->keypart_map= last_range->min_keypart_map;
8586
 
      end_key->key=      (const uchar*) last_range->max_key;
8587
 
      end_key->length=   last_range->max_length;
8588
 
      /*
8589
 
        We use HA_READ_AFTER_KEY here because if we are reading on a key
8590
 
        prefix. We want to find all keys with this prefix.
8591
 
      */
8592
 
      end_key->flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8593
 
                          HA_READ_AFTER_KEY);
8594
 
      end_key->keypart_map= last_range->max_keypart_map;
8595
 
 
 
8575
      last_range->make_min_endpoint(&mrange_slot->start_key);
 
8576
      last_range->make_max_endpoint(&mrange_slot->end_key);
8596
8577
      mrange_slot->range_flag= last_range->flag;
8597
8578
    }
8598
8579
 
8616
8597
/*
8617
8598
  Get the next record with a different prefix.
8618
8599
 
8619
 
  SYNOPSIS
8620
 
    QUICK_RANGE_SELECT::get_next_prefix()
8621
 
    prefix_length  length of cur_prefix
8622
 
    cur_prefix     prefix of a key to be searched for
8623
 
 
8624
 
  DESCRIPTION
8625
 
    Each subsequent call to the method retrieves the first record that has a
8626
 
    prefix with length prefix_length different from cur_prefix, such that the
8627
 
    record with the new prefix is within the ranges described by
8628
 
    this->ranges. The record found is stored into the buffer pointed by
8629
 
    this->record.
8630
 
    The method is useful for GROUP-BY queries with range conditions to
8631
 
    discover the prefix of the next group that satisfies the range conditions.
8632
 
 
8633
 
  TODO
 
8600
  @param prefix_length   length of cur_prefix
 
8601
  @param group_key_parts The number of key parts in the group prefix
 
8602
  @param cur_prefix      prefix of a key to be searched for
 
8603
 
 
8604
  Each subsequent call to the method retrieves the first record that has a
 
8605
  prefix with length prefix_length and which is different from cur_prefix,
 
8606
  such that the record with the new prefix is within the ranges described by
 
8607
  this->ranges. The record found is stored into the buffer pointed by
 
8608
  this->record. The method is useful for GROUP-BY queries with range
 
8609
  conditions to discover the prefix of the next group that satisfies the range
 
8610
  conditions.
 
8611
 
 
8612
  @todo
 
8613
 
8634
8614
    This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
8635
8615
    methods should be unified into a more general one to reduce code
8636
8616
    duplication.
8637
8617
 
8638
 
  RETURN
8639
 
    0                  on success
8640
 
    HA_ERR_END_OF_FILE if returned all keys
8641
 
    other              if some error occurred
 
8618
  @retval 0                  on success
 
8619
  @retval HA_ERR_END_OF_FILE if returned all keys
 
8620
  @retval other              if some error occurred
8642
8621
*/
8643
8622
 
8644
8623
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
8645
 
                                        key_part_map keypart_map,
 
8624
                                        uint group_key_parts,
8646
8625
                                        uchar *cur_prefix)
8647
8626
{
8648
8627
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
 
8628
  const key_part_map keypart_map= make_prev_keypart_map(group_key_parts);
8649
8629
 
8650
8630
  for (;;)
8651
8631
  {
8652
8632
    int result;
8653
 
    key_range start_key, end_key;
8654
8633
    if (last_range)
8655
8634
    {
8656
8635
      /* Read the next record in the same range with prefix after cur_prefix. */
8657
 
      DBUG_ASSERT(cur_prefix != 0);
 
8636
      DBUG_ASSERT(cur_prefix != NULL);
8658
8637
      result= file->index_read_map(record, cur_prefix, keypart_map,
8659
8638
                                   HA_READ_AFTER_KEY);
8660
 
      if (result || (file->compare_key(file->end_range) <= 0))
 
8639
      if (result || last_range->max_keypart_map == 0)
8661
8640
        DBUG_RETURN(result);
 
8641
 
 
8642
      key_range previous_endpoint;
 
8643
      last_range->make_max_endpoint(&previous_endpoint, prefix_length, keypart_map);
 
8644
      if (file->compare_key(&previous_endpoint) <= 0)
 
8645
        DBUG_RETURN(0);
8662
8646
    }
8663
8647
 
8664
8648
    uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
8670
8654
    }
8671
8655
    last_range= *(cur_range++);
8672
8656
 
8673
 
    start_key.key=    (const uchar*) last_range->min_key;
8674
 
    start_key.length= min(last_range->min_length, prefix_length);
8675
 
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
8676
 
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8677
 
                       (last_range->flag & EQ_RANGE) ?
8678
 
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8679
 
    end_key.key=      (const uchar*) last_range->max_key;
8680
 
    end_key.length=   min(last_range->max_length, prefix_length);
8681
 
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
8682
 
    /*
8683
 
      We use READ_AFTER_KEY here because if we are reading on a key
8684
 
      prefix we want to find all keys with this prefix
8685
 
    */
8686
 
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8687
 
                       HA_READ_AFTER_KEY);
 
8657
    key_range start_key, end_key;
 
8658
    last_range->make_min_endpoint(&start_key, prefix_length, keypart_map);
 
8659
    last_range->make_max_endpoint(&end_key, prefix_length, keypart_map);
8688
8660
 
8689
8661
    result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
8690
8662
                                   last_range->max_keypart_map ? &end_key : 0,
8779
8751
}
8780
8752
 
8781
8753
/*
8782
 
  This is a hack: we inherit from QUICK_SELECT so that we can use the
 
8754
  This is a hack: we inherit from QUICK_RANGE_SELECT so that we can use the
8783
8755
  get_next() interface, but we have to hold a pointer to the original
8784
 
  QUICK_SELECT because its data are used all over the place.  What
 
8756
  QUICK_RANGE_SELECT because its data are used all over the place. What
8785
8757
  should be done is to factor out the data that is needed into a base
8786
8758
  class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
8787
8759
  which handle the ranges and implement the get_next() function.  But
10903
10875
  {
10904
10876
    uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
10905
10877
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
10906
 
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
 
10878
                                                      group_key_parts, 
 
10879
                                                      cur_prefix)))
10907
10880
      DBUG_RETURN(result);
10908
10881
    seen_first_key= TRUE;
10909
10882
  }