~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Brian Aker
  • Date: 2010-06-28 16:17:36 UTC
  • mfrom: (1637.4.1 drizzle)
  • Revision ID: brian@gaz-20100628161736-eormhb2mnd551i2h
Merge unused

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
/**
17
17
  @file
18
18
 
19
19
  @brief
20
 
  select_query and join optimization
 
20
  mysql_select and join optimization
21
21
 
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
51
51
#include "drizzled/index_hint.h"
52
52
#include "drizzled/records.h"
53
53
#include "drizzled/internal/iocache.h"
54
 
#include "drizzled/drizzled.h"
55
 
#include "drizzled/plugin/storage_engine.h"
56
54
 
57
55
#include "drizzled/sql_union.h"
58
56
#include "drizzled/optimizer/key_field.h"
63
61
#include "drizzled/optimizer/quick_range_select.h"
64
62
#include "drizzled/optimizer/quick_ror_intersect_select.h"
65
63
 
66
 
#include "drizzled/filesort.h"
67
 
 
68
64
using namespace std;
69
65
 
70
66
namespace drizzled
79
75
static Item* part_of_refkey(Table *form,Field *field);
80
76
static bool cmp_buffer_with_ref(JoinTable *tab);
81
77
static void change_cond_ref_to_const(Session *session,
82
 
                                     list<COND_CMP>& save_list,
 
78
                                     vector<COND_CMP>& save_list,
83
79
                                     Item *and_father,
84
80
                                     Item *cond,
85
81
                                     Item *field,
118
114
{
119
115
  bool res;
120
116
  register Select_Lex *select_lex= &lex->select_lex;
121
 
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
 
117
  DRIZZLE_SELECT_START(session->query.c_str());
122
118
 
123
119
  if (select_lex->master_unit()->is_union() ||
124
120
      select_lex->master_unit()->fake_select_lex)
132
128
    unit->set_limit(unit->global_parameters);
133
129
    session->session_marker= 0;
134
130
    /*
135
 
      'options' of select_query will be set in JOIN, as far as JOIN for
 
131
      'options' of mysql_select will be set in JOIN, as far as JOIN for
136
132
      every PS/SP execution new, we will not need reset this flag if
137
133
      setup_tables_done_option changed for next rexecution
138
134
    */
139
 
    res= select_query(session,
140
 
                      &select_lex->ref_pointer_array,
 
135
    res= mysql_select(session, &select_lex->ref_pointer_array,
141
136
                      (TableList*) select_lex->table_list.first,
142
 
                      select_lex->with_wild,
143
 
                      select_lex->item_list,
 
137
                      select_lex->with_wild, select_lex->item_list,
144
138
                      select_lex->where,
145
139
                      select_lex->order_list.elements +
146
140
                      select_lex->group_list.elements,
147
 
                      (Order*) select_lex->order_list.first,
148
 
                      (Order*) select_lex->group_list.first,
 
141
                      (order_st*) select_lex->order_list.first,
 
142
                      (order_st*) select_lex->group_list.first,
149
143
                      select_lex->having,
150
144
                      select_lex->options | session->options |
151
145
                      setup_tables_done_option,
271
265
 
272
266
/*****************************************************************************
273
267
  Check fields, find best join, do the select and output fields.
274
 
  select_query assumes that all tables are already opened
 
268
  mysql_select assumes that all tables are already opened
275
269
*****************************************************************************/
276
270
 
277
271
/*
351
345
  @retval
352
346
    true   an error
353
347
*/
354
 
bool select_query(Session *session,
 
348
bool mysql_select(Session *session,
355
349
                  Item ***rref_pointer_array,
356
350
                  TableList *tables, 
357
351
                  uint32_t wild_num, 
358
352
                  List<Item> &fields,
359
353
                  COND *conds, 
360
354
                  uint32_t og_num,  
361
 
                  Order *order,
362
 
                  Order *group,
 
355
                  order_st *order, 
 
356
                  order_st *group,
363
357
                  Item *having, 
364
358
                  uint64_t select_options,
365
359
                  select_result *result, 
453
447
  return (cond? (new Item_cond_and(cond, item)) : item);
454
448
}
455
449
 
 
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
 
456
463
/*****************************************************************************
457
464
  Create JoinTableS, make a guess about the table types,
458
465
  Approximate how many records will be used in each table
548
555
                         Select_Lex *select_lex,
549
556
                         vector<optimizer::SargableParam> &sargables)
550
557
{
551
 
  uint  and_level,found_eq_constant;
 
558
  uint  and_level,i,found_eq_constant;
552
559
  optimizer::KeyField *key_fields, *end, *field;
553
560
  uint32_t sz;
554
561
  uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
571
578
    substitutions.
572
579
  */
573
580
  sz= sizeof(optimizer::KeyField) *
574
 
      (((session->lex->current_select->cond_count+1)*2 +
 
581
      (((session->lex->current_select->cond_count+1) +
575
582
        session->lex->current_select->between_count)*m+1);
576
 
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
 
583
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
577
584
    return true;
578
585
  and_level= 0;
579
586
  field= end= key_fields;
591
598
      if (field->getValue()->type() == Item::NULL_ITEM &&
592
599
          ! field->getField()->real_maybe_null())
593
600
      {
594
 
        field->getField()->getTable()->reginfo.not_exists_optimize= 1;
 
601
        field->getField()->table->reginfo.not_exists_optimize= 1;
595
602
      }
596
603
    }
597
604
  }
598
 
  for (uint32_t i= 0; i < tables; i++)
 
605
  for (i= 0; i < tables; i++)
599
606
  {
600
607
    /*
601
608
      Block the creation of keys for inner tables of outer joins.
618
625
    TableList *table;
619
626
    while ((table= li++))
620
627
    {
621
 
      if (table->getNestedJoin())
 
628
      if (table->nested_join)
622
629
        add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
623
630
                              sargables);
624
631
    }
650
657
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
651
658
    prev= &key_end;
652
659
    found_eq_constant= 0;
 
660
    for (i= 0; i < keyuse->elements-1; i++, use++)
653
661
    {
654
 
      uint32_t i;
655
 
 
656
 
      for (i= 0; i < keyuse->elements-1; i++, use++)
 
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())
657
665
      {
658
 
        if (! use->getUsedTables() && use->getOptimizeFlags() != KEY_OPTIMIZE_REF_OR_NULL)
659
 
          use->getTable()->const_key_parts[use->getKey()]|= use->getKeypartMap();
660
 
        if (use->getKey() == prev->getKey() && use->getTable() == prev->getTable())
661
 
        {
662
 
          if (prev->getKeypart() + 1 < use->getKeypart() || 
663
 
              ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
664
 
            continue;                           /* remove */
665
 
        }
666
 
        else if (use->getKeypart() != 0)                // First found must be 0
667
 
          continue;
 
666
        if (prev->getKeypart() + 1 < use->getKeypart() || 
 
667
            ((prev->getKeypart() == use->getKeypart()) && found_eq_constant))
 
668
          continue;                             /* remove */
 
669
      }
 
670
      else if (use->getKeypart() != 0)          // First found must be 0
 
671
        continue;
668
672
 
669
 
#ifdef HAVE_VALGRIND
670
 
        /* Valgrind complains about overlapped memcpy when save_pos==use. */
671
 
        if (save_pos != use)
 
673
#ifdef HAVE_purify
 
674
      /* Valgrind complains about overlapped memcpy when save_pos==use. */
 
675
      if (save_pos != use)
672
676
#endif
673
 
          *save_pos= *use;
674
 
        prev=use;
675
 
        found_eq_constant= ! use->getUsedTables();
676
 
        /* Save ptr to first use */
677
 
        if (! use->getTable()->reginfo.join_tab->keyuse)
678
 
          use->getTable()->reginfo.join_tab->keyuse= save_pos;
679
 
        use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
680
 
        save_pos++;
681
 
      }
682
 
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
683
 
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
684
 
      keyuse->elements= i;
 
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++;
685
685
    }
 
