~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Patrick Crews
  • Date: 2011-01-29 14:17:35 UTC
  • mto: (2126.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2127.
  • Revision ID: gleebix@gmail.com-20110129141735-3y2658vt5ur0a33o
Fixes to make test-dbqp

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
 
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
    }
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)))
3650
3423
    table->maybe_null=0;
3651
3424
 
3652
3425
  /* Check appearance of new constant items in Item_equal objects */
3653
 
  JOIN *join= tab->join;
 
3426
  Join *join= tab->join;
3654
3427
  if (join->conds)
3655
3428
    update_const_equal_items(join->conds, tab);
3656
3429
  TableList *tbl;
3663
3436
      embedded= embedding;
3664
3437
      if (embedded->on_expr)
3665
3438
         update_const_equal_items(embedded->on_expr, tab);
3666
 
      embedding= embedded->embedding;
 
3439
      embedding= embedded->getEmbedding();
3667
3440
    }
3668
3441
    while (embedding &&
3669
 
           embedding->nested_join->join_list.head() == embedded);
 
3442
           embedding->getNestedJoin()->join_list.head() == embedded);
3670
3443
  }
3671
3444
 
3672
3445
  return(0);
3678
3451
  int error;
3679
3452
  if (table->status & STATUS_GARBAGE)           // If first read
3680
3453
  {
3681
 
    if ((error=table->cursor->read_first_row(table->record[0],
3682
 
                                           table->s->primary_key)))
 
3454
    if ((error=table->cursor->read_first_row(table->getInsertRecord(),
 
3455
                                           table->getShare()->getPrimaryKey())))
3683
3456
    {
3684
3457
      if (error != HA_ERR_END_OF_FILE)
3685
3458
        return table->report_error(error);
3718
3491
      error= HA_ERR_KEY_NOT_FOUND;
3719
3492
    else
3720
3493
    {
3721
 
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
 
3494
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
3722
3495
                                            (unsigned char*) tab->ref.key_buff,
3723
3496
                                            make_prev_keypart_map(tab->ref.key_parts),
3724
3497
                                            HA_READ_KEY_EXACT);
3766
3539
 
3767
3540
  if (!table->cursor->inited)
3768
3541
  {
3769
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3542
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3543
    if (error != 0)
 
3544
    {
 
3545
      table->print_error(error, MYF(0));
 
3546
    }
3770
3547
  }
3771
3548
 
3772
3549
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3778
3555
      table->status=STATUS_NOT_FOUND;
3779
3556
      return -1;
3780
3557
    }
3781
 
    error=table->cursor->index_read_map(table->record[0],
 
3558
    error=table->cursor->index_read_map(table->getInsertRecord(),
3782
3559
                                      tab->ref.key_buff,
3783
3560
                                      make_prev_keypart_map(tab->ref.key_parts),
3784
3561
                                      HA_READ_KEY_EXACT);
3814
3591
 
3815
3592
  /* Initialize the index first */
3816
3593
  if (!table->cursor->inited)
3817
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3594
  {
 
3595
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3596
    if (error != 0)
 
3597
      return table->report_error(error);
 
3598
  }
3818
3599
 
3819
3600
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3820
3601
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3825
3606
 
3826
3607
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3827
3608
    return -1;
3828
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3609
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
3829
3610
                                         tab->ref.key_buff,
3830
3611
                                         make_prev_keypart_map(tab->ref.key_parts),
3831
3612
                                         HA_READ_KEY_EXACT)))
3848
3629
  Table *table= tab->table;
3849
3630
 
3850
3631
  if (!table->cursor->inited)
3851
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3632
  {
 
3633
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
 
3634
    if (error != 0)
 
3635
      return table->report_error(error);
 
3636
  }
3852
3637
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3853
3638
    return -1;
3854
 
  if ((error=table->cursor->index_read_last_map(table->record[0],
 
3639
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
3855
3640
                                              tab->ref.key_buff,
3856
3641
                                              make_prev_keypart_map(tab->ref.key_parts))))
3857
3642
  {
3862
3647
  return 0;
3863
3648
}
3864
3649
 
3865
 
int join_no_more_records(READ_RECORD *)
 
3650
int join_no_more_records(ReadRecord *)
3866
3651
{
3867
3652
  return -1;
3868
3653
}
3869
3654
 
3870
 
int join_read_next_same_diff(READ_RECORD *info)
 
