~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Monty Taylor
  • Date: 2010-07-19 05:06:59 UTC
  • mto: (1662.1.2 rollup)
  • mto: This revision was merged to the branch mainline in revision 1663.
  • Revision ID: mordred@inaugust.com-20100719050659-if3thz0k66m1jkaf
Backed out two bits that snuck in to the merge.

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
  @{
24
24
*/
25
 
#include <config.h>
 
25
#include "config.h"
26
26
 
27
27
#include <string>
28
28
#include <iostream>
29
29
#include <algorithm>
30
30
#include <vector>
31
31
 
32
 
#include <drizzled/sql_select.h> /* include join.h */
33
 
 
34
 
#include <drizzled/error.h>
35
 
#include <drizzled/gettext.h>
36
 
#include <drizzled/util/test.h>
37
 
#include <drizzled/name_resolution_context_state.h>
38
 
#include <drizzled/nested_join.h>
39
 
#include <drizzled/probes.h>
40
 
#include <drizzled/show.h>
41
 
#include <drizzled/item/cache.h>
42
 
#include <drizzled/item/cmpfunc.h>
43
 
#include <drizzled/item/copy_string.h>
44
 
#include <drizzled/item/uint.h>
45
 
#include <drizzled/cached_item.h>
46
 
#include <drizzled/sql_base.h>
47
 
#include <drizzled/field/blob.h>
48
 
#include <drizzled/check_stack_overrun.h>
49
 
#include <drizzled/lock.h>
50
 
#include <drizzled/item/outer_ref.h>
51
 
#include <drizzled/index_hint.h>
52
 
#include <drizzled/records.h>
53
 
#include <drizzled/internal/iocache.h>
54
 
#include <drizzled/drizzled.h>
55
 
#include <drizzled/plugin/storage_engine.h>
56
 
 
57
 
#include <drizzled/sql_union.h>
58
 
#include <drizzled/optimizer/key_field.h>
59
 
#include <drizzled/optimizer/position.h>
60
 
#include <drizzled/optimizer/sargable_param.h>
61
 
#include <drizzled/optimizer/key_use.h>
62
 
#include <drizzled/optimizer/range.h>
63
 
#include <drizzled/optimizer/quick_range_select.h>
64
 
#include <drizzled/optimizer/quick_ror_intersect_select.h>
65
 
 
66
 
#include <drizzled/filesort.h>
67
 
#include <drizzled/sql_lex.h>
68
 
#include <drizzled/session.h>
69
 
#include <drizzled/sort_field.h>
70
 
#include <drizzled/select_result.h>
 
32
#include "drizzled/sql_select.h" /* include join.h */
 
33
 
 
34
#include "drizzled/error.h"
 
35
#include "drizzled/gettext.h"
 
36
#include "drizzled/util/test.h"
 
37
#include "drizzled/name_resolution_context_state.h"
 
38
#include "drizzled/nested_join.h"
 
39
#include "drizzled/probes.h"
 
40
#include "drizzled/show.h"
 
41
#include "drizzled/item/cache.h"
 
42
#include "drizzled/item/cmpfunc.h"
 
43
#include "drizzled/item/copy_string.h"
 
44
#include "drizzled/item/uint.h"
 
45
#include "drizzled/cached_item.h"
 
46
#include "drizzled/sql_base.h"
 
47
#include "drizzled/field/blob.h"
 
48
#include "drizzled/check_stack_overrun.h"
 
49
#include "drizzled/lock.h"
 
50
#include "drizzled/item/outer_ref.h"
 
51
#include "drizzled/index_hint.h"
 
52
#include "drizzled/records.h"
 
53
#include "drizzled/internal/iocache.h"
 
54
 
 
55
#include "drizzled/sql_union.h"
 
56
#include "drizzled/optimizer/key_field.h"
 
57
#include "drizzled/optimizer/position.h"
 
58
#include "drizzled/optimizer/sargable_param.h"
 
59
#include "drizzled/optimizer/key_use.h"
 
60
#include "drizzled/optimizer/range.h"
 
61
#include "drizzled/optimizer/quick_range_select.h"
 
62
#include "drizzled/optimizer/quick_ror_intersect_select.h"
71
63
 
72
64
using namespace std;
73
65
 
83
75
static Item* part_of_refkey(Table *form,Field *field);
84
76
static bool cmp_buffer_with_ref(JoinTable *tab);
85
77
static void change_cond_ref_to_const(Session *session,
86
 
                                     list<COND_CMP>& save_list,
 
78
                                     vector<COND_CMP>& save_list,
87
79
                                     Item *and_father,
88
80
                                     Item *cond,
89
81
                                     Item *field,
122
114
{
123
115
  bool res;
124
116
  register Select_Lex *select_lex= &lex->select_lex;
125
 
  DRIZZLE_SELECT_START(session->getQueryString()->c_str());
 
117
  DRIZZLE_SELECT_START(session->query.c_str());
126
118
 
127
119
  if (select_lex->master_unit()->is_union() ||
128
120
      select_lex->master_unit()->fake_select_lex)
136
128
    unit->set_limit(unit->global_parameters);
137
129
    session->session_marker= 0;
138
130
    /*
139
 
      '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
140
132
      every PS/SP execution new, we will not need reset this flag if
141
133
      setup_tables_done_option changed for next rexecution
142
134
    */
143
 
    res= select_query(session,
144
 
                      &select_lex->ref_pointer_array,
 
135
    res= mysql_select(session, &select_lex->ref_pointer_array,
145
136
                      (TableList*) select_lex->table_list.first,
146
 
                      select_lex->with_wild,
147
 
                      select_lex->item_list,
 
137
                      select_lex->with_wild, select_lex->item_list,
148
138
                      select_lex->where,
149
139
                      select_lex->order_list.elements +
150
140
                      select_lex->group_list.elements,
151
 
                      (Order*) select_lex->order_list.first,
152
 
                      (Order*) select_lex->group_list.first,
 
141
                      (order_st*) select_lex->order_list.first,
 
142
                      (order_st*) select_lex->group_list.first,
153
143
                      select_lex->having,
154
144
                      select_lex->options | session->options |
155
145
                      setup_tables_done_option,
212
202
  bool res= false;
213
203
  bool direct_ref= false;
214
204
 
215
 
  List<Item_outer_ref>::iterator ref_it(select->inner_refs_list.begin());
 
205
  List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
216
206
  while ((ref= ref_it++))
217
207
  {
218
208
    Item *item= ref->outer_ref;
219
209
    Item **item_ref= ref->ref;
220
210
    Item_ref *new_ref;
221
211
    /*
222
 
      @todo this field item already might be present in the select list.
 
212
      TODO: this field item already might be present in the select list.
223
213
      In this case instead of adding new field item we could use an
224
214
      existing one. The change will lead to less operations for copying fields,
225
215
      smaller temporary tables and less data passed through filesort.
275
265
 
276
266
/*****************************************************************************
277
267
  Check fields, find best join, do the select and output fields.
278
 
  select_query assumes that all tables are already opened
 
268
  mysql_select assumes that all tables are already opened
279
269
*****************************************************************************/
280
270
 
281
271
/*
355
345
  @retval
356
346
    true   an error
357
347
*/
358
 
bool select_query(Session *session,
 
348
bool mysql_select(Session *session,
359
349
                  Item ***rref_pointer_array,
360
350
                  TableList *tables, 
361
351
                  uint32_t wild_num, 
362
352
                  List<Item> &fields,
363
353
                  COND *conds, 
364
354
                  uint32_t og_num,  
365
 
                  Order *order,
366
 
                  Order *group,
 
355
                  order_st *order, 
 
356
                  order_st *group,
367
357
                  Item *having, 
368
358
                  uint64_t select_options,
369
359
                  select_result *result, 
425
415
    goto err; // 1
426
416
  }
427
417
 
428
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
418
  if (session->lex->describe & DESCRIBE_EXTENDED)
429
419
  {
430
420
    join->conds_history= join->conds;
431
421
    join->having_history= (join->having?join->having:join->tmp_having);
436
426
 
437
427
  join->exec();
438
428
 
439
 
  if (session->getLex()->describe & DESCRIBE_EXTENDED)
 
429
  if (session->lex->describe & DESCRIBE_EXTENDED)
440
430
  {
441
431
    select_lex->where= join->conds_history;
442
432
    select_lex->having= join->having_history;
457
447
  return (cond? (new Item_cond_and(cond, item)) : item);
458
448
}
459
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->getNestedJoin())
 
459
      fix_list_after_tbl_changes(new_parent, &table->getNestedJoin()->join_list);
 
460
  }
 
461
}
 
462
 
460
463
/*****************************************************************************
461
464
  Create JoinTableS, make a guess about the table types,
462
465
  Approximate how many records will be used in each table
575
578
    substitutions.
576
579
  */
577
580
  sz= sizeof(optimizer::KeyField) *
578
 
      (((session->getLex()->current_select->cond_count+1)*2 +
579
 
        session->getLex()->current_select->between_count)*m+1);
580
 
  if (! (key_fields= (optimizer::KeyField*) session->getMemRoot()->allocate(sz)))
 
581
      (((session->lex->current_select->cond_count+1)*2 +
 
582
        session->lex->current_select->between_count)*m+1);
 
583
  if (! (key_fields= (optimizer::KeyField*) session->alloc(sz)))
581
584
    return true;
582
585
  and_level= 0;
583
586
  field= end= key_fields;
618
621
 
619
622
  /* Process ON conditions for the nested joins */
620
623
  {
621
 
    List<TableList>::iterator li(join_tab->join->join_list->begin());
 
624
    List_iterator<TableList> li(*join_tab->join->join_list);
622
625
    TableList *table;
623
626
    while ((table= li++))
624
627
    {
670
673
        else if (use->getKeypart() != 0)                // First found must be 0
671
674
          continue;
672
675
 
673
 
#ifdef HAVE_VALGRIND
 
676
#ifdef HAVE_purify
674
677
        /* Valgrind complains about overlapped memcpy when save_pos==use. */
675
678
        if (save_pos != use)
676
679
#endif
752
755
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
753
756
{
754
757
  List<Item_field> indexed_fields;
755
 
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
756
 
  Order      *cur_group;
 
758
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
 
759
  order_st      *cur_group;
757
760
  Item_field *cur_item;
758
761
  key_map possible_keys(0);
759
762
 
766
769
  else if (join->select_distinct)
767
770
  { /* Collect all query fields referenced in the SELECT clause. */
768
771
    List<Item> &select_items= join->fields_list;
769
 
    List<Item>::iterator select_items_it(select_items.begin());
 
772
    List_iterator<Item> select_items_it(select_items);
770
773
    Item *item;
771
774
    while ((item= select_items_it++))
772
775
      item->walk(&Item::collect_item_field_processor, 0,
936
939
 
937
940
  /*
938
941
    we should restore old value of count_cuted_fields because
939
 
    store_val_in_field can be called from insert_query
 
942
    store_val_in_field can be called from mysql_insert
940
943
    with select_insert, which make count_cuted_fields= 1
941
944
   */
942
945
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1009
1012
  j->ref.key_length=length;
1010
1013
  j->ref.key=(int) key;
1011
1014
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1012
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1015
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1013
1016
               (keyparts+1)))) ||
1014
 
      !(j->ref.items=    (Item**) session->getMemRoot()->allocate(sizeof(Item*)*keyparts)) ||
1015
 
      !(j->ref.cond_guards= (bool**) session->getMemRoot()->allocate(sizeof(uint*)*keyparts)))
 
1017
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1018
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1016
1019
  {
1017
1020
    return(true);
1018
1021
  }
1213
1216
  return tmp;
1214
1217
}
1215
1218
 
 
1219
/*
 
1220
  Check if given expression uses only table fields covered by the given index
 
1221
 
 
1222
  SYNOPSIS
 
1223
    uses_index_fields_only()
 
1224
      item           Expression to check
 
1225
      tbl            The table having the index
 
1226
      keyno          The index number
 
1227
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
 
1228
 
 
1229
  DESCRIPTION
 
1230
    Check if given expression only uses fields covered by index #keyno in the
 
1231
    table tbl. The expression can use any fields in any other tables.
 
1232
 
 
1233
    The expression is guaranteed not to be AND or OR - those constructs are
 
1234
    handled outside of this function.
 
1235
 
 
1236
  RETURN
 
1237
    true   Yes
 
1238
    false  No
 
1239
*/
 
1240
static bool uses_index_fields_only(Item *item, Table *tbl, uint32_t keyno, bool other_tbls_ok)
 
1241
{
 
1242
  if (item->const_item())
 
1243
    return true;
 
1244
 
 
1245
  /*
 
1246
    Don't push down the triggered conditions. Nested outer joins execution
 
1247
    code may need to evaluate a condition several times (both triggered and
 
1248
    untriggered), and there is no way to put thi
 
1249
    TODO: Consider cloning the triggered condition and using the copies for:
 
1250
      1. push the first copy down, to have most restrictive index condition
 
1251
         possible
 
1252
      2. Put the second copy into tab->select_cond.
 
1253
  */
 
1254
  if (item->type() == Item::FUNC_ITEM &&
 
1255
      ((Item_func*)item)->functype() == Item_func::TRIG_COND_FUNC)
 
1256
    return false;
 
1257
 
 
1258
  if (!(item->used_tables() & tbl->map))
 
1259
    return other_tbls_ok;
 
1260
 
 
1261
  Item::Type item_type= item->type();
 
1262
  switch (item_type) {
 
1263
  case Item::FUNC_ITEM:
 
1264
    {
 
1265
      /* This is a function, apply condition recursively to arguments */
 
1266
      Item_func *item_func= (Item_func*)item;
 
1267
      Item **child;
 
1268
      Item **item_end= (item_func->arguments()) + item_func->argument_count();
 
1269
      for (child= item_func->arguments(); child != item_end; child++)
 
1270
      {
 
1271
        if (!uses_index_fields_only(*child, tbl, keyno, other_tbls_ok))
 
1272
          return false;
 
1273
      }
 
1274
      return true;
 
1275
    }
 
1276
  case Item::COND_ITEM:
 
1277
    {
 
1278
      /* This is a function, apply condition recursively to arguments */
 
1279
      List_iterator<Item> li(*((Item_cond*)item)->argument_list());
 
1280
      Item *list_item;
 
1281
      while ((list_item=li++))
 
1282
      {
 
1283
        if (!uses_index_fields_only(item, tbl, keyno, other_tbls_ok))
 
1284
          return false;
 
1285
      }
 
1286
      return true;
 
1287
    }
 
1288
  case Item::FIELD_ITEM:
 
1289
    {
 
1290
      Item_field *item_field= (Item_field*)item;
 
1291
      if (item_field->field->getTable() != tbl)
 
1292
        return true;
 
1293
      return item_field->field->part_of_key.test(keyno);
 
1294
    }
 
1295
  case Item::REF_ITEM:
 
1296
    return uses_index_fields_only(item->real_item(), tbl, keyno,
 
1297
                                  other_tbls_ok);
 
1298
  default:
 
1299
    return false; /* Play it safe, don't push unknown non-const items */
 
1300
  }
 
1301
}
 
1302
 
1216
1303
#define ICP_COND_USES_INDEX_ONLY 10
1217
1304
 
 
1305
/*
 
1306
  Get a part of the condition that can be checked using only index fields
 
1307
 
 
1308
  SYNOPSIS
 
1309
    make_cond_for_index()
 
1310
      cond           The source condition
 
1311
      table          The table that is partially available
 
1312
      keyno          The index in the above table. Only fields covered by the index
 
1313
                     are available
 
1314
      other_tbls_ok  true <=> Fields of other non-const tables are allowed
 
1315
 
 
1316
  DESCRIPTION
 
1317
    Get a part of the condition that can be checked when for the given table
 
1318
    we have values only of fields covered by some index. The condition may
 
1319
    refer to other tables, it is assumed that we have values of all of their
 
1320
    fields.
 
1321
 
 
1322
    Example:
 
1323
      make_cond_for_index(
 
1324
         "cond(t1.field) AND cond(t2.key1) AND cond(t2.non_key) AND cond(t2.key2)",
 
1325
          t2, keyno(t2.key1))
 
1326
      will return
 
1327
        "cond(t1.field) AND cond(t2.key2)"
 
1328
 
 
1329
  RETURN
 
1330
    Index condition, or NULL if no condition could be inferred.
 
1331
*/
 
1332
static Item *make_cond_for_index(Item *cond, Table *table, uint32_t keyno, bool other_tbls_ok)
 
1333
{
 
1334
  if (!cond)
 
1335
    return NULL;
 
1336
  if (cond->type() == Item::COND_ITEM)
 
1337
  {
 
1338
    uint32_t n_marked= 0;
 
1339
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
 
1340
    {
 
1341
      Item_cond_and *new_cond=new Item_cond_and;
 
1342
      if (!new_cond)
 
1343
        return (COND*) 0;
 
1344
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1345
      Item *item;
 
1346
      while ((item=li++))
 
1347
      {
 
1348
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
 
1349
        if (fix)
 
1350
          new_cond->argument_list()->push_back(fix);
 
1351
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
 
1352
      }
 
1353
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
 
1354
        cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1355
      switch (new_cond->argument_list()->elements) {
 
1356
      case 0:
 
1357
        return (COND*) 0;
 
1358
      case 1:
 
1359
        return new_cond->argument_list()->head();
 
1360
      default:
 
1361
        new_cond->quick_fix_field();
 
1362
        return new_cond;
 
1363
      }
 
1364
    }
 
1365
    else /* It's OR */
 
1366
    {
 
1367
      Item_cond_or *new_cond=new Item_cond_or;
 
1368
      if (!new_cond)
 
1369
        return (COND*) 0;
 
1370
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1371
      Item *item;
 
1372
      while ((item=li++))
 
1373
      {
 
1374
        Item *fix= make_cond_for_index(item, table, keyno, other_tbls_ok);
 
1375
        if (!fix)
 
1376
          return (COND*) 0;
 
1377
        new_cond->argument_list()->push_back(fix);
 
1378
        n_marked += test(item->marker == ICP_COND_USES_INDEX_ONLY);
 
1379
      }
 
1380
      if (n_marked ==((Item_cond*)cond)->argument_list()->elements)
 
1381
        cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1382
      new_cond->quick_fix_field();
 
1383
      new_cond->top_level_item();
 
1384
      return new_cond;
 
1385
    }
 
1386
  }
 
1387
 
 
1388
  if (!uses_index_fields_only(cond, table, keyno, other_tbls_ok))
 
1389
    return (COND*) 0;
 
1390
  cond->marker= ICP_COND_USES_INDEX_ONLY;
 
1391
  return cond;
 
1392
}
 
1393
 
 
1394
 
 
1395
static Item *make_cond_remainder(Item *cond, bool exclude_index)
 
1396
{
 
1397
  if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
 
1398
    return 0; /* Already checked */
 
1399
 
 
1400
  if (cond->type() == Item::COND_ITEM)
 
1401
  {
 
1402
    table_map tbl_map= 0;
 
1403
    if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
 
1404
    {
 
1405
      /* Create new top level AND item */
 
1406
      Item_cond_and *new_cond=new Item_cond_and;
 
1407
      if (!new_cond)
 
1408
        return (COND*) 0;
 
1409
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1410
      Item *item;
 
1411
      while ((item=li++))
 
1412
      {
 
1413
        Item *fix= make_cond_remainder(item, exclude_index);
 
1414
        if (fix)
 
1415
        {
 
1416
          new_cond->argument_list()->push_back(fix);
 
1417
          tbl_map |= fix->used_tables();
 
1418
        }
 
1419
      }
 
1420
      switch (new_cond->argument_list()->elements) {
 
1421
      case 0:
 
1422
        return (COND*) 0;
 
1423
      case 1:
 
1424
        return new_cond->argument_list()->head();
 
1425
      default:
 
1426
        new_cond->quick_fix_field();
 
1427
        ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
 
1428
        return new_cond;
 
1429
      }
 
1430
    }
 
1431
    else /* It's OR */
 
1432
    {
 
1433
      Item_cond_or *new_cond=new Item_cond_or;
 
1434
      if (!new_cond)
 
1435
        return (COND*) 0;
 
1436
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
 
1437
      Item *item;
 
1438
      while ((item=li++))
 
1439
      {
 
1440
        Item *fix= make_cond_remainder(item, false);
 
1441
        if (!fix)
 
1442
          return (COND*) 0;
 
1443
        new_cond->argument_list()->push_back(fix);
 
1444
        tbl_map |= fix->used_tables();
 
1445
      }
 
1446
      new_cond->quick_fix_field();
 
1447
      ((Item_cond*)new_cond)->used_tables_cache= tbl_map;
 
1448
      new_cond->top_level_item();
 
1449
      return new_cond;
 
1450
    }
 
1451
  }
 
1452
  return cond;
 
1453
}
1218
1454
 
1219
1455
/**
1220
1456
  cleanup JoinTable.
1221
1457
*/
1222
1458
void JoinTable::cleanup()
1223
1459
{
1224
 
  safe_delete(select);
1225
 
  safe_delete(quick);
1226
 
 
 
1460
  delete select;
 
1461
  select= 0;
 
1462
  delete quick;
 
1463
  quick= 0;
1227
1464
  if (cache.buff)
1228
 
  {
1229
 
    size_t size= cache.end - cache.buff;
1230
 
    global_join_buffer.sub(size);
1231
1465
    free(cache.buff);
1232
 
  }
1233
1466
  cache.buff= 0;
1234
1467
  limit= 0;
1235
1468
  if (table)
1249
1482
  read_record.end_read_record();
1250
1483
}
1251
1484
 
1252
 
bool only_eq_ref_tables(Join *join,Order *order,table_map tables)
 
1485
bool only_eq_ref_tables(Join *join,order_st *order,table_map tables)
1253
1486
{
1254
1487
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1255
1488
  {
1278
1511
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
1279
1512
  @endcode
1280
1513
*/
1281
 
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
 
1514
bool eq_ref_table(Join *join, order_st *start_order, JoinTable *tab)
1282
1515
{
1283
1516
  if (tab->cached_eq_ref_table)                 // If cached
1284
1517
    return tab->eq_ref_table;
1297
1530
  {
1298
1531
    if (! (*ref_item)->const_item())
1299
1532
    {                                           // Not a const ref
1300
 
      Order *order;
 
1533
      order_st *order;
1301
1534
      for (order=start_order ; order ; order=order->next)
1302
1535
      {
1303
1536
        if ((*ref_item)->eq(order->item[0],0))
1352
1585
  bool in_upper_level= false;
1353
1586
  while (cond_equal)
1354
1587
  {
1355
 
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1588
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
1356
1589
    while ((item= li++))
1357
1590
    {
1358
1591
      if (item->contains(field))
1517
1750
        /* Merge two multiple equalities forming a new one */
1518
1751
        left_item_equal->merge(right_item_equal);
1519
1752
        /* Remove the merged multiple equality from the list */
1520
 
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1753
        List_iterator<Item_equal> li(cond_equal->current_level);
1521
1754
        while ((li++) != right_item_equal) {};
1522
1755
        li.remove();
1523
1756
      }
1657
1890
                                       (Item_row *) right_item,
1658
1891
                                       cond_equal, eq_list);
1659
1892
      if (!is_converted)
1660
 
        session->getLex()->current_select->cond_count++;
 
1893
        session->lex->current_select->cond_count++;
1661
1894
    }
1662
1895
    else
1663
1896
    {
1664
1897
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1665
 
      session->getLex()->current_select->cond_count++;
 
1898
      session->lex->current_select->cond_count++;
1666
1899
    }
1667
1900
 
1668
1901
    if (!is_converted)
1718
1951
    if (left_item->type() == Item::ROW_ITEM &&
1719
1952
        right_item->type() == Item::ROW_ITEM)
1720
1953
    {
1721
 
      session->getLex()->current_select->cond_count--;
 
1954
      session->lex->current_select->cond_count--;
1722
1955
      return check_row_equality(session,
1723
1956
                                (Item_row *) left_item,
1724
1957
                                (Item_row *) right_item,
1749
1982
    just an argument of a comparison predicate.
1750
1983
    The function also determines the maximum number of members in
1751
1984
    equality lists of each Item_cond_and object assigning it to
1752
 
    session->getLex()->current_select->max_equal_elems.
 
1985
    session->lex->current_select->max_equal_elems.
1753
1986
 
1754
1987
  @note
1755
1988
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1806
2039
      Item_func::COND_AND_FUNC;
1807
2040
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1808
2041
 
1809
 
    List<Item>::iterator li(args->begin());
 
2042
    List_iterator<Item> li(*args);
1810
2043
    Item *item;
1811
2044
 
1812
2045
    if (and_level)
1828
2061
          li.remove();
1829
2062
      }
1830
2063
 
1831
 
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
2064
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
1832
2065
      while ((item_equal= it++))
1833
2066
      {
1834
2067
        item_equal->fix_length_and_dec();
1835
2068
        item_equal->update_used_tables();
1836
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2069
        set_if_bigger(session->lex->current_select->max_equal_elems,
1837
2070
                      item_equal->members());
1838
2071
      }
1839
2072
 
1844
2077
       Make replacement of equality predicates for lower levels
1845
2078
       of the condition expression.
1846
2079
    */
1847
 
    li= args->begin();
 
2080
    li.rewind();
1848
2081
    while ((item= li++))
1849
2082
    {
1850
2083
      Item *new_item;
1892
2125
        }
1893
2126
        else
1894
2127
          item_equal= (Item_equal *) eq_list.pop();
1895
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2128
        set_if_bigger(session->lex->current_select->max_equal_elems,
1896
2129
                      item_equal->members());
1897
2130
        return item_equal;
1898
2131
      }
1905
2138
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
2139
        and_cond->quick_fix_field();
1907
2140
        List<Item> *args= and_cond->argument_list();
1908
 
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
2141
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
2142
        while ((item_equal= it++))
1910
2143
        {
1911
2144
          item_equal->fix_length_and_dec();
1912
2145
          item_equal->update_used_tables();
1913
 
          set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2146
          set_if_bigger(session->lex->current_select->max_equal_elems,
1914
2147
                        item_equal->members());
1915
2148
        }
1916
2149
        and_cond->cond_equal= cond_equal;
2031
2264
  if (join_list)
2032
2265
  {
2033
2266
    TableList *table;
2034
 
    List<TableList>::iterator li(join_list->begin());
 
2267
    List_iterator<TableList> li(*join_list);
2035
2268
 
2036
2269
    while ((table= li++))
2037
2270
    {
2246
2479
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2247
2480
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2248
2481
 
2249
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2482
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2250
2483
      while ((item_equal= it++))
2251
2484
      {
2252
2485
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2253
2486
      }
2254
2487
    }
2255
2488
 
2256
 
    List<Item>::iterator li(cond_list->begin());
 
2489
    List_iterator<Item> li(*cond_list);
2257
2490
    Item *item;
2258
2491
    while ((item= li++))
2259
2492
    {
2269
2502
 
2270
2503
    if (and_level)
2271
2504
    {
2272
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2505
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2273
2506
      while ((item_equal= it++))
2274
2507
      {
2275
2508
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2311
2544
  @param cond       condition whose multiple equalities are to be checked
2312
2545
  @param table      constant table that has been read
2313
2546
*/
2314
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2547
static void update_const_equal_items(COND *cond, JoinTable *tab)
2315
2548
{
2316
2549
  if (!(cond->used_tables() & tab->table->map))
2317
2550
    return;
2319
2552
  if (cond->type() == Item::COND_ITEM)
2320
2553
  {
2321
2554
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2322
 
    List<Item>::iterator li(cond_list->begin());
 
2555
    List_iterator_fast<Item> li(*cond_list);
2323
2556
    Item *item;
2324
2557
    while ((item= li++))
2325
2558
      update_const_equal_items(item, tab);
2368
2601
  and_level
2369
2602
*/
2370
2603
static void change_cond_ref_to_const(Session *session,
2371
 
                                     list<COND_CMP>& save_list,
 
2604
                                     vector<COND_CMP>& save_list,
2372
2605
                                     Item *and_father,
2373
2606
                                     Item *cond,
2374
2607
                                     Item *field,
2377
2610
  if (cond->type() == Item::COND_ITEM)
2378
2611
  {
2379
2612
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2380
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2613
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2381
2614
    Item *item;
2382
2615
    while ((item=li++))
2383
2616
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2384
 
 
2385
2617
    return;
2386
2618
  }
2387
2619
  if (cond->eq_cmp_result() == Item::COND_OK)
2400
2632
       left_item->collation.collation == value->collation.collation))
2401
2633
  {
2402
2634
    Item *tmp=value->clone_item();
 
2635
    tmp->collation.set(right_item->collation);
 
2636
 
2403
2637
    if (tmp)
2404
2638
    {
2405
 
      tmp->collation.set(right_item->collation);
2406
2639
      session->change_item_tree(args + 1, tmp);
2407
2640
      func->update_used_tables();
2408
2641
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2422
2655
            right_item->collation.collation == value->collation.collation))
2423
2656
  {
2424
2657
    Item *tmp= value->clone_item();
 
2658
    tmp->collation.set(left_item->collation);
 
2659
 
2425
2660
    if (tmp)
2426
2661
    {
2427
 
      tmp->collation.set(left_item->collation);
2428
2662
      session->change_item_tree(args, tmp);
2429
2663
      value= tmp;
2430
2664
      func->update_used_tables();
2457
2691
  if (conds->type() == Item::COND_ITEM)
2458
2692
  {
2459
2693
    Item_cond *cnd= (Item_cond*) conds;
2460
 
    List<Item>::iterator li(cnd->argument_list()->begin());
 
2694
    List_iterator<Item> li(*(cnd->argument_list()));
2461
2695
    Item *item;
2462
2696
    while ((item= li++))
2463
2697
    {
2474
2708
}
2475
2709
 
2476
2710
static void propagate_cond_constants(Session *session, 
2477
 
                                     list<COND_CMP>& save_list, 
 
2711
                                     vector<COND_CMP>& save_list, 
2478
2712
                                     COND *and_father, 
2479
2713
                                     COND *cond)
2480
2714
{
2481
2715
  if (cond->type() == Item::COND_ITEM)
2482
2716
  {
2483
2717
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2718
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2485
2719
    Item *item;
2486
 
    list<COND_CMP> save;
 
2720
    vector<COND_CMP> save;
2487
2721
    while ((item=li++))
2488
2722
    {
2489
2723
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2491
2725
    if (and_level)
2492
2726
    {
2493
2727
      // Handle other found items
2494
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2728
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2495
2729
      {
2496
 
        Item **args= iter->second->arguments();
2497
 
        if (not args[0]->const_item())
 
2730
        Item **args= iter->cmp_func->arguments();
 
2731
        if (!args[0]->const_item())
2498
2732
        {
2499
 
          change_cond_ref_to_const(session, save, iter->first,
2500
 
                                   iter->first, args[0], args[1] );
 
2733
          change_cond_ref_to_const( session, save, iter->and_level,
 
2734
                                    iter->and_level, args[0], args[1] );
2501
2735
        }
2502
2736
      }
2503
2737
    }
2610
2844
         position:
2611
2845
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2612
2846
             joins) we've opened but didn't close.
2613
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2847
          2. {each nested_join_st structure not simplified away}->counter - number
2614
2848
             of this nested join's children that have already been added to to
2615
2849
             the partial join order.
2616
2850
  @endverbatim
2617
2851
 
2618
2852
  @param join       Join being processed
 
2853
  @param last_tab   Last table in current partial join order (this function is
 
2854
                    not called for empty partial join orders)
2619
2855
  @param next_tab   Table we're going to extend the current partial join with
2620
2856
 
2621
2857
  @retval
2624
2860
  @retval
2625
2861
    true   Requested join order extension not allowed.
2626
2862
*/
2627
 
bool check_interleaving_with_nj(JoinTable *next_tab)
 
2863
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
2628
2864
{
2629
2865
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
2630
 
  Join *join= next_tab->join;
 
2866
  Join *join= last_tab->join;
2631
2867
 
2632
2868
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2633
2869
  {
2688
2924
                             &join->cond_equal);
2689
2925
 
2690
2926
    /* change field = field to field = const for each found field = const */
2691
 
    list<COND_CMP> temp;
 
2927
    vector<COND_CMP> temp;
2692
2928
    propagate_cond_constants(session, temp, conds, conds);
2693
2929
    /*
2694
2930
      Remove all instances of item == item
2715
2951
  {
2716
2952
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2717
2953
 
2718
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2954
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2719
2955
    Item::cond_result tmp_cond_value;
2720
2956
    bool should_fix_fields= false;
2721
2957
 
2769
3005
    {                                           
2770
3006
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2771
3007
      item= ((Item_cond*) cond)->argument_list()->head();
2772
 
      ((Item_cond*) cond)->argument_list()->clear();
 
3008
      ((Item_cond*) cond)->argument_list()->empty();
2773
3009
      return item;
2774
3010
    }
2775
3011
  }
2847
3083
  }
2848
3084
  else if (cond->const_item() && !cond->is_expensive())
2849
3085
  /*
2850
 
    @todo
 
3086
    TODO:
2851
3087
    Excluding all expensive functions is too restritive we should exclude only
2852
 
    materialized IN subquery predicates because they can't yet be evaluated
2853
 
    here (they need additional initialization that is done later on).
2854
 
 
2855
 
    The proper way to exclude the subqueries would be to walk the cond tree and
2856
 
    check for materialized subqueries there.
2857
 
 
 
3088
    materialized IN because it is created later than this phase, and cannot be
 
3089
    evaluated at this point.
 
3090
    The condition should be something as (need to fix member access):
 
3091
      !(cond->type() == Item::FUNC_ITEM &&
 
3092
        ((Item_func*)cond)->func_name() == "<in_optimizer>" &&
 
3093
        ((Item_in_optimizer*)cond)->is_expensive()))
2858
3094
  */
2859
3095
  {
2860
3096
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
2919
3155
  {
2920
3156
    bool and_level= (((Item_cond*) cond)->functype()
2921
3157
                     == Item_func::COND_AND_FUNC);
2922
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
3158
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2923
3159
    Item *item;
2924
3160
    while ((item=li++))
2925
3161
    {
3057
3293
    table->emptyRecord();
3058
3294
    if (table->group && join->tmp_table_param.sum_func_count &&
3059
3295
        table->getShare()->sizeKeys() && !table->cursor->inited)
3060
 
    {
3061
 
      int tmp_error;
3062
 
      tmp_error= table->cursor->startIndexScan(0, 0);
3063
 
      if (tmp_error != 0)
3064
 
      {
3065
 
        table->print_error(tmp_error, MYF(0));
3066
 
        return -1;
3067
 
      }
3068
 
    }
 
3296
      table->cursor->startIndexScan(0, 0);
3069
3297
  }
3070
3298
  /* Set up select_end */
3071
3299
  Next_select_func end_select= setup_end_select_func(join);
3162
3390
      rc= sub_select(join,join_tab,end_of_records);
3163
3391
    return rc;
3164
3392
  }
3165
 
  if (join->session->getKilled())               // If aborted by user
 
3393
  if (join->session->killed)            // If aborted by user
3166
3394
  {
3167
3395
    join->session->send_kill_message();
3168
3396
    return NESTED_LOOP_KILLED;
3363
3591
{
3364
3592
  int error;
3365
3593
  Table *table= tab->table;
3366
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3594
  if ((error=table->cursor->index_read_map(table->record[0],
3367
3595
                                         tab->ref.key_buff,
3368
3596
                                         make_prev_keypart_map(tab->ref.key_parts),
3369
3597
                                         HA_READ_KEY_EXACT)))
3371
3599
  return 0;
3372
3600
}
3373
3601
 
 
3602
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3603
{
 
3604
  int error;
 
3605
  Table *table=tab->table;
 
3606
  table->const_table=1;
 
3607
  table->null_row=0;
 
3608
  table->status=STATUS_NO_RECORD;
 
3609
 
 
3610
  if (tab->type == AM_SYSTEM)
 
3611
  {
 
3612
    if ((error=join_read_system(tab)))
 
3613
    {                                           // Info for DESCRIBE
 
3614
      tab->info="const row not found";
 
3615
      /* Mark for EXPLAIN that the row was not found */
 
3616
      pos->setFanout(0.0);
 
3617
      pos->clearRefDependMap();
 
3618
      if (! table->maybe_null || error > 0)
 
3619
        return(error);
 
3620
    }
 
3621
  }
 
3622
  else
 
3623
  {
 
3624
    if (! table->key_read && 
 
3625
        table->covering_keys.test(tab->ref.key) && 
 
3626
        ! table->no_keyread &&
 
3627
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3628
    {
 
3629
      table->key_read=1;
 
3630
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3631
      tab->index= tab->ref.key;
 
3632
    }
 
3633
    error=join_read_const(tab);
 
3634
    if (table->key_read)
 
3635
    {
 
3636
      table->key_read=0;
 
3637
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3638
    }
 
3639
    if (error)
 
3640
    {
 
3641
      tab->info="unique row not found";
 
3642
      /* Mark for EXPLAIN that the row was not found */
 
3643
      pos->setFanout(0.0);
 
3644
      pos->clearRefDependMap();
 
3645
      if (!table->maybe_null || error > 0)
 
3646
        return(error);
 
3647
    }
 
3648
  }
 
3649
  if (*tab->on_expr_ref && !table->null_row)
 
3650
  {
 
3651
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3652
      table->mark_as_null_row();
 
3653
  }
 
3654
  if (!table->null_row)
 
3655
    table->maybe_null=0;
 
3656
 
 
3657
  /* Check appearance of new constant items in Item_equal objects */
 
3658
  Join *join= tab->join;
 
3659
  if (join->conds)
 
3660
    update_const_equal_items(join->conds, tab);
 
3661
  TableList *tbl;
 
3662
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3663
  {
 
3664
    TableList *embedded;
 
3665
    TableList *embedding= tbl;
 
3666
    do
 
3667
    {
 
3668
      embedded= embedding;
 
3669
      if (embedded->on_expr)
 
3670
         update_const_equal_items(embedded->on_expr, tab);
 
3671
      embedding= embedded->getEmbedding();
 
3672
    }
 
3673
    while (embedding &&
 
3674
           embedding->getNestedJoin()->join_list.head() == embedded);
 
3675
  }
 
3676
 
 
3677
  return(0);
 
3678
}
 
3679
 
 
3680
int join_read_system(JoinTable *tab)
 
3681
{
 
3682
  Table *table= tab->table;
 
3683
  int error;
 
3684
  if (table->status & STATUS_GARBAGE)           // If first read
 
3685
  {
 
3686
    if ((error=table->cursor->read_first_row(table->record[0],
 
3687
                                           table->getShare()->getPrimaryKey())))
 
3688
    {
 
3689
      if (error != HA_ERR_END_OF_FILE)
 
3690
        return table->report_error(error);
 
3691
      tab->table->mark_as_null_row();
 
3692
      table->emptyRecord();                     // Make empty record
 
3693
      return -1;
 
3694
    }
 
3695
    table->storeRecord();
 
3696
  }
 
3697
  else if (!table->status)                      // Only happens with left join
 
3698
    table->restoreRecord();                     // restore old record
 
3699
  table->null_row=0;
 
3700
  return table->status ? -1 : 0;
 
3701
}
 
3702
 
3374
3703
/**
3375
3704
  Read a (constant) table when there is at most one matching row.
3376
3705
 
3394
3723
      error= HA_ERR_KEY_NOT_FOUND;
3395
3724
    else
3396
3725
    {
3397
 
      error=table->cursor->index_read_idx_map(table->getInsertRecord(),tab->ref.key,
 
3726
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
3398
3727
                                            (unsigned char*) tab->ref.key_buff,
3399
3728
                                            make_prev_keypart_map(tab->ref.key_parts),
3400
3729
                                            HA_READ_KEY_EXACT);
3442
3771
 
3443
3772
  if (!table->cursor->inited)
3444
3773
  {
3445
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3446
 
    if (error != 0)
3447
 
    {
3448
 
      table->print_error(error, MYF(0));
3449
 
    }
 
3774
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3450
3775
  }
3451
3776
 
3452
 
  /* @todo Why don't we do "Late NULLs Filtering" here? */
 
3777
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3453
3778
  if (cmp_buffer_with_ref(tab) ||
3454
3779
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3455
3780
  {
3458
3783
      table->status=STATUS_NOT_FOUND;
3459
3784
      return -1;
3460
3785
    }
3461
 
    error=table->cursor->index_read_map(table->getInsertRecord(),
 
3786
    error=table->cursor->index_read_map(table->record[0],
3462
3787
                                      tab->ref.key_buff,
3463
3788
                                      make_prev_keypart_map(tab->ref.key_parts),
3464
3789
                                      HA_READ_KEY_EXACT);
3494
3819
 
3495
3820
  /* Initialize the index first */
3496
3821
  if (!table->cursor->inited)
3497
 
  {
3498
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3499
 
    if (error != 0)
3500
 
      return table->report_error(error);
3501
 
  }
 
3822
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3502
3823
 
3503
3824
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3504
3825
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3509
3830
 
3510
3831
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3511
3832
    return -1;
3512
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3833
  if ((error=table->cursor->index_read_map(table->record[0],
3513
3834
                                         tab->ref.key_buff,
3514
3835
                                         make_prev_keypart_map(tab->ref.key_parts),
3515
3836
                                         HA_READ_KEY_EXACT)))
3532
3853
  Table *table= tab->table;
3533
3854
 
3534
3855
  if (!table->cursor->inited)
3535
 
  {
3536
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3537
 
    if (error != 0)
3538
 
      return table->report_error(error);
3539
 
  }
 
3856
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3540
3857
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3541
3858
    return -1;
3542
 
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
 
3859
  if ((error=table->cursor->index_read_last_map(table->record[0],
3543
3860
                                              tab->ref.key_buff,
3544
3861
                                              make_prev_keypart_map(tab->ref.key_parts))))
3545
3862
  {
3568
3885
      /* Save index tuple from record to the buffer */
3569
3886
      key_copy(tab->insideout_buf, info->record, key, 0);
3570
3887
 
3571
 
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3888
      if ((error=table->cursor->index_next_same(table->record[0],
3572
3889
                                              tab->ref.key_buff,
3573
3890
                                              tab->ref.key_length)))
3574
3891
      {
3592
3909
  Table *table= info->table;
3593
3910
  JoinTable *tab=table->reginfo.join_tab;
3594
3911
 
3595
 
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3912
  if ((error=table->cursor->index_next_same(table->record[0],
3596
3913
                                          tab->ref.key_buff,
3597
3914
                                          tab->ref.key_length)))
3598
3915
  {
3611
3928
  Table *table= info->table;
3612
3929
  JoinTable *tab=table->reginfo.join_tab;
3613
3930
 
3614
 
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
 
3931
  if ((error=table->cursor->index_prev(table->record[0])))
3615
3932
    return table->report_error(error);
3616
3933
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3617
3934
                      tab->ref.key_length))
3640
3957
 
3641
3958
int test_if_quick_select(JoinTable *tab)
3642
3959
{
3643
 
  safe_delete(tab->select->quick);
3644
 
 
 
3960
  delete tab->select->quick;
 
3961
  tab->select->quick= 0;
3645
3962
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3646
3963
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3647
3964
}
3651
3968
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3652
3969
    return 1;
3653
3970
 
3654
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3655
 
    return 1;
 
3971
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3656
3972
 
3657
3973
  return (*tab->read_record.read_record)(&tab->read_record);
3658
3974
}
3671
3987
  tab->read_record.table=table;
3672
3988
  tab->read_record.cursor=table->cursor;
3673
3989
  tab->read_record.index=tab->index;
3674
 
  tab->read_record.record=table->getInsertRecord();
 
3990
  tab->read_record.record=table->record[0];
3675
3991
  if (tab->insideout_match_tab)
3676
3992
  {
3677
3993
    tab->read_record.do_insideout_scan= tab;
3685
4001
  }
3686
4002
 
3687
4003
  if (!table->cursor->inited)
3688
 
  {
3689
 
    error= table->cursor->startIndexScan(tab->index, tab->sorted);
3690
 
    if (error != 0)
3691
 
    {
3692
 
      table->report_error(error);
3693
 
      return -1;
3694
 
    }
3695
 
  }
3696
 
  if ((error=tab->table->cursor->index_first(tab->table->getInsertRecord())))
 
4004
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
4005
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
3697
4006
  {
3698
4007
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3699
4008
      table->report_error(error);
3749
4058
  tab->read_record.table=table;
3750
4059
  tab->read_record.cursor=table->cursor;
3751
4060
  tab->read_record.index=tab->index;
3752
 
  tab->read_record.record=table->getInsertRecord();
 
4061
  tab->read_record.record=table->record[0];
3753
4062
  if (!table->cursor->inited)
3754
 
  {
3755
 
    error= table->cursor->startIndexScan(tab->index, 1);
3756
 
    if (error != 0)
3757
 
      return table->report_error(error);
3758
 
  }
3759
 
  if ((error= tab->table->cursor->index_last(tab->table->getInsertRecord())))
 
4063
    table->cursor->startIndexScan(tab->index, 1);
 
4064
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
3760
4065
    return table->report_error(error);
3761
4066
 
3762
4067
  return 0;
3819
4124
        {
3820
4125
          if (!join->first_record)
3821
4126
          {
3822
 
                  List<Item>::iterator it(join->fields->begin());
 
4127
                  List_iterator_fast<Item> it(*join->fields);
3823
4128
                  Item *item;
3824
4129
            /* No matching rows for group function */
3825
4130
            join->clear();
3835
4140
              error=join->result->send_data(*join->fields) ? 1 : 0;
3836
4141
            join->send_records++;
3837
4142
          }
3838
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
4143
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3839
4144
          {
3840
4145
            if (join->rollup_send_data((uint32_t) (idx+1)))
3841
4146
              error= 1;
3896
4201
  Table *table=join->tmp_table;
3897
4202
  int     idx= -1;
3898
4203
 
3899
 
  if (join->session->getKilled())
 
4204
  if (join->session->killed)
3900
4205
  {                                             // Aborted by user
3901
4206
    join->session->send_kill_message();
3902
4207
    return NESTED_LOOP_KILLED;
3917
4222
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
3918
4223
        if (!join->having || join->having->val_int())
3919
4224
        {
3920
 
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
4225
          int error= table->cursor->insertRecord(table->record[0]);
3921
4226
 
3922
4227
          if (error)
3923
4228
          {
3925
4230
            return NESTED_LOOP_ERROR;
3926
4231
          }
3927
4232
        }
3928
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
4233
        if (join->rollup.state != ROLLUP::STATE_NONE)
3929
4234
        {
3930
4235
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3931
4236
            return NESTED_LOOP_ERROR;
3944
4249
    if (idx < (int) join->send_group_parts)
3945
4250
    {
3946
4251
      copy_fields(&join->tmp_table_param);
3947
 
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3948
 
        return NESTED_LOOP_ERROR;
 
4252
      copy_funcs(join->tmp_table_param.items_to_copy);
3949
4253
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
3950
4254
        return NESTED_LOOP_ERROR;
3951
4255
      return NESTED_LOOP_OK;
3962
4266
  outer join table.
3963
4267
  We can't remove tests that are made against columns which are stored
3964
4268
  in sorted order.
 
4269
*****************************************************************************/
 
4270
 
 
4271
/**
3965
4272
  @return
3966
 
    1 if right_item used is a removable reference key on left_item
3967
 
    0 otherwise.
3968
 
****************************************************************************/
 
4273
    1 if right_item is used removable reference key on left_item
 
4274
*/
3969
4275
bool test_if_ref(Item_field *left_item,Item *right_item)
3970
4276
{
3971
4277
  Field *field=left_item->field;
4058
4364
      Item_cond_and *new_cond=new Item_cond_and;
4059
4365
      if (!new_cond)
4060
4366
        return (COND*) 0;
4061
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4367
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4062
4368
      Item *item;
4063
4369
      while ((item=li++))
4064
4370
      {
4088
4394
      Item_cond_or *new_cond=new Item_cond_or;
4089
4395
      if (!new_cond)
4090
4396
        return (COND*) 0;
4091
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4397
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4092
4398
      Item *item;
4093
4399
      while ((item=li++))
4094
4400
      {
4166
4472
    }
4167
4473
 
4168
4474
    for (part=0 ; part < ref_parts ; part++,key_part++)
4169
 
    {
4170
4475
      if (field->eq(key_part->field) &&
4171
 
          !(key_part->key_part_flag & HA_PART_KEY_SEG) &&
4172
 
          //If field can be NULL, we should not remove this predicate, as
4173
 
          //it may lead to non-rejection of NULL values. 
4174
 
          !(field->real_maybe_null()))
4175
 
      {
 
4476
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
4176
4477
        return table->reginfo.join_tab->ref.items[part];
4177
 
      }
4178
 
    }
4179
4478
  }
4180
4479
  return (Item*) 0;
4181
4480
}
4200
4499
  @retval
4201
4500
    -1   Reverse key can be used
4202
4501
*/
4203
 
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4502
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4204
4503
{
4205
4504
  KeyPartInfo *key_part= NULL;
4206
4505
  KeyPartInfo *key_part_end= NULL;
4306
4605
    - MAX_KEY                   If we can't use other key
4307
4606
    - the number of found key   Otherwise
4308
4607
*/
4309
 
static uint32_t test_if_subkey(Order *order,
 
4608
static uint32_t test_if_subkey(order_st *order,
4310
4609
                               Table *table,
4311
4610
                               uint32_t ref,
4312
4611
                               uint32_t ref_key_parts,
4408
4707
*/
4409
4708
bool find_field_in_order_list (Field *field, void *data)
4410
4709
{
4411
 
  Order *group= (Order *) data;
 
4710
  order_st *group= (order_st *) data;
4412
4711
  bool part_found= 0;
4413
 
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4712
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4414
4713
  {
4415
4714
    Item *item= (*tmp_group->item)->real_item();
4416
4715
    if (item->type() == Item::FIELD_ITEM &&
4440
4739
{
4441
4740
  List<Item> *fields= (List<Item> *) data;
4442
4741
  bool part_found= 0;
4443
 
  List<Item>::iterator li(fields->begin());
 
4742
  List_iterator<Item> li(*fields);
4444
4743
  Item *item;
4445
4744
 
4446
4745
  while ((item= li++))
4480
4779
  @retval
4481
4780
    1    We can use an index.
4482
4781
*/
4483
 
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4782
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
4484
4783
{
4485
4784
  int32_t ref_key;
4486
4785
  uint32_t ref_key_parts;
4497
4796
  */
4498
4797
  usable_keys= *map;
4499
4798
 
4500
 
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4799
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4501
4800
  {
4502
4801
    Item *item= (*tmp_order->item)->real_item();
4503
4802
    if (item->type() != Item::FIELD_ITEM)
4525
4824
    save_quick= select->quick;
4526
4825
    /*
4527
4826
      assume results are not ordered when index merge is used
4528
 
      @todo sergeyp: Results of all index merge selects actually are ordered
 
4827
      TODO: sergeyp: Results of all index merge selects actually are ordered
4529
4828
      by clustered PK values.
4530
4829
    */
4531
4830
 
4800
5099
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4801
5100
          if (select && select->quick)
4802
5101
          {
4803
 
            safe_delete(select->quick);
 
5102
            delete select->quick;
 
5103
            select->quick= 0;
4804
5104
          }
4805
5105
          if (table->covering_keys.test(best_key))
4806
5106
          {
4873
5173
          tab->limit= 0;
4874
5174
          return 0; // Reverse sort not supported
4875
5175
        }
4876
 
        select->quick= tmp;
 
5176
        select->quick=tmp;
4877
5177
      }
4878
5178
    }
4879
5179
    else if (tab->type != AM_NEXT &&
4922
5222
    -1          Some fatal error
4923
5223
    1           No records
4924
5224
*/
4925
 
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
5225
int create_sort_index(Session *session, Join *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
4926
5226
{
4927
5227
  uint32_t length= 0;
4928
5228
  ha_rows examined_rows;
4949
5249
                              is_order_by ?  &table->keys_in_use_for_order_by :
4950
5250
                              &table->keys_in_use_for_group_by))
4951
5251
    return(0);
4952
 
  for (Order *ord= join->order; ord; ord= ord->next)
 
5252
  for (order_st *ord= join->order; ord; ord= ord->next)
4953
5253
    length++;
4954
 
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
4955
 
  {
4956
 
    return(-1);
4957
 
  }
 
5254
  if (!(join->sortorder=
 
5255
        make_unireg_sortorder(order, &length, join->sortorder)))
 
5256
    goto err;
4958
5257
 
4959
5258
  table->sort.io_cache= new internal::IO_CACHE;
4960
5259
  table->status=0;                              // May be wrong if quick_select
4989
5288
                                                                 &tab->ref,
4990
5289
                                                                 tab->found_records))))
4991
5290
      {
4992
 
        return(-1);
 
5291
        goto err;
4993
5292
      }
4994
5293
    }
4995
5294
  }
4996
5295
 
4997
5296
  if (table->getShare()->getType())
4998
5297
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
4999
 
 
5000
 
  FileSort filesort(*session);
5001
 
  table->sort.found_records=filesort.run(table,join->sortorder, length,
5002
 
                                         select, filesort_limit, 0,
5003
 
                                         examined_rows);
 
5298
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
5299
                                     select, filesort_limit, 0,
 
5300
                                     &examined_rows);
5004
5301
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5005
5302
  if (select)
5006
5303
  {
5018
5315
    table->key_read=0;
5019
5316
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5020
5317
  }
5021
 
 
5022
5318
  return(table->sort.found_records == HA_POS_ERROR);
 
5319
err:
 
5320
  return(-1);
5023
5321
}
5024
5322
 
5025
5323
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5030
5328
  int error;
5031
5329
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
5032
5330
 
5033
 
  org_record=(char*) (record=table->getInsertRecord())+offset;
5034
 
  new_record=(char*) table->getUpdateRecord()+offset;
5035
 
 
5036
 
  if ((error= cursor->startTableScan(1)))
5037
 
    goto err;
5038
 
 
 
5331
  org_record=(char*) (record=table->record[0])+offset;
 
5332
  new_record=(char*) table->record[1]+offset;
 
5333
 
 
5334
  cursor->startTableScan(1);
5039
5335
  error=cursor->rnd_next(record);
5040
5336
  for (;;)
5041
5337
  {
5042
 
    if (session->getKilled())
 
5338
    if (session->killed)
5043
5339
    {
5044
5340
      session->send_kill_message();
5045
5341
      error=0;
5119
5415
                               uint32_t key_length,
5120
5416
                               Item *having)
5121
5417
{
5122
 
  unsigned char *key_pos, *record=table->getInsertRecord();
 
5418
  unsigned char *key_pos, *record=table->record[0];
5123
5419
  int error;
5124
5420
  Cursor *cursor= table->cursor;
5125
5421
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5152
5448
    return(1);
5153
5449
  }
5154
5450
 
5155
 
  if ((error= cursor->startTableScan(1)))
5156
 
    goto err;
5157
 
 
 
5451
  cursor->startTableScan(1);
5158
5452
  key_pos= &key_buffer[0];
5159
5453
  for (;;)
5160
5454
  {
5161
5455
    unsigned char *org_key_pos;
5162
 
    if (session->getKilled())
 
5456
    if (session->killed)
5163
5457
    {
5164
5458
      session->send_kill_message();
5165
5459
      error=0;
5213
5507
  return(1);
5214
5508
}
5215
5509
 
5216
 
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
 
5510
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
5217
5511
{
5218
5512
  uint32_t count;
5219
 
  SortField *sort,*pos;
 
5513
  SORT_FIELD *sort,*pos;
5220
5514
 
5221
5515
  count=0;
5222
 
  for (Order *tmp = order; tmp; tmp=tmp->next)
 
5516
  for (order_st *tmp = order; tmp; tmp=tmp->next)
5223
5517
    count++;
5224
5518
  if (!sortorder)
5225
 
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
 
5519
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
5226
5520
                                       (max(count, *length) + 1));
5227
5521
  pos= sort= sortorder;
5228
5522
 
5344
5638
static bool find_order_in_list(Session *session, 
5345
5639
                               Item **ref_pointer_array, 
5346
5640
                               TableList *tables,
5347
 
                               Order *order,
 
5641
                               order_st *order,
5348
5642
                               List<Item> &fields,
5349
5643
                               List<Item> &all_fields,
5350
5644
                               bool is_group_field)
5366
5660
    if (!count || count > fields.elements)
5367
5661
    {
5368
5662
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5369
 
               order_item->full_name(), session->where());
 
5663
               order_item->full_name(), session->where);
5370
5664
      return true;
5371
5665
    }
5372
5666
    order->item= ref_pointer_array + count - 1;
5443
5737
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5444
5738
                          ER(ER_NON_UNIQ_ERROR),
5445
5739
                          ((Item_ident*) order_item)->field_name,
5446
 
                          session->where());
 
5740
                          session->where);
5447
5741
    }
5448
5742
  }
5449
5743
 
5483
5777
                TableList *tables,
5484
5778
                            List<Item> &fields,
5485
5779
                List<Item> &all_fields,
5486
 
                Order *order)
 
5780
                order_st *order)
5487
5781
{
5488
 
  session->setWhere("order clause");
 
5782
  session->where="order clause";
5489
5783
  for (; order; order=order->next)
5490
5784
  {
5491
5785
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5525
5819
                TableList *tables,
5526
5820
                      List<Item> &fields,
5527
5821
                List<Item> &all_fields,
5528
 
                Order *order,
 
5822
                order_st *order,
5529
5823
                      bool *hidden_group_fields)
5530
5824
{
5531
5825
  *hidden_group_fields=0;
5532
 
  Order *ord;
 
5826
  order_st *ord;
5533
5827
 
5534
5828
  if (!order)
5535
5829
    return 0;                           /* Everything is ok */
5536
5830
 
5537
5831
  uint32_t org_fields=all_fields.elements;
5538
5832
 
5539
 
  session->setWhere("group statement");
 
5833
  session->where="group statement";
5540
5834
  for (ord= order; ord; ord= ord->next)
5541
5835
  {
5542
5836
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5569
5863
    Item *item;
5570
5864
    Item_field *field;
5571
5865
    int cur_pos_in_select_list= 0;
5572
 
    List<Item>::iterator li(fields.begin());
5573
 
    List<Item_field>::iterator naf_it(session->getLex()->current_select->non_agg_fields.begin());
 
5866
    List_iterator<Item> li(fields);
 
5867
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
5574
5868
 
5575
5869
    field= naf_it++;
5576
5870
    while (field && (item=li++))
5596
5890
            if ((*ord->item)->eq((Item*)field, 0))
5597
5891
              goto next_field;
5598
5892
          /*
5599
 
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
 
5893
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
 
5894
            ER_NON_GROUPING_FIELD_USED
5600
5895
          */
5601
5896
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5602
5897
          return 1;
5618
5913
  Try to use the fields in the order given by 'order' to allow one to
5619
5914
  optimize away 'order by'.
5620
5915
*/
5621
 
Order *create_distinct_group(Session *session,
 
5916
order_st *create_distinct_group(Session *session,
5622
5917
                                Item **ref_pointer_array,
5623
 
                                Order *order_list,
 
5918
                                order_st *order_list,
5624
5919
                                List<Item> &fields,
5625
5920
                                List<Item> &,
5626
5921
                                bool *all_order_by_fields_used)
5627
5922
{
5628
 
  List<Item>::iterator li(fields.begin());
 
5923
  List_iterator<Item> li(fields);
5629
5924
  Item *item;
5630
 
  Order *order,*group,**prev;
 
5925
  order_st *order,*group,**prev;
5631
5926
 
5632
5927
  *all_order_by_fields_used= 1;
5633
5928
  while ((item=li++))
5638
5933
  {
5639
5934
    if (order->in_field_list)
5640
5935
    {
5641
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5936
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
5642
5937
      if (!ord)
5643
5938
        return 0;
5644
5939
      *prev=ord;
5649
5944
      *all_order_by_fields_used= 0;
5650
5945
  }
5651
5946
 
5652
 
  li= fields.begin();
 
5947
  li.rewind();
5653
5948
  while ((item=li++))
5654
5949
  {
5655
5950
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5658
5953
        Don't put duplicate columns from the SELECT list into the
5659
5954
        GROUP BY list.
5660
5955
      */
5661
 
      Order *ord_iter;
 
5956
      order_st *ord_iter;
5662
5957
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5663
5958
        if ((*ord_iter->item)->eq(item, 1))
5664
5959
          goto next_item;
5665
5960
 
5666
 
      Order *ord=(Order*) session->calloc(sizeof(Order));
 
5961
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
5667
5962
      if (!ord)
5668
5963
        return 0;
5669
5964
 
5689
5984
*/
5690
5985
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5691
5986
{
5692
 
  List<Item>::iterator li(fields.begin());
 
5987
  List_iterator<Item> li(fields);
5693
5988
  Item *field;
5694
5989
 
5695
5990
  param->field_count=param->sum_func_count=param->func_count=
5746
6041
*/
5747
6042
int test_if_item_cache_changed(List<Cached_item> &list)
5748
6043
{
5749
 
  List<Cached_item>::iterator li(list.begin());
 
6044
  List_iterator<Cached_item> li(list);
5750
6045
  int idx= -1,i;
5751
6046
  Cached_item *buff;
5752
6047
 
5795
6090
                       List<Item> &all_fields)
5796
6091
{
5797
6092
  Item *pos;
5798
 
  List<Item>::iterator li(all_fields.begin());
 
6093
  List_iterator_fast<Item> li(all_fields);
5799
6094
  CopyField *copy= NULL;
5800
 
  res_selected_fields.clear();
5801
 
  res_all_fields.clear();
5802
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6095
  res_selected_fields.empty();
 
6096
  res_all_fields.empty();
 
6097
  List_iterator_fast<Item> itr(res_all_fields);
5803
6098
  List<Item> extra_funcs;
5804
6099
  uint32_t i, border= all_fields.elements - elements;
5805
6100
 
5807
6102
      !(copy=param->copy_field= new CopyField[param->field_count]))
5808
6103
    goto err2;
5809
6104
 
5810
 
  param->copy_funcs.clear();
 
6105
  param->copy_funcs.empty();
5811
6106
  for (i= 0; (pos= li++); i++)
5812
6107
  {
5813
6108
    Field *field;
5862
6157
        {
5863
6158
          copy->set(tmp, item->result_field);
5864
6159
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
5865
 
#ifdef HAVE_VALGRIND
 
6160
#ifdef HAVE_purify
5866
6161
          copy->to_ptr[copy->from_length]= 0;
5867
6162
#endif
5868
6163
          copy++;
5876
6171
             !real_pos->with_sum_func)
5877
6172
    {                                           // Save for send fields
5878
6173
      pos= real_pos;
5879
 
      /* 
5880
 
        @todo In most cases this result will be sent to the user.
 
6174
      /* TODO:
 
6175
        In most cases this result will be sent to the user.
5881
6176
        This should be changed to use copy_int or copy_real depending
5882
6177
        on how the value is to be used: In some cases this may be an
5883
6178
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5931
6226
  for (; ptr != end; ptr++)
5932
6227
    (*ptr->do_copy)(ptr);
5933
6228
 
5934
 
  List<Item>::iterator it(param->copy_funcs.begin());
 
6229
  List_iterator_fast<Item> it(param->copy_funcs);
5935
6230
  Item_copy_string *item;
5936
6231
  while ((item = (Item_copy_string*) it++))
5937
6232
    item->copy();
5960
6255
                                                uint32_t elements,
5961
6256
                              List<Item> &all_fields)
5962
6257
{
5963
 
  List<Item>::iterator it(all_fields.begin());
 
6258
  List_iterator_fast<Item> it(all_fields);
5964
6259
  Item *item_field,*item;
5965
6260
 
5966
 
  res_selected_fields.clear();
5967
 
  res_all_fields.clear();
 
6261
  res_selected_fields.empty();
 
6262
  res_all_fields.empty();
5968
6263
 
5969
6264
  uint32_t i, border= all_fields.elements - elements;
5970
6265
  for (i= 0; (item= it++); i++)
6009
6304
      item_field;
6010
6305
  }
6011
6306
 
6012
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6307
  List_iterator_fast<Item> itr(res_all_fields);
6013
6308
  for (i= 0; i < border; i++)
6014
6309
    itr++;
6015
6310
  itr.sublist(res_selected_fields, elements);
6039
6334
                               uint32_t elements,
6040
6335
                                                 List<Item> &all_fields)
6041
6336
{
6042
 
  List<Item>::iterator it(all_fields.begin());
 
6337
  List_iterator_fast<Item> it(all_fields);
6043
6338
  Item *item, *new_item;
6044
 
  res_selected_fields.clear();
6045
 
  res_all_fields.clear();
 
6339
  res_selected_fields.empty();
 
6340
  res_all_fields.empty();
6046
6341
 
6047
6342
  uint32_t i, border= all_fields.elements - elements;
6048
6343
  for (i= 0; (item= it++); i++)
6052
6347
      new_item;
6053
6348
  }
6054
6349
 
6055
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6350
  List_iterator_fast<Item> itr(res_all_fields);
6056
6351
  for (i= 0; i < border; i++)
6057
6352
    itr++;
6058
6353
  itr.sublist(res_selected_fields, elements);
6135
6430
}
6136
6431
 
6137
6432
/** Copy result of functions to record in tmp_table. */
6138
 
bool copy_funcs(Item **func_ptr, const Session *session)
 
6433
void copy_funcs(Item **func_ptr)
6139
6434
{
6140
6435
  Item *func;
6141
6436
  for (; (func = *func_ptr) ; func_ptr++)
6142
 
  {
6143
6437
    func->save_in_result_field(1);
6144
 
    /*
6145
 
      Need to check the THD error state because Item::val_xxx() don't
6146
 
      return error code, but can generate errors
6147
 
      @todo change it for a real status check when Item::val_xxx()
6148
 
      are extended to return status code.
6149
 
    */
6150
 
    if (session->is_error())
6151
 
      return true;
6152
 
  }
6153
 
  return false;
6154
6438
}
6155
6439
 
6156
6440
/**
6202
6486
  @param changed        out:  returns 1 if item contains a replaced field item
6203
6487
 
6204
6488
  @todo
6205
 
    - @todo Some functions are not null-preserving. For those functions
 
6489
    - TODO: Some functions are not null-preserving. For those functions
6206
6490
    updating of the maybe_null attribute is an overkill.
6207
6491
 
6208
6492
  @retval
6210
6494
  @retval
6211
6495
    1   on error
6212
6496
*/
6213
 
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
 
6497
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
6214
6498
{
6215
6499
  if (expr->arg_count)
6216
6500
  {
6217
 
    Name_resolution_context *context= &session->getLex()->current_select->context;
 
6501
    Name_resolution_context *context= &session->lex->current_select->context;
6218
6502
    Item **arg,**arg_end;
6219
6503
    bool arg_changed= false;
6220
6504
    for (arg= expr->arguments(),
6224
6508
      Item *item= *arg;
6225
6509
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6226
6510
      {
6227
 
        Order *group_tmp;
 
6511
        order_st *group_tmp;
6228
6512
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6229
6513
        {
6230
6514
          if (item->eq(*group_tmp->item,0))
6292
6576
                List<TableList> *tables, enum_query_type)
6293
6577
{
6294
6578
  /* List is reversed => we should reverse it before using */
6295
 
  List<TableList>::iterator ti(tables->begin());
6296
 
  TableList **table= (TableList **)session->getMemRoot()->allocate(sizeof(TableList*) *
 
6579
  List_iterator_fast<TableList> ti(*tables);
 
6580
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6297
6581
                                                tables->elements);
6298
6582
  if (table == 0)
6299
6583
    return;  // out of memory
6307
6591
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6308
6592
{
6309
6593
  /* QQ: session may not be set for sub queries, but this should be fixed */
6310
 
  if(not session)
6311
 
    session= current_session;
6312
 
 
 
6594
  assert(session);
6313
6595
 
6314
6596
  str->append(STRING_WITH_LEN("select "));
6315
6597
 
6329
6611
 
6330
6612
  //Item List
6331
6613
  bool first= 1;
6332
 
  List<Item>::iterator it(item_list.begin());
 
6614
  List_iterator_fast<Item> it(item_list);
6333
6615
  Item *item;
6334
6616
  while ((item= it++))
6335
6617
  {
6342
6624
 
6343
6625
  /*
6344
6626
    from clause
6345
 
    @todo support USING/FORCE/IGNORE index
 
6627
    TODO: support USING/FORCE/IGNORE index
6346
6628
  */
6347
6629
  if (table_list.elements)
6348
6630
  {
6376
6658
  if (group_list.elements)
6377
6659
  {
6378
6660
    str->append(STRING_WITH_LEN(" group by "));
6379
 
    print_order(str, (Order *) group_list.first, query_type);
 
6661
    print_order(str, (order_st *) group_list.first, query_type);
6380
6662
    switch (olap)
6381
6663
    {
6382
6664
      case CUBE_TYPE:
6407
6689
  if (order_list.elements)
6408
6690
  {
6409
6691
    str->append(STRING_WITH_LEN(" order by "));
6410
 
    print_order(str, (Order *) order_list.first, query_type);
 
6692
    print_order(str, (order_st *) order_list.first, query_type);
6411
6693
  }
6412
6694
 
6413
6695
  // limit