~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2010-12-30 04:59:36 UTC
  • mto: (2040.1.2 clean) (2041.2.1 clean)
  • mto: This revision was merged to the branch mainline in revision 2041.
  • Revision ID: brian@tangent.org-20101230045936-r1i4sek9qotl8abq
result_type() to display the internal type.

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
  @{
38
38
#include "drizzled/nested_join.h"
39
39
#include "drizzled/probes.h"
40
40
#include "drizzled/show.h"
41
 
#include "drizzled/plugin/info_schema_table.h"
42
41
#include "drizzled/item/cache.h"
43
42
#include "drizzled/item/cmpfunc.h"
44
43
#include "drizzled/item/copy_string.h"
50
49
#include "drizzled/lock.h"
51
50
#include "drizzled/item/outer_ref.h"
52
51
#include "drizzled/index_hint.h"
53
 
#include "drizzled/memory/multi_malloc.h"
54
52
#include "drizzled/records.h"
55
53
#include "drizzled/internal/iocache.h"
 
54
#include "drizzled/drizzled.h"
56
55
 
57
56
#include "drizzled/sql_union.h"
58
57
#include "drizzled/optimizer/key_field.h"
63
62
#include "drizzled/optimizer/quick_range_select.h"
64
63
#include "drizzled/optimizer/quick_ror_intersect_select.h"
65
64
 
 
65
#include "drizzled/filesort.h"
 
66
 
66
67
using namespace std;
67
68
 
68
69
namespace drizzled
116
117
{
117
118
  bool res;
118
119
  register Select_Lex *select_lex= &lex->select_lex;
119
 
  DRIZZLE_SELECT_START(session->query.c_str());
 
120
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
120
121
 
121
122
  if (select_lex->master_unit()->is_union() ||
122
123
      select_lex->master_unit()->fake_select_lex)
 
124
  {
123
125
    res= drizzle_union(session, lex, result, &lex->unit,
124
126
                       setup_tables_done_option);
 
127
  }
125
128
  else
126
129
  {
127
130
    Select_Lex_Unit *unit= &lex->unit;
128
131
    unit->set_limit(unit->global_parameters);
129
132
    session->session_marker= 0;
130
133
    /*
131
 
      '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
132
135
      every PS/SP execution new, we will not need reset this flag if
133
136
      setup_tables_done_option changed for next rexecution
134
137
    */
135
 
    res= mysql_select(session, &select_lex->ref_pointer_array,
 
138
    res= select_query(session,
 
139
                      &select_lex->ref_pointer_array,
136
140
                      (TableList*) select_lex->table_list.first,
137
 
                      select_lex->with_wild, select_lex->item_list,
 
141
                      select_lex->with_wild,
 
142
                      select_lex->item_list,
138
143
                      select_lex->where,
139
144
                      select_lex->order_list.elements +
140
145
                      select_lex->group_list.elements,
141
 
                      (order_st*) select_lex->order_list.first,
142
 
                      (order_st*) select_lex->group_list.first,
 
146
                      (Order*) select_lex->order_list.first,
 
147
                      (Order*) select_lex->group_list.first,
143
148
                      select_lex->having,
144
149
                      select_lex->options | session->options |
145
150
                      setup_tables_done_option,
265
270
 
266
271
/*****************************************************************************
267
272
  Check fields, find best join, do the select and output fields.
268
 
  mysql_select assumes that all tables are already opened
 
273
  select_query assumes that all tables are already opened
269
274
*****************************************************************************/
270
275
 
271
276
/*
345
350
  @retval
346
351
    true   an error
347
352
*/
348
 
bool mysql_select(Session *session,
 
353
bool select_query(Session *session,
349
354
                  Item ***rref_pointer_array,
350
355
                  TableList *tables, 
351
356
                  uint32_t wild_num, 
352
357
                  List<Item> &fields,
353
358
                  COND *conds, 
354
359
                  uint32_t og_num,  
355
 
                  order_st *order, 
356
 
                  order_st *group,
 
360
                  Order *order,
 
361
                  Order *group,
357
362
                  Item *having, 
358
363
                  uint64_t select_options,
359
364
                  select_result *result, 
364
369
  bool free_join= 1;
365
370
 
366
371
  select_lex->context.resolve_in_select_list= true;
367
 
  JOIN *join;
 
372
  Join *join;
368
373
  if (select_lex->join != 0)
369
374
  {
370
375
    join= select_lex->join;
397
402
  }
398
403
  else
399
404
  {
400
 
    if (!(join= new JOIN(session, fields, select_options, result)))
 
405
    if (!(join= new Join(session, fields, select_options, result)))
401
406
      return(true);
402
407
    session->set_proc_info("init");
403
408
    session->used_tables=0;                         // Updated by setup_fields
447
452
  return (cond? (new Item_cond_and(cond, item)) : item);
448
453
}
449
454
 
450
 
static void fix_list_after_tbl_changes(Select_Lex *new_parent, List<TableList> *tlist)
451
 
{
452
 
  List_iterator<TableList> it(*tlist);
453
 
  TableList *table;
454
 
  while ((table= it++))
455
 
  {
456
 
    if (table->on_expr)
457
 
      table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
458
 
    if (table->nested_join)
459
 
      fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
460
 
  }
461
 
}
462
 
 
463
455
/*****************************************************************************
464
456
  Create JoinTableS, make a guess about the table types,
465
457
  Approximate how many records will be used in each table
555
547
                         Select_Lex *select_lex,
556
548
                         vector<optimizer::SargableParam> &sargables)
557
549
{
558
 
  uint  and_level,i,found_eq_constant;
 
550
  uint  and_level,found_eq_constant;
559
551
  optimizer::KeyField *key_fields, *end, *field;
560
552
  uint32_t sz;
561
553
  uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
578
570
    substitutions.
579
571
  */
580
572
  sz= sizeof(optimizer::KeyField) *
581
 
      (((session->lex->current_select->cond_count+1) +
 
573
      (((session->lex->current_select->cond_count+1)*2 +
582
574
        session->lex->current_select->between_count)*m+1);
583
575
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
584
576
    return true;
598
590
      if (field->getValue()->type() == Item::NULL_ITEM &&
599
591
          ! field->getField()->real_maybe_null())
600
592
      {
601
 
        field->getField()->table->reginfo.not_exists_optimize= 1;
 
593
        field->getField()->getTable()->reginfo.not_exists_optimize= 1;
602
594
      }
603
595
    }
604
596
  }
605
 
  for (i= 0; i < tables; i++)
 
597
  for (uint32_t i= 0; i < tables; i++)
606
598
  {
607
599
    /*
608
600
      Block the creation of keys for inner tables of outer joins.
625
617
    TableList *table;
626
618
    while ((table= li++))
627
619
    {
628
 
      if (table->nested_join)
 
620
      if (table->getNestedJoin())
629
621
        add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
630
622
                              sargables);
631
623
    }
657
649
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
658
650
    prev= &key_end;
659
651
    found_eq_constant= 0;
660
 
    for (i= 0; i < keyuse->elements-1; i++, use++)
661
652
    {
662
 
      if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
663
 
        use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
664
 
      if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
 
653
      uint32_t i;
 
654
 
 
655
      for (i= 0; i < keyuse->elements-1; i++, use++)
665
656
      {
666
 
        if (prev->getKeypart() + 1 < use->getKeypart() || 
667
 
            ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
668
 
          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++;
669
680
      }
670
 
      else if (use->getKeypart() != 0)          // First found must be 0
671
 
        continue;
672
 
 
673
 
#ifdef HAVE_purify
674
 
      /* Valgrind complains about overlapped memcpy when save_pos==use. */
675
 
      if (save_pos != use)
676
 
#endif
677
 
        *save_pos= *use;
678
 
      prev=use;
679
 
      found_eq_constant= ! use->getUsedTables();
680
 
      /* Save ptr to first use */
681
 
      if (! use->getTable()->reginfo.join_tab->keyuse)
682
 
        use->getTable()->reginfo.join_tab->keyuse= save_pos;
683
 
      use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
684
 
      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;
685
684
    }
686
 
    i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
687
 
    set_dynamic(keyuse, (unsigned char*) &key_end, i);
688
 
    keyuse->elements= i;
689
685
  }
690
686
  return false;
691
687
}
693
689
/**
694
690
  Update some values in keyuse for faster choose_plan() loop.
695
691
*/
696
 
void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
 
692
void optimize_keyuse(Join *join, DYNAMIC_ARRAY *keyuse_array)
697
693
{
698
694
  optimizer::KeyUse *end,*keyuse= dynamic_element(keyuse_array, 
699
695
                                                  0, 
748
744
  @return
749
745
    None
750
746
*/
751
 
void add_group_and_distinct_keys(JOIN *join, JoinTable *join_tab)
 
747
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
752
748
{
753
749
  List<Item_field> indexed_fields;
754
750
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
755
 
  order_st      *cur_group;
 
751
  Order      *cur_group;
756
752
  Item_field *cur_item;
757
753
  key_map possible_keys(0);
758
754
 
853
849
  Field **f_ptr,*field;
854
850
 
855
851
  null_fields= blobs= fields= rec_length=0;
856
 
  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++)
857
853
  {
858
854
    if (field->isReadSet())
859
855
    {
884
880
StoredKey *get_store_key(Session *session,
885
881
                         optimizer::KeyUse *keyuse,
886
882
                         table_map used_tables,
887
 
                         KEY_PART_INFO *key_part,
 
883
                         KeyPartInfo *key_part,
888
884
                         unsigned char *key_buff,
889
885
                         uint32_t maybe_null)
890
886
{
929
925
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
930
926
{
931
927
  bool error;
932
 
  Table *table= field->table;
 
928
  Table *table= field->getTable();
933
929
  Session *session= table->in_use;
934
930
  ha_rows cuted_fields=session->cuted_fields;
935
931
 
936
932
  /*
937
933
    we should restore old value of count_cuted_fields because
938
 
    store_val_in_field can be called from mysql_insert
 
934
    store_val_in_field can be called from insert_query
939
935
    with select_insert, which make count_cuted_fields= 1
940
936
   */
941
937
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
960
956
    *e1= e2;
961
957
}
962
958
 
963
 
bool create_ref_for_key(JOIN *join, 
 
959
bool create_ref_for_key(Join *join, 
964
960
                        JoinTable *j, 
965
961
                        optimizer::KeyUse *org_keyuse,
966
962
                        table_map used_tables)
971
967
  uint32_t length;
972
968
  uint32_t key;
973
969
  Table *table= NULL;
974
 
  KEY *keyinfo= NULL;
 
970
  KeyInfo *keyinfo= NULL;
975
971
 
976
972
  /*  Use best key from find_best */
977
973
  table= j->table;
1138
1134
      3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
1139
1135
         appropiate JoinTable members.
1140
1136
*/
1141
 
void add_not_null_conds(JOIN *join)
 
1137
void add_not_null_conds(Join *join)
1142
1138
{
1143
1139
  for (uint32_t i= join->const_tables; i < join->tables; i++)
1144
1140
  {
1155
1151
          Item *notnull;
1156
1152
          assert(item->type() == Item::FIELD_ITEM);
1157
1153
          Item_field *not_null_item= (Item_field*)item;
1158
 
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
 
1154
          JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
1159
1155
          /*
1160
1156
            For UPDATE queries such as:
1161
1157
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
1212
1208
  return tmp;
1213
1209
}
1214
1210
 
1215
 
/*
1216
 
  Check if given expression uses only table fields covered by the given index
1217
 
 
1218
 
  SYNOPSIS
1219
 
    uses_index_fields_only()
1220
 
      item           Expression to check
1221
 
      tbl            The table having the index
1222
 
      keyno          The index number
1223
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1224
 
 
1225
 
  DESCRIPTION
1226
 
    Check if given expression only uses fields covered by index #keyno in the
1227
 
    table tbl. The expression can use any fields in any other tables.
1228
 
 
1229
 
    The expression is guaranteed not to be AND or OR - those constructs are
1230
 
    handled outside of this function.
1231
 
 
1232
 
  RETURN
1233
 
    true   Yes
1234
 
    false  No
1235
 
*/
1236
 
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
1237
 
{
1238
 
  if (item->const_item())
1239
 
    return true;
1240
 
 
1241
 
  /*
1242
 
    Don't push down the triggered conditions. Nested outer joins execution
1243
 
    code may need to evaluate a condition several times (both triggered and
1244
 
    untriggered), and there is no way to put thi
1245
 
    TODO: Consider cloning the triggered condition and using the copies for:
1246
 
      1. push the first copy down, to have most restrictive index condition
1247
 
         possible
1248
 
      2. Put the second copy into tab->select_cond.
1249
 
  */
1250
 
  if (item->type() == Item::FUNC_ITEM &&
1251
 
      ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
1252
 
    return false;
1253
 
 
1254
 
  if (!(item->used_tables() & tbl->map))
1255
 
    return other_tbls_ok;
1256
 
 
1257
 
  Item::Type item_type= item->type();
1258
 
  switch (item_type) {
1259
 
  case Item::FUNC_ITEM:
1260
 
    {
1261
 
      /* This is a function, apply condition recursively to arguments */
1262
 
      Item_func *item_func= (Item_func*)item;
1263
 
      Item **child;
1264
 
      Item **item_end= (item_func->arguments()) + item_func->argument_count();
1265
 
      for (child= item_func->arguments(); child != item_end; child++)
1266
 
      {
1267
 
        if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
1268
 
          return false;
1269
 
      }
1270
 
      return true;
1271
 
    }
1272
 
  case Item::COND_ITEM:
1273
 
    {
1274
 
      /* This is a function, apply condition recursively to arguments */
1275
 
      List_iterator<Item> li(*((Item_cond*)item)->argument_list());
1276
 
      Item *list_item;
1277
 
      while ((list_item=li++))
1278
 
      {
1279
 
        if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
1280
 
          return false;
1281
 
      }
1282
 
      return true;
1283
 
    }
1284
 
  case Item::FIELD_ITEM:
1285
 
    {
1286
 
      Item_field *item_field= (Item_field*)item;
1287
 
      if (item_field->field->table != tbl)
1288
 
        return true;
1289
 
      return item_field->field->part_of_key.test(keyno);
1290
 
    }
1291
 
  case Item::REF_ITEM:
1292
 
    return uses_index_fields_only(item->real_item(), tbl, keyno,
1293
 
                                  other_tbls_ok);
1294
 
  default:
1295
 
    return false; /* Play it safe, don't push unknown non-const items */
1296
 
  }
1297
 
}
1298
 
 
1299
1211
#define ICP_COND_USES_INDEX_ONLY 10
1300
1212
 
1301
 
/*
1302
 
  Get a part of the condition that can be checked using only index fields
1303
 
 
1304
 
  SYNOPSIS
1305
 
    make_cond_for_index()
1306
 
      cond           The source condition
1307
 
      table          The table that is partially available
1308
 
      keyno          The index in the above table. Only fields covered by the index
1309
 
                     are available
1310
 
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
1311
 
 
1312
 
  DESCRIPTION
1313
 
    Get a part of the condition that can be checked when for the given table
1314
 
    we have values only of fields covered by some index. The condition may
1315
 
    refer to other tables, it is assumed that we have values of all of their
1316
 
    fields.
1317
 
 
1318
 
    Example:
1319
 
      make_cond_for_index(
1320
 
         "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
1321
 
          t2, keyno(t2.key1))
1322
 
      will return
1323
 
        "cond(t1.field) AND cond(t2.key2)"
1324
 
 
1325
 
  RETURN
1326
 
    Index condition, or NULL if no condition could be inferred.
1327
 
*/
1328
 
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
1329
 
{
1330
 
  if (!cond)
1331
 
    return NULL;
1332
 
  if (cond->type() == Item::COND_ITEM)
1333
 
  {
1334
 
    uint32_t n_marked= 0;
1335
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1336
 
    {
1337
 
      Item_cond_and *new_cond=new Item_cond_and;
1338
 
      if (!new_cond)
1339
 
        return (COND*) 0;
1340
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1341
 
      Item *item;
1342
 
      while ((item=li++))
1343
 
      {
1344
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1345
 
        if (fix)
1346
 
          new_cond->argument_list()->push_back(fix);
1347
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1348
 
      }
1349
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1350
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1351
 
      switch (new_cond->argument_list()->elements) {
1352
 
      case 0:
1353
 
        return (COND*) 0;
1354
 
      case 1:
1355
 
        return new_cond->argument_list()->head();
1356
 
      default:
1357
 
        new_cond->quick_fix_field();
1358
 
        return new_cond;
1359
 
      }
1360
 
    }
1361
 
    else /* It's OR */
1362
 
    {
1363
 
      Item_cond_or *new_cond=new Item_cond_or;
1364
 
      if (!new_cond)
1365
 
        return (COND*) 0;
1366
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1367
 
      Item *item;
1368
 
      while ((item=li++))
1369
 
      {
1370
 
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
1371
 
        if (!fix)
1372
 
          return (COND*) 0;
1373
 
        new_cond->argument_list()->push_back(fix);
1374
 
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
1375
 
      }
1376
 
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
1377
 
        cond->marker= ICP_COND_USES_INDEX_ONLY;
1378
 
      new_cond->quick_fix_field();
1379
 
      new_cond->top_level_item();
1380
 
      return new_cond;
1381
 
    }
1382
 
  }
1383
 
 
1384
 
  if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
1385
 
    return (COND*) 0;
1386
 
  cond->marker= ICP_COND_USES_INDEX_ONLY;
1387
 
  return cond;
1388
 
}
1389
 
 
1390
 
 
1391
 
static Item *make_cond_remainder(Item *cond, bool exclude_index)
1392
 
{
1393
 
  if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
1394
 
    return 0; /* Already checked */
1395
 
 
1396
 
  if (cond->type() == Item::COND_ITEM)
1397
 
  {
1398
 
    table_map tbl_map= 0;
1399
 
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
1400
 
    {
1401
 
      /* Create new top level AND item */
1402
 
      Item_cond_and *new_cond=new Item_cond_and;
1403
 
      if (!new_cond)
1404
 
        return (COND*) 0;
1405
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1406
 
      Item *item;
1407
 
      while ((item=li++))
1408
 
      {
1409
 
        Item *fix= make_cond_remainder(item, exclude_index);
1410
 
        if (fix)
1411
 
        {
1412
 
          new_cond->argument_list()->push_back(fix);
1413
 
          tbl_map |= fix->used_tables();
1414
 
        }
1415
 
      }
1416
 
      switch (new_cond->argument_list()->elements) {
1417
 
      case 0:
1418
 
        return (COND*) 0;
1419
 
      case 1:
1420
 
        return new_cond->argument_list()->head();
1421
 
      default:
1422
 
        new_cond->quick_fix_field();
1423
 
        ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1424
 
        return new_cond;
1425
 
      }
1426
 
    }
1427
 
    else /* It's OR */
1428
 
    {
1429
 
      Item_cond_or *new_cond=new Item_cond_or;
1430
 
      if (!new_cond)
1431
 
        return (COND*) 0;
1432
 
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
1433
 
      Item *item;
1434
 
      while ((item=li++))
1435
 
      {
1436
 
        Item *fix= make_cond_remainder(item, false);
1437
 
        if (!fix)
1438
 
          return (COND*) 0;
1439
 
        new_cond->argument_list()->push_back(fix);
1440
 
        tbl_map |= fix->used_tables();
1441
 
      }
1442
 
      new_cond->quick_fix_field();
1443
 
      ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
1444
 
      new_cond->top_level_item();
1445
 
      return new_cond;
1446
 
    }
1447
 
  }
1448
 
  return cond;
1449
 
}
1450
1213
 
1451
1214
/**
1452
1215
  cleanup JoinTable.
1458
1221
  delete quick;
1459
1222
  quick= 0;
1460
1223
  if (cache.buff)
 
1224
  {
 
1225
    size_t size= cache.end - cache.buff;
 
1226
    global_join_buffer.sub(size);
1461
1227
    free(cache.buff);
 
1228
  }
1462
1229
  cache.buff= 0;
1463
1230
  limit= 0;
1464
1231
  if (table)
1475
1242
    */
1476
1243
    table->reginfo.join_tab= 0;
1477
1244
  }
1478
 
  end_read_record(&read_record);
 
1245
  read_record.end_read_record();
1479
1246
}
1480
1247
 
1481
 
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)
1482
1249
{
1483
1250
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1484
1251
  {
1507
1274
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
1508
1275
  @endcode
1509
1276
*/
1510
 
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab)
 
1277
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
1511
1278
{
1512
1279
  if (tab->cached_eq_ref_table)                 // If cached
1513
1280
    return tab->eq_ref_table;
1526
1293
  {
1527
1294
    if (! (*ref_item)->const_item())
1528
1295
    {                                           // Not a const ref
1529
 
      order_st *order;
 
1296
      Order *order;
1530
1297
      for (order=start_order ; order ; order=order->next)
1531
1298
      {
1532
1299
        if ((*ref_item)->eq(order->item[0],0))
2266
2033
    {
2267
2034
      if (table->on_expr)
2268
2035
      {
2269
 
        List<TableList> *nested_join_list= table->nested_join ?
2270
 
          &table->nested_join->join_list : NULL;
 
2036
        List<TableList> *nested_join_list= table->getNestedJoin() ?
 
2037
          &table->getNestedJoin()->join_list : NULL;
2271
2038
        /*
2272
2039
          We can modify table->on_expr because its old value will
2273
2040
          be restored before re-execution of PS/SP.
2320
2087
  if (outer_ref)
2321
2088
    return cmp;
2322
2089
  JoinTable **idx= (JoinTable **) table_join_idx;
2323
 
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
 
2090
  cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
2324
2091
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
2325
2092
}
2326
2093
 
2567
2334
      while ((item_field= it++))
2568
2335
      {
2569
2336
        Field *field= item_field->field;
2570
 
        JoinTable *stat= field->table->reginfo.join_tab;
 
2337
        JoinTable *stat= field->getTable()->reginfo.join_tab;
2571
2338
        key_map possible_keys= field->key_start;
2572
 
        possible_keys&= field->table->keys_in_use_for_query;
 
2339
        possible_keys&= field->getTable()->keys_in_use_for_query;
2573
2340
        stat[0].const_keys|= possible_keys;
2574
2341
 
2575
2342
        /*
2579
2346
        */
2580
2347
        if (possible_keys.any())
2581
2348
        {
2582
 
          Table *field_tab= field->table;
 
2349
          Table *field_tab= field->getTable();
2583
2350
          optimizer::KeyUse *use;
2584
2351
          for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
2585
2352
            if (possible_keys.test(use->getKey()) &&
2610
2377
    Item *item;
2611
2378
    while ((item=li++))
2612
2379
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
 
2380
 
2613
2381
    return;
2614
2382
  }
2615
2383
  if (cond->eq_cmp_result() == Item::COND_OK)
2628
2396
       left_item->collation.collation == value->collation.collation))
2629
2397
  {
2630
2398
    Item *tmp=value->clone_item();
2631
 
    tmp->collation.set(right_item->collation);
2632
 
 
2633
2399
    if (tmp)
2634
2400
    {
 
2401
      tmp->collation.set(right_item->collation);
2635
2402
      session->change_item_tree(args + 1, tmp);
2636
2403
      func->update_used_tables();
2637
2404
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2651
2418
            right_item->collation.collation == value->collation.collation))
2652
2419
  {
2653
2420
    Item *tmp= value->clone_item();
2654
 
    tmp->collation.set(left_item->collation);
2655
 
 
2656
2421
    if (tmp)
2657
2422
    {
 
2423
      tmp->collation.set(left_item->collation);
2658
2424
      session->change_item_tree(args, tmp);
2659
2425
      value= tmp;
2660
2426
      func->update_used_tables();
2724
2490
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2725
2491
      {
2726
2492
        Item **args= iter->cmp_func->arguments();
2727
 
        if (!args[0]->const_item())
 
2493
        if (not args[0]->const_item())
2728
2494
        {
2729
 
          change_cond_ref_to_const( session, save, iter->and_level,
2730
 
                                    iter->and_level, args[0], args[1] );
 
2495
          change_cond_ref_to_const(session, save_list, iter->and_level,
 
2496
                                   iter->and_level, args[0], args[1] );
2731
2497
        }
2732
2498
      }
2733
2499
    }
2846
2612
  @endverbatim
2847
2613
 
2848
2614
  @param join       Join being processed
2849
 
  @param last_tab   Last table in current partial join order (this function is
2850
 
                    not called for empty partial join orders)
2851
2615
  @param next_tab   Table we're going to extend the current partial join with
2852
2616
 
2853
2617
  @retval
2856
2620
  @retval
2857
2621
    true   Requested join order extension not allowed.
2858
2622
*/
2859
 
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
 
2623
bool check_interleaving_with_nj(JoinTable *next_tab)
2860
2624
{
2861
 
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
2862
 
  JOIN *join= last_tab->join;
 
2625
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
 
2626
  Join *join= next_tab->join;
2863
2627
 
2864
2628
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2865
2629
  {
2874
2638
    Do update counters for "pairs of brackets" that we've left (marked as
2875
2639
    X,Y,Z in the above picture)
2876
2640
  */
2877
 
  for (;next_emb; next_emb= next_emb->embedding)
 
2641
  for (;next_emb; next_emb= next_emb->getEmbedding())
2878
2642
  {
2879
 
    next_emb->nested_join->counter_++;
2880
 
    if (next_emb->nested_join->counter_ == 1)
 
2643
    next_emb->getNestedJoin()->counter_++;
 
2644
    if (next_emb->getNestedJoin()->counter_ == 1)
2881
2645
    {
2882
2646
      /*
2883
2647
        next_emb is the first table inside a nested join we've "entered". In
2884
2648
        the picture above, we're looking at the 'X' bracket. Don't exit yet as
2885
2649
        X bracket might have Y pair bracket.
2886
2650
      */
2887
 
      join->cur_embedding_map |= next_emb->nested_join->nj_map;
 
2651
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
2888
2652
    }
2889
2653
 
2890
 
    if (next_emb->nested_join->join_list.elements !=
2891
 
        next_emb->nested_join->counter_)
 
2654
    if (next_emb->getNestedJoin()->join_list.elements !=
 
2655
        next_emb->getNestedJoin()->counter_)
2892
2656
      break;
2893
2657
 
2894
2658
    /*
2895
2659
      We're currently at Y or Z-bracket as depicted in the above picture.
2896
2660
      Mark that we've left it and continue walking up the brackets hierarchy.
2897
2661
    */
2898
 
    join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
 
2662
    join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
2899
2663
  }
2900
2664
  return false;
2901
2665
}
2902
2666
 
2903
 
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)
2904
2668
{
2905
2669
  Session *session= join->session;
2906
2670
 
3023
2787
    {
3024
2788
      Field *field= ((Item_field*) args[0])->field;
3025
2789
      if (field->flags & AUTO_INCREMENT_FLAG 
3026
 
          && ! field->table->maybe_null 
 
2790
          && ! field->getTable()->maybe_null 
3027
2791
          && session->options & OPTION_AUTO_IS_NULL
3028
2792
          && (
3029
2793
            session->first_successful_insert_id_in_prev_stmt > 0 
3081
2845
  /*
3082
2846
    TODO:
3083
2847
    Excluding all expensive functions is too restritive we should exclude only
3084
 
    materialized IN because it is created later than this phase, and cannot be
3085
 
    evaluated at this point.
3086
 
    The condition should be something as (need to fix member access):
3087
 
      !(cond->type() == Item::FUNC_ITEM &&
3088
 
        ((Item_func*)cond)->func_name() == "<in_optimizer>" &&
3089
 
        ((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
 
3090
2854
  */
3091
2855
  {
3092
2856
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
3209
2973
  @return
3210
2974
    end_select function to use. This function can't fail.
3211
2975
*/
3212
 
Next_select_func setup_end_select_func(JOIN *join)
 
2976
Next_select_func setup_end_select_func(Join *join)
3213
2977
{
3214
2978
  Table *table= join->tmp_table;
3215
2979
  Tmp_Table_Param *tmp_tbl= &join->tmp_table_param;
3221
2985
    if (table->group && tmp_tbl->sum_func_count &&
3222
2986
        !tmp_tbl->precomputed_group_by)
3223
2987
    {
3224
 
      if (table->s->keys)
 
2988
      if (table->getShare()->sizeKeys())
3225
2989
      {
3226
2990
        end_select= end_update;
3227
2991
      }
3232
2996
    }
3233
2997
    else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
3234
2998
    {
3235
 
      end_select=end_write_group;
 
2999
      end_select= end_write_group;
3236
3000
    }
3237
3001
    else
3238
3002
    {
3239
 
      end_select=end_write;
 
3003
      end_select= end_write;
3240
3004
      if (tmp_tbl->precomputed_group_by)
3241
3005
      {
3242
3006
        /*
3274
3038
  @retval
3275
3039
    -1  if error should be sent
3276
3040
*/
3277
 
int do_select(JOIN *join, List<Item> *fields, Table *table)
 
3041
int do_select(Join *join, List<Item> *fields, Table *table)
3278
3042
{
3279
3043
  int rc= 0;
3280
3044
  enum_nested_loop_state error= NESTED_LOOP_OK;
3288
3052
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
3289
3053
    table->emptyRecord();
3290
3054
    if (table->group && join->tmp_table_param.sum_func_count &&
3291
 
        table->s->keys && !table->cursor->inited)
3292
 
      table->cursor->ha_index_init(0, 0);
 
3055
        table->getShare()->sizeKeys() && !table->cursor->inited)
 
3056
      table->cursor->startIndexScan(0, 0);
3293
3057
  }
3294
3058
  /* Set up select_end */
3295
3059
  Next_select_func end_select= setup_end_select_func(join);
3375
3139
  return(join->session->is_error() ? -1 : rc);
3376
3140
}
3377
3141
 
3378
 
enum_nested_loop_state sub_select_cache(JOIN *join, JoinTable *join_tab, bool end_of_records)
 
3142
enum_nested_loop_state sub_select_cache(Join *join, JoinTable *join_tab, bool end_of_records)
3379
3143
{
3380
3144
  enum_nested_loop_state rc;
3381
3145
 
3386
3150
      rc= sub_select(join,join_tab,end_of_records);
3387
3151
    return rc;
3388
3152
  }
3389
 
  if (join->session->killed)            // If aborted by user
 
3153
  if (join->session->getKilled())               // If aborted by user
3390
3154
  {
3391
3155
    join->session->send_kill_message();
3392
3156
    return NESTED_LOOP_KILLED;
3393
3157
  }
3394
3158
  if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
3395
3159
  {
3396
 
    if (! store_record_in_cache(&join_tab->cache))
 
3160
    if (! join_tab->cache.store_record_in_cache())
3397
3161
      return NESTED_LOOP_OK;                     // There is more room in cache
3398
3162
    return flush_cached_records(join,join_tab,false);
3399
3163
  }
3522
3286
  @return
3523
3287
    return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
3524
3288
*/
3525
 
enum_nested_loop_state sub_select(JOIN *join, JoinTable *join_tab, bool end_of_records)
 
3289
enum_nested_loop_state sub_select(Join *join, JoinTable *join_tab, bool end_of_records)
3526
3290
{
3527
3291
  join_tab->table->null_row=0;
3528
3292
  if (end_of_records)
3530
3294
 
3531
3295
  int error;
3532
3296
  enum_nested_loop_state rc;
3533
 
  READ_RECORD *info= &join_tab->read_record;
 
3297
  ReadRecord *info= &join_tab->read_record;
3534
3298
 
3535
3299
  if (join->resume_nested_loop)
3536
3300
  {
3587
3351
{
3588
3352
  int error;
3589
3353
  Table *table= tab->table;
3590
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3354
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
3591
3355
                                         tab->ref.key_buff,
3592
3356
                                         make_prev_keypart_map(tab->ref.key_parts),
3593
3357
                                         HA_READ_KEY_EXACT)))
3651
3415
    table->maybe_null=0;
3652
3416
 
3653
3417
  /* Check appearance of new constant items in Item_equal objects */
3654
 
  JOIN *join= tab->join;
 
3418
  Join *join= tab->join;
3655
3419
  if (join->conds)
3656
3420
    update_const_equal_items(join->conds, tab);
3657
3421
  TableList *tbl;
3664
3428
      embedded= embedding;
3665
3429
      if (embedded->on_expr)
3666
3430
         update_const_equal_items(embedded->on_expr, tab);
3667
 
      embedding= embedded->embedding;
 
3431
      embedding= embedded->getEmbedding();
3668
3432
    }
3669
3433
    while (embedding &&
3670
 
           embedding->nested_join->join_list.head() == embedded);
 
3434
           embedding->getNestedJoin()->join_list.head() == embedded);
3671
3435
  }
3672
3436
 
3673
3437
  return(0);
3679
3443
  int error;
3680
3444
  if (table->status & STATUS_GARBAGE)           // If first read
3681
3445
  {
3682
 
    if ((error=table->cursor->read_first_row(table->record[0],
3683
 
                                           table->s->primary_key)))
 
3446
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
 
3447
                                           table->getShare()->getPrimaryKey())))
3684
3448
    {
3685
3449
      if (error != HA_ERR_END_OF_FILE)
3686
3450
        return table->report_error(error);
3719
3483
      error= HA_ERR_KEY_NOT_FOUND;
3720
3484
    else
3721
3485
    {
3722
 
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
 
3486
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
3723
3487
                                            (unsigned char*) tab->ref.key_buff,
3724
3488
                                            make_prev_keypart_map(tab->ref.key_parts),
3725
3489
                                            HA_READ_KEY_EXACT);
3767
3531
 
3768
3532
  if (!table->cursor->inited)
3769
3533
  {
3770
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3534
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3771
3535
  }
3772
3536
 
3773
3537
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3779
3543
      table->status=STATUS_NOT_FOUND;
3780
3544
      return -1;
3781
3545
    }
3782
 
    error=table->cursor->index_read_map(table->record[0],
 
3546
    error=table->cursor->index_read_map(table->getInsertRecord(),
3783
3547
                                      tab->ref.key_buff,
3784
3548
                                      make_prev_keypart_map(tab->ref.key_parts),
3785
3549
                                      HA_READ_KEY_EXACT);
3815
3579
 
3816
3580
  /* Initialize the index first */
3817
3581
  if (!table->cursor->inited)
3818
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3582
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3819
3583
 
3820
3584
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3821
3585
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3826
3590
 
3827
3591
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3828
3592
    return -1;
3829
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3593
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
3830
3594
                                         tab->ref.key_buff,
3831
3595
                                         make_prev_keypart_map(tab->ref.key_parts),
3832
3596
                                         HA_READ_KEY_EXACT)))
3849
3613
  Table *table= tab->table;
3850
3614
 
3851
3615
  if (!table->cursor->inited)
3852
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3616
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3853
3617
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3854
3618
    return -1;
3855
 
  if ((error=table->cursor->index_read_last_map(table->record[0],
 
3619
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3856
3620
                                              tab->ref.key_buff,
3857
3621
                                              make_prev_keypart_map(tab->ref.key_parts))))
3858
3622
  {
3863
3627
  return 0;
3864
3628
}
3865
3629
 
3866
 
int join_no_more_records(READ_RECORD *)
 
3630
int join_no_more_records(ReadRecord *)
3867
3631
{
3868
3632
  return -1;
3869
3633
}
3870
3634
 
3871
 
int join_read_next_same_diff(READ_RECORD *info)
 
3635
int join_read_next_same_diff(ReadRecord *info)
3872
3636
{
3873
3637
  Table *table= info->table;
3874
3638
  JoinTable *tab=table->reginfo.join_tab;
3875
3639
  if (tab->insideout_match_tab->found_match)
3876
3640
  {
3877
 
    KEY *key= tab->table->key_info + tab->index;
 
3641
    KeyInfo *key= tab->table->key_info + tab->index;
3878
3642
    do
3879
3643
    {
3880
3644
      int error;
3881
3645
      /* Save index tuple from record to the buffer */
3882
3646
      key_copy(tab->insideout_buf, info->record, key, 0);
3883
3647
 
3884
 
      if ((error=table->cursor->index_next_same(table->record[0],
 
3648
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3885
3649
                                              tab->ref.key_buff,
3886
3650
                                              tab->ref.key_length)))
3887
3651
      {
3899
3663
    return join_read_next_same(info);
3900
3664
}
3901
3665
 
3902
 
int join_read_next_same(READ_RECORD *info)
 
3666
int join_read_next_same(ReadRecord *info)
3903
3667
{
3904
3668
  int error;
3905
3669
  Table *table= info->table;
3906
3670
  JoinTable *tab=table->reginfo.join_tab;
3907
3671
 
3908
 
  if ((error=table->cursor->index_next_same(table->record[0],
 
3672
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3909
3673
                                          tab->ref.key_buff,
3910
3674
                                          tab->ref.key_length)))
3911
3675
  {
3918
3682
  return 0;
3919
3683
}
3920
3684
 
3921
 
int join_read_prev_same(READ_RECORD *info)
 
3685
int join_read_prev_same(ReadRecord *info)
3922
3686
{
3923
3687
  int error;
3924
3688
  Table *table= info->table;
3925
3689
  JoinTable *tab=table->reginfo.join_tab;
3926
3690
 
3927
 
  if ((error=table->cursor->index_prev(table->record[0])))
 
3691
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
3928
3692
    return table->report_error(error);
3929
3693
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3930
3694
                      tab->ref.key_length))
3942
3706
  return join_init_read_record(tab);
3943
3707
}
3944
3708
 
3945
 
int rr_sequential(READ_RECORD *info);
3946
3709
int init_read_record_seq(JoinTable *tab)
3947
3710
{
3948
 
  tab->read_record.read_record= rr_sequential;
3949
 
  if (tab->read_record.cursor->ha_rnd_init(1))
 
3711
  tab->read_record.init_reard_record_sequential();
 
3712
 
 
3713
  if (tab->read_record.cursor->startTableScan(1))
3950
3714
    return 1;
3951
3715
  return (*tab->read_record.read_record)(&tab->read_record);
3952
3716
}
3963
3727
{
3964
3728
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3965
3729
    return 1;
3966
 
  init_read_record(&tab->read_record, tab->join->session, tab->table,
3967
 
                   tab->select,1,1);
 
3730
 
 
3731
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
 
3732
 
3968
3733
  return (*tab->read_record.read_record)(&tab->read_record);
3969
3734
}
3970
3735
 
3975
3740
  if (!table->key_read && table->covering_keys.test(tab->index) &&
3976
3741
      !table->no_keyread)
3977
3742
  {
3978
 
    table->key_read=1;
 
3743
    table->key_read= 1;
3979
3744
    table->cursor->extra(HA_EXTRA_KEYREAD);
3980
3745
  }
3981
 
  tab->table->status=0;
 
3746
  tab->table->status= 0;
3982
3747
  tab->read_record.table=table;
3983
3748
  tab->read_record.cursor=table->cursor;
3984
3749
  tab->read_record.index=tab->index;
3985
 
  tab->read_record.record=table->record[0];
 
3750
  tab->read_record.record=table->getInsertRecord();
3986
3751
  if (tab->insideout_match_tab)
3987
3752
  {
3988
3753
    tab->read_record.do_insideout_scan= tab;
3996
3761
  }
3997
3762
 
3998
3763
  if (!table->cursor->inited)
3999
 
    table->cursor->ha_index_init(tab->index, tab->sorted);
4000
 
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
 
3764
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
3765
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
4001
3766
  {
4002
3767
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
4003
3768
      table->report_error(error);
4007
3772
  return 0;
4008
3773
}
4009
3774
 
4010
 
int join_read_next_different(READ_RECORD *info)
 
3775
int join_read_next_different(ReadRecord *info)
4011
3776
{
4012
3777
  JoinTable *tab= info->do_insideout_scan;
4013
3778
  if (tab->insideout_match_tab->found_match)
4014
3779
  {
4015
 
    KEY *key= tab->table->key_info + tab->index;
 
3780
    KeyInfo *key= tab->table->key_info + tab->index;
4016
3781
    do
4017
3782
    {
4018
3783
      int error;
4030
3795
    return join_read_next(info);
4031
3796
}
4032
3797
 
4033
 
int join_read_next(READ_RECORD *info)
 
3798
int join_read_next(ReadRecord *info)
4034
3799
{
4035
3800
  int error;
4036
3801
  if ((error=info->cursor->index_next(info->record)))
4053
3818
  tab->read_record.table=table;
4054
3819
  tab->read_record.cursor=table->cursor;
4055
3820
  tab->read_record.index=tab->index;
4056
 
  tab->read_record.record=table->record[0];
 
3821
  tab->read_record.record=table->getInsertRecord();
4057
3822
  if (!table->cursor->inited)
4058
 
    table->cursor->ha_index_init(tab->index, 1);
4059
 
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
 
3823
    table->cursor->startIndexScan(tab->index, 1);
 
3824
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
4060
3825
    return table->report_error(error);
4061
3826
 
4062
3827
  return 0;
4063
3828
}
4064
3829
 
4065
 
int join_read_prev(READ_RECORD *info)
 
3830
int join_read_prev(ReadRecord *info)
4066
3831
{
4067
3832
  int error;
4068
3833
  if ((error= info->cursor->index_prev(info->record)))
4088
3853
  return safe_index_read(tab);
4089
3854
}
4090
3855
 
4091
 
int join_read_next_same_or_null(READ_RECORD *info)
 
3856
int join_read_next_same_or_null(ReadRecord *info)
4092
3857
{
4093
3858
  int error;
4094
3859
  if ((error= join_read_next_same(info)) >= 0)
4102
3867
  return safe_index_read(tab);                  // then read null keys
4103
3868
}
4104
3869
 
4105
 
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *, bool end_of_records)
 
3870
enum_nested_loop_state end_send_group(Join *join, JoinTable *, bool end_of_records)
4106
3871
{
4107
3872
  int idx= -1;
4108
3873
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
4191
3956
  return(NESTED_LOOP_OK);
4192
3957
}
4193
3958
 
4194
 
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *, bool end_of_records)
 
3959
enum_nested_loop_state end_write_group(Join *join, JoinTable *, bool end_of_records)
4195
3960
{
4196
3961
  Table *table=join->tmp_table;
4197
3962
  int     idx= -1;
4198
3963
 
4199
 
  if (join->session->killed)
 
3964
  if (join->session->getKilled())
4200
3965
  {                                             // Aborted by user
4201
3966
    join->session->send_kill_message();
4202
3967
    return NESTED_LOOP_KILLED;
4217
3982
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
4218
3983
        if (!join->having || join->having->val_int())
4219
3984
        {
4220
 
          int error= table->cursor->ha_write_row(table->record[0]);
4221
 
          if (error && create_myisam_from_heap(join->session, table,
4222
 
                                              join->tmp_table_param.start_recinfo,
4223
 
                                                &join->tmp_table_param.recinfo,
4224
 
                                              error, 0))
4225
 
          return NESTED_LOOP_ERROR;
 
3985
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
3986
 
 
3987
          if (error)
 
3988
          {
 
3989
            my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
 
3990
            return NESTED_LOOP_ERROR;
 
3991
          }
4226
3992
        }
4227
3993
        if (join->rollup.state != ROLLUP::STATE_NONE)
4228
3994
        {
4243
4009
    if (idx < (int) join->send_group_parts)
4244
4010
    {
4245
4011
      copy_fields(&join->tmp_table_param);
4246
 
      copy_funcs(join->tmp_table_param.items_to_copy);
 
4012
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
 
4013
        return NESTED_LOOP_ERROR;
4247
4014
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
4248
4015
        return NESTED_LOOP_ERROR;
4249
4016
      return NESTED_LOOP_OK;
4260
4027
  outer join table.
4261
4028
  We can't remove tests that are made against columns which are stored
4262
4029
  in sorted order.
4263
 
*****************************************************************************/
4264
 
 
4265
 
/**
4266
4030
  @return
4267
 
    1 if right_item is used removable reference key on left_item
4268
 
*/
 
4031
    1 if right_item used is a removable reference key on left_item
 
4032
    0 otherwise.
 
4033
****************************************************************************/
4269
4034
bool test_if_ref(Item_field *left_item,Item *right_item)
4270
4035
{
4271
4036
  Field *field=left_item->field;
4272
4037
  // No need to change const test. We also have to keep tests on LEFT JOIN
4273
 
  if (!field->table->const_table && !field->table->maybe_null)
 
4038
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
4274
4039
  {
4275
 
    Item *ref_item=part_of_refkey(field->table,field);
 
4040
    Item *ref_item=part_of_refkey(field->getTable(),field);
4276
4041
    if (ref_item && ref_item->eq(right_item,1))
4277
4042
    {
4278
4043
      right_item= right_item->real_item();
4455
4220
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
4456
4221
  if (ref_parts)
4457
4222
  {
4458
 
    KEY_PART_INFO *key_part=
 
4223
    KeyPartInfo *key_part=
4459
4224
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
4460
4225
    uint32_t part;
4461
4226
 
4466
4231
    }
4467
4232
 
4468
4233
    for (part=0 ; part < ref_parts ; part++,key_part++)
 
4234
    {
4469
4235
      if (field->eq(key_part->field) &&
4470
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
 
4236
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
 
4237
          //If field can be NULL, we should not remove this predicate, as
 
4238
          //it may lead to non-rejection of NULL values. 
 
4239
          !(field->real_maybe_null()))
 
4240
      {
4471
4241
        return table->reginfo.join_tab->ref.items[part];
 
4242
      }
 
4243
    }
4472
4244
  }
4473
4245
  return (Item*) 0;
4474
4246
}
4493
4265
  @retval
4494
4266
    -1   Reverse key can be used
4495
4267
*/
4496
 
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4268
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4497
4269
{
4498
 
  KEY_PART_INFO *key_part= NULL;
4499
 
  KEY_PART_INFO *key_part_end= NULL;
 
4270
  KeyPartInfo *key_part= NULL;
 
4271
  KeyPartInfo *key_part_end= NULL;
4500
4272
  key_part= table->key_info[idx].key_part;
4501
4273
  key_part_end= key_part + table->key_info[idx].key_parts;
4502
4274
  key_part_map const_key_parts=table->const_key_parts[idx];
4524
4296
      */
4525
4297
      if (!on_primary_key &&
4526
4298
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
4527
 
          table->s->primary_key != MAX_KEY)
 
4299
          table->getShare()->hasPrimaryKey())
4528
4300
      {
4529
4301
        on_primary_key= true;
4530
 
        key_part= table->key_info[table->s->primary_key].key_part;
4531
 
        key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
4532
 
        const_key_parts=table->const_key_parts[table->s->primary_key];
 
4302
        key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
 
4303
        key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
 
4304
        const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
4533
4305
 
4534
4306
        for (; const_key_parts & 1 ; const_key_parts>>= 1)
4535
4307
          key_part++;
4578
4350
  @retval
4579
4351
    0   no sub key
4580
4352
*/
4581
 
inline bool is_subkey(KEY_PART_INFO *key_part,
4582
 
                      KEY_PART_INFO *ref_key_part,
4583
 
                      KEY_PART_INFO *ref_key_part_end)
 
4353
inline bool is_subkey(KeyPartInfo *key_part,
 
4354
                      KeyPartInfo *ref_key_part,
 
4355
                      KeyPartInfo *ref_key_part_end)
4584
4356
{
4585
4357
  for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
4586
4358
    if (! key_part->field->eq(ref_key_part->field))
4599
4371
    - MAX_KEY                   If we can't use other key
4600
4372
    - the number of found key   Otherwise
4601
4373
*/
4602
 
static uint32_t test_if_subkey(order_st *order,
 
4374
static uint32_t test_if_subkey(Order *order,
4603
4375
                               Table *table,
4604
4376
                               uint32_t ref,
4605
4377
                               uint32_t ref_key_parts,
4609
4381
  uint32_t min_length= UINT32_MAX;
4610
4382
  uint32_t best= MAX_KEY;
4611
4383
  uint32_t not_used;
4612
 
  KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
4613
 
  KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
 
4384
  KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
 
4385
  KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
4614
4386
 
4615
 
  for (nr= 0 ; nr < table->s->keys ; nr++)
 
4387
  for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
4616
4388
  {
4617
4389
    if (usable_keys->test(nr) &&
4618
4390
        table->key_info[nr].key_length < min_length &&
4661
4433
*/
4662
4434
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
4663
4435
{
4664
 
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
 
4436
  for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
4665
4437
  {
4666
 
    if (keynr == table->s->primary_key ||
 
4438
    if (keynr == table->getShare()->getPrimaryKey() ||
4667
4439
         (table->key_info[keynr].flags & HA_NOSAME))
4668
4440
    {
4669
 
      KEY *keyinfo= table->key_info + keynr;
4670
 
      KEY_PART_INFO *key_part= NULL;
4671
 
      KEY_PART_INFO *key_part_end= NULL;
 
4441
      KeyInfo *keyinfo= table->key_info + keynr;
 
4442
      KeyPartInfo *key_part= NULL;
 
4443
      KeyPartInfo *key_part_end= NULL;
4672
4444
 
4673
4445
      for (key_part=keyinfo->key_part,
4674
4446
           key_part_end=key_part+ keyinfo->key_parts;
4701
4473
*/
4702
4474
bool find_field_in_order_list (Field *field, void *data)
4703
4475
{
4704
 
  order_st *group= (order_st *) data;
 
4476
  Order *group= (Order *) data;
4705
4477
  bool part_found= 0;
4706
 
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4478
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4707
4479
  {
4708
4480
    Item *item= (*tmp_group->item)->real_item();
4709
4481
    if (item->type() == Item::FIELD_ITEM &&
4773
4545
  @retval
4774
4546
    1    We can use an index.
4775
4547
*/
4776
 
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4548
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
4777
4549
{
4778
4550
  int32_t ref_key;
4779
4551
  uint32_t ref_key_parts;
4790
4562
  */
4791
4563
  usable_keys= *map;
4792
4564
 
4793
 
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4565
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4794
4566
  {
4795
4567
    Item *item= (*tmp_order->item)->real_item();
4796
4568
    if (item->type() != Item::FIELD_ITEM)
4919
4691
    int best_key= -1;
4920
4692
    bool is_best_covering= false;
4921
4693
    double fanout= 1;
4922
 
    JOIN *join= tab->join;
 
4694
    Join *join= tab->join;
4923
4695
    uint32_t tablenr= tab - join->join_tab;
4924
4696
    ha_rows table_records= table->cursor->stats.records;
4925
4697
    bool group= join->group && order == join->group_list;
4962
4734
      fanout*= cur_pos.getFanout(); // fanout is always >= 1
4963
4735
    }
4964
4736
 
4965
 
    for (nr=0; nr < table->s->keys ; nr++)
 
4737
    for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
4966
4738
    {
4967
4739
      int direction;
4968
4740
      if (keys.test(nr) &&
4969
4741
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4970
4742
      {
4971
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->cursor->primary_key_is_clustered());
 
4743
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
4972
4744
 
4973
4745
        /*
4974
4746
          Don't use an index scan with ORDER BY without limit.
4985
4757
        {
4986
4758
          double rec_per_key;
4987
4759
          double index_scan_time;
4988
 
          KEY *keyinfo= tab->table->key_info+nr;
 
4760
          KeyInfo *keyinfo= tab->table->key_info+nr;
4989
4761
          if (select_limit == HA_POS_ERROR)
4990
4762
            select_limit= table_records;
4991
4763
          if (group)
5216
4988
    -1          Some fatal error
5217
4989
    1           No records
5218
4990
*/
5219
 
int create_sort_index(Session *session, JOIN *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
4991
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
5220
4992
{
5221
4993
  uint32_t length= 0;
5222
4994
  ha_rows examined_rows;
5243
5015
                              is_order_by ?  &table->keys_in_use_for_order_by :
5244
5016
                              &table->keys_in_use_for_group_by))
5245
5017
    return(0);
5246
 
  for (order_st *ord= join->order; ord; ord= ord->next)
 
5018
  for (Order *ord= join->order; ord; ord= ord->next)
5247
5019
    length++;
5248
 
  if (!(join->sortorder=
5249
 
        make_unireg_sortorder(order, &length, join->sortorder)))
5250
 
    goto err;
 
5020
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
 
5021
  {
 
5022
    return(-1);
 
5023
  }
5251
5024
 
5252
5025
  table->sort.io_cache= new internal::IO_CACHE;
5253
 
  memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
5254
5026
  table->status=0;                              // May be wrong if quick_select
5255
5027
 
5256
5028
  // If table has a range, move it to select
5283
5055
                                                                 &tab->ref,
5284
5056
                                                                 tab->found_records))))
5285
5057
      {
5286
 
        goto err;
 
5058
        return(-1);
5287
5059
      }
5288
5060
    }
5289
5061
  }
5290
5062
 
5291
 
  if (table->s->tmp_table)
 
5063
  if (table->getShare()->getType())
5292
5064
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
5293
 
  table->sort.found_records=filesort(session, table,join->sortorder, length,
5294
 
                                     select, filesort_limit, 0,
5295
 
                                     &examined_rows);
 
5065
 
 
5066
  FileSort filesort(*session);
 
5067
  table->sort.found_records=filesort.run(table,join->sortorder, length,
 
5068
                                         select, filesort_limit, 0,
 
5069
                                         examined_rows);
5296
5070
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5297
5071
  if (select)
5298
5072
  {
5310
5084
    table->key_read=0;
5311
5085
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5312
5086
  }
 
5087
 
5313
5088
  return(table->sort.found_records == HA_POS_ERROR);
5314
 
err:
5315
 
  return(-1);
5316
5089
}
5317
5090
 
5318
5091
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5321
5094
  char *org_record,*new_record;
5322
5095
  unsigned char *record;
5323
5096
  int error;
5324
 
  uint32_t reclength= table->s->reclength-offset;
5325
 
 
5326
 
  org_record=(char*) (record=table->record[0])+offset;
5327
 
  new_record=(char*) table->record[1]+offset;
5328
 
 
5329
 
  cursor->ha_rnd_init(1);
 
5097
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
 
5098
 
 
5099
  org_record=(char*) (record=table->getInsertRecord())+offset;
 
5100
  new_record=(char*) table->getUpdateRecord()+offset;
 
5101
 
 
5102
  cursor->startTableScan(1);
5330
5103
  error=cursor->rnd_next(record);
5331
5104
  for (;;)
5332
5105
  {
5333
 
    if (session->killed)
 
5106
    if (session->getKilled())
5334
5107
    {
5335
5108
      session->send_kill_message();
5336
5109
      error=0;
5346
5119
    }
5347
5120
    if (having && !having->val_int())
5348
5121
    {
5349
 
      if ((error=cursor->ha_delete_row(record)))
 
5122
      if ((error=cursor->deleteRecord(record)))
5350
5123
        goto err;
5351
5124
      error=cursor->rnd_next(record);
5352
5125
      continue;
5373
5146
      }
5374
5147
      if (table->compare_record(first_field) == 0)
5375
5148
      {
5376
 
        if ((error=cursor->ha_delete_row(record)))
 
5149
        if ((error=cursor->deleteRecord(record)))
5377
5150
          goto err;
5378
5151
      }
5379
5152
      else if (!found)
5384
5157
    }
5385
5158
    if (!found)
5386
5159
      break;                                    // End of cursor
5387
 
    /* Restart search on next row */
5388
 
    error=cursor->restart_rnd_next(record,cursor->ref);
 
5160
    /* Move current position to the next row */
 
5161
    error= cursor->rnd_pos(record, cursor->ref);
5389
5162
  }
5390
5163
 
5391
5164
  cursor->extra(HA_EXTRA_NO_CACHE);
5410
5183
                               uint32_t key_length,
5411
5184
                               Item *having)
5412
5185
{
5413
 
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
 
5186
  unsigned char *key_pos, *record=table->getInsertRecord();
5414
5187
  int error;
5415
5188
  Cursor *cursor= table->cursor;
5416
5189
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5417
 
  uint32_t *field_lengths,*field_length;
 
5190
  uint32_t *field_length;
5418
5191
  HASH hash;
 
5192
  std::vector<unsigned char> key_buffer;
 
5193
  std::vector<uint32_t> field_lengths;
5419
5194
 
5420
 
  if (! memory::multi_malloc(false,
5421
 
                       &key_buffer,
5422
 
                       (uint32_t) ((key_length + extra_length) *
5423
 
                               (long) cursor->stats.records),
5424
 
                       &field_lengths,
5425
 
                       (uint32_t) (field_count*sizeof(*field_lengths)),
5426
 
                       NULL))
5427
 
    return(1);
 
5195
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
 
5196
  field_lengths.resize(field_count);
5428
5197
 
5429
5198
  {
5430
5199
    Field **ptr;
5431
5200
    uint32_t total_length= 0;
5432
 
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
 
5201
 
 
5202
    for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
5433
5203
    {
5434
5204
      uint32_t length= (*ptr)->sort_length();
5435
5205
      (*field_length++)= length;
5443
5213
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5444
5214
                key_length, (hash_get_key) 0, 0, 0))
5445
5215
  {
5446
 
    free((char*) key_buffer);
5447
5216
    return(1);
5448
5217
  }
5449
5218
 
5450
 
  cursor->ha_rnd_init(1);
5451
 
  key_pos=key_buffer;
 
5219
  cursor->startTableScan(1);
 
5220
  key_pos= &key_buffer[0];
5452
5221
  for (;;)
5453
5222
  {
5454
5223
    unsigned char *org_key_pos;
5455
 
    if (session->killed)
 
5224
    if (session->getKilled())
5456
5225
    {
5457
5226
      session->send_kill_message();
5458
5227
      error=0;
5468
5237
    }
5469
5238
    if (having && !having->val_int())
5470
5239
    {
5471
 
      if ((error=cursor->ha_delete_row(record)))
 
5240
      if ((error=cursor->deleteRecord(record)))
5472
5241
        goto err;
5473
5242
      continue;
5474
5243
    }
5475
5244
 
5476
5245
    /* copy fields to key buffer */
5477
5246
    org_key_pos= key_pos;
5478
 
    field_length=field_lengths;
 
5247
    field_length= &field_lengths[0];
5479
5248
    for (Field **ptr= first_field ; *ptr ; ptr++)
5480
5249
    {
5481
5250
      (*ptr)->sort_string(key_pos,*field_length);
5485
5254
    if (hash_search(&hash, org_key_pos, key_length))
5486
5255
    {
5487
5256
      /* Duplicated found ; Remove the row */
5488
 
      if ((error=cursor->ha_delete_row(record)))
 
5257
      if ((error=cursor->deleteRecord(record)))
5489
5258
        goto err;
5490
5259
    }
5491
5260
    else
5492
5261
      (void) my_hash_insert(&hash, org_key_pos);
5493
5262
    key_pos+=extra_length;
5494
5263
  }
5495
 
  free((char*) key_buffer);
5496
5264
  hash_free(&hash);
5497
5265
  cursor->extra(HA_EXTRA_NO_CACHE);
5498
 
  (void) cursor->ha_rnd_end();
 
5266
  (void) cursor->endTableScan();
5499
5267
  return(0);
5500
5268
 
5501
5269
err:
5502
 
  free((char*) key_buffer);
5503
5270
  hash_free(&hash);
5504
5271
  cursor->extra(HA_EXTRA_NO_CACHE);
5505
 
  (void) cursor->ha_rnd_end();
 
5272
  (void) cursor->endTableScan();
5506
5273
  if (error)
5507
5274
    table->print_error(error,MYF(0));
5508
5275
  return(1);
5509
5276
}
5510
5277
 
5511
 
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
 
5278
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5512
5279
{
5513
5280
  uint32_t count;
5514
 
  SORT_FIELD *sort,*pos;
 
5281
  SortField *sort,*pos;
5515
5282
 
5516
5283
  count=0;
5517
 
  for (order_st *tmp = order; tmp; tmp=tmp->next)
 
5284
  for (Order *tmp = order; tmp; tmp=tmp->next)
5518
5285
    count++;
5519
5286
  if (!sortorder)
5520
 
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
 
5287
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
5521
5288
                                       (max(count, *length) + 1));
5522
5289
  pos= sort= sortorder;
5523
5290
 
5639
5406
static bool find_order_in_list(Session *session, 
5640
5407
                               Item **ref_pointer_array, 
5641
5408
                               TableList *tables,
5642
 
                               order_st *order,
 
5409
                               Order *order,
5643
5410
                               List<Item> &fields,
5644
5411
                               List<Item> &all_fields,
5645
5412
                               bool is_group_field)
5671
5438
    return false;
5672
5439
  }
5673
5440
  /* Lookup the current GROUP/order_st field in the SELECT clause. */
5674
 
  select_item= find_item_in_list(order_item, fields, &counter,
 
5441
  select_item= find_item_in_list(session, order_item, fields, &counter,
5675
5442
                                 REPORT_EXCEPT_NOT_FOUND, &resolution);
5676
5443
  if (!select_item)
5677
5444
    return true; /* The item is not unique, or some other error occured. */
5738
5505
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5739
5506
                          ER(ER_NON_UNIQ_ERROR),
5740
5507
                          ((Item_ident*) order_item)->field_name,
5741
 
                          current_session->where);
 
5508
                          session->where);
5742
5509
    }
5743
5510
  }
5744
5511
 
5778
5545
                TableList *tables,
5779
5546
                            List<Item> &fields,
5780
5547
                List<Item> &all_fields,
5781
 
                order_st *order)
 
5548
                Order *order)
5782
5549
{
5783
5550
  session->where="order clause";
5784
5551
  for (; order; order=order->next)
5820
5587
                TableList *tables,
5821
5588
                      List<Item> &fields,
5822
5589
                List<Item> &all_fields,
5823
 
                order_st *order,
 
5590
                Order *order,
5824
5591
                      bool *hidden_group_fields)
5825
5592
{
5826
5593
  *hidden_group_fields=0;
5827
 
  order_st *ord;
 
5594
  Order *ord;
5828
5595
 
5829
5596
  if (!order)
5830
5597
    return 0;                           /* Everything is ok */
5914
5681
  Try to use the fields in the order given by 'order' to allow one to
5915
5682
  optimize away 'order by'.
5916
5683
*/
5917
 
order_st *create_distinct_group(Session *session,
 
5684
Order *create_distinct_group(Session *session,
5918
5685
                                Item **ref_pointer_array,
5919
 
                                order_st *order_list,
 
5686
                                Order *order_list,
5920
5687
                                List<Item> &fields,
5921
5688
                                List<Item> &,
5922
5689
                                bool *all_order_by_fields_used)
5923
5690
{
5924
5691
  List_iterator<Item> li(fields);
5925
5692
  Item *item;
5926
 
  order_st *order,*group,**prev;
 
5693
  Order *order,*group,**prev;
5927
5694
 
5928
5695
  *all_order_by_fields_used= 1;
5929
5696
  while ((item=li++))
5934
5701
  {
5935
5702
    if (order->in_field_list)
5936
5703
    {
5937
 
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
 
5704
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5938
5705
      if (!ord)
5939
5706
        return 0;
5940
5707
      *prev=ord;
5954
5721
        Don't put duplicate columns from the SELECT list into the
5955
5722
        GROUP BY list.
5956
5723
      */
5957
 
      order_st *ord_iter;
 
5724
      Order *ord_iter;
5958
5725
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5959
5726
        if ((*ord_iter->item)->eq(item, 1))
5960
5727
          goto next_item;
5961
5728
 
5962
 
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
 
5729
      Order *ord=(Order*) session->calloc(sizeof(Order));
5963
5730
      if (!ord)
5964
5731
        return 0;
5965
5732
 
6146
5913
          saved value
6147
5914
        */
6148
5915
        field= item->field;
6149
 
        item->result_field=field->new_field(session->mem_root,field->table, 1);
 
5916
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
6150
5917
              /*
6151
5918
                We need to allocate one extra byte for null handling and
6152
5919
                another extra byte to not get warnings from purify in
6158
5925
        {
6159
5926
          copy->set(tmp, item->result_field);
6160
5927
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
6161
 
#ifdef HAVE_purify
 
5928
#ifdef HAVE_VALGRIND
6162
5929
          copy->to_ptr[copy->from_length]= 0;
6163
5930
#endif
6164
5931
          copy++;
6279
6046
      }
6280
6047
      else if ((field= item->get_tmp_table_field()))
6281
6048
      {
6282
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
 
6049
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
6283
6050
          item_field= ((Item_sum*) item)->result_item(field);
6284
6051
        else
6285
6052
          item_field= (Item*) new Item_field(field);
6431
6198
}
6432
6199
 
6433
6200
/** Copy result of functions to record in tmp_table. */
6434
 
void copy_funcs(Item **func_ptr)
 
6201
bool copy_funcs(Item **func_ptr, const Session *session)
6435
6202
{
6436
6203
  Item *func;
6437
6204
  for (; (func = *func_ptr) ; func_ptr++)
 
6205
  {
6438
6206
    func->save_in_result_field(1);
 
6207
    /*
 
6208
      Need to check the THD error state because Item::val_xxx() don't
 
6209
      return error code, but can generate errors
 
6210
      TODO: change it for a real status check when Item::val_xxx()
 
6211
      are extended to return status code.
 
6212
    */
 
6213
    if (session->is_error())
 
6214
      return true;
 
6215
  }
 
6216
  return false;
6439
6217
}
6440
6218
 
6441
6219
/**
6495
6273
  @retval
6496
6274
    1   on error
6497
6275
*/
6498
 
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
 
6276
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
6499
6277
{
6500
6278
  if (expr->arg_count)
6501
6279
  {
6509
6287
      Item *item= *arg;
6510
6288
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6511
6289
      {
6512
 
        order_st *group_tmp;
 
6290
        Order *group_tmp;
6513
6291
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6514
6292
        {
6515
6293
          if (item->eq(*group_tmp->item,0))
6592
6370
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6593
6371
{
6594
6372
  /* QQ: session may not be set for sub queries, but this should be fixed */
6595
 
  if (!session)
 
6373
  if(not session)
6596
6374
    session= current_session;
6597
6375
 
 
6376
 
6598
6377
  str->append(STRING_WITH_LEN("select "));
6599
6378
 
6600
6379
  /* First add options */
6660
6439
  if (group_list.elements)
6661
6440
  {
6662
6441
    str->append(STRING_WITH_LEN(" group by "));
6663
 
    print_order(str, (order_st *) group_list.first, query_type);
 
6442
    print_order(str, (Order *) group_list.first, query_type);
6664
6443
    switch (olap)
6665
6444
    {
6666
6445
      case CUBE_TYPE:
6691
6470
  if (order_list.elements)
6692
6471
  {
6693
6472
    str->append(STRING_WITH_LEN(" order by "));
6694
 
    print_order(str, (order_st *) order_list.first, query_type);
 
6473
    print_order(str, (Order *) order_list.first, query_type);
6695
6474
  }
6696
6475
 
6697
6476
  // limit