~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2009-05-09 22:13:47 UTC
  • mto: This revision was merged to the branch mainline in revision 1009.
  • Revision ID: mordred@inaugust.com-20090509221347-l712szviusbobro0
Re-added bitset<> as a replacement for Bitmap<>

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
#include "drizzled/index_hint.h"
50
50
 
51
51
#include <string>
 
52
#include <iostream>
52
53
 
53
54
using namespace std;
54
55
 
798
799
static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
799
800
{
800
801
  join_tab->packed_info= TAB_INFO_HAVE_VALUE;
801
 
  if (join_tab->table->covering_keys.is_set(join_tab->ref.key))
 
802
  if (join_tab->table->covering_keys.test(join_tab->ref.key))
802
803
    join_tab->packed_info |= TAB_INFO_USING_INDEX;
803
804
  if (where)
804
805
    join_tab->packed_info |= TAB_INFO_USING_WHERE;
3444
3445
  {
3445
3446
    TableList *embedding= tables->embedding;
3446
3447
    stat_vector[i]=s;
3447
 
    s->keys.init();
3448
 
    s->const_keys.init();
3449
 
    s->checked_keys.init();
3450
 
    s->needed_reg.init();
 
3448
    s->keys.reset();
 
3449
    s->const_keys.reset();
 
3450
    s->checked_keys.reset();
 
3451
    s->needed_reg.reset();
3451
3452
    table_vector[i]=s->table=table=tables->table;
3452
3453
    table->pos_in_table_list= tables;
3453
3454
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
3456
3457
        table->file->print_error(error, MYF(0));
3457
3458
        return(1);
3458
3459
    }
3459
 
    table->quick_keys.clear_all();
 
3460
    table->quick_keys.reset();
3460
3461
    table->reginfo.join_tab=s;
3461
3462
    table->reginfo.not_exists_optimize=0;
3462
3463
    memset(table->const_key_parts, 0,
3653
3654
        {
3654
3655
          start_keyuse=keyuse;
3655
3656
          key=keyuse->key;
3656
 
          s->keys.set_bit(key);               // QQ: remove this ?
 
3657
          s->keys.set(key);               // QQ: remove this ?
3657
3658
 
3658
3659
          refs=0;
3659
 
          const_ref.clear_all();
3660
 
          eq_part.clear_all();
 
3660
          const_ref.reset();
 
3661
          eq_part.reset();
3661
3662
          do
3662
3663
          {
3663
3664
            if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
3664
3665
            {
3665
3666
              if (!((~found_const_table_map) & keyuse->used_tables))
3666
 
                const_ref.set_bit(keyuse->keypart);
 
3667
                const_ref.set(keyuse->keypart);
3667
3668
              else
3668
3669
                refs|=keyuse->used_tables;
3669
 
              eq_part.set_bit(keyuse->keypart);
 
3670
              eq_part.set(keyuse->keypart);
3670
3671
            }
3671
3672
            keyuse++;
3672
3673
          } while (keyuse->table == table && keyuse->key == key);
3673
3674
 
3674
 
          if (eq_part.is_prefix(table->key_info[key].key_parts) &&
 
3675
          if (is_keymap_prefix(eq_part, table->key_info[key].key_parts) &&
3675
3676
              !table->pos_in_table_list->embedding)
3676
3677
          {
3677
3678
            if ((table->key_info[key].flags & (HA_NOSAME))
3682
3683
                int tmp;
3683
3684
                ref_changed = 1;
3684
3685
                s->type= JT_CONST;
3685
 
                join->const_table_map|=table->map;
 
3686
                join->const_table_map|= table->map;
3686
3687
                set_position(join,const_count++,s,start_keyuse);
3687
3688
                if (create_ref_for_key(join, s, start_keyuse,
3688
3689
                                       found_const_table_map))
3701
3702
                found_ref|= refs;      // Table is const if all refs are const
3702
3703
            }
3703
3704
            else if (const_ref == eq_part)
3704
 
              s->const_keys.set_bit(key);
 
3705
              s->const_keys.set(key);
3705
3706
          }
3706
3707
        }
3707
3708
      }
3719
3720
      Field *field= sargables->field;
3720
3721
      JOIN_TAB *join_tab= field->table->reginfo.join_tab;
3721
3722
      key_map possible_keys= field->key_start;
3722
 
      possible_keys.intersect(field->table->keys_in_use_for_query);
 
3723
      possible_keys&= field->table->keys_in_use_for_query;
3723
3724
      bool is_const= 1;
3724
3725
      for (uint32_t j=0; j < sargables->num_values; j++)
3725
3726
        is_const&= sargables->arg_value[j]->const_item();
3726
3727
      if (is_const)
3727
 
        join_tab[0].const_keys.merge(possible_keys);
 
3728
        join_tab[0].const_keys|= possible_keys;
3728
3729
    }
3729
3730
  }
