~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2009-08-11 20:22:59 UTC
  • mfrom: (1093.1.59 captain)
  • Revision ID: brian@gaz-20090811202259-5a92huu2yqmzdx1u
MErge Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
 
55
55
using namespace std;
56
56
 
57
 
const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
58
 
                              "MAYBE_REF","ALL","range","index",
59
 
                              "ref_or_null","unique_subquery","index_subquery",
60
 
                              "index_merge"
 
57
static const string access_method_str[]=
 
58
{
 
59
  "UNKNOWN",
 
60
  "system",
 
61
  "const",
 
62
  "eq_ref",
 
63
  "ref",
 
64
  "MAYBE_REF",
 
65
  "ALL",
 
66
  "range",
 
67
  "index",
 
68
  "ref_or_null",
 
69
  "unique_subquery",
 
70
  "index_subquery",
 
71
  "index_merge"
61
72
};
62
73
 
63
74
static int sort_keyuse(KeyUse *a,KeyUse *b);
1697
1708
          key_buff, maybe_null);
1698
1709
      /*
1699
1710
        Remember if we are going to use REF_OR_NULL
1700
 
        But only if field _really_ can be null i.e. we force JT_REF
1701
 
        instead of JT_REF_OR_NULL in case if field can't be null
 
1711
        But only if field _really_ can be null i.e. we force AM_REF
 
1712
        instead of AM_REF_OR_NULL in case if field can't be null
1702
1713
      */
1703
1714
      if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
1704
1715
        null_ref_key= key_buff;
1706
1717
    }
1707
1718
  }
1708
1719
  *ref_key=0;       // end_marker
1709
 
  if (j->type == JT_CONST)
 
1720
  if (j->type == AM_CONST)
1710
1721
    j->table->const_table= 1;
1711
1722
  else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) != HA_NOSAME) ||
1712
1723
           keyparts != keyinfo->key_parts || null_ref_key)
1713
1724
  {
1714
1725
    /* Must read with repeat */
1715
 
    j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
 
1726
    j->type= null_ref_key ? AM_REF_OR_NULL : AM_REF;
1716
1727
    j->ref.null_ref_key= null_ref_key;
1717
1728
  }
1718
1729
  else if (keyuse_uses_no_tables)
1724
1735
      Here we should not mark the table as a 'const' as a field may
1725
1736
      have a 'normal' value or a NULL value.
1726
1737
    */
1727
 
    j->type=JT_CONST;
 
1738
    j->type= AM_CONST;
1728
1739
  }
1729
1740
  else
1730
 
    j->type=JT_EQ_REF;
 
1741
    j->type= AM_EQ_REF;
1731
1742
  return(0);
1732
1743
}
1733
1744
 
1786
1797
  for (uint32_t i=join->const_tables ; i < join->tables ; i++)
1787
1798
  {
1788
1799
    JoinTable *tab=join->join_tab+i;
1789
 
    if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
1790
 
         tab->type == JT_REF_OR_NULL) &&
 
1800
    if ((tab->type == AM_REF || tab->type == AM_EQ_REF ||
 
1801
         tab->type == AM_REF_OR_NULL) &&
1791
1802
        !tab->table->maybe_null)
1792
1803
    {
1793
1804
      for (uint32_t keypart= 0; keypart < tab->ref.key_parts; keypart++)
2156
2167
    return tab->eq_ref_table;
2157
2168
  tab->cached_eq_ref_table=1;
2158
2169
  /* We can skip const tables only if not an outer table */
2159
 
  if (tab->type == JT_CONST && !tab->first_inner)
 
2170
  if (tab->type == AM_CONST && !tab->first_inner)
2160
2171
    return (tab->eq_ref_table=1);               /* purecov: inspected */
2161
 
  if (tab->type != JT_EQ_REF || tab->table->maybe_null)
 
2172
  if (tab->type != AM_EQ_REF || tab->table->maybe_null)
2162
2173
    return (tab->eq_ref_table=0);               // We must use this
2163
2174
  Item **ref_item=tab->ref.items;
2164
2175
  Item **end=ref_item+tab->ref.key_parts;
4238
4249
  return 0;
4239
4250
}
4240
4251
 
4241
 
int join_read_const_table(JoinTable *tab, POSITION *pos)
 
