~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Olaf van der Spek
  • Date: 2011-02-12 18:24:24 UTC
  • mto: (2167.1.2 build) (2172.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 2168.
  • Revision ID: olafvdspek@gmail.com-20110212182424-kgnm9osi7qo97at2
casts

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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
15
15
 
16
16
/**
17
17
  @file
18
18
 
19
19
  @brief
20
 
  mysql_select and join optimization
 
20
  select_query and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
49
49
#include "drizzled/lock.h"
50
50
#include "drizzled/item/outer_ref.h"
51
51
#include "drizzled/index_hint.h"
52
 
#include "drizzled/memory/multi_malloc.h"
53
52
#include "drizzled/records.h"
54
53
#include "drizzled/internal/iocache.h"
 
54
#include "drizzled/drizzled.h"
55
55
 
56
56
#include "drizzled/sql_union.h"
57
57
#include "drizzled/optimizer/key_field.h"
62
62
#include "drizzled/optimizer/quick_range_select.h"
63
63
#include "drizzled/optimizer/quick_ror_intersect_select.h"
64
64
 
 
65
#include "drizzled/filesort.h"
 
66
 
65
67
using namespace std;
66
68
 
67
69
namespace drizzled
76
78
static Item* part_of_refkey(Table *form,Field *field);
77
79
static bool cmp_buffer_with_ref(JoinTable *tab);
78
80
static void change_cond_ref_to_const(Session *session,
79
 
                                     vector<COND_CMP>& save_list,
 
81
                                     list<COND_CMP>& save_list,
80
82
                                     Item *and_father,
81
83
                                     Item *cond,
82
84
                                     Item *field,
115
117
{
116
118
  bool res;
117
119
  register Select_Lex *select_lex= &lex->select_lex;
118
 
  DRIZZLE_SELECT_START(session->query.c_str());
 
120
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
119
121
 
120
122
  if (select_lex->master_unit()->is_union() ||
121
123
      select_lex->master_unit()->fake_select_lex)
 
124
  {
122
125
    res= drizzle_union(session, lex, result, &lex->unit,
123
126
                       setup_tables_done_option);
 
127
  }
124
128
  else
125
129
  {
126
130
    Select_Lex_Unit *unit= &lex->unit;
127
131
    unit->set_limit(unit->global_parameters);
128
132
    session->session_marker= 0;
129
133
    /*
130
 
      'options' of mysql_select will be set in JOIN, as far as JOIN for
 
134
      'options' of select_query will be set in JOIN, as far as JOIN for
131
135
      every PS/SP execution new, we will not need reset this flag if
132
136
      setup_tables_done_option changed for next rexecution
133
137
    */
134
 
    res= mysql_select(session, &select_lex->ref_pointer_array,
 
138
    res= select_query(session,
 
139
                      &select_lex->ref_pointer_array,
135
140
                      (TableList*) select_lex->table_list.first,
136
 
                      select_lex->with_wild, select_lex->item_list,
 
141
                      select_lex->with_wild,
 
142
                      select_lex->item_list,
137
143
                      select_lex->where,
138
144
                      select_lex->order_list.elements +
139
145
                      select_lex->group_list.elements,
140
 
                      (order_st*) select_lex->order_list.first,
141
 
                      (order_st*) select_lex->group_list.first,
 
146
                      (Order*) select_lex->order_list.first,
 
147
                      (Order*) select_lex->group_list.first,
142
148
                      select_lex->having,
143
149
                      select_lex->options | session->options |
144
150
                      setup_tables_done_option,
264
270
 
265
271
/*****************************************************************************
266
272
  Check fields, find best join, do the select and output fields.
267
 
  mysql_select assumes that all tables are already opened
 
273
  select_query assumes that all tables are already opened
268
274
*****************************************************************************/
269
275
 
270
276
/*
344
350
  @retval
345
351
    true   an error
346
352
*/
347
 
bool mysql_select(Session *session,
 
353
bool select_query(Session *session,
348
354
                  Item ***rref_pointer_array,
349
355
                  TableList *tables, 
350
356
                  uint32_t wild_num, 
351
357
                  List<Item> &fields,
352
358
                  COND *conds, 
353
359
                  uint32_t og_num,  
354
 
                  order_st *order, 
355
 
                  order_st *group,
 
360
                  Order *order,
 
361
                  Order *group,
356
362
                  Item *having, 
357
363
                  uint64_t select_options,
358
364
                  select_result *result, 
363
369
  bool free_join= 1;
364
370
 
365
371
  select_lex->context.resolve_in_select_list= true;
366
 
  JOIN *join;
 
372
  Join *join;
367
373
  if (select_lex->join != 0)
368
374
  {
369
375
    join= select_lex->join;
396
402
  }
397
403
  else
398
404
  {
399
 
    if (!(join= new JOIN(session, fields, select_options, result)))
 
405
    if (!(join= new Join(session, fields, select_options, result)))
400
406
      return(true);
401
407
    session->set_proc_info("init");
402
408
    session->used_tables=0;                         // Updated by setup_fields
446
452
  return (cond? (new Item_cond_and(cond, item)) : item);
447
453
}
448
454
 
449
 
static void fix_list_after_tbl_changes(Select_Lex *new_parent, List<TableList> *tlist)
450
 
{
451
 
  List_iterator<TableList> it(*tlist);
452
 
  TableList *table;
453
 
  while ((table= it++))
454
 
  {
455
 
    if (table->on_expr)
456
 
      table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
457
 
    if (table->nested_join)
458
 
      fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
459
 
  }
460
 
}
461
 
 
462
455
/*****************************************************************************
463
456
  Create JoinTableS, make a guess about the table types,
464
457
  Approximate how many records will be used in each table
554
547
                         Select_Lex *select_lex,
555
548
                         vector<optimizer::SargableParam> &sargables)
556
549
{
557
 
  uint  and_level,i,found_eq_constant;
 
550
  uint  and_level,found_eq_constant;
558
551
  optimizer::KeyField *key_fields, *end, *field;
559
552
  uint32_t sz;
560
553
  uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
577
570
    substitutions.
578
571
  */
579
572
  sz= sizeof(optimizer::KeyField) *
580
 
      (((session->lex->current_select->cond_count+1) +
 
573
      (((session->lex->current_select->cond_count+1)*2 +
581
574
        session->lex->current_select->between_count)*m+1);
582
575
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
583
576
    return true;
597
590
      if (field->getValue()->type() == Item::NULL_ITEM &&
598
591
          ! field->getField()->real_maybe_null())
599
592
      {
600
 
        field->getField()->table->reginfo.not_exists_optimize= 1;
 
593
        field->getField()->getTable()->reginfo.not_exists_optimize= 1;
601
594
      }
602
595
    }
603
596
  }
604
 
  for (i= 0; i < tables; i++)
 
597
  for (uint32_t i= 0; i < tables; i++)
605
598
  {
606
599
    /*
607
600
      Block the creation of keys for inner tables of outer joins.
624
617
    TableList *table;
625
618
    while ((table= li++))
626
619
    {
627
 
      if (table->nested_join)
 
620
      if (table->getNestedJoin())
628
621
        add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
629
622
                              sargables);
630
623
    }
656
649
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
657
650
    prev= &key_end;
658
651
    found_eq_constant= 0;
659
 
    for (i= 0; i < keyuse->elements-1; i++, use++)
660
652
    {
661
 
      if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
662
 
        use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
663
 
      if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
 
653
      uint32_t i;
 
654
 
 
655
      for (i= 0; i < keyuse->elements-1; i++, use++)
664
656
      {
665
 
        if (prev->getKeypart() + 1 < use->getKeypart() || 
666
 
            ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
667
 
          continue;                             /* remove */
 
657
        if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
 
658
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
 
659
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
 
660
        {
 
661
          if (prev->getKeypart() + 1 < use->getKeypart() || 
 
662
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
 
663
            continue;                           /* remove */
 
664
        }
 
665
        else if (use->getKeypart() != 0)                // First found must be 0
 
666
          continue;
 
667
 
 
668
#ifdef HAVE_VALGRIND
 
669
        /* Valgrind complains about overlapped memcpy when save_pos==use. */
 
670
        if (save_pos != use)
 
671
#endif
 
672
          *save_pos= *use;
 
673
        prev=use;
 
674
        found_eq_constant= ! use->getUsedTables();
 
675
        /* Save ptr to first use */
 
676
        if (! use->getTable()->reginfo.join_tab->keyuse)
 
677
          use->getTable()->reginfo.join_tab->keyuse= save_pos;
 
678
        use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
 
679
        save_pos++;
668
680
      }
669
 
      else if (use->getKeypart() != 0)          // First found must be 0
670
 
        continue;
671
 
 
672
 
#ifdef HAVE_purify
673
 
      /* Valgrind complains about overlapped memcpy when save_pos==use. */
674
 
      if (save_pos != use)
675
 
#endif
676
 
        *save_pos= *use;
677
 
      prev=use;
678
 
      found_eq_constant= ! use->getUsedTables();
679
 
      /* Save ptr to first use */
680
 
      if (! use->getTable()->reginfo.join_tab->keyuse)
681
 
        use->getTable()->reginfo.join_tab->keyuse= save_pos;
682
 
      use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
683
 
      save_pos++;
 
681
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
 
682
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
 
683
      keyuse->elements= i;
684
684
    }
685
 
    i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
686
 
    set_dynamic(keyuse, (unsigned char*) &key_end, i);
687
 
    keyuse->elements= i;
688
685
  }
689
686
  return false;
690
687
}
692
689
/**
693
690
  Update some values in keyuse for faster choose_plan() loop.
694
691
*/
695
 
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
 
692
void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
696
693
{
697
694
  optimizer::KeyUse *end,*keyuse= dynamic_element(keyuse_array, 
698
695
                                                  0, 
747
744
  @return
748
745
    None
749
746
*/
750
 
void add_group_and_distinct_keys(JOIN *join, JoinTable *join_tab)
 
747
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
751
748
{
752
749
  List<Item_field> indexed_fields;
753
750
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
754
 
  order_st      *cur_group;
 
751
  Order      *cur_group;
755
752
  Item_field *cur_item;
756
753
  key_map possible_keys(0);
757
754
 
852
849
  Field **f_ptr,*field;
853
850
 
854
851
  null_fields= blobs= fields= rec_length=0;
855
 
  for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
 
852
  for (f_ptr=join_tab->table->getFields() ; (field= *f_ptr) ; f_ptr++)
856
853
  {
857
854
    if (field->isReadSet())
858
855
    {
883
880
StoredKey *get_store_key(Session *session,
884
881
                         optimizer::KeyUse *keyuse,
885
882
                         table_map used_tables,
886
 
                         KEY_PART_INFO *key_part,
 
883
                         KeyPartInfo *key_part,
887
884
                         unsigned char *key_buff,
888
885
                         uint32_t maybe_null)
889
886
{
928
925
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
929
926
{
930
927
  bool error;
931
 
  Table *table= field->table;
 
928
  Table *table= field->getTable();
932
929
  Session *session= table->in_use;
933
930
  ha_rows cuted_fields=session->cuted_fields;
934
931
 
935
932
  /*
936
933
    we should restore old value of count_cuted_fields because
937
 
    store_val_in_field can be called from mysql_insert
 
934
    store_val_in_field can be called from insert_query
938
935
    with select_insert, which make count_cuted_fields= 1
939
936
   */
940
937
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
959
956
    *e1= e2;
960
957
}
961
958
 
962
 
bool create_ref_for_key(JOIN *join, 
 
959
bool create_ref_for_key(Join *join, 
963
960
                        JoinTable *j, 
964
961
                        optimizer::KeyUse *org_keyuse,
965
962
                        table_map used_tables)
970
967
  uint32_t length;
971
968
  uint32_t key;
972
969
  Table *table= NULL;
973
 
  KEY *keyinfo= NULL;
 
970
  KeyInfo *keyinfo= NULL;
974
971
 
975
972
  /*  Use best key from find_best */
976
973
  table= j->table;
1137
1134
      3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
1138
1135
         appropiate JoinTable members.
1139
1136
*/
1140
 
void add_not_null_conds(JOIN *join)
 
1137
void add_not_null_conds(Join *join)
1141
1138
{
1142
1139
  for (uint32_t i= join->const_tables; i < join->tables; i++)
1143
1140
  {
1154
1151
          Item *notnull;
1155
1152
          assert(item->type() == Item::FIELD_ITEM);
1156
1153
          Item_field *not_null_item= (Item_field*)item;
1157
 
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
 
1154
          JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
1158
1155
          /*
1159
1156
            For UPDATE queries such as:
1160
1157
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
1211
1208
  return tmp;
1212
1209
}
1213
1210
 
1214
 
/*
1215
 
  Check if given expression uses only table fields covered by the given index
1216
 
 
1217
 
  SYNOPSIS
1218
 
    uses_index_fields_only()
1219
 
      item           Expression to check
1220
 
      tbl            The table having the index
1221
 
      keyno          The index number
1222
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1223
 
 
1224
 
  DESCRIPTION
1225
 
    Check if given expression only uses fields covered by index #keyno in the
1226
 
    table tbl. The expression can use any fields in any other tables.
1227
 
 
1228
 
    The expression is guaranteed not to be AND or OR - those constructs are
1229
 
    handled outside of this function.
1230
 
 
1231
 
  RETURN
1232
 
    true   Yes
1233
 
    false  No
1234
 
*/
1235
 
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
1236
 
{
1237
 
  if (item->const_item())
1238
 
    return true;
1239
 
 
1240
 
  /*
1241
 
    Don't push down the triggered conditions. Nested outer joins execution
1242
 
    code may need to evaluate a condition several times (both triggered and
1243
 
    untriggered), and there is no way to put thi
1244
 
    TODO: Consider cloning the triggered condition and using the copies for:
1245
 
      1. push the first copy down, to have most restrictive index condition
1246
 
         possible
1247
 
      2. Put the second copy into tab->select_cond.
1248
 
  */
1249
 
  if (item->type() == Item::FUNC_ITEM &&
1250
 
      ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
1251
 
    return false;
1252
 
 
1253
 
  if (!(item->used_tables() & tbl->map))
1254
 
    return other_tbls_ok;
1255
 
 
1256
 
  Item::Type item_type= item->type();
1257
 
  switch (item_type) {
1258
 
  case Item::FUNC_ITEM:
1259
 
    {
1260
 
      /* This is a function, apply condition recursively to arguments */
1261
 
      Item_func *item_func= (Item_func*)item;
1262
 
      Item **child;
1263
 
      Item **item_end= (item_func->arguments()) + item_func->argument_count();
1264
 
      for (child= item_func->arguments(); child != item_end; child++)
1265
 
      {
1266
 
        if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
1267
 
          return false;
1268
 
      }
1269
 
      return true;
1270
 
    }
1271
 
  case Item::COND_ITEM:
1272
 
    {
1273
 
      /* This is a function, apply condition recursively to arguments */
1274
 
      List_iterator<Item> li(*((Item_cond*)item)->argument_list());
1275
 
      Item *list_item;
1276
 
      while ((list_item=li++))
1277
 
      {
1278
 
        if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
1279
 
          return false;
1280
 
      }
1281
 
      return true;
1282
 
    }
1283
 
  case Item::FIELD_ITEM:
1284
 
    {
1285
 
      Item_field *item_field= (Item_field*)item;
1286
 
      if (item_field->field->table != tbl)
1287
 
        return true;
1288
 
      return item_field->field->part_of_key.test(keyno);
1289
 
    }
1290
 
  case Item::REF_ITEM:
1291
 
    return uses_index_fields_only(item->real_item(), tbl, keyno,
1292
 
                                  other_tbls_ok);
1293
 
  default:
1294
 
    return false; /* Play it safe, don't push unknown non-const items */
1295
 
  }
1296
 
}
1297
 
 
1298
1211
#define ICP_COND_USES_INDEX_ONLY 10
1299
1212
 
1300
 
/*
1301
 
  Get a part of the condition that can be checked using only index fields
1302
 
 
1303
 
  SYNOPSIS
1304
 
    make_cond_for_index()
1305
 
      cond           The source condition
1306
 
      table          The table that is partially available
1307
 
      keyno          The index in the above table. Only fields covered by the index
1308
 
                     are available
1309
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1310
 
 
1311
 
  DESCRIPTION
1312
 
    Get a part of the condition that can be checked when for the given table
1313
 
    we have values only of fields covered by some index. The condition may
1314
 
    refer to other tables, it is assumed that we have values of all of their
1315
 
    fields.
1316
 
 
1317
 
    Example:
1318
 
      make_cond_for_index(
1319
 
         "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
1320
 
          t2, keyno(t2.key1))
1321
 
      will return
1322
 
        "cond(t1.field) AND cond(t2.key2)"
1323
 
 
1324
 
  RETURN
1325
 
    Index condition, or NULL if no condition could be inferred.
1326
 
*/
1327
 
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
1328
 
{
1329
 
  if (!cond)
1330
 
    return NULL;
1331
 
  if (cond->type() == Item::COND_ITEM)
1332
 
  {
1333
 
    uint32_t n_marked= 0;
1334
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1335
 
    {
1336
 
      Item_cond_and *new_cond=new Item_cond_and;
1337
 
      if (!new_cond)
1338
 
        return (COND*) 0;
1339
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1340
 
      Item *item;
1341
 
      while ((item=li++))
1342
 
      {
1343
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1344
 
        if (fix)
1345
 
          new_cond->argument_list()->push_back(fix);
1346
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1347
 
      }
1348
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1349
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1350
 
      switch (new_cond->argument_list()->elements) {
1351
 
      case 0:
1352
 
        return (COND*) 0;
1353
 
      case 1:
1354
 
        return new_cond->argument_list()->head();
1355
 
      default:
1356
 
        new_cond->quick_fix_field();
1357
 
        return new_cond;
1358
 
      }
1359
 
    }
1360
 
    else /* It's OR */
1361
 
    {
1362
 
      Item_cond_or *new_cond=new Item_cond_or;
1363
 
      if (!new_cond)
1364
 
        return (COND*) 0;
1365
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1366
 
      Item *item;
1367
 
      while ((item=li++))
1368
 
      {
1369
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1370
 
        if (!fix)
1371
 
          return (COND*) 0;
1372
 
        new_cond->argument_list()->push_back(fix);
1373
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1374
 
      }
1375
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1376
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1377
 
      new_cond->quick_fix_field();
1378
 
      new_cond->top_level_item();
1379
 
      return new_cond;
1380
 
    }
1381
 
  }
1382
 
 
1383
 
  if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
1384
 
    return (COND*) 0;
1385
 
  cond->marker= ICP_COND_USES_INDEX_ONLY;
1386
 
  return cond;
1387
 
}
1388
 
 
1389
 
 
1390
 
static Item *make_cond_remainder(Item *cond, bool exclude_index)
1391
 
{
1392
 
  if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
1393
 
    return 0; /* Already checked */
1394
 
 
1395
 
  if (cond->type() == Item::COND_ITEM)
1396
 
  {
1397
 
    table_map tbl_map= 0;
1398
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1399
 
    {
1400
 
      /* Create new top level AND item */
1401
 
      Item_cond_and *new_cond=new Item_cond_and;
1402
 
      if (!new_cond)
1403
 
        return (COND*) 0;
1404
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1405
 
      Item *item;
1406
 
      while ((item=li++))
1407
 
      {
1408
 
        Item *fix= make_cond_remainder(item, exclude_index);
1409
 
        if (fix)
1410
 
        {
1411
 
          new_cond->argument_list()->push_back(fix);
1412
 
          tbl_map |= fix->used_tables();
1413
 
        }
1414
 
      }
1415
 
      switch (new_cond->argument_list()->elements) {
1416
 
      case 0:
1417
 
        return (COND*) 0;
1418
 
      case 1:
1419
 
        return new_cond->argument_list()->head();
1420
 
      default:
1421
 
        new_cond->quick_fix_field();
1422
 
        ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1423
 
        return new_cond;
1424
 
      }
1425
 
    }
1426
 
    else /* It's OR */
1427
 
    {
1428
 
      Item_cond_or *new_cond=new Item_cond_or;
1429
 
      if (!new_cond)
1430
 
        return (COND*) 0;
1431
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1432
 
      Item *item;
1433
 
      while ((item=li++))
1434
 
      {
1435
 
        Item *fix= make_cond_remainder(item, false);
1436
 
        if (!fix)
1437
 
          return (COND*) 0;
1438
 
        new_cond->argument_list()->push_back(fix);
1439
 
        tbl_map |= fix->used_tables();
1440
 
      }
1441
 
      new_cond->quick_fix_field();
1442
 
      ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1443
 
      new_cond->top_level_item();
1444
 
      return new_cond;
1445
 
    }
1446
 
  }
1447
 
  return cond;
1448
 
}
1449
1213
 
1450
1214
/**
1451
1215
  cleanup JoinTable.
1457
1221
  delete quick;
1458
1222
  quick= 0;
1459
1223
  if (cache.buff)
 
1224
  {
 
1225
    size_t size= cache.end - cache.buff;
 
1226
    global_join_buffer.sub(size);
1460
1227
    free(cache.buff);
 
1228
  }
1461
1229
  cache.buff= 0;
1462
1230
  limit= 0;
1463
1231
  if (table)
1474
1242
    */
1475
1243
    table->reginfo.join_tab= 0;
1476
1244
  }
1477
 
  end_read_record(&read_record);
 
1245
  read_record.end_read_record();
1478
1246
}
1479
1247
 
1480
 
bool only_eq_ref_tables(JOIN *join,order_st *order,table_map tables)
 
1248
bool only_eq_ref_tables(Join *join,Order *order,table_map tables)
1481
1249
{
1482
1250
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1483
1251
  {
1506
1274
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
1507
1275
  @endcode
1508
1276
*/
1509
 
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab)
 
1277
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
1510
1278
{
1511
1279
  if (tab->cached_eq_ref_table)                 // If cached
1512
1280
    return tab->eq_ref_table;
1525
1293
  {
1526
1294
    if (! (*ref_item)->const_item())
1527
1295
    {                                           // Not a const ref
1528
 
      order_st *order;
 
1296
      Order *order;
1529
1297
      for (order=start_order ; order ; order=order->next)
1530
1298
      {
1531
1299
        if ((*ref_item)->eq(order->item[0],0))
2265
2033
    {
2266
2034
      if (table->on_expr)
2267
2035
      {
2268
 
        List<TableList> *nested_join_list= table->nested_join ?
2269
 
          &table->nested_join->join_list : NULL;
 
2036
        List<TableList> *nested_join_list= table->getNestedJoin() ?
 
2037
          &table->getNestedJoin()->join_list : NULL;
2270
2038
        /*
2271
2039
          We can modify table->on_expr because its old value will
2272
2040
          be restored before re-execution of PS/SP.
2319
2087
  if (outer_ref)
2320
2088
    return cmp;
2321
2089
  JoinTable **idx= (JoinTable **) table_join_idx;
2322
 
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
 
2090
  cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
2323
2091
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
2324
2092
}
2325
2093
 
2539
2307
  @param cond       condition whose multiple equalities are to be checked
2540
2308
  @param table      constant table that has been read
2541
2309
*/
2542
 
static void update_const_equal_items(COND *cond, JoinTable *tab)
 
2310
void update_const_equal_items(COND *cond, JoinTable *tab)
2543
2311
{
2544
2312
  if (!(cond->used_tables() & tab->table->map))
2545
2313
    return;
2566
2334
      while ((item_field= it++))
2567
2335
      {
2568
2336
        Field *field= item_field->field;
2569
 
        JoinTable *stat= field->table->reginfo.join_tab;
 
2337
        JoinTable *stat= field->getTable()->reginfo.join_tab;
2570
2338
        key_map possible_keys= field->key_start;
2571
 
        possible_keys&= field->table->keys_in_use_for_query;
 
2339
        possible_keys&= field->getTable()->keys_in_use_for_query;
2572
2340
        stat[0].const_keys|= possible_keys;
2573
2341
 
2574
2342
        /*
2578
2346
        */
2579
2347
        if (possible_keys.any())
2580
2348
        {
2581
 
          Table *field_tab= field->table;
 
2349
          Table *field_tab= field->getTable();
2582
2350
          optimizer::KeyUse *use;
2583
2351
          for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
2584
2352
            if (possible_keys.test(use->getKey()) &&
2596
2364
  and_level
2597
2365
*/
2598
2366
static void change_cond_ref_to_const(Session *session,
2599
 
                                     vector<COND_CMP>& save_list,
 
2367
                                     list<COND_CMP>& save_list,
2600
2368
                                     Item *and_father,
2601
2369
                                     Item *cond,
2602
2370
                                     Item *field,
2609
2377
    Item *item;
2610
2378
    while ((item=li++))
2611
2379
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
 
2380
 
2612
2381
    return;
2613
2382
  }
2614
2383
  if (cond->eq_cmp_result() == Item::COND_OK)
2627
2396
       left_item->collation.collation == value->collation.collation))
2628
2397
  {
2629
2398
    Item *tmp=value->clone_item();
2630
 
    tmp->collation.set(right_item->collation);
2631
 
 
2632
2399
    if (tmp)
2633
2400
    {
 
2401
      tmp->collation.set(right_item->collation);
2634
2402
      session->change_item_tree(args + 1, tmp);
2635
2403
      func->update_used_tables();
2636
2404
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2650
2418
            right_item->collation.collation == value->collation.collation))
2651
2419
  {
2652
2420
    Item *tmp= value->clone_item();
2653
 
    tmp->collation.set(left_item->collation);
2654
 
 
2655
2421
    if (tmp)
2656
2422
    {
 
2423
      tmp->collation.set(left_item->collation);
2657
2424
      session->change_item_tree(args, tmp);
2658
2425
      value= tmp;
2659
2426
      func->update_used_tables();
2703
2470
}
2704
2471
 
2705
2472
static void propagate_cond_constants(Session *session, 
2706
 
                                     vector<COND_CMP>& save_list, 
 
2473
                                     list<COND_CMP>& save_list, 
2707
2474
                                     COND *and_father, 
2708
2475
                                     COND *cond)
2709
2476
{
2712
2479
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2713
2480
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2714
2481
    Item *item;
2715
 
    vector<COND_CMP> save;
 
2482
    list<COND_CMP> save;
2716
2483
    while ((item=li++))
2717
2484
    {
2718
2485
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2720
2487
    if (and_level)
2721
2488
    {
2722
2489
      // Handle other found items
2723
 
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2490
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2724
2491
      {
2725
 
        Item **args= iter->cmp_func->arguments();
2726
 
        if (!args[0]->const_item())
 
2492
        Item **args= iter->second->arguments();
 
2493
        if (not args[0]->const_item())
2727
2494
        {
2728
 
          change_cond_ref_to_const( session, save, iter->and_level,
2729
 
                                    iter->and_level, args[0], args[1] );
 
2495
          change_cond_ref_to_const(session, save, iter->first,
 
2496
                                   iter->first, args[0], args[1] );
2730
2497
        }
2731
2498
      }
2732
2499
    }
2839
2606
         position:
2840
2607
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2841
2608
             joins) we've opened but didn't close.
2842
 
          2. {each nested_join_st structure not simplified away}->counter - number
 
2609
          2. {each NestedJoin class not simplified away}->counter - number
2843
2610
             of this nested join's children that have already been added to to
2844
2611
             the partial join order.
2845
2612
  @endverbatim
2846
2613
 
2847
2614
  @param join       Join being processed
2848
 
  @param last_tab   Last table in current partial join order (this function is
2849
 
                    not called for empty partial join orders)
2850
2615
  @param next_tab   Table we're going to extend the current partial join with
2851
2616
 
2852
2617
  @retval
2855
2620
  @retval
2856
2621
    true   Requested join order extension not allowed.
2857
2622
*/
2858
 
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
 
2623
bool check_interleaving_with_nj(JoinTable *next_tab)
2859
2624
{
2860
 
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
2861
 
  JOIN *join= last_tab->join;
 
2625
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
 
2626
  Join *join= next_tab->join;
2862
2627
 
2863
2628
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2864
2629
  {
2873
2638
    Do update counters for "pairs of brackets" that we've left (marked as
2874
2639
    X,Y,Z in the above picture)
2875
2640
  */
2876
 
  for (;next_emb; next_emb= next_emb->embedding)
 
2641
  for (;next_emb; next_emb= next_emb->getEmbedding())
2877
2642
  {
2878
 
    next_emb->nested_join->counter_++;
2879
 
    if (next_emb->nested_join->counter_ == 1)
 
2643
    next_emb->getNestedJoin()->counter_++;
 
2644
    if (next_emb->getNestedJoin()->counter_ == 1)
2880
2645
    {
2881
2646
      /*
2882
2647
        next_emb is the first table inside a nested join we've "entered". In
2883
2648
        the picture above, we're looking at the 'X' bracket. Don't exit yet as
2884
2649
        X bracket might have Y pair bracket.
2885
2650
      */
2886
 
      join->cur_embedding_map |= next_emb->nested_join->nj_map;
 
2651
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
2887
2652
    }
2888
2653
 
2889
 
    if (next_emb->nested_join->join_list.elements !=
2890
 
        next_emb->nested_join->counter_)
 
2654
    if (next_emb->getNestedJoin()->join_list.elements !=
 
2655
        next_emb->getNestedJoin()->counter_)
2891
2656
      break;
2892
2657
 
2893
2658
    /*
2894
2659
      We're currently at Y or Z-bracket as depicted in the above picture.
2895
2660
      Mark that we've left it and continue walking up the brackets hierarchy.
2896
2661
    */
2897
 
    join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
 
2662
    join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
2898
2663
  }
2899
2664
  return false;
2900
2665
}
2901
2666
 
2902
 
COND *optimize_cond(JOIN *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
 
2667
COND *optimize_cond(Join *join, COND *conds, List<TableList> *join_list, Item::cond_result *cond_value)
2903
2668
{
2904
2669
  Session *session= join->session;
2905
2670
 
2919
2684
                             &join->cond_equal);
2920
2685
 
2921
2686
    /* change field = field to field = const for each found field = const */
2922
 
    vector<COND_CMP> temp;
 
2687
    list<COND_CMP> temp;
2923
2688
    propagate_cond_constants(session, temp, conds, conds);
2924
2689
    /*
2925
2690
      Remove all instances of item == item
3022
2787
    {
3023
2788
      Field *field= ((Item_field*) args[0])->field;
3024
2789
      if (field->flags & AUTO_INCREMENT_FLAG 
3025
 
          && ! field->table->maybe_null 
 
2790
          && ! field->getTable()->maybe_null 
3026
2791
          && session->options & OPTION_AUTO_IS_NULL
3027
2792
          && (
3028
2793
            session->first_successful_insert_id_in_prev_stmt > 0 
3080
2845
  /*
3081
2846
    TODO:
3082
2847
    Excluding all expensive functions is too restritive we should exclude only
3083
 
    materialized IN because it is created later than this phase, and cannot be
3084
 
    evaluated at this point.
3085
 
    The condition should be something as (need to fix member access):
3086
 
      !(cond->type() == Item::FUNC_ITEM &&
3087
 
        ((Item_func*)cond)->func_name() == "<in_optimizer>" &&
3088
 
        ((Item_in_optimizer*)cond)->is_expensive()))
 
2848
    materialized IN subquery predicates because they can't yet be evaluated
 
2849
    here (they need additional initialization that is done later on).
 
2850
 
 
2851
    The proper way to exclude the subqueries would be to walk the cond tree and
 
2852
    check for materialized subqueries there.
 
2853
 
3089
2854
  */
3090
2855
  {
3091
2856
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
3208
2973
  @return
3209
2974
    end_select function to use. This function can't fail.
3210
2975
*/
3211
 
Next_select_func setup_end_select_func(JOIN *join)
 
2976
Next_select_func setup_end_select_func(Join *join)
3212
2977
{
3213
2978
  Table *table= join->tmp_table;
3214
2979
  Tmp_Table_Param *tmp_tbl= &join->tmp_table_param;
3220
2985
    if (table->group && tmp_tbl->sum_func_count &&
3221
2986
        !tmp_tbl->precomputed_group_by)
3222
2987
    {
3223
 
      if (table->s->keys)
 
2988
      if (table->getShare()->sizeKeys())
3224
2989
      {
3225
2990
        end_select= end_update;
3226
2991
      }
3231
2996
    }
3232
2997
    else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
3233
2998
    {
3234
 
      end_select=end_write_group;
 
2999
      end_select= end_write_group;
3235
3000
    }
3236
3001
    else
3237
3002
    {
3238
 
      end_select=end_write;
 
3003
      end_select= end_write;
3239
3004
      if (tmp_tbl->precomputed_group_by)
3240
3005
      {
3241
3006
        /*
3273
3038
  @retval
3274
3039
    -1  if error should be sent
3275
3040
*/
3276
 
int do_select(JOIN *join, List<Item> *fields, Table *table)
 
3041
int do_select(Join *join, List<Item> *fields, Table *table)
3277
3042
{
3278
3043
  int rc= 0;
3279
3044
  enum_nested_loop_state error= NESTED_LOOP_OK;
3287
3052
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
3288
3053
    table->emptyRecord();
3289
3054
    if (table->group && join->tmp_table_param.sum_func_count &&
3290
 
        table->s->keys && !table->cursor->inited)
3291
 
      table->cursor->ha_index_init(0, 0);
 
3055
        table->getShare()->sizeKeys() && !table->cursor->inited)
 
3056
    {
 
3057
      int tmp_error;
 
3058
      tmp_error= table->cursor->startIndexScan(0, 0);
 
3059
      if (tmp_error != 0)
 
3060
      {
 
3061
        table->print_error(tmp_error, MYF(0));
 
3062
        return -1;
 
3063
      }
 
3064
    }
3292
3065
  }
3293
3066
  /* Set up select_end */
3294
3067
  Next_select_func end_select= setup_end_select_func(join);
3374
3147
  return(join->session->is_error() ? -1 : rc);
3375
3148
}
3376
3149
 
3377
 
enum_nested_loop_state sub_select_cache(JOIN *join, JoinTable *join_tab, bool end_of_records)
 
3150
enum_nested_loop_state sub_select_cache(Join *join, JoinTable *join_tab, bool end_of_records)
3378
3151
{
3379
3152
  enum_nested_loop_state rc;
3380
3153
 
3385
3158
      rc= sub_select(join,join_tab,end_of_records);
3386
3159
    return rc;
3387
3160
  }
3388
 
  if (join->session->killed)            // If aborted by user
 
3161
  if (join->session->getKilled())               // If aborted by user
3389
3162
  {
3390
3163
    join->session->send_kill_message();
3391
3164
    return NESTED_LOOP_KILLED;
3392
3165
  }
3393
3166
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
3394
3167
  {
3395
 
    if (! store_record_in_cache(&join_tab->cache))
 
3168
    if (! join_tab->cache.store_record_in_cache())
3396
3169
      return NESTED_LOOP_OK;                     // There is more room in cache
3397
3170
    return flush_cached_records(join,join_tab,false);
3398
3171
  }
3521
3294
  @return
3522
3295
    return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
3523
3296
*/
3524
 
enum_nested_loop_state sub_select(JOIN *join, JoinTable *join_tab, bool end_of_records)
 
3297
enum_nested_loop_state sub_select(Join *join, JoinTable *join_tab, bool end_of_records)
3525
3298
{
3526
3299
  join_tab->table->null_row=0;
3527
3300
  if (end_of_records)
3529
3302
 
3530
3303
  int error;
3531
3304
  enum_nested_loop_state rc;
3532
 
  READ_RECORD *info= &join_tab->read_record;
 
3305
  ReadRecord *info= &join_tab->read_record;
3533
3306
 
3534
3307
  if (join->resume_nested_loop)
3535
3308
  {
3586
3359
{
3587
3360
  int error;
3588
3361
  Table *table= tab->table;
3589
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3362
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
3590
3363
                                         tab->ref.key_buff,
3591
3364
                                         make_prev_keypart_map(tab->ref.key_parts),
3592
3365
                                         HA_READ_KEY_EXACT)))
3594
3367
  return 0;
3595
3368
}
3596
3369
 
3597
 
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
3598
 
{
3599
 
  int error;
3600
 
  Table *table=tab->table;
3601
 
  table->const_table=1;
3602
 
  table->null_row=0;
3603
 
  table->status=STATUS_NO_RECORD;
3604
 
 
3605
 
  if (tab->type == AM_SYSTEM)
3606
 
  {
3607
 
    if ((error=join_read_system(tab)))
3608
 
    {                                           // Info for DESCRIBE
3609
 
      tab->info="const row not found";
3610
 
      /* Mark for EXPLAIN that the row was not found */
3611
 
      pos->setFanout(0.0);
3612
 
      pos->clearRefDependMap();
3613
 
      if (! table->maybe_null || error > 0)
3614
 
        return(error);
3615
 
    }
3616
 
  }
3617
 
  else
3618
 
  {
3619
 
    if (! table->key_read && 
3620
 
        table->covering_keys.test(tab->ref.key) && 
3621
 
        ! table->no_keyread &&
3622
 
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3623
 
    {
3624
 
      table->key_read=1;
3625
 
      table->cursor->extra(HA_EXTRA_KEYREAD);
3626
 
      tab->index= tab->ref.key;
3627
 
    }
3628
 
    error=join_read_const(tab);
3629
 
    if (table->key_read)
3630
 
    {
3631
 
      table->key_read=0;
3632
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
3633
 
    }
3634
 
    if (error)
3635
 
    {
3636
 
      tab->info="unique row not found";
3637
 
      /* Mark for EXPLAIN that the row was not found */
3638
 
      pos->setFanout(0.0);
3639
 
      pos->clearRefDependMap();
3640
 
      if (!table->maybe_null || error > 0)
3641
 
        return(error);
3642
 
    }
3643
 
  }
3644
 
  if (*tab->on_expr_ref && !table->null_row)
3645
 
  {
3646
 
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
3647
 
      table->mark_as_null_row();
3648
 
  }
3649
 
  if (!table->null_row)
3650
 
    table->maybe_null=0;
3651
 
 
3652
 
  /* Check appearance of new constant items in Item_equal objects */
3653
 
  JOIN *join= tab->join;
3654
 
  if (join->conds)
3655
 
    update_const_equal_items(join->conds, tab);
3656
 
  TableList *tbl;
3657
 
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
3658
 
  {
3659
 
    TableList *embedded;
3660
 
    TableList *embedding= tbl;
3661
 
    do
3662
 
    {
3663
 
      embedded= embedding;
3664
 
      if (embedded->on_expr)
3665
 
         update_const_equal_items(embedded->on_expr, tab);
3666
 
      embedding= embedded->embedding;
3667
 
    }
3668
 
    while (embedding &&
3669
 
           embedding->nested_join->join_list.head() == embedded);
3670
 
  }
3671
 
 
3672
 
  return(0);
3673
 
}
3674
 
 
3675
 
int join_read_system(JoinTable *tab)
3676
 
{
3677
 
  Table *table= tab->table;
3678
 
  int error;
3679
 
  if (table->status & STATUS_GARBAGE)           // If first read
3680
 
  {
3681
 
    if ((error=table->cursor->read_first_row(table->record[0],
3682
 
                                           table->s->primary_key)))
3683
 
    {
3684
 
      if (error != HA_ERR_END_OF_FILE)
3685
 
        return table->report_error(error);
3686
 
      tab->table->mark_as_null_row();
3687
 
      table->emptyRecord();                     // Make empty record
3688
 
      return -1;
3689
 
    }
3690
 
    table->storeRecord();
3691
 
  }
3692
 
  else if (!table->status)                      // Only happens with left join
3693
 
    table->restoreRecord();                     // restore old record
3694
 
  table->null_row=0;
3695
 
  return table->status ? -1 : 0;
3696
 
}
3697
 
 
3698
3370
/**
3699
3371
  Read a (constant) table when there is at most one matching row.
3700
3372
 
3718
3390
      error= HA_ERR_KEY_NOT_FOUND;
3719
3391
    else
3720
3392
    {
3721
 
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
 
3393
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
3722
3394
                                            (unsigned char*) tab->ref.key_buff,
3723
3395
                                            make_prev_keypart_map(tab->ref.key_parts),
3724
3396
                                            HA_READ_KEY_EXACT);
3766
3438
 
3767
3439
  if (!table->cursor->inited)
3768
3440
  {
3769
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3441
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3442
    if (error != 0)
 
3443
    {
 
3444
      table->print_error(error, MYF(0));
 
3445
    }
3770
3446
  }
3771
3447
 
3772
3448
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3778
3454
      table->status=STATUS_NOT_FOUND;
3779
3455
      return -1;
3780
3456
    }
3781
 
    error=table->cursor->index_read_map(table->record[0],
 
3457
    error=table->cursor->index_read_map(table->getInsertRecord(),
3782
3458
                                      tab->ref.key_buff,
3783
3459
                                      make_prev_keypart_map(tab->ref.key_parts),
3784
3460
                                      HA_READ_KEY_EXACT);
3814
3490
 
3815
3491
  /* Initialize the index first */
3816
3492
  if (!table->cursor->inited)
3817
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3493
  {
 
3494
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3495
    if (error != 0)
 
3496
      return table->report_error(error);
 
3497
  }
3818
3498
 
3819
3499
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3820
3500
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3825
3505
 
3826
3506
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3827
3507
    return -1;
3828
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3508
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
3829
3509
                                         tab->ref.key_buff,
3830
3510
                                         make_prev_keypart_map(tab->ref.key_parts),
3831
3511
                                         HA_READ_KEY_EXACT)))
3848
3528
  Table *table= tab->table;
3849
3529
 
3850
3530
  if (!table->cursor->inited)
3851
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3531
  {
 
3532
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3533
    if (error != 0)
 
3534
      return table->report_error(error);
 
3535
  }
3852
3536
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3853
3537
    return -1;
3854
 
  if ((error=table->cursor->index_read_last_map(table->record[0],
 
3538
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3855
3539
                                              tab->ref.key_buff,
3856
3540
                                              make_prev_keypart_map(tab->ref.key_parts))))
3857
3541
  {
3862
3546
  return 0;
3863
3547
}
3864
3548
 
3865
 
int join_no_more_records(READ_RECORD *)
 
3549
int join_no_more_records(ReadRecord *)
3866
3550
{
3867
3551
  return -1;
3868
3552
}
3869
3553
 
3870
 
int join_read_next_same_diff(READ_RECORD *info)
 
3554
int join_read_next_same_diff(ReadRecord *info)
3871
3555
{
3872
3556
  Table *table= info->table;
3873
3557
  JoinTable *tab=table->reginfo.join_tab;
3874
3558
  if (tab->insideout_match_tab->found_match)
3875
3559
  {
3876
 
    KEY *key= tab->table->key_info + tab->index;
 
3560
    KeyInfo *key= tab->table->key_info + tab->index;
3877
3561
    do
3878
3562
    {
3879
3563
      int error;
3880
3564
      /* Save index tuple from record to the buffer */
3881
3565
      key_copy(tab->insideout_buf, info->record, key, 0);
3882
3566
 
3883
 
      if ((error=table->cursor->index_next_same(table->record[0],
 
3567
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3884
3568
                                              tab->ref.key_buff,
3885
3569
                                              tab->ref.key_length)))
3886
3570
      {
3898
3582
    return join_read_next_same(info);
3899
3583
}
3900
3584
 
3901
 
int join_read_next_same(READ_RECORD *info)
 
3585
int join_read_next_same(ReadRecord *info)
3902
3586
{
3903
3587
  int error;
3904
3588
  Table *table= info->table;
3905
3589
  JoinTable *tab=table->reginfo.join_tab;
3906
3590
 
3907
 
  if ((error=table->cursor->index_next_same(table->record[0],
 
3591
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3908
3592
                                          tab->ref.key_buff,
3909
3593
                                          tab->ref.key_length)))
3910
3594
  {
3917
3601
  return 0;
3918
3602
}
3919
3603
 
3920
 
int join_read_prev_same(READ_RECORD *info)
 
3604
int join_read_prev_same(ReadRecord *info)
3921
3605
{
3922
3606
  int error;
3923
3607
  Table *table= info->table;
3924
3608
  JoinTable *tab=table->reginfo.join_tab;
3925
3609
 
3926
 
  if ((error=table->cursor->index_prev(table->record[0])))
 
3610
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
3927
3611
    return table->report_error(error);
3928
3612
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3929
3613
                      tab->ref.key_length))
3941
3625
  return join_init_read_record(tab);
3942
3626
}
3943
3627
 
3944
 
int rr_sequential(READ_RECORD *info);
3945
3628
int init_read_record_seq(JoinTable *tab)
3946
3629
{
3947
 
  tab->read_record.read_record= rr_sequential;
3948
 
  if (tab->read_record.cursor->ha_rnd_init(1))
 
3630
  tab->read_record.init_reard_record_sequential();
 
3631
 
 
3632
  if (tab->read_record.cursor->startTableScan(1))
3949
3633
    return 1;
3950
3634
  return (*tab->read_record.read_record)(&tab->read_record);
3951
3635
}
3962
3646
{
3963
3647
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3964
3648
    return 1;
3965
 
  init_read_record(&tab->read_record, tab->join->session, tab->table,
3966
 
                   tab->select,1,1);
 
3649
 
 
3650
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
 
3651
    return 1;
 
3652
 
3967
3653
  return (*tab->read_record.read_record)(&tab->read_record);
3968
3654
}
3969
3655
 
3974
3660
  if (!table->key_read && table->covering_keys.test(tab->index) &&
3975
3661
      !table->no_keyread)
3976
3662
  {
3977
 
    table->key_read=1;
 
3663
    table->key_read= 1;
3978
3664
    table->cursor->extra(HA_EXTRA_KEYREAD);
3979
3665
  }
3980
 
  tab->table->status=0;
 
3666
  tab->table->status= 0;
3981
3667
  tab->read_record.table=table;
3982
3668
  tab->read_record.cursor=table->cursor;
3983
3669
  tab->read_record.index=tab->index;
3984
 
  tab->read_record.record=table->record[0];
 
3670
  tab->read_record.record=table->getInsertRecord();
3985
3671
  if (tab->insideout_match_tab)
3986
3672
  {
3987
3673
    tab->read_record.do_insideout_scan= tab;
3995
3681
  }
3996
3682
 
3997
3683
  if (!table->cursor->inited)
3998
 
    table->cursor->ha_index_init(tab->index, tab->sorted);
3999
 
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
 
3684
  {
 
3685
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
 
3686
    if (error != 0)
 
3687
    {
 
3688
      table->report_error(error);
 
3689
      return -1;
 
3690
    }
 
3691
  }
 
3692
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
4000
3693
  {
4001
3694
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
4002
3695
      table->report_error(error);
4006
3699
  return 0;
4007
3700
}
4008
3701
 
4009
 
int join_read_next_different(READ_RECORD *info)
 
3702
int join_read_next_different(ReadRecord *info)
4010
3703
{
4011
3704
  JoinTable *tab= info->do_insideout_scan;
4012
3705
  if (tab->insideout_match_tab->found_match)
4013
3706
  {
4014
 
    KEY *key= tab->table->key_info + tab->index;
 
3707
    KeyInfo *key= tab->table->key_info + tab->index;
4015
3708
    do
4016
3709
    {
4017
3710
      int error;
4029
3722
    return join_read_next(info);
4030
3723
}
4031
3724
 
4032
 
int join_read_next(READ_RECORD *info)
 
3725
int join_read_next(ReadRecord *info)
4033
3726
{
4034
3727
  int error;
4035
3728
  if ((error=info->cursor->index_next(info->record)))
4052
3745
  tab->read_record.table=table;
4053
3746
  tab->read_record.cursor=table->cursor;
4054
3747
  tab->read_record.index=tab->index;
4055
 
  tab->read_record.record=table->record[0];
 
3748
  tab->read_record.record=table->getInsertRecord();
4056
3749
  if (!table->cursor->inited)
4057
 
    table->cursor->ha_index_init(tab->index, 1);
4058
 
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
 
3750
  {
 
3751
    error= table->cursor->startIndexScan(tab->index, 1);
 
3752
    if (error != 0)
 
3753
      return table->report_error(error);
 
3754
  }
 
3755
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
4059
3756
    return table->report_error(error);
4060
3757
 
4061
3758
  return 0;
4062
3759
}
4063
3760
 
4064
 
int join_read_prev(READ_RECORD *info)
 
3761
int join_read_prev(ReadRecord *info)
4065
3762
{
4066
3763
  int error;
4067
3764
  if ((error= info->cursor->index_prev(info->record)))
4087
3784
  return safe_index_read(tab);
4088
3785
}
4089
3786
 
4090
 
int join_read_next_same_or_null(READ_RECORD *info)
 
3787
int join_read_next_same_or_null(ReadRecord *info)
4091
3788
{
4092
3789
  int error;
4093
3790
  if ((error= join_read_next_same(info)) >= 0)
4101
3798
  return safe_index_read(tab);                  // then read null keys
4102
3799
}
4103
3800
 
4104
 
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *, bool end_of_records)
 
3801
enum_nested_loop_state end_send_group(Join *join, JoinTable *, bool end_of_records)
4105
3802
{
4106
3803
  int idx= -1;
4107
3804
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
4134
3831
              error=join->result->send_data(*join->fields) ? 1 : 0;
4135
3832
            join->send_records++;
4136
3833
          }
4137
 
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
 
3834
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
4138
3835
          {
4139
3836
            if (join->rollup_send_data((uint32_t) (idx+1)))
4140
3837
              error= 1;
4190
3887
  return(NESTED_LOOP_OK);
4191
3888
}
4192
3889
 
4193
 
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *, bool end_of_records)
 
3890
enum_nested_loop_state end_write_group(Join *join, JoinTable *, bool end_of_records)
4194
3891
{
4195
3892
  Table *table=join->tmp_table;
4196
3893
  int     idx= -1;
4197
3894
 
4198
 
  if (join->session->killed)
 
3895
  if (join->session->getKilled())
4199
3896
  {                                             // Aborted by user
4200
3897
    join->session->send_kill_message();
4201
3898
    return NESTED_LOOP_KILLED;
4216
3913
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
4217
3914
        if (!join->having || join->having->val_int())
4218
3915
        {
4219
 
          int error= table->cursor->ha_write_row(table->record[0]);
4220
 
          if (error && create_myisam_from_heap(join->session, table,
4221
 
                                              join->tmp_table_param.start_recinfo,
4222
 
                                                &join->tmp_table_param.recinfo,
4223
 
                                              error, 0))
4224
 
          return NESTED_LOOP_ERROR;
 
3916
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
3917
 
 
3918
          if (error)
 
3919
          {
 
3920
            my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
 
3921
            return NESTED_LOOP_ERROR;
 
3922
          }
4225
3923
        }
4226
 
        if (join->rollup.state != ROLLUP::STATE_NONE)
 
3924
        if (join->rollup.getState() != Rollup::STATE_NONE)
4227
3925
        {
4228
3926
          if (join->rollup_write_data((uint32_t) (idx+1), table))
4229
3927
            return NESTED_LOOP_ERROR;
4242
3940
    if (idx < (int) join->send_group_parts)
4243
3941
    {
4244
3942
      copy_fields(&join->tmp_table_param);
4245
 
      copy_funcs(join->tmp_table_param.items_to_copy);
 
3943
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
 
3944
        return NESTED_LOOP_ERROR;
4246
3945
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
4247
3946
        return NESTED_LOOP_ERROR;
4248
3947
      return NESTED_LOOP_OK;
4259
3958
  outer join table.
4260
3959
  We can't remove tests that are made against columns which are stored
4261
3960
  in sorted order.
4262
 
*****************************************************************************/
4263
 
 
4264
 
/**
4265
3961
  @return
4266
 
    1 if right_item is used removable reference key on left_item
4267
 
*/
 
3962
    1 if right_item used is a removable reference key on left_item
 
3963
    0 otherwise.
 
3964
****************************************************************************/
4268
3965
bool test_if_ref(Item_field *left_item,Item *right_item)
4269
3966
{
4270
3967
  Field *field=left_item->field;
4271
3968
  // No need to change const test. We also have to keep tests on LEFT JOIN
4272
 
  if (!field->table->const_table && !field->table->maybe_null)
 
3969
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
4273
3970
  {
4274
 
    Item *ref_item=part_of_refkey(field->table,field);
 
3971
    Item *ref_item=part_of_refkey(field->getTable(),field);
4275
3972
    if (ref_item && ref_item->eq(right_item,1))
4276
3973
    {
4277
3974
      right_item= right_item->real_item();
4454
4151
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
4455
4152
  if (ref_parts)
4456
4153
  {
4457
 
    KEY_PART_INFO *key_part=
 
4154
    KeyPartInfo *key_part=
4458
4155
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
4459
4156
    uint32_t part;
4460
4157
 
4465
4162
    }
4466
4163
 
4467
4164
    for (part=0 ; part < ref_parts ; part++,key_part++)
 
4165
    {
4468
4166
      if (field->eq(key_part->field) &&
4469
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
 
4167
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
 
4168
          //If field can be NULL, we should not remove this predicate, as
 
4169
          //it may lead to non-rejection of NULL values. 
 
4170
          !(field->real_maybe_null()))
 
4171
      {
4470
4172
        return table->reginfo.join_tab->ref.items[part];
 
4173
      }
 
4174
    }
4471
4175
  }
4472
4176
  return (Item*) 0;
4473
4177
}
4492
4196
  @retval
4493
4197
    -1   Reverse key can be used
4494
4198
*/
4495
 
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4199
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4496
4200
{
4497
 
  KEY_PART_INFO *key_part= NULL;
4498
 
  KEY_PART_INFO *key_part_end= NULL;
 
4201
  KeyPartInfo *key_part= NULL;
 
4202
  KeyPartInfo *key_part_end= NULL;
4499
4203
  key_part= table->key_info[idx].key_part;
4500
4204
  key_part_end= key_part + table->key_info[idx].key_parts;
4501
4205
  key_part_map const_key_parts=table->const_key_parts[idx];
4523
4227
      */
4524
4228
      if (!on_primary_key &&
4525
4229
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
4526
 
          table->s->primary_key != MAX_KEY)
 
4230
          table->getShare()->hasPrimaryKey())
4527
4231
      {
4528
4232
        on_primary_key= true;
4529
 
        key_part= table->key_info[table->s->primary_key].key_part;
4530
 
        key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
4531
 
        const_key_parts=table->const_key_parts[table->s->primary_key];
 
4233
        key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
 
4234
        key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
 
4235
        const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
4532
4236
 
4533
4237
        for (; const_key_parts & 1 ; const_key_parts>>= 1)
4534
4238
          key_part++;
4577
4281
  @retval
4578
4282
    0   no sub key
4579
4283
*/
4580
 
inline bool is_subkey(KEY_PART_INFO *key_part,
4581
 
                      KEY_PART_INFO *ref_key_part,
4582
 
                      KEY_PART_INFO *ref_key_part_end)
 
4284
inline bool is_subkey(KeyPartInfo *key_part,
 
4285
                      KeyPartInfo *ref_key_part,
 
4286
                      KeyPartInfo *ref_key_part_end)
4583
4287
{
4584
4288
  for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
4585
4289
    if (! key_part->field->eq(ref_key_part->field))
4598
4302
    - MAX_KEY                   If we can't use other key
4599
4303
    - the number of found key   Otherwise
4600
4304
*/
4601
 
static uint32_t test_if_subkey(order_st *order,
 
4305
static uint32_t test_if_subkey(Order *order,
4602
4306
                               Table *table,
4603
4307
                               uint32_t ref,
4604
4308
                               uint32_t ref_key_parts,
4608
4312
  uint32_t min_length= UINT32_MAX;
4609
4313
  uint32_t best= MAX_KEY;
4610
4314
  uint32_t not_used;
4611
 
  KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
4612
 
  KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
 
4315
  KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
 
4316
  KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
4613
4317
 
4614
 
  for (nr= 0 ; nr < table->s->keys ; nr++)
 
4318
  for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
4615
4319
  {
4616
4320
    if (usable_keys->test(nr) &&
4617
4321
        table->key_info[nr].key_length < min_length &&
4660
4364
*/
4661
4365
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
4662
4366
{
4663
 
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
 
4367
  for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
4664
4368
  {
4665
 
    if (keynr == table->s->primary_key ||
 
4369
    if (keynr == table->getShare()->getPrimaryKey() ||
4666
4370
         (table->key_info[keynr].flags & HA_NOSAME))
4667
4371
    {
4668
 
      KEY *keyinfo= table->key_info + keynr;
4669
 
      KEY_PART_INFO *key_part= NULL;
4670
 
      KEY_PART_INFO *key_part_end= NULL;
 
4372
      KeyInfo *keyinfo= table->key_info + keynr;
 
4373
      KeyPartInfo *key_part= NULL;
 
4374
      KeyPartInfo *key_part_end= NULL;
4671
4375
 
4672
4376
      for (key_part=keyinfo->key_part,
4673
4377
           key_part_end=key_part+ keyinfo->key_parts;
4700
4404
*/
4701
4405
bool find_field_in_order_list (Field *field, void *data)
4702
4406
{
4703
 
  order_st *group= (order_st *) data;
 
4407
  Order *group= (Order *) data;
4704
4408
  bool part_found= 0;
4705
 
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4409
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4706
4410
  {
4707
4411
    Item *item= (*tmp_group->item)->real_item();
4708
4412
    if (item->type() == Item::FIELD_ITEM &&
4772
4476
  @retval
4773
4477
    1    We can use an index.
4774
4478
*/
4775
 
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4479
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
4776
4480
{
4777
4481
  int32_t ref_key;
4778
4482
  uint32_t ref_key_parts;
4789
4493
  */
4790
4494
  usable_keys= *map;
4791
4495
 
4792
 
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4496
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4793
4497
  {
4794
4498
    Item *item= (*tmp_order->item)->real_item();
4795
4499
    if (item->type() != Item::FIELD_ITEM)
4918
4622
    int best_key= -1;
4919
4623
    bool is_best_covering= false;
4920
4624
    double fanout= 1;
4921
 
    JOIN *join= tab->join;
 
4625
    Join *join= tab->join;
4922
4626
    uint32_t tablenr= tab - join->join_tab;
4923
4627
    ha_rows table_records= table->cursor->stats.records;
4924
4628
    bool group= join->group && order == join->group_list;
4961
4665
      fanout*= cur_pos.getFanout(); // fanout is always >= 1
4962
4666
    }
4963
4667
 
4964
 
    for (nr=0; nr < table->s->keys ; nr++)
 
4668
    for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
4965
4669
    {
4966
4670
      int direction;
4967
4671
      if (keys.test(nr) &&
4968
4672
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4969
4673
      {
4970
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->cursor->primary_key_is_clustered());
 
4674
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
4971
4675
 
4972
4676
        /*
4973
4677
          Don't use an index scan with ORDER BY without limit.
4984
4688
        {
4985
4689
          double rec_per_key;
4986
4690
          double index_scan_time;
4987
 
          KEY *keyinfo= tab->table->key_info+nr;
 
4691
          KeyInfo *keyinfo= tab->table->key_info+nr;
4988
4692
          if (select_limit == HA_POS_ERROR)
4989
4693
            select_limit= table_records;
4990
4694
          if (group)
5215
4919
    -1          Some fatal error
5216
4920
    1           No records
5217
4921
*/
5218
 
int create_sort_index(Session *session, JOIN *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
4922
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
5219
4923
{
5220
4924
  uint32_t length= 0;
5221
4925
  ha_rows examined_rows;
5242
4946
                              is_order_by ?  &table->keys_in_use_for_order_by :
5243
4947
                              &table->keys_in_use_for_group_by))
5244
4948
    return(0);
5245
 
  for (order_st *ord= join->order; ord; ord= ord->next)
 
4949
  for (Order *ord= join->order; ord; ord= ord->next)
5246
4950
    length++;
5247
 
  if (!(join->sortorder=
5248
 
        make_unireg_sortorder(order, &length, join->sortorder)))
5249
 
    goto err;
 
4951
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
 
4952
  {
 
4953
    return(-1);
 
4954
  }
5250
4955
 
5251
4956
  table->sort.io_cache= new internal::IO_CACHE;
5252
 
  memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
5253
4957
  table->status=0;                              // May be wrong if quick_select
5254
4958
 
5255
4959
  // If table has a range, move it to select
5282
4986
                                                                 &tab->ref,
5283
4987
                                                                 tab->found_records))))
5284
4988
      {
5285
 
        goto err;
 
4989
        return(-1);
5286
4990
      }
5287
4991
    }
5288
4992
  }
5289
4993
 
5290
 
  if (table->s->tmp_table)
 
4994
  if (table->getShare()->getType())
5291
4995
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
5292
 
  table->sort.found_records=filesort(session, table,join->sortorder, length,
5293
 
                                     select, filesort_limit, 0,
5294
 
                                     &examined_rows);
 
4996
 
 
4997
  FileSort filesort(*session);
 
4998
  table->sort.found_records=filesort.run(table,join->sortorder, length,
 
4999
                                         select, filesort_limit, 0,
 
5000
                                         examined_rows);
5295
5001
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5296
5002
  if (select)
5297
5003
  {
5309
5015
    table->key_read=0;
5310
5016
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5311
5017
  }
 
5018
 
5312
5019
  return(table->sort.found_records == HA_POS_ERROR);
5313
 
err:
5314
 
  return(-1);
5315
5020
}
5316
5021
 
5317
5022
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5320
5025
  char *org_record,*new_record;
5321
5026
  unsigned char *record;
5322
5027
  int error;
5323
 
  uint32_t reclength= table->s->reclength-offset;
5324
 
 
5325
 
  org_record=(char*) (record=table->record[0])+offset;
5326
 
  new_record=(char*) table->record[1]+offset;
5327
 
 
5328
 
  cursor->ha_rnd_init(1);
 
5028
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
 
5029
 
 
5030
  org_record=(char*) (record=table->getInsertRecord())+offset;
 
5031
  new_record=(char*) table->getUpdateRecord()+offset;
 
5032
 
 
5033
  if ((error= cursor->startTableScan(1)))
 
5034
    goto err;
 
5035
 
5329
5036
  error=cursor->rnd_next(record);
5330
5037
  for (;;)
5331
5038
  {
5332
 
    if (session->killed)
 
5039
    if (session->getKilled())
5333
5040
    {
5334
5041
      session->send_kill_message();
5335
5042
      error=0;
5345
5052
    }
5346
5053
    if (having && !having->val_int())
5347
5054
    {
5348
 
      if ((error=cursor->ha_delete_row(record)))
 
5055
      if ((error=cursor->deleteRecord(record)))
5349
5056
        goto err;
5350
5057
      error=cursor->rnd_next(record);
5351
5058
      continue;
5372
5079
      }
5373
5080
      if (table->compare_record(first_field) == 0)
5374
5081
      {
5375
 
        if ((error=cursor->ha_delete_row(record)))
 
5082
        if ((error=cursor->deleteRecord(record)))
5376
5083
          goto err;
5377
5084
      }
5378
5085
      else if (!found)
5383
5090
    }
5384
5091
    if (!found)
5385
5092
      break;                                    // End of cursor
5386
 
    /* Restart search on next row */
5387
 
    error=cursor->restart_rnd_next(record,cursor->ref);
 
5093
    /* Move current position to the next row */
 
5094
    error= cursor->rnd_pos(record, cursor->ref);
5388
5095
  }
5389
5096
 
5390
5097
  cursor->extra(HA_EXTRA_NO_CACHE);
5409
5116
                               uint32_t key_length,
5410
5117
                               Item *having)
5411
5118
{
5412
 
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
 
5119
  unsigned char *key_pos, *record=table->getInsertRecord();
5413
5120
  int error;
5414
5121
  Cursor *cursor= table->cursor;
5415
5122
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5416
 
  uint32_t *field_lengths,*field_length;
 
5123
  uint32_t *field_length;
5417
5124
  HASH hash;
 
5125
  std::vector<unsigned char> key_buffer;
 
5126
  std::vector<uint32_t> field_lengths;
5418
5127
 
5419
 
  if (! memory::multi_malloc(false,
5420
 
                       &key_buffer,
5421
 
                       (uint32_t) ((key_length + extra_length) *
5422
 
                               (long) cursor->stats.records),
5423
 
                       &field_lengths,
5424
 
                       (uint32_t) (field_count*sizeof(*field_lengths)),
5425
 
                       NULL))
5426
 
    return(1);
 
5128
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
 
5129
  field_lengths.resize(field_count);
5427
5130
 
5428
5131
  {
5429
5132
    Field **ptr;
5430
5133
    uint32_t total_length= 0;
5431
 
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
 
5134
 
 
5135
    for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
5432
5136
    {
5433
5137
      uint32_t length= (*ptr)->sort_length();
5434
5138
      (*field_length++)= length;
5442
5146
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5443
5147
                key_length, (hash_get_key) 0, 0, 0))
5444
5148
  {
5445
 
    free((char*) key_buffer);
5446
5149
    return(1);
5447
5150
  }
5448
5151
 
5449
 
  cursor->ha_rnd_init(1);
5450
 
  key_pos=key_buffer;
 
5152
  if ((error= cursor->startTableScan(1)))
 
5153
    goto err;
 
5154
 
 
5155
  key_pos= &key_buffer[0];
5451
5156
  for (;;)
5452
5157
  {
5453
5158
    unsigned char *org_key_pos;
5454
 
    if (session->killed)
 
5159
    if (session->getKilled())
5455
5160
    {
5456
5161
      session->send_kill_message();
5457
5162
      error=0;
5467
5172
    }
5468
5173
    if (having && !having->val_int())
5469
5174
    {
5470
 
      if ((error=cursor->ha_delete_row(record)))
 
5175
      if ((error=cursor->deleteRecord(record)))
5471
5176
        goto err;
5472
5177
      continue;
5473
5178
    }
5474
5179
 
5475
5180
    /* copy fields to key buffer */
5476
5181
    org_key_pos= key_pos;
5477
 
    field_length=field_lengths;
 
5182
    field_length= &field_lengths[0];
5478
5183
    for (Field **ptr= first_field ; *ptr ; ptr++)
5479
5184
    {
5480
5185
      (*ptr)->sort_string(key_pos,*field_length);
5484
5189
    if (hash_search(&hash, org_key_pos, key_length))
5485
5190
    {
5486
5191
      /* Duplicated found ; Remove the row */
5487
 
      if ((error=cursor->ha_delete_row(record)))
 
5192
      if ((error=cursor->deleteRecord(record)))
5488
5193
        goto err;
5489
5194
    }
5490
5195
    else
5491
5196
      (void) my_hash_insert(&hash, org_key_pos);
5492
5197
    key_pos+=extra_length;
5493
5198
  }
5494
 
  free((char*) key_buffer);
5495
5199
  hash_free(&hash);
5496
5200
  cursor->extra(HA_EXTRA_NO_CACHE);
5497
 
  (void) cursor->ha_rnd_end();
 
5201
  (void) cursor->endTableScan();
5498
5202
  return(0);
5499
5203
 
5500
5204
err:
5501
 
  free((char*) key_buffer);
5502
5205
  hash_free(&hash);
5503
5206
  cursor->extra(HA_EXTRA_NO_CACHE);
5504
 
  (void) cursor->ha_rnd_end();
 
5207
  (void) cursor->endTableScan();
5505
5208
  if (error)
5506
5209
    table->print_error(error,MYF(0));
5507
5210
  return(1);
5508
5211
}
5509
5212
 
5510
 
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
 
5213
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5511
5214
{
5512
5215
  uint32_t count;
5513
 
  SORT_FIELD *sort,*pos;
 
5216
  SortField *sort,*pos;
5514
5217
 
5515
5218
  count=0;
5516
 
  for (order_st *tmp = order; tmp; tmp=tmp->next)
 
5219
  for (Order *tmp = order; tmp; tmp=tmp->next)
5517
5220
    count++;
5518
5221
  if (!sortorder)
5519
 
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
 
5222
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
5520
5223
                                       (max(count, *length) + 1));
5521
5224
  pos= sort= sortorder;
5522
5225
 
5638
5341
static bool find_order_in_list(Session *session, 
5639
5342
                               Item **ref_pointer_array, 
5640
5343
                               TableList *tables,
5641
 
                               order_st *order,
 
5344
                               Order *order,
5642
5345
                               List<Item> &fields,
5643
5346
                               List<Item> &all_fields,
5644
5347
                               bool is_group_field)
5660
5363
    if (!count || count > fields.elements)
5661
5364
    {
5662
5365
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5663
 
               order_item->full_name(), session->where);
 
5366
               order_item->full_name(), session->where());
5664
5367
      return true;
5665
5368
    }
5666
5369
    order->item= ref_pointer_array + count - 1;
5670
5373
    return false;
5671
5374
  }
5672
5375
  /* Lookup the current GROUP/order_st field in the SELECT clause. */
5673
 
  select_item= find_item_in_list(order_item, fields, &counter,
 
5376
  select_item= find_item_in_list(session, order_item, fields, &counter,
5674
5377
                                 REPORT_EXCEPT_NOT_FOUND, &resolution);
5675
5378
  if (!select_item)
5676
5379
    return true; /* The item is not unique, or some other error occured. */
5737
5440
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5738
5441
                          ER(ER_NON_UNIQ_ERROR),
5739
5442
                          ((Item_ident*) order_item)->field_name,
5740
 
                          current_session->where);
 
5443
                          session->where());
5741
5444
    }
5742
5445
  }
5743
5446
 
5777
5480
                TableList *tables,
5778
5481
                            List<Item> &fields,
5779
5482
                List<Item> &all_fields,
5780
 
                order_st *order)
 
5483
                Order *order)
5781
5484
{
5782
 
  session->where="order clause";
 
5485
  session->setWhere("order clause");
5783
5486
  for (; order; order=order->next)
5784
5487
  {
5785
5488
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5819
5522
                TableList *tables,
5820
5523
                      List<Item> &fields,
5821
5524
                List<Item> &all_fields,
5822
 
                order_st *order,
 
5525
                Order *order,
5823
5526
                      bool *hidden_group_fields)
5824
5527
{
5825
5528
  *hidden_group_fields=0;
5826
 
  order_st *ord;
 
5529
  Order *ord;
5827
5530
 
5828
5531
  if (!order)
5829
5532
    return 0;                           /* Everything is ok */
5830
5533
 
5831
5534
  uint32_t org_fields=all_fields.elements;
5832
5535
 
5833
 
  session->where="group statement";
 
5536
  session->setWhere("group statement");
5834
5537
  for (ord= order; ord; ord= ord->next)
5835
5538
  {
5836
5539
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5913
5616
  Try to use the fields in the order given by 'order' to allow one to
5914
5617
  optimize away 'order by'.
5915
5618
*/
5916
 
order_st *create_distinct_group(Session *session,
 
5619
Order *create_distinct_group(Session *session,
5917
5620
                                Item **ref_pointer_array,
5918
 
                                order_st *order_list,
 
5621
                                Order *order_list,
5919
5622
                                List<Item> &fields,
5920
5623
                                List<Item> &,
5921
5624
                                bool *all_order_by_fields_used)
5922
5625
{
5923
5626
  List_iterator<Item> li(fields);
5924
5627
  Item *item;
5925
 
  order_st *order,*group,**prev;
 
5628
  Order *order,*group,**prev;
5926
5629
 
5927
5630
  *all_order_by_fields_used= 1;
5928
5631
  while ((item=li++))
5933
5636
  {
5934
5637
    if (order->in_field_list)
5935
5638
    {
5936
 
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
 
5639
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5937
5640
      if (!ord)
5938
5641
        return 0;
5939
5642
      *prev=ord;
5953
5656
        Don't put duplicate columns from the SELECT list into the
5954
5657
        GROUP BY list.
5955
5658
      */
5956
 
      order_st *ord_iter;
 
5659
      Order *ord_iter;
5957
5660
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5958
5661
        if ((*ord_iter->item)->eq(item, 1))
5959
5662
          goto next_item;
5960
5663
 
5961
 
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
 
5664
      Order *ord=(Order*) session->calloc(sizeof(Order));
5962
5665
      if (!ord)
5963
5666
        return 0;
5964
5667
 
6145
5848
          saved value
6146
5849
        */
6147
5850
        field= item->field;
6148
 
        item->result_field=field->new_field(session->mem_root,field->table, 1);
 
5851
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
6149
5852
              /*
6150
5853
                We need to allocate one extra byte for null handling and
6151
5854
                another extra byte to not get warnings from purify in
6157
5860
        {
6158
5861
          copy->set(tmp, item->result_field);
6159
5862
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
6160
 
#ifdef HAVE_purify
 
5863
#ifdef HAVE_VALGRIND
6161
5864
          copy->to_ptr[copy->from_length]= 0;
6162
5865
#endif
6163
5866
          copy++;
6278
5981
      }
6279
5982
      else if ((field= item->get_tmp_table_field()))
6280
5983
      {
6281
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
 
5984
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
6282
5985
          item_field= ((Item_sum*) item)->result_item(field);
6283
5986
        else
6284
5987
          item_field= (Item*) new Item_field(field);
6430
6133
}
6431
6134
 
6432
6135
/** Copy result of functions to record in tmp_table. */
6433
 
void copy_funcs(Item **func_ptr)
 
6136
bool copy_funcs(Item **func_ptr, const Session *session)
6434
6137
{
6435
6138
  Item *func;
6436
6139
  for (; (func = *func_ptr) ; func_ptr++)
 
6140
  {
6437
6141
    func->save_in_result_field(1);
 
6142
    /*
 
6143
      Need to check the THD error state because Item::val_xxx() don't
 
6144
      return error code, but can generate errors
 
6145
      TODO: change it for a real status check when Item::val_xxx()
 
6146
      are extended to return status code.
 
6147
    */
 
6148
    if (session->is_error())
 
6149
      return true;
 
6150
  }
 
6151
  return false;
6438
6152
}
6439
6153
 
6440
6154
/**
6494
6208
  @retval
6495
6209
    1   on error
6496
6210
*/
6497
 
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
 
6211
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
6498
6212
{
6499
6213
  if (expr->arg_count)
6500
6214
  {
6508
6222
      Item *item= *arg;
6509
6223
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6510
6224
      {
6511
 
        order_st *group_tmp;
 
6225
        Order *group_tmp;
6512
6226
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6513
6227
        {
6514
6228
          if (item->eq(*group_tmp->item,0))
6591
6305
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6592
6306
{
6593
6307
  /* QQ: session may not be set for sub queries, but this should be fixed */
6594
 
  if (!session)
 
6308
  if(not session)
6595
6309
    session= current_session;
6596
6310
 
 
6311
 
6597
6312
  str->append(STRING_WITH_LEN("select "));
6598
6313
 
6599
6314
  /* First add options */
6659
6374
  if (group_list.elements)
6660
6375
  {
6661
6376
    str->append(STRING_WITH_LEN(" group by "));
6662
 
    print_order(str, (order_st *) group_list.first, query_type);
 
6377
    print_order(str, (Order *) group_list.first, query_type);
6663
6378
    switch (olap)
6664
6379
    {
6665
6380
      case CUBE_TYPE:
6690
6405
  if (order_list.elements)
6691
6406
  {
6692
6407
    str->append(STRING_WITH_LEN(" order by "));
6693
 
    print_order(str, (order_st *) order_list.first, query_type);
 
6408
    print_order(str, (Order *) order_list.first, query_type);
6694
6409
  }
6695
6410
 
6696
6411
  // limit