3730
3731
 
3761
3762
    */
3762
3763
    add_group_and_distinct_keys(join, s);
3763
3764
 
3764
 
    if (!s->const_keys.is_clear_all() &&
 
3765
    if (s->const_keys.any() &&
3765
3766
        !s->table->pos_in_table_list->embedding)
3766
3767
    {
3767
3768
      ha_rows records;
4043
4044
    else
4044
4045
    {
4045
4046
      JOIN_TAB *stat=field->table->reginfo.join_tab;
4046
 
      key_map possible_keys=field->key_start;
4047
 
      possible_keys.intersect(field->table->keys_in_use_for_query);
4048
 
      stat[0].keys.merge(possible_keys);             // Add possible keys
 
4047
      key_map possible_keys= field->key_start;
 
4048
      possible_keys&= field->table->keys_in_use_for_query;
 
4049
      stat[0].keys|= possible_keys;             // Add possible keys
4049
4050
 
4050
4051
      /*
4051
4052
        Save the following cases:
4058
4059
         Field BETWEEN ...
4059
4060
         Field IN ...
4060
4061
      */
4061
 
      stat[0].key_dependent|=used_tables;
 
4062
      stat[0].key_dependent|= used_tables;
4062
4063
 
4063
4064
      bool is_const=1;
4064
4065
      for (uint32_t i=0; i<num_values; i++)
4067
4068
          break;
4068
4069
      }
4069
4070
      if (is_const)
4070
 
        stat[0].const_keys.merge(possible_keys);
 
4071
        stat[0].const_keys|= possible_keys;
4071
4072
      else if (!eq_func)
4072
4073
      {
4073
4074
        /*
4430
4431
  {
4431
4432
    for (uint32_t key= 0 ; key < form->sizeKeys() ; key++)
4432
4433
    {
4433
 
      if (!(form->keys_in_use_for_query.is_set(key)))
 
4434
      if (!(form->keys_in_use_for_query.test(key)))
4434
4435
        continue;
4435
4436
 
4436
4437
      uint32_t key_parts= (uint32_t) form->key_info[key].key_parts;
4705
4706
      /* Save ptr to first use */
4706
4707
      if (!use->table->reginfo.join_tab->keyuse)
4707
4708
        use->table->reginfo.join_tab->keyuse=save_pos;
4708
 
      use->table->reginfo.join_tab->checked_keys.set_bit(use->key);
 
4709
      use->table->reginfo.join_tab->checked_keys.set(use->key);
4709
4710
      save_pos++;
4710
4711
    }
4711
4712
    i=(uint32_t) (save_pos-(KEYUSE*) keyuse->buffer);
4807
4808
 
4808
4809
  /* Intersect the keys of all group fields. */
4809
4810
  cur_item= indexed_fields_it++;
4810
 
  possible_keys.merge(cur_item->field->part_of_key);
 
4811
  possible_keys|= cur_item->field->part_of_key;
4811
4812
  while ((cur_item= indexed_fields_it++))
4812
4813
  {
4813
 
    possible_keys.intersect(cur_item->field->part_of_key);
 
4814
    possible_keys&= cur_item->field->part_of_key;
4814
4815
  }
4815
4816
 
4816
 
  if (!possible_keys.is_clear_all())
4817
 
    join_tab->const_keys.merge(possible_keys);
 
4817
  if (possible_keys.any())
 
4818
    join_tab->const_keys|= possible_keys;
4818
4819
}
4819
4820
 
4820
4821
 
5054
5055
             ...
5055
5056
        */
5056
5057
        if (try_sj_inside_out &&
5057
 
            table->covering_keys.is_set(key) &&
 
5058
            table->covering_keys.test(key) &&
5058
5059
            (handled_sj_equalities | bound_sj_equalities) ==     // (1)
5059
5060
            PREV_BITS(uint64_t, s->emb_sj_nest->sj_in_exprs)) // (1)
5060
5061
        {
5126
5127
                quick_cond is equivalent to ref_const_cond (if it was an
5127
5128
                empty interval we wouldn't have got here).
5128
5129
              */
5129
 
              if (table->quick_keys.is_set(key))
 
5130
              if (table->quick_keys.test(key))
5130
5131
                records= (double) table->quick_rows[key];
5131
5132
              else
5132
5133
              {
5156
5157
                can make an adjustment is a special case of the criteria used
5157
5158
                in ReuseRangeEstimateForRef-3.
5158
5159
              */
5159
 
              if (table->quick_keys.is_set(key) &&
 
5160
              if (table->quick_keys.test(key) &&
5160
5161
                  const_part & (1 << table->quick_key_parts[key]) &&
5161
5162
                  table->quick_n_ranges[key] == 1 &&
5162
5163
                  records > (double) table->quick_rows[key])
5167
5168
            /* Limit the number of matched rows */
5168
5169
            tmp= records;
5169
5170
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5170
 
            if (table->covering_keys.is_set(key))
 
5171
            if (table->covering_keys.test(key))
5171
5172
            {
5172
5173
              /* we can use only index tree */
5173
5174
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5227
5228
 
5228
5229
              (C3) "range optimizer used (have ref_or_null?2:1) intervals"
5229
5230
            */
5230
 
            if (table->quick_keys.is_set(key) && !found_ref &&          //(C1)
 
5231
            if (table->quick_keys.test(key) && !found_ref &&          //(C1)
5231
5232
                table->quick_key_parts[key] == max_key_part &&          //(C2)
5232
5233
                table->quick_n_ranges[key] == 1+((ref_or_null_part)?1:0)) //(C3)
5233
5234
            {
5254
5255
                  cheaper in some cases ?
5255
5256
                  TODO: figure this out and adjust the plan choice if needed.
5256
5257
                */
5257
 
                if (!found_ref && table->quick_keys.is_set(key) &&    // (1)
 
5258
                if (!found_ref && table->quick_keys.test(key) &&    // (1)
5258
5259
                    table->quick_key_parts[key] > max_key_part &&     // (2)
5259
5260
                    records < (double)table->quick_rows[key])         // (3)
5260
5261
                  records= (double)table->quick_rows[key];
5319
5320
                optimizer is the same as in ReuseRangeEstimateForRef-3,
5320
5321
                applied to first table->quick_key_parts[key] key parts.
5321
5322
              */
5322
 
              if (table->quick_keys.is_set(key) &&
 
5323
              if (table->quick_keys.test(key) &&
5323
5324
                  table->quick_key_parts[key] <= max_key_part &&
5324
5325
                  const_part & (1 << table->quick_key_parts[key]) &&
5325
5326
                  table->quick_n_ranges[key] == 1 + ((ref_or_null_part &
5332
5333
 
5333
5334
            /* Limit the number of matched rows */
5334
5335
            set_if_smaller(tmp, (double) session->variables.max_seeks_for_key);
5335
 
            if (table->covering_keys.is_set(key))
 
5336
            if (table->covering_keys.test(key))
5336
5337
            {
5337
5338
              /* we can use only index tree */
5338
5339
              tmp= record_count * table->file->index_only_read_time(key, tmp);
5398
5399
      !(s->quick && best_key && s->quick->index == best_key->key &&      // (2)
5399
5400
        best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
5400
5401
      !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) &&   // (3)
5401
 
        ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
 
5402
        ! s->table->covering_keys.none() && best_key && !s->quick) &&// (3)
5402
5403
      !(s->table->force_index && best_key && !s->quick))                 // (4)
5403
5404
  {                                             // Check full join
5404
5405
    ha_rows rnd_records= s->found_records;
6403
6404
 
6404
6405
    if (j->type == JT_SYSTEM)
6405
6406
      continue;
6406
 
    if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
 
6407
    if (j->keys.none() || !(keyuse= join->best_positions[tablenr].key))
6407
6408
    {
6408
6409
      j->type=JT_ALL;
6409
6410
      if (tablenr != join->const_tables)
6658
6659
  join_tab->select_cond=0;
6659
6660
  join_tab->quick=0;
6660
6661
  join_tab->type= JT_ALL;                       /* Map through all records */
6661
 
  join_tab->keys.init();
6662
 
  join_tab->keys.set_all();                     /* test everything in quick */
 
6662
  join_tab->keys.set();                     /* test everything in quick */
6663
6663
  join_tab->info=0;
6664
6664
  join_tab->on_expr_ref=0;
6665
6665
  join_tab->last_inner= 0;
7080
7080
        {
7081
7081
          /* Use quick key read if it's a constant and it's not used
7082
7082
             with key reading */
7083
 
          if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
 
7083
          if (tab->needed_reg.none() && tab->type != JT_EQ_REF
7084
7084
              && (tab->type != JT_REF || (uint32_t) tab->ref.key == tab->quick->index))
7085
7085
          {
7086
7086
            sel->quick=tab->quick;              // Use value from get_quick_...
7087
 
            sel->quick_keys.clear_all();
7088
 
            sel->needed_reg.clear_all();
 
7087
            sel->quick_keys.reset();
 
7088
            sel->needed_reg.reset();
7089
7089
          }
7090
7090
          else
7091
7091
          {
7096
7096
        uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
7097
7097
        if (i == join->const_tables && ref_key)
7098
7098
        {
7099
 
          if (!tab->const_keys.is_clear_all() &&
 
7099
          if (tab->const_keys.any() &&
7100
7100
              tab->table->reginfo.impossible_range)
7101
7101
            return(1);
7102
7102
        }
7103
7103
        else if (tab->type == JT_ALL && ! use_quick_range)
7104
7104
        {
7105
 
          if (!tab->const_keys.is_clear_all() &&
 
7105
          if (tab->const_keys.any() &&
7106
7106
              tab->table->reginfo.impossible_range)
7107
7107
            return(1);                          // Impossible range
7108
7108
          /*
7112
7112
            the index if we are using limit and this is the first table
7113
7113
          */
7114
7114
 
7115
 
          if ((cond && (!tab->keys.is_subset(tab->const_keys) && i > 0)) ||
7116
 
              (!tab->const_keys.is_clear_all() && (i == join->const_tables) && (join->unit->select_limit_cnt < join->best_positions[i].records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
 
7115
          if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
 
7116
              (!tab->const_keys.none() && (i == join->const_tables) && (join->unit->select_limit_cnt < join->best_positions[i].records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
7117
7117
          {
7118
7118
            /* Join with outer join condition */
7119
7119
            COND *orig_cond=sel->cond;
7162
7162
          else
7163
7163
          {
7164
7164
            sel->needed_reg=tab->needed_reg;
7165
 
            sel->quick_keys.clear_all();
 
7165
            sel->quick_keys.reset();
7166
7166
          }
7167
 
          if (!sel->quick_keys.is_subset(tab->checked_keys) ||
7168
 
              !sel->needed_reg.is_subset(tab->checked_keys))
 
7167
          if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
 
7168
              !((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
7169
7169
          {
7170
 
            tab->keys=sel->quick_keys;
7171
 
            tab->keys.merge(sel->needed_reg);
7172
 
            tab->use_quick= (!sel->needed_reg.is_clear_all() &&
7173
 
                             (select->quick_keys.is_clear_all() ||
 
7170
            tab->keys= sel->quick_keys;
 
7171
            tab->keys|= sel->needed_reg;
 
7172
            tab->use_quick= (!sel->needed_reg.none() &&
 
7173
                             (select->quick_keys.none() ||
7174
7174
                              (select->quick &&
7175
7175
                               (select->quick->records >= 100L)))) ?
7176
7176
              2 : 1;
7357
7357
      Item_field *item_field= (Item_field*)item;
7358
7358
      if (item_field->field->table != tbl)
7359
7359
        return true;
7360
 
      return item_field->field->part_of_key.is_set(keyno);
 
7360
      return item_field->field->part_of_key.test(keyno);
7361
7361
    }
7362
7362
  case Item::REF_ITEM:
7363
7363
    return uses_index_fields_only(item->real_item(), tbl, keyno,
7680
7680
      table->status=STATUS_NO_RECORD;
7681
7681
      tab->read_first_record= join_read_const;
7682
7682
      tab->read_record.read_record= join_no_more_records;
7683
 
      if (table->covering_keys.is_set(tab->ref.key) &&
 
7683
      if (table->covering_keys.test(tab->ref.key) &&
7684
7684
          !table->no_keyread)
7685
7685
      {
7686
7686
        table->key_read=1;
7698
7698
      tab->quick=0;
7699
7699
      tab->read_first_record= join_read_key;
7700
7700
      tab->read_record.read_record= join_no_more_records;
7701
 
      if (table->covering_keys.is_set(tab->ref.key) &&
 
7701
      if (table->covering_keys.test(tab->ref.key) &&
7702
7702
          !table->no_keyread)
7703
7703
      {
7704
7704
        table->key_read=1;
7717
7717
      }
7718
7718
      delete tab->quick;
7719
7719
      tab->quick=0;
7720
 
      if (table->covering_keys.is_set(tab->ref.key) &&
 
7720
      if (table->covering_keys.test(tab->ref.key) &&
7721
7721
          !table->no_keyread)
7722
7722
      {
7723
7723
        table->key_read=1;
7799
7799
        {
7800
7800
          if (tab->select && tab->select->quick &&
7801
7801
              tab->select->quick->index != MAX_KEY && //not index_merge
7802
 
              table->covering_keys.is_set(tab->select->quick->index))
 
7802
              table->covering_keys.test(tab->select->quick->index))
7803
7803
          {
7804
7804
            table->key_read=1;
7805
7805
            table->file->extra(HA_EXTRA_KEYREAD);
7806
7806
          }
7807
 
          else if (!table->covering_keys.is_clear_all() &&
 
7807
          else if (!table->covering_keys.none() &&
7808
7808
                   !(tab->select && tab->select->quick))
7809
7809
          {                                     // Only read index tree
7810
7810
            if (!tab->insideout_match_tab)
9409
9409
        Field *field= item_field->field;
9410
9410
        JOIN_TAB *stat= field->table->reginfo.join_tab;
9411
9411
        key_map possible_keys= field->key_start;
9412
 
        possible_keys.intersect(field->table->keys_in_use_for_query);
9413
 
        stat[0].const_keys.merge(possible_keys);
 
9412
        possible_keys&= field->table->keys_in_use_for_query;
 
9413
        stat[0].const_keys|= possible_keys;
9414
9414
 
9415
9415
        /*
9416
9416
          For each field in the multiple equality (for which we know that it
9417
9417
          is a constant) we have to find its corresponding key part, and set
9418
9418
          that key part in const_key_parts.
9419
9419
        */
9420
 
        if (!possible_keys.is_clear_all())
 
9420
        if (possible_keys.any())
9421
9421
        {
9422
9422
          Table *field_tab= field->table;
9423
9423
          KEYUSE *use;
9424
9424
          for (use= stat->keyuse; use && use->table == field_tab; use++)
9425
 
            if (possible_keys.is_set(use->key) &&
 
9425
            if (possible_keys.test(use->key) &&
9426
9426
                field_tab->key_info[use->key].key_part[use->keypart].field ==
9427
9427
                field)
9428
9428
              field_tab->const_key_parts[use->key]|= use->keypart_map;
11311
11311
  }
11312
11312
  else
11313
11313
  {
11314
 
    if (!table->key_read && table->covering_keys.is_set(tab->ref.key) &&
 
11314
    if (!table->key_read && table->covering_keys.test(tab->ref.key) &&
11315
11315
        !table->no_keyread &&
11316
11316
        (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
11317
11317
    {
11696
11696
{
11697
11697
  int error;
11698
11698
  Table *table=tab->table;
11699
 
  if (!table->key_read && table->covering_keys.is_set(tab->index) &&
 
11699
  if (!table->key_read && table->covering_keys.test(tab->index) &&
11700
11700
      !table->no_keyread)
11701
11701
  {
11702
11702
    table->key_read=1;
11772
11772
{
11773
11773
  Table *table=tab->table;
11774
11774
  int error;
11775
 
  if (!table->key_read && table->covering_keys.is_set(tab->index) &&
 
11775
  if (!table->key_read && table->covering_keys.test(tab->index) &&
11776
11776
      !table->no_keyread)
11777
11777
  {
11778
11778
    table->key_read=1;
12677
12677
 
12678
12678
  for (nr= 0 ; nr < table->s->keys ; nr++)
12679
12679
  {
12680
 
    if (usable_keys->is_set(nr) &&
 
12680
    if (usable_keys->test(nr) &&
12681
12681
        table->key_info[nr].key_length < min_length &&
12682
12682
        table->key_info[nr].key_parts >= ref_key_parts &&
12683
12683
        is_subkey(table->key_info[nr].key_part, ref_key_part,
12871
12871
    Item *item= (*tmp_order->item)->real_item();
12872
12872
    if (item->type() != Item::FIELD_ITEM)
12873
12873
    {
12874
 
      usable_keys.clear_all();
 
12874
      usable_keys.reset();
12875
12875
      return(0);
12876
12876
    }
12877
 
    usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
12878
 
    if (usable_keys.is_clear_all())
 
12877
    usable_keys&= ((Item_field*) item)->field->part_of_sortkey;
 
12878
    if (usable_keys.none())
12879
12879
      return(0);                                        // No usable keys
12880
12880
  }
12881
12881
 
12911
12911
    /*
12912
12912
      We come here when there is a REF key.
12913
12913
    */
12914
 
    if (!usable_keys.is_set(ref_key))
 
12914
    if (! usable_keys.test(ref_key))
12915
12915
    {
12916
12916
      /*
12917
12917
        We come here when ref_key is not among usable_keys
12921
12921
        If using index only read, only consider other possible index only
12922
12922
        keys
12923
12923
      */
12924
 
      if (table->covering_keys.is_set(ref_key))
12925
 
        usable_keys.intersect(table->covering_keys);
 
12924
      if (table->covering_keys.test(ref_key))
 
12925
        usable_keys&= table->covering_keys;
12926
12926
      if (tab->pre_idx_push_select_cond)
12927
12927
        tab->select_cond= tab->select->cond= tab->pre_idx_push_select_cond;
12928
12928
      if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
12958
12958
            parameres are set correctly by the range optimizer.
12959
12959
           */
12960
12960
          key_map new_ref_key_map;
12961
 
          new_ref_key_map.clear_all();  // Force the creation of quick select
12962
 
          new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
 
12961
          new_ref_key_map.reset();  // Force the creation of quick select
 
12962
          new_ref_key_map.set(new_ref_key); // only for new_ref_key.
12963
12963
 
12964
12964
          if (select->test_quick_select(tab->join->session, new_ref_key_map, 0,
12965
12965
                                        (tab->join->select_options &
12974
12974
      }
12975
12975
    }
12976
12976
    /* Check if we get the rows in requested sorted order by using the key */
12977
 
    if (usable_keys.is_set(ref_key) &&
 
12977
    if (usable_keys.test(ref_key) &&
12978
12978
        (order_direction= test_if_order_by_key(order,table,ref_key,
12979
12979
                                               &used_key_parts)))
12980
12980
      goto check_reverse_order;
13014
13014
      if (tab->type == JT_ALL && tab->join->tables > tab->join->const_tables + 1)
13015
13015
        return(0);
13016
13016
      keys= *table->file->keys_to_use_for_scanning();
13017
 
      keys.merge(table->covering_keys);
 
13017
      keys|= table->covering_keys;
13018
13018
 
13019
13019
      /*
13020
13020
        We are adding here also the index specified in FORCE INDEX clause,
13022
13022
        This is to allow users to use index in order_st BY.
13023
13023
      */
13024
13024
      if (table->force_index)
13025
 
        keys.merge(group ? table->keys_in_use_for_group_by :
 
13025
        keys|= (group ? table->keys_in_use_for_group_by :
13026
13026
                           table->keys_in_use_for_order_by);
13027
 
      keys.intersect(usable_keys);
 
13027
      keys&= usable_keys;
13028
13028
    }
13029
13029
    else
13030
13030
      keys= usable_keys;
13036
13036
    for (nr=0; nr < table->s->keys ; nr++)
13037
13037
    {
13038
13038
      int direction;
13039
 
      if (keys.is_set(nr) &&
 
13039
      if (keys.test(nr) &&
13040
13040
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
13041
13041
      {
13042
 
        bool is_covering= table->covering_keys.is_set(nr) || (nr == table->s->primary_key && table->file->primary_key_is_clustered());
 
13042
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->file->primary_key_is_clustered());
13043
13043
 
13044
13044
        /*
13045
13045
          Don't use an index scan with order_st BY without limit.
13122
13122
            ha_rows quick_records= table_records;
13123
13123
            if (is_best_covering && !is_covering)
13124
13124
              continue;
13125
 
            if (table->quick_keys.is_set(nr))
 
13125
            if (table->quick_keys.test(nr))
13126
13126
              quick_records= table->quick_rows[nr];
13127
13127
            if (best_key < 0 ||
13128
13128
                (select_limit <= cmin(quick_records,best_records) ?
13142
13142
    if (best_key >= 0)
13143
13143
    {
13144
13144
      bool quick_created= false;
13145
 
      if (table->quick_keys.is_set(best_key) && best_key != ref_key)
 
13145
      if (table->quick_keys.test(best_key) && best_key != ref_key)
13146
13146
      {
13147
13147
        key_map test_map;
13148
 
        test_map.clear_all();       // Force the creation of quick select
13149
 
        test_map.set_bit(best_key); // only best_key.
 
13148
        test_map.reset();       // Force the creation of quick select
 
13149
        test_map.set(best_key); // only best_key.
13150
13150
        quick_created=
13151
13151
          select->test_quick_select(join->session, test_map, 0,
13152
13152
                                    join->select_options & OPTION_FOUND_ROWS ?
13167
13167
            delete select->quick;
13168
13168
            select->quick= 0;
13169
13169
          }
13170
 
          if (table->covering_keys.is_set(best_key))
 
13170
          if (table->covering_keys.test(best_key))
13171
13171
          {
13172
13172
            table->key_read=1;
13173
13173
            table->file->extra(HA_EXTRA_KEYREAD);
15836
15836
                                          strlen(join_type_str[tab->type]),
15837
15837
                                          cs));
15838
15838
      /* Build "possible_keys" value and add it to item_list */
15839
 
      if (!tab->keys.is_clear_all())
 
15839
      if (tab->keys.any())
15840
15840
      {
15841
15841
        uint32_t j;
15842
15842
        for (j=0 ; j < table->s->keys ; j++)
15843
15843
        {
15844
 
          if (tab->keys.is_set(j))
 
15844
          if (tab->keys.test(j))
15845
15845
          {
15846
15846
            if (tmp1.length())
15847
15847
              tmp1.append(',');
15965
15965
      /* Build "Extra" field and add it to item_list. */
15966
15966
      bool key_read=table->key_read;
15967
15967
      if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
15968
 
          table->covering_keys.is_set(tab->index))
 
15968
          table->covering_keys.test(tab->index))
15969
15969
        key_read=1;
15970
15970
      if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
15971
15971
          !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
16014
16014
        {
16015
16015
          if (tab->use_quick == 2)
16016
16016
          {
16017
 
            /* 4 bits per 1 hex digit + terminating '\0' */
16018
 
            char buf[MAX_KEY / 4 + 1];
 
16017
            /*
 
16018
             * To print out the bitset in tab->keys, we go through
 
16019
             * it 32 bits at a time. We need to do this to ensure
 
16020
             * that the to_ulong() method will not throw an
 
16021
             * out_of_range exception at runtime which would happen
 
16022
             * if the bitset we were working with was larger than 64
 
16023
             * bits on a 64-bit platform (for example).
 
16024
             */
 
16025
            stringstream s, w;
 
16026
            string str;
 
16027
            w << tab->keys;
 
16028
            w >> str;
 
16029
            for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
 
16030
            {
 
16031
              bitset<32> tmp(str, pos, 32);
 
16032
              if (tmp.any())
 
16033
                s << uppercase << hex << tmp.to_ulong();
 
16034
            }
16019
16035
            extra.append(STRING_WITH_LEN("; Range checked for each "
16020
16036
                                         "record (index map: 0x"));
16021
 
            extra.append(tab->keys.print(buf));
 
16037
            extra.append(s.str().c_str());
16022
16038
            extra.append(')');
16023
16039
          }
16024
16040
          else if (tab->select->cond)