~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

  • Committer: Stewart Smith
  • Date: 2010-06-04 02:51:04 UTC
  • mto: This revision was merged to the branch mainline in revision 1590.
  • Revision ID: stewart@flamingspork.com-20100604025104-ilf5mrvwbpd5crzv
have a constant for the maximum number of enum elements

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->nested_join)
 
459
      fix_list_after_tbl_changes(new_parent, &table->nested_join->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
552
555
                         Select_Lex *select_lex,
553
556
                         vector<optimizer::SargableParam> &sargables)
554
557
{
555
 
  uint  and_level,found_eq_constant;
 
558
  uint  and_level,i,found_eq_constant;
556
559
  optimizer::KeyField *key_fields, *end, *field;
557
560
  uint32_t sz;
558
561
  uint32_t m= max(select_lex->max_equal_elems,(uint32_t)1);
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) +
 
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;
595
598
      if (field->getValue()->type() == Item::NULL_ITEM &&
596
599
          ! field->getField()->real_maybe_null())
597
600
      {
598
 
        field->getField()->getTable()->reginfo.not_exists_optimize= 1;
 
601
        field->getField()->table->reginfo.not_exists_optimize= 1;
599
602
      }
600
603
    }
601
604
  }
602
 
  for (uint32_t i= 0; i < tables; i++)
 
605
  for (i= 0; i < tables; i++)
603
606
  {
604
607
    /*
605
608
      Block the creation of keys for inner tables of outer joins.
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
    {
625
 
      if (table->getNestedJoin())
 
628
      if (table->nested_join)
626
629
        add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
627
630
                              sargables);
628
631
    }
654
657
    use= save_pos= dynamic_element(keyuse, 0, optimizer::KeyUse*);
655
658
    prev= &key_end;
656
659
    found_eq_constant= 0;
 
660
    for (i= 0; i < keyuse->elements-1; i++, use++)
657
661
    {
658
 
      uint32_t i;
659
 
 
660
 
      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())
661
665
      {
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())
665
 
        {
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;
 
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;
672
672
 
673
 
#ifdef HAVE_VALGRIND
674
 
        /* Valgrind complains about overlapped memcpy when save_pos==use. */
675
 
        if (save_pos != use)
 
673
#ifdef HAVE_purify
 
674
      /* Valgrind complains about overlapped memcpy when save_pos==use. */
 
675
      if (save_pos != use)
676
676
#endif
677
 
          *save_pos= *use;
678
 
        prev=use;
679
 
        found_eq_constant= ! use->getUsedTables();
680
 
        /* Save ptr to first use */
681
 
        if (! use->getTable()->reginfo.join_tab->keyuse)
682
 
          use->getTable()->reginfo.join_tab->keyuse= save_pos;
683
 
        use->getTable()->reginfo.join_tab->checked_keys.set(use->getKey());
684
 
        save_pos++;
685
 
      }
686
 
      i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
687
 
      set_dynamic(keyuse, (unsigned char*) &key_end, i);
688
 
      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++;
689
685
    }
 
686
    i= (uint32_t) (save_pos - (optimizer::KeyUse*) keyuse->buffer);
 
687
    set_dynamic(keyuse, (unsigned char*) &key_end, i);
 
688
    keyuse->elements= i;
690
689
  }
691
690
  return false;