4252
int join_read_const_table(JoinTable *tab, Position *pos)
4242
4253
{
4243
4254
  int error;
4244
4255
  Table *table=tab->table;
4246
4257
  table->null_row=0;
4247
4258
  table->status=STATUS_NO_RECORD;
4248
4259
 
4249
 
  if (tab->type == JT_SYSTEM)
 
4260
  if (tab->type == AM_SYSTEM)
4250
4261
  {
4251
4262
    if ((error=join_read_system(tab)))
4252
4263
    {                                           // Info for DESCRIBE
5450
5461
  {
5451
5462
    ref_key=       tab->ref.key;
5452
5463
    ref_key_parts= tab->ref.key_parts;
5453
 
    if (tab->type == JT_REF_OR_NULL)
 
5464
    if (tab->type == AM_REF_OR_NULL)
5454
5465
      return(0);
5455
5466
  }
5456
5467
  else if (select && select->quick)             // Range found by opt_range
5564
5575
    uint32_t tablenr= tab - join->join_tab;
5565
5576
    ha_rows table_records= table->file->stats.records;
5566
5577
    bool group= join->group && order == join->group_list;
 
5578
    Position cur_pos;
5567
5579
 
5568
5580
    /*
5569
5581
      If not used with LIMIT, only use keys if the whole query can be
5576
5588
        filesort() and join cache are usually faster than reading in
5577
5589
        index order and not using join cache
5578
5590
        */
5579
 
      if (tab->type == JT_ALL && tab->join->tables > tab->join->const_tables + 1)
 
5591
      if (tab->type == AM_ALL && tab->join->tables > tab->join->const_tables + 1)
5580
5592
        return(0);
5581
5593
      keys= *table->file->keys_to_use_for_scanning();
5582
5594
      keys|= table->covering_keys;
5594
5606
    else
5595
5607
      keys= usable_keys;
5596
5608
 
5597
 
    read_time= join->best_positions[tablenr].read_time;
 
5609
    cur_pos= join->getPosFromOptimalPlan(tablenr);
 
5610
    read_time= cur_pos.read_time;
5598
5611
    for (uint32_t i= tablenr+1; i < join->tables; i++)
5599
 
      fanout*= join->best_positions[i].records_read; // fanout is always >= 1
 
5612
    {
 
5613
      cur_pos= join->getPosFromOptimalPlan(i);
 
5614
      fanout*= cur_pos.records_read; // fanout is always >= 1
 
5615
    }
5600
5616
 
5601
5617
    for (nr=0; nr < table->s->keys ; nr++)
5602
5618
    {
5726
5742
          tab->index= best_key;
5727
5743
          tab->read_first_record= best_key_direction > 0 ?
5728
5744
                                  join_read_first:join_read_last;
5729
 
          tab->type=JT_NEXT;           // Read with index_first(), index_next()
 
5745
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
5730
5746
          if (select && select->quick)
5731
5747
          {
5732
5748
            delete select->quick;
5746
5762
              tab->limit= select_limit;
5747
5763
          }
5748
5764
        }
5749
 
        else if (tab->type != JT_ALL)
 
5765
        else if (tab->type != AM_ALL)
5750
5766
        {
5751
5767
          /*
5752
5768
            We're about to use a quick access to the table.
5754
5770
            method is actually used.
5755
5771
          */
5756
5772
          assert(tab->select->quick);
5757
 
          tab->type=JT_ALL;
 
5773
          tab->type= AM_ALL;
5758
5774
          tab->use_quick=1;
5759
5775
          tab->ref.key= -1;
5760
5776
          tab->ref.key_parts=0;         // Don't use ref key.
5808
5824
        select->quick=tmp;
5809
5825
      }
5810
5826
    }
5811
 
    else if (tab->type != JT_NEXT &&
 
5827
    else if (tab->type != AM_NEXT &&
5812
5828
             tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
5813
5829
    {
5814
5830
      /*
5941
5957
  tab->select_cond=0;
5942
5958
  tab->last_inner= 0;
5943
5959
  tab->first_unmatched= 0;
5944
 
  tab->type=JT_ALL;                             // Read with normal read_record
 
5960
  tab->type= AM_ALL;                            // Read with normal read_record
5945
5961
  tab->read_first_record= join_init_read_record;
5946
5962
  tab->join->examined_rows+=examined_rows;
5947
5963
  if (table->key_read)                          // Restore if we used indexes
7256
7272
      item_list.push_back(new Item_string(table_name_buffer, len, cs));
7257
7273
    }
7258
7274
    /* type */
7259
 
    item_list.push_back(new Item_string(join_type_str[JT_ALL],
7260
 
                                          strlen(join_type_str[JT_ALL]),
7261
 
                                          cs));
 
7275
    item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(),
 
7276
                                        access_method_str[AM_ALL].length(),
 
7277
                                        cs));
7262
7278
    /* possible_keys */
7263
7279
    item_list.push_back(item_null);
7264
7280
    /* key*/
7312
7328
      item_list.push_back(new Item_string(join->select_lex->type,
7313
7329
                                          strlen(join->select_lex->type),
7314
7330
                                          cs));
7315
 
      if (tab->type == JT_ALL && tab->select && tab->select->quick)
 
7331
      if (tab->type == AM_ALL && tab->select && tab->select->quick)
7316
7332
      {
7317
7333
        quick_type= tab->select->quick->get_type();
7318
7334
        if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
7319
7335
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
7320
7336
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
7321
 
          tab->type = JT_INDEX_MERGE;
 
7337
          tab->type = AM_INDEX_MERGE;
7322
7338
        else
7323
 
          tab->type = JT_RANGE;
 
7339
          tab->type = AM_RANGE;
7324
7340
      }
7325
7341
      /* table */
7326
7342
      if (table->derived_select_number)
7339
7355
                                            cs));
7340
7356
      }