686
    i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
 
687
    set_dynamic(keyuse, (unsigned char*) &key_end, i);
 
688
    keyuse->elements= i;
686
689
  }
687
690
  return false;
688
691
}
749
752
{
750
753
  List<Item_field> indexed_fields;
751
754
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
752
 
  Order      *cur_group;
 
755
  order_st      *cur_group;
753
756
  Item_field *cur_item;
754
757
  key_map possible_keys(0);
755
758
 
926
929
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
927
930
{
928
931
  bool error;
929
 
  Table *table= field->getTable();
 
932
  Table *table= field->table;
930
933
  Session *session= table->in_use;
931
934
  ha_rows cuted_fields=session->cuted_fields;
932
935
 
933
936
  /*
934
937
    we should restore old value of count_cuted_fields because
935
 
    store_val_in_field can be called from insert_query
 
938
    store_val_in_field can be called from mysql_insert
936
939
    with select_insert, which make count_cuted_fields= 1
937
940
   */
938
941
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1005
1008
  j->ref.key_length=length;
1006
1009
  j->ref.key=(int) key;
1007
1010
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1008
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1011
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1009
1012
               (keyparts+1)))) ||
1010
 
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
1011
 
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
 
1013
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1014
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1012
1015
  {
1013
1016
    return(true);
1014
1017
  }
1152
1155
          Item *notnull;
1153
1156
          assert(item->type() == Item::FIELD_ITEM);
1154
1157
          Item_field *not_null_item= (Item_field*)item;
1155
 
          JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
 
1158
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
1156
1159
          /*
1157
1160
            For UPDATE queries such as:
1158
1161
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
1209
1212
  return tmp;
1210
1213
}
1211
1214
 
 
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
 
1212
1299
#define ICP_COND_USES_INDEX_ONLY 10
1213
1300
 
 
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
}
1214
1450
 
1215
1451
/**
1216
1452
  cleanup JoinTable.
1222
1458
  delete quick;
1223
1459
  quick= 0;
1224
1460
  if (cache.buff)
1225
 
  {
1226
 
    size_t size= cache.end - cache.buff;
1227
 
    global_join_buffer.sub(size);
1228
1461
    free(cache.buff);
1229
 
  }
1230
1462
  cache.buff= 0;
1231
1463
  limit= 0;
1232
1464
  if (table)
1246
1478
  read_record.end_read_record();
1247
1479
}
1248
1480
 
1249
 
bool only_eq_ref_tables(Join *join,Order *order,table_map tables)
 
1481
bool only_eq_ref_tables(Join *join,order_st *order,table_map tables)
1250
1482
{
1251
1483
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1252
1484
  {
1275
1507
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
1276
1508
  @endcode
1277
1509
*/
1278
 
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
 
