~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

Merge Stewart's dead code removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/**
17
17
  @file
18
18
 
19
19
  @brief
20
 
  select_query and join optimization
 
20
  mysql_select and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
24
24
*/
25
 
#include "config.h"
 
25
#include "drizzled/server_includes.h"
26
26
 
27
27
#include <string>
28
28
#include <iostream>
30
30
#include <vector>
31
31
 
32
32
#include "drizzled/sql_select.h" /* include join.h */
 
33
#include "drizzled/table_map_iterator.h"
33
34
 
34
35
#include "drizzled/error.h"
35
36
#include "drizzled/gettext.h"
38
39
#include "drizzled/nested_join.h"
39
40
#include "drizzled/probes.h"
40
41
#include "drizzled/show.h"
 
42
#include "drizzled/plugin/info_schema_table.h"
41
43
#include "drizzled/item/cache.h"
42
44
#include "drizzled/item/cmpfunc.h"
43
45
#include "drizzled/item/copy_string.h"
49
51
#include "drizzled/lock.h"
50
52
#include "drizzled/item/outer_ref.h"
51
53
#include "drizzled/index_hint.h"
52
 
#include "drizzled/records.h"
53
 
#include "drizzled/internal/iocache.h"
54
 
#include "drizzled/drizzled.h"
55
 
#include "drizzled/plugin/storage_engine.h"
 
54
#include "drizzled/memory/multi_malloc.h"
56
55
 
57
56
#include "drizzled/sql_union.h"
58
57
#include "drizzled/optimizer/key_field.h"
59
58
#include "drizzled/optimizer/position.h"
60
59
#include "drizzled/optimizer/sargable_param.h"
61
60
#include "drizzled/optimizer/key_use.h"
62
 
#include "drizzled/optimizer/range.h"
63
 
#include "drizzled/optimizer/quick_range_select.h"
64
 
#include "drizzled/optimizer/quick_ror_intersect_select.h"
65
 
 
66
 
#include "drizzled/filesort.h"
67
61
 
68
62
using namespace std;
 
63
using namespace drizzled;
69
64
 
70
 
namespace drizzled
 
65
static const string access_method_str[]=
71
66
{
 
67
  "UNKNOWN",
 
68
  "system",
 
69
  "const",
 
70
  "eq_ref",
 
71
  "ref",
 
72
  "MAYBE_REF",
 
73
  "ALL",
 
74
  "range",
 
75
  "index",
 
76
  "ref_or_null",
 
77
  "unique_subquery",
 
78
  "index_subquery",
 
79
  "index_merge"
 
80
};
72
81
 
