~ubuntu-branches/ubuntu/lucid/mysql-dfsg-5.1/lucid-security

« back to all changes in this revision

Viewing changes to sql/opt_range.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 22:33:55 UTC
  • mfrom: (1.1.5)
  • Revision ID: package-import@ubuntu.com-20120222223355-or06x1euyk8n0ldi
Tags: 5.1.61-0ubuntu0.10.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496
* Dropped patches unnecessary with 5.1.61:
  - debian/patches/90_mysql_safer_strmov.dpatch
  - debian/patches/51_ssl_test_certs.dpatch
  - debian/patches/52_CVE-2009-4030.dpatch
  - debian/patches/53_CVE-2009-4484.dpatch
  - debian/patches/54_CVE-2008-7247.dpatch
  - debian/patches/55_CVE-2010-1621.dpatch
  - debian/patches/56_CVE-2010-1850.dpatch
  - debian/patches/57_CVE-2010-1849.dpatch
  - debian/patches/58_CVE-2010-1848.dpatch
  - debian/patches/59_CVE-2010-1626.dpatch
  - debian/patches/60_CVE-2010-2008.dpatch
  - debian/patches/60_CVE-2010-3677.dpatch
  - debian/patches/60_CVE-2010-3678.dpatch
  - debian/patches/60_CVE-2010-3679.dpatch
  - debian/patches/60_CVE-2010-3680.dpatch
  - debian/patches/60_CVE-2010-3681.dpatch
  - debian/patches/60_CVE-2010-3682.dpatch
  - debian/patches/60_CVE-2010-3683.dpatch
  - debian/patches/60_CVE-2010-3833.dpatch
  - debian/patches/60_CVE-2010-3834.dpatch
  - debian/patches/60_CVE-2010-3835.dpatch
  - debian/patches/60_CVE-2010-3836.dpatch
  - debian/patches/60_CVE-2010-3837.dpatch
  - debian/patches/60_CVE-2010-3838.dpatch
  - debian/patches/60_CVE-2010-3839.dpatch
  - debian/patches/60_CVE-2010-3840.dpatch
  - debian/patches/61_disable_longfilename_test.dpatch
  - debian/patches/62_alter_table_fix.dpatch
  - debian/patches/63_cherrypick-upstream-49479.dpatch
  - debian/patches/10_readline_build_fix.dpatch
* debian/mysql-client-5.1.docs: removed EXCEPTIONS-CLIENT file
* debian/mysql-server-5.1.docs,debian/libmysqlclient16.docs,
  debian/libmysqlclient-dev.docs: removed, no longer necessary.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
 
1
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
446
446
                                  range_key, *range_key_flag);
447
447
    *range_key_flag|= key_tree->min_flag;
448
448
    if (key_tree->next_key_part &&
 
449
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
449
450
        key_tree->next_key_part->part == key_tree->part+1 &&
450
 
        !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)) &&
451
 
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
451
        !(*range_key_flag & (NO_MIN_RANGE | NEAR_MIN)))
452
452
      res+= key_tree->next_key_part->store_min_key(key, range_key,
453
453
                                                   range_key_flag);
454
454
    return res;
462
462
                                 range_key, *range_key_flag);
463
463
    (*range_key_flag)|= key_tree->max_flag;
464
464
    if (key_tree->next_key_part &&
 
465
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
465
466
        key_tree->next_key_part->part == key_tree->part+1 &&
466
 
        !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)) &&
467
 
        key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
467
        !(*range_key_flag & (NO_MAX_RANGE | NEAR_MAX)))
468
468
      res+= key_tree->next_key_part->store_max_key(key, range_key,
469
469
                                                   range_key_flag);
470
470
    return res;
1171
1171
    if (file) 