7341
7357
      /* "type" column */
7342
 
      item_list.push_back(new Item_string(join_type_str[tab->type],
7343
 
                                          strlen(join_type_str[tab->type]),
 
7358
      item_list.push_back(new Item_string(access_method_str[tab->type].c_str(),
 
7359
                                          access_method_str[tab->type].length(),
7344
7360
                                          cs));
7345
7361
      /* Build "possible_keys" value and add it to item_list */
7346
7362
      if (tab->keys.any())
7384
7400
        }
7385
7401
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
7386
7402
      }
7387
 
      else if (tab->type == JT_NEXT)
 
7403
      else if (tab->type == AM_NEXT)
7388
7404
      {
7389
7405
        KEY *key_info=table->key_info+ tab->index;
7390
7406
        register uint32_t length;
7448
7464
        double examined_rows;
7449
7465
        if (tab->select && tab->select->quick)
7450
7466
          examined_rows= rows2double(tab->select->quick->records);
7451
 
        else if (tab->type == JT_NEXT || tab->type == JT_ALL)
 
7467
        else if (tab->type == AM_NEXT || tab->type == AM_ALL)
7452
7468
          examined_rows= rows2double(tab->limit ? tab->limit :
7453
7469
                                     tab->table->file->records());
7454
7470
        else
7455
 
          examined_rows= join->best_positions[i].records_read;
 
7471
        {
 
7472
          Position cur_pos= join->getPosFromOptimalPlan(i);
 
7473
          examined_rows= cur_pos.records_read;
 
7474
        }
7456
7475
 
7457
7476
        item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
7458
7477
                                         MY_INT64_NUM_DECIMAL_DIGITS));
7462
7481
        {
7463
7482
          float f= 0.0;
7464
7483
          if (examined_rows)
7465
 
            f= (float) (100.0 * join->best_positions[i].records_read /
 
7484
          {
 
7485
            Position cur_pos= join->getPosFromOptimalPlan(i);
 
7486
            f= (float) (100.0 * cur_pos.records_read /
7466
7487
                        examined_rows);
 
7488
          }
7467
7489
          item_list.push_back(new Item_float(f, 2));
7468
7490
        }
7469
7491
      }
7470
7492
 
7471
7493
      /* Build "Extra" field and add it to item_list. */
7472
7494
      bool key_read=table->key_read;
7473
 
      if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
 
7495
      if ((tab->type == AM_NEXT || tab->type == AM_CONST) &&
7474
7496
          table->covering_keys.test(tab->index))
7475
7497
        key_read=1;
7476
7498
      if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&