Commit bb532336 authored by unknown's avatar unknown
Browse files

Merge


sql/opt_range.cc:
  SCCS merged
sql/records.cc:
  SCCS merged
parents 246df068 f47d9b5a
Loading
Loading
Loading
Loading
+15 −47
Original line number Diff line number Diff line
@@ -725,7 +725,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
  key_part_info= head->key_info[index].key_part;
  my_init_dynamic_array(&ranges, sizeof(QUICK_RANGE*), 16, 16);

  /* 'thd' is not accessible in QUICK_RANGE_SELECT::get_next_init(). */
  /* 'thd' is not accessible in QUICK_RANGE_SELECT::reset(). */
  multi_range_bufsiz= thd->variables.read_rnd_buff_size;
  multi_range_count= thd->variables.multi_range_count;
  multi_range_length= 0;
@@ -749,9 +749,6 @@ int QUICK_RANGE_SELECT::init()
{
  DBUG_ENTER("QUICK_RANGE_SELECT::init");

  if ((error= get_next_init()))
    DBUG_RETURN(error);

  if (file->inited == handler::NONE)
    DBUG_RETURN(error= file->ha_index_init(index));
  error= 0;
@@ -5655,9 +5652,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()
    We reuse the same instance of handler so we need to call both init and 
    reset here.
  */
  if (cur_quick->init())
  if (cur_quick->init() || cur_quick->reset())
    DBUG_RETURN(1);
  cur_quick->reset();

  unique= new Unique(refpos_order_cmp, (void *)head->file,
                     head->file->ref_length,
@@ -5675,10 +5671,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge()

      if (cur_quick->file->inited != handler::NONE) 
        cur_quick->file->ha_index_end();
      if (cur_quick->init())
      if (cur_quick->init() || cur_quick->reset())
        DBUG_RETURN(1);
      /* QUICK_RANGE_SELECT::reset never fails */
      cur_quick->reset();
    }

    if (result)
@@ -5745,9 +5739,8 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
    if (pk_quick_select)
    {
      doing_pk_scan= TRUE;
      if ((result= pk_quick_select->init()))
      if ((result= pk_quick_select->init()) || (result= pk_quick_select->reset()))
        DBUG_RETURN(result);
      pk_quick_select->reset();
      DBUG_RETURN(pk_quick_select->get_next());
    }
  }
@@ -5908,27 +5901,14 @@ int QUICK_ROR_UNION_SELECT::get_next()
  DBUG_RETURN(error);
}


/*
  Initialize data structures needed by get_next().

  SYNOPSIS
    QUICK_RANGE_SELECT::get_next_init()

  DESCRIPTION
    This is called from get_next() at its first call for an object.
    It allocates memory buffers and sets size variables.

  RETURN
    0           OK.
    != 0        Error.
*/

int QUICK_RANGE_SELECT::get_next_init(void)
int QUICK_RANGE_SELECT::reset()
{
  uint  mrange_bufsiz;
  byte  *mrange_buff;
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next_init");
  DBUG_ENTER("QUICK_RANGE_SELECT::reset");
  next=0;
  range= NULL;
  cur_range= (QUICK_RANGE**) ranges.buffer;
  
  /* Do not allocate the buffers twice. */
  if (multi_range_length)
@@ -5937,15 +5917,8 @@ int QUICK_RANGE_SELECT::get_next_init(void)
    DBUG_RETURN(0);
  }

  /* If the ranges are not yet initialized, wait for the next call. */
  if (! ranges.elements)
  {
    DBUG_RETURN(0);
  }

  /*
    Allocate the ranges array.
  */
  /* Allocate the ranges array. */
  DBUG_ASSERT(ranges.elements);
  multi_range_length= min(multi_range_count, ranges.elements);
  DBUG_ASSERT(multi_range_length > 0);
  while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
@@ -5962,9 +5935,7 @@ int QUICK_RANGE_SELECT::get_next_init(void)
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
  }

  /*
    Allocate the handler buffer if necessary.
  */
  /* Allocate the handler buffer if necessary.  */
  if (file->table_flags() & HA_NEED_READ_RANGE_BUFFER)
  {
    mrange_bufsiz= min(multi_range_bufsiz,
@@ -5992,9 +5963,6 @@ int QUICK_RANGE_SELECT::get_next_init(void)
    multi_range_buff->buffer_end= mrange_buff + mrange_bufsiz;
    multi_range_buff->end_of_used_area= mrange_buff;
  }

  /* Initialize the current QUICK_RANGE pointer. */
  cur_range= (QUICK_RANGE**) ranges.buffer;
  DBUG_RETURN(0);
}