1172
1172
    {
1173
1173
      range_end();
1174
 
      if (head->key_read)
1175
 
      {
1176
 
        head->key_read= 0;
1177
 
        file->extra(HA_EXTRA_NO_KEYREAD);
1178
 
      }
 
1174
      head->set_keyread(FALSE);
1179
1175
      if (free_file)
1180
1176
      {
1181
1177
        DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
1198
1194
 
1199
1195
QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param,
1200
1196
                                                   TABLE *table)
1201
 
  :pk_quick_select(NULL), thd(thd_param)
 
1197
  :unique(NULL), pk_quick_select(NULL), thd(thd_param)
1202
1198
{
1203
1199
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
1204
1200
  index= MAX_KEY;
1240
1236
  List_iterator_fast<QUICK_RANGE_SELECT> quick_it(quick_selects);
1241
1237
  QUICK_RANGE_SELECT* quick;
1242
1238
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
 
1239
  delete unique;
1243
1240
  quick_it.rewind();
1244
1241
  while ((quick= quick_it++))
1245
1242
    quick->file= NULL;
1338
1335
  }
1339
1336
 
1340
1337
  thd= head->in_use;
1341
 
  if (!(file= head->file->clone(thd->mem_root)))
 
1338
  if (!(file= head->file->clone(head->s->normalized_path.str, thd->mem_root)))
1342
1339
  {
1343
1340
    /* 
1344
1341
      Manually set the error flag. Note: there seems to be quite a few
1377
1374
  head->file= file;
1378
1375
  /* We don't have to set 'head->keyread' here as the 'file' is unique */
1379
1376
  if (!head->no_keyread)
1380
 
  {
1381
 
    head->key_read= 1;
1382
1377
    head->mark_columns_used_by_index(index);
1383
 
  }
1384
1378
  head->prepare_for_position();
1385
1379
  head->file= org_file;
1386
1380
  bitmap_copy(&column_bitmap, head->read_set);
1700
1694
    tmp->prev= *next_arg;                       // Link into next/prev chain
1701
1695
    (*next_arg)->next=tmp;
1702
1696
    (*next_arg)= tmp;
 
1697
    tmp->part= this->part;
1703
1698
  }
1704
1699
  else
1705
1700
  {
5531
5526
        SEL_TREE *tmp= get_full_func_mm_tree(param, cond_func, 
5532
5527
                                    field_item, (Item*)(intptr)i, inv);
5533
5528
        if (inv)
 
5529
        {
5534
5530
          tree= !tree ? tmp : tree_or(param, tree, tmp);
 
5531
          if (tree == NULL)
 
5532
            break;
 
5533
        }
5535
5534
        else 
5536
5535
          tree= tree_and(param, tree, tmp);
5537
5536
      }
6671
6670
    else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
6672
6671
    {                                           // Found tmp.max < key2.min
6673
6672
      SEL_ARG *next=tmp->next;
 
6673
      /* key1 on the left of key2 non-overlapping */
6674
6674
      if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
6675
6675
      {
6676
6676
        // Join near ranges like tmp.max < 0 and key2.min >= 0
6699
6699
      int tmp_cmp;
6700
6700
      if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
6701
6701
      {
 
6702
        /* tmp is on the right of key2 non-overlapping */
6702
6703
        if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
6703
6704
        {                                       // ranges are connected
6704
6705
          tmp->copy_min_to_min(key2);
6733
6734
      }
6734
6735
    }
6735
6736
 
6736
 
    // tmp.max >= key2.min && tmp.min <= key.max  (overlapping ranges)
 
6737
    /* 
 
6738
      tmp.min >= key2.min && tmp.min <= key.max  (overlapping ranges)
 
6739
      key2.min <= tmp.min <= key2.max 
 
6740
    */  
6737
6741
    if (eq_tree(tmp->next_key_part,key2->next_key_part))
6738
6742
    {
6739
6743
      if (tmp->is_same(key2))
6740
6744
      {
 
6745
        /* 
 
6746
          Found exact match of key2 inside key1. 
 
6747
          Use the relevant range in key1.
 
6748
        */
6741
6749
        tmp->merge_flags(key2);                 // Copy maybe flags
6742
6750
        key2->increment_use_count(-1);          // Free not used tree
6743
6751
      }
6744
6752
      else
6745
6753
      {
6746
6754
        SEL_ARG *last=tmp;
 
6755
        SEL_ARG *first=tmp;
 
6756
        /* 
 
6757
          Find the last range in tmp that overlaps key2 and has the same 
 
6758
          condition on the rest of the keyparts.
 
6759
        */
6747
6760
        while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
6748
6761
               eq_tree(last->next->next_key_part,key2->next_key_part))
6749
6762
        {
 
6763
          /*
 
6764
            We've found the last overlapping key1 range in last.
 
6765
            This means that the ranges between (and including) the 
 
6766
            first overlapping range (tmp) and the last overlapping range
 
6767
            (last) are fully nested into the current range of key2 
 
6768
            and can safely be discarded. We just need the minimum endpoint
 
6769
            of the first overlapping range (tmp) so we can compare it with
 
6770
            the minimum endpoint of the enclosing key2 range.
 
6771
          */
6750
6772
          SEL_ARG *save=last;
6751
6773
          last=last->next;
6752
6774
          key1=key1->tree_delete(save);
6753
6775
        }
6754
 
        last->copy_min(tmp);
 
6776
        /*
 
6777
          The tmp range (the first overlapping range) could have been discarded
 
6778
          by the previous loop. We should re-direct tmp to the new united range 
 
6779
          that's taking its place.
 
6780
        */
 
6781
        tmp= last;
 
6782
        last->copy_min(first);
6755
6783
        bool full_range= last->copy_min(key2);
6756
6784
        if (!full_range)
6757
6785
        {
7261
7289
}
7262
7290
 
7263
7291
 
7264
 
/*
7265
 
  Count how many times SEL_ARG graph "root" refers to its part "key"
 
7292
/**
 
7293
  Count how many times SEL_ARG graph "root" refers to its part "key" via
 
7294
  transitive closure.
7266
7295
  
7267
 
  SYNOPSIS
7268
 
    count_key_part_usage()
7269
 
      root  An RB-Root node in a SEL_ARG graph.
7270
 
      key   Another RB-Root node in that SEL_ARG graph.
7271
 
 
7272
 
  DESCRIPTION
7273
 
    The passed "root" node may refer to "key" node via root->next_key_part,
7274
 
    root->next->n
7275
 
 
7276
 
    This function counts how many times the node "key" is referred (via
7277
 
    SEL_ARG::next_key_part) by 
7278
 
     - intervals of RB-tree pointed by "root", 
7279
 
     - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from 
7280
 
       intervals of RB-tree pointed by "root",
7281
 
     - and so on.
 
7296
  @param root  An RB-Root node in a SEL_ARG graph.
 
7297
  @param key   Another RB-Root node in that SEL_ARG graph.
 
7298
 
 
7299
  The passed "root" node may refer to "key" node via root->next_key_part,
 
7300
  root->next->n
 
7301
 
 
7302
  This function counts how many times the node "key" is referred (via
 
7303
  SEL_ARG::next_key_part) by 
 
7304
  - intervals of RB-tree pointed by "root", 
 
7305
  - intervals of RB-trees that are pointed by SEL_ARG::next_key_part from 
 
7306
  intervals of RB-tree pointed by "root",
 
7307
  - and so on.
7282
7308
    
7283
 
    Here is an example (horizontal links represent next_key_part pointers, 
7284
 
    vertical links - next/prev prev pointers):  
 
7309
  Here is an example (horizontal links represent next_key_part pointers, 
 
7310
  vertical links - next/prev prev pointers):  
7285
7311
    
7286
7312
         +----+               $
7287
7313
         |root|-----------------+
7301
7327
          ...     +---+       $    |
7302
7328
                  |   |------------+
7303
7329
                  +---+       $
7304
 
  RETURN 
7305
 
    Number of links to "key" from nodes reachable from "root".
 
7330
  @return 
 
7331
  Number of links to "key" from nodes reachable from "root".
7306
7332
*/
7307
7333
 
7308
7334
static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key)
7557
7583
    param->first_null_comp= key_tree->part+1;
7558
7584
 
7559
7585
  if (key_tree->next_key_part &&
7560
 
      key_tree->next_key_part->part == key_tree->part+1 &&
7561
 
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
7586
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
 
7587
      key_tree->next_key_part->part == key_tree->part+1)
7562
7588
  {                                             // const key as prefix
7563
7589
    if (min_key_length == max_key_length &&
7564
7590
        !memcmp(min_key, max_key, (uint) (tmp_max_key - max_key)) &&
7597
7623
 
7598
7624
  if (unlikely(param->thd->killed != 0))
7599
7625
    return HA_POS_ERROR;
7600
 
  
 
7626
 
7601
7627
  keynr=param->real_keynr[idx];
7602
7628
  param->range_count++;
7603
7629
  if (!tmp_min_flag && ! tmp_max_flag &&
7839
7865
                                 &tmp_max_key,max_key_flag);
7840
7866
 
7841
7867
  if (key_tree->next_key_part &&
7842
 
      key_tree->next_key_part->part == key_tree->part+1 &&
7843
 
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE)
 
7868
      key_tree->next_key_part->type == SEL_ARG::KEY_RANGE &&
 
7869
      key_tree->next_key_part->part == key_tree->part+1)
7844
7870
  {                                               // const key as prefix
7845
7871
    if ((tmp_min_key - min_key) == (tmp_max_key - max_key) &&
7846
7872
         memcmp(min_key, max_key, (uint)(tmp_max_key - max_key))==0 &&
8132
8158
  List_iterator_fast<QUICK_RANGE_SELECT> cur_quick_it(quick_selects);
8133
8159
  QUICK_RANGE_SELECT* cur_quick;
8134
8160
  int result;
8135
 
  Unique *unique;
8136
8161
  handler *file= head->file;
8137
8162
  DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge");
8138
8163
 
8139
8164
  /* We're going to just read rowids. */
8140
 
  file->extra(HA_EXTRA_KEYREAD);
 
8165
  head->set_keyread(TRUE);
8141
8166
  head->prepare_for_position();
8142
8167
 
8143
8168
  cur_quick_it.rewind();
8151
8176
  if (cur_quick->init() || cur_quick->reset())
8152
8177
    DBUG_RETURN(1);
8153
8178
 
8154
 
  unique= new Unique(refpos_order_cmp, (void *)file,
8155
 
                     file->ref_length,
8156
 
                     thd->variables.sortbuff_size);
 
8179
  if (unique == NULL)
 
8180
  {
 
8181
    DBUG_EXECUTE_IF("index_merge_may_not_create_a_Unique", abort(); );
 
8182
    DBUG_EXECUTE_IF("only_one_Unique_may_be_created", 
 
8183
                    DBUG_SET("+d,index_merge_may_not_create_a_Unique"); );
 
8184
 
 
8185
    unique= new Unique(refpos_order_cmp, (void *)file,
 
8186
                       file->ref_length,
 
8187
                       thd->variables.sortbuff_size);
 
8188
  }
 
8189
  else
 
8190
    unique->reset();
 
8191
 
 
8192
  DBUG_ASSERT(file->ref_length == unique->get_size());
 
8193
  DBUG_ASSERT(thd->variables.sortbuff_size == unique->get_max_in_memory_size());
 
8194
 
8157
8195
  if (!unique)
8158
8196
    DBUG_RETURN(1);
8159
8197
  for (;;)
8168
8206
      if (cur_quick->file->inited != handler::NONE) 
8169
8207
        cur_quick->file->ha_index_end();
8170
8208
      if (cur_quick->init() || cur_quick->reset())
8171
 
      {
8172
 
        delete unique;
8173
8209
        DBUG_RETURN(1);
8174
 
      }
8175
8210
    }
8176
8211
 
8177
8212
    if (result)
8179
8214
      if (result != HA_ERR_END_OF_FILE)
8180
8215
      {
8181
8216
        cur_quick->range_end();
8182
 
        delete unique;
8183
8217
        DBUG_RETURN(result);
8184
8218
      }
8185
8219
      break;
8186
8220
    }
8187
8221
 
8188
8222
    if (thd->killed)
8189
 
    {
8190
 
      delete unique;
8191
8223
      DBUG_RETURN(1);
8192
 
    }
8193
8224
 
8194
8225
    /* skip row if it will be retrieved by clustered PK scan */
8195
8226
    if (pk_quick_select && pk_quick_select->row_in_ranges())
8198
8229
    cur_quick->file->position(cur_quick->record);
8199
8230
    result= unique->unique_add((char*)cur_quick->file->ref);
8200
8231
    if (result)
8201
 
    {
8202
 
      delete unique;
8203
8232
      DBUG_RETURN(1);
8204
 
    }
8205
8233
  }
8206
8234
 
8207
8235
  /*
8210
8238
    sequence.
8211
8239
  */
8212
8240
  result= unique->get(head);
8213
 
  delete unique;
8214
8241
  doing_pk_scan= FALSE;
8215
8242
  /* index_merge currently doesn't support "using index" at all */
8216
 
  file->extra(HA_EXTRA_NO_KEYREAD);
 
8243
  head->set_keyread(FALSE);
8217
8244
  init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE);
8218
8245
  DBUG_RETURN(result);
8219
8246
}
8328
8355
            if ((error= quick->get_next()))
8329
8356
              DBUG_RETURN(error);
8330
8357
          }
 