3655
int join_read_next_same_diff(ReadRecord *info)
3871
3656
{
3872
3657
  Table *table= info->table;
3873
3658
  JoinTable *tab=table->reginfo.join_tab;
3874
3659
  if (tab->insideout_match_tab->found_match)
3875
3660
  {
3876
 
    KEY *key= tab->table->key_info + tab->index;
 
3661
    KeyInfo *key= tab->table->key_info + tab->index;
3877
3662
    do
3878
3663
    {
3879
3664
      int error;
3880
3665
      /* Save index tuple from record to the buffer */
3881
3666
      key_copy(tab->insideout_buf, info->record, key, 0);
3882
3667
 
3883
 
      if ((error=table->cursor->index_next_same(table->record[0],
 
3668
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3884
3669
                                              tab->ref.key_buff,
3885
3670
                                              tab->ref.key_length)))
3886
3671
      {
3898
3683
    return join_read_next_same(info);
3899
3684
}
3900
3685
 
3901
 
int join_read_next_same(READ_RECORD *info)
 
3686
int join_read_next_same(ReadRecord *info)
3902
3687
{
3903
3688
  int error;
3904
3689
  Table *table= info->table;
3905
3690
  JoinTable *tab=table->reginfo.join_tab;
3906
3691
 
3907
 
  if ((error=table->cursor->index_next_same(table->record[0],
 
3692
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
3908
3693
                                          tab->ref.key_buff,
3909
3694
                                          tab->ref.key_length)))
3910
3695
  {
3917
3702
  return 0;
3918
3703
}
3919
3704
 
3920
 
int join_read_prev_same(READ_RECORD *info)
 
3705
int join_read_prev_same(ReadRecord *info)
3921
3706
{
3922
3707
  int error;
3923
3708
  Table *table= info->table;
3924
3709
  JoinTable *tab=table->reginfo.join_tab;
3925
3710
 
3926
 
  if ((error=table->cursor->index_prev(table->record[0])))
 
3711
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
3927
3712
    return table->report_error(error);
3928
3713
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3929
3714
                      tab->ref.key_length))
3941
3726
  return join_init_read_record(tab);
3942
3727
}
3943
3728
 
3944
 
int rr_sequential(READ_RECORD *info);
3945
3729
int init_read_record_seq(JoinTable *tab)
3946
3730
{
3947
 
  tab->read_record.read_record= rr_sequential;
3948
 
  if (tab->read_record.cursor->ha_rnd_init(1))
 
3731
  tab->read_record.init_reard_record_sequential();
 
3732
 
 
3733
  if (tab->read_record.cursor->startTableScan(1))
3949
3734
    return 1;
3950
3735
  return (*tab->read_record.read_record)(&tab->read_record);
3951
3736
}
3962
3747
{
3963
3748
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3964
3749
    return 1;
3965
 
  init_read_record(&tab->read_record, tab->join->session, tab->table,
3966
 
                   tab->select,1,1);
 
3750
 
 
3751
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
 
3752
    return 1;
 
3753
 
3967
3754
  return (*tab->read_record.read_record)(&tab->read_record);
3968
3755
}
3969
3756
 
3974
3761
  if (!table->key_read && table->covering_keys.test(tab->index) &&
3975
3762
      !table->no_keyread)
3976
3763
  {
3977
 
    table->key_read=1;
 
3764
    table->key_read= 1;
3978
3765
    table->cursor->extra(HA_EXTRA_KEYREAD);
3979
3766
  }
3980
 
  tab->table->status=0;
 
3767
  tab->table->status= 0;
3981
3768
  tab->read_record.table=table;
3982
3769
  tab->read_record.cursor=table->cursor;
3983
3770
  tab->read_record.index=tab->index;
3984
 
  tab->read_record.record=table->record[0];
 
3771
  tab->read_record.record=table->getInsertRecord();
3985
3772
  if (tab->insideout_match_tab)
3986
3773
  {
3987
3774
    tab->read_record.do_insideout_scan= tab;
3995
3782
  }
3996
3783
 
3997
3784
  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])))
 
3785
  {
 
3786
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
 
3787
    if (error != 0)
 
3788
    {
 
3789
      table->report_error(error);
 
3790
      return -1;
 
3791
    }
 
3792
  }
 
3793
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
4000
3794
  {
4001
3795
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
4002
3796
      table->report_error(error);
4006
3800
  return 0;
4007
3801
}
4008
3802
 
4009
 
int join_read_next_different(READ_RECORD *info)
 