@@ -7948,10 +7916,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
  result= file->ha_index_init(index);
  result= file->index_last(record);
  if (quick_prefix_select)
    quick_prefix_select->reset();
  if (result)
    DBUG_RETURN(result);
  if (quick_prefix_select && quick_prefix_select->reset())
    DBUG_RETURN(1);
  /* Save the prefix of the last group. */
  key_copy(last_prefix, record, index_info, group_prefix_len);

+46 −27
Original line number Diff line number Diff line
@@ -59,6 +59,44 @@ class QUICK_RANGE :public Sql_alloc {
/*
  Quick select interface.
  This class is a parent for all QUICK_*_SELECT and FT_SELECT classes.
  
  The usage scenario is as follows:
  1. Create quick select
    quick= new QUICK_XXX_SELECT(...);
    
  2. Perform lightweight initialization. This can be done in 2 ways:
  2.a: Regular initialization
    if (quick->init())
    {
      //the only valid action after failed init() call is delete
      delete quick;
    }
  2.b: Special initialization for quick selects merged by QUICK_ROR_*_SELECT
    if (quick->init_ror_merged_scan())
      delete quick;
        
  3. Perform zero, one, or more scans.
    while (...)
    {
      // initialize quick select for scan. This may allocate
      // buffers and/or prefetch rows. 
      if (quick->reset())
      {
        //the only valid action after failed reset() call is delete
        delete quick;
        //abort query
      }
      
      // perform the scan
      do
      {
        res= quick->get_next();
      } while (res && ...)
    }
    
  4. Delete the select:
    delete quick;
  
*/

class QUICK_SELECT_I
@@ -117,27 +155,16 @@ class QUICK_SELECT_I
    reset() should be called when it is certain that row retrieval will be
    necessary. This call may do heavyweight initialization like buffering first
    N records etc. If reset() call fails get_next() must not be called.
    Note that reset() may be called several times if this quick select 
    executes in a subselect.
    Note that reset() may be called several times if 
     * the quick select is executed in a subselect
     * a JOIN buffer is used
    
    RETURN
      0      OK
      other  Error code
  */
  virtual int  reset(void) = 0;

  /*
    Initialize get_next() for row retrieval.
    SYNOPSIS
      get_next_init()

    get_next_init() must be called before the first get_next().
    If get_next_init() call fails get_next() must not be called.

    RETURN
      0      OK
      other  Error code
  */
  virtual int  get_next_init() { return false; }
  virtual int  get_next() = 0;   /* get next record to retrieve */

  /* Range end should be called when we have looped over the whole index */
@@ -284,18 +311,7 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
  ~QUICK_RANGE_SELECT();

  int init();
  int reset(void)
  {
    next=0;
    range= NULL;
    cur_range= (QUICK_RANGE**) ranges.buffer;
    /*
      Note: in opt_range.cc there are places where it is assumed that this
      function always succeeds 
    */
    return 0;
  }
  int get_next_init(void);
  int reset(void);
  int get_next();
  void range_end();
  int get_next_prefix(uint prefix_length, byte *cur_prefix);
@@ -310,6 +326,8 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
#ifndef DBUG_OFF
  void dbug_dump(int indent, bool verbose);
#endif
private:
  /* Used only by QUICK_SELECT_DESC */
  QUICK_RANGE_SELECT(const QUICK_RANGE_SELECT& org) : QUICK_SELECT_I()
  {
    bcopy(&org, this, sizeof(*this));
@@ -685,6 +703,7 @@ class FT_SELECT: public QUICK_RANGE_SELECT {
      QUICK_RANGE_SELECT (thd, table, key, 1) { init(); }
  ~FT_SELECT() { file->ft_end(); }
  int init() { return error=file->ft_init(); }
  int reset() { return 0; }
  int get_next() { return error=file->ft_read(record); }
  int get_type() { return QS_TYPE_FULLTEXT; }
};
+0 −11
Original line number Diff line number Diff line
@@ -100,19 +100,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
  }
  else if (select && select->quick)
  {
    int error;
    DBUG_PRINT("info",("using rr_quick"));

    if (!table->file->inited)
      table->file->ha_index_init(select->quick->index);
    info->read_record=rr_quick;

    if ((error= select->quick->get_next_init()))
    {
      /* Cannot return error code here. Instead print to error log. */
      table->file->print_error(error,MYF(ME_NOREFRESH));
      thd->fatal_error();
    }
  }
  else if (table->sort.record_pointers)
  {