8358
          quick->file->position(quick->record);
8331
8359
        }
8332
8360
        memcpy(last_rowid, quick->file->ref, head->file->ref_length);
8333
8361
        last_rowid_count= 1;
8423
8451
  in_range= FALSE;
8424
8452
  cur_range= (QUICK_RANGE**) ranges.buffer;
8425
8453
 
8426
 
  if (file->inited == handler::NONE && (error= file->ha_index_init(index,1)))
8427
 
    DBUG_RETURN(error);
8428
 
 
 
8454
  if (file->inited == handler::NONE)
 
8455
  {
 
8456
    if (in_ror_merged_scan)
 
8457
      head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap);
 
8458
    if ((error= file->ha_index_init(index,1)))
 
8459
        DBUG_RETURN(error);
 
8460
  }
 
8461
 
8429
8462
  /* Do not allocate the buffers twice. */
8430
8463
  if (multi_range_length)
8431
8464
  {
8511
8544
{
8512
8545
  int             result;
8513
8546
  KEY_MULTI_RANGE *mrange;
8514
 
  key_range       *start_key;
8515
 
  key_range       *end_key;
8516
8547
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next");
8517
8548
  DBUG_ASSERT(multi_range_length && multi_range &&
8518
8549
              (cur_range >= (QUICK_RANGE**) ranges.buffer) &&
8552
8583
         mrange_slot < mrange_end;
8553
8584
         mrange_slot++)
8554
8585
    {
8555
 
      start_key= &mrange_slot->start_key;
8556
 
      end_key= &mrange_slot->end_key;
8557
8586
      last_range= *(cur_range++);
8558
 
 
8559
 
      start_key->key=    (const uchar*) last_range->min_key;
8560
 
      start_key->length= last_range->min_length;
8561
 
      start_key->flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8562
 
                          (last_range->flag & EQ_RANGE) ?
8563
 
                          HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8564
 
      start_key->keypart_map= last_range->min_keypart_map;
8565
 
      end_key->key=      (const uchar*) last_range->max_key;
8566
 
      end_key->length=   last_range->max_length;
8567
 
      /*
8568
 
        We use HA_READ_AFTER_KEY here because if we are reading on a key
8569
 
        prefix. We want to find all keys with this prefix.
8570
 
      */
8571
 
      end_key->flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8572
 
                          HA_READ_AFTER_KEY);
8573
 
      end_key->keypart_map= last_range->max_keypart_map;
8574
 
 
 
8587
      last_range->make_min_endpoint(&mrange_slot->start_key);
 
8588
      last_range->make_max_endpoint(&mrange_slot->end_key);
8575
8589
      mrange_slot->range_flag= last_range->flag;
8576
8590
    }
8577
8591
 
8595
8609
/*
8596
8610
  Get the next record with a different prefix.
8597
8611
 
8598
 
  SYNOPSIS
8599
 
    QUICK_RANGE_SELECT::get_next_prefix()
8600
 
    prefix_length  length of cur_prefix
8601
 
    cur_prefix     prefix of a key to be searched for
8602
 
 
8603
 
  DESCRIPTION
8604
 
    Each subsequent call to the method retrieves the first record that has a
8605
 
    prefix with length prefix_length different from cur_prefix, such that the
8606
 
    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.
8609
 
    The method is useful for GROUP-BY queries with range conditions to
8610
 
    discover the prefix of the next group that satisfies the range conditions.
8611
 
 
8612
 
  TODO
 
8612
  @param prefix_length   length of cur_prefix
 
8613
  @param group_key_parts The number of key parts in the group prefix
 
8614
  @param cur_prefix      prefix of a key to be searched for
 
8615
 
 
8616
  Each subsequent call to the method retrieves the first record that has a
 
8617
  prefix with length prefix_length and which is different from cur_prefix,
 
8618
  such that the record with the new prefix is within the ranges described by
 
8619
  this->ranges. The record found is stored into the buffer pointed by
 
8620
  this->record. The method is useful for GROUP-BY queries with range
 
8621
  conditions to discover the prefix of the next group that satisfies the range
 
8622
  conditions.
 
8623
 
 
8624
  @todo
 
8625
 
8613
8626
    This method is a modified copy of QUICK_RANGE_SELECT::get_next(), so both
8614
8627
    methods should be unified into a more general one to reduce code
8615
8628
    duplication.
8616
8629
 
8617
 
  RETURN
8618
 
    0                  on success
8619
 
    HA_ERR_END_OF_FILE if returned all keys
8620
 
    other              if some error occurred
 
8630
  @retval 0                  on success
 
8631
  @retval HA_ERR_END_OF_FILE if returned all keys
 
8632
  @retval other              if some error occurred
8621
8633
*/
8622
8634
 
8623
8635
int QUICK_RANGE_SELECT::get_next_prefix(uint prefix_length,
8624
 
                                        key_part_map keypart_map,
 
8636
                                        uint group_key_parts,
8625
8637
                                        uchar *cur_prefix)
8626
8638
{
8627
8639
  DBUG_ENTER("QUICK_RANGE_SELECT::get_next_prefix");
 
8640
  const key_part_map keypart_map= make_prev_keypart_map(group_key_parts);
8628
8641
 
8629
8642
  for (;;)
8630
8643
  {
8631
8644
    int result;
8632
 
    key_range start_key, end_key;
8633
8645
    if (last_range)
8634
8646
    {
8635
8647
      /* Read the next record in the same range with prefix after cur_prefix. */
8636
 
      DBUG_ASSERT(cur_prefix != 0);
 
8648
      DBUG_ASSERT(cur_prefix != NULL);
8637
8649
      result= file->index_read_map(record, cur_prefix, keypart_map,
8638
8650
                                   HA_READ_AFTER_KEY);
8639
 
      if (result || (file->compare_key(file->end_range) <= 0))
 
8651
      if (result || last_range->max_keypart_map == 0)
8640
8652
        DBUG_RETURN(result);
 
8653
 
 
8654
      key_range previous_endpoint;
 
8655
      last_range->make_max_endpoint(&previous_endpoint, prefix_length, keypart_map);
 
8656
      if (file->compare_key(&previous_endpoint) <= 0)
 
8657
        DBUG_RETURN(0);
8641
8658
    }
8642
8659
 
8643
8660
    uint count= ranges.elements - (cur_range - (QUICK_RANGE**) ranges.buffer);
8649
8666
    }
8650
8667
    last_range= *(cur_range++);
8651
8668
 
8652
 
    start_key.key=    (const uchar*) last_range->min_key;
8653
 
    start_key.length= min(last_range->min_length, prefix_length);
8654
 
    start_key.keypart_map= last_range->min_keypart_map & keypart_map;
8655
 
    start_key.flag=   ((last_range->flag & NEAR_MIN) ? HA_READ_AFTER_KEY :
8656
 
                       (last_range->flag & EQ_RANGE) ?
8657
 
                       HA_READ_KEY_EXACT : HA_READ_KEY_OR_NEXT);
8658
 
    end_key.key=      (const uchar*) last_range->max_key;
8659
 
    end_key.length=   min(last_range->max_length, prefix_length);
8660
 
    end_key.keypart_map= last_range->max_keypart_map & keypart_map;
8661
 
    /*
8662
 
      We use READ_AFTER_KEY here because if we are reading on a key
8663
 
      prefix we want to find all keys with this prefix
8664
 
    */
8665
 
    end_key.flag=     (last_range->flag & NEAR_MAX ? HA_READ_BEFORE_KEY :
8666
 
                       HA_READ_AFTER_KEY);
 
8669
    key_range start_key, end_key;
 
8670
    last_range->make_min_endpoint(&start_key, prefix_length, keypart_map);
 
8671
    last_range->make_max_endpoint(&end_key, prefix_length, keypart_map);
8667
8672
 
8668
8673
    result= file->read_range_first(last_range->min_keypart_map ? &start_key : 0,
8669
8674
                                   last_range->max_keypart_map ? &end_key : 0,
8758
8763
}
8759
8764
 
8760
8765
/*
8761
 
  This is a hack: we inherit from QUICK_SELECT so that we can use the
 
8766
  This is a hack: we inherit from QUICK_RANGE_SELECT so that we can use the
8762
8767
  get_next() interface, but we have to hold a pointer to the original
8763
 
  QUICK_SELECT because its data are used all over the place.  What
 
8768
  QUICK_RANGE_SELECT because its data are used all over the place. What
8764
8769
  should be done is to factor out the data that is needed into a base
8765
8770
  class (QUICK_SELECT), and then have two subclasses (_ASC and _DESC)
8766
8771
  which handle the ranges and implement the get_next() function.  But
9822
9827
    }
9823
9828
    else if (cur_arg->const_item())
9824
9829
    {
9825
 
      DBUG_RETURN(TRUE);
 
9830
      /*
 
9831
        For predicates of the form "const OP expr" we also have to check 'expr'
 
9832
        to make a decision.
 
9833
      */
 
9834
      continue;
9826
9835
    }
9827
9836
    else
9828
9837
      DBUG_RETURN(FALSE);
10279
10288
                           uint use_index, double read_cost_arg,
10280
10289
                           ha_rows records_arg, uint key_infix_len_arg,
10281
10290
                           uchar *key_infix_arg, MEM_ROOT *parent_alloc)