3803
int join_read_next_different(ReadRecord *info)
4010
3804
{
4011
3805
  JoinTable *tab= info->do_insideout_scan;
4012
3806
  if (tab->insideout_match_tab->found_match)
4013
3807
  {
4014
 
    KEY *key= tab->table->key_info + tab->index;
 
3808
    KeyInfo *key= tab->table->key_info + tab->index;
4015
3809
    do
4016
3810
    {
4017
3811
      int error;
4029
3823
    return join_read_next(info);
4030
3824
}
4031
3825
 
4032
 
int join_read_next(READ_RECORD *info)
 
3826
int join_read_next(ReadRecord *info)
4033
3827
{
4034
3828
  int error;
4035
3829
  if ((error=info->cursor->index_next(info->record)))
4052
3846
  tab->read_record.table=table;
4053
3847
  tab->read_record.cursor=table->cursor;
4054
3848
  tab->read_record.index=tab->index;
4055
 
  tab->read_record.record=table->record[0];
 
3849
  tab->read_record.record=table->getInsertRecord();
4056
3850
  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])))
 
3851
  {
 
3852
    error= table->cursor->startIndexScan(tab->index, 1);
 
3853
    if (error != 0)
 
3854
      return table->report_error(error);
 
3855
  }
 
3856
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
4059
3857
    return table->report_error(error);
4060
3858
 
4061
3859
  return 0;
4062
3860
}
4063
3861
 
4064
 
int join_read_prev(READ_RECORD *info)
 
3862
int join_read_prev(ReadRecord *info)
4065
3863
{
4066
3864
  int error;
4067
3865
  if ((error= info->cursor->index_prev(info->record)))
4087
3885
  return safe_index_read(tab);
4088
3886
}
4089
3887
 
4090
 
int join_read_next_same_or_null(READ_RECORD *info)
 
3888
int join_read_next_same_or_null(ReadRecord *info)
4091
3889
{
4092
3890
  int error;
4093
3891
  if ((error= join_read_next_same(info)) >= 0)
4101
3899
  return safe_index_read(tab);                  // then read null keys
4102
3900
}
4103
3901
 
4104
 
enum_nested_loop_state end_send_group(JOIN *join, JoinTable *, bool end_of_records)
 
3902
enum_nested_loop_state end_send_group(Join *join, JoinTable *, bool end_of_records)
4105
3903
{
4106
3904
  int idx= -1;
4107
3905
  enum_nested_loop_state ok_code= NESTED_LOOP_OK;
4134
3932
              error=join->result->send_data(*join->fields) ? 1 : 0;
4135
3933
            join->send_records++;
4136
3934
          }
4137
 
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
 
3935
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
4138
3936
          {
4139
3937
            if (join->rollup_send_data((uint32_t) (idx+1)))
4140
3938
              error= 1;
4190
3988
  return(NESTED_LOOP_OK);
4191
3989
}
4192
3990
 
4193
 
enum_nested_loop_state end_write_group(JOIN *join, JoinTable *, bool end_of_records)
 
