~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2009-05-08 19:07:39 UTC
  • mto: This revision was merged to the branch mainline in revision 1009.
  • Revision ID: mordred@inaugust.com-20090508190739-rwas5y9xjg1a92p6
Reverted a crap-ton of padraig's work.

Show diffs side-by-side

added added

removed removed

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