10282
 
  :join(join_arg), index_info(index_info_arg),
 
10291
  :file(table->file), join(join_arg), index_info(index_info_arg),
10283
10292
   group_prefix_len(group_prefix_len_arg),
10284
10293
   group_key_parts(group_key_parts_arg), have_min(have_min_arg),
10285
10294
   have_max(have_max_arg), seen_first_key(FALSE),
10288
10297
   max_functions_it(NULL)
10289
10298
{
10290
10299
  head=       table;
10291
 
  file=       head->file;
10292
10300
  index=      use_index;
10293
10301
  record=     head->record[0];
10294
10302
  tmp_record= head->record[1];
10596
10604
  int result;
10597
10605
  DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
10598
10606
 
10599
 
  file->extra(HA_EXTRA_KEYREAD); /* We need only the key attributes */
 
10607
  head->set_keyread(TRUE); /* We need only the key attributes */
10600
10608
  if ((result= file->ha_index_init(index,1)))
10601
10609
    DBUG_RETURN(result);
10602
10610
  if (quick_prefix_select && quick_prefix_select->reset())
10878
10886
  {
10879
10887
    uchar *cur_prefix= seen_first_key ? group_prefix : NULL;
10880
10888
    if ((result= quick_prefix_select->get_next_prefix(group_prefix_len,
10881
 
                         make_prev_keypart_map(group_key_parts), cur_prefix)))
 
10889
                                                      group_key_parts, 
 
10890
                                                      cur_prefix)))
10882
10891
      DBUG_RETURN(result);
10883
10892
    seen_first_key= TRUE;
10884
10893
  }