73
82
static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b);
74
83
static COND *build_equal_items(Session *session, COND *cond,
79
88
static Item* part_of_refkey(Table *form,Field *field);
80
89
static bool cmp_buffer_with_ref(JoinTable *tab);
81
90
static void change_cond_ref_to_const(Session *session,
82
 
                                     list<COND_CMP>& save_list,
 
91
                                     vector<COND_CMP>& save_list,
83
92
                                     Item *and_father,
84
93
                                     Item *cond,
85
94
                                     Item *field,
118
127
{
119
128
  bool res;
120
129
  register Select_Lex *select_lex= &lex->select_lex;
121
 
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
 
130
  DRIZZLE_SELECT_START(session->query);
122
131
 
123
132
  if (select_lex->master_unit()->is_union() ||
124
133
      select_lex->master_unit()->fake_select_lex)
125
 
  {
126
134
    res= drizzle_union(session, lex, result, &lex->unit,
127
135
                       setup_tables_done_option);
128
 
  }
129
136
  else
130
137
  {
131
138
    Select_Lex_Unit *unit= &lex->unit;
132
139
    unit->set_limit(unit->global_parameters);
133
140
    session->session_marker= 0;
134
141
    /*
135
 
      'options' of select_query will be set in JOIN, as far as JOIN for
 
142
      'options' of mysql_select will be set in JOIN, as far as JOIN for
136
143
      every PS/SP execution new, we will not need reset this flag if
137
144
      setup_tables_done_option changed for next rexecution
138
145
    */
139
 
    res= select_query(session,
140
 
                      &select_lex->ref_pointer_array,
 
146
    res= mysql_select(session, &select_lex->ref_pointer_array,
141
147
                      (TableList*) select_lex->table_list.first,
142
 
                      select_lex->with_wild,
143
 
                      select_lex->item_list,
 
148
                      select_lex->with_wild, select_lex->item_list,
144
149
                      select_lex->where,
145
150
                      select_lex->order_list.elements +
146
151
                      select_lex->group_list.elements,
147
 
                      (Order*) select_lex->order_list.first,
148
 
                      (Order*) select_lex->group_list.first,
 
152
                      (order_st*) select_lex->order_list.first,
 
153
                      (order_st*) select_lex->group_list.first,
149
154
                      select_lex->having,
150
155
                      select_lex->options | session->options |
151
156
                      setup_tables_done_option,
271
276
 
272
277
/*****************************************************************************
273
278
  Check fields, find best join, do the select and output fields.
274
 
  select_query assumes that all tables are already opened
 
279
  mysql_select assumes that all tables are already opened
275
280
*****************************************************************************/
276
281
 
277
282
/*
328
333
                              for a, b and c in this list.
329
334
  @param conds                top level item of an expression representing
330
335
                              WHERE clause of the top level select
331
 
  @param og_num               total number of ORDER BY and GROUP BY clauses
 
336
  @param og_num               total number of order_st BY and GROUP BY clauses
332
337
                              arguments
333
 
  @param order                linked list of ORDER BY agruments
 
338
  @param order                linked list of order_st BY agruments
334
339
  @param group                linked list of GROUP BY arguments
335
340
  @param having               top level item of HAVING expression
336
341
  @param select_options       select options (BIG_RESULT, etc)
351
356
  @retval
352
357
    true   an error
353
358
*/
354
 
bool select_query(Session *session,
 
359
bool mysql_select(Session *session,
355
360
                  Item ***rref_pointer_array,
356
 
                  TableList *tables, 
 
361
                        TableList *tables, 
357
362
                  uint32_t wild_num, 
358
363
                  List<Item> &fields,
359
 
                  COND *conds, 
 
364
                        COND *conds, 
360
365
                  uint32_t og_num,  
361
 
                  Order *order,
362
 
                  Order *group,
363
 
                  Item *having, 
 
366
                  order_st *order, 
 
367
                  order_st *group,
 
368
                        Item *having, 
364
369
                  uint64_t select_options,
365
 
                  select_result *result, 
 
370
                        select_result *result, 
366
371
                  Select_Lex_Unit *unit,
367
 
                  Select_Lex *select_lex)
 
372
                        Select_Lex *select_lex)
368
373
{
369
374
  bool err;
370
375
  bool free_join= 1;
371
376
 
372
377
  select_lex->context.resolve_in_select_list= true;
373
 
  Join *join;
 
378
  JOIN *join;
374
379
  if (select_lex->join != 0)
375
380
  {
376
381
    join= select_lex->join;
403
408
  }
404
409
  else
405
410
  {
406
 
    if (!(join= new Join(session, fields, select_options, result)))
 
411
    if (!(join= new JOIN(session, fields, select_options, result)))
407
412
      return(true);
408
413
    session->set_proc_info("init");
409
414
    session->used_tables=0;                         // Updated by setup_fields
415
420
    }
416
421
  }
417
422
 
418
 
  err= join->optimize();
419
 
  if (err)
 
423
  if ((err= join->optimize()))
420
424
  {
421
 
    goto err; // 1
 
425
    goto err;                                   // 1
422
426
  }
423
427
 
424
428
  if (session->lex->describe & DESCRIBE_EXTENDED)
453
457
  return (cond? (new Item_cond_and(cond, item)) : item);
454
458
}
455
459
 
 
460
static void fix_list_after_tbl_changes(Select_Lex *new_parent, List<TableList> *tlist)
 
461
{
 
462
  List_iterator<TableList> it(*tlist);
 
463
  TableList *table;
 
464
  while ((table= it++))
 
465
  {
 
466
    if (table->on_expr)
 
467
      table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
 
468
    if (table->nested_join)
 
469
      fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
 
470
  }
 
471
}
 
472
 
456
473
/*****************************************************************************
457
474
  Create JoinTableS, make a guess about the table types,
458
475
  Approximate how many records will be used in each table
459
476
*****************************************************************************/
460
 
ha_rows get_quick_record_count(Session *session, optimizer::SqlSelect *select, Table *table, const key_map *keys,ha_rows limit)
 
477
ha_rows get_quick_record_count(Session *session, SQL_SELECT *select, Table *table, const key_map *keys,ha_rows limit)
461
478
{
462
479
  int error;
463
480
  if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
548
565
                         Select_Lex *select_lex,
549
566
                         vector<optimizer::SargableParam> &sargables)
550
567
{
551
 
  uint  and_level,found_eq_constant;
 
568
  uint  and_level,i,found_eq_constant;
552
569
  optimizer::KeyField *key_fields, *end, *field;
553
570
  uint32_t sz;
554
571
  uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
571
588
    substitutions.
572
589
  */
573
590
  sz= sizeof(optimizer::KeyField) *
574
 
      (((session->lex->current_select->cond_count+1)*2 +
 
591
      (((session->lex->current_select->cond_count+1) +
575
592
        session->lex->current_select->between_count)*m+1);
576
 
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
 
593
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
577
594
    return true;
578
595
  and_level= 0;
579
596
  field= end= key_fields;
591
608
      if (field->getValue()->type() == Item::NULL_ITEM &&
592
609
          ! field->getField()->real_maybe_null())
593
610
      {
594
 
        field->getField()->getTable()->reginfo.not_exists_optimize= 1;
 
611
        field->getField()->table->reginfo.not_exists_optimize= 1;
595
612
      }
596
613
    }
597
614
  }
598
 
  for (uint32_t i= 0; i < tables; i++)
 
615
  for (i= 0; i < tables; i++)
599
616
  {
600
617
    /*
601
618
      Block the creation of keys for inner tables of outer joins.
618
635
    TableList *table;
619
636
    while ((table= li++))
620
637
    {
621
 
      if (table->getNestedJoin())
 
638
      if (table->nested_join)
622
639
        add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
623
640
                              sargables);
624
641
    }
641
658
  {
642
659
    optimizer::KeyUse key_end,*prev,*save_pos,*use;
643
660
 
644
 
    internal::my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
645
 
                       (qsort_cmp) sort_keyuse);
 
661
    my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
 
662
          (qsort_cmp) sort_keyuse);
646
663
 
647
664
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
648
665
    insert_dynamic(keyuse,(unsigned char*) &key_end);
650
667
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
651
668
    prev= &key_end;
652
669
    found_eq_constant= 0;
 
670
    for (i= 0; i < keyuse->elements-1; i++, use++)
653
671
    {
654
 
      uint32_t i;
655
 
 
656
 
      for (i= 0; i < keyuse->elements-1; i++, use++)
 
672
      if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
 
673
        use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
 
674
      if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
657
675
      {
658
 
        if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
659
 
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
660
 
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
661
 
        {
662
 
          if (prev->getKeypart() + 1 < use->getKeypart() || 
663
 
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
664
 
            continue;                           /* remove */
665
 
        }
666
 
        else if (use->getKeypart() != 0)                // First found must be 0
667
 
          continue;
 
676
        if (prev->getKeypart() + 1 < use->getKeypart() || 
 
677
            ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
 
678
          continue;                             /* remove */
 
679
      }
 
680
      else if (use->getKeypart() != 0)          // First found must be 0
 
681
        continue;
668
682
 
669
 
#ifdef HAVE_VALGRIND
670
 
        /* Valgrind complains about overlapped memcpy when save_pos==use. */
671
 
        if (save_pos != use)
 
683
#ifdef HAVE_purify
 
684
      /* Valgrind complains about overlapped memcpy when save_pos==use. */
 
685
      if (save_pos != use)
672
686
#endif
673
 
          *save_pos= *use;
674
 
        prev=use;
675
 
        found_eq_constant= ! use->getUsedTables();
676
 
        /* Save ptr to first use */
677
 
        if (! use->getTable()->reginfo.join_tab->keyuse)
678
 
          use->getTable()->reginfo.join_tab->keyuse= save_pos;
679
 
        use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
680
 
        save_pos++;
681
 
      }
682
 
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
683
 
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
684
 
      keyuse->elements= i;
 
687
        *save_pos= *use;
 
688
      prev=use;
 
689
      found_eq_constant= ! use->getUsedTables();
 
690
      /* Save ptr to first use */
 
691
      if (! use->getTable()->reginfo.join_tab->keyuse)
 
692
        use->getTable()->reginfo.join_tab->keyuse= save_pos;
 
693
      use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
 
694
      save_pos++;
685
695
    }
 
696
    i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
 
697
    set_dynamic(keyuse, (unsigned char*) &key_end, i);
 
698
    keyuse->elements= i;
686
699
  }
687
700
  return false;
688
701
}
690
703
/**
691
704
  Update some values in keyuse for faster choose_plan() loop.
692
705
*/
693
 
void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
 
706
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
694
707
{
695
708
  optimizer::KeyUse *end,*keyuse= dynamic_element(keyuse_array, 
696
709
                                                  0, 
715
728
      if (map == 1)                     // Only one table
716
729
      {
717
730
        Table *tmp_table=join->all_tables[tablenr];
718
 
        keyuse->setTableRows(max(tmp_table->cursor->stats.records, (ha_rows)100));
 
731
        keyuse->setTableRows(max(tmp_table->file->stats.records, (ha_rows)100));
719
732
      }
720
733
    }
721
734
    /*
745
758
  @return
746
759
    None
747
760
*/
748
 
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
 
761
void add_group_and_distinct_keys(JOIN *join, JoinTable *join_tab)
749
762
{
750
763
  List<Item_field> indexed_fields;
751
764
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
752
 
  Order      *cur_group;
 
765
  order_st      *cur_group;
753
766
  Item_field *cur_item;
754
767
  key_map possible_keys(0);
755
768
 
850
863
  Field **f_ptr,*field;
851
864
 
852
865
  null_fields= blobs= fields= rec_length=0;
853
 
  for (f_ptr=join_tab->table->getFields() ; (field= *f_ptr) ; f_ptr++)
 
866
  for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
854
867
  {
855
868
    if (field->isReadSet())
856
869
    {
869
882
    rec_length+=sizeof(bool);
870
883
  if (blobs)
871
884
  {
872
 
    uint32_t blob_length=(uint32_t) (join_tab->table->cursor->stats.mean_rec_length-
 
885
    uint32_t blob_length=(uint32_t) (join_tab->table->file->stats.mean_rec_length-
873
886
                                     (join_tab->table->getRecordLength()- rec_length));
874
887
    rec_length+= max((uint32_t)4,blob_length);
875
888
  }
881
894
StoredKey *get_store_key(Session *session,
882
895
                         optimizer::KeyUse *keyuse,
883
896
                         table_map used_tables,
884
 
                         KeyPartInfo *key_part,
 
897
                         KEY_PART_INFO *key_part,
885
898
                         unsigned char *key_buff,
886
899
                         uint32_t maybe_null)
887
900
{
888
901
  Item_ref *key_use_val= static_cast<Item_ref *>(keyuse->getVal());
 
902
  Item_ref **dir_val= reinterpret_cast<Item_ref **>(key_use_val->ref);
889
903
  if (! ((~used_tables) & keyuse->getUsedTables())) // if const item
890
904
  {
891
905
    return new store_key_const_item(session,
898
912
  else if (key_use_val->type() == Item::FIELD_ITEM ||
899
913
           (key_use_val->type() == Item::REF_ITEM &&
900
914
            key_use_val->ref_type() == Item_ref::OUTER_REF &&
901
 
            (*(Item_ref**)((Item_ref*)key_use_val)->ref)->ref_type() == Item_ref::DIRECT_REF &&
 
915
            (*dir_val)->ref_type() == Item_ref::DIRECT_REF &&
902
916
            key_use_val->real_item()->type() == Item::FIELD_ITEM))
903
917
  {
904
918
    return new store_key_field(session,
926
940
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
927
941
{
928
942
  bool error;
929
 
  Table *table= field->getTable();
 
943
  Table *table= field->table;
930
944
  Session *session= table->in_use;
931
945
  ha_rows cuted_fields=session->cuted_fields;
932
946
 
933
947
  /*
934
948
    we should restore old value of count_cuted_fields because
935
 
    store_val_in_field can be called from insert_query
 
949
    store_val_in_field can be called from mysql_insert
936
950
    with select_insert, which make count_cuted_fields= 1
937
951
   */
938
952
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
957
971
    *e1= e2;
958
972
}
959
973
 
960
 
bool create_ref_for_key(Join *join, 
 
974
bool create_ref_for_key(JOIN *join, 
961
975
                        JoinTable *j, 
962
976
                        optimizer::KeyUse *org_keyuse,
963
977
                        table_map used_tables)
968
982
  uint32_t length;
969
983
  uint32_t key;
970
984
  Table *table= NULL;
971
 
  KeyInfo *keyinfo= NULL;
 
985
  KEY *keyinfo= NULL;
972
986
 
973
987
  /*  Use best key from find_best */
974
988
  table= j->table;
1005
1019
  j->ref.key_length=length;
1006
1020
  j->ref.key=(int) key;
1007
1021
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1008
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1022
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1009
1023
               (keyparts+1)))) ||
1010
 
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
1011
 
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
 
1024
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1025
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1012
1026
  {
1013
1027
    return(true);
1014
1028
  }
1135
1149
      3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
1136
1150
         appropiate JoinTable members.
1137
1151
*/
1138
 
void add_not_null_conds(Join *join)
 
1152
void add_not_null_conds(JOIN *join)
1139
1153
{
1140
1154
  for (uint32_t i= join->const_tables; i < join->tables; i++)
1141
1155
  {
1152
1166
          Item *notnull;
1153
1167
          assert(item->type() == Item::FIELD_ITEM);
1154
1168
          Item_field *not_null_item= (Item_field*)item;
1155
 
          JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
 
1169
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
1156
1170
          /*
1157
1171
            For UPDATE queries such as:
1158
1172
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
1209
1223
  return tmp;
1210
1224
}
1211
1225
 
 
1226
/*
 
1227
  Check if given expression uses only table fields covered by the given index
 
1228
 
 
1229
  SYNOPSIS
 
1230
    uses_index_fields_only()
 
1231
      item           Expression to check
 
1232
      tbl            The table having the index
 
1233
      keyno          The index number
 
1234
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
 
1235
 
 
1236
  DESCRIPTION
 
1237
    Check if given expression only uses fields covered by index #keyno in the
 
1238
    table tbl. The expression can use any fields in any other tables.
 
1239
 
 
1240
    The expression is guaranteed not to be AND or OR - those constructs are
 
1241
    handled outside of this function.
 
1242
 
 
1243
  RETURN
 
1244
    true   Yes
 
1245
    false  No
 
1246
*/
 
1247
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
 
1248
{
 
1249
  if (item->const_item())
 
1250
    return true;
 
1251
 
 
1252
  /*
 
1253
    Don't push down the triggered conditions. Nested outer joins execution
 
1254
    code may need to evaluate a condition several times (both triggered and
 
1255
    untriggered), and there is no way to put thi
 
1256
    TODO: Consider cloning the triggered condition and using the copies for:
 
1257
      1. push the first copy down, to have most restrictive index condition
 
1258
         possible
 
1259
      2. Put the second copy into tab->select_cond.
 
1260
  */
 
1261
  if (item->type() == Item::FUNC_ITEM &&
 
1262
      ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
 
1263
    return false;
 
1264
 
 
1265
  if (!(item->used_tables() & tbl->map))
 
1266
    return other_tbls_ok;
 
1267
 
 
1268
  Item::Type item_type= item->type();
 
1269
  switch (item_type) {
 
1270
  case Item::FUNC_ITEM:
 
1271
    {
 
1272
      /* This is a function, apply condition recursively to arguments */
 
1273
      Item_func *item_func= (Item_func*)item;
 
1274
      Item **child;
 
1275
      Item **item_end= (item_func->arguments()) + item_func->argument_count();
 
1276
      for (child= item_func->arguments(); child != item_end; child++)
 
1277
      {
 
1278
        if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
 
1279
          return false;
 
1280
      }
 
1281
      return true;
 
1282
    }
 
1283
  case Item::COND_ITEM:
 
1284
    {
 
1285
      /* This is a function, apply condition recursively to arguments */
 
1286
      List_iterator<Item> li(*((Item_cond*)item)->argument_list());
 
1287
      Item *list_item;
 
1288
      while ((list_item=li++))
 
1289
      {
 
1290
        if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
 
1291
          return false;
 
1292
      }
 
1293
      return true;
 
1294
    }
 
1295
  case Item::FIELD_ITEM:
 
1296
    {
 
1297
      Item_field *item_field= (Item_field*)item;
 
1298
      if (item_field->field->table != tbl)
 
1299
        return true;
 
1300
      return item_field->field->part_of_key.test(keyno);
 
1301
    }
 
1302
  case Item::REF_ITEM:
 
1303
    return uses_index_fields_only(item->real_item(), tbl, keyno,
 
1304
                                  other_tbls_ok);
 
1305
  default:
 
1306
    return false; /* Play it safe, don't push unknown non-const items */
 
1307
  }
 
1308
}
 
1309
 
1212
1310
#define ICP_COND_USES_INDEX_ONLY 10
1213
1311
 
 
1312
/*
 
1313
  Get a part of the condition that can be checked using only index fields
 
1314
 
 
1315
  SYNOPSIS
 
1316
    make_cond_for_index()
 
1317
      cond           The source condition
 
1318
      table          The table that is partially available
 
1319
      keyno          The index in the above table. Only fields covered by the index
 
1320
                     are available
 
1321
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
 
1322
 
 
1323
  DESCRIPTION
 
1324
    Get a part of the condition that can be checked when for the given table
 
1325
    we have values only of fields covered by some index. The condition may
 
1326
    refer to other tables, it is assumed that we have values of all of their
 
1327
    fields.
 
1328
 
 
1329
    Example:
 
1330
      make_cond_for_index(
 
1331
         "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
 
1332
          t2, keyno(t2.key1))
 
1333
      will return
 
1334
        "cond(t1.field) AND cond(t2.key2)"
 
1335
 
 
1336
  RETURN
 
1337
    Index condition, or NULL if no condition could be inferred.
 
1338
*/
 
1339
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
 
1340
{
 
1341
  if (!cond)
 
1342
    return NULL;
 
1343
  if (cond->type() == Item::COND_ITEM)
 
1344
  {
 
1345
    uint32_t n_marked= 0;
 
1346
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
 
1347
    {
 
1348
      Item_cond_and *new_cond=new Item_cond_and;
 
1349
      if (!new_cond)
 
1350
        return (COND*) 0;
 
1351
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1352
      Item *item;
 
1353
      while ((item=li++))
 
1354
      {
 
1355
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
 
1356
        if (fix)
 
1357
          new_cond->argument_list()->push_back(fix);
 
1358
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
 
1359
      }
 
1360
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
 
1361
        cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1362
      switch (new_cond->argument_list()->elements) {
 
1363
      case 0:
 
1364
        return (COND*) 0;
 
1365
      case 1:
 
1366
        return new_cond->argument_list()->head();
 
1367
      default:
 
1368
        new_cond->quick_fix_field();
 
1369
        return new_cond;
 
1370
      }
 
1371
    }
 
1372
    else /* It's OR */
 
1373
    {
 
1374
      Item_cond_or *new_cond=new Item_cond_or;
 
1375
      if (!new_cond)
 
1376
        return (COND*) 0;
 
1377
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1378
      Item *item;
 
1379
      while ((item=li++))
 
1380
      {
 
1381
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
 
1382
        if (!fix)
 
1383
          return (COND*) 0;
 
1384
        new_cond->argument_list()->push_back(fix);
 
1385
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
 
1386
      }
 
1387
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
 
1388
        cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1389
      new_cond->quick_fix_field();
 
1390
      new_cond->top_level_item();
 
1391
      return new_cond;
 
1392
    }
 
1393
  }
 
1394
 
 
1395
  if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
 
1396
    return (COND*) 0;
 
1397
  cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1398
  return cond;
 
1399
}
 
1400
 
 
1401
 
 
1402
static Item *make_cond_remainder(Item *cond, bool exclude_index)
 
1403
{
 
1404
  if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
 
1405
    return 0; /* Already checked */
 
1406
 
 
1407
  if (cond->type() == Item::COND_ITEM)
 
1408
  {
 
1409
    table_map tbl_map= 0;
 
1410
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
 
1411
    {
 
1412
      /* Create new top level AND item */
 
1413
      Item_cond_and *new_cond=new Item_cond_and;
 
1414
      if (!new_cond)
 
1415
        return (COND*) 0;
 
1416
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1417
      Item *item;
 
1418
      while ((item=li++))
 
1419
      {
 
1420
        Item *fix= make_cond_remainder(item, exclude_index);
 
1421
        if (fix)
 
1422
        {
 
1423
          new_cond->argument_list()->push_back(fix);
 
1424
          tbl_map |= fix->used_tables();
 
1425
        }
 
1426
      }
 
1427
      switch (new_cond->argument_list()->elements) {
 
1428
      case 0:
 
1429
        return (COND*) 0;
 
1430
      case 1:
 
1431
        return new_cond->argument_list()->head();
 
1432
      default:
 
1433
        new_cond->quick_fix_field();
 
1434
        ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
 
1435
        return new_cond;
 
1436
      }
 
1437
    }
 
1438
    else /* It's OR */
 
1439
    {
 
1440
      Item_cond_or *new_cond=new Item_cond_or;
 
1441
      if (!new_cond)
 
1442
        return (COND*) 0;
 
1443
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1444
      Item *item;
 
1445
      while ((item=li++))
 
1446
      {
 
1447
        Item *fix= make_cond_remainder(item, false);
 
1448
        if (!fix)
 
1449
          return (COND*) 0;
 
1450
        new_cond->argument_list()->push_back(fix);
 
1451
        tbl_map |= fix->used_tables();
 
1452
      }
 
1453
      new_cond->quick_fix_field();
 
1454
      ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
 
1455
      new_cond->top_level_item();
 
1456
      return new_cond;
 
1457
    }
 
1458
  }
 
1459
  return cond;
 
1460
}
1214
1461
 
1215
1462
/**
1216
1463
  cleanup JoinTable.
1222
1469
  delete quick;
1223
1470
  quick= 0;
1224
1471
  if (cache.buff)
1225
 
  {
1226
 
    size_t size= cache.end - cache.buff;
1227
 
    global_join_buffer.sub(size);
1228
1472
    free(cache.buff);
1229
 
  }
1230
1473
  cache.buff= 0;
1231
1474
  limit= 0;
1232
1475
  if (table)
1234
1477
    if (table->key_read)
1235
1478
    {
1236
1479
      table->key_read= 0;
1237
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
1480
      table->file->extra(HA_EXTRA_NO_KEYREAD);
1238
1481
    }
1239
 
    table->cursor->ha_index_or_rnd_end();
 
1482
    table->file->ha_index_or_rnd_end();
1240
1483
    /*
1241
1484
      We need to reset this for next select
1242
1485
      (Tested in part_of_refkey)
1243
1486
    */
1244
1487
    table->reginfo.join_tab= 0;
1245
1488
  }
1246
 
  read_record.end_read_record();
 
1489
  end_read_record(&read_record);
1247
1490
}
1248
1491
 
1249
 
bool only_eq_ref_tables(Join *join,Order *order,table_map tables)
 
1492
bool only_eq_ref_tables(JOIN *join,order_st *order,table_map tables)
1250
1493
{
1251
1494
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1252
1495
  {
1257
1500
}
1258
1501
 
1259
1502
/**
1260
 
  Remove the following expressions from ORDER BY and GROUP BY:
 
1503
  Remove the following expressions from order_st BY and GROUP BY:
1261
1504
  Constant expressions @n
1262
1505
  Expression that only uses tables that are of type EQ_REF and the reference
1263
1506
  is in the order_st list or if all refereed tables are of the above type.
1264
1507
 
1265
1508
  In the following, the X field can be removed:
1266
1509
  @code
1267
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
1268
 
  SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
 
1510
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t1.a,t2.X
 
1511
  SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b order_st BY t1.a,t3.X
1269
1512
  @endcode
1270
1513
 
1271
1514
  These can't be optimized:
1272
1515
  @code
1273
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
1274
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
1275
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
 
1516
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t2.X,t1.a
 
1517
  SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b order_st BY t1.a,t2.c
 
1518
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t2.b,t1.a
1276
1519
  @endcode
1277
1520
*/
1278
 
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
 
1521
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab)
1279
1522
{
1280
1523
  if (tab->cached_eq_ref_table)                 // If cached
1281
1524
    return tab->eq_ref_table;
1294
1537
  {
1295
1538
    if (! (*ref_item)->const_item())
1296
1539
    {                                           // Not a const ref
1297
 
      Order *order;
 
1540
      order_st *order;
1298
1541
      for (order=start_order ; order ; order=order->next)
1299
1542
      {
1300
1543
        if ((*ref_item)->eq(order->item[0],0))
2034
2277
    {
2035
2278
      if (table->on_expr)
2036
2279
      {
2037
 
        List<TableList> *nested_join_list= table->getNestedJoin() ?
2038
 
          &table->getNestedJoin()->join_list : NULL;
 
2280
        List<TableList> *nested_join_list= table->nested_join ?
 
2281
          &table->nested_join->join_list : NULL;
2039
2282
        /*
2040
2283
          We can modify table->on_expr because its old value will
2041
2284
          be restored before re-execution of PS/SP.
2088
2331
  if (outer_ref)
2089
2332
    return cmp;
2090
2333
  JoinTable **idx= (JoinTable **) table_join_idx;
2091
 
  cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
 
2334
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
2092
2335
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
2093
2336
}
2094
2337
 
2308
2551
  @param cond       condition whose multiple equalities are to be checked
2309
2552
  @param table      constant table that has been read
2310
2553
*/
2311
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2554
static void update_const_equal_items(COND *cond, JoinTable *tab)
2312
2555
{
2313
2556
  if (!(cond->used_tables() & tab->table->map))
2314
2557
    return;
2335
2578
      while ((item_field= it++))
2336
2579
      {
2337
2580
        Field *field= item_field->field;
2338
 
        JoinTable *stat= field->getTable()->reginfo.join_tab;
 
2581
        JoinTable *stat= field->table->reginfo.join_tab;
2339
2582
        key_map possible_keys= field->key_start;
2340
 
        possible_keys&= field->getTable()->keys_in_use_for_query;
 
2583
        possible_keys&= field->table->keys_in_use_for_query;
2341
2584
        stat[0].const_keys|= possible_keys;
2342
2585
 
2343
2586
        /*
2347
2590
        */
2348
2591
        if (possible_keys.any())
2349
2592
        {
2350
 
          Table *field_tab= field->getTable();
 
2593
          Table *field_tab= field->table;
2351
2594
          optimizer::KeyUse *use;
2352
2595
          for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
2353
2596
            if (possible_keys.test(use->getKey()) &&
2365
2608
  and_level
2366
2609
*/
2367
2610
static void change_cond_ref_to_const(Session *session,
2368
 
                                     list<COND_CMP>& save_list,
 
2611
                                     vector<COND_CMP>& save_list,
2369
2612
                                     Item *and_father,
2370
2613
                                     Item *cond,
2371
2614
                                     Item *field,
2378
2621
    Item *item;
2379
2622
    while ((item=li++))
2380
2623
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2381
 
 
2382
2624
    return;
2383
2625
  }
2384
2626
  if (cond->eq_cmp_result() == Item::COND_OK)
2397
2639
       left_item->collation.collation == value->collation.collation))
2398
2640
  {
2399
2641
    Item *tmp=value->clone_item();
 
2642
    tmp->collation.set(right_item->collation);
 
2643
 
2400
2644
    if (tmp)
2401
2645
    {
2402
 
      tmp->collation.set(right_item->collation);
2403
2646
      session->change_item_tree(args + 1, tmp);
2404
2647
      func->update_used_tables();
2405
2648
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2419
2662
            right_item->collation.collation == value->collation.collation))
2420
2663
  {
2421
2664
    Item *tmp= value->clone_item();
 
2665
    tmp->collation.set(left_item->collation);
 
2666
 
2422
2667
    if (tmp)
2423
2668
    {
2424
 
      tmp->collation.set(left_item->collation);
2425
2669
      session->change_item_tree(args, tmp);
2426
2670
      value= tmp;
2427
2671
      func->update_used_tables();
2471
2715
}
2472
2716
 
2473
2717
static void propagate_cond_constants(Session *session, 
2474
 
                                     list<COND_CMP>& save_list, 
 
2718
                                     vector<COND_CMP>& save_list, 
2475
2719
                                     COND *and_father, 
2476
2720
                                     COND *cond)
2477
2721
{
2480
2724
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2481
2725
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2482
2726
    Item *item;
2483
 
    list<COND_CMP> save;
 
2727
    vector<COND_CMP> save;
2484
2728
    while ((item=li++))
2485
2729
    {
2486
2730
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2488
2732
    if (and_level)
2489
2733
    {
2490
2734
      // Handle other found items
2491
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2735
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2492
2736
      {
2493
 
        Item **args= iter->second->arguments();
2494
 
        if (not args[0]->const_item())
 
2737
        Item **args= iter->cmp_func->arguments();
 
2738
        if (!args[0]->const_item())
2495
2739
        {
2496
 
          change_cond_ref_to_const(session, save, iter->first,
2497
 
                                   iter->first, args[0], args[1] );
 
2740
          change_cond_ref_to_const( session, save, iter->and_level,
 
2741
                                    iter->and_level, args[0], args[1] );
2498
2742
        }
2499
2743
      }
2500
2744
    }
2607
2851
         position:
2608
2852
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2609
2853
             joins) we've opened but didn't close.
2610
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2854
          2. {each nested_join_st structure not simplified away}->counter - number
2611
2855
             of this nested join's children that have already been added to to
2612
2856
             the partial join order.
2613
2857
  @endverbatim
2614
2858
 
2615
2859
  @param join       Join being processed
 
2860
  @param last_tab   Last table in current partial join order (this function is
 
2861
                    not called for empty partial join orders)
2616
2862
  @param next_tab   Table we're going to extend the current partial join with
2617
2863
 
2618
2864
  @retval
2621
2867
  @retval
2622
2868
    true   Requested join order extension not allowed.
2623
2869
*/
2624
 
bool check_interleaving_with_nj(JoinTable *next_tab)
 
2870
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
2625
2871
{
2626
 
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
2627
 
  Join *join= next_tab->join;
 
2872
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
 
2873
  JOIN *join= last_tab->join;
2628
2874
 
2629
2875
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2630
2876
  {
2639
2885
    Do update counters for "pairs of brackets" that we've left (marked as
2640
2886
    X,Y,Z in the above picture)
2641
2887
  */
2642
 
  for (;next_emb; next_emb= next_emb->getEmbedding())
 
2888
  for (;next_emb; next_emb= next_emb->embedding)
2643
2889
  {
2644
 
    next_emb->getNestedJoin()->counter_++;
2645
 
    if (next_emb->getNestedJoin()->counter_ == 1)
 
2890
    next_emb->nested_join->counter_++;
 
2891
    if (next_emb->nested_join->counter_ == 1)
2646
2892
    {
2647
2893
      /*
2648
2894
        next_emb is the first table inside a nested join we've "entered". In
2649
2895
        the picture above, we're looking at the 'X' bracket. Don't exit yet as
2650
2896
        X bracket might have Y pair bracket.
2651
2897
      */
2652
 
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
 
2898
      join->cur_embedding_map |= next_emb->nested_join->nj_map;
2653
2899
    }
2654
2900
 
2655
 
    if (next_emb->getNestedJoin()->join_list.elements !=
2656
 
        next_emb->getNestedJoin()->counter_)
 
2901
    if (next_emb->nested_join->join_list.elements !=
 
2902
        next_emb->nested_join->counter_)
2657
2903
      break;
2658
2904
 
2659
2905
    /*
2660
2906
      We're currently at Y or Z-bracket as depicted in the above picture.
2661
2907
      Mark that we've left it and continue walking up the brackets hierarchy.
2662
2908
    */
2663
 
    join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
 
2909
    join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
2664
2910
  }
2665
2911
  return false;
2666
2912
}
2667
2913
 
2668
 
COND *optimize_cond(Join *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
 
2914
COND *optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
2669
2915
{
2670
2916
  Session *session= join->session;
2671
2917
 
2685
2931
                             &join->cond_equal);
2686
2932
 
2687
2933
    /* change field = field to field = const for each found field = const */
2688
 
    list<COND_CMP> temp;
 
2934
    vector<COND_CMP> temp;
2689
2935
    propagate_cond_constants(session, temp, conds, conds);
2690
2936
    /*
2691
2937
      Remove all instances of item == item
2788
3034
    {
2789
3035
      Field *field= ((Item_field*) args[0])->field;
2790
3036
      if (field->flags & AUTO_INCREMENT_FLAG 
2791
 
          && ! field->getTable()->maybe_null 
 
3037
          && ! field->table->maybe_null 
2792
3038
          && session->options & OPTION_AUTO_IS_NULL
2793
3039
          && (
2794
3040
            session->first_successful_insert_id_in_prev_stmt > 0 
2846
3092
  /*
2847
3093
    TODO:
2848
3094
    Excluding all expensive functions is too restritive we should exclude only
2849
 
    materialized IN subquery predicates because they can't yet be evaluated
2850
 
    here (they need additional initialization that is done later on).
2851
 
 
2852
 
    The proper way to exclude the subqueries would be to walk the cond tree and
2853
 
    check for materialized subqueries there.
2854
 
 
 
3095
    materialized IN because it is created later than this phase, and cannot be
 
3096
    evaluated at this point.
 
3097
    The condition should be something as (need to fix member access):
 
3098
      !(cond->type() == Item::FUNC_ITEM &&
 
3099
        ((Item_func*)cond)->func_name() == "<in_optimizer>" &&
 
3100
        ((Item_in_optimizer*)cond)->is_expensive()))
2855
3101
  */
2856
3102
  {
2857
3103
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
2974
3220
  @return
2975
3221
    end_select function to use. This function can't fail.
2976
3222
*/
2977
 
Next_select_func setup_end_select_func(Join *join)
 
3223
Next_select_func setup_end_select_func(JOIN *join)
2978
3224
{
2979
3225
  Table *table= join->tmp_table;
2980
3226
  Tmp_Table_Param *tmp_tbl= &join->tmp_table_param;
2986
3232
    if (table->group && tmp_tbl->sum_func_count &&
2987
3233
        !tmp_tbl->precomputed_group_by)
2988
3234
    {
2989
 
      if (table->getShare()->sizeKeys())
 
3235
      if (table->s->keys)
2990
3236
      {
2991
3237
        end_select= end_update;
2992
3238
      }
2997
3243
    }
2998
3244
    else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
2999
3245
    {
3000
 
      end_select= end_write_group;
 
3246
      end_select=end_write_group;
3001
3247
    }
3002
3248
    else
3003
3249
    {
3004
 
      end_select= end_write;
 
3250
      end_select=end_write;
3005
3251
      if (tmp_tbl->precomputed_group_by)
3006
3252
      {
3007
3253
        /*
3039
3285
  @retval
3040
3286
    -1  if error should be sent
3041
3287
*/
3042
 
int do_select(Join *join, List<Item> *fields, Table *table)
 
3288
int do_select(JOIN *join, List<Item> *fields, Table *table)
3043
3289
{
3044
3290
  int rc= 0;
3045
3291
  enum_nested_loop_state error= NESTED_LOOP_OK;
3050
3296
 
3051
3297
  if (table)
3052
3298
  {
3053
 
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
3299
    table->file->extra(HA_EXTRA_WRITE_CACHE);
3054
3300
    table->emptyRecord();
3055
3301
    if (table->group && join->tmp_table_param.sum_func_count &&
3056
 
        table->getShare()->sizeKeys() && !table->cursor->inited)
3057
 
    {
3058
 
      int tmp_error;
3059
 
      tmp_error= table->cursor->startIndexScan(0, 0);
3060
 
      if (tmp_error != 0)
3061
 
      {
3062
 
        table->print_error(tmp_error, MYF(0));
3063
 
        return -1;
3064
 
      }
3065
 
    }
 
3302
        table->s->keys && !table->file->inited)
 
3303
      table->file->ha_index_init(0, 0);
3066
3304
  }
3067
3305
  /* Set up select_end */
3068
3306
  Next_select_func end_select= setup_end_select_func(join);
3134
3372
  if (table)
3135
3373
  {
3136
3374
    int tmp, new_errno= 0;
3137
 
    if ((tmp=table->cursor->extra(HA_EXTRA_NO_CACHE)))
 
3375
    if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
3138
3376
    {
3139
3377
      new_errno= tmp;
3140
3378
    }
3141
 
    if ((tmp=table->cursor->ha_index_or_rnd_end()))
 
3379
    if ((tmp=table->file->ha_index_or_rnd_end()))
3142
3380
    {
3143
3381
      new_errno= tmp;
3144
3382
    }
3145
3383
    if (new_errno)
3146
 
      table->print_error(new_errno,MYF(0));
 
3384
      table->file->print_error(new_errno,MYF(0));
3147
3385
  }
3148
3386
  return(join->session->is_error() ? -1 : rc);
3149
3387
}
3150
3388
 
3151
 
enum_nested_loop_state sub_select_cache(Join *join, JoinTable *join_tab, bool end_of_records)
 
3389
enum_nested_loop_state sub_select_cache(JOIN *join, JoinTable *join_tab, bool end_of_records)
3152
3390
{
3153
3391
  enum_nested_loop_state rc;
3154
3392
 
3159
3397
      rc= sub_select(join,join_tab,end_of_records);
3160
3398
    return rc;
3161
3399
  }
3162
 
  if (join->session->getKilled())               // If aborted by user
 
3400
  if (join->session->killed)            // If aborted by user
3163
3401
  {
3164
3402
    join->session->send_kill_message();
3165
3403
    return NESTED_LOOP_KILLED;
3166
3404
  }
3167
3405
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
3168
3406
  {
3169
 
    if (! join_tab->cache.store_record_in_cache())
 
3407
    if (! store_record_in_cache(&join_tab->cache))
3170
3408
      return NESTED_LOOP_OK;                     // There is more room in cache
3171
3409
    return flush_cached_records(join,join_tab,false);
3172
3410
  }
3295
3533
  @return
3296
3534
    return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
3297
3535
*/
3298
 
enum_nested_loop_state sub_select(Join *join, JoinTable *join_tab, bool end_of_records)
 
3536
enum_nested_loop_state sub_select(JOIN *join, JoinTable *join_tab, bool end_of_records)
3299
3537
{
3300
3538
  join_tab->table->null_row=0;
3301
3539
  if (end_of_records)
3303
3541
 
3304
3542
  int error;
3305
3543
  enum_nested_loop_state rc;
3306
 
  ReadRecord *info= &join_tab->read_record;
 
3544
  READ_RECORD *info= &join_tab->read_record;
3307
3545
 
3308
3546
  if (join->resume_nested_loop)
3309
3547
  {
3360
3598
{
3361
3599
  int error;
3362
3600
  Table *table= tab->table;
3363
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3601
  if ((error=table->file->index_read_map(table->record[0],
3364
3602
                                         tab->ref.key_buff,
3365
3603
                                         make_prev_keypart_map(tab->ref.key_parts),
3366
3604
                                         HA_READ_KEY_EXACT)))
3368
3606
  return 0;
3369
3607
}
3370
3608
 
 
3609
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3610
{
 
3611
  int error;
 
3612
  Table *table=tab->table;
 
3613
  table->const_table=1;
 
3614
  table->null_row=0;
 
3615
  table->status=STATUS_NO_RECORD;
 
3616
 
 
3617
  if (tab->type == AM_SYSTEM)
 
3618
  {
 
3619
    if ((error=join_read_system(tab)))
 
3620
    {                                           // Info for DESCRIBE
 
3621
      tab->info="const row not found";
 
3622
      /* Mark for EXPLAIN that the row was not found */
 
3623
      pos->setFanout(0.0);
 
3624
      pos->clearRefDependMap();
 
3625
      if (! table->maybe_null || error > 0)
 
3626
        return(error);
 
3627
    }
 
3628
  }
 
3629
  else
 
3630
  {
 
3631
    if (! table->key_read && 
 
3632
        table->covering_keys.test(tab->ref.key) && 
 
3633
        ! table->no_keyread &&
 
3634
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3635
    {
 
3636
      table->key_read=1;
 
3637
      table->file->extra(HA_EXTRA_KEYREAD);
 
3638
      tab->index= tab->ref.key;
 
3639
    }
 
3640
    error=join_read_const(tab);
 
3641
    if (table->key_read)
 
3642
    {
 
3643
      table->key_read=0;
 
3644
      table->file->extra(HA_EXTRA_NO_KEYREAD);
 
3645
    }
 
3646
    if (error)
 
3647
    {
 
3648
      tab->info="unique row not found";
 
3649
      /* Mark for EXPLAIN that the row was not found */
 
3650
      pos->setFanout(0.0);
 
3651
      pos->clearRefDependMap();
 
3652
      if (!table->maybe_null || error > 0)
 
3653
        return(error);
 
3654
    }
 
3655
  }
 
3656
  if (*tab->on_expr_ref && !table->null_row)
 
3657
  {
 
3658
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3659
      table->mark_as_null_row();
 
3660
  }
 
3661
  if (!table->null_row)
 
3662
    table->maybe_null=0;
 
3663
 
 
3664
  /* Check appearance of new constant items in Item_equal objects */
 
3665
  JOIN *join= tab->join;
 
3666
  if (join->conds)
 
3667
    update_const_equal_items(join->conds, tab);
 
3668
  TableList *tbl;
 
3669
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3670
  {
 
3671
    TableList *embedded;
 
3672
    TableList *embedding= tbl;
 
3673
    do
 
3674
    {
 
3675
      embedded= embedding;
 
3676
      if (embedded->on_expr)
 
3677
         update_const_equal_items(embedded->on_expr, tab);
 
3678
      embedding= embedded->embedding;
 
3679
    }
 
3680
    while (embedding &&
 
3681
           embedding->nested_join->join_list.head() == embedded);
 
3682
  }
 
3683
 
 
3684
  return(0);
 
3685
}
 
3686
 
 
3687
int join_read_system(JoinTable *tab)
 
3688
{
 
3689
  Table *table= tab->table;
 
3690
  int error;
 
3691
  if (table->status & STATUS_GARBAGE)           // If first read
 
3692
  {
 
3693
    if ((error=table->file->read_first_row(table->record[0],
 
3694
                                           table->s->primary_key)))
 
3695
    {
 
3696
      if (error != HA_ERR_END_OF_FILE)
 
3697
        return table->report_error(error);
 
3698
      tab->table->mark_as_null_row();
 
3699
      table->emptyRecord();                     // Make empty record
 
3700
      return -1;
 
3701
    }
 
3702
    table->storeRecord();
 
3703
  }
 
3704
  else if (!table->status)                      // Only happens with left join
 
3705
    table->restoreRecord();                     // restore old record
 
3706
  table->null_row=0;
 
3707
  return table->status ? -1 : 0;
 
3708
}
 
3709
 
3371
3710
/**
3372
3711
  Read a (constant) table when there is at most one matching row.
3373
3712
 
3391
3730
      error= HA_ERR_KEY_NOT_FOUND;
3392
3731
    else
3393
3732
    {
3394
 
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
 
3733
      error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
3395
3734
                                            (unsigned char*) tab->ref.key_buff,
3396
3735
                                            make_prev_keypart_map(tab->ref.key_parts),
3397
3736
                                            HA_READ_KEY_EXACT);
3437
3776
  int error;
3438
3777
  Table *table= tab->table;
3439
3778
 
3440
 
  if (!table->cursor->inited)
 
3779
  if (!table->file->inited)
3441
3780
  {
3442
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3443
 
    if (error != 0)
3444
 
    {
3445
 
      table->print_error(error, MYF(0));
3446
 
    }
 
3781
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3447
3782
  }
3448
3783
 
3449
3784
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3455
3790
      table->status=STATUS_NOT_FOUND;
3456
3791
      return -1;
3457
3792
    }
3458
 
    error=table->cursor->index_read_map(table->getInsertRecord(),
 
3793
    error=table->file->index_read_map(table->record[0],
3459
3794
                                      tab->ref.key_buff,
3460
3795
                                      make_prev_keypart_map(tab->ref.key_parts),
3461
3796
                                      HA_READ_KEY_EXACT);
3490
3825
  Table *table= tab->table;
3491
3826
 
3492
3827
  /* Initialize the index first */
3493
 
  if (!table->cursor->inited)
3494
 
  {
3495
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3496
 
    if (error != 0)
3497
 
      return table->report_error(error);
3498
 
  }
 
3828
  if (!table->file->inited)
 
3829
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3499
3830
 
3500
3831
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3501
3832
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3506
3837
 
3507
3838
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3508
3839
    return -1;
3509
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3840
  if ((error=table->file->index_read_map(table->record[0],
3510
3841
                                         tab->ref.key_buff,
3511
3842
                                         make_prev_keypart_map(tab->ref.key_parts),
3512
3843
                                         HA_READ_KEY_EXACT)))
3520
3851
}
3521
3852
 
3522
3853
/**
3523
 
  This function is used when optimizing away ORDER BY in
3524
 
  SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC.
 
3854
  This function is used when optimizing away order_st BY in
 
3855
  SELECT * FROM t1 WHERE a=1 order_st BY a DESC,b DESC.
3525
3856
*/
3526
3857
int join_read_last_key(JoinTable *tab)
3527
3858
{
3528
3859
  int error;
3529
3860
  Table *table= tab->table;
3530
3861
 
3531
 
  if (!table->cursor->inited)
3532
 
  {
3533
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3534
 
    if (error != 0)
3535
 
      return table->report_error(error);
3536
 
  }
 
3862
  if (!table->file->inited)
 
3863
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3537
3864
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3538
3865
    return -1;
3539
 
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
 
3866
  if ((error=table->file->index_read_last_map(table->record[0],
3540
3867
                                              tab->ref.key_buff,
3541
3868
                                              make_prev_keypart_map(tab->ref.key_parts))))
3542
3869
  {
3547
3874
  return 0;
3548
3875
}
3549
3876
 
3550
 
int join_no_more_records(ReadRecord *)
 
3877
int join_no_more_records(READ_RECORD *)
3551
3878
{
3552
3879
  return -1;
3553
3880
}
3554
3881
 
3555
 
int join_read_next_same_diff(ReadRecord *info)
 
3882
int join_read_next_same_diff(READ_RECORD *info)
3556
3883
{
3557
3884
  Table *table= info->table;
3558
3885
  JoinTable *tab=table->reginfo.join_tab;
3559
3886
  if (tab->insideout_match_tab->found_match)
3560
3887
  {
3561
 
    KeyInfo *key= tab->table->key_info + tab->index;
 
3888
    KEY *key= tab->table->key_info + tab->index;
3562
3889
    do
3563
3890
    {
3564
3891
      int error;
3565
3892
      /* Save index tuple from record to the buffer */
3566
3893
      key_copy(tab->insideout_buf, info->record, key, 0);
3567
3894
 
3568
 
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3895
      if ((error=table->file->index_next_same(table->record[0],
3569
3896
                                              tab->ref.key_buff,
3570
3897
                                              tab->ref.key_length)))
3571
3898
      {
3583
3910
    return join_read_next_same(info);
3584
3911
}
3585
3912
 
3586
 
int join_read_next_same(ReadRecord *info)
 
3913
int join_read_next_same(READ_RECORD *info)
3587
3914
{
3588
3915
  int error;
3589
3916
  Table *table= info->table;
3590
3917
  JoinTable *tab=table->reginfo.join_tab;
3591
3918
 
3592
 
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3919
  if ((error=table->file->index_next_same(table->record[0],
3593
3920
                                          tab->ref.key_buff,
3594
3921
                                          tab->ref.key_length)))
3595
3922
  {
3602
3929
  return 0;
3603
3930
}
3604
3931
 
3605
 
int join_read_prev_same(ReadRecord *info)
 
3932
int join_read_prev_same(READ_RECORD *info)
3606
3933
{
3607
3934
  int error;
3608
3935
  Table *table= info->table;
3609
3936
  JoinTable *tab=table->reginfo.join_tab;
3610
3937
 
3611
 
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
 
3938
  if ((error=table->file->index_prev(table->record[0])))
3612
3939
    return table->report_error(error);
3613
3940
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3614
3941
                      tab->ref.key_length))
3626
3953
  return join_init_read_record(tab);
3627
3954
}
3628
3955
 
 
3956
int rr_sequential(READ_RECORD *info);
3629
3957
int init_read_record_seq(JoinTable *tab)
3630
3958
{
3631
 
  tab->read_record.init_reard_record_sequential();
3632
 
 
3633
 
  if (tab->read_record.cursor->startTableScan(1))
 
3959
  tab->read_record.read_record= rr_sequential;
 
3960
  if (tab->read_record.file->ha_rnd_init(1))
3634
3961
    return 1;
3635
3962
  return (*tab->read_record.read_record)(&tab->read_record);
3636
3963
}
3647
3974
{
3648
3975
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3649
3976
    return 1;
3650
 
 
3651
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3652
 
    return 1;
3653
 
 
 
3977
  init_read_record(&tab->read_record, tab->join->session, tab->table,
 
3978
                   tab->select,1,1);
3654
3979
  return (*tab->read_record.read_record)(&tab->read_record);
3655
3980
}
3656
3981
 
3661
3986
  if (!table->key_read && table->covering_keys.test(tab->index) &&
3662
3987
      !table->no_keyread)
3663
3988
  {
3664
 
    table->key_read= 1;
3665
 
    table->cursor->extra(HA_EXTRA_KEYREAD);
 
3989
    table->key_read=1;
 
3990
    table->file->extra(HA_EXTRA_KEYREAD);
3666
3991
  }
3667
 
  tab->table->status= 0;
 
3992
  tab->table->status=0;
3668
3993
  tab->read_record.table=table;
3669
 
  tab->read_record.cursor=table->cursor;
 
3994
  tab->read_record.file=table->file;
3670
3995
  tab->read_record.index=tab->index;
3671
 
  tab->read_record.record=table->getInsertRecord();
 
3996
  tab->read_record.record=table->record[0];
3672
3997
  if (tab->insideout_match_tab)
3673
3998
  {
3674
3999
    tab->read_record.do_insideout_scan= tab;
3681
4006
    tab->read_record.do_insideout_scan= 0;
3682
4007
  }
3683
4008
 
3684
 
  if (!table->cursor->inited)
3685
 
  {
3686
 
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
3687
 
    if (error != 0)
3688
 
    {
3689
 
      table->report_error(error);
3690
 
      return -1;
3691
 
    }
3692
 
  }
3693
 
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
 
4009
  if (!table->file->inited)
 
4010
    table->file->ha_index_init(tab->index, tab->sorted);
 
4011
  if ((error=tab->table->file->index_first(tab->table->record[0])))
3694
4012
  {
3695
4013
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3696
4014
      table->report_error(error);
3700
4018
  return 0;
3701
4019
}
3702
4020
 
3703
 
int join_read_next_different(ReadRecord *info)
 
4021
int join_read_next_different(READ_RECORD *info)
3704
4022
{
3705
4023
  JoinTable *tab= info->do_insideout_scan;
3706
4024
  if (tab->insideout_match_tab->found_match)
3707
4025
  {
3708
 
    KeyInfo *key= tab->table->key_info + tab->index;
 
4026
    KEY *key= tab->table->key_info + tab->index;
3709
4027
    do
3710
4028
    {
3711
4029
      int error;
3712
4030
      /* Save index tuple from record to the buffer */
3713
4031
      key_copy(tab->insideout_buf, info->record, key, 0);
3714
4032
 
3715
 
      if ((error=info->cursor->index_next(info->record)))
 
4033
      if ((error=info->file->index_next(info->record)))
3716
4034
        return info->table->report_error(error);
3717
4035
    } while (!key_cmp(tab->table->key_info[tab->index].key_part,
3718
4036
                      tab->insideout_buf, key->key_length));
3723
4041
    return join_read_next(info);
3724
4042
}
3725
4043
 
3726
 
int join_read_next(ReadRecord *info)
 
4044
int join_read_next(READ_RECORD *info)
3727
4045
{
3728
4046
  int error;
3729
 
  if ((error=info->cursor->index_next(info->record)))
 
4047
  if ((error=info->file->index_next(info->record)))
3730
4048
    return info->table->report_error(error);
3731
4049
  return 0;
3732
4050
}
3739
4057
      !table->no_keyread)
3740
4058
  {
3741
4059
    table->key_read=1;
3742
 
    table->cursor->extra(HA_EXTRA_KEYREAD);
 
4060
    table->file->extra(HA_EXTRA_KEYREAD);
3743
4061
  }
3744
4062
  tab->table->status=0;
3745
4063
  tab->read_record.read_record=join_read_prev;
3746
4064
  tab->read_record.table=table;
3747
 
  tab->read_record.cursor=table->cursor;
 
4065
  tab->read_record.file=table->file;
3748
4066
  tab->read_record.index=tab->index;
3749
 
  tab->read_record.record=table->getInsertRecord();
3750
 
  if (!table->cursor->inited)
3751
 
  {
3752
 
    error= table->cursor->startIndexScan(tab->index, 1);
3753
 
    if (error != 0)
3754
 
      return table->report_error(error);
3755
 
  }
3756
 
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
 
4067
  tab->read_record.record=table->record[0];
 
4068
  if (!table->file->inited)
 
4069
    table->file->ha_index_init(tab->index, 1);
 
4070
  if ((error= tab->table->file->index_last(tab->table->record[0])))
3757
4071
    return table->report_error(error);
3758
4072
 
3759
4073
  return 0;
3760
4074
}
3761
4075
 
3762
 
int join_read_prev(ReadRecord *info)
 
4076
int join_read_prev(READ_RECORD *info)
3763
4077
{
3764
4078
  int error;
3765
 
  if ((error= info->cursor->index_prev(info->record)))
 
4079
  if ((error= info->file->index_prev(info->record)))
3766
4080
    return info->table->report_error(error);
3767
4081
 
3768
4082
  return 0;
3785
4099
  return safe_index_read(tab);
3786
4100
}
3787
4101
 
3788
 
int join_read_next_same_or_null(ReadRecord *info)
 
4102
int join_read_next_same_or_null(READ_RECORD *info)
3789
4103
{
3790
4104
  int error;
3791
4105
  if ((error= join_read_next_same(info)) >= 0)
3799
4113
  return safe_index_read(tab);                  // then read null keys
3800
4114
}
3801
4115
 
3802
 
enum_nested_loop_state end_send_group(Join *join, JoinTable *, bool end_of_records)
 
4116
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *, bool end_of_records)
3803
4117
{
3804
4118
  int idx= -1;
3805
4119
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
3832
4146
              error=join->result->send_data(*join->fields) ? 1 : 0;
3833
4147
            join->send_records++;
3834
4148
          }
3835
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
4149
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3836
4150
          {
3837
4151
            if (join->rollup_send_data((uint32_t) (idx+1)))
3838
4152
              error= 1;
3888
4202
  return(NESTED_LOOP_OK);
3889
4203
}
3890
4204
 
3891
 
enum_nested_loop_state end_write_group(Join *join, JoinTable *, bool end_of_records)
 
4205
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *, bool end_of_records)
3892
4206
{
3893
4207
  Table *table=join->tmp_table;
3894
4208
  int     idx= -1;
3895
4209
 
3896
 
  if (join->session->getKilled())
 
4210
  if (join->session->killed)
3897
4211
  {                                             // Aborted by user
3898
4212
    join->session->send_kill_message();
3899
4213
    return NESTED_LOOP_KILLED;
3914
4228
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
3915
4229
        if (!join->having || join->having->val_int())
3916
4230
        {
3917
 
          int error= table->cursor->insertRecord(table->getInsertRecord());
3918
 
 
3919
 
          if (error)
3920
 
          {
3921
 
            my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
3922
 
            return NESTED_LOOP_ERROR;
3923
 
          }
 
4231
          int error= table->file->ha_write_row(table->record[0]);
 
4232
          if (error && create_myisam_from_heap(join->session, table,
 
4233
                                              join->tmp_table_param.start_recinfo,
 
4234
                                                &join->tmp_table_param.recinfo,
 
4235
                                              error, 0))
 
4236
          return NESTED_LOOP_ERROR;
3924
4237
        }
3925
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
4238
        if (join->rollup.state != ROLLUP::STATE_NONE)
3926
4239
        {
3927
4240
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3928
4241
            return NESTED_LOOP_ERROR;
3941
4254
    if (idx < (int) join->send_group_parts)
3942
4255
    {
3943
4256
      copy_fields(&join->tmp_table_param);
3944
 
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3945
 
        return NESTED_LOOP_ERROR;
 
4257
      copy_funcs(join->tmp_table_param.items_to_copy);
3946
4258
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
3947
4259
        return NESTED_LOOP_ERROR;
3948
4260
      return NESTED_LOOP_OK;
3959
4271
  outer join table.
3960
4272
  We can't remove tests that are made against columns which are stored
3961
4273
  in sorted order.
 
4274
*****************************************************************************/
 
4275
 
 
4276
/**
3962
4277
  @return
3963
 
    1 if right_item used is a removable reference key on left_item
3964
 
    0 otherwise.
3965
 
****************************************************************************/
 
4278
    1 if right_item is used removable reference key on left_item
 
4279
*/
3966
4280
bool test_if_ref(Item_field *left_item,Item *right_item)
3967
4281
{
3968
4282
  Field *field=left_item->field;
3969
4283
  // No need to change const test. We also have to keep tests on LEFT JOIN
3970
 
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
 
4284
  if (!field->table->const_table && !field->table->maybe_null)
3971
4285
  {
3972
 
    Item *ref_item=part_of_refkey(field->getTable(),field);
 
4286
    Item *ref_item=part_of_refkey(field->table,field);
3973
4287
    if (ref_item && ref_item->eq(right_item,1))
3974
4288
    {
3975
4289
      right_item= right_item->real_item();
4152
4466
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
4153
4467
  if (ref_parts)
4154
4468
  {
4155
 
    KeyPartInfo *key_part=
 
4469
    KEY_PART_INFO *key_part=
4156
4470
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
4157
4471
    uint32_t part;
4158
4472
 
4163
4477
    }
4164
4478
 
4165
4479
    for (part=0 ; part < ref_parts ; part++,key_part++)
4166
 
    {
4167
4480
      if (field->eq(key_part->field) &&
4168
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4169
 
          //If field can be NULL, we should not remove this predicate, as
4170
 
          //it may lead to non-rejection of NULL values. 
4171
 
          !(field->real_maybe_null()))
4172
 
      {
 
4481
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
4173
4482
        return table->reginfo.join_tab->ref.items[part];
4174
 
      }
4175
 
    }
4176
4483
  }
4177
4484
  return (Item*) 0;
4178
4485
}
4197
4504
  @retval
4198
4505
    -1   Reverse key can be used
4199
4506
*/
4200
 
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4507
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4201
4508
{
4202
 
  KeyPartInfo *key_part= NULL;
4203
 
  KeyPartInfo *key_part_end= NULL;
 
4509
  KEY_PART_INFO *key_part= NULL;
 
4510
  KEY_PART_INFO *key_part_end= NULL;
4204
4511
  key_part= table->key_info[idx].key_part;
4205
4512
  key_part_end= key_part + table->key_info[idx].key_parts;
4206
4513
  key_part_map const_key_parts=table->const_key_parts[idx];
4214
4521
 
4215
4522
    /*
4216
4523
      Skip key parts that are constants in the WHERE clause.
4217
 
      These are already skipped in the ORDER BY by const_expression_in_where()
 
4524
      These are already skipped in the order_st BY by const_expression_in_where()
4218
4525
    */
4219
4526
    for (; const_key_parts & 1 ; const_key_parts>>= 1)
4220
4527
      key_part++;
4227
4534
        the primary key as a suffix.
4228
4535
      */
4229
4536
      if (!on_primary_key &&
4230
 
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
4231
 
          table->getShare()->hasPrimaryKey())
 
4537
          (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
 
4538
          table->s->primary_key != MAX_KEY)
4232
4539
      {
4233
4540
        on_primary_key= true;
4234
 
        key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
4235
 
        key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
4236
 
        const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
 
4541
        key_part= table->key_info[table->s->primary_key].key_part;
 
4542
        key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
 
4543
        const_key_parts=table->const_key_parts[table->s->primary_key];
4237
4544
 
4238
4545
        for (; const_key_parts & 1 ; const_key_parts>>= 1)
4239
4546
          key_part++;
4261
4568
  }
4262
4569
  *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
4263
4570
    (uint32_t) (key_part - table->key_info[idx].key_part);
4264
 
  if (reverse == -1 && !(table->index_flags(idx) &
 
4571
  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
4265
4572
                         HA_READ_PREV))
4266
4573
    reverse= 0;                                 // Index can't be used
4267
4574
  return(reverse);
4282
4589
  @retval
4283
4590
    0   no sub key
4284
4591
*/
4285
 
inline bool is_subkey(KeyPartInfo *key_part,
4286
 
                      KeyPartInfo *ref_key_part,
4287
 
                      KeyPartInfo *ref_key_part_end)
 
4592
inline bool is_subkey(KEY_PART_INFO *key_part,
 
4593
                      KEY_PART_INFO *ref_key_part,
 
4594
                      KEY_PART_INFO *ref_key_part_end)
4288
4595
{
4289
4596
  for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
4290
4597
    if (! key_part->field->eq(ref_key_part->field))
4303
4610
    - MAX_KEY                   If we can't use other key
4304
4611
    - the number of found key   Otherwise
4305
4612
*/
4306
 
static uint32_t test_if_subkey(Order *order,
 
4613
static uint32_t test_if_subkey(order_st *order,
4307
4614
                               Table *table,
4308
4615
                               uint32_t ref,
4309
4616
                               uint32_t ref_key_parts,
4313
4620
  uint32_t min_length= UINT32_MAX;
4314
4621
  uint32_t best= MAX_KEY;
4315
4622
  uint32_t not_used;
4316
 
  KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
4317
 
  KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
 
4623
  KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
 
4624
  KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
4318
4625
 
4319
 
  for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
 
4626
  for (nr= 0 ; nr < table->s->keys ; nr++)
4320
4627
  {
4321
4628
    if (usable_keys->test(nr) &&
4322
4629
        table->key_info[nr].key_length < min_length &&
4365
4672
*/
4366
4673
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
4367
4674
{
4368
 
  for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
 
4675
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
4369
4676
  {
4370
 
    if (keynr == table->getShare()->getPrimaryKey() ||
 
4677
    if (keynr == table->s->primary_key ||
4371
4678
         (table->key_info[keynr].flags & HA_NOSAME))
4372
4679
    {
4373
 
      KeyInfo *keyinfo= table->key_info + keynr;
4374
 
      KeyPartInfo *key_part= NULL;
4375
 
      KeyPartInfo *key_part_end= NULL;
 
4680
      KEY *keyinfo= table->key_info + keynr;
 
4681
      KEY_PART_INFO *key_part= NULL;
 
4682
      KEY_PART_INFO *key_part_end= NULL;
4376
4683
 
4377
4684
      for (key_part=keyinfo->key_part,
4378
4685
           key_part_end=key_part+ keyinfo->key_parts;
4405
4712
*/
4406
4713
bool find_field_in_order_list (Field *field, void *data)
4407
4714
{
4408
 
  Order *group= (Order *) data;
 
4715
  order_st *group= (order_st *) data;
4409
4716
  bool part_found= 0;
4410
 
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4717
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4411
4718
  {
4412
4719
    Item *item= (*tmp_group->item)->real_item();
4413
4720
    if (item->type() == Item::FIELD_ITEM &&
4453
4760
}
4454
4761
 
4455
4762
/**
4456
 
  Test if we can skip the ORDER BY by using an index.
 
4763
  Test if we can skip the order_st BY by using an index.
4457
4764
 
4458
4765
  SYNOPSIS
4459
4766
    test_if_skip_sort_order()
4477
4784
  @retval
4478
4785
    1    We can use an index.
4479
4786
*/
4480
 
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4787
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
4481
4788
{
4482
4789
  int32_t ref_key;
4483
4790
  uint32_t ref_key_parts;
4484
4791
  int order_direction;
4485
4792
  uint32_t used_key_parts;
4486
4793
  Table *table=tab->table;
4487
 
  optimizer::SqlSelect *select= tab->select;
 
4794
  SQL_SELECT *select=tab->select;
4488
4795
  key_map usable_keys;
4489
 
  optimizer::QuickSelectInterface *save_quick= NULL;
 
4796
  QUICK_SELECT_I *save_quick= 0;
4490
4797
 
4491
4798
  /*
4492
4799
    Keys disabled by ALTER Table ... DISABLE KEYS should have already
4494
4801
  */
4495
4802
  usable_keys= *map;
4496
4803
 
4497
 
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4804
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4498
4805
  {
4499
4806
    Item *item= (*tmp_order->item)->real_item();
4500
4807
    if (item->type() != Item::FIELD_ITEM)
4516
4823
    if (tab->type == AM_REF_OR_NULL)
4517
4824
      return(0);
4518
4825
  }
4519
 
  else if (select && select->quick)             // Range found by optimizer/range
 
4826
  else if (select && select->quick)             // Range found by opt_range
4520
4827
  {
4521
4828
    int quick_type= select->quick->get_type();
4522
4829
    save_quick= select->quick;
4526
4833
      by clustered PK values.
4527
4834
    */
4528
4835
 
4529
 
    if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
4530
 
        quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
4531
 
        quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT)
 
4836
    if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
 
4837
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
4838
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
4532
4839
      return(0);
4533
4840
    ref_key=       select->quick->index;
4534
4841
    ref_key_parts= select->quick->used_key_parts;
4578
4885
        else
4579
4886
        {
4580
4887
          /*
4581
 
            The range optimizer constructed QuickRange for ref_key, and
 
4888
            The range optimizer constructed QUICK_RANGE for ref_key, and
4582
4889
            we want to use instead new_ref_key as the index. We can't
4583
4890
            just change the index of the quick select, because this may
4584
4891
            result in an incosistent QUICK_SELECT object. Below we
4623
4930
    int best_key= -1;
4624
4931
    bool is_best_covering= false;
4625
4932
    double fanout= 1;
4626
 
    Join *join= tab->join;
 
4933
    JOIN *join= tab->join;
4627
4934
    uint32_t tablenr= tab - join->join_tab;
4628
 
    ha_rows table_records= table->cursor->stats.records;
 
4935
    ha_rows table_records= table->file->stats.records;
4629
4936
    bool group= join->group && order == join->group_list;
4630
4937
    optimizer::Position cur_pos;
4631
4938
 
4642
4949
        */
4643
4950
      if (tab->type == AM_ALL && tab->join->tables > tab->join->const_tables + 1)
4644
4951
        return(0);
4645
 
      keys= *table->cursor->keys_to_use_for_scanning();
 
4952
      keys= *table->file->keys_to_use_for_scanning();
4646
4953
      keys|= table->covering_keys;
4647
4954
 
4648
4955
      /*
4666
4973
      fanout*= cur_pos.getFanout(); // fanout is always >= 1
4667
4974
    }
4668
4975
 
4669
 
    for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
 
4976
    for (nr=0; nr < table->s->keys ; nr++)
4670
4977
    {
4671
4978
      int direction;
4672
4979
      if (keys.test(nr) &&
4673
4980
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4674
4981
      {
4675
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
 
4982
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->file->primary_key_is_clustered());
4676
4983
 
4677
4984
        /*
4678
 
          Don't use an index scan with ORDER BY without limit.
 
4985
          Don't use an index scan with order_st BY without limit.
4679
4986
          For GROUP BY without limit always use index scan
4680
4987
          if there is a suitable index.
4681
4988
          Why we hold to this asymmetry hardly can be explained
4689
4996
        {
4690
4997
          double rec_per_key;
4691
4998
          double index_scan_time;
4692
 
          KeyInfo *keyinfo= tab->table->key_info+nr;
 
4999
          KEY *keyinfo= tab->table->key_info+nr;
4693
5000
          if (select_limit == HA_POS_ERROR)
4694
5001
            select_limit= table_records;
4695
5002
          if (group)
4742
5049
            Rows in such a sequence are supposed to be ordered
4743
5050
            by rowid/primary key. When reading the data
4744
5051
            in a sequence we'll touch not more pages than the
4745
 
            table cursor contains.
 
5052
            table file contains.
4746
5053
            TODO. Use the formula for a disk sweep sequential access
4747
5054
            to calculate the cost of accessing data rows for one
4748
5055
            index entry.
4749
5056
          */
4750
5057
          index_scan_time= select_limit/rec_per_key *
4751
 
                           min(rec_per_key, table->cursor->scan_time());
 
5058
                           min(rec_per_key, table->file->scan_time());
4752
5059
          if (is_covering || (ref_key < 0 && (group || table->force_index)) ||
4753
5060
              index_scan_time < read_time)
4754
5061
          {
4803
5110
          if (table->covering_keys.test(best_key))
4804
5111
          {
4805
5112
            table->key_read=1;
4806
 
            table->cursor->extra(HA_EXTRA_KEYREAD);
 
5113
            table->file->extra(HA_EXTRA_KEYREAD);
4807
5114
          }
4808
 
          table->cursor->ha_index_or_rnd_end();
 
5115
          table->file->ha_index_or_rnd_end();
4809
5116
          if (join->select_options & SELECT_DESCRIBE)
4810
5117
          {
4811
5118
            tab->ref.key= -1;
4837
5144
  }
4838
5145
 
4839
5146
check_reverse_order:
4840
 
  if (order_direction == -1)            // If ORDER BY ... DESC
 
5147
  if (order_direction == -1)            // If order_st BY ... DESC
4841
5148
  {
4842
5149
    if (select && select->quick)
4843
5150
    {
4845
5152
        Don't reverse the sort order, if it's already done.
4846
5153
        (In some cases test_if_order_by_key() can be called multiple times
4847
5154
      */
4848
 
      if (! select->quick->reverse_sorted())
 
5155
      if (!select->quick->reverse_sorted())
4849
5156
      {
4850
 
        optimizer::QuickSelectDescending *tmp= NULL;
 
5157
        QUICK_SELECT_DESC *tmp;
4851
5158
        bool error= false;
4852
5159
        int quick_type= select->quick->get_type();
4853
 
        if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
4854
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT ||
4855
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
4856
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX)
 
5160
        if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
 
5161
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
 
5162
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
5163
            quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
4857
5164
        {
4858
5165
          tab->limit= 0;
4859
5166
          select->quick= save_quick;
4860
 
          return 0; // Use filesort
 
5167
          return(0);                   // Use filesort
4861
5168
        }
4862
5169
 
4863
 
        /* ORDER BY range_key DESC */
4864
 
        tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
4865
 
                                                  used_key_parts, 
4866
 
                                                  &error);
4867
 
        if (! tmp || error)
 
5170
        /* order_st BY range_key DESC */
 
5171
        tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
 
5172
                                          used_key_parts, &error);
 
5173
        if (!tmp || error)
4868
5174
        {
4869
5175
          delete tmp;
4870
 
          select->quick= save_quick;
4871
 
          tab->limit= 0;
4872
 
          return 0; // Reverse sort not supported
 
5176
                select->quick= save_quick;
 
5177
                tab->limit= 0;
 
5178
          return(0);            // Reverse sort not supported
4873
5179
        }
4874
5180
        select->quick=tmp;
4875
5181
      }
4878
5184
             tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
4879
5185
    {
4880
5186
      /*
4881
 
        SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
 
5187
        SELECT * FROM t1 WHERE a=1 order_st BY a DESC,b DESC
4882
5188
 
4883
5189
        Use a traversal function that starts by reading the last row
4884
5190
        with key part (A) and then traverse the index backwards.
4889
5195
  }
4890
5196
  else if (select && select->quick)
4891
5197
    select->quick->sorted= 1;
4892
 
  return 1;
 
5198
  return(1);
4893
5199
}
4894
5200
 
4895
5201
/*
4910
5216
  IMPLEMENTATION
4911
5217
   - If there is an index that can be used, 'tab' is modified to use
4912
5218
     this index.
4913
 
   - If no index, create with filesort() an index cursor that can be used to
 
5219
   - If no index, create with filesort() an index file that can be used to
4914
5220
     retrieve rows in order (should be done with 'read_record').
4915
5221
     The sorted data is stored in tab->table and will be freed when calling
4916
5222
     tab->table->free_io_cache().
4920
5226
    -1          Some fatal error
4921
5227
    1           No records
4922
5228
*/
4923
 
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
5229
int create_sort_index(Session *session, JOIN *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
4924
5230
{
4925
5231
  uint32_t length= 0;
4926
5232
  ha_rows examined_rows;
4927
5233
  Table *table;
4928
 
  optimizer::SqlSelect *select= NULL;
 
5234
  SQL_SELECT *select;
4929
5235
  JoinTable *tab;
4930
5236
 
4931
5237
  if (join->tables == join->const_tables)
4942
5248
  */
4943
5249
  if ((order != join->group_list ||
4944
5250
       !(join->select_options & SELECT_BIG_RESULT) ||
4945
 
       (select && select->quick && (select->quick->get_type() == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))) &&
 
5251
       (select && select->quick && (select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))) &&
4946
5252
      test_if_skip_sort_order(tab,order,select_limit,0,
4947
5253
                              is_order_by ?  &table->keys_in_use_for_order_by :
4948
5254
                              &table->keys_in_use_for_group_by))
4949
5255
    return(0);
4950
 
  for (Order *ord= join->order; ord; ord= ord->next)
 
5256
  for (order_st *ord= join->order; ord; ord= ord->next)
4951
5257
    length++;
4952
 
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
4953
 
  {
4954
 
    return(-1);
4955
 
  }
 
5258
  if (!(join->sortorder=
 
5259
        make_unireg_sortorder(order, &length, join->sortorder)))
 
5260
    goto err;
4956
5261
 
4957
 
  table->sort.io_cache= new internal::IO_CACHE;
 
5262
  table->sort.io_cache= new IO_CACHE;
 
5263
  memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
4958
5264
  table->status=0;                              // May be wrong if quick_select
4959
5265
 
4960
5266
  // If table has a range, move it to select
4971
5277
      if (table->key_read && ((uint32_t) tab->ref.key != select->quick->index))
4972
5278
      {
4973
5279
        table->key_read=0;
4974
 
        table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
5280
        table->file->extra(HA_EXTRA_NO_KEYREAD);
4975
5281
      }
4976
5282
    }
4977
5283
    else
4982
5288
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
4983
5289
        field, quick will contain an empty record set.
4984
5290
      */
4985
 
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session, 
4986
 
                                                                 table, 
4987
 
                                                                 &tab->ref,
4988
 
                                                                 tab->found_records))))
4989
 
      {
4990
 
        return(-1);
4991
 
      }
 
5291
      if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref,
 
5292
                                                     tab->found_records))))
 
5293
        goto err;
4992
5294
    }
4993
5295
  }
4994
5296
 
4995
 
  if (table->getShare()->getType())
4996
 
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
 
5297
  /* Fill schema tables with data before filesort if it's necessary */
 
5298
  if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
 
5299
      get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
 
5300
    goto err;
4997
5301
 
4998
 
  FileSort filesort(*session);
4999
 
  table->sort.found_records=filesort.run(table,join->sortorder, length,
5000
 
                                         select, filesort_limit, 0,
5001
 
                                         examined_rows);
 
5302
  if (table->s->tmp_table)
 
5303
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
 
5304
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
5305
                                     select, filesort_limit, 0,
 
5306
                                     &examined_rows);
5002
5307
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5003
5308
  if (select)
5004
5309
  {
5014
5319
  if (table->key_read)                          // Restore if we used indexes
5015
5320
  {
5016
5321
    table->key_read=0;
5017
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
5322
    table->file->extra(HA_EXTRA_NO_KEYREAD);
5018
5323
  }
5019
 
 
5020
5324
  return(table->sort.found_records == HA_POS_ERROR);
 
5325
err:
 
5326
  return(-1);
5021
5327
}
5022
5328
 
5023
5329
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5024
5330
{
5025
 
  Cursor *cursor=table->cursor;
 
5331
  Cursor *file=table->file;
5026
5332
  char *org_record,*new_record;
5027
5333
  unsigned char *record;
5028
5334
  int error;
5029
 
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
5030
 
 
5031
 
  org_record=(char*) (record=table->getInsertRecord())+offset;
5032
 
  new_record=(char*) table->getUpdateRecord()+offset;
5033
 
 
5034
 
  if ((error= cursor->startTableScan(1)))
5035
 
    goto err;
5036
 
 
5037
 
  error=cursor->rnd_next(record);
 
5335
  uint32_t reclength= table->s->reclength-offset;
 
5336
 
 
5337
  org_record=(char*) (record=table->record[0])+offset;
 
5338
  new_record=(char*) table->record[1]+offset;
 
5339
 
 
5340
  file->ha_rnd_init(1);
 
5341
  error=file->rnd_next(record);
5038
5342
  for (;;)
5039
5343
  {
5040
 
    if (session->getKilled())
 
5344
    if (session->killed)
5041
5345
    {
5042
5346
      session->send_kill_message();
5043
5347
      error=0;
5053
5357
    }
5054
5358
    if (having && !having->val_int())
5055
5359
    {
5056
 
      if ((error=cursor->deleteRecord(record)))
 
5360
      if ((error=file->ha_delete_row(record)))
5057
5361
        goto err;
5058
 
      error=cursor->rnd_next(record);
 
5362
      error=file->rnd_next(record);
5059
5363
      continue;
5060
5364
    }
5061
5365
    if (copy_blobs(first_field))
5066
5370
    }
5067
5371
    memcpy(new_record,org_record,reclength);
5068
5372
 
5069
 
    /* Read through rest of cursor and mark duplicated rows deleted */
 
5373
    /* Read through rest of file and mark duplicated rows deleted */
5070
5374
    bool found=0;
5071
5375
    for (;;)
5072
5376
    {
5073
 
      if ((error=cursor->rnd_next(record)))
 
5377
      if ((error=file->rnd_next(record)))
5074
5378
      {
5075
5379
        if (error == HA_ERR_RECORD_DELETED)
5076
5380
          continue;
5080
5384
      }
5081
5385
      if (table->compare_record(first_field) == 0)
5082
5386
      {
5083
 
        if ((error=cursor->deleteRecord(record)))
 
5387
        if ((error=file->ha_delete_row(record)))
5084
5388
          goto err;
5085
5389
      }
5086
5390
      else if (!found)
5087
5391
      {
5088
5392
        found= 1;
5089
 
        cursor->position(record);       // Remember position
 
5393
        file->position(record); // Remember position
5090
5394
      }
5091
5395
    }
5092
5396
    if (!found)
5093
 
      break;                                    // End of cursor
5094
 
    /* Move current position to the next row */
5095
 
    error= cursor->rnd_pos(record, cursor->ref);
 
5397
      break;                                    // End of file
 
5398
    /* Restart search on next row */
 
5399
    error=file->restart_rnd_next(record,file->ref);
5096
5400
  }
5097
5401
 
5098
 
  cursor->extra(HA_EXTRA_NO_CACHE);
 
5402
  file->extra(HA_EXTRA_NO_CACHE);
5099
5403
  return(0);
5100
5404
err:
5101
 
  cursor->extra(HA_EXTRA_NO_CACHE);
 
5405
  file->extra(HA_EXTRA_NO_CACHE);
5102
5406
  if (error)
5103
 
    table->print_error(error,MYF(0));
 
5407
    file->print_error(error,MYF(0));
5104
5408
  return(1);
5105
5409
}
5106
5410
 
5117
5421
                               uint32_t key_length,
5118
5422
                               Item *having)
5119
5423
{
5120
 
  unsigned char *key_pos, *record=table->getInsertRecord();
 
5424
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
5121
5425
  int error;
5122
 
  Cursor *cursor= table->cursor;
 
5426
  Cursor *file= table->file;
5123
5427
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5124
 
  uint32_t *field_length;
 
5428
  uint32_t *field_lengths,*field_length;
5125
5429
  HASH hash;
5126
 
  std::vector<unsigned char> key_buffer;
5127
 
  std::vector<uint32_t> field_lengths;
5128
5430
 
5129
 
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5130
 
  field_lengths.resize(field_count);
 
5431
  if (! memory::multi_malloc(false,
 
5432
                       &key_buffer,
 
5433
                       (uint32_t) ((key_length + extra_length) *
 
5434
                               (long) file->stats.records),
 
5435
                       &field_lengths,
 
5436
                       (uint32_t) (field_count*sizeof(*field_lengths)),
 
5437
                       NULL))
 
5438
    return(1);
5131
5439
 
5132
5440
  {
5133
5441
    Field **ptr;
5134
5442
    uint32_t total_length= 0;
5135
 
 
5136
 
    for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
 
5443
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
5137
5444
    {
5138
5445
      uint32_t length= (*ptr)->sort_length();
5139
5446
      (*field_length++)= length;
5144
5451
    extra_length= ALIGN_SIZE(key_length)-key_length;
5145
5452
  }
5146
5453
 
5147
 
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
 
5454
  if (hash_init(&hash, &my_charset_bin, (uint32_t) file->stats.records, 0,
5148
5455
                key_length, (hash_get_key) 0, 0, 0))
5149
5456
  {
 
5457
    free((char*) key_buffer);
5150
5458
    return(1);
5151
5459
  }
5152
5460
 
5153
 
  if ((error= cursor->startTableScan(1)))
5154
 
    goto err;
5155
 
 
5156
 
  key_pos= &key_buffer[0];
 
5461
  file->ha_rnd_init(1);
 
5462
  key_pos=key_buffer;
5157
5463
  for (;;)
5158
5464
  {
5159
5465
    unsigned char *org_key_pos;
5160
 
    if (session->getKilled())
 
5466
    if (session->killed)
5161
5467
    {
5162
5468
      session->send_kill_message();
5163
5469
      error=0;
5164
5470
      goto err;
5165
5471
    }
5166
 
    if ((error=cursor->rnd_next(record)))
 
5472
    if ((error=file->rnd_next(record)))
5167
5473
    {
5168
5474
      if (error == HA_ERR_RECORD_DELETED)
5169
5475
        continue;
5173
5479
    }
5174
5480
    if (having && !having->val_int())
5175
5481
    {
5176
 
      if ((error=cursor->deleteRecord(record)))
 
5482
      if ((error=file->ha_delete_row(record)))
5177
5483
        goto err;
5178
5484
      continue;
5179
5485
    }
5180
5486
 
5181
5487
    /* copy fields to key buffer */
5182
5488
    org_key_pos= key_pos;
5183
 
    field_length= &field_lengths[0];
 
5489
    field_length=field_lengths;
5184
5490
    for (Field **ptr= first_field ; *ptr ; ptr++)
5185
5491
    {
5186
5492
      (*ptr)->sort_string(key_pos,*field_length);
5190
5496
    if (hash_search(&hash, org_key_pos, key_length))
5191
5497
    {
5192
5498
      /* Duplicated found ; Remove the row */
5193
 
      if ((error=cursor->deleteRecord(record)))
 
5499
      if ((error=file->ha_delete_row(record)))
5194
5500
        goto err;
5195
5501
    }
5196
5502
    else
5197
5503
      (void) my_hash_insert(&hash, org_key_pos);
5198
5504
    key_pos+=extra_length;
5199
5505
  }
 
5506
  free((char*) key_buffer);
5200
5507
  hash_free(&hash);
5201
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5202
 
  (void) cursor->endTableScan();
 
5508
  file->extra(HA_EXTRA_NO_CACHE);
 
5509
  (void) file->ha_rnd_end();
5203
5510
  return(0);
5204
5511
 
5205
5512
err:
 
5513
  free((char*) key_buffer);
5206
5514
  hash_free(&hash);
5207
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5208
 
  (void) cursor->endTableScan();
 
5515
  file->extra(HA_EXTRA_NO_CACHE);
 
5516
  (void) file->ha_rnd_end();
5209
5517
  if (error)
5210
 
    table->print_error(error,MYF(0));
 
5518
    file->print_error(error,MYF(0));
5211
5519
  return(1);
5212
5520
}
5213
5521
 
5214
 
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
 
5522
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
5215
5523
{
5216
5524
  uint32_t count;
5217
 
  SortField *sort,*pos;
 
5525
  SORT_FIELD *sort,*pos;
5218
5526
 
5219
5527
  count=0;
5220
 
  for (Order *tmp = order; tmp; tmp=tmp->next)
 
5528
  for (order_st *tmp = order; tmp; tmp=tmp->next)
5221
5529
    count++;
5222
5530
  if (!sortorder)
5223
 
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
 
5531
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
5224
5532
                                       (max(count, *length) + 1));
5225
5533
  pos= sort= sortorder;
5226
5534
 
5308
5616
*****************************************************************************/
5309
5617
 
5310
5618
/**
5311
 
  Resolve an ORDER BY or GROUP BY column reference.
 
5619
  Resolve an order_st BY or GROUP BY column reference.
5312
5620
 
5313
5621
  Given a column reference (represented by 'order') from a GROUP BY or order_st
5314
5622
  BY clause, find the actual column it represents. If the column being
5315
5623
  resolved is from the GROUP BY clause, the procedure searches the SELECT
5316
5624
  list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
5317
 
  the ORDER BY clause, only the SELECT list is being searched.
 
5625
  the order_st BY clause, only the SELECT list is being searched.
5318
5626
 
5319
5627
  If 'order' is resolved to an Item, then order->item is set to the found
5320
5628
  Item. If there is no item for the found column (that is, it was resolved
5342
5650
static bool find_order_in_list(Session *session, 
5343
5651
                               Item **ref_pointer_array, 
5344
5652
                               TableList *tables,
5345
 
                               Order *order,
 
5653
                               order_st *order,
5346
5654
                               List<Item> &fields,
5347
5655
                               List<Item> &all_fields,
5348
5656
                               bool is_group_field)
5364
5672
    if (!count || count > fields.elements)
5365
5673
    {
5366
5674
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5367
 
               order_item->full_name(), session->where());
 
5675
               order_item->full_name(), session->where);
5368
5676
      return true;
5369
5677
    }
5370
5678
    order->item= ref_pointer_array + count - 1;
5374
5682
    return false;
5375
5683
  }
5376
5684
  /* Lookup the current GROUP/order_st field in the SELECT clause. */
5377
 
  select_item= find_item_in_list(session, order_item, fields, &counter,
 
5685
  select_item= find_item_in_list(order_item, fields, &counter,
5378
5686
                                 REPORT_EXCEPT_NOT_FOUND, &resolution);
5379
5687
  if (!select_item)
5380
5688
    return true; /* The item is not unique, or some other error occured. */
5441
5749
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5442
5750
                          ER(ER_NON_UNIQ_ERROR),
5443
5751
                          ((Item_ident*) order_item)->field_name,
5444
 
                          session->where());
 
5752
                          current_session->where);
5445
5753
    }
5446
5754
  }
5447
5755
 
5481
5789
                TableList *tables,
5482
5790
                            List<Item> &fields,
5483
5791
                List<Item> &all_fields,
5484
 
                Order *order)
 
5792
                order_st *order)
5485
5793
{
5486
 
  session->setWhere("order clause");
 
5794
  session->where="order clause";
5487
5795
  for (; order; order=order->next)
5488
5796
  {
5489
5797
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5523
5831
                TableList *tables,
5524
5832
                      List<Item> &fields,
5525
5833
                List<Item> &all_fields,
5526
 
                Order *order,
 
5834
                order_st *order,
5527
5835
                      bool *hidden_group_fields)
5528
5836
{
5529
5837
  *hidden_group_fields=0;
5530
 
  Order *ord;
 
5838
  order_st *ord;
5531
5839
 
5532
5840
  if (!order)
5533
5841
    return 0;                           /* Everything is ok */
5534
5842
 
5535
5843
  uint32_t org_fields=all_fields.elements;
5536
5844
 
5537
 
  session->setWhere("group statement");
 
5845
  session->where="group statement";
5538
5846
  for (ord= order; ord; ord= ord->next)
5539
5847
  {
5540
5848
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5617
5925
  Try to use the fields in the order given by 'order' to allow one to
5618
5926
  optimize away 'order by'.
5619
5927
*/
5620
 
Order *create_distinct_group(Session *session,
 
5928
order_st *create_distinct_group(Session *session,
5621
5929
                                Item **ref_pointer_array,
5622
 
                                Order *order_list,
 
5930
                                order_st *order_list,
5623
5931
                                List<Item> &fields,
5624
5932
                                List<Item> &,
5625
5933
                                bool *all_order_by_fields_used)
5626
5934
{
5627
5935
  List_iterator<Item> li(fields);
5628
5936
  Item *item;
5629
 
  Order *order,*group,**prev;
 
5937
  order_st *order,*group,**prev;
5630
5938
 
5631
5939
  *all_order_by_fields_used= 1;
5632
5940
  while ((item=li++))
5637
5945
  {
5638
5946
    if (order->in_field_list)
5639
5947
    {
5640
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5948
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
5641
5949
      if (!ord)
5642
5950
        return 0;
5643
5951
      *prev=ord;
5657
5965
        Don't put duplicate columns from the SELECT list into the
5658
5966
        GROUP BY list.
5659
5967
      */
5660
 
      Order *ord_iter;
 
5968
      order_st *ord_iter;
5661
5969
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5662
5970
        if ((*ord_iter->item)->eq(item, 1))
5663
5971
          goto next_item;
5664
5972
 
5665
 
      Order *ord=(Order*) session->calloc(sizeof(Order));
 
5973
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
5666
5974
      if (!ord)
5667
5975
        return 0;
5668
5976
 
5849
6157
          saved value
5850
6158
        */
5851
6159
        field= item->field;
5852
 
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
 
6160
        item->result_field=field->new_field(session->mem_root,field->table, 1);
5853
6161
              /*
5854
6162
                We need to allocate one extra byte for null handling and
5855
6163
                another extra byte to not get warnings from purify in
5856
6164
                Field_varstring::val_int
5857
6165
              */
5858
 
        if (!(tmp= (unsigned char*) memory::sql_alloc(field->pack_length()+2)))
 
6166
        if (!(tmp= (unsigned char*) sql_alloc(field->pack_length()+2)))
5859
6167
          goto err;
5860
6168
        if (copy)
5861
6169
        {
5862
6170
          copy->set(tmp, item->result_field);
5863
6171
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
5864
 
#ifdef HAVE_VALGRIND
 
6172
#ifdef HAVE_purify
5865
6173
          copy->to_ptr[copy->from_length]= 0;
5866
6174
#endif
5867
6175
          copy++;
5901
6209
    itr++;
5902
6210
  itr.sublist(res_selected_fields, elements);
5903
6211
  /*
5904
 
    Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
 
6212
    Put elements from HAVING, order_st BY and GROUP BY last to ensure that any
5905
6213
    reference used in these will resolve to a item that is already calculated
5906
6214
  */
5907
6215
  param->copy_funcs.concat(&extra_funcs);
5982
6290
      }
5983
6291
      else if ((field= item->get_tmp_table_field()))
5984
6292
      {
5985
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
 
6293
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
5986
6294
          item_field= ((Item_sum*) item)->result_item(field);
5987
6295
        else
5988
6296
          item_field= (Item*) new Item_field(field);
6134
6442
}
6135
6443
 
6136
6444
/** Copy result of functions to record in tmp_table. */
6137
 
bool copy_funcs(Item **func_ptr, const Session *session)
 
6445
void copy_funcs(Item **func_ptr)
6138
6446
{
6139
6447
  Item *func;
6140
6448
  for (; (func = *func_ptr) ; func_ptr++)
6141
 
  {
6142
6449
    func->save_in_result_field(1);
6143
 
    /*
6144
 
      Need to check the THD error state because Item::val_xxx() don't
6145
 
      return error code, but can generate errors
6146
 
      TODO: change it for a real status check when Item::val_xxx()
6147
 
      are extended to return status code.
6148
 
    */
6149
 
    if (session->is_error())
6150
 
      return true;
6151
 
  }
6152
 
  return false;
6153
6450
}
6154
6451
 
6155
6452
/**
6209
6506
  @retval
6210
6507
    1   on error
6211
6508
*/
6212
 
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
 
6509
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
6213
6510
{
6214
6511
  if (expr->arg_count)
6215
6512
  {
6223
6520
      Item *item= *arg;
6224
6521
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6225
6522
      {
6226
 
        Order *group_tmp;
 
6523
        order_st *group_tmp;
6227
6524
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6228
6525
        {
6229
6526
          if (item->eq(*group_tmp->item,0))
6252
6549
  return 0;
6253
6550
}
6254
6551
 
 
6552
/**
 
6553
  EXPLAIN handling.
 
6554
 
 
6555
  Send a description about what how the select will be done to stdout.
 
6556
*/
 
6557
void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
 
6558
                     bool distinct,const char *message)
 
6559
{
 
6560
  List<Item> field_list;
 
6561
  List<Item> item_list;
 
6562
  Session *session=join->session;
 
6563
  select_result *result=join->result;
 
6564
  Item *item_null= new Item_null();
 
6565
  const CHARSET_INFO * const cs= system_charset_info;
 
6566
  int quick_type;
 
6567
  /* Don't log this into the slow query log */
 
6568
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
 
6569
  join->unit->offset_limit_cnt= 0;
 
6570
 
 
6571
  /*
 
6572
    NOTE: the number/types of items pushed into item_list must be in sync with
 
6573
    EXPLAIN column types as they're "defined" in Session::send_explain_fields()
 
6574
  */
 
6575
  if (message)
 
6576
  {
 
6577
    item_list.push_back(new Item_int((int32_t)
 
6578
                                     join->select_lex->select_number));
 
6579
    item_list.push_back(new Item_string(join->select_lex->type,
 
6580
                                        strlen(join->select_lex->type), cs));
 
6581
    for (uint32_t i=0 ; i < 7; i++)
 
6582
      item_list.push_back(item_null);
 
6583
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6584
      item_list.push_back(item_null);
 
6585
 
 
6586
    item_list.push_back(new Item_string(message,strlen(message),cs));
 
6587
    if (result->send_data(item_list))
 
6588
      join->error= 1;
 
6589
  }
 
6590
  else if (join->select_lex == join->unit->fake_select_lex)
 
6591
  {
 
6592
    /*
 
6593
      here we assume that the query will return at least two rows, so we
 
6594
      show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
 
6595
      and no filesort will be actually done, but executing all selects in
 
6596
      the UNION to provide precise EXPLAIN information will hardly be
 
6597
      appreciated :)
 
6598
    */
 
6599
    char table_name_buffer[NAME_LEN];
 
6600
    item_list.empty();
 
6601
    /* id */
 
6602
    item_list.push_back(new Item_null);
 
6603
    /* select_type */
 
6604
    item_list.push_back(new Item_string(join->select_lex->type,
 
6605
                                        strlen(join->select_lex->type),
 
6606
                                        cs));
 
6607
    /* table */
 
6608
    {
 
6609
      Select_Lex *sl= join->unit->first_select();
 
6610
      uint32_t len= 6, lastop= 0;
 
6611
      memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
 
6612
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
 
6613
      {
 
6614
        len+= lastop;
 
6615
        lastop= snprintf(table_name_buffer + len, NAME_LEN - len,
 
6616
                         "%u,", sl->select_number);
 
6617
      }
 
6618
      if (sl || len + lastop >= NAME_LEN)
 
6619
      {
 
6620
        memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
 
6621
        len+= 4;
 
6622
      }
 
6623
      else
 
6624
      {
 
6625
        len+= lastop;
 
6626
        table_name_buffer[len - 1]= '>';  // change ',' to '>'
 
6627
      }
 
6628
      item_list.push_back(new Item_string(table_name_buffer, len, cs));
 
6629
    }
 
6630
    /* type */
 
6631
    item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(),
 
6632
                                        access_method_str[AM_ALL].length(),
 
6633
                                        cs));
 
6634
    /* possible_keys */
 
6635
    item_list.push_back(item_null);
 
6636
    /* key*/
 
6637
    item_list.push_back(item_null);
 
6638
    /* key_len */
 
6639
    item_list.push_back(item_null);
 
6640
    /* ref */
 
6641
    item_list.push_back(item_null);
 
6642
    /* in_rows */
 
6643
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6644
      item_list.push_back(item_null);
 
6645
    /* rows */
 
6646
    item_list.push_back(item_null);
 
6647
    /* extra */
 
6648
    if (join->unit->global_parameters->order_list.first)
 
6649
      item_list.push_back(new Item_string("Using filesort",
 
6650
                                          14, cs));
 
6651
    else
 
6652
      item_list.push_back(new Item_string("", 0, cs));
 
6653
 
 
6654
    if (result->send_data(item_list))
 
6655
      join->error= 1;
 
6656
  }
 
6657
  else
 
6658
  {
 
6659
    table_map used_tables=0;
 
6660
    for (uint32_t i=0 ; i < join->tables ; i++)
 
6661
    {
 
6662
      JoinTable *tab=join->join_tab+i;
 
6663
      Table *table=tab->table;
 
6664
      TableList *table_list= tab->table->pos_in_table_list;
 
6665
      char buff[512];
 
6666
      char buff1[512], buff2[512], buff3[512];
 
6667
      char keylen_str_buf[64];
 
6668
      String extra(buff, sizeof(buff),cs);
 
6669
      char table_name_buffer[NAME_LEN];
 
6670
      String tmp1(buff1,sizeof(buff1),cs);
 
6671
      String tmp2(buff2,sizeof(buff2),cs);
 
6672
      String tmp3(buff3,sizeof(buff3),cs);
 
6673
      extra.length(0);
 
6674
      tmp1.length(0);
 
6675
      tmp2.length(0);
 
6676
      tmp3.length(0);
 
6677
 
 
6678
      quick_type= -1;
 
6679
      item_list.empty();
 
6680
      /* id */
 
6681
      item_list.push_back(new Item_uint((uint32_t)
 
6682
                                       join->select_lex->select_number));
 
6683
      /* select_type */
 
6684
      item_list.push_back(new Item_string(join->select_lex->type,
 
6685
                                          strlen(join->select_lex->type),
 
6686
                                          cs));
 
6687
      if (tab->type == AM_ALL && tab->select && tab->select->quick)
 
6688
      {
 
6689
        quick_type= tab->select->quick->get_type();
 
6690
        if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
 
6691
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
 
6692
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
 
6693
          tab->type = AM_INDEX_MERGE;
 
6694
        else
 
6695
          tab->type = AM_RANGE;
 
6696
      }
 
6697
      /* table */
 
6698
      if (table->derived_select_number)
 
6699
      {
 
6700
        /* Derived table name generation */
 
6701
        int len= snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
 
6702
                          "<derived%u>",
 
6703
                          table->derived_select_number);
 
6704
        item_list.push_back(new Item_string(table_name_buffer, len, cs));
 
6705
      }
 
6706
      else
 
6707
      {
 
6708
        TableList *real_table= table->pos_in_table_list;
 
6709
        item_list.push_back(new Item_string(real_table->alias,
 
6710
                                            strlen(real_table->alias),
 
6711
                                            cs));
 
6712
      }
 
6713
      /* "type" column */
 
6714
      item_list.push_back(new Item_string(access_method_str[tab->type].c_str(),
 
6715
                                          access_method_str[tab->type].length(),
 
6716
                                          cs));
 
6717
      /* Build "possible_keys" value and add it to item_list */
 
6718
      if (tab->keys.any())
 
6719
      {
 
6720
        uint32_t j;
 
6721
        for (j=0 ; j < table->s->keys ; j++)
 
6722
        {
 
6723
          if (tab->keys.test(j))
 
6724
          {
 
6725
            if (tmp1.length())
 
6726
              tmp1.append(',');
 
6727
            tmp1.append(table->key_info[j].name,
 
6728
                        strlen(table->key_info[j].name),
 
6729
                        system_charset_info);
 
6730
          }
 
6731
        }
 
6732
      }
 
6733
      if (tmp1.length())
 
6734
        item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
 
6735
      else
 
6736
        item_list.push_back(item_null);
 
6737
 
 
6738
      /* Build "key", "key_len", and "ref" values and add them to item_list */
 
6739
      if (tab->ref.key_parts)
 
6740
      {
 
6741
        KEY *key_info=table->key_info+ tab->ref.key;
 
6742
        register uint32_t length;
 
6743
        item_list.push_back(new Item_string(key_info->name,
 
6744
                                            strlen(key_info->name),
 
6745
                                            system_charset_info));
 
6746
        length= int64_t2str(tab->ref.key_length, keylen_str_buf, 10) -
 
6747
                keylen_str_buf;
 
6748
        item_list.push_back(new Item_string(keylen_str_buf, length,
 
6749
                                            system_charset_info));
 
6750
        for (StoredKey **ref=tab->ref.key_copy ; *ref ; ref++)
 
6751
        {
 
6752
          if (tmp2.length())
 
6753
            tmp2.append(',');
 
6754
          tmp2.append((*ref)->name(), strlen((*ref)->name()),
 
6755
                      system_charset_info);
 
6756
        }
 
6757
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6758
      }
 
6759
      else if (tab->type == AM_NEXT)
 
6760
      {
 
6761
        KEY *key_info=table->key_info+ tab->index;
 
6762
        register uint32_t length;
 
6763
        item_list.push_back(new Item_string(key_info->name,
 
6764
                                            strlen(key_info->name),cs));
 
6765
        length= int64_t2str(key_info->key_length, keylen_str_buf, 10) -
 
6766
                keylen_str_buf;
 
6767
        item_list.push_back(new Item_string(keylen_str_buf,
 
6768
                                            length,
 
6769
                                            system_charset_info));
 
6770
        item_list.push_back(item_null);
 
6771
      }
 
6772
      else if (tab->select && tab->select->quick)
 
6773
      {
 
6774
        tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
 
6775
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6776
        item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
 
6777
        item_list.push_back(item_null);
 
6778
      }
 
6779
      else
 
6780
      {
 
6781
        if (table_list->schema_table && 
 
6782
            table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
 
6783
        {
 
6784
          if (table_list->has_db_lookup_value)
 
6785
          {
 
6786
            int f_idx= table_list->schema_table->getFirstColumnIndex();
 
6787
            const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
 
6788
            tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
 
6789
          }
 
6790
          if (table_list->has_table_lookup_value)
 
6791
          {
 
6792
            if (table_list->has_db_lookup_value)
 
6793
              tmp2.append(',');
 
6794
            int f_idx= table_list->schema_table->getSecondColumnIndex();
 
6795
            const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
 
6796
            tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
 
6797
          }
 
6798
          if (tmp2.length())
 
6799
            item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6800
          else
 
6801
            item_list.push_back(item_null);
 
6802
        }
 
6803
        else
 
6804
          item_list.push_back(item_null);
 
6805
        item_list.push_back(item_null);
 
6806
        item_list.push_back(item_null);
 
6807
      }
 
6808
 
 
6809
      /* Add "rows" field to item_list. */
 
6810
      if (table_list->schema_table)
 
6811
      {
 
6812
        /* in_rows */
 
6813
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6814
          item_list.push_back(item_null);
 
6815
        /* rows */
 
6816
        item_list.push_back(item_null);
 
6817
      }
 
6818
      else
 
6819
      {
 
6820
        double examined_rows;
 
6821
        if (tab->select && tab->select->quick)
 
6822
          examined_rows= rows2double(tab->select->quick->records);
 
6823
        else if (tab->type == AM_NEXT || tab->type == AM_ALL)
 
6824
          examined_rows= rows2double(tab->limit ? tab->limit :
 
6825
                                     tab->table->file->records());
 
6826
        else
 
6827
        {
 
6828
          optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
 
6829
          examined_rows= cur_pos.getFanout();
 
6830
        }
 
6831
 
 
6832
        item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
 
6833
                                         MY_INT64_NUM_DECIMAL_DIGITS));
 
6834
 
 
6835
        /* Add "filtered" field to item_list. */
 
6836
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6837
        {
 
6838
          float f= 0.0;
 
6839
          if (examined_rows)
 
6840
          {
 
6841
            optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
 
6842
            f= (float) (100.0 * cur_pos.getFanout() /
 
6843
                        examined_rows);
 
6844
          }
 
6845
          item_list.push_back(new Item_float(f, 2));
 
6846
        }
 
6847
      }
 
6848
 
 
6849
      /* Build "Extra" field and add it to item_list. */
 
6850
      bool key_read=table->key_read;
 
6851
      if ((tab->type == AM_NEXT || tab->type == AM_CONST) &&
 
6852
          table->covering_keys.test(tab->index))
 
6853
        key_read=1;
 
6854
      if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
 
6855
          !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
 
6856
        key_read=1;
 
6857
 
 
6858
      if (tab->info)
 
6859
        item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
 
6860
      else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
 
6861
      {
 
6862
        if (tab->packed_info & TAB_INFO_USING_INDEX)
 
6863
          extra.append(STRING_WITH_LEN("; Using index"));
 
6864
        if (tab->packed_info & TAB_INFO_USING_WHERE)
 
6865
          extra.append(STRING_WITH_LEN("; Using where"));
 
6866
        if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
 
6867
          extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
6868
        /* Skip initial "; "*/
 
6869
        const char *str= extra.ptr();
 
6870
        uint32_t len= extra.length();
 
6871
        if (len)
 
6872
        {
 
6873
          str += 2;
 
6874
          len -= 2;
 
6875
        }
 
6876
        item_list.push_back(new Item_string(str, len, cs));
 
6877
      }
 
6878
      else
 
6879
      {
 
6880
        uint32_t keyno= MAX_KEY;
 
6881
        if (tab->ref.key_parts)
 
6882
          keyno= tab->ref.key;
 
6883
        else if (tab->select && tab->select->quick)
 
6884
          keyno = tab->select->quick->index;
 
6885
 
 
6886
        if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
6887
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
 
6888
            quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
 
6889
        {
 
6890
          extra.append(STRING_WITH_LEN("; Using "));
 
6891
          tab->select->quick->add_info_string(&extra);
 
6892
        }
 
6893
          if (tab->select)
 
6894
        {
 
6895
          if (tab->use_quick == 2)
 
6896
          {
 
6897
            /*
 
6898
             * To print out the bitset in tab->keys, we go through
 
6899
             * it 32 bits at a time. We need to do this to ensure
 
6900
             * that the to_ulong() method will not throw an
 
6901
             * out_of_range exception at runtime which would happen
 
6902
             * if the bitset we were working with was larger than 64
 
6903
             * bits on a 64-bit platform (for example).
 
6904
             */
 
6905
            stringstream s, w;
 
6906
            string str;
 
6907
            w << tab->keys;
 
6908
            w >> str;
 
6909
            for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
 
6910
            {
 
6911
              bitset<32> tmp(str, pos, 32);
 
6912
              if (tmp.any())
 
6913
                s << uppercase << hex << tmp.to_ulong();
 
6914
            }
 
6915
            extra.append(STRING_WITH_LEN("; Range checked for each "
 
6916
                                         "record (index map: 0x"));
 
6917
            extra.append(s.str().c_str());
 
6918
            extra.append(')');
 
6919
          }
 
6920
          else if (tab->select->cond)
 
6921
          {
 
6922
            extra.append(STRING_WITH_LEN("; Using where"));
 
6923
          }
 
6924
        }
 
6925
        if (key_read)
 
6926
        {
 
6927
          if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
 
6928
            extra.append(STRING_WITH_LEN("; Using index for group-by"));
 
6929
          else
 
6930
            extra.append(STRING_WITH_LEN("; Using index"));
 
6931
        }
 
6932
        if (table->reginfo.not_exists_optimize)
 
6933
          extra.append(STRING_WITH_LEN("; Not exists"));
 
6934
 
 
6935
        if (table_list->schema_table &&
 
6936
            table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
 
6937
        {
 
6938
          if (!table_list->table_open_method)
 
6939
            extra.append(STRING_WITH_LEN("; Skip_open_table"));
 
6940
          else if (table_list->table_open_method == OPEN_FRM_ONLY)
 
6941
            extra.append(STRING_WITH_LEN("; Open_frm_only"));
 
6942
          else
 
6943
            extra.append(STRING_WITH_LEN("; Open_full_table"));
 
6944
          if (table_list->has_db_lookup_value &&
 
6945
              table_list->has_table_lookup_value)
 
6946
            extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
 
6947
          else if (table_list->has_db_lookup_value ||
 
6948
                   table_list->has_table_lookup_value)
 
6949
            extra.append(STRING_WITH_LEN("; Scanned 1 database"));
 
6950
          else
 
6951
            extra.append(STRING_WITH_LEN("; Scanned all databases"));
 
6952
        }
 
6953
        if (need_tmp_table)
 
6954
        {
 
6955
          need_tmp_table=0;
 
6956
          extra.append(STRING_WITH_LEN("; Using temporary"));
 
6957
        }
 
6958
        if (need_order)
 
6959
        {
 
6960
          need_order=0;
 
6961
          extra.append(STRING_WITH_LEN("; Using filesort"));
 
6962
        }
 
6963
        if (distinct & test_all_bits(used_tables,session->used_tables))
 
6964
          extra.append(STRING_WITH_LEN("; Distinct"));
 
6965
 
 
6966
        if (tab->insideout_match_tab)
 
6967
        {
 
6968
          extra.append(STRING_WITH_LEN("; LooseScan"));
 
6969
        }
 
6970
 
 
6971
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
 
6972
        {
 
6973
          if (tab->ref.cond_guards[part])
 
6974
          {
 
6975
            extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
6976
            break;
 
6977
          }
 
6978
        }
 
6979
 
 
6980
        if (i > 0 && tab[-1].next_select == sub_select_cache)
 
6981
          extra.append(STRING_WITH_LEN("; Using join buffer"));
 
6982
 
 
6983
        /* Skip initial "; "*/
 
6984
        const char *str= extra.ptr();
 
6985
        uint32_t len= extra.length();
 
6986
        if (len)
 
6987
        {
 
6988
          str += 2;
 
6989
          len -= 2;
 
6990
        }
 
6991
        item_list.push_back(new Item_string(str, len, cs));
 
6992
      }
 
6993
      // For next iteration
 
6994
      used_tables|=table->map;
 
6995
      if (result->send_data(item_list))
 
6996
        join->error= 1;
 
6997
    }
 
6998
  }
 
6999
  for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit();
 
7000
       unit;
 
7001
       unit= unit->next_unit())
 
7002
  {
 
7003
    if (mysql_explain_union(session, unit, result))
 
7004
      return;
 
7005
  }
 
7006
  return;
 
7007
}
 
7008
 
 
7009
bool mysql_explain_union(Session *session, Select_Lex_Unit *unit, select_result *result)
 
7010
{
 
7011
  bool res= false;
 
7012
  Select_Lex *first= unit->first_select();
 
7013
 
 
7014
  for (Select_Lex *sl= first;
 
7015
       sl;
 
7016
       sl= sl->next_select())
 
7017
  {
 
7018
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
 
7019
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
 
7020
    sl->type= (((&session->lex->select_lex)==sl)?
 
7021
               (sl->first_inner_unit() || sl->next_select() ?
 
7022
                "PRIMARY" : "SIMPLE"):
 
7023
               ((sl == first)?
 
7024
                ((sl->linkage == DERIVED_TABLE_TYPE) ?
 
7025
                 "DERIVED":
 
7026
                 ((uncacheable & UNCACHEABLE_DEPENDENT) ?
 
7027
                  "DEPENDENT SUBQUERY":
 
7028
                  (uncacheable?"UNCACHEABLE SUBQUERY":
 
7029
                   "SUBQUERY"))):
 
7030
                ((uncacheable & UNCACHEABLE_DEPENDENT) ?
 
7031
                 "DEPENDENT UNION":
 
7032
                 uncacheable?"UNCACHEABLE UNION":
 
7033
                 "UNION")));
 
7034
    sl->options|= SELECT_DESCRIBE;
 
7035
  }
 
7036
  if (unit->is_union())
 
7037
  {
 
7038
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
 
7039
    unit->fake_select_lex->type= "UNION RESULT";
 
7040
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
 
7041
    if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
 
7042
      res= unit->exec();
 
7043
    res|= unit->cleanup();
 
7044
  }
 
7045
  else
 
7046
  {
 
7047
    session->lex->current_select= first;
 
7048
    unit->set_limit(unit->global_parameters);
 
7049
    res= mysql_select(session, &first->ref_pointer_array,
 
7050
                        (TableList*) first->table_list.first,
 
7051
                        first->with_wild, first->item_list,
 
7052
                        first->where,
 
7053
                        first->order_list.elements +
 
7054
                        first->group_list.elements,
 
7055
                        (order_st*) first->order_list.first,
 
7056
                        (order_st*) first->group_list.first,
 
7057
                        first->having,
 
7058
                        first->options | session->options | SELECT_DESCRIBE,
 
7059
                        result, unit, first);
 
7060
  }
 
7061
  return(res || session->is_error());
 
7062
}
6255
7063
 
6256
7064
static void print_table_array(Session *session, String *str, TableList **table,
6257
7065
                              TableList **end)
6292
7100
{
6293
7101
  /* List is reversed => we should reverse it before using */
6294
7102
  List_iterator_fast<TableList> ti(*tables);
6295
 
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
7103
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6296
7104
                                                tables->elements);
6297
7105
  if (table == 0)
6298
7106
    return;  // out of memory
6306
7114
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6307
7115
{
6308
7116
  /* QQ: session may not be set for sub queries, but this should be fixed */
6309
 
  if(not session)
 
7117
  if (!session)
6310
7118
    session= current_session;
6311
7119
 
6312
 
 
6313
7120
  str->append(STRING_WITH_LEN("select "));
6314
7121
 
6315
7122
  /* First add options */
6375
7182
  if (group_list.elements)
6376
7183
  {
6377
7184
    str->append(STRING_WITH_LEN(" group by "));
6378
 
    print_order(str, (Order *) group_list.first, query_type);
 
7185
    print_order(str, (order_st *) group_list.first, query_type);
6379
7186
    switch (olap)
6380
7187
    {
6381
7188
      case CUBE_TYPE:
6406
7213
  if (order_list.elements)
6407
7214
  {
6408
7215
    str->append(STRING_WITH_LEN(" order by "));
6409
 
    print_order(str, (Order *) order_list.first, query_type);
 
7216
    print_order(str, (order_st *) order_list.first, query_type);
6410
7217
  }
6411
7218
 
6412
7219
  // limit
6418
7225
/**
6419
7226
  @} (end of group Query_Optimizer)
6420
7227
*/
6421
 
 
6422
 
} /* namespace drizzled */