3991
enum_nested_loop_state end_write_group(Join *join, JoinTable *, bool end_of_records)
4194
3992
{
4195
3993
  Table *table=join->tmp_table;
4196
3994
  int     idx= -1;
4197
3995
 
4198
 
  if (join->session->killed)
 
3996
  if (join->session->getKilled())
4199
3997
  {                                             // Aborted by user
4200
3998
    join->session->send_kill_message();
4201
3999
    return NESTED_LOOP_KILLED;
4216
4014
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
4217
4015
        if (!join->having || join->having->val_int())
4218
4016
        {
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;
 
4017
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
4018
 
 
4019
          if (error)
 
4020
          {
 
4021
            my_error(ER_USE_SQL_BIG_RESULT, MYF(0));
 
4022
            return NESTED_LOOP_ERROR;
 
4023
          }
4225
4024
        }
4226
 
        if (join->rollup.state != ROLLUP::STATE_NONE)
 
4025
        if (join->rollup.getState() != Rollup::STATE_NONE)
4227
4026
        {
4228
4027
          if (join->rollup_write_data((uint32_t) (idx+1), table))
4229
4028
            return NESTED_LOOP_ERROR;
4242
4041
    if (idx < (int) join->send_group_parts)
4243
4042
    {
4244
4043
      copy_fields(&join->tmp_table_param);
4245
 
      copy_funcs(join->tmp_table_param.items_to_copy);
 
4044
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
 
4045
        return NESTED_LOOP_ERROR;
4246
4046
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
4247
4047
        return NESTED_LOOP_ERROR;
4248
4048
      return NESTED_LOOP_OK;
4259
4059
  outer join table.
4260
4060
  We can't remove tests that are made against columns which are stored
4261
4061
  in sorted order.
4262
 
*****************************************************************************/
4263
 
 
4264
 
/**
4265
4062
  @return
4266
 
    1 if right_item is used removable reference key on left_item
4267
 
*/
 
4063
    1 if right_item used is a removable reference key on left_item
 
4064
    0 otherwise.
 
4065
****************************************************************************/
4268
4066
bool test_if_ref(Item_field *left_item,Item *right_item)
4269
4067
{
4270
4068
  Field *field=left_item->field;
4271
4069
  // 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)
 
4070
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
4273
4071
  {
4274
 
    Item *ref_item=part_of_refkey(field->table,field);
 
4072
    Item *ref_item=part_of_refkey(field->getTable(),field);
4275
4073
    if (ref_item && ref_item->eq(right_item,1))
4276
4074
    {
4277
4075
      right_item= right_item->real_item();
4454
4252
  uint32_t ref_parts=table->reginfo.join_tab->ref.key_parts;
4455
4253
  if (ref_parts)
4456
4254
  {
4457
 
    KEY_PART_INFO *key_part=
 
4255
    KeyPartInfo *key_part=
4458
4256
      table->key_info[table->reginfo.join_tab->ref.key].key_part;
4459
4257
    uint32_t part;
4460
4258
 
4465
4263
    }
4466
4264
 
4467
4265
    for (part=0 ; part < ref_parts ; part++,key_part++)
 
4266
    {
4468
4267
      if (field->eq(key_part->field) &&
4469
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
 
4268
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
 
4269
          //If field can be NULL, we should not remove this predicate, as
 
4270
          //it may lead to non-rejection of NULL values. 
 
4271
          !(field->real_maybe_null()))
 
4272
      {
4470
4273
        return table->reginfo.join_tab->ref.items[part];
 
4274
      }
 
4275
    }
4471
4276
  }
4472
4277
  return (Item*) 0;
4473
4278
}
4492
4297
  @retval
4493
4298
    -1   Reverse key can be used
4494
4299
*/
4495
 
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4300
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4496
4301
{
4497
 
  KEY_PART_INFO *key_part= NULL;
4498
 
  KEY_PART_INFO *key_part_end= NULL;
 
4302
  KeyPartInfo *key_part= NULL;
 
4303
  KeyPartInfo *key_part_end= NULL;
4499
4304
  key_part= table->key_info[idx].key_part;
4500
4305
  key_part_end= key_part + table->key_info[idx].key_parts;
4501
4306
  key_part_map const_key_parts=table->const_key_parts[idx];
4523
4328
      */
4524
4329
      if (!on_primary_key &&
4525
4330
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
4526
 
          table->s->primary_key != MAX_KEY)
 
4331
          table->getShare()->hasPrimaryKey())
4527
4332
      {
4528
4333
        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];
 
4334
        key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
 
4335
        key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
 
4336
        const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
4532
4337
 
4533
4338
        for (; const_key_parts & 1 ; const_key_parts>>= 1)
4534
4339
          key_part++;
4577
4382
  @retval
4578
4383
    0   no sub key
4579
4384
*/
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)
 
4385
inline bool is_subkey(KeyPartInfo *key_part,
 
4386
                      KeyPartInfo *ref_key_part,
 
4387
                      KeyPartInfo *ref_key_part_end)
4583
4388
{
4584
4389
  for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
4585
4390
    if (! key_part->field->eq(ref_key_part->field))
4598
4403
    - MAX_KEY                   If we can't use other key
4599
4404
    - the number of found key   Otherwise
4600
4405
*/
4601
 
static uint32_t test_if_subkey(order_st *order,
 
4406
static uint32_t test_if_subkey(Order *order,
4602
4407
                               Table *table,
4603
4408
                               uint32_t ref,
4604
4409
                               uint32_t ref_key_parts,
4608
4413
  uint32_t min_length= UINT32_MAX;
4609
4414
  uint32_t best= MAX_KEY;
4610
4415
  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;
 
4416
  KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
 
4417
  KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
4613
4418
 
4614
 
  for (nr= 0 ; nr < table->s->keys ; nr++)
 
4419
  for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
4615
4420
  {
4616
4421
    if (usable_keys->test(nr) &&
4617
4422
        table->key_info[nr].key_length < min_length &&
4660
4465
*/
4661
4466
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
4662
4467
{
4663
 
  for (uint32_t keynr= 0; keynr < table->s->keys; keynr++)
 
4468
  for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
4664
4469
  {
4665
 
    if (keynr == table->s->primary_key ||
 
4470
    if (keynr == table->getShare()->getPrimaryKey() ||
4666
4471
         (table->key_info[keynr].flags & HA_NOSAME))
4667
4472
    {
4668
 
      KEY *keyinfo= table->key_info + keynr;
4669
 
      KEY_PART_INFO *key_part= NULL;
4670
 
      KEY_PART_INFO *key_part_end= NULL;
 
4473
      KeyInfo *keyinfo= table->key_info + keynr;
 
4474
      KeyPartInfo *key_part= NULL;
 
4475
      KeyPartInfo *key_part_end= NULL;
4671
4476
 
4672
4477
      for (key_part=keyinfo->key_part,
4673
4478
           key_part_end=key_part+ keyinfo->key_parts;
4700
4505
*/
4701
4506
bool find_field_in_order_list (Field *field, void *data)
4702
4507
{
4703
 
  order_st *group= (order_st *) data;
 
4508
  Order *group= (Order *) data;
4704
4509
  bool part_found= 0;
4705
 
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4510
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4706
4511
  {
4707
4512
    Item *item= (*tmp_group->item)->real_item();
4708
4513
    if (item->type() == Item::FIELD_ITEM &&
4772
4577
  @retval
4773
4578
    1    We can use an index.
4774
4579
*/
4775
 
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4580
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
4776
4581
{
4777
4582
  int32_t ref_key;
4778
4583
  uint32_t ref_key_parts;
4789
4594
  */
4790
4595
  usable_keys= *map;
4791
4596
 
4792
 
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4597
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4793
4598
  {
4794
4599
    Item *item= (*tmp_order->item)->real_item();
4795
4600
    if (item->type() != Item::FIELD_ITEM)
4918
4723
    int best_key= -1;
4919
4724
    bool is_best_covering= false;
4920
4725
    double fanout= 1;
4921
 
    JOIN *join= tab->join;
 
4726
    Join *join= tab->join;
4922
4727
    uint32_t tablenr= tab - join->join_tab;
4923
4728
    ha_rows table_records= table->cursor->stats.records;
4924
4729
    bool group= join->group && order == join->group_list;
4961
4766
      fanout*= cur_pos.getFanout(); // fanout is always >= 1
4962
4767
    }
4963
4768
 
4964
 
    for (nr=0; nr < table->s->keys ; nr++)
 
4769
    for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
4965
4770
    {
4966
4771
      int direction;
4967
4772
      if (keys.test(nr) &&
4968
4773
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4969
4774
      {
4970
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->cursor->primary_key_is_clustered());
 
4775
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
4971
4776
 
4972
4777
        /*
4973
4778
          Don't use an index scan with ORDER BY without limit.
4984
4789
        {
4985
4790
          double rec_per_key;
4986
4791
          double index_scan_time;
4987
 
          KEY *keyinfo= tab->table->key_info+nr;
 
4792
          KeyInfo *keyinfo= tab->table->key_info+nr;
4988
4793
          if (select_limit == HA_POS_ERROR)
4989
4794
            select_limit= table_records;
4990
4795
          if (group)
5215
5020
    -1          Some fatal error
5216
5021
    1           No records
5217
5022
*/
5218
 
int create_sort_index(Session *session, JOIN *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
5023
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
5219
5024
{
5220
5025
  uint32_t length= 0;
5221
5026
  ha_rows examined_rows;
5242
5047
                              is_order_by ?  &table->keys_in_use_for_order_by :
5243
5048
                              &table->keys_in_use_for_group_by))
5244
5049
    return(0);
5245
 
  for (order_st *ord= join->order; ord; ord= ord->next)
 
5050
  for (Order *ord= join->order; ord; ord= ord->next)
5246
5051
    length++;
5247
 
  if (!(join->sortorder=
5248
 
        make_unireg_sortorder(order, &length, join->sortorder)))
5249
 
    goto err;
 
5052
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
 
5053
  {
 
5054
    return(-1);
 
5055
  }
5250
5056
 
5251
5057
  table->sort.io_cache= new internal::IO_CACHE;
5252
 
  memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
5253
5058
  table->status=0;                              // May be wrong if quick_select
5254
5059
 
5255
5060
  // If table has a range, move it to select
5282
5087
                                                                 &tab->ref,
5283
5088
                                                                 tab->found_records))))
5284
5089
      {
5285
 
        goto err;
 
5090
        return(-1);
5286
5091
      }
5287
5092
    }
5288
5093
  }
5289
5094
 
5290
 
  if (table->s->tmp_table)
 
5095
  if (table->getShare()->getType())
5291
5096
    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);
 
5097
 
 
5098
  FileSort filesort(*session);
 
5099
  table->sort.found_records=filesort.run(table,join->sortorder, length,
 
5100
                                         select, filesort_limit, 0,
 
5101
                                         examined_rows);
5295
5102
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5296
5103
  if (select)
5297
5104
  {
5309
5116
    table->key_read=0;
5310
5117
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5311
5118
  }
 
5119
 
5312
5120
  return(table->sort.found_records == HA_POS_ERROR);
5313
 
err:
5314
 
  return(-1);
5315
5121
}
5316
5122
 
5317
5123
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5320
5126
  char *org_record,*new_record;
5321
5127
  unsigned char *record;
5322
5128
  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);
 
5129
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
 
5130
 
 
5131
  org_record=(char*) (record=table->getInsertRecord())+offset;
 
5132
  new_record=(char*) table->getUpdateRecord()+offset;
 
5133
 
 
5134
  if ((error= cursor->startTableScan(1)))
 
5135
    goto err;
 
5136
 
5329
5137
  error=cursor->rnd_next(record);
5330
5138
  for (;;)
5331
5139
  {
5332
 
    if (session->killed)
 
5140
    if (session->getKilled())
5333
5141
    {
5334
5142
      session->send_kill_message();
5335
5143
      error=0;
5345
5153
    }
5346
5154
    if (having && !having->val_int())
5347
5155
    {
5348
 
      if ((error=cursor->ha_delete_row(record)))
 
5156
      if ((error=cursor->deleteRecord(record)))
5349
5157
        goto err;
5350
5158
      error=cursor->rnd_next(record);
5351
5159
      continue;
5372
5180
      }
5373
5181
      if (table->compare_record(first_field) == 0)
5374
5182
      {
5375
 
        if ((error=cursor->ha_delete_row(record)))
 
5183
        if ((error=cursor->deleteRecord(record)))
5376
5184
          goto err;
5377
5185
      }
5378
5186
      else if (!found)
5383
5191
    }
5384
5192
    if (!found)
5385
5193
      break;                                    // End of cursor
5386
 
    /* Restart search on next row */
5387
 
    error=cursor->restart_rnd_next(record,cursor->ref);
 
5194
    /* Move current position to the next row */
 
5195
    error= cursor->rnd_pos(record, cursor->ref);
5388
5196
  }
5389
5197
 
5390
5198
  cursor->extra(HA_EXTRA_NO_CACHE);
5409
5217
                               uint32_t key_length,
5410
5218
                               Item *having)
5411
5219
{
5412
 
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
 
5220
  unsigned char *key_pos, *record=table->getInsertRecord();
5413
5221
  int error;
5414
5222
  Cursor *cursor= table->cursor;
5415
5223
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5416
 
  uint32_t *field_lengths,*field_length;
 
5224
  uint32_t *field_length;
5417
5225
  HASH hash;
 
5226
  std::vector<unsigned char> key_buffer;
 
5227
  std::vector<uint32_t> field_lengths;
5418
5228
 
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);
 
5229
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
 
5230
  field_lengths.resize(field_count);
5427
5231
 
5428
5232
  {
5429
5233
    Field **ptr;
5430
5234
    uint32_t total_length= 0;
5431
 
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
 
5235
 
 
5236
    for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
5432
5237
    {
5433
5238
      uint32_t length= (*ptr)->sort_length();
5434
5239
      (*field_length++)= length;
5442
5247
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5443
5248
                key_length, (hash_get_key) 0, 0, 0))
5444
5249
  {
5445
 
    free((char*) key_buffer);
5446
5250
    return(1);
5447
5251
  }
5448
5252
 
5449
 
  cursor->ha_rnd_init(1);
5450
 
  key_pos=key_buffer;
 
5253
  if ((error= cursor->startTableScan(1)))
 
5254
    goto err;
 
5255
 
 
5256
  key_pos= &key_buffer[0];
5451
5257
  for (;;)
5452
5258
  {
5453
5259
    unsigned char *org_key_pos;
5454
 
    if (session->killed)
 
5260
    if (session->getKilled())
5455
5261
    {
5456
5262
      session->send_kill_message();
5457
5263
      error=0;
5467
5273
    }
5468
5274
    if (having && !having->val_int())
5469
5275
    {
5470
 
      if ((error=cursor->ha_delete_row(record)))
 
5276
      if ((error=cursor->deleteRecord(record)))
5471
5277
        goto err;
5472
5278
      continue;
5473
5279
    }
5474
5280
 
5475
5281
    /* copy fields to key buffer */
5476
5282
    org_key_pos= key_pos;
5477
 
    field_length=field_lengths;
 
5283
    field_length= &field_lengths[0];
5478
5284
    for (Field **ptr= first_field ; *ptr ; ptr++)
5479
5285
    {
5480
5286
      (*ptr)->sort_string(key_pos,*field_length);
5484
5290
    if (hash_search(&hash, org_key_pos, key_length))
5485
5291
    {
5486
5292
      /* Duplicated found ; Remove the row */
5487
 
      if ((error=cursor->ha_delete_row(record)))
 
5293
      if ((error=cursor->deleteRecord(record)))
5488
5294
        goto err;
5489
5295
    }
5490
5296
    else
5491
5297
      (void) my_hash_insert(&hash, org_key_pos);
5492
5298
    key_pos+=extra_length;
5493
5299
  }
5494
 
  free((char*) key_buffer);
5495
5300
  hash_free(&hash);
5496
5301
  cursor->extra(HA_EXTRA_NO_CACHE);
5497
 
  (void) cursor->ha_rnd_end();
 
5302
  (void) cursor->endTableScan();
5498
5303
  return(0);
5499
5304
 
5500
5305
err:
5501
 
  free((char*) key_buffer);
5502
5306
  hash_free(&hash);
5503
5307
  cursor->extra(HA_EXTRA_NO_CACHE);
5504
 
  (void) cursor->ha_rnd_end();
 
5308
  (void) cursor->endTableScan();
5505
5309
  if (error)
5506
5310
    table->print_error(error,MYF(0));
5507
5311
  return(1);
5508
5312
}
5509
5313
 
5510
 
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
 
5314
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
5511
5315
{
5512
5316
  uint32_t count;
5513
 
  SORT_FIELD *sort,*pos;
 
5317
  SortField *sort,*pos;
5514
5318
 
5515
5319
  count=0;
5516
 
  for (order_st *tmp = order; tmp; tmp=tmp->next)
 
5320
  for (Order *tmp = order; tmp; tmp=tmp->next)
5517
5321
    count++;
5518
5322
  if (!sortorder)
5519
 
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
 
5323
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
5520
5324
                                       (max(count, *length) + 1));
5521
5325
  pos= sort= sortorder;
5522
5326
 
5638
5442
static bool find_order_in_list(Session *session, 
5639
5443
                               Item **ref_pointer_array, 
5640
5444
                               TableList *tables,
5641
 
                               order_st *order,
 
5445
                               Order *order,
5642
5446
                               List<Item> &fields,
5643
5447
                               List<Item> &all_fields,
5644
5448
                               bool is_group_field)
5660
5464
    if (!count || count > fields.elements)
5661
5465
    {
5662
5466
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5663
 
               order_item->full_name(), session->where);
 
5467
               order_item->full_name(), session->where());
5664
5468
      return true;
5665
5469
    }
5666
5470
    order->item= ref_pointer_array + count - 1;
5670
5474
    return false;
5671
5475
  }
5672
5476
  /* Lookup the current GROUP/order_st field in the SELECT clause. */
5673
 
  select_item= find_item_in_list(order_item, fields, &counter,
 
5477
  select_item= find_item_in_list(session, order_item, fields, &counter,
5674
5478
                                 REPORT_EXCEPT_NOT_FOUND, &resolution);
5675
5479
  if (!select_item)
5676
5480
    return true; /* The item is not unique, or some other error occured. */
5737
5541
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5738
5542
                          ER(ER_NON_UNIQ_ERROR),
5739
5543
                          ((Item_ident*) order_item)->field_name,
5740
 
                          current_session->where);
 
5544
                          session->where());
5741
5545
    }
5742
5546
  }
5743
5547
 
5777
5581
                TableList *tables,
5778
5582
                            List<Item> &fields,
5779
5583
                List<Item> &all_fields,
5780
 
                order_st *order)
 
5584
                Order *order)
5781
5585
{
5782
 
  session->where="order clause";
 
5586
  session->setWhere("order clause");
5783
5587
  for (; order; order=order->next)
5784
5588
  {
5785
5589
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5819
5623
                TableList *tables,
5820
5624
                      List<Item> &fields,
5821
5625
                List<Item> &all_fields,
5822
 
                order_st *order,
 
5626
                Order *order,
5823
5627
                      bool *hidden_group_fields)
5824
5628
{
5825
5629
  *hidden_group_fields=0;
5826
 
  order_st *ord;
 
5630
  Order *ord;
5827
5631
 
5828
5632
  if (!order)
5829
5633
    return 0;                           /* Everything is ok */
5830
5634
 
5831
5635
  uint32_t org_fields=all_fields.elements;
5832
5636
 
5833
 
  session->where="group statement";
 
5637
  session->setWhere("group statement");
5834
5638
  for (ord= order; ord; ord= ord->next)
5835
5639
  {
5836
5640
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5913
5717
  Try to use the fields in the order given by 'order' to allow one to
5914
5718
  optimize away 'order by'.
5915
5719
*/
5916
 
order_st *create_distinct_group(Session *session,
 
5720
Order *create_distinct_group(Session *session,
5917
5721
                                Item **ref_pointer_array,
5918
 
                                order_st *order_list,
 
5722
                                Order *order_list,
5919
5723
                                List<Item> &fields,
5920
5724
                                List<Item> &,
5921
5725
                                bool *all_order_by_fields_used)
5922
5726
{
5923
5727
  List_iterator<Item> li(fields);
5924
5728
  Item *item;
5925
 
  order_st *order,*group,**prev;
 
5729
  Order *order,*group,**prev;
5926
5730
 
5927
5731
  *all_order_by_fields_used= 1;
5928
5732
  while ((item=li++))
5933
5737
  {
5934
5738
    if (order->in_field_list)
5935
5739
    {
5936
 
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
 
5740
      Order *ord=(Order*) session->memdup((char*) order,sizeof(Order));
5937
5741
      if (!ord)
5938
5742
        return 0;
5939
5743
      *prev=ord;
5953
5757
        Don't put duplicate columns from the SELECT list into the
5954
5758
        GROUP BY list.
5955
5759
      */
5956
 
      order_st *ord_iter;
 
5760
      Order *ord_iter;
5957
5761
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5958
5762
        if ((*ord_iter->item)->eq(item, 1))
5959
5763
          goto next_item;
5960
5764
 
5961
 
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
 
5765
      Order *ord=(Order*) session->calloc(sizeof(Order));
5962
5766
      if (!ord)
5963
5767
        return 0;
5964
5768
 
6145
5949
          saved value
6146
5950
        */
6147
5951
        field= item->field;
6148
 
        item->result_field=field->new_field(session->mem_root,field->table, 1);
 
5952
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
6149
5953
              /*
6150
5954
                We need to allocate one extra byte for null handling and
6151
5955
                another extra byte to not get warnings from purify in
6157
5961
        {
6158
5962
          copy->set(tmp, item->result_field);
6159
5963
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
6160
 
#ifdef HAVE_purify
 
5964
#ifdef HAVE_VALGRIND
6161
5965
          copy->to_ptr[copy->from_length]= 0;
6162
5966
#endif
6163
5967
          copy++;
6278
6082
      }
6279
6083
      else if ((field= item->get_tmp_table_field()))
6280
6084
      {
6281
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
 
6085
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
6282
6086
          item_field= ((Item_sum*) item)->result_item(field);
6283
6087
        else
6284
6088
          item_field= (Item*) new Item_field(field);
6430
6234
}
6431
6235
 
6432
6236
/** Copy result of functions to record in tmp_table. */
6433
 
void copy_funcs(Item **func_ptr)
 
6237
bool copy_funcs(Item **func_ptr, const Session *session)
6434
6238
{
6435
6239
  Item *func;
6436
6240
  for (; (func = *func_ptr) ; func_ptr++)
 
6241
  {
6437
6242
    func->save_in_result_field(1);
 
6243
    /*
 
6244
      Need to check the THD error state because Item::val_xxx() don't
 
6245
      return error code, but can generate errors
 
6246
      TODO: change it for a real status check when Item::val_xxx()
 
6247
      are extended to return status code.
 
6248
    */
 
6249
    if (session->is_error())
 
6250
      return true;
 
6251
  }
 
6252
  return false;
6438
6253
}
6439
6254
 
6440
6255
/**
6494
6309
  @retval
6495
6310
    1   on error
6496
6311
*/
6497
 
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
 
6312
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
6498
6313
{
6499
6314
  if (expr->arg_count)
6500
6315
  {
6508
6323
      Item *item= *arg;
6509
6324
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6510
6325
      {
6511
 
        order_st *group_tmp;
 
6326
        Order *group_tmp;
6512
6327
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6513
6328
        {
6514
6329
          if (item->eq(*group_tmp->item,0))
6591
6406
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6592
6407
{
6593
6408
  /* QQ: session may not be set for sub queries, but this should be fixed */
6594
 
  if (!session)
 
6409
  if(not session)
6595
6410
    session= current_session;
6596
6411
 
 
6412
 
6597
6413
  str->append(STRING_WITH_LEN("select "));
6598
6414
 
6599
6415
  /* First add options */
6659
6475
  if (group_list.elements)
6660
6476
  {
6661
6477
    str->append(STRING_WITH_LEN(" group by "));
6662
 
    print_order(str, (order_st *) group_list.first, query_type);
 
6478
    print_order(str, (Order *) group_list.first, query_type);
6663
6479
    switch (olap)
6664
6480
    {
6665
6481
      case CUBE_TYPE:
6690
6506
  if (order_list.elements)
6691
6507
  {
6692
6508
    str->append(STRING_WITH_LEN(" order by "));
6693
 
    print_order(str, (order_st *) order_list.first, query_type);
 
6509
    print_order(str, (Order *) order_list.first, query_type);
6694
6510
  }
6695
6511
 
6696
6512
  // limit