692
691
}
752
751
void add_group_and_distinct_keys(Join *join, JoinTable *join_tab)
753
752
{
754
753
  List<Item_field> indexed_fields;
755
 
  List<Item_field>::iterator indexed_fields_it(indexed_fields.begin());
756
 
  Order      *cur_group;
 
754
  List_iterator<Item_field> indexed_fields_it(indexed_fields);
 
755
  order_st      *cur_group;
757
756
  Item_field *cur_item;
758
757
  key_map possible_keys(0);
759
758
 
766
765
  else if (join->select_distinct)
767
766
  { /* Collect all query fields referenced in the SELECT clause. */
768
767
    List<Item> &select_items= join->fields_list;
769
 
    List<Item>::iterator select_items_it(select_items.begin());
 
768
    List_iterator<Item> select_items_it(select_items);
770
769
    Item *item;
771
770
    while ((item= select_items_it++))
772
771
      item->walk(&Item::collect_item_field_processor, 0,
854
853
  Field **f_ptr,*field;
855
854
 
856
855
  null_fields= blobs= fields= rec_length=0;
857
 
  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++)
858
857
  {
859
858
    if (field->isReadSet())
860
859
    {
930
929
bool store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
931
930
{
932
931
  bool error;
933
 
  Table *table= field->getTable();
 
932
  Table *table= field->table;
934
933
  Session *session= table->in_use;
935
934
  ha_rows cuted_fields=session->cuted_fields;
936
935
 
937
936
  /*
938
937
    we should restore old value of count_cuted_fields because
939
 
    store_val_in_field can be called from insert_query
 
938
    store_val_in_field can be called from mysql_insert
940
939
    with select_insert, which make count_cuted_fields= 1
941
940
   */
942
941
  enum_check_fields old_count_cuted_fields= session->count_cuted_fields;
1009
1008
  j->ref.key_length=length;
1010
1009
  j->ref.key=(int) key;
1011
1010
  if (!(j->ref.key_buff= (unsigned char*) session->calloc(ALIGN_SIZE(length)*2)) ||
1012
 
      !(j->ref.key_copy= (StoredKey**) session->getMemRoot()->allocate((sizeof(StoredKey*) *
 
1011
      !(j->ref.key_copy= (StoredKey**) session->alloc((sizeof(StoredKey*) *
1013
1012
               (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)))
 
1013
      !(j->ref.items=    (Item**) session->alloc(sizeof(Item*)*keyparts)) ||
 
1014
      !(j->ref.cond_guards= (bool**) session->alloc(sizeof(uint*)*keyparts)))
1016
1015
  {
1017
1016
    return(true);
1018
1017
  }
1156
1155
          Item *notnull;
1157
1156
          assert(item->type() == Item::FIELD_ITEM);
1158
1157
          Item_field *not_null_item= (Item_field*)item;
1159
 
          JoinTable *referred_tab= not_null_item->field->getTable()->reginfo.join_tab;
 
1158
          JoinTable *referred_tab= not_null_item->field->table->reginfo.join_tab;
1160
1159
          /*
1161
1160
            For UPDATE queries such as:
1162
1161
            UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
1213
1212
  return tmp;
1214
1213
}
1215
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
 
1216
1299
#define ICP_COND_USES_INDEX_ONLY 10
1217
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
}
1218
1450
 
1219
1451
/**
1220
1452
  cleanup JoinTable.
1221
1453
*/
1222
1454
void JoinTable::cleanup()
1223
1455
{
1224
 
  safe_delete(select);
1225
 
  safe_delete(quick);
1226
 
 
 
1456
  delete select;
 
1457
  select= 0;
 
1458
  delete quick;
 
1459
  quick= 0;
1227
1460
  if (cache.buff)
1228
 
  {
1229
 
    size_t size= cache.end - cache.buff;
1230
 
    global_join_buffer.sub(size);
1231
1461
    free(cache.buff);
1232
 
  }
1233
1462
  cache.buff= 0;
1234
1463
  limit= 0;
1235
1464
  if (table)
1249
1478
  read_record.end_read_record();
1250
1479
}
1251
1480
 
1252
 
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)
1253
1482
{
1254
1483
  for (JoinTable **tab=join->map2table ; tables ; tab++, tables>>=1)
1255
1484
  {
1278
1507
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
1279
1508
  @endcode
1280
1509
*/
1281
 
bool eq_ref_table(Join *join, Order *start_order, JoinTable *tab)
 
1510
bool eq_ref_table(Join *join, order_st *start_order, JoinTable *tab)
1282
1511
{
1283
1512
  if (tab->cached_eq_ref_table)                 // If cached
1284
1513
    return tab->eq_ref_table;
1297
1526
  {
1298
1527
    if (! (*ref_item)->const_item())
1299
1528
    {                                           // Not a const ref
1300
 
      Order *order;
 
1529
      order_st *order;
1301
1530
      for (order=start_order ; order ; order=order->next)
1302
1531
      {
1303
1532
        if ((*ref_item)->eq(order->item[0],0))
1352
1581
  bool in_upper_level= false;
1353
1582
  while (cond_equal)
1354
1583
  {
1355
 
    List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1584
    List_iterator_fast<Item_equal> li(cond_equal->current_level);
1356
1585
    while ((item= li++))
1357
1586
    {
1358
1587
      if (item->contains(field))
1517
1746
        /* Merge two multiple equalities forming a new one */
1518
1747
        left_item_equal->merge(right_item_equal);
1519
1748
        /* Remove the merged multiple equality from the list */
1520
 
        List<Item_equal>::iterator li(cond_equal->current_level.begin());
 
1749
        List_iterator<Item_equal> li(cond_equal->current_level);
1521
1750
        while ((li++) != right_item_equal) {};
1522
1751
        li.remove();
1523
1752
      }
1657
1886
                                       (Item_row *) right_item,
1658
1887
                                       cond_equal, eq_list);
1659
1888
      if (!is_converted)
1660
 
        session->getLex()->current_select->cond_count++;
 
1889
        session->lex->current_select->cond_count++;
1661
1890
    }
1662
1891
    else
1663
1892
    {
1664
1893
      is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
1665
 
      session->getLex()->current_select->cond_count++;
 
1894
      session->lex->current_select->cond_count++;
1666
1895
    }
1667
1896
 
1668
1897
    if (!is_converted)
1718
1947
    if (left_item->type() == Item::ROW_ITEM &&
1719
1948
        right_item->type() == Item::ROW_ITEM)
1720
1949
    {
1721
 
      session->getLex()->current_select->cond_count--;
 
1950
      session->lex->current_select->cond_count--;
1722
1951
      return check_row_equality(session,
1723
1952
                                (Item_row *) left_item,
1724
1953
                                (Item_row *) right_item,
1749
1978
    just an argument of a comparison predicate.
1750
1979
    The function also determines the maximum number of members in
1751
1980
    equality lists of each Item_cond_and object assigning it to
1752
 
    session->getLex()->current_select->max_equal_elems.
 
1981
    session->lex->current_select->max_equal_elems.
1753
1982
 
1754
1983
  @note
1755
1984
    Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
1806
2035
      Item_func::COND_AND_FUNC;
1807
2036
    List<Item> *args= ((Item_cond*) cond)->argument_list();
1808
2037
 
1809
 
    List<Item>::iterator li(args->begin());
 
2038
    List_iterator<Item> li(*args);
1810
2039
    Item *item;
1811
2040
 
1812
2041
    if (and_level)
1828
2057
          li.remove();
1829
2058
      }
1830
2059
 
1831
 
      List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
2060
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
1832
2061
      while ((item_equal= it++))
1833
2062
      {
1834
2063
        item_equal->fix_length_and_dec();
1835
2064
        item_equal->update_used_tables();
1836
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2065
        set_if_bigger(session->lex->current_select->max_equal_elems,
1837
2066
                      item_equal->members());
1838
2067
      }
1839
2068
 
1844
2073
       Make replacement of equality predicates for lower levels
1845
2074
       of the condition expression.
1846
2075
    */
1847
 
    li= args->begin();
 
2076
    li.rewind();
1848
2077
    while ((item= li++))
1849
2078
    {
1850
2079
      Item *new_item;
1892
2121
        }
1893
2122
        else
1894
2123
          item_equal= (Item_equal *) eq_list.pop();
1895
 
        set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2124
        set_if_bigger(session->lex->current_select->max_equal_elems,
1896
2125
                      item_equal->members());
1897
2126
        return item_equal;
1898
2127
      }
1905
2134
        Item_cond_and *and_cond= new Item_cond_and(eq_list);
1906
2135
        and_cond->quick_fix_field();
1907
2136
        List<Item> *args= and_cond->argument_list();
1908
 
        List<Item_equal>::iterator it(cond_equal.current_level.begin());
 
2137
        List_iterator_fast<Item_equal> it(cond_equal.current_level);
1909
2138
        while ((item_equal= it++))
1910
2139
        {
1911
2140
          item_equal->fix_length_and_dec();
1912
2141
          item_equal->update_used_tables();
1913
 
          set_if_bigger(session->getLex()->current_select->max_equal_elems,
 
2142
          set_if_bigger(session->lex->current_select->max_equal_elems,
1914
2143
                        item_equal->members());
1915
2144
        }
1916
2145
        and_cond->cond_equal= cond_equal;
2031
2260
  if (join_list)
2032
2261
  {
2033
2262
    TableList *table;
2034
 
    List<TableList>::iterator li(join_list->begin());
 
2263
    List_iterator<TableList> li(*join_list);
2035
2264
 
2036
2265
    while ((table= li++))
2037
2266
    {
2038
2267
      if (table->on_expr)
2039
2268
      {
2040
 
        List<TableList> *nested_join_list= table->getNestedJoin() ?
2041
 
          &table->getNestedJoin()->join_list : NULL;
 
2269
        List<TableList> *nested_join_list= table->nested_join ?
 
2270
          &table->nested_join->join_list : NULL;
2042
2271
        /*
2043
2272
          We can modify table->on_expr because its old value will
2044
2273
          be restored before re-execution of PS/SP.
2091
2320
  if (outer_ref)
2092
2321
    return cmp;
2093
2322
  JoinTable **idx= (JoinTable **) table_join_idx;
2094
 
  cmp= idx[field2->field->getTable()->tablenr]-idx[field1->field->getTable()->tablenr];
 
2323
  cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
2095
2324
  return cmp < 0 ? -1 : (cmp ? 1 : 0);
2096
2325
}
2097
2326
 
2246
2475
      cond_equal= &((Item_cond_and *) cond)->cond_equal;
2247
2476
      cond_list->disjoin((List<Item> *) &cond_equal->current_level);
2248
2477
 
2249
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2478
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2250
2479
      while ((item_equal= it++))
2251
2480
      {
2252
2481
        item_equal->sort(&compare_fields_by_table_order, table_join_idx);
2253
2482
      }
2254
2483
    }
2255
2484
 
2256
 
    List<Item>::iterator li(cond_list->begin());
 
2485
    List_iterator<Item> li(*cond_list);
2257
2486
    Item *item;
2258
2487
    while ((item= li++))
2259
2488
    {
2269
2498
 
2270
2499
    if (and_level)
2271
2500
    {
2272
 
      List<Item_equal>::iterator it(cond_equal->current_level.begin());
 
2501
      List_iterator_fast<Item_equal> it(cond_equal->current_level);
2273
2502
      while ((item_equal= it++))
2274
2503
      {
2275
2504
        cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
2311
2540
  @param cond       condition whose multiple equalities are to be checked
2312
2541
  @param table      constant table that has been read
2313
2542
*/
2314
 
void update_const_equal_items(COND *cond, JoinTable *tab)
 
2543
static void update_const_equal_items(COND *cond, JoinTable *tab)
2315
2544
{
2316
2545
  if (!(cond->used_tables() & tab->table->map))
2317
2546
    return;
2319
2548
  if (cond->type() == Item::COND_ITEM)
2320
2549
  {
2321
2550
    List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
2322
 
    List<Item>::iterator li(cond_list->begin());
 
2551
    List_iterator_fast<Item> li(*cond_list);
2323
2552
    Item *item;
2324
2553
    while ((item= li++))
2325
2554
      update_const_equal_items(item, tab);
2338
2567
      while ((item_field= it++))
2339
2568
      {
2340
2569
        Field *field= item_field->field;
2341
 
        JoinTable *stat= field->getTable()->reginfo.join_tab;
 
2570
        JoinTable *stat= field->table->reginfo.join_tab;
2342
2571
        key_map possible_keys= field->key_start;
2343
 
        possible_keys&= field->getTable()->keys_in_use_for_query;
 
2572
        possible_keys&= field->table->keys_in_use_for_query;
2344
2573
        stat[0].const_keys|= possible_keys;
2345
2574
 
2346
2575
        /*
2350
2579
        */
2351
2580
        if (possible_keys.any())
2352
2581
        {
2353
 
          Table *field_tab= field->getTable();
 
2582
          Table *field_tab= field->table;
2354
2583
          optimizer::KeyUse *use;
2355
2584
          for (use= stat->keyuse; use && use->getTable() == field_tab; use++)
2356
2585
            if (possible_keys.test(use->getKey()) &&
2368
2597
  and_level
2369
2598
*/
2370
2599
static void change_cond_ref_to_const(Session *session,
2371
 
                                     list<COND_CMP>& save_list,
 
2600
                                     vector<COND_CMP>& save_list,
2372
2601
                                     Item *and_father,
2373
2602
                                     Item *cond,
2374
2603
                                     Item *field,
2377
2606
  if (cond->type() == Item::COND_ITEM)
2378
2607
  {
2379
2608
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2380
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2609
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2381
2610
    Item *item;
2382
2611
    while ((item=li++))
2383
2612
      change_cond_ref_to_const(session, save_list, and_level ? cond : item, item, field, value);
2384
 
 
2385
2613
    return;
2386
2614
  }
2387
2615
  if (cond->eq_cmp_result() == Item::COND_OK)
2400
2628
       left_item->collation.collation == value->collation.collation))
2401
2629
  {
2402
2630
    Item *tmp=value->clone_item();
 
2631
    tmp->collation.set(right_item->collation);
 
2632
 
2403
2633
    if (tmp)
2404
2634
    {
2405
 
      tmp->collation.set(right_item->collation);
2406
2635
      session->change_item_tree(args + 1, tmp);
2407
2636
      func->update_used_tables();
2408
2637
      if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) &&
2422
2651
            right_item->collation.collation == value->collation.collation))
2423
2652
  {
2424
2653
    Item *tmp= value->clone_item();
 
2654
    tmp->collation.set(left_item->collation);
 
2655
 
2425
2656
    if (tmp)
2426
2657
    {
2427
 
      tmp->collation.set(left_item->collation);
2428
2658
      session->change_item_tree(args, tmp);
2429
2659
      value= tmp;
2430
2660
      func->update_used_tables();
2457
2687
  if (conds->type() == Item::COND_ITEM)
2458
2688
  {
2459
2689
    Item_cond *cnd= (Item_cond*) conds;
2460
 
    List<Item>::iterator li(cnd->argument_list()->begin());
 
2690
    List_iterator<Item> li(*(cnd->argument_list()));
2461
2691
    Item *item;
2462
2692
    while ((item= li++))
2463
2693
    {
2474
2704
}
2475
2705
 
2476
2706
static void propagate_cond_constants(Session *session, 
2477
 
                                     list<COND_CMP>& save_list, 
 
2707
                                     vector<COND_CMP>& save_list, 
2478
2708
                                     COND *and_father, 
2479
2709
                                     COND *cond)
2480
2710
{
2481
2711
  if (cond->type() == Item::COND_ITEM)
2482
2712
  {
2483
2713
    bool and_level= ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC;
2484
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2714
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2485
2715
    Item *item;
2486
 
    list<COND_CMP> save;
 
2716
    vector<COND_CMP> save;
2487
2717
    while ((item=li++))
2488
2718
    {
2489
2719
      propagate_cond_constants(session, save, and_level ? cond : item, item);
2491
2721
    if (and_level)
2492
2722
    {
2493
2723
      // Handle other found items
2494
 
      for (list<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
 
2724
      for (vector<COND_CMP>::iterator iter= save.begin(); iter != save.end(); ++iter)
2495
2725
      {
2496
 
        Item **args= iter->second->arguments();
2497
 
        if (not args[0]->const_item())
 
2726
        Item **args= iter->cmp_func->arguments();
 
2727
        if (!args[0]->const_item())
2498
2728
        {
2499
 
          change_cond_ref_to_const(session, save, iter->first,
2500
 
                                   iter->first, args[0], args[1] );
 
2729
          change_cond_ref_to_const( session, save, iter->and_level,
 
2730
                                    iter->and_level, args[0], args[1] );
2501
2731
        }
2502
2732
      }
2503
2733
    }
2610
2840
         position:
2611
2841
          1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
2612
2842
             joins) we've opened but didn't close.
2613
 
          2. {each NestedJoin class not simplified away}->counter - number
 
2843
          2. {each nested_join_st structure not simplified away}->counter - number
2614
2844
             of this nested join's children that have already been added to to
2615
2845
             the partial join order.
2616
2846
  @endverbatim
2617
2847
 
2618
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)
2619
2851
  @param next_tab   Table we're going to extend the current partial join with
2620
2852
 
2621
2853
  @retval
2624
2856
  @retval
2625
2857
    true   Requested join order extension not allowed.
2626
2858
*/
2627
 
bool check_interleaving_with_nj(JoinTable *next_tab)
 
2859
bool check_interleaving_with_nj(JoinTable *last_tab, JoinTable *next_tab)
2628
2860
{
2629
 
  TableList *next_emb= next_tab->table->pos_in_table_list->getEmbedding();
2630
 
  Join *join= next_tab->join;
 
2861
  TableList *next_emb= next_tab->table->pos_in_table_list->embedding;
 
2862
  Join *join= last_tab->join;
2631
2863
 
2632
2864
  if ((join->cur_embedding_map & ~next_tab->embedding_map).any())
2633
2865
  {
2642
2874
    Do update counters for "pairs of brackets" that we've left (marked as
2643
2875
    X,Y,Z in the above picture)
2644
2876
  */
2645
 
  for (;next_emb; next_emb= next_emb->getEmbedding())
 
2877
  for (;next_emb; next_emb= next_emb->embedding)
2646
2878
  {
2647
 
    next_emb->getNestedJoin()->counter_++;
2648
 
    if (next_emb->getNestedJoin()->counter_ == 1)
 
2879
    next_emb->nested_join->counter_++;
 
2880
    if (next_emb->nested_join->counter_ == 1)
2649
2881
    {
2650
2882
      /*
2651
2883
        next_emb is the first table inside a nested join we've "entered". In
2652
2884
        the picture above, we're looking at the 'X' bracket. Don't exit yet as
2653
2885
        X bracket might have Y pair bracket.
2654
2886
      */
2655
 
      join->cur_embedding_map |= next_emb->getNestedJoin()->nj_map;
 
2887
      join->cur_embedding_map |= next_emb->nested_join->nj_map;
2656
2888
    }
2657
2889
 
2658
 
    if (next_emb->getNestedJoin()->join_list.elements !=
2659
 
        next_emb->getNestedJoin()->counter_)
 
2890
    if (next_emb->nested_join->join_list.elements !=
 
2891
        next_emb->nested_join->counter_)
2660
2892
      break;
2661
2893
 
2662
2894
    /*
2663
2895
      We're currently at Y or Z-bracket as depicted in the above picture.
2664
2896
      Mark that we've left it and continue walking up the brackets hierarchy.
2665
2897
    */
2666
 
    join->cur_embedding_map &= ~next_emb->getNestedJoin()->nj_map;
 
2898
    join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
2667
2899
  }
2668
2900
  return false;
2669
2901
}
2688
2920
                             &join->cond_equal);
2689
2921
 
2690
2922
    /* change field = field to field = const for each found field = const */
2691
 
    list<COND_CMP> temp;
 
2923
    vector<COND_CMP> temp;
2692
2924
    propagate_cond_constants(session, temp, conds, conds);
2693
2925
    /*
2694
2926
      Remove all instances of item == item
2715
2947
  {
2716
2948
    bool and_level= (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC);
2717
2949
 
2718
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
2950
    List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
2719
2951
    Item::cond_result tmp_cond_value;
2720
2952
    bool should_fix_fields= false;
2721
2953
 
2769
3001
    {                                           
2770
3002
      /* Argument list contains only one element, so reduce it so a single item, then remove list */
2771
3003
      item= ((Item_cond*) cond)->argument_list()->head();
2772
 
      ((Item_cond*) cond)->argument_list()->clear();
 
3004
      ((Item_cond*) cond)->argument_list()->empty();
2773
3005
      return item;
2774
3006
    }
2775
3007
  }
2791
3023
    {
2792
3024
      Field *field= ((Item_field*) args[0])->field;
2793
3025
      if (field->flags & AUTO_INCREMENT_FLAG 
2794
 
          && ! field->getTable()->maybe_null 
 
3026
          && ! field->table->maybe_null 
2795
3027
          && session->options & OPTION_AUTO_IS_NULL
2796
3028
          && (
2797
3029
            session->first_successful_insert_id_in_prev_stmt > 0 
2847
3079
  }
2848
3080
  else if (cond->const_item() && !cond->is_expensive())
2849
3081
  /*
2850
 
    @todo
 
3082
    TODO:
2851
3083
    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
 
 
 
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()))
2858
3090
  */
2859
3091
  {
2860
3092
    *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
2919
3151
  {
2920
3152
    bool and_level= (((Item_cond*) cond)->functype()
2921
3153
                     == Item_func::COND_AND_FUNC);
2922
 
    List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
3154
    List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
2923
3155
    Item *item;
2924
3156
    while ((item=li++))
2925
3157
    {
2989
3221
    if (table->group && tmp_tbl->sum_func_count &&
2990
3222
        !tmp_tbl->precomputed_group_by)
2991
3223
    {
2992
 
      if (table->getShare()->sizeKeys())
 
3224
      if (table->getShare()->keys)
2993
3225
      {
2994
3226
        end_select= end_update;
2995
3227
      }
3056
3288
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
3057
3289
    table->emptyRecord();
3058
3290
    if (table->group && join->tmp_table_param.sum_func_count &&
3059
 
        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
 
    }
 
3291
        table->getShare()->keys && !table->cursor->inited)
 
3292
      table->cursor->startIndexScan(0, 0);
3069
3293
  }
3070
3294
  /* Set up select_end */
3071
3295
  Next_select_func end_select= setup_end_select_func(join);
3162
3386
      rc= sub_select(join,join_tab,end_of_records);
3163
3387
    return rc;
3164
3388
  }
3165
 
  if (join->session->getKilled())               // If aborted by user
 
3389
  if (join->session->killed)            // If aborted by user
3166
3390
  {
3167
3391
    join->session->send_kill_message();
3168
3392
    return NESTED_LOOP_KILLED;
3363
3587
{
3364
3588
  int error;
3365
3589
  Table *table= tab->table;
3366
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3590
  if ((error=table->cursor->index_read_map(table->record[0],
3367
3591
                                         tab->ref.key_buff,
3368
3592
                                         make_prev_keypart_map(tab->ref.key_parts),
3369
3593
                                         HA_READ_KEY_EXACT)))
3371
3595
  return 0;
3372
3596
}
3373
3597
 
 
3598
int join_read_const_table(JoinTable *tab, optimizer::Position *pos)
 
3599
{
 
3600
  int error;
 
3601
  Table *table=tab->table;
 
3602
  table->const_table=1;
 
3603
  table->null_row=0;
 
3604
  table->status=STATUS_NO_RECORD;
 
3605
 
 
3606
  if (tab->type == AM_SYSTEM)
 
3607
  {
 
3608
    if ((error=join_read_system(tab)))
 
3609
    {                                           // Info for DESCRIBE
 
3610
      tab->info="const row not found";
 
3611
      /* Mark for EXPLAIN that the row was not found */
 
3612
      pos->setFanout(0.0);
 
3613
      pos->clearRefDependMap();
 
3614
      if (! table->maybe_null || error > 0)
 
3615
        return(error);
 
3616
    }
 
3617
  }
 
3618
  else
 
3619
  {
 
3620
    if (! table->key_read && 
 
3621
        table->covering_keys.test(tab->ref.key) && 
 
3622
        ! table->no_keyread &&
 
3623
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
 
3624
    {
 
3625
      table->key_read=1;
 
3626
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3627
      tab->index= tab->ref.key;
 
3628
    }
 
3629
    error=join_read_const(tab);
 
3630
    if (table->key_read)
 
3631
    {
 
3632
      table->key_read=0;
 
3633
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3634
    }
 
3635
    if (error)
 
3636
    {
 
3637
      tab->info="unique row not found";
 
3638
      /* Mark for EXPLAIN that the row was not found */
 
3639
      pos->setFanout(0.0);
 
3640
      pos->clearRefDependMap();
 
3641
      if (!table->maybe_null || error > 0)
 
3642
        return(error);
 
3643
    }
 
3644
  }
 
3645
  if (*tab->on_expr_ref && !table->null_row)
 
3646
  {
 
3647
    if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
 
3648
      table->mark_as_null_row();
 
3649
  }
 
3650
  if (!table->null_row)
 
3651
    table->maybe_null=0;
 
3652
 
 
3653
  /* Check appearance of new constant items in Item_equal objects */
 
3654
  Join *join= tab->join;
 
3655
  if (join->conds)
 
3656
    update_const_equal_items(join->conds, tab);
 
3657
  TableList *tbl;
 
3658
  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
 
3659
  {
 
3660
    TableList *embedded;
 
3661
    TableList *embedding= tbl;
 
3662
    do
 
3663
    {
 
3664
      embedded= embedding;
 
3665
      if (embedded->on_expr)
 
3666
         update_const_equal_items(embedded->on_expr, tab);
 
3667
      embedding= embedded->embedding;
 
3668
    }
 
3669
    while (embedding &&
 
3670
           embedding->nested_join->join_list.head() == embedded);
 
3671
  }
 
3672
 
 
3673
  return(0);
 
3674
}
 
3675
 
 
3676
int join_read_system(JoinTable *tab)
 
3677
{
 
3678
  Table *table= tab->table;
 
3679
  int error;
 
3680
  if (table->status & STATUS_GARBAGE)           // If first read
 
3681
  {
 
3682
    if ((error=table->cursor->read_first_row(table->record[0],
 
3683
                                           table->getShare()->primary_key)))
 
3684
    {
 
3685
      if (error != HA_ERR_END_OF_FILE)
 
3686
        return table->report_error(error);
 
3687
      tab->table->mark_as_null_row();
 
3688
      table->emptyRecord();                     // Make empty record
 
3689
      return -1;
 
3690
    }
 
3691
    table->storeRecord();
 
3692
  }
 
3693
  else if (!table->status)                      // Only happens with left join
 
3694
    table->restoreRecord();                     // restore old record
 
3695
  table->null_row=0;
 
3696
  return table->status ? -1 : 0;
 
3697
}
 
3698
 
3374
3699
/**
3375
3700
  Read a (constant) table when there is at most one matching row.
3376
3701
 
3394
3719
      error= HA_ERR_KEY_NOT_FOUND;
3395
3720
    else
3396
3721
    {
3397
 
      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,
3398
3723
                                            (unsigned char*) tab->ref.key_buff,
3399
3724
                                            make_prev_keypart_map(tab->ref.key_parts),
3400
3725
                                            HA_READ_KEY_EXACT);
3442
3767
 
3443
3768
  if (!table->cursor->inited)
3444
3769
  {
3445
 
    error= table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3446
 
    if (error != 0)
3447
 
    {
3448
 
      table->print_error(error, MYF(0));
3449
 
    }
 
3770
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3450
3771
  }
3451
3772
 
3452
 
  /* @todo Why don't we do "Late NULLs Filtering" here? */
 
3773
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3453
3774
  if (cmp_buffer_with_ref(tab) ||
3454
3775
      (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
3455
3776
  {
3458
3779
      table->status=STATUS_NOT_FOUND;
3459
3780
      return -1;
3460
3781
    }
3461
 
    error=table->cursor->index_read_map(table->getInsertRecord(),
 
3782
    error=table->cursor->index_read_map(table->record[0],
3462
3783
                                      tab->ref.key_buff,
3463
3784
                                      make_prev_keypart_map(tab->ref.key_parts),
3464
3785
                                      HA_READ_KEY_EXACT);
3494
3815
 
3495
3816
  /* Initialize the index first */
3496
3817
  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
 
  }
 
3818
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3502
3819
 
3503
3820
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3504
3821
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3509
3826
 
3510
3827
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3511
3828
    return -1;
3512
 
  if ((error=table->cursor->index_read_map(table->getInsertRecord(),
 
3829
  if ((error=table->cursor->index_read_map(table->record[0],
3513
3830
                                         tab->ref.key_buff,
3514
3831
                                         make_prev_keypart_map(tab->ref.key_parts),
3515
3832
                                         HA_READ_KEY_EXACT)))
3532
3849
  Table *table= tab->table;
3533
3850
 
3534
3851
  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
 
  }
 
3852
    table->cursor->startIndexScan(tab->ref.key, tab->sorted);
3540
3853
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3541
3854
    return -1;
3542
 
  if ((error=table->cursor->index_read_last_map(table->getInsertRecord(),
 
3855
  if ((error=table->cursor->index_read_last_map(table->record[0],
3543
3856
                                              tab->ref.key_buff,
3544
3857
                                              make_prev_keypart_map(tab->ref.key_parts))))
3545
3858
  {
3568
3881
      /* Save index tuple from record to the buffer */
3569
3882
      key_copy(tab->insideout_buf, info->record, key, 0);
3570
3883
 
3571
 
      if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3884
      if ((error=table->cursor->index_next_same(table->record[0],
3572
3885
                                              tab->ref.key_buff,
3573
3886
                                              tab->ref.key_length)))
3574
3887
      {
3592
3905
  Table *table= info->table;
3593
3906
  JoinTable *tab=table->reginfo.join_tab;
3594
3907
 
3595
 
  if ((error=table->cursor->index_next_same(table->getInsertRecord(),
 
3908
  if ((error=table->cursor->index_next_same(table->record[0],
3596
3909
                                          tab->ref.key_buff,
3597
3910
                                          tab->ref.key_length)))
3598
3911
  {
3611
3924
  Table *table= info->table;
3612
3925
  JoinTable *tab=table->reginfo.join_tab;
3613
3926
 
3614
 
  if ((error=table->cursor->index_prev(table->getInsertRecord())))
 
3927
  if ((error=table->cursor->index_prev(table->record[0])))
3615
3928
    return table->report_error(error);
3616
3929
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3617
3930
                      tab->ref.key_length))
3629
3942
  return join_init_read_record(tab);
3630
3943
}
3631
3944
 
 
3945
int rr_sequential(ReadRecord *info);
3632
3946
int init_read_record_seq(JoinTable *tab)
3633
3947
{
3634
 
  tab->read_record.init_reard_record_sequential();
3635
 
 
 
3948
  tab->read_record.read_record= rr_sequential;
3636
3949
  if (tab->read_record.cursor->startTableScan(1))
3637
3950
    return 1;
3638
3951
  return (*tab->read_record.read_record)(&tab->read_record);
3640
3953
 
3641
3954
int test_if_quick_select(JoinTable *tab)
3642
3955
{
3643
 
  safe_delete(tab->select->quick);
3644
 
 
 
3956
  delete tab->select->quick;
 
3957
  tab->select->quick= 0;
3645
3958
  return tab->select->test_quick_select(tab->join->session, tab->keys,
3646
3959
                                        (table_map) 0, HA_POS_ERROR, 0, false);
3647
3960
}
3651
3964
  if (tab->select && tab->select->quick && tab->select->quick->reset())
3652
3965
    return 1;
3653
3966
 
3654
 
  if (tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true))
3655
 
    return 1;
 
3967
  tab->read_record.init_read_record(tab->join->session, tab->table, tab->select, 1, true);
3656
3968
 
3657
3969
  return (*tab->read_record.read_record)(&tab->read_record);
3658
3970
}
3671
3983
  tab->read_record.table=table;
3672
3984
  tab->read_record.cursor=table->cursor;
3673
3985
  tab->read_record.index=tab->index;
3674
 
  tab->read_record.record=table->getInsertRecord();
 
3986
  tab->read_record.record=table->record[0];
3675
3987
  if (tab->insideout_match_tab)
3676
3988
  {
3677
3989
    tab->read_record.do_insideout_scan= tab;
3685
3997
  }
3686
3998
 
3687
3999
  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())))
 
4000
    table->cursor->startIndexScan(tab->index, tab->sorted);
 
4001
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
3697
4002
  {
3698
4003
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
3699
4004
      table->report_error(error);
3749
4054
  tab->read_record.table=table;
3750
4055
  tab->read_record.cursor=table->cursor;
3751
4056
  tab->read_record.index=tab->index;
3752
 
  tab->read_record.record=table->getInsertRecord();
 
4057
  tab->read_record.record=table->record[0];
3753
4058
  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())))
 
4059
    table->cursor->startIndexScan(tab->index, 1);
 
4060
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
3760
4061
    return table->report_error(error);
3761
4062
 
3762
4063
  return 0;
3819
4120
        {
3820
4121
          if (!join->first_record)
3821
4122
          {
3822
 
                  List<Item>::iterator it(join->fields->begin());
 
4123
                  List_iterator_fast<Item> it(*join->fields);
3823
4124
                  Item *item;
3824
4125
            /* No matching rows for group function */
3825
4126
            join->clear();
3835
4136
              error=join->result->send_data(*join->fields) ? 1 : 0;
3836
4137
            join->send_records++;
3837
4138
          }
3838
 
          if (join->rollup.getState() != Rollup::STATE_NONE && error <= 0)
 
4139
          if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
3839
4140
          {
3840
4141
            if (join->rollup_send_data((uint32_t) (idx+1)))
3841
4142
              error= 1;
3896
4197
  Table *table=join->tmp_table;
3897
4198
  int     idx= -1;
3898
4199
 
3899
 
  if (join->session->getKilled())
 
4200
  if (join->session->killed)
3900
4201
  {                                             // Aborted by user
3901
4202
    join->session->send_kill_message();
3902
4203
    return NESTED_LOOP_KILLED;
3917
4218
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
3918
4219
        if (!join->having || join->having->val_int())
3919
4220
        {
3920
 
          int error= table->cursor->insertRecord(table->getInsertRecord());
 
4221
          int error= table->cursor->insertRecord(table->record[0]);
3921
4222
 
3922
4223
          if (error)
3923
4224
          {
3925
4226
            return NESTED_LOOP_ERROR;
3926
4227
          }
3927
4228
        }
3928
 
        if (join->rollup.getState() != Rollup::STATE_NONE)
 
4229
        if (join->rollup.state != ROLLUP::STATE_NONE)
3929
4230
        {
3930
4231
          if (join->rollup_write_data((uint32_t) (idx+1), table))
3931
4232
            return NESTED_LOOP_ERROR;
3944
4245
    if (idx < (int) join->send_group_parts)
3945
4246
    {
3946
4247
      copy_fields(&join->tmp_table_param);
3947
 
      if (copy_funcs(join->tmp_table_param.items_to_copy, join->session))
3948
 
        return NESTED_LOOP_ERROR;
 
4248
      copy_funcs(join->tmp_table_param.items_to_copy);
3949
4249
      if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
3950
4250
        return NESTED_LOOP_ERROR;
3951
4251
      return NESTED_LOOP_OK;
3962
4262
  outer join table.
3963
4263
  We can't remove tests that are made against columns which are stored
3964
4264
  in sorted order.
 
4265
*****************************************************************************/
 
4266
 
 
4267
/**
3965
4268
  @return
3966
 
    1 if right_item used is a removable reference key on left_item
3967
 
    0 otherwise.
3968
 
****************************************************************************/
 
4269
    1 if right_item is used removable reference key on left_item
 
4270
*/
3969
4271
bool test_if_ref(Item_field *left_item,Item *right_item)
3970
4272
{
3971
4273
  Field *field=left_item->field;
3972
4274
  // No need to change const test. We also have to keep tests on LEFT JOIN
3973
 
  if (not field->getTable()->const_table && !field->getTable()->maybe_null)
 
4275
  if (!field->table->const_table && !field->table->maybe_null)
3974
4276
  {
3975
 
    Item *ref_item=part_of_refkey(field->getTable(),field);
 
4277
    Item *ref_item=part_of_refkey(field->table,field);
3976
4278
    if (ref_item && ref_item->eq(right_item,1))
3977
4279
    {
3978
4280
      right_item= right_item->real_item();
4058
4360
      Item_cond_and *new_cond=new Item_cond_and;
4059
4361
      if (!new_cond)
4060
4362
        return (COND*) 0;
4061
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4363
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4062
4364
      Item *item;
4063
4365
      while ((item=li++))
4064
4366
      {
4088
4390
      Item_cond_or *new_cond=new Item_cond_or;
4089
4391
      if (!new_cond)
4090
4392
        return (COND*) 0;
4091
 
      List<Item>::iterator li(((Item_cond*) cond)->argument_list()->begin());
 
4393
      List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
4092
4394
      Item *item;
4093
4395
      while ((item=li++))
4094
4396
      {
4166
4468
    }
4167
4469
 
4168
4470
    for (part=0 ; part < ref_parts ; part++,key_part++)
4169
 
    {
4170
4471
      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
 
      {
 
4472
          !(key_part->key_part_flag & HA_PART_KEY_SEG))
4176
4473
        return table->reginfo.join_tab->ref.items[part];
4177
 
      }
4178
 
    }
4179
4474
  }
4180
4475
  return (Item*) 0;
4181
4476
}
4200
4495
  @retval
4201
4496
    -1   Reverse key can be used
4202
4497
*/
4203
 
static int test_if_order_by_key(Order *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
 
4498
static int test_if_order_by_key(order_st *order, Table *table, uint32_t idx, uint32_t *used_key_parts)
4204
4499
{
4205
4500
  KeyPartInfo *key_part= NULL;
4206
4501
  KeyPartInfo *key_part_end= NULL;
4231
4526
      */
4232
4527
      if (!on_primary_key &&
4233
4528
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
4234
 
          table->getShare()->hasPrimaryKey())
 
4529
          table->getShare()->primary_key != MAX_KEY)
4235
4530
      {
4236
4531
        on_primary_key= true;
4237
 
        key_part= table->key_info[table->getShare()->getPrimaryKey()].key_part;
4238
 
        key_part_end=key_part+table->key_info[table->getShare()->getPrimaryKey()].key_parts;
4239
 
        const_key_parts=table->const_key_parts[table->getShare()->getPrimaryKey()];
 
4532
        key_part= table->key_info[table->getShare()->primary_key].key_part;
 
4533
        key_part_end=key_part+table->key_info[table->getShare()->primary_key].key_parts;
 
4534
        const_key_parts=table->const_key_parts[table->getShare()->primary_key];
4240
4535
 
4241
4536
        for (; const_key_parts & 1 ; const_key_parts>>= 1)
4242
4537
          key_part++;
4306
4601
    - MAX_KEY                   If we can't use other key
4307
4602
    - the number of found key   Otherwise
4308
4603
*/
4309
 
static uint32_t test_if_subkey(Order *order,
 
4604
static uint32_t test_if_subkey(order_st *order,
4310
4605
                               Table *table,
4311
4606
                               uint32_t ref,
4312
4607
                               uint32_t ref_key_parts,
4319
4614
  KeyPartInfo *ref_key_part= table->key_info[ref].key_part;
4320
4615
  KeyPartInfo *ref_key_part_end= ref_key_part + ref_key_parts;
4321
4616
 
4322
 
  for (nr= 0 ; nr < table->getShare()->sizeKeys() ; nr++)
 
4617
  for (nr= 0 ; nr < table->getShare()->keys ; nr++)
4323
4618
  {
4324
4619
    if (usable_keys->test(nr) &&
4325
4620
        table->key_info[nr].key_length < min_length &&
4368
4663
*/
4369
4664
bool list_contains_unique_index(Table *table, bool (*find_func) (Field *, void *), void *data)
4370
4665
{
4371
 
  for (uint32_t keynr= 0; keynr < table->getShare()->sizeKeys(); keynr++)
 
4666
  for (uint32_t keynr= 0; keynr < table->getShare()->keys; keynr++)
4372
4667
  {
4373
 
    if (keynr == table->getShare()->getPrimaryKey() ||
 
4668
    if (keynr == table->getShare()->primary_key ||
4374
4669
         (table->key_info[keynr].flags & HA_NOSAME))
4375
4670
    {
4376
4671
      KeyInfo *keyinfo= table->key_info + keynr;
4408
4703
*/
4409
4704
bool find_field_in_order_list (Field *field, void *data)
4410
4705
{
4411
 
  Order *group= (Order *) data;
 
4706
  order_st *group= (order_st *) data;
4412
4707
  bool part_found= 0;
4413
 
  for (Order *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
 
4708
  for (order_st *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
4414
4709
  {
4415
4710
    Item *item= (*tmp_group->item)->real_item();
4416
4711
    if (item->type() == Item::FIELD_ITEM &&
4440
4735
{
4441
4736
  List<Item> *fields= (List<Item> *) data;
4442
4737
  bool part_found= 0;
4443
 
  List<Item>::iterator li(fields->begin());
 
4738
  List_iterator<Item> li(*fields);
4444
4739
  Item *item;
4445
4740
 
4446
4741
  while ((item= li++))
4480
4775
  @retval
4481
4776
    1    We can use an index.
4482
4777
*/
4483
 
bool test_if_skip_sort_order(JoinTable *tab, Order *order, ha_rows select_limit, bool no_changes, const key_map *map)
 
4778
bool test_if_skip_sort_order(JoinTable *tab, order_st *order, ha_rows select_limit, bool no_changes, const key_map *map)
4484
4779
{
4485
4780
  int32_t ref_key;
4486
4781
  uint32_t ref_key_parts;
4497
4792
  */
4498
4793
  usable_keys= *map;
4499
4794
 
4500
 
  for (Order *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
 
4795
  for (order_st *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
4501
4796
  {
4502
4797
    Item *item= (*tmp_order->item)->real_item();
4503
4798
    if (item->type() != Item::FIELD_ITEM)
4525
4820
    save_quick= select->quick;
4526
4821
    /*
4527
4822
      assume results are not ordered when index merge is used
4528
 
      @todo sergeyp: Results of all index merge selects actually are ordered
 
4823
      TODO: sergeyp: Results of all index merge selects actually are ordered
4529
4824
      by clustered PK values.
4530
4825
    */
4531
4826
 
4669
4964
      fanout*= cur_pos.getFanout(); // fanout is always >= 1
4670
4965
    }
4671
4966
 
4672
 
    for (nr=0; nr < table->getShare()->sizeKeys() ; nr++)
 
4967
    for (nr=0; nr < table->getShare()->keys ; nr++)
4673
4968
    {
4674
4969
      int direction;
4675
4970
      if (keys.test(nr) &&
4676
4971
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4677
4972
      {
4678
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->getPrimaryKey() && table->cursor->primary_key_is_clustered());
 
4973
        bool is_covering= table->covering_keys.test(nr) || (nr == table->getShare()->primary_key && table->cursor->primary_key_is_clustered());
4679
4974
 
4680
4975
        /*
4681
4976
          Don't use an index scan with ORDER BY without limit.
4800
5095
          tab->type= AM_NEXT;           // Read with index_first(), index_next()
4801
5096
          if (select && select->quick)
4802
5097
          {
4803
 
            safe_delete(select->quick);
 
5098
            delete select->quick;
 
5099
            select->quick= 0;
4804
5100
          }
4805
5101
          if (table->covering_keys.test(best_key))
4806
5102
          {
4873
5169
          tab->limit= 0;
4874
5170
          return 0; // Reverse sort not supported
4875
5171
        }
4876
 
        select->quick= tmp;
 
5172
        select->quick=tmp;
4877
5173
      }
4878
5174
    }
4879
5175
    else if (tab->type != AM_NEXT &&
4922
5218
    -1          Some fatal error
4923
5219
    1           No records
4924
5220
*/
4925
 
int create_sort_index(Session *session, Join *join, Order *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
 
5221
int create_sort_index(Session *session, Join *join, order_st *order, ha_rows filesort_limit, ha_rows select_limit, bool is_order_by)
4926
5222
{
4927
5223
  uint32_t length= 0;
4928
5224
  ha_rows examined_rows;
4949
5245
                              is_order_by ?  &table->keys_in_use_for_order_by :
4950
5246
                              &table->keys_in_use_for_group_by))
4951
5247
    return(0);
4952
 
  for (Order *ord= join->order; ord; ord= ord->next)
 
5248
  for (order_st *ord= join->order; ord; ord= ord->next)
4953
5249
    length++;
4954
 
  if (!(join->sortorder= make_unireg_sortorder(order, &length, join->sortorder)))
4955
 
  {
4956
 
    return(-1);
4957
 
  }
 
5250
  if (!(join->sortorder=
 
5251
        make_unireg_sortorder(order, &length, join->sortorder)))
 
5252
    goto err;
4958
5253
 
4959
5254
  table->sort.io_cache= new internal::IO_CACHE;
 
5255
  memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
4960
5256
  table->status=0;                              // May be wrong if quick_select
4961
5257
 
4962
5258
  // If table has a range, move it to select
4989
5285
                                                                 &tab->ref,
4990
5286
                                                                 tab->found_records))))
4991
5287
      {
4992
 
        return(-1);
 
5288
        goto err;
4993
5289
      }
4994
5290
    }
4995
5291
  }
4996
5292
 
4997
 
  if (table->getShare()->getType())
 
5293
  if (table->getShare()->tmp_table)
4998
5294
    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);
 
5295
  table->sort.found_records=filesort(session, table,join->sortorder, length,
 
5296
                                     select, filesort_limit, 0,
 
5297
                                     &examined_rows);
5004
5298
  tab->records= table->sort.found_records;      // For SQL_CALC_ROWS
5005
5299
  if (select)
5006
5300
  {
5018
5312
    table->key_read=0;
5019
5313
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
5020
5314
  }
5021
 
 
5022
5315
  return(table->sort.found_records == HA_POS_ERROR);
 
5316
err:
 
5317
  return(-1);
5023
5318
}
5024
5319
 
5025
5320
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5028
5323
  char *org_record,*new_record;
5029
5324
  unsigned char *record;
5030
5325
  int error;
5031
 
  uint32_t reclength= table->getShare()->getRecordLength() - offset;
5032
 
 
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
 
 
 
5326
  uint32_t reclength= table->getShare()->reclength - offset;
 
5327
 
 
5328
  org_record=(char*) (record=table->record[0])+offset;
 
5329
  new_record=(char*) table->record[1]+offset;
 
5330
 
 
5331
  cursor->startTableScan(1);
5039
5332
  error=cursor->rnd_next(record);
5040
5333
  for (;;)
5041
5334
  {
5042
 
    if (session->getKilled())
 
5335
    if (session->killed)
5043
5336
    {
5044
5337
      session->send_kill_message();
5045
5338
      error=0;
5119
5412
                               uint32_t key_length,
5120
5413
                               Item *having)
5121
5414
{
5122
 
  unsigned char *key_pos, *record=table->getInsertRecord();
 
5415
  unsigned char *key_pos, *record=table->record[0];
5123
5416
  int error;
5124
5417
  Cursor *cursor= table->cursor;
5125
5418
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5126
 
  uint32_t *field_length;
 
5419
  uint32_t *field_lengths,*field_length;
5127
5420
  HASH hash;
5128
 
  std::vector<unsigned char> key_buffer;
5129
 
  std::vector<uint32_t> field_lengths;
 
5421
  std::vector<unsigned char>key_buffer;
5130
5422
 
5131
5423
  key_buffer.resize((key_length + extra_length) * (long) cursor->stats.records);
5132
 
  field_lengths.resize(field_count);
 
5424
 
 
5425
  field_lengths= (uint32_t *)std::malloc(field_count * sizeof(*field_lengths));
 
5426
 
 
5427
  if (field_lengths == NULL)
 
5428
    return(1);
5133
5429
 
5134
5430
  {
5135
5431
    Field **ptr;
5136
5432
    uint32_t total_length= 0;
5137
5433
 
5138
 
    for (ptr= first_field, field_length= &field_lengths[0] ; *ptr ; ptr++)
 
5434
    for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
5139
5435
    {
5140
5436
      uint32_t length= (*ptr)->sort_length();
5141
5437
      (*field_length++)= length;
5149
5445
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
5150
5446
                key_length, (hash_get_key) 0, 0, 0))
5151
5447
  {
 
5448
    free((char*) field_lengths);
5152
5449
    return(1);
5153
5450
  }
5154
5451
 
5155
 
  if ((error= cursor->startTableScan(1)))
5156
 
    goto err;
5157
 
 
 
5452
  cursor->startTableScan(1);
5158
5453
  key_pos= &key_buffer[0];
5159
5454
  for (;;)
5160
5455
  {
5161
5456
    unsigned char *org_key_pos;
5162
 
    if (session->getKilled())
 
5457
    if (session->killed)
5163
5458
    {
5164
5459
      session->send_kill_message();
5165
5460
      error=0;
5182
5477
 
5183
5478
    /* copy fields to key buffer */
5184
5479
    org_key_pos= key_pos;
5185
 
    field_length= &field_lengths[0];
 
5480
    field_length=field_lengths;
5186
5481
    for (Field **ptr= first_field ; *ptr ; ptr++)
5187
5482
    {
5188
5483
      (*ptr)->sort_string(key_pos,*field_length);
5199
5494
      (void) my_hash_insert(&hash, org_key_pos);
5200
5495
    key_pos+=extra_length;
5201
5496
  }
 
5497
  free((char*) field_lengths);
5202
5498
  hash_free(&hash);
5203
5499
  cursor->extra(HA_EXTRA_NO_CACHE);
5204
5500
  (void) cursor->endTableScan();
5205
5501
  return(0);
5206
5502
 
5207
5503
err:
 
5504
  free((char*) field_lengths);
5208
5505
  hash_free(&hash);
5209
5506
  cursor->extra(HA_EXTRA_NO_CACHE);
5210
5507
  (void) cursor->endTableScan();
5213
5510
  return(1);
5214
5511
}
5215
5512
 
5216
 
SortField *make_unireg_sortorder(Order *order, uint32_t *length, SortField *sortorder)
 
5513
SORT_FIELD *make_unireg_sortorder(order_st *order, uint32_t *length, SORT_FIELD *sortorder)
5217
5514
{
5218
5515
  uint32_t count;
5219
 
  SortField *sort,*pos;
 
5516
  SORT_FIELD *sort,*pos;
5220
5517
 
5221
5518
  count=0;
5222
 
  for (Order *tmp = order; tmp; tmp=tmp->next)
 
5519
  for (order_st *tmp = order; tmp; tmp=tmp->next)
5223
5520
    count++;
5224
5521
  if (!sortorder)
5225
 
    sortorder= (SortField*) memory::sql_alloc(sizeof(SortField) *
 
5522
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
5226
5523
                                       (max(count, *length) + 1));
5227
5524
  pos= sort= sortorder;
5228
5525
 
5344
5641
static bool find_order_in_list(Session *session, 
5345
5642
                               Item **ref_pointer_array, 
5346
5643
                               TableList *tables,
5347
 
                               Order *order,
 
5644
                               order_st *order,
5348
5645
                               List<Item> &fields,
5349
5646
                               List<Item> &all_fields,
5350
5647
                               bool is_group_field)
5366
5663
    if (!count || count > fields.elements)
5367
5664
    {
5368
5665
      my_error(ER_BAD_FIELD_ERROR, MYF(0),
5369
 
               order_item->full_name(), session->where());
 
5666
               order_item->full_name(), session->where);
5370
5667
      return true;
5371
5668
    }
5372
5669
    order->item= ref_pointer_array + count - 1;
5376
5673
    return false;
5377
5674
  }
5378
5675
  /* Lookup the current GROUP/order_st field in the SELECT clause. */
5379
 
  select_item= find_item_in_list(session, order_item, fields, &counter,
 
5676
  select_item= find_item_in_list(order_item, fields, &counter,
5380
5677
                                 REPORT_EXCEPT_NOT_FOUND, &resolution);
5381
5678
  if (!select_item)
5382
5679
    return true; /* The item is not unique, or some other error occured. */
5443
5740
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
5444
5741
                          ER(ER_NON_UNIQ_ERROR),
5445
5742
                          ((Item_ident*) order_item)->field_name,
5446
 
                          session->where());
 
5743
                          current_session->where);
5447
5744
    }
5448
5745
  }
5449
5746
 
5483
5780
                TableList *tables,
5484
5781
                            List<Item> &fields,
5485
5782
                List<Item> &all_fields,
5486
 
                Order *order)
 
5783
                order_st *order)
5487
5784
{
5488
 
  session->setWhere("order clause");
 
5785
  session->where="order clause";
5489
5786
  for (; order; order=order->next)
5490
5787
  {
5491
5788
    if (find_order_in_list(session, ref_pointer_array, tables, order, fields,
5525
5822
                TableList *tables,
5526
5823
                      List<Item> &fields,
5527
5824
                List<Item> &all_fields,
5528
 
                Order *order,
 
5825
                order_st *order,
5529
5826
                      bool *hidden_group_fields)
5530
5827
{
5531
5828
  *hidden_group_fields=0;
5532
 
  Order *ord;
 
5829
  order_st *ord;
5533
5830
 
5534
5831
  if (!order)
5535
5832
    return 0;                           /* Everything is ok */
5536
5833
 
5537
5834
  uint32_t org_fields=all_fields.elements;
5538
5835
 
5539
 
  session->setWhere("group statement");
 
5836
  session->where="group statement";
5540
5837
  for (ord= order; ord; ord= ord->next)
5541
5838
  {
5542
5839
    if (find_order_in_list(session, ref_pointer_array, tables, ord, fields,
5569
5866
    Item *item;
5570
5867
    Item_field *field;
5571
5868
    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());
 
5869
    List_iterator<Item> li(fields);
 
5870
    List_iterator<Item_field> naf_it(session->lex->current_select->non_agg_fields);
5574
5871
 
5575
5872
    field= naf_it++;
5576
5873
    while (field && (item=li++))
5596
5893
            if ((*ord->item)->eq((Item*)field, 0))
5597
5894
              goto next_field;
5598
5895
          /*
5599
 
            @todo change ER_WRONG_FIELD_WITH_GROUP to more detailed ER_NON_GROUPING_FIELD_USED
 
5896
            TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
 
5897
            ER_NON_GROUPING_FIELD_USED
5600
5898
          */
5601
5899
          my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
5602
5900
          return 1;
5618
5916
  Try to use the fields in the order given by 'order' to allow one to
5619
5917
  optimize away 'order by'.
5620
5918
*/
5621
 
Order *create_distinct_group(Session *session,
 
5919
order_st *create_distinct_group(Session *session,
5622
5920
                                Item **ref_pointer_array,
5623
 
                                Order *order_list,
 
5921
                                order_st *order_list,
5624
5922
                                List<Item> &fields,
5625
5923
                                List<Item> &,
5626
5924
                                bool *all_order_by_fields_used)
5627
5925
{
5628
 
  List<Item>::iterator li(fields.begin());
 
5926
  List_iterator<Item> li(fields);
5629
5927
  Item *item;
5630
 
  Order *order,*group,**prev;
 
5928
  order_st *order,*group,**prev;
5631
5929
 
5632
5930
  *all_order_by_fields_used= 1;
5633
5931
  while ((item=li++))
5638
5936
  {
5639
5937
    if (order->in_field_list)
5640
5938
    {
5641
 
      Order *ord=(Order*) session->getMemRoot()->duplicate((char*) order,sizeof(Order));
 
5939
      order_st *ord=(order_st*) session->memdup((char*) order,sizeof(order_st));
5642
5940
      if (!ord)
5643
5941
        return 0;
5644
5942
      *prev=ord;
5649
5947
      *all_order_by_fields_used= 0;
5650
5948
  }
5651
5949
 
5652
 
  li= fields.begin();
 
5950
  li.rewind();
5653
5951
  while ((item=li++))
5654
5952
  {
5655
5953
    if (!item->const_item() && !item->with_sum_func && !item->marker)
5658
5956
        Don't put duplicate columns from the SELECT list into the
5659
5957
        GROUP BY list.
5660
5958
      */
5661
 
      Order *ord_iter;
 
5959
      order_st *ord_iter;
5662
5960
      for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
5663
5961
        if ((*ord_iter->item)->eq(item, 1))
5664
5962
          goto next_item;
5665
5963
 
5666
 
      Order *ord=(Order*) session->calloc(sizeof(Order));
 
5964
      order_st *ord=(order_st*) session->calloc(sizeof(order_st));
5667
5965
      if (!ord)
5668
5966
        return 0;
5669
5967
 
5689
5987
*/
5690
5988
void count_field_types(Select_Lex *select_lex, Tmp_Table_Param *param, List<Item> &fields, bool reset_with_sum_func)
5691
5989
{
5692
 
  List<Item>::iterator li(fields.begin());
 
5990
  List_iterator<Item> li(fields);
5693
5991
  Item *field;
5694
5992
 
5695
5993
  param->field_count=param->sum_func_count=param->func_count=
5746
6044
*/
5747
6045
int test_if_item_cache_changed(List<Cached_item> &list)
5748
6046
{
5749
 
  List<Cached_item>::iterator li(list.begin());
 
6047
  List_iterator<Cached_item> li(list);
5750
6048
  int idx= -1,i;
5751
6049
  Cached_item *buff;
5752
6050
 
5795
6093
                       List<Item> &all_fields)
5796
6094
{
5797
6095
  Item *pos;
5798
 
  List<Item>::iterator li(all_fields.begin());
 
6096
  List_iterator_fast<Item> li(all_fields);
5799
6097
  CopyField *copy= NULL;
5800
 
  res_selected_fields.clear();
5801
 
  res_all_fields.clear();
5802
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6098
  res_selected_fields.empty();
 
6099
  res_all_fields.empty();
 
6100
  List_iterator_fast<Item> itr(res_all_fields);
5803
6101
  List<Item> extra_funcs;
5804
6102
  uint32_t i, border= all_fields.elements - elements;
5805
6103
 
5807
6105
      !(copy=param->copy_field= new CopyField[param->field_count]))
5808
6106
    goto err2;
5809
6107
 
5810
 
  param->copy_funcs.clear();
 
6108
  param->copy_funcs.empty();
5811
6109
  for (i= 0; (pos= li++); i++)
5812
6110
  {
5813
6111
    Field *field;
5850
6148
          saved value
5851
6149
        */
5852
6150
        field= item->field;
5853
 
        item->result_field=field->new_field(session->mem_root,field->getTable(), 1);
 
6151
        item->result_field=field->new_field(session->mem_root,field->table, 1);
5854
6152
              /*
5855
6153
                We need to allocate one extra byte for null handling and
5856
6154
                another extra byte to not get warnings from purify in
5862
6160
        {
5863
6161
          copy->set(tmp, item->result_field);
5864
6162
          item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
5865
 
#ifdef HAVE_VALGRIND
 
6163
#ifdef HAVE_purify
5866
6164
          copy->to_ptr[copy->from_length]= 0;
5867
6165
#endif
5868
6166
          copy++;
5876
6174
             !real_pos->with_sum_func)
5877
6175
    {                                           // Save for send fields
5878
6176
      pos= real_pos;
5879
 
      /* 
5880
 
        @todo In most cases this result will be sent to the user.
 
6177
      /* TODO:
 
6178
        In most cases this result will be sent to the user.
5881
6179
        This should be changed to use copy_int or copy_real depending
5882
6180
        on how the value is to be used: In some cases this may be an
5883
6181
        argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
5931
6229
  for (; ptr != end; ptr++)
5932
6230
    (*ptr->do_copy)(ptr);
5933
6231
 
5934
 
  List<Item>::iterator it(param->copy_funcs.begin());
 
6232
  List_iterator_fast<Item> it(param->copy_funcs);
5935
6233
  Item_copy_string *item;
5936
6234
  while ((item = (Item_copy_string*) it++))
5937
6235
    item->copy();
5960
6258
                                                uint32_t elements,
5961
6259
                              List<Item> &all_fields)
5962
6260
{
5963
 
  List<Item>::iterator it(all_fields.begin());
 
6261
  List_iterator_fast<Item> it(all_fields);
5964
6262
  Item *item_field,*item;
5965
6263
 
5966
 
  res_selected_fields.clear();
5967
 
  res_all_fields.clear();
 
6264
  res_selected_fields.empty();
 
6265
  res_all_fields.empty();
5968
6266
 
5969
6267
  uint32_t i, border= all_fields.elements - elements;
5970
6268
  for (i= 0; (item= it++); i++)
5983
6281
      }
5984
6282
      else if ((field= item->get_tmp_table_field()))
5985
6283
      {
5986
 
        if (item->type() == Item::SUM_FUNC_ITEM && field->getTable()->group)
 
6284
        if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
5987
6285
          item_field= ((Item_sum*) item)->result_item(field);
5988
6286
        else
5989
6287
          item_field= (Item*) new Item_field(field);
6009
6307
      item_field;
6010
6308
  }
6011
6309
 
6012
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6310
  List_iterator_fast<Item> itr(res_all_fields);
6013
6311
  for (i= 0; i < border; i++)
6014
6312
    itr++;
6015
6313
  itr.sublist(res_selected_fields, elements);
6039
6337
                               uint32_t elements,
6040
6338
                                                 List<Item> &all_fields)
6041
6339
{
6042
 
  List<Item>::iterator it(all_fields.begin());
 
6340
  List_iterator_fast<Item> it(all_fields);
6043
6341
  Item *item, *new_item;
6044
 
  res_selected_fields.clear();
6045
 
  res_all_fields.clear();
 
6342
  res_selected_fields.empty();
 
6343
  res_all_fields.empty();
6046
6344
 
6047
6345
  uint32_t i, border= all_fields.elements - elements;
6048
6346
  for (i= 0; (item= it++); i++)
6052
6350
      new_item;
6053
6351
  }
6054
6352
 
6055
 
  List<Item>::iterator itr(res_all_fields.begin());
 
6353
  List_iterator_fast<Item> itr(res_all_fields);
6056
6354
  for (i= 0; i < border; i++)
6057
6355
    itr++;
6058
6356
  itr.sublist(res_selected_fields, elements);
6135
6433
}
6136
6434
 
6137
6435
/** Copy result of functions to record in tmp_table. */
6138
 
bool copy_funcs(Item **func_ptr, const Session *session)
 
6436
void copy_funcs(Item **func_ptr)
6139
6437
{
6140
6438
  Item *func;
6141
6439
  for (; (func = *func_ptr) ; func_ptr++)
6142
 
  {
6143
6440
    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
6441
}
6155
6442
 
6156
6443
/**
6202
6489
  @param changed        out:  returns 1 if item contains a replaced field item
6203
6490
 
6204
6491
  @todo
6205
 
    - @todo Some functions are not null-preserving. For those functions
 
6492
    - TODO: Some functions are not null-preserving. For those functions
6206
6493
    updating of the maybe_null attribute is an overkill.
6207
6494
 
6208
6495
  @retval
6210
6497
  @retval
6211
6498
    1   on error
6212
6499
*/
6213
 
bool change_group_ref(Session *session, Item_func *expr, Order *group_list, bool *changed)
 
6500
bool change_group_ref(Session *session, Item_func *expr, order_st *group_list, bool *changed)
6214
6501
{
6215
6502
  if (expr->arg_count)
6216
6503
  {
6217
 
    Name_resolution_context *context= &session->getLex()->current_select->context;
 
6504
    Name_resolution_context *context= &session->lex->current_select->context;
6218
6505
    Item **arg,**arg_end;
6219
6506
    bool arg_changed= false;
6220
6507
    for (arg= expr->arguments(),
6224
6511
      Item *item= *arg;
6225
6512
      if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
6226
6513
      {
6227
 
        Order *group_tmp;
 
6514
        order_st *group_tmp;
6228
6515
        for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
6229
6516
        {
6230
6517
          if (item->eq(*group_tmp->item,0))
6292
6579
                List<TableList> *tables, enum_query_type)
6293
6580
{
6294
6581
  /* 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*) *
 
6582
  List_iterator_fast<TableList> ti(*tables);
 
6583
  TableList **table= (TableList **)session->alloc(sizeof(TableList*) *
6297
6584
                                                tables->elements);
6298
6585
  if (table == 0)
6299
6586
    return;  // out of memory
6307
6594
void Select_Lex::print(Session *session, String *str, enum_query_type query_type)
6308
6595
{
6309
6596
  /* QQ: session may not be set for sub queries, but this should be fixed */
6310
 
  if(not session)
 
6597
  if (!session)
6311
6598
    session= current_session;
6312
6599
 
6313
 
 
6314
6600
  str->append(STRING_WITH_LEN("select "));
6315
6601
 
6316
6602
  /* First add options */
6329
6615
 
6330
6616
  //Item List
6331
6617
  bool first= 1;
6332
 
  List<Item>::iterator it(item_list.begin());
 
6618
  List_iterator_fast<Item> it(item_list);
6333
6619
  Item *item;
6334
6620
  while ((item= it++))
6335
6621
  {
6342
6628
 
6343
6629
  /*
6344
6630
    from clause
6345
 
    @todo support USING/FORCE/IGNORE index
 
6631
    TODO: support USING/FORCE/IGNORE index
6346
6632
  */
6347
6633
  if (table_list.elements)
6348
6634
  {
6376
6662
  if (group_list.elements)
6377
6663
  {
6378
6664
    str->append(STRING_WITH_LEN(" group by "));
6379
 
    print_order(str, (Order *) group_list.first, query_type);
 
6665
    print_order(str, (order_st *) group_list.first, query_type);
6380
6666
    switch (olap)
6381
6667
    {
6382
6668
      case CUBE_TYPE:
6407
6693
  if (order_list.elements)
6408
6694
  {
6409
6695
    str->append(STRING_WITH_LEN(" order by "));
6410
 
    print_order(str, (Order *) order_list.first, query_type);
 
6696
    print_order(str, (order_st *) order_list.first, query_type);
6411
6697
  }
6412
6698
 
6413
6699
  // limit