~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2010-05-15 18:23:34 UTC
  • mto: (1530.6.1)
  • mto: This revision was merged to the branch mainline in revision 1556.
  • Revision ID: mordred@inaugust.com-20100515182334-bgbmwij0mioklajx
Renamed classes that were in drizzled::plugin but which were not meant
for consumption by plugin authors to drizzled::module - since they
really have to do with plugin module loading. This way when we
look in drizzled/plugin, we see nothing but plugin interfaces. Win.

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