1510
bool eq_ref_table(Join *join, order_st *start_order, JoinTable *tab)
1279
1511
{
1280
1512
  if (tab->cached_eq_ref_table)                 // If cached
1281
1513
    return tab->eq_ref_table;
1294
1526
  {
1295
1527
    if (! (*ref_item)->const_item())
1296
1528
    {                                           // Not a const ref
1297
 
      Order *order;
 
1529
      order_st *order;
1298
1530
      for (order=start_order ; order ; order=order->next)
1299
1531
      {
1300
1532
        if ((*ref_item)->eq(order->item[0],0))
2034
2266
    {
2035
2267
      if (table->on_expr)
2036
2268
      {
2037
 
        List<TableList> *nested_join_list= table->getNestedJoin() ?
2038
 
          &table->getNestedJoin()->join_list : NULL;
 
2269
        List<TableList> *nested_join_list= table->nested_join ?
 
2270
          &table->nested_join->join_list : NULL;
2039
2271
        /*
2040
2272
          We can modify table->on_expr because its old value will
2041
2273
          be restored before re-execution of PS/SP.
2088
2320
  if (outer_ref)
2089
2321
    return cmp;
2090
2322
  JoinTable **idx= (JoinTable **) table_join_idx;
2091
 
  cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
 
2323
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
2092
2324
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
2093
2325
}
2094
2326
 
2308
2540
  @param cond       condition whose multiple equalities are to be checked
2309
2541
  @param table      constant table that has been read
2310
2542
*/
2311
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2543
static void update_const_equal_items(COND *cond, JoinTable *tab)
2312
2544
{
2313
2545
  if (!(cond->used_tables() & tab->table->map))
2314
2546
    return;
2335
2567
      while ((item_field= it++))
2336
2568
      {
2337
2569
        Field *field= item_field->field;
2338
 
        JoinTable *stat= field->getTable()->reginfo.join_tab;
 
2570
        JoinTable *stat= field->table->reginfo.join_tab;
2339
2571
        key_map possible_keys= field->key_start;
2340
 
        possible_keys&= field->getTable()->keys_in_use_for_query;
 
2572
        possible_keys&= field->table->keys_in_use_for_query;
2341
2573
        stat[0].const_keys|= possible_keys;
2342
2574
 
2343
2575
        /*
2347
2579
        */
2348
2580
        if (possible_keys.any())
2349
2581
        {
2350
 
          Table *field_tab= field->getTable();
 
2582
          Table *field_tab= field->table;
2351
2583
          optimizer::KeyUse *use;
2352
2584
          for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
2353
2585
            if (possible_keys.test(use->getKey()) &&
2365
2597
  and_level
2366
2598
*/
2367
2599
static void change_cond_ref_to_const(Session *session,
2368
 
                                     list<COND_CMP>& save_list,
 
2600
                                     vector<COND_CMP>& save_list,
2369
2601
                                     Item *and_father,
2370
2602
                                     Item *cond,
2371
2603
                                     Item *field,
2378
2610
    Item *item;
2379
2611
    while ((item=li++))
2380
2612
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2381
 
 
2382
2613
    return;
2383
2614
  }
2384
2615
  if (cond->eq_cmp_result() == Item::COND_OK)
2397
2628
       left_item->collation.collation == value->collation.collation))
2398
2629
  {
2399
2630
    Item *tmp=value->clone_item();
 
2631
    tmp->collation.set(right_item->collation);
 
2632
 
2400
2633
    if (tmp)
2401
2634
    {
2402
 
      tmp->collation.set(right_item->collation);
2403
2635
      session->change_item_tree(args + 1, tmp);
2404
2636
      func->update_used_tables();
2405
2637
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2419
2651
            right_item->collation.collation == value->collation.collation))
2420
2652
  {
2421
2653
    Item *tmp= value->clone_item();
 
2654
    tmp->collation.set(left_item->collation);
 
2655
 
2422
2656
    if (tmp)
2423
2657
    {
2424
 
      tmp->collation.set(left_item->collation);
2425
2658
      session->change_item_tree(args, tmp);
2426
2659
      value= tmp;
2427
2660
      func->update_used_tables();
2471
2704
}
2472
2705
 
2473
2706
static void propagate_cond_constants(Session *session, 
2474
 
                                     list<COND_CMP>& save_list, 
 
2707
                                     vector<COND_CMP>& save_list, 
2475
2708
                                     COND *and_father, 
2476
2709
                                     COND *cond)
2477
2710
{
2480
2713
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2481
2714
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2482
2715
    Item *item;
2483
 
    list<COND_CMP> save;
 
2716
    vector<COND_CMP> save;
2484
2717
    while ((item=li++))
2485
2718
    {
2486
2719
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2488
2721
    if (and_level)
2489
2722
    {
2490
2723
      // Handle other found items
2491
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2724
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2492
2725
      {
2493
 
        Item **args= iter->second->arguments();
2494
 
        if (not args[0]->const_item())
 
2726
        Item **args= iter->cmp_func->arguments();
 
2727
        if (!args[0]->const_item())
2495
2728
        {
2496
 
          change_cond_ref_to_const(session, save, iter->first,
2497
 
                                   iter->first, args[0], args[1] );
 
2729
          change_cond_ref_to_const( session, save, iter->and_level,
 
2730
                                    iter->and_level, args[0], args[1] );
2498
2731
        }
2499
2732
      }
2500
2733
    }
2607
2840
         position:
2608
2841
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2609
2842
             joins) we've opened but didn't close.
2610
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2843
          2. {each nested_join_st structure not simplified away}->counter - number
2611
2844
             of this nested join's children that have already been added to to
2612
2845
             the partial join order.
2613
2846
  @endverbatim
2614
2847
 
2615
2848
  @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)
2616
2851
  @param next_tab   Table we're going to extend the current partial join with
2617
2852
 
2618
2853
  @retval
2621
2856
  @retval
2622
2857
    true   Requested join order extension not allowed.
2623
2858
*/
2624
 
bool check_interleaving_with_nj(JoinTable *next_tab)
 
2859
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
2625
2860
{
2626
 
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
2627
 
  Join *join= next_tab->join;
 
2861
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
 
2862
  Join *join= last_tab->join;
2628
2863
 
2629
2864
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2630
2865
  {
2639
2874
    Do update counters for "pairs of brackets" that we've left (marked as
2640
2875
    X,Y,Z in the above picture)
2641
2876
  */
2642
 
  for (;next_emb; next_emb= next_emb->getEmbedding())
 
2877
  for (;next_emb; next_emb= next_emb->embedding)
2643
2878
  {
2644
 
    next_emb->getNestedJoin()->counter_++;
2645
 
    if (next_emb->getNestedJoin()->counter_ == 1)
 
2879
    next_emb->nested_join->counter_++;
 
2880
    if (next_emb->nested_join->counter_ == 1)
2646
2881
    {
2647
2882
      /*
2648
2883
        next_emb is the first table inside a nested join we've "entered". In
2649
2884
        the picture above, we're looking at the 'X' bracket. Don't exit yet as
2650
2885
        X bracket might have Y pair bracket.
2651
2886
      */
2652
 
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
 
2887
      join->cur_embedding_map |= next_emb->nested_join->nj_map;
2653
2888
    }
2654
2889
 
2655
 
    if (next_emb->getNestedJoin()->join_list.elements !=
2656
 
        next_emb->getNestedJoin()->counter_)
 
2890
    if (next_emb->nested_join->join_list.elements !=
 
2891
        next_emb->nested_join->counter_)
2657
2892
      break;
2658
2893
 
2659
2894
    /*
2660
2895
      We're currently at Y or Z-bracket as depicted in the above picture.
2661
2896
      Mark that we've left it and continue walking up the brackets hierarchy.
2662
2897
    */
2663
 
    join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
 
2898
    join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
2664
2899
  }
2665
2900
  return false;
2666
2901
}
2685
2920
                             &join->cond_equal);
2686
2921
 
2687
2922
    /* change field = field to field = const for each found field = const */
2688
 
    list<COND_CMP> temp;
 
2923
    vector<COND_CMP> temp;
2689
2924
    propagate_cond_constants(session, temp, conds, conds);
2690
2925
    /*
2691
2926
      Remove all instances of item == item
2788
3023
    {
2789
3024
      Field *field= ((Item_field*) args[0])->field;
2790
3025
      if (field->flags & AUTO_INCREMENT_FLAG 
2791
 
          && ! field->getTable()->maybe_null 
 
3026
          && ! field->table->maybe_null 
2792
3027
          && session->options & OPTION_AUTO_IS_NULL
2793
3028
          && (
2794
3029
            session->first_successful_insert_id_in_prev_stmt > 0 
2846
3081
  /*
2847
3082
    TODO:
2848
3083
    Excluding all expensive functions is too restritive we should exclude only
2849
 
    materialized IN subquery predicates because they can't yet be evaluated
2850
 
    here (they need additional initialization that is done later on).
2851
 
 
2852
 
    The proper way to exclude the subqueries would be to walk the cond tree and
2853
 
    check for materialized subqueries there.
2854
 
 
 
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()))
2855
3090
  */
2856
3091
  {
2857
3092
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
3054
3289
    table->emptyRecord();
3055
3290
    if (table->group && join->tmp_table_param.sum_func_count &&
3056
3291
        table->getShare()->sizeKeys() && !table->cursor->inited)
3057
 
    {
3058
 
      int tmp_error;
3059
 
      tmp_error= table->cursor->startIndexScan(0, 0);
3060
 
      if (tmp_error != 0)
3061
 
      {
3062
 
        table->print_error(tmp_error, MYF(0));
3063
 
        return -1;
3064
 
      }
3065
 
    }
 
3292
      table->cursor->startIndexScan(0, 0);
3066
3293
  }
3067
3294
  /* Set up select_end */
3068
3295
  Next_select_func end_select= setup_end_select_func(join);
3159
3386
      rc= sub_select(join,join_tab,end_of_records);
3160
3387
    return rc;
3161
3388
  }
3162
 
  if (join->session->getKilled())               // If aborted by user
 
3389
  if (join->session->killed)            // If aborted by user
3163
3390
  {
3164
3391
    join->session->send_kill_message();
3165
3392
    return NESTED_LOOP_KILLED;
3360
3587
{
3361
3588
  int error;
3362
3589
  Table *table= tab->table;
3363
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3590
  if ((error=table->cursor->index_read_map(table->record[0],
3364
3591
                                         tab->ref.key_buff,
3365
3592
                                         make_prev_keypart_map(tab->ref.key_parts),
3366
3593
                                         HA_READ_KEY_EXACT)))
3368
3595
  return 0;
3369
3596
}
3370
3597
 
 
3598
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3599
{
 
3600
  int error;
 
3601
  Table *table=tab->table;
 
3602
  table->const_table=1;
 
3603
  table->null_row=0;
 
3604
  table->status=STATUS_NO_RECORD;
 
3605
 
 
3606
  if (tab->type == AM_SYSTEM)
 
3607
  {
 
3608
    if ((error=join_read_system(tab)))
 
3609
    {                                           // Info for DESCRIBE
 
3610
      tab->info="const row not found";
 
3611
      /* Mark for EXPLAIN that the row was not found */
 
3612
      pos->setFanout(0.0);
 
3613
      pos->clearRefDependMap();
 
3614
      if (! table->maybe_null || error > 0)
 
3615
        return(error);
 
3616
    }
 
3617
  }
 
3618
  else
 
3619
  {
 
3620
    if (! table->key_read && 
 
3621
        table->covering_keys.test(tab->ref.key) && 
 
3622
        ! table->no_keyread &&
 
3623
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3624
    {
 
3625
      table->key_read=1;
 
3626
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3627
      tab->index= tab->ref.key;
 
3628
    }
 
3629
    error=join_read_const(tab);
 
3630
    if (table->key_read)
 
3631
    {
 
3632
      table->key_read=0;
 
3633
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3634
    }
 
3635
    if (error)
 
3636
    {
 
3637
      tab->info="unique row not found";
 
3638
      /* Mark for EXPLAIN that the row was not found */
 
3639
      pos->setFanout(0.0);
 
3640
      pos->clearRefDependMap();
 
3641
      if (!table->maybe_null || error > 0)
 
3642
        return(error);
 
3643
    }
 
3644
  }
 
3645
  if (*tab->on_expr_ref && !table->null_row)
 
3646
  {
 
3647
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3648
      table->mark_as_null_row();
 
3649
  }
 
3650
  if (!table->null_row)
 
3651
    table->maybe_null=0;
 
3652
 
 
3653
  /* Check appearance of new constant items in Item_equal objects */
 
3654
  Join *join= tab->join;
 
3655
  if (join->conds)
 
3656
    update_const_equal_items(join->conds, tab);
 
3657
  TableList *tbl;
 
3658
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3659
  {
 
3660
    TableList *embedded;
 
3661
    TableList *embedding= tbl;
 
3662
    do
 
3663
    {
 
3664
      embedded= embedding;
 
3665
      if (embedded->on_expr)
 
3666
         update_const_equal_items(embedded->on_expr, tab);
 
3667
      embedding= embedded->embedding;
 
3668
    }
 
3669
    while (embedding &&
 
3670
           embedding->nested_join->join_list.head() == embedded);
 
3671
  }
 
3672
 
 
3673
  return(0);
 
3674
}
 
3675
 
 
3676
int join_read_system(JoinTable *tab)
 
3677
{
 
3678
  Table *table= tab->table;
 
3679
  int error;
 
3680
  if (table->status & STATUS_GARBAGE)           // If first read
 
3681
  {
 
3682
    if ((error=table->cursor->read_first_row(table->record[0],
 
3683
                                           table->getShare()->getPrimaryKey())))
 
3684
    {
 
3685
      if (error != HA_ERR_END_OF_FILE)
 
3686
        return table->report_error(error);
 
3687
      tab->table->mark_as_null_row();
 
3688
      table->emptyRecord();                     // Make empty record
 
3689
      return -1;
 
3690
    }
 
3691
    table->storeRecord();
 
3692
  }
 
3693
  else if (!table->status)                      // Only happens with left join
 
3694
    table->restoreRecord();                     // restore old record
 
3695
  table->null_row=0;
 
3696
  return table->status ? -1 : 0;
 
3697
}
 
3698
 
3371
3699
/**
3372
3700
  Read a (constant) table when there is at most one matching row.
3373
3701
 
3391
3719
      error= HA_ERR_KEY_NOT_FOUND;
3392
3720
    else
3393
3721
    {
3394
 
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
 
3722
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
3395
3723
                                            (unsigned char*) tab->ref.key_buff,
3396
3724
                                            make_prev_keypart_map(tab->ref.key_parts),
3397
3725
                                            HA_READ_KEY_EXACT);
3439
3767
 
3440
3768
  if (!table->cursor->inited)
3441
3769
  {
3442
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3443
 
    if (error != 0)
3444
 
    {
3445
 
      table->print_error(error, MYF(0));
3446
 
    }
 
3770
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3447
3771
  }
3448
3772
 
3449
3773
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3455
3779
      table->status=STATUS_NOT_FOUND;
3456
3780
      return -1;
3457
3781
    }
3458
 
    error=table->cursor->index_read_map(table->getInsertRecord(),
 
3782
    error=table->cursor->index_read_map(table->record[0],
3459
3783
                                      tab->ref.key_buff,
3460
3784
                                      make_prev_keypart_map(tab->ref.key_parts),
3461
3785
                                      HA_READ_KEY_EXACT);
3491
3815
 
3492
3816
  /* Initialize the index first */
3493
3817
  if (!table->cursor->inited)
3494
 
  {
3495
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3496
 
    if (error != 0)
3497
 
      return table->report_error(error);
3498
 
  }
 
3818
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3499
3819
 
3500
3820
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3501
3821
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3506
3826
 
3507
3827
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3508
3828
    return -1;
3509
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3829
  if ((error=table->cursor->index_read_map(table->record[0],
3510
3830
                                         tab->ref.key_buff,
3511
3831
                                         make_prev_keypart_map(tab->ref.key_parts),
3512
3832
                                         HA_READ_KEY_EXACT)))
3529
3849
  Table *table= tab->table;
3530
3850
 
3531
3851
  if (!table->cursor->inited)
3532
 
  {
3533
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3534
 
    if (error != 0)
3535
 
      return table->report_error(error);
3536
 
  }
 
3852
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3537
3853
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3538
3854
    return -1;
3539
 
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
 
3855
  if ((error=table->cursor->index_read_last_map(table->record[0],
3540
3856
                                              tab->ref.key_buff,
3541
3857
                                              make_prev_keypart_map(tab->ref.key_parts))))
3542
3858
  {
3565
3881
      /* Save index tuple from record to the buffer */
3566
3882
      key_copy(tab->insideout_buf, info->record, key, 0);
3567
3883
 
3568
 
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3884
      if ((error=table->cursor->index_next_same(table->record[0],
3569
3885
                                              tab->ref.key_buff,
3570
3886
                                              tab->ref.key_length)))
3571
3887
      {
3589
3905
  Table *table= info->table;
3590
3906
  JoinTable *tab=table->reginfo.join_tab;
3591
3907
 
3592
 
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3908
  if ((error=table->cursor->index_next_same(table->record[0],
3593
3909
                                          tab->ref.key_buff,
3594
3910
                                          tab->ref.key_length)))
3595
3911
  {
3608
3924
  Table *table= info->table;
3609
3925
  JoinTable *tab=table->reginfo.join_tab;
3610
3926
 
3611
 
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
 
3927
  if ((error=table->cursor->index_prev(table->record[0])))
3612
3928
    return table->report_error(error);
3613
3929
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3614
3930
                      tab->ref.key_length))
3648
3964
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3649
3965
    return 1;
3650
3966
 
3651
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3652
 
    return 1;
 
3967
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3653
3968
 
3654
3969
  return (*tab->read_record.read_record)(&tab->read_record);
3655
3970
}
3668
3983
  tab->read_record.table=table;
3669
3984
  tab->read_record.cursor=table->cursor;
3670
3985
  tab->read_record.index=tab->index;
3671
 
  tab->read_record.record=table->getInsertRecord();
 
3986
  tab->read_record.record=table->record[0];
3672
3987
  if (tab->insideout_match_tab)
3673
3988
  {
3674
3989
    tab->read_record.do_insideout_scan= tab;
3682
3997
  }
3683
3998
 
3684
3999
  if (!table->cursor->inited)
3685
 
  {
3686
 
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
3687
 
    if (error != 0)
3688
 
    {
3689
 
      table->report_error(error);
3690
 
      return -1;
3691
 
    }
3692
 
  }
3693
 
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
 
4000
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
4001
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
3694
4002
  {
3695
4003
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3696
4004
      table->report_error(error);
3746
4054
  tab->read_record.table=table;
3747
4055
  tab->read_record.cursor=table->cursor;
3748
4056
  tab->read_record.index=tab->index;
3749
 
  tab->read_record.record=table->getInsertRecord();
 
4057
  tab->read_record.record=table->record[0];
3750
4058
  if (!table->cursor->inited)
3751
 
  {
3752
 
    error= table->cursor->startIndexScan(tab->index, 1);
3753
 
    if (error != 0)
3754
 
      return table->report_error(error);
3755
 
  }
3756
 
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
 
4059
    table->cursor->startIndexScan(tab->index, 1);
 
4060
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
3757
4061
    return table->report_error(error);
3758
4062
 
3759
4063
  return 0;
3832
4136
              error=join->result->send_data(*join->fields) ? 1 : 0;
3833
4137
            join->send_records++;
3834
4138
          }
3835
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
4139
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3836
4140
          {
3837
4141
            if (join->rollup_send_data((uint32_t) (idx+1)))
3838
4142
              error= 1;
3893
4197
  Table *table=join->tmp_table;
3894
4198
  int     idx= -1;
3895
4199
 
3896
 
  if (join->session->getKilled())
 
4200
  if (join->session->killed)
3897
4201
  {                                             // Aborted by user
3898
4202
    join->session->send_kill_message();
3899
4203
    return NESTED_LOOP_KILLED;
3914
4218
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
3915
4219
        if (!join->having || join->having->val_int())
3916
4220
        {
3917
 
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
4221
          int error= table->cursor->insertRecord(table->record[0]);
3918
4222
 
3919
4223
          if (error)
3920
4224
          {
3922
4226
            return NESTED_LOOP_ERROR;
3923
4227
          }
3924
4228
        }
3925
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
4229
        if (join->rollup.state != ROLLUP::STATE_NONE)
3926
4230
        {
3927
4231
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3928
4232
            return NESTED_LOOP_ERROR;
3941
4245
    if (idx < (int) join->send_group_parts)
3942
4246
    {
3943
4247
      copy_fields(&join->tmp_table_param);
3944
 
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3945
 
        return NESTED_LOOP_ERROR;
 
4248
      copy_funcs(join->tmp_table_param.items_to_copy);
3946
4249
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
3947
4250
        return NESTED_LOOP_ERROR;
3948
4251
      return NESTED_LOOP_OK;
3959
4262
  outer join table.
3960
4263
  We can't remove tests that are made against columns which are stored
3961
4264
  in sorted order.
 
4265
*****************************************************************************/
 
4266
 
 
4267
/**
3962
4268
  @return
3963
 
    1 if right_item used is a removable reference key on left_item
3964
 
    0 otherwise.
3965
 
****************************************************************************/
 
4269
    1 if right_item is used removable reference key on left_item
 
4270
*/
3966
4271
bool test_if_ref(Item_field *left_item,Item *right_item)
3967
4272
{
3968
4273
  Field *field=left_item->field;
3969
4274
  // No need to change const test. We also have to keep tests on LEFT JOIN
3970
 
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
 
4275
  if (!field->table->const_table && !field->table->maybe_null)
3971
4276
  {
3972
 
    Item *ref_item=part_of_refkey(field->getTable(),field);
 
4277
    Item *ref_item=part_of_refkey(field->table,field);
3973
4278
    if (ref_item && ref_item->eq(right_item,1))
3974
4279
    {
3975
4280
      right_item= right_item->real_item();
4163
4468
    }
4164
4469
 
4165
4470
    for (part=0 ; part < ref_parts ; part++,key_part++)
4166
 
    {
4167
4471
      if (field->eq(key_part->field) &&
4168
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4169
 
          //If field can be NULL, we should not remove this predicate, as
4170
 
          //it may lead to non-rejection of NULL values. 
4171
 
          !(field->real_maybe_null()))
4172
 
      {
 
4472
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
4173
4473
        return table->reginfo.join_tab->ref.items[part];
4174
 
      }
4175
 
    }
4176
4474
  }
4177
4475
  return (Item*) 0;
4178
4476
}
4197
4495
  @retval
4198
4496
    -1   Reverse key can be used
4199
4497
*/
4200
 
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4498
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4201
4499
{
4202
4500
  KeyPartInfo *key_part= NULL;
4203
4501
  KeyPartInfo *key_part_end= NULL;
4303
4601
    - MAX_KEY                   If we can't use other key
4304
4602
    - the number of found key   Otherwise
4305
4603
*/
4306
 
static uint32_t test_if_subkey(Order *order,
 
4604
static uint32_t test_if_subkey(order_st *order,
4307
4605
                               Table *table,
4308
4606
                               uint32_t ref,
4309
4607
                               uint32_t ref_key_parts,
4405
4703
*/
4406
4704
bool find_field_in_order_list (Field *field, void *data)
4407
4705
{
4408
 
  Order *group= (Order *) data;
 
4706
  order_st *group= (order_st *) data;
4409
4707
  bool part_found= 0;
4410
 
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4708
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4411
4709
  {
4412
4710
    Item *item= (*tmp_group->item)->real_item();
4413
4711
    if (item->type() == Item::FIELD_ITEM &&
4477
4775
  @retval
4478
4776
    1    We can use an index.
4479
4777
*/
4480
 
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4778
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
4481
4779
{
4482
4780
  int32_t ref_key;
4483
4781
  uint32_t ref_key_parts;
4494
4792
  */
4495
4793
  usable_keys= *map;
4496
4794
 
4497
 
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4795
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4498
4796
  {
4499
4797
    Item *item= (*tmp_order->item)->real_item();
4500
4798
    if (item->type() != Item::FIELD_ITEM)
4920
5218
    -1          Some fatal error
4921
5219
    1           No records
4922
5220
*/
4923
 
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
5221
int create_sort_index(Session *session, Join *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
4924
5222
{
4925
5223
  uint32_t length= 0;
4926
5224
  ha_rows examined_rows;
4947
5245
                              is_order_by ?  &table->keys_in_use_for_order_by :
4948
5246
                              &table->keys_in_use_for_group_by))
4949
5247
    return(0);
4950
 
  for (Order *ord= join->order; ord; ord= ord->next)
 
5248
  for (order_st *ord= join->order; ord; ord= ord->next)
4951
5249
    length++;
4952
 
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
4953
 
  {
4954
 
    return(-1);
4955
 
  }
 
5250
  if (!(join->sortorder=
 
5251
        make_unireg_sortorder(order, &length, join->sortorder)))
 
5252
    goto err;
4956
5253
 
4957
5254
  table->sort.io_cache= new internal::IO_CACHE;
4958
5255
  table->status=0;                              // May be wrong if quick_select
4987
5284
                                                                 &tab->ref,
4988
5285
                                                                 tab->found_records))))
4989
5286
      {
4990
 
        return(-1);
 
5287
        goto err;
4991
5288
      }
4992
5289
    }
4993
5290
  }
4994
5291
 
4995
5292
  if (table->getShare()->getType())
4996
5293
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
4997
 
 
4998
 
  FileSort filesort(*session);
4999
 
  table->sort.found_records=filesort.run(table,join->sortorder, length,
5000
 
                                         select, filesort_limit, 0,
5001
 
                                         examined_rows);
 
5294
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
5295
                                     select, filesort_limit, 0,
 
5296
                                     &examined_rows);
5002
5297
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5003
5298
  if (select)
5004
5299
  {
5016
5311
    table->key_read=0;
5017
5312
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5018
5313
  }
5019
 
 
5020
5314
  return(table->sort.found_records == HA_POS_ERROR);
 
5315
err:
 
5316
  return(-1);
5021
5317
}
5022
5318
 
5023
5319
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5028
5324
  int error;
5029
5325
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
5030
5326
 
5031
 
  org_record=(char*) (record=table->getInsertRecord())+offset;
5032
 
  new_record=(char*) table->getUpdateRecord()+offset;
5033
 
 
5034
 
  if ((error= cursor->startTableScan(1)))
5035
 
    goto err;
5036
 
 
 
5327
  org_record=(char*) (record=table->record[0])+offset;
 
5328
  new_record=(char*) table->record[1]+offset;
 
5329
 
 
5330
  cursor->startTableScan(1);
5037
5331
  error=cursor->rnd_next(record);
5038
5332
  for (;;)
5039
5333
  {
5040
 
    if (session->getKilled())
 
5334
    if (session->killed)
5041
5335
    {
5042
5336
      session->send_kill_message();
5043
5337
      error=0;
5117
5411
                               uint32_t key_length,
5118
5412
                               Item *having)
5119
5413
{
5120
 
  unsigned char *key_pos, *record=table->getInsertRecord();
 
5414
  unsigned char *key_pos, *record=table->record[0];
5121
5415
  int error;
5122
5416
  Cursor *cursor= table->cursor;
5123
5417
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5150
5444
    return(1);
5151
5445
  }
5152
5446
 
5153
 
  if ((error= cursor->startTableScan(1)))
5154
 
    goto err;
5155
 
 
 
5447
  cursor->startTableScan(1);
5156
5448
  key_pos= &key_buffer[0];
5157
5449
  for (;;)
5158
5450
  {
5159
5451
    unsigned char *org_key_pos;
5160
 
    if (session->getKilled())
 
5452
    if (session->killed)
5161
5453
    {
5162
5454
      session->send_kill_message();
5163
5455
      error=0;
5211
5503
  return(1);
5212
5504
}
5213
5505
 
5214
 
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
 
5506
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
5215
5507
{
5216
5508
  uint32_t count;
5217
 
  SortField *sort,*pos;
 
5509
  SORT_FIELD *sort,*pos;
5218
5510
 
5219
5511
  count=0;
5220
 
  for (Order *tmp = order; tmp; tmp=tmp->next)
 
5512
  for (order_st *tmp = order; tmp; tmp=tmp->next)
5221
5513
    count++;
5222
5514
  if (!sortorder)
5223
 
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
 
5515
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
5224
5516
                                       (max(count, *length) + 1));
5225
5517
  pos= sort= sortorder;
5226
5518
 
5342
5634
static bool find_order_in_list(Session *session, 
5343
5635
                               Item **ref_pointer_array, 
5344
5636
                               TableList *tables,
5345
 
                               Order *order,
 
5637
                               order_st *order,
5346
5638
                               List<Item> &fields,
5347
5639
                               List<Item> &all_fields,
5348
5640
                               bool is_group_field)
5364
5656
    if (!count || count > fields.elements)
5365
5657
    {
5366
5658
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5367
 
               order_item->full_name(), session->where());
 
5659
               order_item->full_name(), session->where);
5368
5660
      return true;
5369
5661
    }
5370
5662
    order->item= ref_pointer_array + count - 1;
5441
5733
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5442
5734
                          ER(ER_NON_UNIQ_ERROR),
5443
5735
                          ((Item_ident*) order_item)->field_name,
5444
 
                          session->where());
 
5736
                          session->where);
5445
5737
    }
5446
5738
  }
5447
5739
 
5481
5773
                TableList *tables,
5482
5774
                            List<Item> &fields,
5483
5775
                List<Item> &all_fields,
5484
 
                Order *order)
 
5776
                order_st *order)
5485
5777
{
5486
 
  session->setWhere("order clause");
 
5778
  session->where="order clause";
5487
5779
  for (; order; order=order->next)
5488
5780
  {
5489
5781
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5523
5815
                TableList *tables,
5524
5816
                      List<Item> &fields,
5525
5817
                List<Item> &all_fields,
5526
 
                Order *order,
 
5818
                order_st *order,
5527
5819
                      bool *hidden_group_fields)
5528
5820
{
5529
5821
  *hidden_group_fields=0;
5530
 
  Order *ord;
 
5822
  order_st *ord;
5531
5823
 
5532
5824
  if (!order)
5533
5825
    return 0;                           /* Everything is ok */
5534
5826
 
5535
5827
  uint32_t org_fields=all_fields.elements;
5536
5828
 
5537
 
  session->setWhere("group statement");
 
5829
  session->where="group statement";
5538
5830
  for (ord= order; ord; ord= ord->next)
5539
5831
  {
5540
5832
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5617
5909
  Try to use the fields in the order given by 'order' to allow one to
5618
5910
  optimize away 'order by'.
5619
5911
*/
5620
 
Order *create_distinct_group(Session *session,
 
5912
order_st *create_distinct_group(Session *session,
5621
5913
                                Item **ref_pointer_array,
5622
 
                                Order *order_list,
 
5914
                                order_st *order_list,
5623
5915
                                List<Item> &fields,
5624
5916
                                List<Item> &,
5625
5917
                                bool *all_order_by_fields_used)
5626
5918
{
5627
5919
  List_iterator<Item> li(fields);
5628
5920
  Item *item;
5629
 
  Order *order,*group,**prev;
 
5921
  order_st *order,*group,**prev;
5630
5922
 
5631
5923
  *all_order_by_fields_used= 1;
5632
5924
  while ((item=li++))
5637
5929
  {
5638
5930
    if (order->in_field_list)
5639
5931
    {
5640
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5932
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
5641
5933
      if (!ord)
5642
5934
        return 0;
5643
5935
      *prev=ord;
5657
5949
        Don't put duplicate columns from the SELECT list into the
5658
5950
        GROUP BY list.
5659
5951
      */
5660
 
      Order *ord_iter;
 
5952
      order_st *ord_iter;
5661
5953
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5662
5954
        if ((*ord_iter->item)->eq(item, 1))
5663
5955
          goto next_item;
5664
5956
 
5665
 
      Order *ord=(Order*) session->calloc(sizeof(Order));
 
5957
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
5666
5958
      if (!ord)
5667
5959
        return 0;
5668
5960
 
5849
6141
          saved value
5850
6142
        */
5851
6143
        field= item->field;
5852
 
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
 
6144
        item->result_field=field->new_field(session->mem_root,field->table, 1);
5853
6145
              /*
5854
6146
                We need to allocate one extra byte for null handling and
5855
6147
                another extra byte to not get warnings from purify in
5861
6153
        {
5862
6154
          copy->set(tmp, item->result_field);
5863
6155
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
5864
 
#ifdef HAVE_VALGRIND
 
6156
#ifdef HAVE_purify
5865
6157
          copy->to_ptr[copy->from_length]= 0;
5866
6158
#endif
5867
6159
          copy++;
5982
6274
      }
5983
6275
      else if ((field= item->get_tmp_table_field()))
5984
6276
      {
5985
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
 
6277
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
5986
6278
          item_field= ((Item_sum*) item)->result_item(field);
5987
6279
        else
5988
6280
          item_field= (Item*) new Item_field(field);
6134
6426
}
6135
6427
 
6136
6428
/** Copy result of functions to record in tmp_table. */
6137
 
bool copy_funcs(Item **func_ptr, const Session *session)
 
6429
void copy_funcs(Item **func_ptr)
6138
6430
{
6139
6431
  Item *func;
6140
6432
  for (; (func = *func_ptr) ; func_ptr++)
6141
 
  {
6142
6433
    func->save_in_result_field(1);
6143
 
    /*
6144
 
      Need to check the THD error state because Item::val_xxx() don't
6145
 
      return error code, but can generate errors
6146
 
      TODO: change it for a real status check when Item::val_xxx()
6147
 
      are extended to return status code.
6148
 
    */
6149
 
    if (session->is_error())
6150
 
      return true;
6151
 
  }
6152
 
  return false;
6153
6434
}
6154
6435
 
6155
6436
/**
6209
6490
  @retval
6210
6491
    1   on error
6211
6492
*/
6212
 
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
 
6493
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
6213
6494
{
6214
6495
  if (expr->arg_count)
6215
6496
  {
6223
6504
      Item *item= *arg;
6224
6505
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6225
6506
      {
6226
 
        Order *group_tmp;
 
6507
        order_st *group_tmp;
6227
6508
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6228
6509
        {
6229
6510
          if (item->eq(*group_tmp->item,0))
6292
6573
{
6293
6574
  /* List is reversed => we should reverse it before using */
6294
6575
  List_iterator_fast<TableList> ti(*tables);
6295
 
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
6576
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6296
6577
                                                tables->elements);
6297
6578
  if (table == 0)
6298
6579
    return;  // out of memory
6306
6587
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6307
6588
{
6308
6589
  /* QQ: session may not be set for sub queries, but this should be fixed */
6309
 
  if(not session)
6310
 
    session= current_session;
6311
 
 
 
6590
  assert(session);
6312
6591
 
6313
6592
  str->append(STRING_WITH_LEN("select "));
6314
6593
 
6375
6654
  if (group_list.elements)
6376
6655
  {
6377
6656
    str->append(STRING_WITH_LEN(" group by "));
6378
 
    print_order(str, (Order *) group_list.first, query_type);
 
6657
    print_order(str, (order_st *) group_list.first, query_type);
6379
6658
    switch (olap)
6380
6659
    {
6381
6660
      case CUBE_TYPE:
6406
6685
  if (order_list.elements)
6407
6686
  {
6408
6687
    str->append(STRING_WITH_LEN(" order by "));
6409
 
    print_order(str, (Order *) order_list.first, query_type);
 
6688
    print_order(str, (order_st *) order_list.first, query_type);
6410
6689
  }
6411
6690
 
6412
6691
  // limit